Skip to content

Commit 994eefe

Browse files
committed
fix: Enhance token batch instruction tests
1 parent cd6d019 commit 994eefe

File tree

2 files changed

+132
-1
lines changed

2 files changed

+132
-1
lines changed

app/features/token-batch/lib/__tests__/batch-parser.test.ts

Lines changed: 112 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,17 @@ import { concatBytes, writeU64LE } from '@/app/shared/lib/bytes';
77
import { isTokenBatchInstruction, parseBatchInstruction } from '../batch-parser';
88
import { BATCH_DISCRIMINATOR } from '../const';
99
import { decodeSubInstructionParams } from '../decode-sub-instruction';
10-
import { buildBatchData, makeAccount, makeTransferCheckedData, makeTransferData } from './test-utils';
10+
import {
11+
buildBatchData,
12+
makeAccount,
13+
makeApproveCheckedData,
14+
makeApproveData,
15+
makeBurnCheckedData,
16+
makeMintToCheckedData,
17+
makeSetAuthorityData,
18+
makeTransferCheckedData,
19+
makeTransferData,
20+
} from './test-utils';
1121

1222
describe('isTokenBatchInstruction', () => {
1323
it('should detect batch instruction for Token Program', () => {
@@ -296,4 +306,105 @@ describe('decodeSubInstructionParams', () => {
296306
const data = new Uint8Array([]);
297307
expect(decodeSubInstructionParams('CloseAccount', data, [])).toBeUndefined();
298308
});
309+
310+
it('should decode Approve params', () => {
311+
const data = makeApproveData(500n);
312+
const accounts = [makeAccount(), makeAccount(), makeAccount(false, true)];
313+
314+
const decoded = decodeSubInstructionParams('Approve', data, accounts);
315+
316+
if (!decoded) throw new Error('Expected decoded to be defined');
317+
expect(decoded.fields).toEqual([{ label: 'Amount', value: '500' }]);
318+
expect(decoded.accounts.map(a => a.label)).toEqual(['Source', 'Delegate', 'Owner']);
319+
});
320+
321+
it('should decode ApproveChecked params', () => {
322+
const data = makeApproveCheckedData(2000000n, 6);
323+
const accounts = [makeAccount(), makeAccount(), makeAccount(), makeAccount(false, true)];
324+
325+
const decoded = decodeSubInstructionParams('ApproveChecked', data, accounts);
326+
327+
if (!decoded) throw new Error('Expected decoded to be defined');
328+
expect(decoded.fields).toEqual([
329+
{ label: 'Amount', value: '2' },
330+
{ label: 'Decimals', value: '6' },
331+
]);
332+
expect(decoded.accounts.map(a => a.label)).toEqual(['Source', 'Mint', 'Delegate', 'Owner']);
333+
});
334+
335+
it('should decode MintToChecked params', () => {
336+
const data = makeMintToCheckedData(50000000n, 8);
337+
const accounts = [makeAccount(), makeAccount(), makeAccount(false, true)];
338+
339+
const decoded = decodeSubInstructionParams('MintToChecked', data, accounts);
340+
341+
if (!decoded) throw new Error('Expected decoded to be defined');
342+
expect(decoded.fields).toEqual([
343+
{ label: 'Amount', value: '0.5' },
344+
{ label: 'Decimals', value: '8' },
345+
]);
346+
expect(decoded.accounts.map(a => a.label)).toEqual(['Mint', 'Destination', 'Mint Authority']);
347+
});
348+
349+
it('should decode BurnChecked params', () => {
350+
const data = makeBurnCheckedData(1500000000n, 9);
351+
const accounts = [makeAccount(), makeAccount(), makeAccount(false, true)];
352+
353+
const decoded = decodeSubInstructionParams('BurnChecked', data, accounts);
354+
355+
if (!decoded) throw new Error('Expected decoded to be defined');
356+
expect(decoded.fields).toEqual([
357+
{ label: 'Amount', value: '1.5' },
358+
{ label: 'Decimals', value: '9' },
359+
]);
360+
expect(decoded.accounts.map(a => a.label)).toEqual(['Account', 'Mint', 'Owner/Delegate']);
361+
});
362+
363+
it('should decode SetAuthority with new authority set to None', () => {
364+
const data = makeSetAuthorityData(1);
365+
const accounts = [makeAccount(), makeAccount(false, true)];
366+
367+
const decoded = decodeSubInstructionParams('SetAuthority', data, accounts);
368+
369+
if (!decoded) throw new Error('Expected decoded to be defined');
370+
expect(decoded.fields).toEqual([
371+
{ label: 'Authority Type', value: 'FreezeAccount' },
372+
{ label: 'New Authority', value: '(none)' },
373+
]);
374+
expect(decoded.accounts.map(a => a.label)).toEqual(['Account', 'Current Authority']);
375+
});
376+
377+
it('should decode SetAuthority with new authority set to Some', () => {
378+
const newAuth = Keypair.generate().publicKey;
379+
const data = makeSetAuthorityData(0, newAuth);
380+
const accounts = [makeAccount(), makeAccount(false, true)];
381+
382+
const decoded = decodeSubInstructionParams('SetAuthority', data, accounts);
383+
384+
if (!decoded) throw new Error('Expected decoded to be defined');
385+
expect(decoded.fields).toEqual([
386+
{ label: 'Authority Type', value: 'MintTokens' },
387+
{ label: 'New Authority', value: newAuth.toBase58() },
388+
]);
389+
});
390+
391+
it('should format Transfer amount with decimals when provided', () => {
392+
const data = makeTransferData(1500000n);
393+
const accounts = [makeAccount(), makeAccount(), makeAccount(false, true)];
394+
395+
const decoded = decodeSubInstructionParams('Transfer', data, accounts, 6);
396+
397+
if (!decoded) throw new Error('Expected decoded to be defined');
398+
expect(decoded.fields).toEqual([{ label: 'Amount', value: '1.5' }]);
399+
});
400+
401+
it('should format Approve amount with decimals when provided', () => {
402+
const data = makeApproveData(25000000n);
403+
const accounts = [makeAccount(), makeAccount(), makeAccount(false, true)];
404+
405+
const decoded = decodeSubInstructionParams('Approve', data, accounts, 8);
406+
407+
if (!decoded) throw new Error('Expected decoded to be defined');
408+
expect(decoded.fields).toEqual([{ label: 'Amount', value: '0.25' }]);
409+
});
299410
});

app/features/token-batch/lib/__tests__/test-utils.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,26 @@ export function makeTransferCheckedData(amount: bigint, decimals: number): Uint8
3131
return concatBytes(new Uint8Array([12]), writeU64LE(amount), new Uint8Array([decimals]));
3232
}
3333

34+
export function makeApproveData(amount: bigint): Uint8Array {
35+
return concatBytes(new Uint8Array([4]), writeU64LE(amount));
36+
}
37+
38+
export function makeApproveCheckedData(amount: bigint, decimals: number): Uint8Array {
39+
return concatBytes(new Uint8Array([13]), writeU64LE(amount), new Uint8Array([decimals]));
40+
}
41+
42+
export function makeMintToCheckedData(amount: bigint, decimals: number): Uint8Array {
43+
return concatBytes(new Uint8Array([14]), writeU64LE(amount), new Uint8Array([decimals]));
44+
}
45+
46+
export function makeBurnData(amount: bigint): Uint8Array {
47+
return concatBytes(new Uint8Array([8]), writeU64LE(amount));
48+
}
49+
50+
export function makeBurnCheckedData(amount: bigint, decimals: number): Uint8Array {
51+
return concatBytes(new Uint8Array([15]), writeU64LE(amount), new Uint8Array([decimals]));
52+
}
53+
3454
// SetAuthority: [discriminator(6), authority_type(u8), option_tag(u8), ?new_authority(32)]
3555
export function makeSetAuthorityData(authorityType: number, newAuthority?: PublicKey): Uint8Array {
3656
if (newAuthority) {

0 commit comments

Comments
 (0)