UNPKG

@catalabs/catalyst-sdk

Version:
154 lines 7.09 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.EvmTokensModule = void 0; const ethers_1 = require("ethers"); const contracts_1 = require("../contracts"); const utils_1 = require("../utils"); const constants_1 = require("./permit2/constants"); const lib_1 = require("./permit2/lib"); const SignatureTransfer_lib_1 = require("./permit2/lib/SignatureTransfer.lib"); class EvmTokensModule { sdk; permitAllowanceProvider; constructor(sdk) { this.sdk = sdk; this.permitAllowanceProvider = new lib_1.AllowanceProvider(this.sdk.provider, constants_1.PERMIT2_ADDRESS); } async checkBalance(token, owner) { return contracts_1.Erc20__factory.connect(token, this.sdk.provider).balanceOf(owner); } async checkBalances(tokens, owner) { const balances = {}; const lens = contracts_1.CatalystLens__factory.connect(this.sdk.addresses.lens, this.sdk.provider); const result = await lens.fetchTokenBalances(owner, tokens); result.forEach((r) => (balances[r.token] = r.amount)); return balances; } async checkAllowance(token, owner, spender) { return contracts_1.Erc20__factory.connect(token, this.sdk.provider).allowance(owner, spender); } async increaseAllowance(token, spender, amount, options) { if (!this.sdk.signer) { throw new Error('increaseAllowance requires a signer, try calling connectSigner first'); } const contract = contracts_1.Erc20__factory.connect(token, this.sdk.signer); const tx = await contract.approve(spender, amount, { gasPrice: options?.gasPrice, maxFeePerGas: options?.maxFeePerGas, maxPriorityFeePerGas: options?.maxPriorityFeePerGas, }); return { hash: tx.hash, wait: async () => { await tx.wait(); }, }; } async estimateApprovalGasFee(token, spender, amount) { if (!this.sdk.signer) { throw new Error('estimateApprovalGasFee requires a signer, try calling connectSigner first'); } const contract = contracts_1.Erc20__factory.connect(token, this.sdk.signer); return contract.approve.estimateGas(spender, amount); } async checkPermitAmount(token, owner, spender) { const { amount, expiration } = await this.permitAllowanceProvider.getAllowanceData(token, owner, spender); if (expiration <= (Date.now() + 5 * utils_1.ONE_MIN_MS) / 1000) { return 0n; } return amount; } async ensurePermit2Allowance(token, options) { if (!this.sdk.signer || !this.sdk.address) { throw new Error('ensurePermit2Allowance requires a signer, try calling connectSigner first'); } return this.ensureAllowance(token, this.sdk.address, constants_1.PERMIT2_ADDRESS, BigInt(ethers_1.MaxUint256), options); } async generatePermitData(token, spender, amount) { if (!this.sdk.signer || !this.sdk.address) { throw new Error('generatePermitData requires a signer, try calling connectSigner first'); } const nonce = await this.permitAllowanceProvider.getNonce(token, this.sdk.address, spender); const permitSingle = { details: { token, amount: amount ?? constants_1.MaxAllowanceTransferAmount, expiration: BigInt((0, utils_1.toDeadline)(1000 * 60 * 60 * 24 * 30)), nonce, }, spender, sigDeadline: BigInt((0, utils_1.toDeadline)(1000 * 60 * 60 * 30)), }; const connectedNetwork = await this.sdk.provider.getNetwork(); const chainId = Number(connectedNetwork.chainId); const { domain, types, values } = lib_1.AllowanceTransfer.getPermitData(permitSingle, constants_1.PERMIT2_ADDRESS, chainId); const signature = await this.sdk.signer.signTypedData(domain, types, values); return { signature, permit: permitSingle }; } async generatePermitBatchData(assets, spender) { if (!this.sdk.signer || !this.sdk.address) { throw new Error('generatePermitBatchData requires a signer, try calling connectSigner first'); } const permitDetailsArray = []; const expiration30Days = BigInt((0, utils_1.toDeadline)(1000 * 60 * 60 * 24 * 30)); for (const { token, amount } of assets) { const nonce = await this.permitAllowanceProvider.getNonce(token, this.sdk.address, spender); permitDetailsArray.push({ token, amount: amount ?? constants_1.MaxAllowanceTransferAmount, expiration: expiration30Days, nonce, }); } const expiration30Mins = BigInt((0, utils_1.toDeadline)(1000 * 60 * 60 * 30)); const permitBatch = { details: permitDetailsArray, spender, sigDeadline: expiration30Mins, }; const connectedNetwork = await this.sdk.provider.getNetwork(); const chainId = Number(connectedNetwork.chainId); const { domain, types, values } = lib_1.AllowanceTransfer.getPermitData(permitBatch, constants_1.PERMIT2_ADDRESS, chainId); const signature = await this.sdk.signer.signTypedData(domain, types, values); return { signature, permit: permitBatch }; } async signPermitBatchTransferFrom(permit, witness) { if (!this.sdk.signer || !this.sdk.address) { throw new Error('generateSignaturePermitBatchData requires a signer, try calling connectSigner first'); } const connectedNetwork = await this.sdk.provider.getNetwork(); const chainId = Number(connectedNetwork.chainId); const { domain, types, values } = SignatureTransfer_lib_1.SignatureTransfer.getPermitData({ permit, permit2Address: constants_1.PERMIT2_ADDRESS, chainId, witness, }); const signature = await this.sdk.signer.signTypedData(domain, types, values); return signature; } async revoke(token, spender) { if (!this.sdk.signer) { throw new Error('revoke requires a signer, try calling connectSigner first'); } const contract = contracts_1.Erc20__factory.connect(token, this.sdk.signer); const tx = await contract.approve(spender, 0); return { hash: tx.hash, wait: async () => { await tx.wait(); }, }; } getTotalSupply(address) { return contracts_1.Erc20__factory.connect(address, this.sdk.provider).totalSupply(); } async ensureAllowance(token, owner, spender, amount, options) { const allowance = await this.checkAllowance(token, owner, spender); if (allowance < amount) { return this.increaseAllowance(token, spender, amount, options); } } } exports.EvmTokensModule = EvmTokensModule; //# sourceMappingURL=evm-tokens.module.js.map