UNPKG

viem

Version:

TypeScript Interface for Ethereum

106 lines (102 loc) 3.29 kB
import type { Address } from 'abitype' import type { Account } from '../../accounts/types.js' import type { Client } from '../../clients/createClient.js' import type { Transport } from '../../clients/transports/createTransport.js' import { erc20Abi } from '../../constants/abis.js' import type { Tokens } from '../../tokens/defineToken.js' import type { Chain } from '../../types/chain.js' import { readContract } from '../public/readContract.js' import { type Amount, defineCall, type ReadParameters, resolveToken, resolveTokenWithDecimals, type TokenParameters, toAmount, } from './internal.js' /** * Gets the ERC-20 allowance a spender has over an account's tokens. * * @example * ```ts * import { createClient, http } from 'viem' * import { mainnet } from 'viem/chains' * import { token } from 'viem/actions' * * const client = createClient({ chain: mainnet, transport: http() }) * * const allowance = await token.getAllowance(client, { * account: '0x...', * spender: '0x...', * token: '0x...', * }) * ``` * * @param client - Client. * @param parameters - Parameters. * @returns The allowance, in base units and human-readable form. */ export async function getAllowance< chain extends Chain | undefined, account extends Account | undefined, tokens extends Tokens | undefined = undefined, >( client: Client<Transport, chain, account, undefined, undefined, tokens>, parameters: getAllowance.Parameters<chain, tokens>, ): Promise<getAllowance.ReturnValue> { const { account, decimals, spender, token, ...rest } = parameters const [amount, { decimals: resolved }] = await Promise.all([ readContract(client, { ...rest, ...getAllowance.call(client, { account, spender, token } as never), }), resolveTokenWithDecimals(client, { decimals, token, }), ]) return toAmount(amount as bigint, resolved) } export namespace getAllowance { export type Args< chain extends Chain | undefined = Chain | undefined, tokens extends Tokens | undefined = Tokens | undefined, > = { /** Account that owns the tokens. */ account: Address /** Spender of the tokens. */ spender: Address } & TokenParameters<chain, tokens> export type Parameters< chain extends Chain | undefined = Chain | undefined, tokens extends Tokens | undefined = Tokens | undefined, > = ReadParameters & Args<chain, tokens> export type ReturnValue = Amount /** * Defines a call to the `allowance` function. * * Can be passed as a parameter to `multicall`, `simulateContract`, or any * other action that accepts a contract call. The token is selected by `token` * symbol (resolved from the client's `tokens` array) or contract address. * * @param client - Client. * @param args - Arguments. * @returns The call. */ export function call< chain extends Chain | undefined, account extends Account | undefined, tokens extends Tokens | undefined = undefined, >( client: Client<Transport, chain, account, undefined, undefined, tokens>, args: Args<chain, tokens>, ) { return defineCall({ address: resolveToken(client, args).address, abi: erc20Abi, functionName: 'allowance', args: [args.account, args.spender], }) } }