Socket
Socket
Sign inDemoInstall

@solana/spl-token

Package Overview
Dependencies
Maintainers
14
Versions
46
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@solana/spl-token - npm Package Compare versions

Comparing version 0.2.0 to 0.3.0

lib/cjs/actions/createNativeMint.js

7

lib/cjs/actions/createAccount.js

@@ -18,2 +18,3 @@ "use strict";

const createAssociatedTokenAccount_1 = require("./createAssociatedTokenAccount");
const extensionType_1 = require("../extensions/extensionType");
/**

@@ -38,7 +39,9 @@ * Create and initialize a new token account

// Otherwise, create the account with the provided keypair and return its public key
const lamports = yield (0, index_2.getMinimumBalanceForRentExemptAccount)(connection);
const mintState = yield (0, index_2.getMint)(connection, mint, confirmOptions === null || confirmOptions === void 0 ? void 0 : confirmOptions.commitment, programId);
const space = (0, extensionType_1.getAccountLenForMint)(mintState);
const lamports = yield connection.getMinimumBalanceForRentExemption(space);
const transaction = new web3_js_1.Transaction().add(web3_js_1.SystemProgram.createAccount({
fromPubkey: payer.publicKey,
newAccountPubkey: keypair.publicKey,
space: index_2.ACCOUNT_SIZE,
space,
lamports,

@@ -45,0 +48,0 @@ programId,

@@ -31,11 +31,11 @@ "use strict";

*/
function createWrappedNativeAccount(connection, payer, owner, amount, keypair, confirmOptions, programId = constants_1.TOKEN_PROGRAM_ID) {
function createWrappedNativeAccount(connection, payer, owner, amount, keypair, confirmOptions, programId = constants_1.TOKEN_PROGRAM_ID, nativeMint = constants_1.NATIVE_MINT) {
return __awaiter(this, void 0, void 0, function* () {
// If the amount provided is explicitly 0 or NaN, just create the account without funding it
if (!amount)
return yield (0, createAccount_1.createAccount)(connection, payer, constants_1.NATIVE_MINT, owner, keypair, confirmOptions, programId);
return yield (0, createAccount_1.createAccount)(connection, payer, nativeMint, owner, keypair, confirmOptions, programId);
// If a keypair isn't provided, create the account at the owner's ATA for the native mint and return its address
if (!keypair) {
const associatedToken = yield (0, index_2.getAssociatedTokenAddress)(constants_1.NATIVE_MINT, owner, false, programId, constants_1.ASSOCIATED_TOKEN_PROGRAM_ID);
const transaction = new web3_js_1.Transaction().add((0, index_1.createAssociatedTokenAccountInstruction)(payer.publicKey, associatedToken, owner, constants_1.NATIVE_MINT, programId, constants_1.ASSOCIATED_TOKEN_PROGRAM_ID), web3_js_1.SystemProgram.transfer({
const associatedToken = yield (0, index_2.getAssociatedTokenAddress)(nativeMint, owner, false, programId, constants_1.ASSOCIATED_TOKEN_PROGRAM_ID);
const transaction = new web3_js_1.Transaction().add((0, index_1.createAssociatedTokenAccountInstruction)(payer.publicKey, associatedToken, owner, nativeMint, programId, constants_1.ASSOCIATED_TOKEN_PROGRAM_ID), web3_js_1.SystemProgram.transfer({
fromPubkey: payer.publicKey,

@@ -60,3 +60,3 @@ toPubkey: associatedToken,

lamports: amount,
}), (0, index_1.createInitializeAccountInstruction)(keypair.publicKey, constants_1.NATIVE_MINT, owner, programId));
}), (0, index_1.createInitializeAccountInstruction)(keypair.publicKey, nativeMint, owner, programId));
yield (0, web3_js_1.sendAndConfirmTransaction)(connection, transaction, [payer, keypair], confirmOptions);

@@ -63,0 +63,0 @@ return keypair.publicKey;

@@ -14,2 +14,3 @@ "use strict";

__exportStar(require("./createMint"), exports);
__exportStar(require("./createNativeMint"), exports);
__exportStar(require("./createAccount"), exports);

@@ -16,0 +17,0 @@ __exportStar(require("./createWrappedNativeAccount"), exports);

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.NATIVE_MINT = exports.ASSOCIATED_TOKEN_PROGRAM_ID = exports.TOKEN_PROGRAM_ID = void 0;
exports.programSupportsExtensions = exports.NATIVE_MINT_2022 = exports.NATIVE_MINT = exports.ASSOCIATED_TOKEN_PROGRAM_ID = exports.TOKEN_2022_PROGRAM_ID = exports.TOKEN_PROGRAM_ID = void 0;
const web3_js_1 = require("@solana/web3.js");
/** Address of the SPL Token program */
exports.TOKEN_PROGRAM_ID = new web3_js_1.PublicKey('TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA');
/** Address of the SPL Token 2022 program */
exports.TOKEN_2022_PROGRAM_ID = new web3_js_1.PublicKey('TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb');
/** Address of the SPL Associated Token Account program */
exports.ASSOCIATED_TOKEN_PROGRAM_ID = new web3_js_1.PublicKey('ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL');
/** Address of the special mint for wrapped native SOL */
/** Address of the special mint for wrapped native SOL in spl-token */
exports.NATIVE_MINT = new web3_js_1.PublicKey('So11111111111111111111111111111111111111112');
/** Address of the special mint for wrapped native SOL in spl-token-2022 */
exports.NATIVE_MINT_2022 = new web3_js_1.PublicKey('9pan9bMn5HatX4EJdBwg9VgCa7Uz5HL8N1m5D3NdXejP');
/** Check that the token program provided is not `Tokenkeg...`, useful when using extensions */
function programSupportsExtensions(programId) {
if (programId === exports.TOKEN_PROGRAM_ID) {
return false;
}
else {
return true;
}
}
exports.programSupportsExtensions = programSupportsExtensions;
//# sourceMappingURL=constants.js.map
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.TokenInvalidInstructionTypeError = exports.TokenInvalidInstructionDataError = exports.TokenInvalidInstructionKeysError = exports.TokenInvalidInstructionProgramError = exports.TokenOwnerOffCurveError = exports.TokenInvalidOwnerError = exports.TokenInvalidMintError = exports.TokenInvalidAccountSizeError = exports.TokenInvalidAccountOwnerError = exports.TokenAccountNotFoundError = exports.TokenError = void 0;
exports.TokenUnsupportedInstructionError = exports.TokenInvalidInstructionTypeError = exports.TokenInvalidInstructionDataError = exports.TokenInvalidInstructionKeysError = exports.TokenInvalidInstructionProgramError = exports.TokenOwnerOffCurveError = exports.TokenInvalidOwnerError = exports.TokenInvalidMintError = exports.TokenInvalidAccountSizeError = exports.TokenInvalidAccountOwnerError = exports.TokenInvalidAccountError = exports.TokenAccountNotFoundError = exports.TokenError = void 0;
/** Base class for errors */

@@ -19,2 +19,10 @@ class TokenError extends Error {

exports.TokenAccountNotFoundError = TokenAccountNotFoundError;
/** Thrown if a program state account is not a valid Account */
class TokenInvalidAccountError extends TokenError {
constructor() {
super(...arguments);
this.name = 'TokenInvalidAccountError';
}
}
exports.TokenInvalidAccountError = TokenInvalidAccountError;
/** Thrown if a program state account is not owned by the expected token program */

@@ -92,2 +100,10 @@ class TokenInvalidAccountOwnerError extends TokenError {

exports.TokenInvalidInstructionTypeError = TokenInvalidInstructionTypeError;
/** Thrown if the program does not support the desired instruction */
class TokenUnsupportedInstructionError extends TokenError {
constructor() {
super(...arguments);
this.name = 'TokenUnsupportedInstructionError';
}
}
exports.TokenUnsupportedInstructionError = TokenUnsupportedInstructionError;
//# sourceMappingURL=errors.js.map

@@ -13,2 +13,3 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
__exportStar(require("./extensions/index"), exports);
__exportStar(require("./instructions/index"), exports);

@@ -15,0 +16,0 @@ __exportStar(require("./state/index"), exports);

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.isSyncNativeInstruction = exports.isBurnCheckedInstruction = exports.isMintToCheckedInstruction = exports.isApproveCheckedInstruction = exports.isTransferCheckedInstruction = exports.isThawAccountInstruction = exports.isFreezeAccountInstruction = exports.isCloseAccountInstruction = exports.isBurnInstruction = exports.isMintToInstruction = exports.isSetAuthorityInstruction = exports.isRevokeInstruction = exports.isApproveInstruction = exports.isTransferInstruction = exports.isInitializeMultisigInstruction = exports.isInitializeAccountInstruction = exports.isInitializeMintInstruction = exports.decodeInstruction = void 0;
exports.isInitializeAccount3Instruction = exports.isSyncNativeInstruction = exports.isInitializeAccount2Instruction = exports.isBurnCheckedInstruction = exports.isMintToCheckedInstruction = exports.isApproveCheckedInstruction = exports.isTransferCheckedInstruction = exports.isThawAccountInstruction = exports.isFreezeAccountInstruction = exports.isCloseAccountInstruction = exports.isBurnInstruction = exports.isMintToInstruction = exports.isSetAuthorityInstruction = exports.isRevokeInstruction = exports.isApproveInstruction = exports.isTransferInstruction = exports.isInitializeMultisigInstruction = exports.isInitializeAccountInstruction = exports.isInitializeMintInstruction = exports.decodeInstruction = void 0;
const buffer_layout_1 = require("@solana/buffer-layout");

@@ -14,2 +14,4 @@ const constants_1 = require("../constants");

const initializeAccount_1 = require("./initializeAccount");
const initializeAccount2_1 = require("./initializeAccount2");
const initializeAccount3_1 = require("./initializeAccount3");
const initializeMint_1 = require("./initializeMint");

@@ -63,5 +65,4 @@ const initializeMultisig_1 = require("./initializeMultisig");

return (0, burnChecked_1.decodeBurnCheckedInstruction)(instruction, programId);
// TODO: implement
if (type === types_1.TokenInstruction.InitializeAccount2)
throw new errors_1.TokenInvalidInstructionTypeError();
return (0, initializeAccount2_1.decodeInitializeAccount2Instruction)(instruction, programId);
if (type === types_1.TokenInstruction.SyncNative)

@@ -71,3 +72,3 @@ return (0, syncNative_1.decodeSyncNativeInstruction)(instruction, programId);

if (type === types_1.TokenInstruction.InitializeAccount3)
throw new errors_1.TokenInvalidInstructionTypeError();
return (0, initializeAccount3_1.decodeInitializeAccount3Instruction)(instruction, programId);
// TODO: implement

@@ -162,9 +163,8 @@ if (type === types_1.TokenInstruction.InitializeMultisig2)

exports.isBurnCheckedInstruction = isBurnCheckedInstruction;
/** TODO: docs, implement */
// export function isInitializeAccount2Instruction(
// decoded: DecodedInstruction
// ): decoded is DecodedInitializeAccount2Instruction {
// return decoded.data.instruction === TokenInstruction.InitializeAccount2;
// }
/** TODO: docs */
function isInitializeAccount2Instruction(decoded) {
return decoded.data.instruction === types_1.TokenInstruction.InitializeAccount2;
}
exports.isInitializeAccount2Instruction = isInitializeAccount2Instruction;
/** TODO: docs */
function isSyncNativeInstruction(decoded) {

@@ -174,9 +174,8 @@ return decoded.data.instruction === types_1.TokenInstruction.SyncNative;

exports.isSyncNativeInstruction = isSyncNativeInstruction;
/** TODO: docs */
function isInitializeAccount3Instruction(decoded) {
return decoded.data.instruction === types_1.TokenInstruction.InitializeAccount3;
}
exports.isInitializeAccount3Instruction = isInitializeAccount3Instruction;
/** TODO: docs, implement */
// export function isInitializeAccount3Instruction(
// decoded: DecodedInstruction
// ): decoded is DecodedInitializeAccount3Instruction {
// return decoded.data.instruction === TokenInstruction.InitializeAccount3;
// }
/** TODO: docs, implement */
// export function isInitializeMultisig2Instruction(

@@ -183,0 +182,0 @@ // decoded: DecodedInstruction

@@ -35,4 +35,9 @@ "use strict";

__exportStar(require("./initializeMint2"), exports); // 20
__exportStar(require("./initializeImmutableOwner"), exports); // 22
__exportStar(require("./initializeMintCloseAuthority"), exports); // 23
__exportStar(require("./reallocate"), exports); // 29
__exportStar(require("./createNativeMint"), exports); // 31
__exportStar(require("./initializeNonTransferableMint"), exports); // 32
__exportStar(require("./decode"), exports);
__exportStar(require("./associatedTokenAccount"), exports);
//# sourceMappingURL=index.js.map
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.decodeInitializeAccount2InstructionUnchecked = exports.decodeInitializeAccount2Instruction = exports.createInitializeAccount2Instruction = exports.initializeAccount2InstructionData = void 0;
const types_1 = require("./types");
const buffer_layout_1 = require("@solana/buffer-layout");
const buffer_layout_utils_1 = require("@solana/buffer-layout-utils");
const web3_js_1 = require("@solana/web3.js");
const constants_1 = require("../constants");
const errors_1 = require("../errors");
exports.initializeAccount2InstructionData = (0, buffer_layout_1.struct)([
(0, buffer_layout_1.u8)('instruction'),
(0, buffer_layout_utils_1.publicKey)('owner'),
]);
/**
* Construct an InitializeAccount2 instruction
*
* @param account New token account
* @param mint Mint account
* @param owner New account's owner/multisignature
* @param programId SPL Token program account
*
* @return Instruction to add to a transaction
*/
function createInitializeAccount2Instruction(account, mint, owner, programId = constants_1.TOKEN_PROGRAM_ID) {
const keys = [
{ pubkey: account, isSigner: false, isWritable: true },
{ pubkey: mint, isSigner: false, isWritable: false },
{ pubkey: web3_js_1.SYSVAR_RENT_PUBKEY, isSigner: false, isWritable: false },
];
const data = Buffer.alloc(exports.initializeAccount2InstructionData.span);
exports.initializeAccount2InstructionData.encode({ instruction: types_1.TokenInstruction.InitializeAccount2, owner }, data);
return new web3_js_1.TransactionInstruction({ keys, programId, data });
}
exports.createInitializeAccount2Instruction = createInitializeAccount2Instruction;
/**
* Decode an InitializeAccount2 instruction and validate it
*
* @param instruction Transaction instruction to decode
* @param programId SPL Token program account
*
* @return Decoded, valid instruction
*/
function decodeInitializeAccount2Instruction(instruction, programId = constants_1.TOKEN_PROGRAM_ID) {
if (!instruction.programId.equals(programId))
throw new errors_1.TokenInvalidInstructionProgramError();
if (instruction.data.length !== exports.initializeAccount2InstructionData.span)
throw new errors_1.TokenInvalidInstructionDataError();
const { keys: { account, mint, rent }, data, } = decodeInitializeAccount2InstructionUnchecked(instruction);
if (data.instruction !== types_1.TokenInstruction.InitializeAccount2)
throw new errors_1.TokenInvalidInstructionTypeError();
if (!account || !mint || !rent)
throw new errors_1.TokenInvalidInstructionKeysError();
// TODO: key checks?
return {
programId,
keys: {
account,
mint,
rent,
},
data,
};
}
exports.decodeInitializeAccount2Instruction = decodeInitializeAccount2Instruction;
/**
* Decode an InitializeAccount2 instruction without validating it
*
* @param instruction Transaction instruction to decode
*
* @return Decoded, non-validated instruction
*/
function decodeInitializeAccount2InstructionUnchecked({ programId, keys: [account, mint, rent], data, }) {
return {
programId,
keys: {
account,
mint,
rent,
},
data: exports.initializeAccount2InstructionData.decode(data),
};
}
exports.decodeInitializeAccount2InstructionUnchecked = decodeInitializeAccount2InstructionUnchecked;
//# sourceMappingURL=initializeAccount2.js.map
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.decodeInitializeAccount3InstructionUnchecked = exports.decodeInitializeAccount3Instruction = exports.createInitializeAccount3Instruction = exports.initializeAccount3InstructionData = void 0;
const types_1 = require("./types");
const buffer_layout_1 = require("@solana/buffer-layout");
const buffer_layout_utils_1 = require("@solana/buffer-layout-utils");
const web3_js_1 = require("@solana/web3.js");
const constants_1 = require("../constants");
const errors_1 = require("../errors");
exports.initializeAccount3InstructionData = (0, buffer_layout_1.struct)([
(0, buffer_layout_1.u8)('instruction'),
(0, buffer_layout_utils_1.publicKey)('owner'),
]);
/**
* Construct an InitializeAccount3 instruction
*
* @param account New token account
* @param mint Mint account
* @param owner New account's owner/multisignature
* @param programId SPL Token program account
*
* @return Instruction to add to a transaction
*/
function createInitializeAccount3Instruction(account, mint, owner, programId = constants_1.TOKEN_PROGRAM_ID) {
const keys = [
{ pubkey: account, isSigner: false, isWritable: true },
{ pubkey: mint, isSigner: false, isWritable: false },
];
const data = Buffer.alloc(exports.initializeAccount3InstructionData.span);
exports.initializeAccount3InstructionData.encode({ instruction: types_1.TokenInstruction.InitializeAccount3, owner }, data);
return new web3_js_1.TransactionInstruction({ keys, programId, data });
}
exports.createInitializeAccount3Instruction = createInitializeAccount3Instruction;
/**
* Decode an InitializeAccount3 instruction and validate it
*
* @param instruction Transaction instruction to decode
* @param programId SPL Token program account
*
* @return Decoded, valid instruction
*/
function decodeInitializeAccount3Instruction(instruction, programId = constants_1.TOKEN_PROGRAM_ID) {
if (!instruction.programId.equals(programId))
throw new errors_1.TokenInvalidInstructionProgramError();
if (instruction.data.length !== exports.initializeAccount3InstructionData.span)
throw new errors_1.TokenInvalidInstructionDataError();
const { keys: { account, mint }, data, } = decodeInitializeAccount3InstructionUnchecked(instruction);
if (data.instruction !== types_1.TokenInstruction.InitializeAccount3)
throw new errors_1.TokenInvalidInstructionTypeError();
if (!account || !mint)
throw new errors_1.TokenInvalidInstructionKeysError();
// TODO: key checks?
return {
programId,
keys: {
account,
mint,
},
data,
};
}
exports.decodeInitializeAccount3Instruction = decodeInitializeAccount3Instruction;
/**
* Decode an InitializeAccount3 instruction without validating it
*
* @param instruction Transaction instruction to decode
*
* @return Decoded, non-validated instruction
*/
function decodeInitializeAccount3InstructionUnchecked({ programId, keys: [account, mint], data, }) {
return {
programId,
keys: {
account,
mint,
},
data: exports.initializeAccount3InstructionData.decode(data),
};
}
exports.decodeInitializeAccount3InstructionUnchecked = decodeInitializeAccount3InstructionUnchecked;
//# sourceMappingURL=initializeAccount3.js.map

@@ -28,3 +28,16 @@ "use strict";

TokenInstruction[TokenInstruction["InitializeMint2"] = 20] = "InitializeMint2";
TokenInstruction[TokenInstruction["GetAccountDataSize"] = 21] = "GetAccountDataSize";
TokenInstruction[TokenInstruction["InitializeImmutableOwner"] = 22] = "InitializeImmutableOwner";
TokenInstruction[TokenInstruction["AmountToUiAmount"] = 23] = "AmountToUiAmount";
TokenInstruction[TokenInstruction["UiAmountToAmount"] = 24] = "UiAmountToAmount";
TokenInstruction[TokenInstruction["InitializeMintCloseAuthority"] = 25] = "InitializeMintCloseAuthority";
TokenInstruction[TokenInstruction["TransferFeeExtension"] = 26] = "TransferFeeExtension";
TokenInstruction[TokenInstruction["ConfidentialTransferExtension"] = 27] = "ConfidentialTransferExtension";
TokenInstruction[TokenInstruction["DefaultAccountStateExtension"] = 28] = "DefaultAccountStateExtension";
TokenInstruction[TokenInstruction["Reallocate"] = 29] = "Reallocate";
TokenInstruction[TokenInstruction["MemoTransferExtension"] = 30] = "MemoTransferExtension";
TokenInstruction[TokenInstruction["CreateNativeMint"] = 31] = "CreateNativeMint";
TokenInstruction[TokenInstruction["InitializeNonTransferableMint"] = 32] = "InitializeNonTransferableMint";
TokenInstruction[TokenInstruction["InterestBearingMintExtension"] = 33] = "InterestBearingMintExtension";
})(TokenInstruction = exports.TokenInstruction || (exports.TokenInstruction = {}));
//# sourceMappingURL=types.js.map

@@ -12,3 +12,3 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.getMinimumBalanceForRentExemptAccount = exports.getAccount = exports.ACCOUNT_SIZE = exports.AccountLayout = exports.AccountState = void 0;
exports.getMinimumBalanceForRentExemptAccountWithExtensions = exports.getMinimumBalanceForRentExemptAccount = exports.getMultipleAccounts = exports.getAccount = exports.ACCOUNT_SIZE = exports.AccountLayout = exports.AccountState = void 0;
const buffer_layout_1 = require("@solana/buffer-layout");

@@ -18,2 +18,5 @@ const buffer_layout_utils_1 = require("@solana/buffer-layout-utils");

const errors_1 = require("../errors");
const multisig_1 = require("./multisig");
const accountType_1 = require("../extensions/accountType");
const extensionType_1 = require("../extensions/extensionType");
/** Token account state as stored by the program */

@@ -55,30 +58,33 @@ var AccountState;

const info = yield connection.getAccountInfo(address, commitment);
if (!info)
throw new errors_1.TokenAccountNotFoundError();
if (!info.owner.equals(programId))
throw new errors_1.TokenInvalidAccountOwnerError();
if (info.data.length != exports.ACCOUNT_SIZE)
throw new errors_1.TokenInvalidAccountSizeError();
const rawAccount = exports.AccountLayout.decode(info.data);
return {
address,
mint: rawAccount.mint,
owner: rawAccount.owner,
amount: rawAccount.amount,
delegate: rawAccount.delegateOption ? rawAccount.delegate : null,
delegatedAmount: rawAccount.delegatedAmount,
isInitialized: rawAccount.state !== AccountState.Uninitialized,
isFrozen: rawAccount.state === AccountState.Frozen,
isNative: !!rawAccount.isNativeOption,
rentExemptReserve: rawAccount.isNativeOption ? rawAccount.isNative : null,
closeAuthority: rawAccount.closeAuthorityOption ? rawAccount.closeAuthority : null,
};
return unpackAccount(info, address, programId);
});
}
exports.getAccount = getAccount;
/** Get the minimum lamport balance for a token account to be rent exempt
/**
* Retrieve information about multiple token accounts in a single RPC call
*
* @param connection Connection to use
* @param addresses Token accounts
* @param commitment Desired level of commitment for querying the state
* @param programId SPL Token program account
*
* @return Token account information
*/
function getMultipleAccounts(connection, addresses, commitment, programId = constants_1.TOKEN_PROGRAM_ID) {
return __awaiter(this, void 0, void 0, function* () {
const infos = yield connection.getMultipleAccountsInfo(addresses, commitment);
const accounts = [];
for (let i = 0; i < infos.length; i++) {
const account = unpackAccount(infos[i], addresses[i], programId);
accounts.push(account);
}
return accounts;
});
}
exports.getMultipleAccounts = getMultipleAccounts;
/** Get the minimum lamport balance for a base token account to be rent exempt
*
* @param connection Connection to use
* @param commitment Desired level of commitment for querying the state
*
* @return Amount of lamports required

@@ -88,6 +94,51 @@ */

return __awaiter(this, void 0, void 0, function* () {
return yield connection.getMinimumBalanceForRentExemption(exports.ACCOUNT_SIZE, commitment);
return yield getMinimumBalanceForRentExemptAccountWithExtensions(connection, [], commitment);
});
}
exports.getMinimumBalanceForRentExemptAccount = getMinimumBalanceForRentExemptAccount;
/** Get the minimum lamport balance for a rent-exempt token account with extensions
*
* @param connection Connection to use
* @param commitment Desired level of commitment for querying the state
*
* @return Amount of lamports required
*/
function getMinimumBalanceForRentExemptAccountWithExtensions(connection, extensions, commitment) {
return __awaiter(this, void 0, void 0, function* () {
const accountLen = (0, extensionType_1.getAccountLen)(extensions);
return yield connection.getMinimumBalanceForRentExemption(accountLen, commitment);
});
}
exports.getMinimumBalanceForRentExemptAccountWithExtensions = getMinimumBalanceForRentExemptAccountWithExtensions;
function unpackAccount(info, address, programId) {
if (!info)
throw new errors_1.TokenAccountNotFoundError();
if (!info.owner.equals(programId))
throw new errors_1.TokenInvalidAccountOwnerError();
if (info.data.length < exports.ACCOUNT_SIZE)
throw new errors_1.TokenInvalidAccountSizeError();
const rawAccount = exports.AccountLayout.decode(info.data.slice(0, exports.ACCOUNT_SIZE));
let tlvData = Buffer.alloc(0);
if (info.data.length > exports.ACCOUNT_SIZE) {
if (info.data.length === multisig_1.MULTISIG_SIZE)
throw new errors_1.TokenInvalidAccountSizeError();
if (info.data[exports.ACCOUNT_SIZE] != accountType_1.AccountType.Account)
throw new errors_1.TokenInvalidAccountError();
tlvData = info.data.slice(exports.ACCOUNT_SIZE + accountType_1.ACCOUNT_TYPE_SIZE);
}
return {
address,
mint: rawAccount.mint,
owner: rawAccount.owner,
amount: rawAccount.amount,
delegate: rawAccount.delegateOption ? rawAccount.delegate : null,
delegatedAmount: rawAccount.delegatedAmount,
isInitialized: rawAccount.state !== AccountState.Uninitialized,
isFrozen: rawAccount.state === AccountState.Frozen,
isNative: !!rawAccount.isNativeOption,
rentExemptReserve: rawAccount.isNativeOption ? rawAccount.isNative : null,
closeAuthority: rawAccount.closeAuthorityOption ? rawAccount.closeAuthority : null,
tlvData,
};
}
//# sourceMappingURL=account.js.map

@@ -12,3 +12,3 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.getAssociatedTokenAddress = exports.getMinimumBalanceForRentExemptMint = exports.getMint = exports.MINT_SIZE = exports.MintLayout = void 0;
exports.getAssociatedTokenAddressSync = exports.getAssociatedTokenAddress = exports.getMinimumBalanceForRentExemptMintWithExtensions = exports.getMinimumBalanceForRentExemptMint = exports.getMint = exports.MINT_SIZE = exports.MintLayout = void 0;
const buffer_layout_1 = require("@solana/buffer-layout");

@@ -19,2 +19,6 @@ const buffer_layout_utils_1 = require("@solana/buffer-layout-utils");

const errors_1 = require("../errors");
const account_1 = require("./account");
const multisig_1 = require("./multisig");
const accountType_1 = require("../extensions/accountType");
const extensionType_1 = require("../extensions/extensionType");
/** Buffer layout for de/serializing a mint */

@@ -49,5 +53,15 @@ exports.MintLayout = (0, buffer_layout_1.struct)([

throw new errors_1.TokenInvalidAccountOwnerError();
if (info.data.length != exports.MINT_SIZE)
if (info.data.length < exports.MINT_SIZE)
throw new errors_1.TokenInvalidAccountSizeError();
const rawMint = exports.MintLayout.decode(info.data);
const rawMint = exports.MintLayout.decode(info.data.slice(0, exports.MINT_SIZE));
let tlvData = Buffer.alloc(0);
if (info.data.length > exports.MINT_SIZE) {
if (info.data.length <= account_1.ACCOUNT_SIZE)
throw new errors_1.TokenInvalidAccountSizeError();
if (info.data.length === multisig_1.MULTISIG_SIZE)
throw new errors_1.TokenInvalidAccountSizeError();
if (info.data[account_1.ACCOUNT_SIZE] != accountType_1.AccountType.Mint)
throw new errors_1.TokenInvalidMintError();
tlvData = info.data.slice(account_1.ACCOUNT_SIZE + accountType_1.ACCOUNT_TYPE_SIZE);
}
return {

@@ -60,2 +74,3 @@ address,

freezeAuthority: rawMint.freezeAuthorityOption ? rawMint.freezeAuthority : null,
tlvData,
};

@@ -74,8 +89,24 @@ });

return __awaiter(this, void 0, void 0, function* () {
return yield connection.getMinimumBalanceForRentExemption(exports.MINT_SIZE, commitment);
return yield getMinimumBalanceForRentExemptMintWithExtensions(connection, [], commitment);
});
}
exports.getMinimumBalanceForRentExemptMint = getMinimumBalanceForRentExemptMint;
/** Get the minimum lamport balance for a rent-exempt mint with extensions
*
* @param connection Connection to use
* @param extensions Extension types included in the mint
* @param commitment Desired level of commitment for querying the state
*
* @return Amount of lamports required
*/
function getMinimumBalanceForRentExemptMintWithExtensions(connection, extensions, commitment) {
return __awaiter(this, void 0, void 0, function* () {
const mintLen = (0, extensionType_1.getMintLen)(extensions);
return yield connection.getMinimumBalanceForRentExemption(mintLen, commitment);
});
}
exports.getMinimumBalanceForRentExemptMintWithExtensions = getMinimumBalanceForRentExemptMintWithExtensions;
/**
* Get the address of the associated token account for a given mint and owner
* Async version of getAssociatedTokenAddressSync
* For backwards compatibility
*

@@ -88,3 +119,3 @@ * @param mint Token mint account

*
* @return Address of the associated token account
* @return Promise containing the address of the associated token account
*/

@@ -100,2 +131,20 @@ function getAssociatedTokenAddress(mint, owner, allowOwnerOffCurve = false, programId = constants_1.TOKEN_PROGRAM_ID, associatedTokenProgramId = constants_1.ASSOCIATED_TOKEN_PROGRAM_ID) {

exports.getAssociatedTokenAddress = getAssociatedTokenAddress;
/**
* Get the address of the associated token account for a given mint and owner
*
* @param mint Token mint account
* @param owner Owner of the new account
* @param allowOwnerOffCurve Allow the owner account to be a PDA (Program Derived Address)
* @param programId SPL Token program account
* @param associatedTokenProgramId SPL Associated Token program account
*
* @return Address of the associated token account
*/
function getAssociatedTokenAddressSync(mint, owner, allowOwnerOffCurve = false, programId = constants_1.TOKEN_PROGRAM_ID, associatedTokenProgramId = constants_1.ASSOCIATED_TOKEN_PROGRAM_ID) {
if (!allowOwnerOffCurve && !web3_js_1.PublicKey.isOnCurve(owner.toBuffer()))
throw new errors_1.TokenOwnerOffCurveError();
const [address] = web3_js_1.PublicKey.findProgramAddressSync([owner.toBuffer(), programId.toBuffer(), mint.toBuffer()], associatedTokenProgramId);
return address;
}
exports.getAssociatedTokenAddressSync = getAssociatedTokenAddressSync;
//# sourceMappingURL=mint.js.map

@@ -15,2 +15,2 @@ import { ConfirmOptions, Connection, Keypair, PublicKey, Signer } from '@solana/web3.js';

*/
export declare function createWrappedNativeAccount(connection: Connection, payer: Signer, owner: PublicKey, amount: number, keypair?: Keypair, confirmOptions?: ConfirmOptions, programId?: PublicKey): Promise<PublicKey>;
export declare function createWrappedNativeAccount(connection: Connection, payer: Signer, owner: PublicKey, amount: number, keypair?: Keypair, confirmOptions?: ConfirmOptions, programId?: PublicKey, nativeMint?: PublicKey): Promise<PublicKey>;
export * from './createMint';
export * from './createNativeMint';
export * from './createAccount';

@@ -3,0 +4,0 @@ export * from './createWrappedNativeAccount';

import { PublicKey } from '@solana/web3.js';
/** Address of the SPL Token program */
export declare const TOKEN_PROGRAM_ID: PublicKey;
/** Address of the SPL Token 2022 program */
export declare const TOKEN_2022_PROGRAM_ID: PublicKey;
/** Address of the SPL Associated Token Account program */
export declare const ASSOCIATED_TOKEN_PROGRAM_ID: PublicKey;
/** Address of the special mint for wrapped native SOL */
/** Address of the special mint for wrapped native SOL in spl-token */
export declare const NATIVE_MINT: PublicKey;
/** Address of the special mint for wrapped native SOL in spl-token-2022 */
export declare const NATIVE_MINT_2022: PublicKey;
/** Check that the token program provided is not `Tokenkeg...`, useful when using extensions */
export declare function programSupportsExtensions(programId: PublicKey): boolean;

@@ -9,2 +9,6 @@ /** Base class for errors */

}
/** Thrown if a program state account is not a valid Account */
export declare class TokenInvalidAccountError extends TokenError {
name: string;
}
/** Thrown if a program state account is not owned by the expected token program */

@@ -46,1 +50,5 @@ export declare class TokenInvalidAccountOwnerError extends TokenError {

}
/** Thrown if the program does not support the desired instruction */
export declare class TokenUnsupportedInstructionError extends TokenError {
name: string;
}

@@ -0,1 +1,2 @@

export * from './extensions/index';
export * from './instructions/index';

@@ -2,0 +3,0 @@ export * from './state/index';

@@ -9,2 +9,4 @@ import { TransactionInstruction } from '@solana/web3.js';

import { DecodedInitializeAccountInstruction } from './initializeAccount';
import { DecodedInitializeAccount2Instruction } from './initializeAccount2';
import { DecodedInitializeAccount3Instruction } from './initializeAccount3';
import { DecodedInitializeMintInstruction } from './initializeMint';

@@ -21,3 +23,3 @@ import { DecodedInitializeMultisigInstruction } from './initializeMultisig';

/** TODO: docs */
export declare type DecodedInstruction = DecodedInitializeMintInstruction | DecodedInitializeAccountInstruction | DecodedInitializeMultisigInstruction | DecodedTransferInstruction | DecodedApproveInstruction | DecodedRevokeInstruction | DecodedSetAuthorityInstruction | DecodedMintToInstruction | DecodedBurnInstruction | DecodedCloseAccountInstruction | DecodedFreezeAccountInstruction | DecodedThawAccountInstruction | DecodedTransferCheckedInstruction | DecodedApproveCheckedInstruction | DecodedMintToCheckedInstruction | DecodedBurnCheckedInstruction | DecodedSyncNativeInstruction | never;
export declare type DecodedInstruction = DecodedInitializeMintInstruction | DecodedInitializeAccountInstruction | DecodedInitializeMultisigInstruction | DecodedTransferInstruction | DecodedApproveInstruction | DecodedRevokeInstruction | DecodedSetAuthorityInstruction | DecodedMintToInstruction | DecodedBurnInstruction | DecodedCloseAccountInstruction | DecodedFreezeAccountInstruction | DecodedThawAccountInstruction | DecodedTransferCheckedInstruction | DecodedApproveCheckedInstruction | DecodedMintToCheckedInstruction | DecodedBurnCheckedInstruction | DecodedInitializeAccount2Instruction | DecodedSyncNativeInstruction | DecodedInitializeAccount3Instruction | never;
/** TODO: docs */

@@ -57,7 +59,9 @@ export declare function decodeInstruction(instruction: TransactionInstruction, programId?: import("@solana/web3.js").PublicKey): DecodedInstruction;

export declare function isBurnCheckedInstruction(decoded: DecodedInstruction): decoded is DecodedBurnCheckedInstruction;
/** TODO: docs, implement */
/** TODO: docs */
export declare function isInitializeAccount2Instruction(decoded: DecodedInstruction): decoded is DecodedInitializeAccount2Instruction;
/** TODO: docs */
export declare function isSyncNativeInstruction(decoded: DecodedInstruction): decoded is DecodedSyncNativeInstruction;
/** TODO: docs */
export declare function isInitializeAccount3Instruction(decoded: DecodedInstruction): decoded is DecodedInitializeAccount3Instruction;
/** TODO: docs, implement */
/** TODO: docs, implement */
/** TODO: docs, implement */

@@ -23,3 +23,8 @@ export * from './types';

export * from './initializeMint2';
export * from './initializeImmutableOwner';
export * from './initializeMintCloseAuthority';
export * from './reallocate';
export * from './createNativeMint';
export * from './initializeNonTransferableMint';
export * from './decode';
export * from './associatedTokenAccount';

@@ -1,1 +0,61 @@

export {};
import { TokenInstruction } from './types';
import { AccountMeta, PublicKey, TransactionInstruction } from '@solana/web3.js';
export interface InitializeAccount2InstructionData {
instruction: TokenInstruction.InitializeAccount2;
owner: PublicKey;
}
export declare const initializeAccount2InstructionData: import("@solana/buffer-layout").Structure<InitializeAccount2InstructionData>;
/**
* Construct an InitializeAccount2 instruction
*
* @param account New token account
* @param mint Mint account
* @param owner New account's owner/multisignature
* @param programId SPL Token program account
*
* @return Instruction to add to a transaction
*/
export declare function createInitializeAccount2Instruction(account: PublicKey, mint: PublicKey, owner: PublicKey, programId?: PublicKey): TransactionInstruction;
/** A decoded, valid InitializeAccount2 instruction */
export interface DecodedInitializeAccount2Instruction {
programId: PublicKey;
keys: {
account: AccountMeta;
mint: AccountMeta;
rent: AccountMeta;
};
data: {
instruction: TokenInstruction.InitializeAccount2;
owner: PublicKey;
};
}
/**
* Decode an InitializeAccount2 instruction and validate it
*
* @param instruction Transaction instruction to decode
* @param programId SPL Token program account
*
* @return Decoded, valid instruction
*/
export declare function decodeInitializeAccount2Instruction(instruction: TransactionInstruction, programId?: PublicKey): DecodedInitializeAccount2Instruction;
/** A decoded, non-validated InitializeAccount2 instruction */
export interface DecodedInitializeAccount2InstructionUnchecked {
programId: PublicKey;
keys: {
account: AccountMeta | undefined;
mint: AccountMeta | undefined;
rent: AccountMeta | undefined;
};
data: {
instruction: number;
owner: PublicKey;
};
}
/**
* Decode an InitializeAccount2 instruction without validating it
*
* @param instruction Transaction instruction to decode
*
* @return Decoded, non-validated instruction
*/
export declare function decodeInitializeAccount2InstructionUnchecked({ programId, keys: [account, mint, rent], data, }: TransactionInstruction): DecodedInitializeAccount2InstructionUnchecked;

@@ -1,1 +0,59 @@

export {};
import { TokenInstruction } from './types';
import { AccountMeta, PublicKey, TransactionInstruction } from '@solana/web3.js';
export interface InitializeAccount3InstructionData {
instruction: TokenInstruction.InitializeAccount3;
owner: PublicKey;
}
export declare const initializeAccount3InstructionData: import("@solana/buffer-layout").Structure<InitializeAccount3InstructionData>;
/**
* Construct an InitializeAccount3 instruction
*
* @param account New token account
* @param mint Mint account
* @param owner New account's owner/multisignature
* @param programId SPL Token program account
*
* @return Instruction to add to a transaction
*/
export declare function createInitializeAccount3Instruction(account: PublicKey, mint: PublicKey, owner: PublicKey, programId?: PublicKey): TransactionInstruction;
/** A decoded, valid InitializeAccount3 instruction */
export interface DecodedInitializeAccount3Instruction {
programId: PublicKey;
keys: {
account: AccountMeta;
mint: AccountMeta;
};
data: {
instruction: TokenInstruction.InitializeAccount3;
owner: PublicKey;
};
}
/**
* Decode an InitializeAccount3 instruction and validate it
*
* @param instruction Transaction instruction to decode
* @param programId SPL Token program account
*
* @return Decoded, valid instruction
*/
export declare function decodeInitializeAccount3Instruction(instruction: TransactionInstruction, programId?: PublicKey): DecodedInitializeAccount3Instruction;
/** A decoded, non-validated InitializeAccount3 instruction */
export interface DecodedInitializeAccount3InstructionUnchecked {
programId: PublicKey;
keys: {
account: AccountMeta | undefined;
mint: AccountMeta | undefined;
};
data: {
instruction: number;
owner: PublicKey;
};
}
/**
* Decode an InitializeAccount3 instruction without validating it
*
* @param instruction Transaction instruction to decode
*
* @return Decoded, non-validated instruction
*/
export declare function decodeInitializeAccount3InstructionUnchecked({ programId, keys: [account, mint], data, }: TransactionInstruction): DecodedInitializeAccount3InstructionUnchecked;

@@ -23,3 +23,16 @@ /** Instructions defined by the program */

InitializeMultisig2 = 19,
InitializeMint2 = 20
InitializeMint2 = 20,
GetAccountDataSize = 21,
InitializeImmutableOwner = 22,
AmountToUiAmount = 23,
UiAmountToAmount = 24,
InitializeMintCloseAuthority = 25,
TransferFeeExtension = 26,
ConfidentialTransferExtension = 27,
DefaultAccountStateExtension = 28,
Reallocate = 29,
MemoTransferExtension = 30,
CreateNativeMint = 31,
InitializeNonTransferableMint = 32,
InterestBearingMintExtension = 33
}

