@gorbchain-xyz/chaindecode
Version:
GorbchainSDK V1.3+ - Complete Solana development toolkit with advanced cryptography, messaging, and collaboration features. Build secure applications with blockchain, DeFi, and end-to-end encryption.
169 lines (168 loc) • 5.66 kB
JavaScript
/**
* Central registry for managing blockchain program instruction decoders
*
* This module provides the core functionality for registering, managing,
* and executing instruction decoders for various blockchain programs.
*/
/**
* Registry for managing instruction decoders across multiple programs
*
* The DecoderRegistry maintains a mapping between program IDs and their
* corresponding decoder functions, enabling automatic instruction decoding
* based on the program that created the instruction.
*
* @example
* ```typescript
* const registry = new DecoderRegistry();
*
* // Register a decoder for SPL Token instructions
* registry.register('spl-token', 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',
* (instruction) => ({
* type: 'spl-token-transfer',
* programId: instruction.programId,
* data: { amount: instruction.amount },
* accounts: instruction.accounts
* })
* );
*
* // Decode an instruction
* const decoded = registry.decode(instruction);
* ```
*/
export class DecoderRegistry {
constructor() {
/** Internal map of program names to decoder functions */
this.decoders = new Map();
/** Internal map of program IDs to program names for lookup */
this.programIdToName = new Map();
}
/**
* Register a decoder function for a specific blockchain program
*
* @param programName - Human-readable name for the program
* @param programId - The program's public key address
* @param decoder - Function that decodes instructions for this program
*
* @example
* ```typescript
* registry.register(
* 'my-custom-program',
* 'ProgramId12345...',
* (instruction) => ({
* type: 'custom-action',
* programId: instruction.programId,
* data: parseCustomData(instruction.data),
* accounts: instruction.accounts
* })
* );
* ```
*/
register(programName, programId, decoder) {
this.decoders.set(programName, decoder);
this.programIdToName.set(programId, programName);
}
/**
* Decode an instruction using the appropriate decoder
*/
decode(instruction) {
var _a;
// First map programId to programName
const programName = this.programIdToName.get(instruction.programId);
if (!programName) {
return this.createRawResult(instruction);
}
// Now get the decoder using the program name
const decoder = this.decoders.get(programName);
if (!decoder) {
return this.createRawResult(instruction);
}
try {
const result = decoder(instruction);
return result;
}
catch (error) {
return {
type: 'error',
programId: instruction.programId,
data: {
error: error.message,
originalData: instruction.data
},
accounts: (_a = instruction.accounts) !== null && _a !== void 0 ? _a : [],
raw: instruction
};
}
}
/**
* Check if a decoder is registered for a specific program ID
*
* @param programId - The program's public key address to check
* @returns True if a decoder is registered for this program ID
*
* @example
* ```typescript
* if (registry.hasDecoder('TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA')) {
* console.log('SPL Token decoder is available');
* }
* ```
*/
hasDecoder(programId) {
return this.programIdToName.has(programId);
}
/**
* Get a list of all registered program names
*
* @returns Array of program names that have registered decoders
*
* @example
* ```typescript
* const programs = registry.getRegisteredPrograms();
* console.log('Supported programs:', programs);
* // Output: ['spl-token', 'gorba-token', 'custom-program']
* ```
*/
getRegisteredPrograms() {
return Array.from(this.decoders.keys());
}
createRawResult(instruction) {
var _a, _b, _c;
let data;
// Handle malformed data
if (!instruction.data) {
data = new Uint8Array(0);
}
else if (instruction.data instanceof Uint8Array || Array.isArray(instruction.data)) {
data = instruction.data;
}
else {
// Handle invalid data types
data = new Uint8Array(0);
}
return {
type: 'unknown',
programId: (_b = (_a = instruction.programAddress) === null || _a === void 0 ? void 0 : _a.toString()) !== null && _b !== void 0 ? _b : instruction.programId,
data: {
raw: Array.from(data),
hex: this.toHexString(data)
},
accounts: (_c = instruction.accounts) !== null && _c !== void 0 ? _c : [],
raw: instruction
};
}
createErrorResult(instruction, error) {
var _a, _b, _c;
return {
type: 'error',
programId: (_b = (_a = instruction.programAddress) === null || _a === void 0 ? void 0 : _a.toString()) !== null && _b !== void 0 ? _b : instruction.programId,
data: { error },
accounts: (_c = instruction.accounts) !== null && _c !== void 0 ? _c : [],
raw: instruction
};
}
toHexString(data) {
return Array.from(data).map(b => {
const hex = b.toString(16);
return hex.length === 1 ? `0${hex}` : hex;
}).join('');
}
}