solana-token-extension-boost
Version:
SDK for Solana Token Extensions with wallet adapter support
138 lines (137 loc) • 6 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.PermanentDelegateToken = void 0;
const web3_js_1 = require("@solana/web3.js");
const spl_token_1 = require("@solana/spl-token");
const token_1 = require("../../core/token");
/**
* PermanentDelegateToken - Extension for Token with permanent delegate functionality
*
* This extension allows setting a permanent delegate that can transfer tokens from any
* account holding this token without the owner's permission.
*/
class PermanentDelegateToken extends token_1.Token {
constructor(connection, mint, delegate) {
super(connection, mint);
this.delegate = delegate;
}
/**
* Create instructions for a token with permanent delegate extension
*
* @param connection - Connection to Solana cluster
* @param payer - Public key of the transaction fee payer
* @param params - Initialization parameters:
* - decimals: Number of decimals
* - mintAuthority: Authority allowed to mint tokens
* - freezeAuthority: Authority allowed to freeze accounts (optional)
* - permanentDelegate: Address of the permanent delegate
* @returns Instructions, signers and mint address
*/
static async createInstructions(connection, payer, params) {
const { decimals, mintAuthority, freezeAuthority = null, permanentDelegate } = params;
try {
const mintKeypair = web3_js_1.Keypair.generate();
const mint = mintKeypair.publicKey;
const mintLen = (0, spl_token_1.getMintLen)([spl_token_1.ExtensionType.PermanentDelegate]);
const lamports = await connection.getMinimumBalanceForRentExemption(mintLen);
const instructions = [
web3_js_1.SystemProgram.createAccount({
fromPubkey: payer,
newAccountPubkey: mint,
space: mintLen,
lamports,
programId: spl_token_1.TOKEN_2022_PROGRAM_ID,
}),
(0, spl_token_1.createInitializePermanentDelegateInstruction)(mint, permanentDelegate, spl_token_1.TOKEN_2022_PROGRAM_ID),
(0, spl_token_1.createInitializeMintInstruction)(mint, decimals, mintAuthority, freezeAuthority, spl_token_1.TOKEN_2022_PROGRAM_ID)
];
return {
instructions,
signers: [mintKeypair],
mint
};
}
catch (error) {
throw new Error(`Could not create PermanentDelegateToken instructions: ${error.message}`);
}
}
/**
* Create instructions for a token account for a token with permanent delegate
*
* @param payer - Public key of the transaction fee payer
* @param owner - Token account owner
* @returns Instructions, token account address, and account existence status
*/
async createTokenAccountInstructions(payer, owner) {
try {
const tokenAccount = await (0, spl_token_1.getAssociatedTokenAddress)(this.mint, owner, false, spl_token_1.TOKEN_2022_PROGRAM_ID);
const instructions = [];
let accountExists = false;
try {
await (0, spl_token_1.getAccount)(this.connection, tokenAccount, "recent", spl_token_1.TOKEN_2022_PROGRAM_ID);
// Account already exists, no instruction needed
accountExists = true;
}
catch (error) {
// Account doesn't exist, add instruction to create it
instructions.push((0, spl_token_1.createAssociatedTokenAccountInstruction)(payer, tokenAccount, owner, this.mint, spl_token_1.TOKEN_2022_PROGRAM_ID));
}
return {
instructions,
address: tokenAccount,
accountExists
};
}
catch (error) {
throw new Error(`Could not create token account instructions: ${error.message}`);
}
}
/**
* Create instruction to transfer tokens as permanent delegate
*
* @param delegate - Public key of the permanent delegate
* @param source - Source account (any account holding the token)
* @param destination - Destination account
* @param amount - Amount to transfer
* @returns Transaction instruction
*/
createTransferAsDelegateInstruction(delegate, source, destination, amount) {
return (0, spl_token_1.createTransferInstruction)(source, destination, delegate, amount, [], spl_token_1.TOKEN_2022_PROGRAM_ID);
}
/**
* Check if an address is the permanent delegate
*
* @param address - Address to check
* @returns true if it is the permanent delegate, false otherwise
*/
async isPermanentDelegate(address) {
try {
const mintInfo = await (0, spl_token_1.getMint)(this.connection, this.mint, "recent", spl_token_1.TOKEN_2022_PROGRAM_ID);
if (!mintInfo.permanentDelegate) {
console.log("Permanent delegate không tồn tại cho token này");
return false;
}
return mintInfo.permanentDelegate.equals(address);
}
catch (error) {
console.error(`Lỗi khi kiểm tra permanent delegate: ${error.message || String(error)}`);
return false;
}
}
/**
* Get the permanent delegate of the token
*
* @returns Address of the permanent delegate or null if none
*/
async getPermanentDelegate() {
try {
const mintInfo = await (0, spl_token_1.getMint)(this.connection, this.mint, "recent", spl_token_1.TOKEN_2022_PROGRAM_ID);
return mintInfo.permanentDelegate || null;
}
catch (error) {
console.error(`Lỗi khi lấy permanent delegate: ${error.message || String(error)}`);
return null;
}
}
}
exports.PermanentDelegateToken = PermanentDelegateToken;