UNPKG

@okx-dex/okx-dex-sdk

Version:
115 lines (114 loc) 5.04 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.EVMApproveExecutor = void 0; // src/api/swap/evm/evm-approve.ts const ethers_1 = require("ethers"); const http_client_1 = require("../../../core/http-client"); // ERC20 ABI for approval const ERC20_ABI = [ { "constant": true, "inputs": [ { "name": "_owner", "type": "address" }, { "name": "_spender", "type": "address" } ], "name": "allowance", "outputs": [{ "name": "", "type": "uint256" }], "type": "function" }, { "constant": false, "inputs": [ { "name": "_spender", "type": "address" }, { "name": "_value", "type": "uint256" } ], "name": "approve", "outputs": [{ "name": "", "type": "bool" }], "type": "function" } ]; class EVMApproveExecutor { constructor(config, networkConfig) { var _a; this.config = config; this.networkConfig = networkConfig; this.DEFAULT_GAS_MULTIPLIER = BigInt(150); // 1.5x if (!((_a = this.config.evm) === null || _a === void 0 ? void 0 : _a.wallet)) { throw new Error("EVM configuration required"); } this.provider = this.config.evm.wallet.provider; this.httpClient = new http_client_1.HTTPClient(this.config); } async executeSwap(swapData, params) { throw new Error("Swap execution not supported in approval executor"); } async getAllowance(tokenAddress, ownerAddress, spenderAddress) { const tokenContract = new ethers_1.ethers.Contract(tokenAddress, ERC20_ABI, this.provider); const allowanceResult = await tokenContract.allowance(ownerAddress, spenderAddress); return allowanceResult; } async handleTokenApproval(chainId, tokenAddress, amount) { var _a; if (!((_a = this.config.evm) === null || _a === void 0 ? void 0 : _a.wallet)) { throw new Error("EVM wallet required"); } const dexContractAddress = await this.getDexContractAddress(chainId); // Check current allowance const currentAllowance = await this.getAllowance(tokenAddress, this.config.evm.wallet.address, dexContractAddress); if (currentAllowance >= BigInt(amount)) { throw new Error("Token already approved for the requested amount"); } try { // Execute the approval transaction const result = await this.executeApprovalTransaction(tokenAddress, dexContractAddress, amount); return { transactionHash: result.hash }; } catch (error) { console.error("Approval execution failed:", error); throw error; } } async getDexContractAddress(chainId) { var _a, _b; try { const response = await this.httpClient.request('GET', '/api/v5/dex/aggregator/supported/chain', { chainId }); if (!((_b = (_a = response.data) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.dexTokenApproveAddress)) { throw new Error(`No dex contract address found for chain ${chainId}`); } return response.data[0].dexTokenApproveAddress; } catch (error) { console.error('Error getting dex contract address:', error); throw error; } } async executeApprovalTransaction(tokenAddress, spenderAddress, amount) { var _a; if (!((_a = this.config.evm) === null || _a === void 0 ? void 0 : _a.wallet)) { throw new Error("EVM wallet required"); } const tokenContract = new ethers_1.ethers.Contract(tokenAddress, ERC20_ABI, this.config.evm.wallet); let retryCount = 0; while (retryCount < (this.networkConfig.maxRetries || 3)) { try { console.log("Sending approval transaction..."); const tx = await tokenContract.approve(spenderAddress, amount, { gasLimit: BigInt(100000), // Safe default for approvals maxFeePerGas: (await this.provider.getFeeData()).maxFeePerGas * this.DEFAULT_GAS_MULTIPLIER / BigInt(100), maxPriorityFeePerGas: (await this.provider.getFeeData()).maxPriorityFeePerGas * this.DEFAULT_GAS_MULTIPLIER / BigInt(100) }); console.log("Waiting for transaction confirmation..."); return await tx.wait(); } catch (error) { retryCount++; console.warn(`Approval attempt ${retryCount} failed, retrying in ${2000 * retryCount}ms...`); if (retryCount === this.networkConfig.maxRetries) throw error; await new Promise(resolve => setTimeout(resolve, 2000 * retryCount)); } } throw new Error('Max retries exceeded for approval transaction'); } } exports.EVMApproveExecutor = EVMApproveExecutor;