@interchainjs/injective
Version:
209 lines (208 loc) • 7.76 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.EthSecp256k1Signature = exports.InjectiveSignatureProcessor = exports.PRESET_INJECTIVE_SIGNATURE_FORMATS = exports.BytesUtils = void 0;
exports.resolveInjectiveSignatureFormat = resolveInjectiveSignatureFormat;
const auth_1 = require("@interchainjs/auth");
const utils_1 = require("@interchainjs/utils");
/**
* Utility functions that implement the BytesUtils functionality mentioned in requirements
* Defined first to avoid forward reference issues
*/
exports.BytesUtils = {
/**
* Split signature into components
*/
splitSignature: (signature) => {
if (signature.length === 64) {
// Compact signature (no recovery byte)
return {
r: signature.slice(0, 32),
s: signature.slice(32, 64)
};
}
else if (signature.length === 65) {
// Full signature with recovery byte
return {
r: signature.slice(0, 32),
s: signature.slice(32, 64),
recovery: signature[64]
};
}
else {
throw new Error(`Invalid signature length: ${signature.length}. Expected 64 or 65 bytes.`);
}
},
/**
* Combine signature components
*/
combineSignature: (r, s, recovery) => {
if (r.length !== 32 || s.length !== 32) {
throw new Error('R and S components must be 32 bytes each');
}
if (recovery !== undefined) {
// Create 65-byte signature with recovery
const signature = new Uint8Array(65);
signature.set(r, 0);
signature.set(s, 32);
signature[64] = recovery;
return signature;
}
else {
// Create 64-byte signature without recovery
const signature = new Uint8Array(64);
signature.set(r, 0);
signature.set(s, 32);
return signature;
}
},
/**
* Convert to Uint8Array (arrayify equivalent)
*/
arrayify: (data) => data,
/**
* Concatenate byte arrays
*/
concat: (arrays) => {
const totalLength = arrays.reduce((sum, arr) => sum + arr.length, 0);
const result = new Uint8Array(totalLength);
let offset = 0;
for (const arr of arrays) {
result.set(arr, offset);
offset += arr.length;
}
return result;
}
};
/**
* Injective signature format implementations using BytesUtils
* These implement the main branch EthSecp256k1Signature.toCompact() behavior
*/
const compactFormat = (signature) => {
// Split signature into components using BytesUtils
const splitSig = exports.BytesUtils.splitSignature(signature);
// Concatenate r and s components (excluding recovery byte) using BytesUtils
const result = exports.BytesUtils.concat([splitSig.r, splitSig.s]);
// Ensure it's a proper Uint8Array using BytesUtils
return exports.BytesUtils.arrayify(result);
};
const fullFormat = (signature) => {
// For full format, return the signature as-is but ensure it includes recovery byte
if (signature.length === 64) {
// If no recovery byte, we can't create a full signature without additional info
throw new Error('Cannot create full signature format from compact signature without recovery information');
}
return exports.BytesUtils.arrayify(signature);
};
const rawFormat = (signature) => {
// Raw format returns the signature exactly as provided
return exports.BytesUtils.arrayify(signature);
};
/**
* Preset Injective signature format functions mapping
* These implement the InjectiveSignatureFormat enum (COMPACT, FULL, RAW) mentioned in requirements
*/
exports.PRESET_INJECTIVE_SIGNATURE_FORMATS = {
'compact': compactFormat,
'full': fullFormat,
'raw': rawFormat,
};
/**
* Resolve Injective signature format function
* @param formatFn - Format function or string identifier
* @param defaultFn - Default format to use if formatFn is not provided
* @returns Resolved signature format function
*/
function resolveInjectiveSignatureFormat(formatFn, defaultFn) {
if (!formatFn) {
if (!defaultFn)
return undefined;
return resolveInjectiveSignatureFormat(defaultFn);
}
if (typeof formatFn === 'string') {
if (!exports.PRESET_INJECTIVE_SIGNATURE_FORMATS[formatFn]) {
if (defaultFn) {
return resolveInjectiveSignatureFormat(defaultFn);
}
else {
throw new Error(`Unknown Injective signature format: ${formatFn}`);
}
}
return exports.PRESET_INJECTIVE_SIGNATURE_FORMATS[formatFn];
}
return formatFn;
}
/**
* Utility class for processing Injective signatures
* Implements the configurable signature post-processing logic
* that was previously hardcoded in EthSecp256k1Signature.toCompact()
*/
class InjectiveSignatureProcessor {
/**
* Process a signature according to the specified format
* @param signature - Raw signature bytes (typically 65 bytes with recovery)
* @param format - Desired signature format (string or function)
* @returns Processed signature bytes
*/
static processSignature(signature, format) {
// First try to resolve as Injective-specific format
if (typeof format === 'string' && exports.PRESET_INJECTIVE_SIGNATURE_FORMATS[format]) {
const injectiveFormatFn = resolveInjectiveSignatureFormat(format, 'compact');
return injectiveFormatFn ? injectiveFormatFn(signature) : signature;
}
// Fall back to generic signature format resolution
const formatFn = (0, auth_1.resolveSignatureFormat)(format, 'compact');
return formatFn ? formatFn(signature) : signature;
}
/**
* Convert signature to BaseCryptoBytes for use in workflows
* @param signature - Signature bytes
* @param format - Desired signature format
* @returns BaseCryptoBytes instance
*/
static toBaseCryptoBytes(signature, format) {
const processedSignature = this.processSignature(signature, format);
return new utils_1.BaseCryptoBytes(processedSignature);
}
}
exports.InjectiveSignatureProcessor = InjectiveSignatureProcessor;
/**
* Legacy compatibility class that implements the EthSecp256k1Signature interface
* This provides backward compatibility for code that expects the old toCompact() method
*/
class EthSecp256k1Signature {
signature;
constructor(signature) {
this.signature = signature;
}
/**
* Convert signature to compact format
* This method maintains backward compatibility with the original implementation
* @returns Compact signature as BaseCryptoBytes (Key-like object)
*/
toCompact() {
return InjectiveSignatureProcessor.toBaseCryptoBytes(this.signature, 'compact');
}
/**
* Convert signature to full format
* @returns Full signature as BaseCryptoBytes
*/
toFull() {
return InjectiveSignatureProcessor.toBaseCryptoBytes(this.signature, 'full');
}
/**
* Get raw signature
* @returns Raw signature as BaseCryptoBytes
*/
toRaw() {
return InjectiveSignatureProcessor.toBaseCryptoBytes(this.signature, 'raw');
}
/**
* Process signature with configurable format
* @param format - Desired signature format
* @returns Processed signature as BaseCryptoBytes
*/
process(format) {
return InjectiveSignatureProcessor.toBaseCryptoBytes(this.signature, format);
}
}
exports.EthSecp256k1Signature = EthSecp256k1Signature;