@catalabs/catalyst-sdk
Version:
Catalyst AMM SDK
154 lines • 7.09 kB
JavaScript
"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