@@ -0,2 +1,4 @@

/// <reference types="node" />
import { Commitment, Connection, PublicKey } from '@solana/web3.js';
import { ExtensionType } from '../extensions/extensionType';
/** Information about a token account */

@@ -29,2 +31,3 @@ export interface Account {

closeAuthority: PublicKey | null;
tlvData: Buffer;
}

@@ -66,9 +69,28 @@ /** Token account state as stored by the program */

export declare function getAccount(connection: Connection, address: PublicKey, commitment?: Commitment, programId?: PublicKey): Promise<Account>;
/** Get the minimum lamport balance for a token account to be rent exempt
/**
* Retrieve information about multiple token accounts in a single RPC call
*
* @param connection Connection to use
* @param addresses Token accounts
* @param commitment Desired level of commitment for querying the state
* @param programId SPL Token program account
*
* @return Token account information
*/
export declare function getMultipleAccounts(connection: Connection, addresses: PublicKey[], commitment?: Commitment, programId?: PublicKey): Promise<Account[]>;
/** Get the minimum lamport balance for a base token account to be rent exempt
*
* @param connection Connection to use
* @param commitment Desired level of commitment for querying the state
*
* @return Amount of lamports required
*/
export declare function getMinimumBalanceForRentExemptAccount(connection: Connection, commitment?: Commitment): Promise<number>;
/** Get the minimum lamport balance for a rent-exempt token account with extensions
*
* @param connection Connection to use
* @param commitment Desired level of commitment for querying the state
*
* @return Amount of lamports required
*/
export declare function getMinimumBalanceForRentExemptAccountWithExtensions(connection: Connection, extensions: ExtensionType[], commitment?: Commitment): Promise<number>;

