PHP WebShell
Текущая директория: /opt/BitGoJS/node_modules/@solana/spl-token/src/actions
Просмотр файла: getOrCreateAssociatedTokenAccount.ts
import {
Commitment,
ConfirmOptions,
Connection,
PublicKey,
sendAndConfirmTransaction,
Signer,
Transaction,
} from '@solana/web3.js';
import { ASSOCIATED_TOKEN_PROGRAM_ID, TOKEN_PROGRAM_ID } from '../constants';
import {
TokenAccountNotFoundError,
TokenInvalidAccountOwnerError,
TokenInvalidMintError,
TokenInvalidOwnerError,
} from '../errors';
import { createAssociatedTokenAccountInstruction } from '../instructions/index';
import { Account, getAccount, getAssociatedTokenAddress } from '../state/index';
/**
* Retrieve the associated token account, or create it if it doesn't exist
*
* @param connection Connection to use
* @param payer Payer of the transaction and initialization fees
* @param mint Mint associated with the account to set or verify
* @param owner Owner of the account to set or verify
* @param allowOwnerOffCurve Allow the owner account to be a PDA (Program Derived Address)
* @param commitment Desired level of commitment for querying the state
* @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 associated token account
*/
export async function getOrCreateAssociatedTokenAccount(
connection: Connection,
payer: Signer,
mint: PublicKey,
owner: PublicKey,
allowOwnerOffCurve = false,
commitment?: Commitment,
confirmOptions?: ConfirmOptions,
programId = TOKEN_PROGRAM_ID,
associatedTokenProgramId = ASSOCIATED_TOKEN_PROGRAM_ID
): Promise<Account> {
const associatedToken = await getAssociatedTokenAddress(
mint,
owner,
allowOwnerOffCurve,
programId,
associatedTokenProgramId
);
// This is the optimal logic, considering TX fee, client-side computation, RPC roundtrips and guaranteed idempotent.
// Sadly we can't do this atomically.
let account: Account;
try {
account = await getAccount(connection, associatedToken, commitment, programId);
} catch (error: unknown) {
// TokenAccountNotFoundError can be possible if the associated address has already received some lamports,
// becoming a system account. Assuming program derived addressing is safe, this is the only case for the
// TokenInvalidAccountOwnerError in this code path.
if (error instanceof TokenAccountNotFoundError || error instanceof TokenInvalidAccountOwnerError) {
// As this isn't atomic, it's possible others can create associated accounts meanwhile.
try {
const transaction = new Transaction().add(
createAssociatedTokenAccountInstruction(
payer.publicKey,
associatedToken,
owner,
mint,
programId,
associatedTokenProgramId
)
);
await sendAndConfirmTransaction(connection, transaction, [payer], confirmOptions);
} catch (error: unknown) {
// Ignore all errors; for now there is no API-compatible way to selectively ignore the expected
// instruction error if the associated account exists already.
}
// Now this should always succeed
account = await getAccount(connection, associatedToken, commitment, programId);
} else {
throw error;
}
}
if (!account.mint.equals(mint)) throw new TokenInvalidMintError();
if (!account.owner.equals(owner)) throw new TokenInvalidOwnerError();
return account;
}
Выполнить команду
Для локальной разработки. Не используйте в интернете!