@getclave/lifi-sdk
Version:
LI.FI Any-to-Any Cross-Chain-Swap SDK
96 lines (95 loc) • 4.03 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.getTokenAllowanceMulticall = exports.getTokenAllowance = exports.getAllowanceMulticall = exports.getAllowance = void 0;
const actions_1 = require("viem/actions");
const isZeroAddress_1 = require("../../utils/isZeroAddress");
const abi_1 = require("./abi");
const getActionWithFallback_1 = require("./getActionWithFallback");
const publicClient_1 = require("./publicClient");
const utils_1 = require("./utils");
const getAllowance = async (client, tokenAddress, ownerAddress, spenderAddress) => {
try {
const approved = await (0, getActionWithFallback_1.getActionWithFallback)(client, actions_1.readContract, 'readContract', {
address: tokenAddress,
abi: abi_1.allowanceAbi,
functionName: 'allowance',
args: [ownerAddress, spenderAddress],
});
return approved;
}
catch (_e) {
return 0n;
}
};
exports.getAllowance = getAllowance;
const getAllowanceMulticall = async (client, chainId, tokens, ownerAddress) => {
if (!tokens.length) {
return [];
}
const multicallAddress = await (0, utils_1.getMulticallAddress)(chainId);
if (!multicallAddress) {
throw new Error(`No multicall address configured for chainId ${chainId}.`);
}
const contracts = tokens.map((token) => ({
address: token.token.address,
abi: abi_1.allowanceAbi,
functionName: 'allowance',
args: [ownerAddress, token.spenderAddress],
}));
const results = await (0, getActionWithFallback_1.getActionWithFallback)(client, actions_1.multicall, 'multicall', {
contracts,
multicallAddress: multicallAddress,
});
if (!results.length) {
throw new Error(`Couldn't load allowance from chainId ${chainId} using multicall.`);
}
return tokens.map(({ token, spenderAddress }, i) => ({
token,
spenderAddress,
allowance: results[i].result,
}));
};
exports.getAllowanceMulticall = getAllowanceMulticall;
/**
* Get the current allowance for a certain token.
* @param token - The token that should be checked
* @param ownerAddress - The owner of the token
* @param spenderAddress - The spender address that has to be approved
* @returns Returns allowance
*/
const getTokenAllowance = async (token, ownerAddress, spenderAddress) => {
// native token don't need approval
if ((0, isZeroAddress_1.isNativeTokenAddress)(token.address)) {
return;
}
const client = await (0, publicClient_1.getPublicClient)(token.chainId);
const approved = await (0, exports.getAllowance)(client, token.address, ownerAddress, spenderAddress);
return approved;
};
exports.getTokenAllowance = getTokenAllowance;
/**
* Get the current allowance for a list of token/spender address pairs.
* @param ownerAddress - The owner of the tokens
* @param tokens - A list of token and spender address pairs
* @returns Returns array of tokens and their allowance
*/
const getTokenAllowanceMulticall = async (ownerAddress, tokens) => {
// filter out native tokens
const filteredTokens = tokens.filter(({ token }) => !(0, isZeroAddress_1.isNativeTokenAddress)(token.address));
// group by chain
const tokenDataByChain = {};
for (const data of filteredTokens) {
if (!tokenDataByChain[data.token.chainId]) {
tokenDataByChain[data.token.chainId] = [];
}
tokenDataByChain[data.token.chainId].push(data);
}
const chainKeys = Object.keys(tokenDataByChain).map(Number.parseInt);
const allowances = (await Promise.all(chainKeys.map(async (chainId) => {
const client = await (0, publicClient_1.getPublicClient)(chainId);
// get allowances for current chain and token list
return (0, exports.getAllowanceMulticall)(client, chainId, tokenDataByChain[chainId], ownerAddress);
}))).flat();
return allowances;
};
exports.getTokenAllowanceMulticall = getTokenAllowanceMulticall;