@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.
905 lines (904 loc) • 35.9 kB
JavaScript
import { getGorbchainConfig } from '../utils/gorbchainConfig.js';
// Get Token-2022 program ID from config
function getToken2022ProgramId() {
var _a, _b;
const config = getGorbchainConfig();
return (_b = (_a = config.programIds) === null || _a === void 0 ? void 0 : _a.token2022) !== null && _b !== void 0 ? _b : 'FGyzDo6bhE7gFmSYymmFnJ3SZZu3xWGBA7sNHXR7QQsn';
}
// Token-2022 Instruction Types (discriminators)
export var Token2022Instruction;
(function (Token2022Instruction) {
// Standard SPL Token instructions
Token2022Instruction[Token2022Instruction["InitializeMint"] = 0] = "InitializeMint";
Token2022Instruction[Token2022Instruction["InitializeAccount"] = 1] = "InitializeAccount";
Token2022Instruction[Token2022Instruction["InitializeMultisig"] = 2] = "InitializeMultisig";
Token2022Instruction[Token2022Instruction["Transfer"] = 3] = "Transfer";
Token2022Instruction[Token2022Instruction["Approve"] = 4] = "Approve";
Token2022Instruction[Token2022Instruction["Revoke"] = 5] = "Revoke";
Token2022Instruction[Token2022Instruction["SetAuthority"] = 6] = "SetAuthority";
Token2022Instruction[Token2022Instruction["MintTo"] = 7] = "MintTo";
Token2022Instruction[Token2022Instruction["Burn"] = 8] = "Burn";
Token2022Instruction[Token2022Instruction["CloseAccount"] = 9] = "CloseAccount";
Token2022Instruction[Token2022Instruction["FreezeAccount"] = 10] = "FreezeAccount";
Token2022Instruction[Token2022Instruction["ThawAccount"] = 11] = "ThawAccount";
Token2022Instruction[Token2022Instruction["TransferChecked"] = 12] = "TransferChecked";
Token2022Instruction[Token2022Instruction["ApproveChecked"] = 13] = "ApproveChecked";
Token2022Instruction[Token2022Instruction["MintToChecked"] = 14] = "MintToChecked";
Token2022Instruction[Token2022Instruction["BurnChecked"] = 15] = "BurnChecked";
Token2022Instruction[Token2022Instruction["InitializeAccount2"] = 16] = "InitializeAccount2";
Token2022Instruction[Token2022Instruction["SyncNative"] = 17] = "SyncNative";
Token2022Instruction[Token2022Instruction["InitializeAccount3"] = 18] = "InitializeAccount3";
Token2022Instruction[Token2022Instruction["InitializeMultisig2"] = 19] = "InitializeMultisig2";
Token2022Instruction[Token2022Instruction["InitializeMint2"] = 20] = "InitializeMint2";
// Token-2022 specific instructions
Token2022Instruction[Token2022Instruction["GetAccountDataSize"] = 21] = "GetAccountDataSize";
Token2022Instruction[Token2022Instruction["InitializeImmutableOwner"] = 22] = "InitializeImmutableOwner";
Token2022Instruction[Token2022Instruction["AmountToUiAmount"] = 23] = "AmountToUiAmount";
Token2022Instruction[Token2022Instruction["UiAmountToAmount"] = 24] = "UiAmountToAmount";
Token2022Instruction[Token2022Instruction["InitializeMintCloseAuthority"] = 25] = "InitializeMintCloseAuthority";
Token2022Instruction[Token2022Instruction["TransferFeeExtension"] = 26] = "TransferFeeExtension";
Token2022Instruction[Token2022Instruction["ConfidentialTransferExtension"] = 27] = "ConfidentialTransferExtension";
Token2022Instruction[Token2022Instruction["DefaultAccountStateExtension"] = 28] = "DefaultAccountStateExtension";
Token2022Instruction[Token2022Instruction["Reallocate"] = 29] = "Reallocate";
Token2022Instruction[Token2022Instruction["MemoTransferExtension"] = 30] = "MemoTransferExtension";
Token2022Instruction[Token2022Instruction["CreateNativeMint"] = 31] = "CreateNativeMint";
Token2022Instruction[Token2022Instruction["InitializeNonTransferableMint"] = 32] = "InitializeNonTransferableMint";
Token2022Instruction[Token2022Instruction["InterestBearingMintExtension"] = 33] = "InterestBearingMintExtension";
Token2022Instruction[Token2022Instruction["CpiGuardExtension"] = 34] = "CpiGuardExtension";
Token2022Instruction[Token2022Instruction["InitializePermanentDelegate"] = 35] = "InitializePermanentDelegate";
Token2022Instruction[Token2022Instruction["TransferHookExtension"] = 36] = "TransferHookExtension";
Token2022Instruction[Token2022Instruction["ConfidentialTransferFeeExtension"] = 37] = "ConfidentialTransferFeeExtension";
Token2022Instruction[Token2022Instruction["WithdrawExcessLamports"] = 38] = "WithdrawExcessLamports";
Token2022Instruction[Token2022Instruction["MetadataPointerExtension"] = 39] = "MetadataPointerExtension";
// NFT/Metadata instructions (custom extensions)
Token2022Instruction[Token2022Instruction["InitializeNFTMetadata"] = 210] = "InitializeNFTMetadata";
})(Token2022Instruction || (Token2022Instruction = {}));
// Authority Types for Token-2022
export var AuthorityType;
(function (AuthorityType) {
AuthorityType[AuthorityType["MintTokens"] = 0] = "MintTokens";
AuthorityType[AuthorityType["FreezeAccount"] = 1] = "FreezeAccount";
AuthorityType[AuthorityType["AccountOwner"] = 2] = "AccountOwner";
AuthorityType[AuthorityType["CloseAccount"] = 3] = "CloseAccount";
AuthorityType[AuthorityType["TransferFeeConfig"] = 4] = "TransferFeeConfig";
AuthorityType[AuthorityType["WithheldWithdraw"] = 5] = "WithheldWithdraw";
AuthorityType[AuthorityType["CloseMint"] = 6] = "CloseMint";
AuthorityType[AuthorityType["InterestRate"] = 7] = "InterestRate";
AuthorityType[AuthorityType["PermanentDelegate"] = 8] = "PermanentDelegate";
AuthorityType[AuthorityType["ConfidentialTransferMint"] = 9] = "ConfidentialTransferMint";
AuthorityType[AuthorityType["TransferHookProgramId"] = 10] = "TransferHookProgramId";
AuthorityType[AuthorityType["ConfidentialTransferFeeConfig"] = 11] = "ConfidentialTransferFeeConfig";
AuthorityType[AuthorityType["MetadataPointer"] = 12] = "MetadataPointer";
})(AuthorityType || (AuthorityType = {}));
/**
* Main Token-2022 decoder function
*/
export function decodeToken2022Instruction(instruction) {
var _a, _b, _c;
const data = instruction.data;
if (!data || data.length === 0) {
return {
type: 'token2022-generic',
programId: getToken2022ProgramId(),
accounts: instruction.accounts,
data: {
type: 'token2022-generic',
description: 'Token-2022 operation (no instruction data)',
error: 'No instruction data available'
}
};
}
let instructionType;
if (data instanceof Uint8Array) {
instructionType = data[0];
}
else if (typeof data === 'string') {
throw new Error('Invalid Token-2022 instruction: data is string, expected Uint8Array');
}
else if (Array.isArray(data)) {
instructionType = data[0];
}
else {
throw new Error('Invalid Token-2022 instruction: unknown data type');
}
const programId = getToken2022ProgramId();
switch (instructionType) {
case Token2022Instruction.Transfer:
return decodeTransfer(instruction, programId);
case Token2022Instruction.MintTo:
return decodeMintTo(instruction, programId);
case Token2022Instruction.Burn:
return decodeBurn(instruction, programId);
case Token2022Instruction.InitializeMint:
return decodeInitializeMint(instruction, programId);
case Token2022Instruction.InitializeAccount:
return decodeInitializeAccount(instruction, programId);
case Token2022Instruction.SetAuthority:
return decodeSetAuthority(instruction, programId);
case Token2022Instruction.Approve:
return decodeApprove(instruction, programId);
case Token2022Instruction.Revoke:
return decodeRevoke(instruction, programId);
case Token2022Instruction.CloseAccount:
return decodeCloseAccount(instruction, programId);
case Token2022Instruction.FreezeAccount:
return decodeFreezeAccount(instruction, programId);
case Token2022Instruction.ThawAccount:
return decodeThawAccount(instruction, programId);
case Token2022Instruction.TransferChecked:
return decodeTransferChecked(instruction, programId);
case Token2022Instruction.ApproveChecked:
return decodeApproveChecked(instruction, programId);
case Token2022Instruction.MintToChecked:
return decodeMintToChecked(instruction, programId);
case Token2022Instruction.BurnChecked:
return decodeBurnChecked(instruction, programId);
case Token2022Instruction.InitializeMint2:
return decodeInitializeMint2(instruction, programId);
case Token2022Instruction.InitializeAccount2:
return decodeInitializeAccount2(instruction, programId);
case Token2022Instruction.InitializeAccount3:
return decodeInitializeAccount3(instruction, programId);
case Token2022Instruction.SyncNative:
return decodeSyncNative(instruction, programId);
// Token-2022 specific instructions
case Token2022Instruction.GetAccountDataSize:
return decodeGetAccountDataSize(instruction, programId);
case Token2022Instruction.InitializeImmutableOwner:
return decodeInitializeImmutableOwner(instruction, programId);
case Token2022Instruction.AmountToUiAmount:
return decodeAmountToUiAmount(instruction, programId);
case Token2022Instruction.UiAmountToAmount:
return decodeUiAmountToAmount(instruction, programId);
case Token2022Instruction.InitializeMintCloseAuthority:
return decodeInitializeMintCloseAuthority(instruction, programId);
case Token2022Instruction.Reallocate:
return decodeReallocate(instruction, programId);
case Token2022Instruction.CreateNativeMint:
return decodeCreateNativeMint(instruction, programId);
case Token2022Instruction.InitializeNonTransferableMint:
return decodeInitializeNonTransferableMint(instruction, programId);
case Token2022Instruction.WithdrawExcessLamports:
return decodeWithdrawExcessLamports(instruction, programId);
case Token2022Instruction.InitializePermanentDelegate:
return decodeInitializePermanentDelegate(instruction, programId);
// NFT/Metadata instructions
case Token2022Instruction.InitializeNFTMetadata:
return decodeInitializeNFTMetadata(instruction, programId);
// Extended Token-2022 instructions (beyond standard range)
case 219:
return {
type: 'token2022-extension-219',
programId,
data: {
instructionType: 219,
name: 'TokenExtension219',
description: 'Token-2022 extension operation (type 219)',
rawData: Array.from((_a = instruction.data) !== null && _a !== void 0 ? _a : [])
},
accounts: instruction.accounts,
raw: instruction
};
case 232:
return {
type: 'token2022-extension-232',
programId,
data: {
instructionType: 232,
name: 'TokenExtension232',
description: 'Token-2022 extension operation (type 232)',
rawData: Array.from(instruction.data)
},
accounts: instruction.accounts,
raw: instruction
};
default:
return {
type: 'token2022-unknown',
programId,
data: {
instructionType,
name: `UnknownToken2022Instruction${instructionType}`,
description: `Unknown Token-2022 instruction type: ${instructionType}`,
error: `Unknown Token-2022 instruction type: ${instructionType}`,
rawData: Array.from((_b = instruction.data) !== null && _b !== void 0 ? _b : [])
},
accounts: (_c = instruction.accounts) !== null && _c !== void 0 ? _c : [],
raw: instruction
};
}
}
/**
* Enhanced Token-2022 instruction decoder with amount extraction
*/
export function decodeToken2022InstructionWithDetails(data) {
if (data.length === 0) {
return {
type: 'token2022-unknown',
instruction: 'Unknown Token-2022 instruction',
accounts: []
};
}
const instructionType = data[0];
switch (instructionType) {
case 3: // Transfer
if (data.length >= 9) {
const amount = new DataView(data.buffer, data.byteOffset + 1, 8).getBigUint64(0, true);
return {
type: 'token2022-transfer',
instruction: 'Transfer tokens',
amount,
accounts: []
};
}
break;
case 7: // MintTo
if (data.length >= 9) {
const amount = new DataView(data.buffer, data.byteOffset + 1, 8).getBigUint64(0, true);
return {
type: 'token2022-mint-to',
instruction: 'Mint tokens',
amount,
accounts: []
};
}
break;
case 8: // Burn
if (data.length >= 9) {
const amount = new DataView(data.buffer, data.byteOffset + 1, 8).getBigUint64(0, true);
return {
type: 'token2022-burn',
instruction: 'Burn tokens',
amount,
accounts: []
};
}
break;
case 4: // Approve
if (data.length >= 9) {
const amount = new DataView(data.buffer, data.byteOffset + 1, 8).getBigUint64(0, true);
return {
type: 'token2022-approve',
instruction: 'Approve token spending',
amount,
accounts: []
};
}
break;
case 0: // InitializeMint
return {
type: 'token2022-initialize-mint',
instruction: 'Initialize token mint',
accounts: []
};
case 1: // InitializeAccount
return {
type: 'token2022-initialize-account',
instruction: 'Initialize token account',
accounts: []
};
case 22: // InitializeImmutableOwner
return {
type: 'token2022-initialize-immutable-owner',
instruction: 'Initialize immutable owner',
accounts: [],
extensions: ['ImmutableOwner']
};
case 25: // InitializeMintCloseAuthority
return {
type: 'token2022-initialize-mint-close-authority',
instruction: 'Initialize mint close authority',
accounts: [],
extensions: ['MintCloseAuthority']
};
case 32: // InitializeNonTransferableMint
return {
type: 'token2022-initialize-non-transferable-mint',
instruction: 'Initialize non-transferable mint',
accounts: [],
extensions: ['NonTransferable']
};
case 35: // InitializePermanentDelegate
return {
type: 'token2022-initialize-permanent-delegate',
instruction: 'Initialize permanent delegate',
accounts: [],
extensions: ['PermanentDelegate']
};
default:
return {
type: 'token2022-unknown',
instruction: `Unknown Token-2022 instruction (type: ${instructionType})`,
accounts: []
};
}
return {
type: 'token2022-unknown',
instruction: 'Unknown Token-2022 instruction',
accounts: []
};
}
// Standard SPL Token instruction decoders (similar to SPL Token)
function decodeTransfer(instruction, programId) {
var _a;
const data = instruction.data;
if (data.length < 9) {
throw new Error('Invalid Transfer instruction: insufficient data');
}
const amount = readU64LE(data, 1);
return {
type: 'token2022-transfer',
programId,
data: {
amount,
source: instruction.accounts[0],
destination: instruction.accounts[1],
authority: instruction.accounts[2]
},
accounts: (_a = instruction.accounts) !== null && _a !== void 0 ? _a : []
};
}
function decodeMintTo(instruction, programId) {
var _a;
const data = instruction.data;
if (data.length < 9) {
throw new Error('Invalid MintTo instruction: insufficient data');
}
const amount = readU64LE(data, 1);
return {
type: 'token2022-mint-to',
programId,
data: {
amount,
mint: instruction.accounts[0],
destination: instruction.accounts[1],
authority: instruction.accounts[2]
},
accounts: (_a = instruction.accounts) !== null && _a !== void 0 ? _a : []
};
}
function decodeBurn(instruction, programId) {
var _a;
const data = instruction.data;
if (data.length < 9) {
throw new Error('Invalid Burn instruction: insufficient data');
}
const amount = readU64LE(data, 1);
return {
type: 'token2022-burn',
programId,
data: {
amount,
account: instruction.accounts[0],
mint: instruction.accounts[1],
authority: instruction.accounts[2]
},
accounts: (_a = instruction.accounts) !== null && _a !== void 0 ? _a : []
};
}
function decodeInitializeMint(instruction, programId) {
var _a;
const data = instruction.data;
if (data.length < 67) {
throw new Error('Invalid InitializeMint instruction: insufficient data');
}
const decimals = data[1];
const mintAuthority = bufferToBase58(data.slice(2, 34));
const freezeAuthorityPresent = data[34] === 1;
const freezeAuthority = freezeAuthorityPresent ? bufferToBase58(data.slice(35, 67)) : null;
return {
type: 'token2022-initialize-mint',
programId,
data: {
decimals,
mintAuthority,
freezeAuthority,
mint: instruction.accounts[0]
},
accounts: (_a = instruction.accounts) !== null && _a !== void 0 ? _a : []
};
}
function decodeInitializeAccount(instruction, programId) {
var _a;
return {
type: 'token2022-initialize-account',
programId,
data: {
account: instruction.accounts[0],
mint: instruction.accounts[1],
owner: instruction.accounts[2],
rent: instruction.accounts[3]
},
accounts: (_a = instruction.accounts) !== null && _a !== void 0 ? _a : []
};
}
function decodeSetAuthority(instruction, programId) {
var _a;
const data = instruction.data;
if (data.length < 3) {
throw new Error('Invalid SetAuthority instruction: insufficient data');
}
const authorityType = data[1];
const newAuthorityPresent = data[2] === 1;
const newAuthority = newAuthorityPresent ? bufferToBase58(data.slice(3, 35)) : null;
return {
type: 'token2022-set-authority',
programId,
data: {
authorityType: getAuthorityTypeName(authorityType),
newAuthority,
currentAuthority: instruction.accounts[1]
},
accounts: (_a = instruction.accounts) !== null && _a !== void 0 ? _a : []
};
}
function decodeApprove(instruction, programId) {
var _a;
const data = instruction.data;
if (data.length < 9) {
throw new Error('Invalid Approve instruction: insufficient data');
}
const amount = readU64LE(data, 1);
return {
type: 'token2022-approve',
programId,
data: {
amount,
source: instruction.accounts[0],
delegate: instruction.accounts[1],
authority: instruction.accounts[2]
},
accounts: (_a = instruction.accounts) !== null && _a !== void 0 ? _a : []
};
}
function decodeRevoke(instruction, programId) {
var _a;
return {
type: 'token2022-revoke',
programId,
data: {
source: instruction.accounts[0],
authority: instruction.accounts[1]
},
accounts: (_a = instruction.accounts) !== null && _a !== void 0 ? _a : []
};
}
function decodeCloseAccount(instruction, programId) {
var _a;
return {
type: 'token2022-close-account',
programId,
data: {
account: instruction.accounts[0],
destination: instruction.accounts[1],
authority: instruction.accounts[2]
},
accounts: (_a = instruction.accounts) !== null && _a !== void 0 ? _a : []
};
}
function decodeFreezeAccount(instruction, programId) {
var _a;
return {
type: 'token2022-freeze-account',
programId,
data: {
account: instruction.accounts[0],
mint: instruction.accounts[1],
authority: instruction.accounts[2]
},
accounts: (_a = instruction.accounts) !== null && _a !== void 0 ? _a : []
};
}
function decodeThawAccount(instruction, programId) {
var _a;
return {
type: 'token2022-thaw-account',
programId,
data: {
account: instruction.accounts[0],
mint: instruction.accounts[1],
authority: instruction.accounts[2]
},
accounts: (_a = instruction.accounts) !== null && _a !== void 0 ? _a : []
};
}
function decodeTransferChecked(instruction, programId) {
var _a;
const data = instruction.data;
if (data.length < 10) {
throw new Error('Invalid TransferChecked instruction: insufficient data');
}
const amount = readU64LE(data, 1);
const decimals = data[9];
return {
type: 'token2022-transfer-checked',
programId,
data: {
amount,
decimals,
source: instruction.accounts[0],
mint: instruction.accounts[1],
destination: instruction.accounts[2],
authority: instruction.accounts[3]
},
accounts: (_a = instruction.accounts) !== null && _a !== void 0 ? _a : []
};
}
function decodeApproveChecked(instruction, programId) {
var _a;
const data = instruction.data;
if (data.length < 10) {
throw new Error('Invalid ApproveChecked instruction: insufficient data');
}
const amount = readU64LE(data, 1);
const decimals = data[9];
return {
type: 'token2022-approve-checked',
programId,
data: {
amount,
decimals,
source: instruction.accounts[0],
mint: instruction.accounts[1],
delegate: instruction.accounts[2],
authority: instruction.accounts[3]
},
accounts: (_a = instruction.accounts) !== null && _a !== void 0 ? _a : []
};
}
function decodeMintToChecked(instruction, programId) {
var _a;
const data = instruction.data;
if (data.length < 10) {
throw new Error('Invalid MintToChecked instruction: insufficient data');
}
const amount = readU64LE(data, 1);
const decimals = data[9];
return {
type: 'token2022-mint-to-checked',
programId,
data: {
amount,
decimals,
mint: instruction.accounts[0],
destination: instruction.accounts[1],
authority: instruction.accounts[2]
},
accounts: (_a = instruction.accounts) !== null && _a !== void 0 ? _a : []
};
}
function decodeBurnChecked(instruction, programId) {
var _a;
const data = instruction.data;
if (data.length < 10) {
throw new Error('Invalid BurnChecked instruction: insufficient data');
}
const amount = readU64LE(data, 1);
const decimals = data[9];
return {
type: 'token2022-burn-checked',
programId,
data: {
amount,
decimals,
account: instruction.accounts[0],
mint: instruction.accounts[1],
authority: instruction.accounts[2]
},
accounts: (_a = instruction.accounts) !== null && _a !== void 0 ? _a : []
};
}
function decodeInitializeMint2(instruction, programId) {
var _a;
const data = instruction.data;
if (data.length < 35) {
throw new Error('Invalid InitializeMint2 instruction: insufficient data');
}
const decimals = data[1];
const mintAuthority = bufferToBase58(data.slice(2, 34));
const freezeAuthorityPresent = data[34] === 1;
const freezeAuthority = freezeAuthorityPresent ? bufferToBase58(data.slice(35, 67)) : null;
return {
type: 'token2022-initialize-mint2',
programId,
data: {
decimals,
mintAuthority,
freezeAuthority,
mint: instruction.accounts[0]
},
accounts: (_a = instruction.accounts) !== null && _a !== void 0 ? _a : []
};
}
function decodeInitializeAccount2(instruction, programId) {
var _a;
const data = instruction.data;
if (data.length < 33) {
throw new Error('Invalid InitializeAccount2 instruction: insufficient data');
}
const owner = bufferToBase58(data.slice(1, 33));
return {
type: 'token2022-initialize-account2',
programId,
data: {
account: instruction.accounts[0],
mint: instruction.accounts[1],
owner,
rent: instruction.accounts[2]
},
accounts: (_a = instruction.accounts) !== null && _a !== void 0 ? _a : []
};
}
function decodeInitializeAccount3(instruction, programId) {
var _a;
const data = instruction.data;
if (data.length < 33) {
throw new Error('Invalid InitializeAccount3 instruction: insufficient data');
}
const owner = bufferToBase58(data.slice(1, 33));
return {
type: 'token2022-initialize-account3',
programId,
data: {
account: instruction.accounts[0],
mint: instruction.accounts[1],
owner
},
accounts: (_a = instruction.accounts) !== null && _a !== void 0 ? _a : []
};
}
function decodeSyncNative(instruction, programId) {
var _a;
return {
type: 'token2022-sync-native',
programId,
data: {
account: instruction.accounts[0]
},
accounts: (_a = instruction.accounts) !== null && _a !== void 0 ? _a : []
};
}
// Token-2022 specific instruction decoders
function decodeGetAccountDataSize(instruction, programId) {
var _a;
return {
type: 'token2022-get-account-data-size',
programId,
data: {
mint: instruction.accounts[0]
},
accounts: (_a = instruction.accounts) !== null && _a !== void 0 ? _a : []
};
}
function decodeInitializeImmutableOwner(instruction, programId) {
var _a;
return {
type: 'token2022-initialize-immutable-owner',
programId,
data: {
account: instruction.accounts[0],
extension: 'ImmutableOwner'
},
accounts: (_a = instruction.accounts) !== null && _a !== void 0 ? _a : []
};
}
function decodeAmountToUiAmount(instruction, programId) {
var _a;
const data = instruction.data;
if (data.length < 9) {
throw new Error('Invalid AmountToUiAmount instruction: insufficient data');
}
const amount = readU64LE(data, 1);
return {
type: 'token2022-amount-to-ui-amount',
programId,
data: {
amount,
mint: instruction.accounts[0]
},
accounts: (_a = instruction.accounts) !== null && _a !== void 0 ? _a : []
};
}
function decodeUiAmountToAmount(instruction, programId) {
var _a;
const data = instruction.data;
if (data.length < 9) {
throw new Error('Invalid UiAmountToAmount instruction: insufficient data');
}
const uiAmount = readU64LE(data, 1);
return {
type: 'token2022-ui-amount-to-amount',
programId,
data: {
uiAmount,
mint: instruction.accounts[0]
},
accounts: (_a = instruction.accounts) !== null && _a !== void 0 ? _a : []
};
}
function decodeInitializeMintCloseAuthority(instruction, programId) {
var _a;
const data = instruction.data;
if (data.length < 33) {
throw new Error('Invalid InitializeMintCloseAuthority instruction: insufficient data');
}
const closeAuthority = bufferToBase58(data.slice(1, 33));
return {
type: 'token2022-initialize-mint-close-authority',
programId,
data: {
mint: instruction.accounts[0],
closeAuthority,
extension: 'MintCloseAuthority'
},
accounts: (_a = instruction.accounts) !== null && _a !== void 0 ? _a : []
};
}
function decodeReallocate(instruction, programId) {
var _a;
const data = instruction.data;
if (data.length < 9) {
throw new Error('Invalid Reallocate instruction: insufficient data');
}
const extensionTypes = [];
for (let i = 1; i < data.length; i += 2) {
extensionTypes.push(data[i]);
}
return {
type: 'token2022-reallocate',
programId,
data: {
account: instruction.accounts[0],
payer: instruction.accounts[1],
systemProgram: instruction.accounts[2],
extensionTypes
},
accounts: (_a = instruction.accounts) !== null && _a !== void 0 ? _a : []
};
}
function decodeCreateNativeMint(instruction, programId) {
var _a;
return {
type: 'token2022-create-native-mint',
programId,
data: {
payer: instruction.accounts[0],
nativeMint: instruction.accounts[1],
systemProgram: instruction.accounts[2]
},
accounts: (_a = instruction.accounts) !== null && _a !== void 0 ? _a : []
};
}
function decodeInitializeNonTransferableMint(instruction, programId) {
var _a;
return {
type: 'token2022-initialize-non-transferable-mint',
programId,
data: {
mint: instruction.accounts[0],
extension: 'NonTransferable'
},
accounts: (_a = instruction.accounts) !== null && _a !== void 0 ? _a : []
};
}
function decodeWithdrawExcessLamports(instruction, programId) {
var _a;
return {
type: 'token2022-withdraw-excess-lamports',
programId,
data: {
source: instruction.accounts[0],
destination: instruction.accounts[1],
authority: instruction.accounts[2]
},
accounts: (_a = instruction.accounts) !== null && _a !== void 0 ? _a : []
};
}
function decodeInitializePermanentDelegate(instruction, programId) {
var _a;
const data = instruction.data;
if (data.length < 33) {
throw new Error('Invalid InitializePermanentDelegate instruction: insufficient data');
}
const delegate = bufferToBase58(data.slice(1, 33));
return {
type: 'token2022-initialize-permanent-delegate',
programId,
data: {
mint: instruction.accounts[0],
delegate,
extension: 'PermanentDelegate'
},
accounts: (_a = instruction.accounts) !== null && _a !== void 0 ? _a : []
};
}
function decodeInitializeNFTMetadata(instruction, programId) {
var _a, _b;
const data = instruction.data;
try {
// Skip instruction type byte (210) and read metadata fields
let offset = 1;
// Skip some header bytes (appears to be 8 bytes based on the data pattern)
offset += 8;
// Read name length (4 bytes, little-endian)
const nameLength = (data[offset] | (data[offset + 1] << 8) | (data[offset + 2] << 16) | (data[offset + 3] << 24));
offset += 4;
// Read name string
const nameBytes = data.slice(offset, offset + nameLength);
const name = String.fromCharCode(...nameBytes);
offset += nameLength;
// Read symbol length (4 bytes, little-endian)
const symbolLength = (data[offset] | (data[offset + 1] << 8) | (data[offset + 2] << 16) | (data[offset + 3] << 24));
offset += 4;
// Read symbol string
const symbolBytes = data.slice(offset, offset + symbolLength);
const symbol = String.fromCharCode(...symbolBytes);
offset += symbolLength;
// Read URI length (4 bytes, little-endian)
const uriLength = (data[offset] | (data[offset + 1] << 8) | (data[offset + 2] << 16) | (data[offset + 3] << 24));
offset += 4;
// Read URI string
const uriBytes = data.slice(offset, offset + uriLength);
const uri = String.fromCharCode(...uriBytes);
return {
type: 'token2022-initialize-nft-metadata',
programId,
data: {
mint: instruction.accounts[0],
metadata: {
name,
symbol,
uri
},
extension: 'NFTMetadata'
},
accounts: (_a = instruction.accounts) !== null && _a !== void 0 ? _a : []
};
}
catch (error) {
// Failed to parse NFT metadata
return {
type: 'token2022-initialize-nft-metadata-error',
programId,
data: {
mint: instruction.accounts[0],
error: error.message,
rawData: Array.from(data),
extension: 'NFTMetadata'
},
accounts: (_b = instruction.accounts) !== null && _b !== void 0 ? _b : []
};
}
}
// Utility functions
function readU64LE(buffer, offset) {
const bytes = Array.isArray(buffer) ? buffer : Array.from(buffer);
let result = BigInt(0);
for (let i = 0; i < 8; i++) {
result += BigInt(bytes[offset + i]) << BigInt(i * 8);
}
return result.toString();
}
function bufferToBase58(buffer) {
// This is a simplified version - in production, use proper base58 encoding
const bytes = Array.isArray(buffer) ? buffer : Array.from(buffer);
return bytes.map(b => b.toString(16).padStart(2, '0')).join('');
}
function getAuthorityTypeName(type) {
switch (type) {
case AuthorityType.MintTokens: return 'MintTokens';
case AuthorityType.FreezeAccount: return 'FreezeAccount';
case AuthorityType.AccountOwner: return 'AccountOwner';
case AuthorityType.CloseAccount: return 'CloseAccount';
case AuthorityType.TransferFeeConfig: return 'TransferFeeConfig';
case AuthorityType.WithheldWithdraw: return 'WithheldWithdraw';
case AuthorityType.CloseMint: return 'CloseMint';
case AuthorityType.InterestRate: return 'InterestRate';
case AuthorityType.PermanentDelegate: return 'PermanentDelegate';
case AuthorityType.ConfidentialTransferMint: return 'ConfidentialTransferMint';
case AuthorityType.TransferHookProgramId: return 'TransferHookProgramId';
case AuthorityType.ConfidentialTransferFeeConfig: return 'ConfidentialTransferFeeConfig';
case AuthorityType.MetadataPointer: return 'MetadataPointer';
default: return `Unknown (${type})`;
}
}