UNPKG

@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.

271 lines (270 loc) 11.3 kB
// System Program Decoder for Solana // Handles SOL transfers, account creation, and other system operations /** * System program instruction types */ export var SystemInstructionType; (function (SystemInstructionType) { SystemInstructionType[SystemInstructionType["CreateAccount"] = 0] = "CreateAccount"; SystemInstructionType[SystemInstructionType["Assign"] = 1] = "Assign"; SystemInstructionType[SystemInstructionType["Transfer"] = 2] = "Transfer"; SystemInstructionType[SystemInstructionType["CreateAccountWithSeed"] = 3] = "CreateAccountWithSeed"; SystemInstructionType[SystemInstructionType["AdvanceNonceAccount"] = 4] = "AdvanceNonceAccount"; SystemInstructionType[SystemInstructionType["WithdrawNonceAccount"] = 5] = "WithdrawNonceAccount"; SystemInstructionType[SystemInstructionType["InitializeNonceAccount"] = 6] = "InitializeNonceAccount"; SystemInstructionType[SystemInstructionType["AuthorizeNonceAccount"] = 7] = "AuthorizeNonceAccount"; SystemInstructionType[SystemInstructionType["Allocate"] = 8] = "Allocate"; SystemInstructionType[SystemInstructionType["AllocateWithSeed"] = 9] = "AllocateWithSeed"; SystemInstructionType[SystemInstructionType["AssignWithSeed"] = 10] = "AssignWithSeed"; SystemInstructionType[SystemInstructionType["TransferWithSeed"] = 11] = "TransferWithSeed"; SystemInstructionType[SystemInstructionType["UpgradeNonceAccount"] = 12] = "UpgradeNonceAccount"; })(SystemInstructionType || (SystemInstructionType = {})); /** * Simple byte reader utility for robust data parsing */ class ByteReader { constructor(data) { this.offset = 0; this.data = data; } /** * Read a 32-bit unsigned integer (little-endian) */ readUint32() { if (this.offset + 4 > this.data.length) { throw new Error(`Cannot read uint32 at offset ${this.offset}, data length: ${this.data.length}`); } const byte0 = this.data[this.offset]; const byte1 = this.data[this.offset + 1]; const byte2 = this.data[this.offset + 2]; const byte3 = this.data[this.offset + 3]; const value = byte0 | (byte1 << 8) | (byte2 << 16) | (byte3 << 24); this.offset += 4; return value >>> 0; // Ensure unsigned } /** * Read a 64-bit unsigned integer (little-endian) as bigint */ readBigUint64() { if (this.offset + 8 > this.data.length) { throw new Error(`Cannot read uint64 at offset ${this.offset}, data length: ${this.data.length}`); } const low = this.data[this.offset] | (this.data[this.offset + 1] << 8) | (this.data[this.offset + 2] << 16) | (this.data[this.offset + 3] << 24); const high = this.data[this.offset + 4] | (this.data[this.offset + 5] << 8) | (this.data[this.offset + 6] << 16) | (this.data[this.offset + 7] << 24); this.offset += 8; return BigInt(low >>> 0) | (BigInt(high >>> 0) << BigInt(32)); } /** * Check if we can read the specified number of bytes */ canRead(bytes) { return this.offset + bytes <= this.data.length; } /** * Get remaining bytes */ remaining() { const result = this.data.length - this.offset; return result; } } /** * Decode system program instruction from raw data */ export function decodeSystemInstruction(data) { if (data.length === 0) { return { type: 'system-unknown', instruction: 'Unknown system instruction', programId: '11111111111111111111111111111111', accounts: [] }; } if (data.length < 4) { return { type: 'system-unknown', instruction: 'Invalid system instruction - too short', programId: '11111111111111111111111111111111', accounts: [] }; } try { const reader = new ByteReader(data); const instructionType = reader.readUint32(); switch (instructionType) { case SystemInstructionType.Transfer: if (reader.canRead(8)) { const lamports = reader.readBigUint64(); return { type: 'system-transfer', instruction: `Transfer ${Number(lamports) / 1e9} SOL`, lamports, programId: '11111111111111111111111111111111', accounts: [] }; } return { type: 'system-transfer-incomplete', instruction: 'Transfer instruction (incomplete data)', programId: '11111111111111111111111111111111', accounts: [] }; case SystemInstructionType.CreateAccount: if (reader.canRead(16)) { // 8 bytes lamports + 8 bytes space const lamports = reader.readBigUint64(); const space = reader.readBigUint64(); return { type: 'system-create-account', instruction: `Create account with ${Number(lamports) / 1e9} SOL and ${space} bytes`, lamports, space, programId: '11111111111111111111111111111111', accounts: [] }; } return { type: 'system-create-account-incomplete', instruction: 'Create account instruction (incomplete data)', programId: '11111111111111111111111111111111', accounts: [] }; case SystemInstructionType.Assign: return { type: 'system-assign', instruction: 'Assign account to program', programId: '11111111111111111111111111111111', accounts: [] }; case SystemInstructionType.Allocate: if (reader.canRead(8)) { const space = reader.readBigUint64(); return { type: 'system-allocate', instruction: `Allocate ${space} bytes`, space, programId: '11111111111111111111111111111111', accounts: [] }; } return { type: 'system-allocate-incomplete', instruction: 'Allocate instruction (incomplete data)', programId: '11111111111111111111111111111111', accounts: [] }; case SystemInstructionType.CreateAccountWithSeed: return { type: 'system-create-account-with-seed', instruction: 'Create account with seed', programId: '11111111111111111111111111111111', accounts: [] }; case SystemInstructionType.TransferWithSeed: if (reader.canRead(8)) { const lamports = reader.readBigUint64(); return { type: 'system-transfer-with-seed', instruction: `Transfer ${Number(lamports) / 1e9} SOL with seed`, lamports, programId: '11111111111111111111111111111111', accounts: [] }; } return { type: 'system-transfer-with-seed-incomplete', instruction: 'Transfer with seed instruction (incomplete data)', programId: '11111111111111111111111111111111', accounts: [] }; case SystemInstructionType.InitializeNonceAccount: return { type: 'system-initialize-nonce', instruction: 'Initialize nonce account', programId: '11111111111111111111111111111111', accounts: [] }; case SystemInstructionType.AdvanceNonceAccount: return { type: 'system-advance-nonce', instruction: 'Advance nonce account', programId: '11111111111111111111111111111111', accounts: [] }; case SystemInstructionType.WithdrawNonceAccount: if (reader.canRead(8)) { const lamports = reader.readBigUint64(); return { type: 'system-withdraw-nonce', instruction: `Withdraw ${Number(lamports) / 1e9} SOL from nonce account`, lamports, programId: '11111111111111111111111111111111', accounts: [] }; } return { type: 'system-withdraw-nonce-incomplete', instruction: 'Withdraw nonce instruction (incomplete data)', programId: '11111111111111111111111111111111', accounts: [] }; case SystemInstructionType.AuthorizeNonceAccount: return { type: 'system-authorize-nonce', instruction: 'Authorize nonce account', programId: '11111111111111111111111111111111', accounts: [] }; case SystemInstructionType.UpgradeNonceAccount: return { type: 'system-upgrade-nonce', instruction: 'Upgrade nonce account', programId: '11111111111111111111111111111111', accounts: [] }; default: return { type: 'system-unknown', instruction: `Unknown system instruction (type: ${instructionType})`, programId: '11111111111111111111111111111111', accounts: [] }; } } catch (error) { return { type: 'system-error', instruction: `Error decoding system instruction: ${error instanceof Error ? error.message : 'Unknown error'}`, programId: '11111111111111111111111111111111', accounts: [] }; } return { type: 'system-unknown', instruction: 'Unknown system instruction', programId: '11111111111111111111111111111111', accounts: [] }; } /** * Helper function to format lamports as SOL */ export function lamportsToSol(lamports) { return (Number(lamports) / 1e9).toFixed(9); } /** * Helper function to format bytes with units */ export function formatBytes(bytes) { const num = Number(bytes); if (num < 1024) return `${num} bytes`; if (num < 1024 * 1024) return `${(num / 1024).toFixed(1)} KB`; return `${(num / (1024 * 1024)).toFixed(1)} MB`; }