[token-js] : JS binding for CreateIdempotent instruction (#3558)
* JS binding for CreateIdempotent instruction * revert * newline * Removed Idempotent flag and extracted Idempotent logic to its own set of functions * Conventions
This commit is contained in:
parent
c84f65c5ff
commit
f61af23932
|
@ -0,0 +1,46 @@
|
|||
import type { ConfirmOptions, Connection, PublicKey, Signer } from '@solana/web3.js';
|
||||
import { sendAndConfirmTransaction, Transaction } from '@solana/web3.js';
|
||||
import { ASSOCIATED_TOKEN_PROGRAM_ID, TOKEN_PROGRAM_ID } from '../constants.js';
|
||||
import { createAssociatedTokenAccountIdempotentInstruction } from '../instructions/associatedTokenAccount.js';
|
||||
import { getAssociatedTokenAddress } from '../state/mint.js';
|
||||
|
||||
/**
|
||||
* Create and initialize a new associated token account
|
||||
* The instruction will succeed even if the associated token account already exists
|
||||
*
|
||||
* @param connection Connection to use
|
||||
* @param payer Payer of the transaction and initialization fees
|
||||
* @param mint Mint for the account
|
||||
* @param owner Owner of the new account
|
||||
* @param confirmOptions Options for confirming the transaction
|
||||
* @param programId SPL Token program account
|
||||
* @param associatedTokenProgramId SPL Associated Token program account
|
||||
*
|
||||
* @return Address of the new or existing associated token account
|
||||
*/
|
||||
export async function createAssociatedTokenAccountIdempotent(
|
||||
connection: Connection,
|
||||
payer: Signer,
|
||||
mint: PublicKey,
|
||||
owner: PublicKey,
|
||||
confirmOptions?: ConfirmOptions,
|
||||
programId = TOKEN_PROGRAM_ID,
|
||||
associatedTokenProgramId = ASSOCIATED_TOKEN_PROGRAM_ID
|
||||
): Promise<PublicKey> {
|
||||
const associatedToken = await getAssociatedTokenAddress(mint, owner, false, programId, associatedTokenProgramId);
|
||||
|
||||
const transaction = new Transaction().add(
|
||||
createAssociatedTokenAccountIdempotentInstruction(
|
||||
payer.publicKey,
|
||||
associatedToken,
|
||||
owner,
|
||||
mint,
|
||||
programId,
|
||||
associatedTokenProgramId
|
||||
)
|
||||
);
|
||||
|
||||
await sendAndConfirmTransaction(connection, transaction, [payer], confirmOptions);
|
||||
|
||||
return associatedToken;
|
||||
}
|
|
@ -6,6 +6,7 @@ export * from './burnChecked.js';
|
|||
export * from './closeAccount.js';
|
||||
export * from './createAccount.js';
|
||||
export * from './createAssociatedTokenAccount.js';
|
||||
export * from './createAssociatedTokenAccountIdempotent.js';
|
||||
export * from './createMint.js';
|
||||
export * from './createMultisig.js';
|
||||
export * from './createNativeMint.js';
|
||||
|
|
|
@ -3,7 +3,7 @@ import { SystemProgram, TransactionInstruction } from '@solana/web3.js';
|
|||
import { ASSOCIATED_TOKEN_PROGRAM_ID, TOKEN_PROGRAM_ID } from '../constants.js';
|
||||
|
||||
/**
|
||||
* Construct an AssociatedTokenAccount instruction
|
||||
* Construct a CreateAssociatedTokenAccount instruction
|
||||
*
|
||||
* @param payer Payer of the initialization fees
|
||||
* @param associatedToken New associated token account
|
||||
|
@ -21,6 +21,57 @@ export function createAssociatedTokenAccountInstruction(
|
|||
mint: PublicKey,
|
||||
programId = TOKEN_PROGRAM_ID,
|
||||
associatedTokenProgramId = ASSOCIATED_TOKEN_PROGRAM_ID
|
||||
): TransactionInstruction {
|
||||
return buildAssociatedTokenAccountInstruction(
|
||||
payer,
|
||||
associatedToken,
|
||||
owner,
|
||||
mint,
|
||||
Buffer.alloc(0),
|
||||
programId,
|
||||
associatedTokenProgramId
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a CreateAssociatedTokenAccountIdempotent instruction
|
||||
*
|
||||
* @param payer Payer of the initialization fees
|
||||
* @param associatedToken New associated token account
|
||||
* @param owner Owner of the new account
|
||||
* @param mint Token mint account
|
||||
* @param programId SPL Token program account
|
||||
* @param associatedTokenProgramId SPL Associated Token program account
|
||||
*
|
||||
* @return Instruction to add to a transaction
|
||||
*/
|
||||
export function createAssociatedTokenAccountIdempotentInstruction(
|
||||
payer: PublicKey,
|
||||
associatedToken: PublicKey,
|
||||
owner: PublicKey,
|
||||
mint: PublicKey,
|
||||
programId = TOKEN_PROGRAM_ID,
|
||||
associatedTokenProgramId = ASSOCIATED_TOKEN_PROGRAM_ID
|
||||
): TransactionInstruction {
|
||||
return buildAssociatedTokenAccountInstruction(
|
||||
payer,
|
||||
associatedToken,
|
||||
owner,
|
||||
mint,
|
||||
Buffer.from([1]),
|
||||
programId,
|
||||
associatedTokenProgramId
|
||||
);
|
||||
}
|
||||
|
||||
function buildAssociatedTokenAccountInstruction(
|
||||
payer: PublicKey,
|
||||
associatedToken: PublicKey,
|
||||
owner: PublicKey,
|
||||
mint: PublicKey,
|
||||
instructionData: Buffer,
|
||||
programId = TOKEN_PROGRAM_ID,
|
||||
associatedTokenProgramId = ASSOCIATED_TOKEN_PROGRAM_ID
|
||||
): TransactionInstruction {
|
||||
const keys = [
|
||||
{ pubkey: payer, isSigner: true, isWritable: true },
|
||||
|
@ -34,6 +85,6 @@ export function createAssociatedTokenAccountInstruction(
|
|||
return new TransactionInstruction({
|
||||
keys,
|
||||
programId: associatedTokenProgramId,
|
||||
data: Buffer.alloc(0),
|
||||
data: instructionData,
|
||||
});
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ import {
|
|||
createMint,
|
||||
getMint,
|
||||
createAccount,
|
||||
createAssociatedTokenAccountIdempotent,
|
||||
getAccount,
|
||||
getAssociatedTokenAddress,
|
||||
} from '../../src';
|
||||
|
@ -142,5 +143,17 @@ describe('createAccount', () => {
|
|||
TEST_PROGRAM_ID
|
||||
)
|
||||
).to.be.rejected;
|
||||
|
||||
// when creating again but with idempotent mode, TX should not throw error
|
||||
return expect(
|
||||
createAssociatedTokenAccountIdempotent(
|
||||
connection,
|
||||
payer,
|
||||
mint,
|
||||
owner.publicKey,
|
||||
undefined,
|
||||
TEST_PROGRAM_ID
|
||||
)
|
||||
).to.be.fulfilled;
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue