diff --git a/token/js/src/extensions/transferHook/instructions.ts b/token/js/src/extensions/transferHook/instructions.ts index 7ddb96fe37f..1a5ffcfb669 100644 --- a/token/js/src/extensions/transferHook/instructions.ts +++ b/token/js/src/extensions/transferHook/instructions.ts @@ -228,7 +228,9 @@ export function createExecuteInstruction( } /** - * Adds all the extra accounts needed for a transfer hook to an instruction + * Adds all the extra accounts needed for a transfer hook to an instruction. + * + * Note this will modify the instruction passed in. * * @param connection Connection to use * @param instruction The instruction to add accounts to @@ -239,7 +241,6 @@ export function createExecuteInstruction( * @param owner Owner of the source account * @param amount The amount of tokens to transfer * @param commitment Commitment to use - * @returns A new instruction with the extra account metas added */ export async function addExtraAccountMetasForExecute( connection: Connection, @@ -295,8 +296,6 @@ export async function addExtraAccountMetasForExecute( // Add the transfer hook program ID and the validation state account instruction.keys.push({ pubkey: programId, isSigner: false, isWritable: false }); instruction.keys.push({ pubkey: validateStatePubkey, isSigner: false, isWritable: false }); - - return instruction; } /** @@ -327,7 +326,7 @@ export async function createTransferCheckedWithTransferHookInstruction( commitment?: Commitment, programId = TOKEN_PROGRAM_ID ) { - const rawInstruction = createTransferCheckedInstruction( + const instruction = createTransferCheckedInstruction( source, mint, destination, @@ -341,19 +340,21 @@ export async function createTransferCheckedWithTransferHookInstruction( const mintInfo = await getMint(connection, mint, commitment, programId); const transferHook = getTransferHook(mintInfo); - return transferHook - ? addExtraAccountMetasForExecute( - connection, - rawInstruction, - transferHook.programId, - source, - mint, - destination, - owner, - amount, - commitment - ) - : rawInstruction; + if (transferHook) { + await addExtraAccountMetasForExecute( + connection, + instruction, + transferHook.programId, + source, + mint, + destination, + owner, + amount, + commitment + ); + } + + return instruction; } /** @@ -386,7 +387,7 @@ export async function createTransferCheckedWithFeeAndTransferHookInstruction( commitment?: Commitment, programId = TOKEN_PROGRAM_ID ) { - const rawInstruction = createTransferCheckedWithFeeInstruction( + const instruction = createTransferCheckedWithFeeInstruction( source, mint, destination, @@ -401,17 +402,19 @@ export async function createTransferCheckedWithFeeAndTransferHookInstruction( const mintInfo = await getMint(connection, mint, commitment, programId); const transferHook = getTransferHook(mintInfo); - return transferHook - ? addExtraAccountMetasForExecute( - connection, - rawInstruction, - transferHook.programId, - source, - mint, - destination, - owner, - amount, - commitment - ) - : rawInstruction; + if (transferHook) { + await addExtraAccountMetasForExecute( + connection, + instruction, + transferHook.programId, + source, + mint, + destination, + owner, + amount, + commitment + ); + } + + return instruction; } diff --git a/token/js/test/unit/transferHook.test.ts b/token/js/test/unit/transferHook.test.ts index ed198ace78d..7dc3dee30a6 100644 --- a/token/js/test/unit/transferHook.test.ts +++ b/token/js/test/unit/transferHook.test.ts @@ -272,27 +272,31 @@ describe('transferHook', () => { }; } - // prettier-ignore // Mocked validate state if (publicKey.equals(validateStatePubkey)) { - const extraAccountsList: ExtraAccountMetaList = { - count: extraAccounts.length, - extraAccounts, + const extraAccountsList: ExtraAccountMetaList = { + count: extraAccounts.length, + extraAccounts, + }; + const instructionDiscriminator = Buffer.from([ + 105, 37, 101, 197, 75, 251, 102, 26, + ]).readBigUInt64LE(); + const data = Buffer.alloc(8 + 4 + 4 + ExtraAccountMetaLayout.span * extraAccounts.length); + ExtraAccountMetaAccountDataLayout.encode( + { + instructionDiscriminator, + length: 4 + ExtraAccountMetaLayout.span * extraAccounts.length, + extraAccountsList, + }, + data + ); + return { + data, + owner: transferHookProgramId, + executable: false, + lamports: 0, + }; } - const instructionDiscriminator = Buffer.from([105, 37, 101, 197, 75, 251, 102, 26]).readBigUInt64LE(); - const data = Buffer.alloc(8 + 4 + 4 + ExtraAccountMetaLayout.span * extraAccounts.length); - ExtraAccountMetaAccountDataLayout.encode({ - instructionDiscriminator, - length: 4 + ExtraAccountMetaLayout.span * extraAccounts.length, - extraAccountsList, - }, data); - return { - data, - owner: transferHookProgramId, - executable: false, - lamports: 0, - }; - } return { data: Buffer.from([]), @@ -393,7 +397,7 @@ describe('transferHook', () => { ) ).to.be.rejectedWith('Missing required account in instruction'); - const rawInstruction = new TransactionInstruction({ + const instruction = new TransactionInstruction({ keys: [ { pubkey: sourcePubkey, isSigner: false, isWritable: true }, { pubkey: mintPubkey, isSigner: false, isWritable: false }, @@ -403,9 +407,9 @@ describe('transferHook', () => { programId: transferHookProgramId, }); - const hydratedInstruction = await addExtraAccountMetasForExecute( + await addExtraAccountMetasForExecute( connection, - rawInstruction, + instruction, transferHookProgramId, sourcePubkey, mintPubkey, @@ -429,7 +433,7 @@ describe('transferHook', () => { { pubkey: validateStatePubkey, isSigner: false, isWritable: false }, ]; - expect(hydratedInstruction.keys).to.eql(checkMetas); + expect(instruction.keys).to.eql(checkMetas); }); it('can create a transfer instruction with extra metas', async () => {