escrow-market-sdk
Version:
SDK for Escrow Market Solana Program
724 lines • 33.9 kB
JavaScript
"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