UNPKG

escrow-market-sdk

Version:
724 lines 33.9 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); Object.defineProperty(exports, "__esModule", { value: true }); exports.EscrowMarketClient = void 0; const web3_js_1 = require("@solana/web3.js"); const spl_token_1 = require("@solana/spl-token"); const anchor_1 = require("@coral-xyz/anchor"); const types_1 = require("./types"); const Utils = __importStar(require("./utils")); /** * Client class để tương tác với Escrow Market program */ class EscrowMarketClient { /** * Khởi tạo EscrowMarketClient * @param connection Connection đến Solana cluster * @param programId Địa chỉ program (string) */ constructor(connection, programId) { this.connection = connection; // Tạo provider chỉ để đọc dữ liệu (read-only) const readOnlyProvider = new anchor_1.AnchorProvider(connection, { publicKey: web3_js_1.PublicKey.default, signTransaction: async () => { throw new Error('Read-only provider cannot sign'); }, signAllTransactions: async () => { throw new Error('Read-only provider cannot sign'); }, }, anchor_1.AnchorProvider.defaultOptions()); // Sử dụng Program constructor với IDL và programId truyền vào this.program = new anchor_1.Program(types_1.IDL, new web3_js_1.PublicKey(programId), readOnlyProvider); } /** * Initialize Config account cho escrow market * @param feePayer Địa chỉ người trả phí * @param admin Admin public key * @param operator Operator public key * @returns Transaction object */ async initialize(feePayer, admin, operator) { // Tìm config address const [configAddress, configBump] = await Utils.findConfigAddress(this.program.programId); // Tạo transaction const tx = await this.program.methods .initialize(admin, operator) .accounts({ config: configAddress, payer: feePayer, systemProgram: web3_js_1.SystemProgram.programId, }) .transaction(); return tx; } /** * Initialize vault cho một mint cụ thể * @param feePayer Địa chỉ người trả phí * @param mint Mint của token * @returns Transaction object */ async initializeVault(feePayer, mint) { // Tìm vault authority const [vaultAuthority, vaultAuthorityBump] = await Utils.findVaultAuthorityAddress(mint, this.program.programId); // Tìm vault token account const [vaultTokenAccount, vaultTokenAccountBump] = await Utils.findVaultTokenAccountAddress(mint, this.program.programId); const accountInfo = await this.connection.getAccountInfo(mint); const tokenProgramId = accountInfo === null || accountInfo === void 0 ? void 0 : accountInfo.owner; // Tạo transaction const tx = await this.program.methods .initializeVault() .accounts({ user: feePayer, mint: mint, vaultTokenAccount: vaultTokenAccount, vaultAuthority: vaultAuthority, tokenProgram: tokenProgramId || spl_token_1.TOKEN_PROGRAM_ID, systemProgram: web3_js_1.SystemProgram.programId, rent: web3_js_1.SYSVAR_RENT_PUBKEY, }) .transaction(); return tx; } /** * Deposit token vào vault * @param depositor Địa chỉ của người gửi token * @param mint Mint của token * @param amount Số lượng token * @returns Transaction object */ async deposit(depositor, mint, amount) { // Chuyển đổi số lượng thành BN const amountBN = Utils.toBN(amount); // Xác định token program ID dựa trên mint let tokenProgramId = spl_token_1.TOKEN_PROGRAM_ID; try { // Lấy thông tin về mint account để xác định program ID const accountInfo = await this.connection.getAccountInfo(mint); if (!accountInfo) { throw new Error("Không tìm thấy mint account"); } // Kiểm tra program ID của mint (token program nào sở hữu mint) tokenProgramId = accountInfo.owner; console.log("Mint program ID:", tokenProgramId.toBase58()); } catch (error) { console.warn("Lỗi khi xác định token program ID, sử dụng TOKEN_PROGRAM_ID mặc định:", error); } // Tìm user token account const userTokenAccount = await (0, spl_token_1.getAssociatedTokenAddress)(mint, depositor, false, tokenProgramId); // Tìm vault authority const [vaultAuthority, vaultAuthorityBump] = await Utils.findVaultAuthorityAddress(mint, this.program.programId); // Tìm vault token account const [vaultTokenAccount] = await Utils.findVaultTokenAccountAddress(mint, this.program.programId); // Kiểm tra xem vault token account đã tồn tại chưa let preInstructions = []; let vaultTokenAccountExists = false; try { // Thử lấy thông tin về vault token account bằng getAccount từ spl-token const rs = await this.connection.getAccountInfo(vaultTokenAccount); vaultTokenAccountExists = rs !== null; } catch (error) { console.log('Kiểm tra vault token account không tồn tại, chuẩn bị tạo mới...'); } if (!vaultTokenAccountExists) { // Nếu không tìm thấy account, thêm instruction để tạo vault token account console.log('Vault token account không tồn tại, đang tạo mới...'); try { // Thêm instruction initializeVault để tạo vault token account mới const initVaultIx = await this.program.methods .initializeVault() .accounts({ payer: depositor, mint: mint, vaultTokenAccount: vaultTokenAccount, vaultAuthority: vaultAuthority, tokenProgram: tokenProgramId, systemProgram: web3_js_1.SystemProgram.programId, rent: web3_js_1.SYSVAR_RENT_PUBKEY, associatedTokenProgram: spl_token_1.ASSOCIATED_TOKEN_PROGRAM_ID }) .instruction(); preInstructions.push(initVaultIx); } catch (initError) { console.error('Lỗi khi tạo vault token account:', initError); throw new Error('Không thể tạo vault token account.'); } } // Tạo transaction const tx = await this.program.methods .deposit(amountBN) .accounts({ user: depositor, mint: mint, userTokenAccount: userTokenAccount, vaultTokenAccount: vaultTokenAccount, vaultAuthority: vaultAuthority, tokenProgram: tokenProgramId, systemProgram: web3_js_1.SystemProgram.programId, associatedTokenProgram: spl_token_1.ASSOCIATED_TOKEN_PROGRAM_ID, }) .preInstructions(preInstructions) .transaction(); return tx; } /** * Withdraw token từ vault (chỉ operator mới có quyền gọi) * @param operatorPubkey Địa chỉ của operator * @param user Địa chỉ của user nhận token * @param mint Mint của token * @param amount Số lượng token * @param nonce Số duy nhất để chống replay attack * @param opts Options cho transaction * @returns Transaction object */ async withdraw(operatorPubkey, user, mint, amount, nonce, opts) { // Chuyển đổi số lượng thành BN const amountBN = Utils.toBN(amount); const nonceBN = Utils.toBN(nonce); // Kiểm tra quyền operator const config = await this.getConfig(); if (!config.operator.equals(operatorPubkey)) { throw new Error("Chỉ operator mới có quyền thực hiện withdraw"); } // Xác định token program ID dựa trên mint let tokenProgramId = spl_token_1.TOKEN_PROGRAM_ID; try { // Lấy thông tin về mint account để xác định program ID const accountInfo = await this.connection.getAccountInfo(mint); if (!accountInfo) { throw new Error("Không tìm thấy mint account"); } // Kiểm tra program ID của mint (token program nào sở hữu mint) tokenProgramId = accountInfo.owner; console.log("Mint program ID:", tokenProgramId.toBase58()); } catch (error) { console.warn("Lỗi khi xác định token program ID, sử dụng TOKEN_PROGRAM_ID mặc định:", error); } // Tìm user token account nếu không được cung cấp const userTokenAccount = (opts === null || opts === void 0 ? void 0 : opts.userTokenAccount) || await (0, spl_token_1.getAssociatedTokenAddress)(mint, user, false, tokenProgramId); // Tìm vault authority const [vaultAuthority, vaultAuthorityBump] = await Utils.findVaultAuthorityAddress(mint, this.program.programId); // Tìm vault token account const vaultTokenAccount = (opts === null || opts === void 0 ? void 0 : opts.vaultTokenAccount) || (await Utils.findVaultTokenAccountAddress(mint, this.program.programId))[0]; // Tìm withdraw nonce account const [withdrawNonce, withdrawNonceBump] = await Utils.findWithdrawNonceAddress(user, nonceBN, this.program.programId); // Mảng chứa các instructions cần thực hiện trước let preInstructions = []; // Kiểm tra userTokenAccount đã tồn tại chưa let userTokenAccountExists = false; try { const accountInfo = await this.connection.getAccountInfo(userTokenAccount); userTokenAccountExists = accountInfo !== null; console.log('User token account exists:', userTokenAccountExists); } catch (error) { console.log('Lỗi khi kiểm tra user token account:', error); } if (!userTokenAccountExists) { console.log('Tạo user token account...'); try { const createUserTokenAccountIx = (0, spl_token_1.createAssociatedTokenAccountInstruction)(operatorPubkey, // payer userTokenAccount, // associatedToken user, // owner mint, // mint tokenProgramId // programId ); preInstructions.push(createUserTokenAccountIx); } catch (error) { console.error('Lỗi khi tạo instruction cho user token account:', error); } } // Tạo transaction const tx = await this.program.methods .withdraw(amountBN, nonceBN) .accounts({ operator: operatorPubkey, user: user, mint: mint, userTokenAccount: userTokenAccount, vaultTokenAccount: vaultTokenAccount, vaultAuthority: vaultAuthority, withdrawNonce: withdrawNonce, tokenProgram: tokenProgramId, systemProgram: web3_js_1.SystemProgram.programId, associatedTokenProgram: spl_token_1.ASSOCIATED_TOKEN_PROGRAM_ID, config: (await Utils.findConfigAddress(this.program.programId))[0], // Thêm config để kiểm tra operator }) .preInstructions(preInstructions) .transaction(); return tx; } /** * Parse events emitted by the program from a transaction signature using Anchor's EventParser * @param signature Transaction signature to parse events from * @returns Array of decoded events from the transaction */ async parseEventsFromTransaction(signature) { var _a; try { // Fetch the transaction data let transactionData = null; let retryCount = 0; const maxRetries = 8; while (retryCount < maxRetries && transactionData === null) { try { transactionData = await this.connection.getTransaction(signature, { commitment: 'confirmed', maxSupportedTransactionVersion: 0 }); if (transactionData === null) { retryCount++; console.log(`Lần thử ${retryCount}/${maxRetries}: Không tìm thấy dữ liệu giao dịch, đang thử lại...`); // Đợi 1 giây trước khi thử lại await new Promise(resolve => setTimeout(resolve, 1000)); } } catch (err) { retryCount++; console.error(`Lần thử ${retryCount}/${maxRetries}: Lỗi khi lấy dữ liệu giao dịch`, err); // Đợi 1 giây trước khi thử lại await new Promise(resolve => setTimeout(resolve, 1000)); } } if (!transactionData || !((_a = transactionData.meta) === null || _a === void 0 ? void 0 : _a.logMessages)) { throw new Error('Transaction data or log messages not found'); } // Use Anchor's EventParser to parse events from logs const { EventParser } = await Promise.resolve().then(() => __importStar(require('@coral-xyz/anchor'))); const eventParser = new EventParser(this.program.programId, this.program.coder); const events = Array.from(eventParser.parseLogs(transactionData.meta.logMessages)); return events; } catch (error) { console.error('Error parsing events from transaction:', error); throw error; } } /** * Settle một deal * @param operatorPubkey Địa chỉ của operator * @param dealId ID của deal * @param buyer Địa chỉ của buyer * @param seller Địa chỉ của seller * @param tokenTransfer Địa chỉ mint của token transfer * @param tokenWithdraw Địa chỉ mint của token withdraw * @param transferAmount Số lượng token chuyển * @param withdrawAmount Số lượng token rút * @param opts Options cho transaction * @returns Transaction object */ async settle(operatorPubkey, dealId, buyer, seller, tokenTransfer, tokenWithdraw, transferAmount, withdrawAmount, opts) { var _a; console.log('===== Bắt đầu quá trình settle ====='); // Tìm deal account const [dealAccount, dealBump] = await Utils.findDealAddress(dealId, this.program.programId); // Tìm config account const [configAccount, configBump] = await Utils.findConfigAddress(this.program.programId); // Lấy thông tin deal nếu tồn tại let dealData = null; try { dealData = await this.program.account.deal.fetch(dealAccount); console.log('Deal đã tồn tại:', dealData); } catch (error) { // Deal chưa tồn tại, sẽ được khởi tạo trong instruction console.log('Deal chưa tồn tại, sẽ được khởi tạo trong instruction'); } // Xác định token program ID cho tokenTransfer let tokenTransferProgramId = spl_token_1.TOKEN_PROGRAM_ID; try { const accountInfo = await this.connection.getAccountInfo(tokenTransfer); if (accountInfo) { tokenTransferProgramId = accountInfo.owner; console.log("Token Transfer Program ID:", tokenTransferProgramId.toBase58()); } } catch (error) { console.warn("Lỗi khi xác định token transfer program ID, sử dụng TOKEN_PROGRAM_ID mặc định:", error); } // Xác định token program ID cho tokenWithdraw let tokenWithdrawProgramId = spl_token_1.TOKEN_PROGRAM_ID; try { const accountInfo = await this.connection.getAccountInfo(tokenWithdraw); if (accountInfo) { tokenWithdrawProgramId = accountInfo.owner; console.log("Token Withdraw Program ID:", tokenWithdrawProgramId.toBase58()); } } catch (error) { console.warn("Lỗi khi xác định token withdraw program ID, sử dụng TOKEN_PROGRAM_ID mặc định:", error); } // Kiểm tra xem hai token program ID có khớp nhau không if (tokenTransferProgramId.toBase58() !== tokenWithdrawProgramId.toBase58()) { console.warn("Cảnh báo: Token transfer program ID khác với token withdraw program ID."); console.warn("Điều này có thể gây ra lỗi MintIsNotOwnedByTokenProgram trong chương trình Solana."); console.warn("Bạn nên sử dụng các token có cùng token program ID."); } // Tìm token accounts - khởi tạo tất cả trong thân hàm const sellerTokenAccount = await (0, spl_token_1.getAssociatedTokenAddress)(tokenTransfer, seller, false, tokenTransferProgramId); const buyerTokenAccount = await (0, spl_token_1.getAssociatedTokenAddress)(tokenTransfer, buyer, false, tokenTransferProgramId); const sellerWithdrawAccount = await (0, spl_token_1.getAssociatedTokenAddress)(tokenWithdraw, seller, false, tokenWithdrawProgramId); // Tìm vault authority const [vaultAuthority, vaultAuthorityBump] = await Utils.findVaultAuthorityAddress(tokenWithdraw, this.program.programId); // Tìm vault token account const [vaultTokenAccount] = await Utils.findVaultTokenAccountAddress(tokenWithdraw, this.program.programId); console.log('vaultTokenAccount', vaultTokenAccount); // Kiểm tra số dư token của seller if (!(opts === null || opts === void 0 ? void 0 : opts.skipBalanceCheck)) { try { const sellerTokenInfo = await this.connection.getTokenAccountBalance(sellerTokenAccount); console.log(`Số dư token của seller: ${sellerTokenInfo.value.uiAmount}`); if (Number(sellerTokenInfo.value.amount) < Number(transferAmount)) { throw new Error(`Seller không đủ token để chuyển. Cần ${Number(transferAmount) / 1e9} tokens.`); } } catch (error) { if ((_a = error.message) === null || _a === void 0 ? void 0 : _a.includes("Seller không đủ token")) { throw error; } console.warn('Lỗi khi kiểm tra số dư token của seller:', error); console.warn('Tiếp tục thực hiện, nhưng có thể gặp lỗi nếu số dư không đủ.'); } } // Mảng chứa các instructions cần thực hiện trước let preInstructions = []; // Kiểm tra sellerTokenAccount đã tồn tại chưa let sellerTokenAccountExists = false; try { const accountInfo = await this.connection.getAccountInfo(sellerTokenAccount); sellerTokenAccountExists = accountInfo !== null; console.log('Seller token account exists:', sellerTokenAccountExists); } catch (error) { console.log('Lỗi khi kiểm tra seller token account:', error); } if (!sellerTokenAccountExists) { console.log('Tạo seller token account...'); try { const createSellerTokenAccountIx = (0, spl_token_1.createAssociatedTokenAccountInstruction)(operatorPubkey, // payer sellerTokenAccount, // associatedToken seller, // owner tokenTransfer, // mint tokenTransferProgramId // programId ); preInstructions.push(createSellerTokenAccountIx); } catch (error) { console.error('Lỗi khi tạo instruction cho seller token account:', error); } } // Kiểm tra buyerTokenAccount đã tồn tại chưa let buyerTokenAccountExists = false; try { const accountInfo = await this.connection.getAccountInfo(buyerTokenAccount); buyerTokenAccountExists = accountInfo !== null; console.log('Buyer token account exists:', buyerTokenAccountExists); } catch (error) { console.log('Lỗi khi kiểm tra buyer token account:', error); } if (!buyerTokenAccountExists) { console.log('Tạo buyer token account...'); try { const createBuyerTokenAccountIx = (0, spl_token_1.createAssociatedTokenAccountInstruction)(operatorPubkey, // payer buyerTokenAccount, // associatedToken buyer, // owner tokenTransfer, // mint tokenTransferProgramId // programId ); preInstructions.push(createBuyerTokenAccountIx); } catch (error) { console.error('Lỗi khi tạo instruction cho buyer token account:', error); } } // Kiểm tra sellerWithdrawAccount đã tồn tại chưa let sellerWithdrawAccountExists = false; try { const accountInfo = await this.connection.getAccountInfo(sellerWithdrawAccount); sellerWithdrawAccountExists = accountInfo !== null; console.log('Seller withdraw account exists:', sellerWithdrawAccountExists); } catch (error) { console.log('Lỗi khi kiểm tra seller withdraw account:', error); } if (!sellerWithdrawAccountExists) { console.log('Tạo seller withdraw account...'); try { const createSellerWithdrawAccountIx = (0, spl_token_1.createAssociatedTokenAccountInstruction)(operatorPubkey, // payer sellerWithdrawAccount, // associatedToken seller, // owner tokenWithdraw, // mint tokenWithdrawProgramId // programId ); preInstructions.push(createSellerWithdrawAccountIx); } catch (error) { console.error('Lỗi khi tạo instruction cho seller withdraw account:', error); } } // Debug log các preInstructions console.log(`Số lượng preInstructions: ${preInstructions.length}`); // Nếu có preInstructions, kiểm tra các tài khoản sẽ được tạo if (preInstructions.length > 0) { console.log('Các tài khoản token cần thiết sẽ được tạo trong transaction...'); } // Sử dụng remaining_accounts để truyền thêm token_withdraw_program const remainingAccounts = [{ pubkey: tokenWithdrawProgramId, isWritable: false, isSigner: false }]; // Tạo transaction const tx = await this.program.methods .settle(dealId, new anchor_1.BN(transferAmount), new anchor_1.BN(withdrawAmount)) .accounts({ seller: seller, operator: operatorPubkey, buyer: buyer, deal: dealAccount, config: configAccount, tokenTransfer: tokenTransfer, sellerTokenAccount: sellerTokenAccount, buyerTokenAccount: buyerTokenAccount, tokenWithdraw: tokenWithdraw, sellerWithdrawAccount: sellerWithdrawAccount, vaultTokenAccount: vaultTokenAccount, vaultAuthority: vaultAuthority, tokenTransferProgram: tokenTransferProgramId, // Sử dụng tokenTransferProgramId cho tokenProgram tokenWithdrawProgram: tokenWithdrawProgramId, // Sử dụng tokenWithdrawProgramId cho tokenProgram associatedTokenProgram: spl_token_1.ASSOCIATED_TOKEN_PROGRAM_ID, systemProgram: web3_js_1.SystemProgram.programId, }) .remainingAccounts(remainingAccounts) .preInstructions(preInstructions) .transaction(); if (preInstructions.length > 0) { console.log(`Đã thêm ${preInstructions.length} instructions để tạo tài khoản vào transaction.`); } console.log('Đã thêm token withdraw program ID vào remaining_accounts:', tokenWithdrawProgramId.toBase58()); console.log('===== Kết thúc quá trình tạo transaction settle ====='); return tx; } /** * Operator cancel một deal * @param operatorPubkey Địa chỉ của operator * @param dealId ID của deal * @param buyer Địa chỉ của buyer * @param tokenWithdraw Địa chỉ mint của token * @param amount Số lượng token hoàn lại * @returns Transaction object */ async operatorCancel(operatorPubkey, dealId, buyer, tokenWithdraw, amount) { // Chuyển đổi số lượng thành BN const amountBN = Utils.toBN(amount); // Tìm deal account const [dealAccount, dealBump] = await Utils.findDealAddress(dealId, this.program.programId); // Tìm config account const [configAccount, configBump] = await Utils.findConfigAddress(this.program.programId); // Xác định token program ID cho tokenWithdraw let tokenWithdrawProgramId = spl_token_1.TOKEN_PROGRAM_ID; try { const accountInfo = await this.connection.getAccountInfo(tokenWithdraw); if (accountInfo) { tokenWithdrawProgramId = accountInfo.owner; console.log("Token Withdraw Program ID:", tokenWithdrawProgramId.toBase58()); } } catch (error) { console.warn("Lỗi khi xác định token withdraw program ID, sử dụng TOKEN_PROGRAM_ID mặc định:", error); } // Tìm buyer withdraw account const buyerWithdrawAccount = await (0, spl_token_1.getAssociatedTokenAddress)(tokenWithdraw, buyer, false, tokenWithdrawProgramId); // Tìm vault authority const [vaultAuthority, vaultAuthorityBump] = await Utils.findVaultAuthorityAddress(tokenWithdraw, this.program.programId); // Tìm vault token account const [vaultTokenAccount] = await Utils.findVaultTokenAccountAddress(tokenWithdraw, this.program.programId); // Mảng chứa các instructions cần thực hiện trước let preInstructions = []; // Kiểm tra buyerWithdrawAccount đã tồn tại chưa let buyerWithdrawAccountExists = false; try { const accountInfo = await this.connection.getAccountInfo(buyerWithdrawAccount); buyerWithdrawAccountExists = accountInfo !== null; console.log('Buyer withdraw account exists:', buyerWithdrawAccountExists); } catch (error) { console.log('Lỗi khi kiểm tra buyer withdraw account:', error); } if (!buyerWithdrawAccountExists) { console.log('Tạo buyer withdraw account...'); try { const createBuyerWithdrawAccountIx = (0, spl_token_1.createAssociatedTokenAccountInstruction)(operatorPubkey, // payer buyerWithdrawAccount, // associatedToken buyer, // owner tokenWithdraw, // mint tokenWithdrawProgramId // programId ); preInstructions.push(createBuyerWithdrawAccountIx); } catch (error) { console.error('Lỗi khi tạo instruction cho buyer withdraw account:', error); } } // Tạo transaction const tx = await this.program.methods .operatorCancel(dealId, amountBN) .accounts({ operator: operatorPubkey, buyer: buyer, deal: dealAccount, config: configAccount, token: tokenWithdraw, buyerTokenAccount: buyerWithdrawAccount, vaultTokenAccount: vaultTokenAccount, vaultAuthority: vaultAuthority, tokenProgram: tokenWithdrawProgramId, systemProgram: web3_js_1.SystemProgram.programId, }) .preInstructions(preInstructions) .transaction(); return tx; } /** * Lấy thông tin Config * @returns Config account */ async getConfig() { const [configAddress] = await Utils.findConfigAddress(this.program.programId); try { const configData = await this.program.account.config.fetch(configAddress); return { admin: new web3_js_1.PublicKey(configData.admin), operator: new web3_js_1.PublicKey(configData.operator), bump: configData.bump, }; } catch (error) { console.error('Lỗi khi lấy thông tin config:', error); throw error; } } /** * Lấy thông tin Deal * @param dealId ID của deal * @returns Deal account hoặc null nếu không tồn tại */ async getDeal(dealId) { const [dealAddress] = await Utils.findDealAddress(dealId, this.program.programId); try { const dealData = await this.program.account.deal.fetch(dealAddress); return { dealId: dealData.dealId, seller: new web3_js_1.PublicKey(dealData.seller), buyer: new web3_js_1.PublicKey(dealData.buyer), tokenTransfer: new web3_js_1.PublicKey(dealData.tokenTransfer), tokenWithdraw: new web3_js_1.PublicKey(dealData.tokenWithdraw), transferAmount: dealData.transferAmount, withdrawAmount: dealData.withdrawAmount, deadline: dealData.deadline, status: dealData.status, bump: dealData.bump, }; } catch (error) { return null; } } /** * Lấy số dư trong vault của một mint * @param mint Mint của token * @returns Số dư token trong vault */ async getVaultBalance(mint) { try { const [vaultTokenAccount] = await Utils.findVaultTokenAccountAddress(mint, this.program.programId); const balance = await this.connection.getTokenAccountBalance(vaultTokenAccount); return BigInt(balance.value.amount); } catch (error) { return BigInt(0); } } /** * Kiểm tra địa chỉ có quyền admin không * @param pubkey Địa chỉ cần kiểm tra * @returns true nếu là admin */ async isAdmin(pubkey) { try { const config = await this.getConfig(); return config.admin.equals(pubkey); } catch (error) { return false; } } /** * Kiểm tra địa chỉ có quyền operator không * @param pubkey Địa chỉ cần kiểm tra * @returns true nếu là operator */ async isOperator(pubkey) { try { const config = await this.getConfig(); return config.operator.equals(pubkey); } catch (error) { return false; } } /** * Đăng ký lắng nghe sự kiện * @param eventName Tên sự kiện * @param callback Hàm callback xử lý sự kiện * @returns ID của listener */ subscribeToEvents(eventName, callback) { const listener = this.program.addEventListener(eventName, (event, slot) => { callback({ event, slot }); }); return listener; } /** * Hủy đăng ký lắng nghe sự kiện * @param listenerId ID của listener */ async unsubscribeFromEvent(listenerId) { await this.program.removeEventListener(listenerId); } } exports.EscrowMarketClient = EscrowMarketClient; //# sourceMappingURL=client.js.map