@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.
177 lines (176 loc) • 9.42 kB
JavaScript
/**
* Transaction processing utilities for the GorbchainSDK
*
* This module contains helper functions for processing and analyzing
* blockchain transactions and instructions.
*/
/**
* Get human-readable description for instruction types
*/
export function getInstructionDescription(type, data) {
var _a, _b, _c;
const descriptions = {
'system-transfer': `Transfer ${(data === null || data === void 0 ? void 0 : data.lamports) || 'unknown amount'} lamports`,
'system-create-account': `Create account with ${(data === null || data === void 0 ? void 0 : data.lamports) || 'unknown'} lamports and ${(data === null || data === void 0 ? void 0 : data.space) || 'unknown'} bytes`,
'system-assign': 'Assign account to program',
'system-allocate': `Allocate ${(data === null || data === void 0 ? void 0 : data.space) || 'unknown'} bytes`,
'spl-token-transfer': `Transfer ${(data === null || data === void 0 ? void 0 : data.amount) || 'unknown amount'} tokens`,
'spl-token-mint-to': `Mint ${(data === null || data === void 0 ? void 0 : data.amount) || 'unknown amount'} tokens`,
'spl-token-burn': `Burn ${(data === null || data === void 0 ? void 0 : data.amount) || 'unknown amount'} tokens`,
'spl-token-approve': `Approve ${(data === null || data === void 0 ? void 0 : data.amount) || 'unknown amount'} tokens`,
'spl-token-revoke': 'Revoke token approval',
'spl-token-close-account': 'Close token account',
'spl-token-freeze-account': 'Freeze token account',
'spl-token-thaw-account': 'Thaw token account',
'spl-token-initialize-mint': `Initialize mint with ${(data === null || data === void 0 ? void 0 : data.decimals) || 'unknown'} decimals`,
'spl-token-initialize-account': 'Initialize token account',
'token2022-transfer': `Transfer ${(data === null || data === void 0 ? void 0 : data.amount) || 'unknown amount'} Token-2022 tokens`,
'token2022-mint-to': `Mint ${(data === null || data === void 0 ? void 0 : data.amount) || 'unknown amount'} Token-2022 tokens`,
'token2022-burn': `Burn ${(data === null || data === void 0 ? void 0 : data.amount) || 'unknown amount'} Token-2022 tokens`,
'token2022-initialize-mint': `Initialize Token-2022 mint with ${(data === null || data === void 0 ? void 0 : data.decimals) || 'unknown'} decimals`,
'ata-create': 'Create Associated Token Account',
'nft-create': `Create NFT: ${((_a = data === null || data === void 0 ? void 0 : data.metadata) === null || _a === void 0 ? void 0 : _a.name) || 'Unknown NFT'}`,
'nft-mint': `Mint NFT: ${((_b = data === null || data === void 0 ? void 0 : data.metadata) === null || _b === void 0 ? void 0 : _b.name) || 'Unknown NFT'}`,
'nft-transfer': `Transfer NFT: ${((_c = data === null || data === void 0 ? void 0 : data.metadata) === null || _c === void 0 ? void 0 : _c.name) || 'Unknown NFT'}`
};
return descriptions[type] || `${type} instruction`;
}
/**
* Check if instruction is token-related
*/
export function isTokenRelatedInstruction(type) {
return type.includes('token') || type.includes('mint') || type.includes('burn') ||
type.includes('transfer') || type.includes('approve');
}
/**
* Check if instruction is NFT-related
*/
export function isNftRelatedInstruction(type) {
return type.includes('nft') || type.includes('metadata') || type.includes('edition');
}
/**
* Classify transaction type based on instructions
*/
export function classifyTransactionType(instructions, accountKeys) {
const instructionTypes = instructions.map(inst => inst.type || 'unknown');
// Check for NFT operations
if (instructionTypes.some(type => isNftRelatedInstruction(type))) {
if (instructionTypes.some(type => type.includes('create') || type.includes('mint'))) {
return { type: 'NFT Transaction', subtype: 'NFT Creation' };
}
return { type: 'NFT Transaction', subtype: 'NFT Operation' };
}
// Check for token operations
if (instructionTypes.some(type => isTokenRelatedInstruction(type))) {
if (instructionTypes.some(type => type.includes('mint'))) {
return { type: 'Token Transaction', subtype: 'Token Minting' };
}
if (instructionTypes.some(type => type.includes('transfer'))) {
return { type: 'Token Transaction', subtype: 'Token Transfer' };
}
return { type: 'Token Transaction', subtype: 'Token Operation' };
}
// Check for system operations
if (instructionTypes.some(type => type.includes('system'))) {
if (instructionTypes.some(type => type.includes('transfer'))) {
return { type: 'System Transaction', subtype: 'SOL Transfer' };
}
if (instructionTypes.some(type => type.includes('create'))) {
return { type: 'System Transaction', subtype: 'Account Creation' };
}
return { type: 'System Transaction', subtype: 'System Operation' };
}
return { type: 'Unknown Transaction', subtype: 'Mixed Operations' };
}
/**
* Build simple transaction summary
*/
export function buildSimpleTransactionSummary(simpleInstructions) {
if (simpleInstructions.length === 0) {
return { type: 'Empty Transaction', description: 'No instructions found' };
}
const firstInstruction = simpleInstructions[0];
const instructionCount = simpleInstructions.length;
if (instructionCount === 1) {
return {
type: firstInstruction.action || 'Unknown Action',
description: firstInstruction.description || getInstructionDescription(firstInstruction.action, firstInstruction.data)
};
}
// Multiple instructions - provide a summary
const actions = simpleInstructions.map(inst => inst.action).filter(Boolean);
const uniqueActions = [...new Set(actions)];
if (uniqueActions.length === 1) {
return {
type: `${uniqueActions[0]} (${instructionCount}x)`,
description: `${instructionCount} ${uniqueActions[0]} operations`
};
}
return {
type: 'Complex Transaction',
description: `${instructionCount} operations: ${uniqueActions.slice(0, 3).join(', ')}${uniqueActions.length > 3 ? '...' : ''}`
};
}
/**
* Extract account changes from raw transaction data
*/
export function extractAccountChanges(rawTransaction, simpleInstructions) {
const changes = {};
// Extract SOL transfers from system instructions
const solTransfers = simpleInstructions
.filter(inst => inst.action === 'Transfer SOL')
.map(inst => {
var _a, _b, _c, _d;
return ({
amount: ((_a = inst.data) === null || _a === void 0 ? void 0 : _a.amount) || '0',
from: ((_b = inst.data) === null || _b === void 0 ? void 0 : _b.source) || 'unknown',
to: ((_c = inst.data) === null || _c === void 0 ? void 0 : _c.destination) || 'unknown',
lamports: ((_d = inst.data) === null || _d === void 0 ? void 0 : _d.lamports) || 0
});
});
if (solTransfers.length > 0) {
changes.solTransfers = solTransfers;
}
// Extract token transfers
const tokenTransfers = simpleInstructions
.filter(inst => { var _a, _b; return ((_a = inst.action) === null || _a === void 0 ? void 0 : _a.includes('Transfer')) && ((_b = inst.action) === null || _b === void 0 ? void 0 : _b.includes('Token')); })
.map(inst => {
var _a, _b, _c, _d, _e, _f, _g;
return ({
mint: ((_a = inst.data) === null || _a === void 0 ? void 0 : _a.mint) || 'unknown',
amount: ((_b = inst.data) === null || _b === void 0 ? void 0 : _b.amount) || '0',
from: ((_c = inst.data) === null || _c === void 0 ? void 0 : _c.source) || 'unknown',
to: ((_d = inst.data) === null || _d === void 0 ? void 0 : _d.destination) || 'unknown',
tokenName: (_e = inst.data) === null || _e === void 0 ? void 0 : _e.tokenName,
tokenSymbol: (_f = inst.data) === null || _f === void 0 ? void 0 : _f.tokenSymbol,
decimals: (_g = inst.data) === null || _g === void 0 ? void 0 : _g.decimals
});
});
if (tokenTransfers.length > 0) {
changes.tokenTransfers = tokenTransfers;
}
// Extract created accounts
const createdAccounts = simpleInstructions
.filter(inst => { var _a; return (_a = inst.action) === null || _a === void 0 ? void 0 : _a.includes('Create'); })
.map(inst => { var _a, _b; return ((_a = inst.data) === null || _a === void 0 ? void 0 : _a.newAccount) || ((_b = inst.data) === null || _b === void 0 ? void 0 : _b.account); })
.filter(Boolean);
if (createdAccounts.length > 0) {
changes.accountsCreated = createdAccounts;
}
return Object.keys(changes).length > 0 ? changes : undefined;
}
/**
* Generate a transaction name based on instructions
*/
export function generateTransactionName(instructions) {
if (!instructions || instructions.length === 0) {
return 'Empty Transaction';
}
const firstInstruction = instructions[0];
if (firstInstruction.action) {
return firstInstruction.action;
}
// Fallback to instruction type analysis
const classification = classifyTransactionType(instructions, []);
return classification.subtype || classification.type;
}