UNPKG

@openocean.finance/widget-sdk

Version:

OpenOcean Any-to-Any Cross-Chain-Swap SDK

88 lines 3.37 kB
import { multicall, readContract } from 'viem/actions'; import { isNativeTokenAddress } from '../../utils/isZeroAddress.js'; import { allowanceAbi } from './abi.js'; import { getPublicClient } from './publicClient.js'; import { getMulticallAddress } from './utils.js'; export const getAllowance = async (chainId, tokenAddress, ownerAddress, spenderAddress) => { const client = await getPublicClient(chainId); try { const approved = (await readContract(client, { address: tokenAddress, abi: allowanceAbi, functionName: 'allowance', args: [ownerAddress, spenderAddress], })); return approved; } catch (_e) { return 0n; } }; export const getAllowanceMulticall = async (chainId, tokens, ownerAddress) => { if (!tokens.length) { return []; } const multicallAddress = await getMulticallAddress(chainId); if (!multicallAddress) { throw new Error(`No multicall address configured for chainId ${chainId}.`); } const client = await getPublicClient(chainId); const contracts = tokens.map((token) => ({ address: token.token.address, abi: allowanceAbi, functionName: 'allowance', args: [ownerAddress, token.spenderAddress], })); const results = await multicall(client, { 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, })); }; /** * 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 */ export const getTokenAllowance = async (token, ownerAddress, spenderAddress) => { // native token don't need approval if (isNativeTokenAddress(token.address)) { return; } const approved = await getAllowance(token.chainId, token.address, ownerAddress, spenderAddress); return approved; }; /** * 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 */ export const getTokenAllowanceMulticall = async (ownerAddress, tokens) => { // filter out native tokens const filteredTokens = tokens.filter(({ token }) => !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) => { // get allowances for current chain and token list return getAllowanceMulticall(chainId, tokenDataByChain[chainId], ownerAddress); }))).flat(); return allowances; }; //# sourceMappingURL=getAllowance.js.map