diff --git a/modules/sdk-coin-sol/src/lib/explainTransactionWasm.ts b/modules/sdk-coin-sol/src/lib/explainTransactionWasm.ts index efff0d075d..90e2733291 100644 --- a/modules/sdk-coin-sol/src/lib/explainTransactionWasm.ts +++ b/modules/sdk-coin-sol/src/lib/explainTransactionWasm.ts @@ -112,7 +112,11 @@ function deriveTransactionType( // Unknown instructions indicate a custom/unrecognized transaction if (instructions.some((i) => i.type === 'Unknown')) return TransactionType.CustomTx; - return TransactionType.Send; + // Send requires an explicit Transfer or TokenTransfer instruction. + // Everything else is a custom/unrecognized transaction. + if (instructions.some((i) => i.type === 'Transfer' || i.type === 'TokenTransfer')) return TransactionType.Send; + + return TransactionType.CustomTx; } // ============================================================================= diff --git a/modules/sdk-coin-sol/test/unit/explainTransactionWasm.ts b/modules/sdk-coin-sol/test/unit/explainTransactionWasm.ts new file mode 100644 index 0000000000..7b4a644408 --- /dev/null +++ b/modules/sdk-coin-sol/test/unit/explainTransactionWasm.ts @@ -0,0 +1,27 @@ +/** + * Tests for explainTransactionWasm (WASM-based Solana transaction explanation). + */ +import 'should'; +import { explainSolTransaction } from '../../src/lib/explainTransactionWasm'; + +describe('explainTransactionWasm', function () { + describe('deriveTransactionType', function () { + it('should classify boilerplate-only transaction as CustomTx', function () { + // Transaction with only NonceAdvance + Memo instructions (no Transfer or TokenTransfer). + // Previously this would incorrectly fall through to 'Send'. + const BOILERPLATE_ONLY_TX_BASE64 = + 'AgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADE3aDK9nmEccOmQJ4crZzPuTnRVa3woFSjKzE2hcsFbNkpvA8Lnj7CVeJ+/UfXwLI5g223D02m4+REUfPc50QCAgEEB8OpoX+Ybq/j8xi80DhFtj8AUVHPrjhK1E3DnT5Bmx346iUtYQKMMBolIAO6PmfJh3w7huFcYcGNOB8sgXN38Wg6ZrWANNJfb64q8B242qfRiT7dffb80H2OoXGQ0aq0lAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABUpTWpkpIQZNJOhxYNo4fHw1td28kruB5B+oQEEFRI0Gp9UXGMd0yShWY5hpHV62i164o5tLbVxzVVshAAAAAAan1RcZLFaO4IqEX3PSl4jPA1wxRbIas0TYBi6pQAAAEHPqtGYOjjqVfHgg1S32M4qMe2AQO/kDy1+CEYQwkisDAwMCBgEEBAAAAAQCAAUJSGVsbG8gQVBJBAAnQVBJIEludGVncmF0aW9uIHRlc3QgY3VzdG9tIHRyYW5zYWN0aW9u'; + + const explained = explainSolTransaction({ + txBase64: BOILERPLATE_ONLY_TX_BASE64, + feeInfo: { fee: '5000' }, + coinName: 'tsol', + }); + + explained.type.should.equal('CustomTx'); + explained.outputAmount.should.equal('0'); + explained.outputs.length.should.equal(0); + (typeof explained.memo).should.equal('string'); + }); + }); +});