@@ -0,2 +1,4 @@

/// <reference types="node" />
import { Commitment, Connection, PublicKey } from '@solana/web3.js';
import { ExtensionType } from '../extensions/extensionType';
/** Information about a mint */

@@ -19,2 +21,4 @@ export interface Mint {

freezeAuthority: PublicKey | null;
/** Additional data for extension */
tlvData: Buffer;
}

@@ -54,3 +58,25 @@ /** Mint as stored by the program */

export declare function getMinimumBalanceForRentExemptMint(connection: Connection, commitment?: Commitment): Promise<number>;
/** Get the minimum lamport balance for a rent-exempt mint with extensions
*
* @param connection Connection to use
* @param extensions Extension types included in the mint
* @param commitment Desired level of commitment for querying the state
*
* @return Amount of lamports required
*/
export declare function getMinimumBalanceForRentExemptMintWithExtensions(connection: Connection, extensions: ExtensionType[], commitment?: Commitment): Promise<number>;
/**
* Async version of getAssociatedTokenAddressSync
* For backwards compatibility
*
* @param mint Token mint account
* @param owner Owner of the new account
* @param allowOwnerOffCurve Allow the owner account to be a PDA (Program Derived Address)
* @param programId SPL Token program account
* @param associatedTokenProgramId SPL Associated Token program account
*
* @return Promise containing the address of the associated token account
*/
export declare function getAssociatedTokenAddress(mint: PublicKey, owner: PublicKey, allowOwnerOffCurve?: boolean, programId?: PublicKey, associatedTokenProgramId?: PublicKey): Promise<PublicKey>;
/**
* Get the address of the associated token account for a given mint and owner

@@ -66,2 +92,2 @@ *

*/
export declare function getAssociatedTokenAddress(mint: PublicKey, owner: PublicKey, allowOwnerOffCurve?: boolean, programId?: PublicKey, associatedTokenProgramId?: PublicKey): Promise<PublicKey>;
export declare function getAssociatedTokenAddressSync(mint: PublicKey, owner: PublicKey, allowOwnerOffCurve?: boolean, programId?: PublicKey, associatedTokenProgramId?: PublicKey): PublicKey;
{
"name": "@solana/spl-token",
"version": "0.2.0",
"version": "0.3.0",
"author": "Solana Maintainers <maintainers@solana.foundation>",
"repository": "https://github.com/solana-labs/solana-program-library",
"license": "Apache-2.0",
"engines": {
"node": ">= 14"
},
"publishConfig": {

@@ -34,9 +31,11 @@ "access": "public"

"example": "node --experimental-specifier-resolution=node --loader ts-node/esm examples/create_mint_and_transfer_tokens.ts",
"test": "yarn test:unit && yarn test:e2e-built && yarn test:e2e-native",
"test": "yarn test:unit && yarn test:e2e-built && yarn test:e2e-native && yarn test:e2e-2022",
"test:unit": "mocha test/unit",
"test:e2e-built": "start-server-and-test 'solana-test-validator --bpf-program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA ../../target/deploy/spl_token.so --reset --quiet' http://localhost:8899/health 'mocha test/e2e'",
"test:e2e-2022": "TEST_PROGRAM_ID=TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb start-server-and-test 'solana-test-validator --bpf-program ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL ../../target/deploy/spl_associated_token_account.so --bpf-program TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb ../../target/deploy/spl_token_2022.so --reset --quiet' http://localhost:8899/health 'mocha test/e2e*'",
"test:e2e-native": "start-server-and-test 'solana-test-validator --reset --quiet' http://localhost:8899/health 'mocha test/e2e'",
"test:build-programs": "cargo build-bpf --manifest-path ../program/Cargo.toml && cargo build-bpf --manifest-path ../program-2022/Cargo.toml && cargo build-bpf --manifest-path ../../associated-token-account/program/Cargo.toml",
"docs": "shx rm -rf docs && NODE_OPTIONS=--max_old_space_size=4096 typedoc && shx cp .nojekyll docs/",
"fmt": "prettier --write '{*,**/*}.{js,ts,jsx,tsx,json}'",
"lint": "eslint --ext .ts . && prettier --check '{*,**/*}.{js,ts,jsx,tsx,json}'",
"lint": "eslint --max-warnings 0 --ext .ts . && prettier --check '{*,**/*}.{js,ts,jsx,tsx,json}'",
"lint:fix": "eslint --fix --ext .ts . && yarn fmt",

@@ -48,6 +47,6 @@ "nuke": "shx rm -rf node_modules yarn.lock"

"@solana/buffer-layout-utils": "^0.2.0",
"@solana/web3.js": "^1.32.0",
"start-server-and-test": "^1.14.0"
"@solana/web3.js": "^1.41.0"
},
"devDependencies": {
"@solana/spl-memo": "^0.1.0",
"@types/chai-as-promised": "^7.1.4",

@@ -70,2 +69,3 @@ "@types/eslint": "^8.4.0",

"shx": "^0.3.4",
"start-server-and-test": "^1.14.0",
"ts-node": "^10.4.0",

@@ -72,0 +72,0 @@ "tslib": "^2.3.1",

# `@solana/spl-token`
A TypeScript library for interacting with the SPL Token program.
A TypeScript library for interacting with the SPL Token and Token-2022 programs.

@@ -8,7 +8,19 @@ ## Links

- [TypeScript Docs](https://solana-labs.github.io/solana-program-library/token/js/)
- [FAQ (Frequently Asked Questions)](./FAQ.md)
- [FAQs (Frequently Asked Questions)](#faqs)
- [Install](#install)
- [Usage](#usage)
- [Build from Source](#build-from-source)
## FAQs
### How can I get support?
Please ask questions in the Solana Stack Exchange: https://solana.stackexchange.com/
If you've found a bug or you'd like to request a feature, please
[open an issue](https://github.com/solana-labs/solana-program-library/issues/new).
### No export named Token
Please see [upgrading from 0.1.x](#upgrading-from-0.1.x).
## Install

@@ -42,10 +54,44 @@

5. Run the tests:
5. Build the on-chain programs:
```shell
yarn test:build-programs
```
6. Run the tests:
```shell
yarn test
```
6. Run the example:
7. Run the example:
```shell
yarn example
```
## Upgrading
### Upgrading from 0.2.0
There are no breaking changes from 0.2.0, only new functionality for Token-2022.
### Upgrading from 0.1.x
When upgrading from spl-token 0.1.x, you may see the following error in your code:
```
import {TOKEN_PROGRAM_ID, Token, AccountLayout} from '@solana/spl-token';
^^^^^
SyntaxError: The requested module '@solana/spl-token' does not provide an export named 'Token'
```
The `@solana/spl-token` library as of version 0.2.0 does not have the `Token`
class. Instead the actions are split up and exported separately.
To use the old version, install it with:
```
npm install @solana/spl-token@0.1.8
```
Otherwise you can find documentation on how to use new versions on the
[SPL docs](https://spl.solana.com/token) or
[Solana Cookbook](https://solanacookbook.com/references/token.html).

@@ -13,4 +13,5 @@ import {

import { createInitializeAccountInstruction } from '../instructions/index';
import { ACCOUNT_SIZE, getMinimumBalanceForRentExemptAccount } from '../state/index';
import { getMint } from '../state/index';
import { createAssociatedTokenAccount } from './createAssociatedTokenAccount';
import { getAccountLenForMint } from '../extensions/extensionType';

@@ -43,3 +44,5 @@ /**

// Otherwise, create the account with the provided keypair and return its public key
const lamports = await getMinimumBalanceForRentExemptAccount(connection);
const mintState = await getMint(connection, mint, confirmOptions?.commitment, programId);
const space = getAccountLenForMint(mintState);
const lamports = await connection.getMinimumBalanceForRentExemption(space);

@@ -50,3 +53,3 @@ const transaction = new Transaction().add(

newAccountPubkey: keypair.publicKey,
space: ACCOUNT_SIZE,
space,
lamports,

@@ -53,0 +56,0 @@ programId,

@@ -40,6 +40,7 @@ import {

confirmOptions?: ConfirmOptions,
programId = TOKEN_PROGRAM_ID
programId = TOKEN_PROGRAM_ID,
nativeMint = NATIVE_MINT
): Promise<PublicKey> {
// If the amount provided is explicitly 0 or NaN, just create the account without funding it
if (!amount) return await createAccount(connection, payer, NATIVE_MINT, owner, keypair, confirmOptions, programId);
if (!amount) return await createAccount(connection, payer, nativeMint, owner, keypair, confirmOptions, programId);

@@ -49,3 +50,3 @@ // If a keypair isn't provided, create the account at the owner's ATA for the native mint and return its address

const associatedToken = await getAssociatedTokenAddress(
NATIVE_MINT,
nativeMint,
owner,

@@ -62,3 +63,3 @@ false,

owner,
NATIVE_MINT,
nativeMint,
programId,

@@ -96,3 +97,3 @@ ASSOCIATED_TOKEN_PROGRAM_ID

}),
createInitializeAccountInstruction(keypair.publicKey, NATIVE_MINT, owner, programId)
createInitializeAccountInstruction(keypair.publicKey, nativeMint, owner, programId)
);

@@ -99,0 +100,0 @@

export * from './createMint';
export * from './createNativeMint';
export * from './createAccount';

@@ -3,0 +4,0 @@ export * from './createWrappedNativeAccount';

@@ -6,6 +6,21 @@ import { PublicKey } from '@solana/web3.js';

/** Address of the SPL Token 2022 program */
export const TOKEN_2022_PROGRAM_ID = new PublicKey('TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb');
/** Address of the SPL Associated Token Account program */
export const ASSOCIATED_TOKEN_PROGRAM_ID = new PublicKey('ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL');
/** Address of the special mint for wrapped native SOL */
/** Address of the special mint for wrapped native SOL in spl-token */
export const NATIVE_MINT = new PublicKey('So11111111111111111111111111111111111111112');
/** Address of the special mint for wrapped native SOL in spl-token-2022 */
export const NATIVE_MINT_2022 = new PublicKey('9pan9bMn5HatX4EJdBwg9VgCa7Uz5HL8N1m5D3NdXejP');
/** Check that the token program provided is not `Tokenkeg...`, useful when using extensions */
export function programSupportsExtensions(programId: PublicKey): boolean {
if (programId === TOKEN_PROGRAM_ID) {
return false;
} else {
return true;
}
}

@@ -13,2 +13,7 @@ /** Base class for errors */

/** Thrown if a program state account is not a valid Account */
export class TokenInvalidAccountError extends TokenError {
name = 'TokenInvalidAccountError';
}
/** Thrown if a program state account is not owned by the expected token program */

@@ -58,1 +63,6 @@ export class TokenInvalidAccountOwnerError extends TokenError {

}
/** Thrown if the program does not support the desired instruction */
export class TokenUnsupportedInstructionError extends TokenError {
name = 'TokenUnsupportedInstructionError';
}

@@ -0,1 +1,2 @@

export * from './extensions/index';
export * from './instructions/index';

@@ -2,0 +3,0 @@ export * from './state/index';

@@ -12,2 +12,4 @@ import { u8 } from '@solana/buffer-layout';

import { DecodedInitializeAccountInstruction, decodeInitializeAccountInstruction } from './initializeAccount';
import { DecodedInitializeAccount2Instruction, decodeInitializeAccount2Instruction } from './initializeAccount2';
import { DecodedInitializeAccount3Instruction, decodeInitializeAccount3Instruction } from './initializeAccount3';
import { DecodedInitializeMintInstruction, decodeInitializeMintInstruction } from './initializeMint';

@@ -43,5 +45,5 @@ import { DecodedInitializeMultisigInstruction, decodeInitializeMultisigInstruction } from './initializeMultisig';

| DecodedBurnCheckedInstruction
// | DecodedInitializeAccount2Instruction
| DecodedInitializeAccount2Instruction
| DecodedSyncNativeInstruction
// | DecodedInitializeAccount3Instruction
| DecodedInitializeAccount3Instruction
// | DecodedInitializeMultisig2Instruction

@@ -77,7 +79,8 @@ // | DecodedInitializeMint2Instruction

if (type === TokenInstruction.BurnChecked) return decodeBurnCheckedInstruction(instruction, programId);
// TODO: implement
if (type === TokenInstruction.InitializeAccount2) throw new TokenInvalidInstructionTypeError();
if (type === TokenInstruction.InitializeAccount2)
return decodeInitializeAccount2Instruction(instruction, programId);
if (type === TokenInstruction.SyncNative) return decodeSyncNativeInstruction(instruction, programId);
// TODO: implement
if (type === TokenInstruction.InitializeAccount3) throw new TokenInvalidInstructionTypeError();
if (type === TokenInstruction.InitializeAccount3)
return decodeInitializeAccount3Instruction(instruction, programId);
// TODO: implement

@@ -177,8 +180,8 @@ if (type === TokenInstruction.InitializeMultisig2) throw new TokenInvalidInstructionTypeError();

/** TODO: docs, implement */
// export function isInitializeAccount2Instruction(
// decoded: DecodedInstruction
// ): decoded is DecodedInitializeAccount2Instruction {
// return decoded.data.instruction === TokenInstruction.InitializeAccount2;
// }
/** TODO: docs */
export function isInitializeAccount2Instruction(
decoded: DecodedInstruction
): decoded is DecodedInitializeAccount2Instruction {
return decoded.data.instruction === TokenInstruction.InitializeAccount2;
}

@@ -190,8 +193,8 @@ /** TODO: docs */

/** TODO: docs, implement */
// export function isInitializeAccount3Instruction(
// decoded: DecodedInstruction
// ): decoded is DecodedInitializeAccount3Instruction {
// return decoded.data.instruction === TokenInstruction.InitializeAccount3;
// }
/** TODO: docs */
export function isInitializeAccount3Instruction(
decoded: DecodedInstruction
): decoded is DecodedInitializeAccount3Instruction {
return decoded.data.instruction === TokenInstruction.InitializeAccount3;
}

@@ -198,0 +201,0 @@ /** TODO: docs, implement */

@@ -24,2 +24,7 @@ export * from './types';

export * from './initializeMint2'; // 20
export * from './initializeImmutableOwner'; // 22
export * from './initializeMintCloseAuthority'; // 23
export * from './reallocate'; // 29
export * from './createNativeMint'; // 31
export * from './initializeNonTransferableMint'; // 32

@@ -26,0 +31,0 @@ export * from './decode';

@@ -1,1 +0,134 @@

export {}; // TODO: implement
import { TokenInstruction } from './types';
import { struct, u8 } from '@solana/buffer-layout';
import { publicKey } from '@solana/buffer-layout-utils';
import { AccountMeta, PublicKey, SYSVAR_RENT_PUBKEY, TransactionInstruction } from '@solana/web3.js';
import { TOKEN_PROGRAM_ID } from '../constants';
import {
TokenInvalidInstructionDataError,
TokenInvalidInstructionKeysError,
TokenInvalidInstructionProgramError,
TokenInvalidInstructionTypeError,
} from '../errors';
export interface InitializeAccount2InstructionData {
instruction: TokenInstruction.InitializeAccount2;
owner: PublicKey;
}
export const initializeAccount2InstructionData = struct<InitializeAccount2InstructionData>([
u8('instruction'),
publicKey('owner'),
]);
/**
* Construct an InitializeAccount2 instruction
*
* @param account New token account
* @param mint Mint account
* @param owner New account's owner/multisignature
* @param programId SPL Token program account
*
* @return Instruction to add to a transaction
*/
export function createInitializeAccount2Instruction(
account: PublicKey,
mint: PublicKey,
owner: PublicKey,
programId = TOKEN_PROGRAM_ID
): TransactionInstruction {
const keys = [
{ pubkey: account, isSigner: false, isWritable: true },
{ pubkey: mint, isSigner: false, isWritable: false },
{ pubkey: SYSVAR_RENT_PUBKEY, isSigner: false, isWritable: false },
];
const data = Buffer.alloc(initializeAccount2InstructionData.span);
initializeAccount2InstructionData.encode({ instruction: TokenInstruction.InitializeAccount2, owner }, data);
return new TransactionInstruction({ keys, programId, data });
}
/** A decoded, valid InitializeAccount2 instruction */
export interface DecodedInitializeAccount2Instruction {
programId: PublicKey;
keys: {
account: AccountMeta;
mint: AccountMeta;
rent: AccountMeta;
};
data: {
instruction: TokenInstruction.InitializeAccount2;
owner: PublicKey;
};
}
/**
* Decode an InitializeAccount2 instruction and validate it
*
* @param instruction Transaction instruction to decode
* @param programId SPL Token program account
*
* @return Decoded, valid instruction
*/
export function decodeInitializeAccount2Instruction(
instruction: TransactionInstruction,
programId = TOKEN_PROGRAM_ID
): DecodedInitializeAccount2Instruction {
if (!instruction.programId.equals(programId)) throw new TokenInvalidInstructionProgramError();
if (instruction.data.length !== initializeAccount2InstructionData.span)
throw new TokenInvalidInstructionDataError();
const {
keys: { account, mint, rent },
data,
} = decodeInitializeAccount2InstructionUnchecked(instruction);
if (data.instruction !== TokenInstruction.InitializeAccount2) throw new TokenInvalidInstructionTypeError();
if (!account || !mint || !rent) throw new TokenInvalidInstructionKeysError();
// TODO: key checks?
return {
programId,
keys: {
account,
mint,
rent,
},
data,
};
}
/** A decoded, non-validated InitializeAccount2 instruction */
export interface DecodedInitializeAccount2InstructionUnchecked {
programId: PublicKey;
keys: {
account: AccountMeta | undefined;
mint: AccountMeta | undefined;
rent: AccountMeta | undefined;
};
data: {
instruction: number;
owner: PublicKey;
};
}
/**
* Decode an InitializeAccount2 instruction without validating it
*
* @param instruction Transaction instruction to decode
*
* @return Decoded, non-validated instruction
*/
export function decodeInitializeAccount2InstructionUnchecked({
programId,
keys: [account, mint, rent],
data,
}: TransactionInstruction): DecodedInitializeAccount2InstructionUnchecked {
return {
programId,
keys: {
account,
mint,
rent,
},
data: initializeAccount2InstructionData.decode(data),
};
}

@@ -1,1 +0,129 @@

export {}; // TODO: implement
import { TokenInstruction } from './types';
import { struct, u8 } from '@solana/buffer-layout';
import { publicKey } from '@solana/buffer-layout-utils';
import { AccountMeta, PublicKey, TransactionInstruction } from '@solana/web3.js';
import { TOKEN_PROGRAM_ID } from '../constants';
import {
TokenInvalidInstructionDataError,
TokenInvalidInstructionKeysError,
TokenInvalidInstructionProgramError,
TokenInvalidInstructionTypeError,
} from '../errors';
export interface InitializeAccount3InstructionData {
instruction: TokenInstruction.InitializeAccount3;
owner: PublicKey;
}
export const initializeAccount3InstructionData = struct<InitializeAccount3InstructionData>([
u8('instruction'),
publicKey('owner'),
]);
/**
* Construct an InitializeAccount3 instruction
*
* @param account New token account
* @param mint Mint account
* @param owner New account's owner/multisignature
* @param programId SPL Token program account
*
* @return Instruction to add to a transaction
*/
export function createInitializeAccount3Instruction(
account: PublicKey,
mint: PublicKey,
owner: PublicKey,
programId = TOKEN_PROGRAM_ID
): TransactionInstruction {
const keys = [
{ pubkey: account, isSigner: false, isWritable: true },
{ pubkey: mint, isSigner: false, isWritable: false },
];
const data = Buffer.alloc(initializeAccount3InstructionData.span);
initializeAccount3InstructionData.encode({ instruction: TokenInstruction.InitializeAccount3, owner }, data);
return new TransactionInstruction({ keys, programId, data });
}
/** A decoded, valid InitializeAccount3 instruction */
export interface DecodedInitializeAccount3Instruction {
programId: PublicKey;
keys: {
account: AccountMeta;
mint: AccountMeta;
};
data: {
instruction: TokenInstruction.InitializeAccount3;
owner: PublicKey;
};
}
/**
* Decode an InitializeAccount3 instruction and validate it
*
* @param instruction Transaction instruction to decode
* @param programId SPL Token program account
*
* @return Decoded, valid instruction
*/
export function decodeInitializeAccount3Instruction(
instruction: TransactionInstruction,
programId = TOKEN_PROGRAM_ID
): DecodedInitializeAccount3Instruction {
if (!instruction.programId.equals(programId)) throw new TokenInvalidInstructionProgramError();
if (instruction.data.length !== initializeAccount3InstructionData.span)
throw new TokenInvalidInstructionDataError();
const {
keys: { account, mint },
data,
} = decodeInitializeAccount3InstructionUnchecked(instruction);
if (data.instruction !== TokenInstruction.InitializeAccount3) throw new TokenInvalidInstructionTypeError();
if (!account || !mint) throw new TokenInvalidInstructionKeysError();
// TODO: key checks?
return {
programId,
keys: {
account,
mint,
},
data,
};
}
/** A decoded, non-validated InitializeAccount3 instruction */
export interface DecodedInitializeAccount3InstructionUnchecked {
programId: PublicKey;
keys: {
account: AccountMeta | undefined;
mint: AccountMeta | undefined;
};
data: {
instruction: number;
owner: PublicKey;
};
}
/**
* Decode an InitializeAccount3 instruction without validating it
*
* @param instruction Transaction instruction to decode
*
* @return Decoded, non-validated instruction
*/
export function decodeInitializeAccount3InstructionUnchecked({
programId,
keys: [account, mint],
data,
}: TransactionInstruction): DecodedInitializeAccount3InstructionUnchecked {
return {
programId,
keys: {
account,
mint,
},
data: initializeAccount3InstructionData.decode(data),
};
}

@@ -24,2 +24,15 @@ /** Instructions defined by the program */

InitializeMint2 = 20,
GetAccountDataSize = 21,
InitializeImmutableOwner = 22,
AmountToUiAmount = 23,
UiAmountToAmount = 24,
InitializeMintCloseAuthority = 25,
TransferFeeExtension = 26,
ConfidentialTransferExtension = 27,
DefaultAccountStateExtension = 28,
Reallocate = 29,
MemoTransferExtension = 30,
CreateNativeMint = 31,
InitializeNonTransferableMint = 32,
InterestBearingMintExtension = 33,
}
import { struct, u32, u8 } from '@solana/buffer-layout';
import { publicKey, u64 } from '@solana/buffer-layout-utils';
import { Commitment, Connection, PublicKey } from '@solana/web3.js';
import { Commitment, Connection, PublicKey, AccountInfo } from '@solana/web3.js';
import { TOKEN_PROGRAM_ID } from '../constants';
import { TokenAccountNotFoundError, TokenInvalidAccountOwnerError, TokenInvalidAccountSizeError } from '../errors';
import {
TokenAccountNotFoundError,
TokenInvalidAccountError,
TokenInvalidAccountOwnerError,
TokenInvalidAccountSizeError,
} from '../errors';
import { MULTISIG_SIZE } from './multisig';
import { AccountType, ACCOUNT_TYPE_SIZE } from '../extensions/accountType';
import { ExtensionType, getAccountLen } from '../extensions/extensionType';

@@ -34,2 +42,3 @@ /** Information about a token account */

closeAuthority: PublicKey | null;
tlvData: Buffer;
}

@@ -94,7 +103,72 @@

const info = await connection.getAccountInfo(address, commitment);
return unpackAccount(info, address, programId);
}
/**
* Retrieve information about multiple token accounts in a single RPC call
*
* @param connection Connection to use
* @param addresses Token accounts
* @param commitment Desired level of commitment for querying the state
* @param programId SPL Token program account
*
* @return Token account information
*/
export async function getMultipleAccounts(
connection: Connection,
addresses: PublicKey[],
commitment?: Commitment,
programId = TOKEN_PROGRAM_ID
): Promise<Account[]> {
const infos = await connection.getMultipleAccountsInfo(addresses, commitment);
const accounts = [];
for (let i = 0; i < infos.length; i++) {
const account = unpackAccount(infos[i], addresses[i], programId);
accounts.push(account);
}
return accounts;
}
/** Get the minimum lamport balance for a base token account to be rent exempt
*
* @param connection Connection to use
* @param commitment Desired level of commitment for querying the state
*
* @return Amount of lamports required
*/
export async function getMinimumBalanceForRentExemptAccount(
connection: Connection,
commitment?: Commitment
): Promise<number> {
return await getMinimumBalanceForRentExemptAccountWithExtensions(connection, [], commitment);
}
/** Get the minimum lamport balance for a rent-exempt token account with extensions
*
* @param connection Connection to use
* @param commitment Desired level of commitment for querying the state
*
* @return Amount of lamports required
*/
export async function getMinimumBalanceForRentExemptAccountWithExtensions(
connection: Connection,
extensions: ExtensionType[],
commitment?: Commitment
): Promise<number> {
const accountLen = getAccountLen(extensions);
return await connection.getMinimumBalanceForRentExemption(accountLen, commitment);
}
function unpackAccount(info: AccountInfo<Buffer> | null, address: PublicKey, programId: PublicKey) {
if (!info) throw new TokenAccountNotFoundError();
if (!info.owner.equals(programId)) throw new TokenInvalidAccountOwnerError();
if (info.data.length != ACCOUNT_SIZE) throw new TokenInvalidAccountSizeError();
if (info.data.length < ACCOUNT_SIZE) throw new TokenInvalidAccountSizeError();
const rawAccount = AccountLayout.decode(info.data);
const rawAccount = AccountLayout.decode(info.data.slice(0, ACCOUNT_SIZE));
let tlvData = Buffer.alloc(0);
if (info.data.length > ACCOUNT_SIZE) {
if (info.data.length === MULTISIG_SIZE) throw new TokenInvalidAccountSizeError();
if (info.data[ACCOUNT_SIZE] != AccountType.Account) throw new TokenInvalidAccountError();
tlvData = info.data.slice(ACCOUNT_SIZE + ACCOUNT_TYPE_SIZE);
}

@@ -113,17 +187,4 @@ return {

closeAuthority: rawAccount.closeAuthorityOption ? rawAccount.closeAuthority : null,
tlvData,
};
}
/** Get the minimum lamport balance for a token account to be rent exempt
*
* @param connection Connection to use
* @param commitment Desired level of commitment for querying the state
*
* @return Amount of lamports required
*/
export async function getMinimumBalanceForRentExemptAccount(
connection: Connection,
commitment?: Commitment
): Promise<number> {
return await connection.getMinimumBalanceForRentExemption(ACCOUNT_SIZE, commitment);
}

@@ -9,4 +9,9 @@ import { struct, u32, u8 } from '@solana/buffer-layout';

TokenInvalidAccountSizeError,
TokenInvalidMintError,
TokenOwnerOffCurveError,
} from '../errors';
import { ACCOUNT_SIZE } from './account';
import { MULTISIG_SIZE } from './multisig';
import { AccountType, ACCOUNT_TYPE_SIZE } from '../extensions/accountType';
import { ExtensionType, getMintLen } from '../extensions/extensionType';

@@ -30,2 +35,4 @@ /** Information about a mint */

freezeAuthority: PublicKey | null;
/** Additional data for extension */
tlvData: Buffer;
}

@@ -77,5 +84,12 @@

if (!info.owner.equals(programId)) throw new TokenInvalidAccountOwnerError();
if (info.data.length != MINT_SIZE) throw new TokenInvalidAccountSizeError();
if (info.data.length < MINT_SIZE) throw new TokenInvalidAccountSizeError();
const rawMint = MintLayout.decode(info.data);
const rawMint = MintLayout.decode(info.data.slice(0, MINT_SIZE));
let tlvData = Buffer.alloc(0);
if (info.data.length > MINT_SIZE) {
if (info.data.length <= ACCOUNT_SIZE) throw new TokenInvalidAccountSizeError();
if (info.data.length === MULTISIG_SIZE) throw new TokenInvalidAccountSizeError();
if (info.data[ACCOUNT_SIZE] != AccountType.Mint) throw new TokenInvalidMintError();
tlvData = info.data.slice(ACCOUNT_SIZE + ACCOUNT_TYPE_SIZE);
}

@@ -89,2 +103,3 @@ return {

freezeAuthority: rawMint.freezeAuthorityOption ? rawMint.freezeAuthority : null,
tlvData,
};

@@ -104,7 +119,25 @@ }

): Promise<number> {
return await connection.getMinimumBalanceForRentExemption(MINT_SIZE, commitment);
return await getMinimumBalanceForRentExemptMintWithExtensions(connection, [], commitment);
}
/** Get the minimum lamport balance for a rent-exempt mint with extensions
*
* @param connection Connection to use
* @param extensions Extension types included in the mint
* @param commitment Desired level of commitment for querying the state
*
* @return Amount of lamports required
*/
export async function getMinimumBalanceForRentExemptMintWithExtensions(
connection: Connection,
extensions: ExtensionType[],
commitment?: Commitment
): Promise<number> {
const mintLen = getMintLen(extensions);
return await connection.getMinimumBalanceForRentExemption(mintLen, commitment);
}
/**
* Get the address of the associated token account for a given mint and owner
* Async version of getAssociatedTokenAddressSync
* For backwards compatibility
*

@@ -117,3 +150,3 @@ * @param mint Token mint account

*
* @return Address of the associated token account
* @return Promise containing the address of the associated token account
*/

@@ -136,1 +169,29 @@ export async function getAssociatedTokenAddress(

}
/**
* Get the address of the associated token account for a given mint and owner
*
* @param mint Token mint account
* @param owner Owner of the new account
* @param allowOwnerOffCurve Allow the owner account to be a PDA (Program Derived Address)
* @param programId SPL Token program account
* @param associatedTokenProgramId SPL Associated Token program account
*
* @return Address of the associated token account
*/
export function getAssociatedTokenAddressSync(
mint: PublicKey,
owner: PublicKey,
allowOwnerOffCurve = false,
programId = TOKEN_PROGRAM_ID,
associatedTokenProgramId = ASSOCIATED_TOKEN_PROGRAM_ID
): PublicKey {
if (!allowOwnerOffCurve && !PublicKey.isOnCurve(owner.toBuffer())) throw new TokenOwnerOffCurveError();
const [address] = PublicKey.findProgramAddressSync(
[owner.toBuffer(), programId.toBuffer(), mint.toBuffer()],
associatedTokenProgramId
);
return address;
}

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc