UNPKG

solana-token-extension-boost

Version:

SDK for Solana Token Extensions with wallet adapter support

138 lines (137 loc) 6 kB
"use strict"; 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;