Skip to content

Commit e6204e5

Browse files
committed
fix(sol): decode Token-2022 unknown data as base64
Decode unknown Token-2022 instruction data as base64 before checking confidential-transfer discriminators.\n\nThis prevents BurnChecked pending approvals from throwing Non-base58 character during transaction explanation.\n\nTicket: CHALO-1512 Session-Id: b8d737f7-739a-42bb-81a7-a9fbaf1ec4a6 Task-Id: 6288c7bd-acc3-46ee-a0bf-b5f2d595384e
1 parent db52e7a commit e6204e5

2 files changed

Lines changed: 16 additions & 2 deletions

File tree

modules/sdk-coin-sol/src/lib/explainTransactionWasm.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import {
99
} from './constants';
1010
import { StakingAuthorizeParams, TransactionExplanation as SolLibTransactionExplanation } from './iface';
1111
import { findTokenName } from './instructionParamsFactory';
12-
import bs58 from 'bs58';
1312

1413
export interface ExplainTransactionWasmOptions {
1514
txBase64: string;
@@ -110,7 +109,7 @@ function isWasmConfidentialTransferInstruction(instr: InstructionParams): boolea
110109
// Token-2022 CT extension: byte 0 = CT_EXT_DISCRIMINATOR, byte 1 ∈ CT_SUB_DISCRIMINATORS
111110
const TOKEN_2022_PROGRAM_ID = 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb';
112111
if (programId === TOKEN_2022_PROGRAM_ID) {
113-
const dataBytes = bs58.decode(instr.data);
112+
const dataBytes = Buffer.from(instr.data, 'base64');
114113
if (dataBytes.length >= 2) {
115114
return dataBytes[0] === CT_EXT_DISCRIMINATOR && CT_SUB_DISCRIMINATORS.has(dataBytes[1]);
116115
}

modules/sdk-coin-sol/test/unit/explainTransactionWasm.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,21 @@ describe('explainTransactionWasm', function () {
4545
explained.tokenEnablements?.[0].tokenName.should.equal('3VDBJWgzRUscjQzzAp52na1dDquExZmD1PkCvH9svGF6');
4646
});
4747

48+
it('should classify a Token-2022 BurnChecked unknown instruction as CustomTx', function () {
49+
// BurnChecked is not decoded by the WASM parser, so it is emitted as Unknown with
50+
// base64-encoded data. This must not throw while checking for confidential transfers.
51+
const TOKEN_2022_BURN_CHECKED_BASE64 =
52+
'AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAIEd4VubrtXALIH766Ipu/Fvh26FyvOPjpBMkYBe3UO30SFN5lu5h+qbiflw3DnoJGsdJ035d0WtazcVkIoE5FhOgk/IBzpsSfv2fKcdhTIHFEQKNBi10zrLtUIacusFNtQBt324e51j94YQl285GzN2rYa/E2DuQ0n/r35KNihi/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEDAwECAAoKQEIPAAAAAAAG';
53+
54+
const explained = explainSolTransaction({
55+
txBase64: TOKEN_2022_BURN_CHECKED_BASE64,
56+
feeInfo: { fee: '5000' },
57+
coinName: 'tsol',
58+
});
59+
60+
explained.type.should.equal('CustomTx');
61+
});
62+
4863
it('should classify token transfer with Token ACL permissionless thaw as Send', function () {
4964
// TokenTransfer (transferChecked, Token-2022) + Token ACL ThawPermissionlessIdempotent for
5065
// the destination ATA. The Unknown thaw instruction previously triggered the CustomTx

0 commit comments

Comments
 (0)