@curvefi/api

中文文档
2.72.6发布于 2026/11/10MITTypeScriptES Module构建来源已验证近 30 天下载 1.2万

JavaScript library for curve.finance

原始使用文档
文档目录22 节
  1. Setup
  2. Init
  3. Notes
  4. General methods
  5. Pools
  6. Available pools
  7. Building a pool from external data (getPoolByData)
  8. Meta pools: base pool dependencies
  9. Pool fields
  10. Wallet balances for pool
  11. Stats
  12. Deposit
  13. Staking
  14. Withdraw
  15. Withdraw imbalance
  16. Withdraw one coin
  17. Swap
  18. BigInt methods
  19. Getting method ABI metadata
  20. Deposit & Stake
  21. Router
  22. FastBridge

Curve JS

Setup

Install from npm:

npm install @curvefi/api

Init

import curve from "@curvefi/api";

(async () => {
    // 1. Dev
    await curve.init('JsonRpc', {url: 'http://localhost:8545/', privateKey: ''}, { gasPrice: 0, maxFeePerGas: 0, maxPriorityFeePerGas: 0, chainId: 1 });
    // OR
    await curve.init('JsonRpc', {}, {}); // In this case JsonRpc url, privateKey, fee data and chainId will be specified automatically

    // 2. Infura
    await curve.init("Infura", { network: "homestead", apiKey: <INFURA_KEY> }, { chainId: 1 });
    
    // 3. Web3 provider
    await curve.init('Web3', { externalProvider: <WEB3_PROVIDER> }, { chainId: 1 });

    // 4. Without RPC
    await curve.init('NoRPC', {chainId: 1, networkName: 'ETHEREUM'});

    // 5. API-only metadata (RPC stays live for quotes/routing)
    await curve.init('JsonRpc', { url: <RPC_URL> }, { chainId: 1, apiOnlyMetadata: true });

    // Fetch factory pools
    await curve.factory.fetchPools();
    await curve.crvUSDFactory.fetchPools();
    await curve.cryptoFactory.fetchPools();
    await curve.twocryptoFactory.fetchPools();
    await curve.tricryptoFactory.fetchPools();
    await curve.stableNgFactory.fetchPools(); 
})()

Note 1. chainId parameter is optional, but you must specify it in the case you use Metamask on localhost network, because Metamask has that bug

Note 2. Web3 init requires the address. Therefore, it can be initialized only after receiving the address.

Note 3. apiOnlyMetadata (default false) makes the library source pool metadata and TVL exclusively from the HTTP APIs, with no on-chain reads during fetchPools or route-graph building. Unlike NoRPC, the RPC provider stays live and is still used for user-facing quotes/routing — this is intended for backends that want to avoid hammering RPC nodes (e.g. rate-limited public endpoints) while initializing and listing pools. Two effects to be aware of:

  • Factory gauge implementations are not read on-chain (gaugeImplementation() returns the zero address).
  • Pools with no TVL in the API — including LLAMMAs, whose TVL is on-chain-only — are treated as 0 liquidity and therefore excluded from the route graph, instead of falling back to on-chain liquidity reads.

Wrong ❌️

import type { FunctionComponent } from 'react'
import { useState, useMemo } from 'react'
import { providers } from 'ethers'
import Onboard from 'bnc-onboard'
import type { Wallet } from 'bnc-onboard/dist/src/interfaces'
import curve from '@curvefi/api'

    ...

const WalletProvider: FunctionComponent = ({ children }) => {
    const [wallet, setWallet] = useState<Wallet>()
    const [provider, setProvider] = useState<providers.Web3Provider>()
    const [address, setAddress] = useState<string>()

    const networkId = 1

    const onboard = useMemo(
        () =>
            Onboard({
                dappId: DAPP_ID,
                networkId,

                subscriptions: {
                    address: (address) => {
                        setAddress(address)
                    },

                    wallet: (wallet) => {
                        setWallet(wallet)
                        if (wallet.provider) {
                            curve.init("Web3", { externalProvider: wallet.provider }, { chainId: networkId })
                        }
                    },
                },
                walletSelect: {
                    wallets: wallets,
                },
            }),
        []
    )

    ...

Right ✔️

import type { FunctionComponent } from 'react'
import { useState, useMemo, useEffect } from 'react'
import { providers } from 'ethers'
import Onboard from 'bnc-onboard'
import type { Wallet } from 'bnc-onboard/dist/src/interfaces'
import curve from '@curvefi/api'

    ...

const WalletProvider: FunctionComponent = ({ children }) => {
    const [wallet, setWallet] = useState<Wallet>()
    const [provider, setProvider] = useState<providers.Web3Provider>()
    const [address, setAddress] = useState<string>()

    const networkId = 1

    const onboard = useMemo(
        () =>
            Onboard({
                dappId: DAPP_ID,
                networkId,

                subscriptions: {
                    address: (address) => {
                        setAddress(address)
                    },

                    wallet: (wallet) => {
                        setWallet(wallet)
                    },
                },
                walletSelect: {
                    wallets: wallets,
                },
            }),
        []
    )

    useEffect(() => {
        if (address && wallet?.provider) {
            curve.init("Web3", { externalProvider: wallet.provider }, { chainId: networkId })
        }
    }, [address, wallet?.provider]);

    ...

Notes

  • 1 Amounts can be passed in args either as numbers or strings.
  • 2 depositOrWithdrawBonus and swapPriceImpact methods return %, e. g. 0 < bonus/priceImpact <= 100
  • 3 Slippage arg should be passed as %, e. g. 0 < slippage <= 100

General methods

import curve from "@curvefi/api";

(async () => {
    await curve.getTVL();
    // 7870819849.685552
    await curve.getVolume();
    // {
    //     totalVolume: 514893871.3481678,
    //     cryptoVolume: 162757004.96876568,
    //     cryptoShare: 31.609815930147377
    // }

    const balances1 = await curve.getBalances(['DAI', 'sUSD']);
    // OR const balances1 = await curve.getBalances(['0x6B175474E89094C44Da98b954EedeAC495271d0F', '0x57Ab1ec28D129707052df4dF418D58a2D46d5f51']);
    console.log(balances1);
    // [ '10000.0', '0.0' ]

    // You can specify addresses
    const balances2 = await curve.getBalances(['aDAI', 'aSUSD'], "0x0063046686E46Dc6F15918b61AE2B121458534a5", "0x66aB6D9362d4F35596279692F0251Db635165871");
    // OR const balances2 = await curve.getBalances(['0x028171bCA77440897B824Ca71D1c56caC55b68A3', '0x6c5024cd4f8a59110119c56f8933403a539555eb'], ["0x0063046686E46Dc6F15918b61AE2B121458534a5", "0x66aB6D9362d4F35596279692F0251Db635165871"]);
    console.log(balances2);
    // {
    //     '0x0063046686E46Dc6F15918b61AE2B121458534a5': [ '0.0', '0.0' ],
    //     '0x66aB6D9362d4F35596279692F0251Db635165871': [ '0.0', '0.0' ]
    // }

    
    const spender = "0xbEbc44782C7dB0a1A60Cb6fe97d0b483032FF1C7" // 3pool swap address

    await curve.getAllowance(["DAI", "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"], curve.signerAddress, spender);
    // [ '0.0', '0.0' ]
    await curve.hasAllowance(["DAI", "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"], ['1000', '1000'], curve.signerAddress, spender);
    // false
    await curve.ensureAllowance(["DAI", "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"], ['1000', '1000'], spender);
    // [
    //     '0xb0cada2a2983dc0ed85a26916d32b9caefe45fecde47640bd7d0e214ff22aed3',
    //     '0x00ea7d827b3ad50ce933e96c579810cd7e70d66a034a86ec4e1e10005634d041'
    // ]
    
    // Get populated approve transactions (without executing)
    const approveTxs = await curve.populateApprove(["DAI", "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"], ['1000', '1000'], spender);
    // OR with custom user address (for API): 
    // await curve.populateApprove(["DAI", "USDC"], ['1000', '1000'], spender, false, '0x...userAddress');
    // Returns array of TransactionLike objects (may include reset to 0 if needed for some tokens)
    console.log(approveTxs);
    // [
    //   { to: '0x6B17...', data: '0x095ea7b3...', hash: '0x...', ... },
    //   { to: '0xA0b8...', data: '0x095ea7b3...', hash: '0x...', ... }
    // ]
})()

Pools

Available pools

import curve from "@curvefi/api";

(async () => {
    await curve.init('JsonRpc', {}, { gasPrice: 0, maxFeePerGas: 0, maxPriorityFeePerGas: 0 });
    await curve.factory.fetchPools();
    await curve.crvUSDFactory.fetchPools();
    await curve.cryptoFactory.fetchPools();
    await curve.twocryptoFactory.fetchPools();
    await curve.tricryptoFactory.fetchPools();
    await curve.stableNgFactory.fetchPools();

    curve.getMainPoolList();
    // [
    //     'compound', 'usdt',    'y',          'busd',
    //     'susd',     'pax',     'ren',        'sbtc',
    //     'hbtc',     '3pool',   'gusd',       'husd',
    //     'usdk',     'usdn',    'musd',       'rsv',
    //     'tbtc',     'dusd',    'pbtc',       'bbtc',
    //     'obtc',     'seth',    'eurs',       'ust',
    //     'aave',     'steth',   'saave',      'ankreth',
    //     'usdp',     'ib',      'link',       'tusd',
    //     'frax',     'lusd',    'busdv2',     'reth',
    //     'alusd',    'mim',     'tricrypto2', 'eurt',
    //     'eurtusd',  'eursusd', 'crveth',     'rai',
    //     'cvxeth',   'xautusd', 'spelleth',   'teth',
    //     '2pool',    '4pool'
    // ]
    
    curve.factory.getPoolList();
    // [
    //     'factory-v2-0',   'factory-v2-2',   'factory-v2-3',   'factory-v2-4',
    //     'factory-v2-5',   'factory-v2-6',   'factory-v2-7',   'factory-v2-8',
    //     'factory-v2-9',   'factory-v2-10',  'factory-v2-11',  'factory-v2-14',
    //     'factory-v2-15',  'factory-v2-17',  'factory-v2-18',  'factory-v2-19',
    //     'factory-v2-21',  'factory-v2-22',  'factory-v2-23',  'factory-v2-24',
    //     'factory-v2-25',  'factory-v2-26',  'factory-v2-27',  'factory-v2-28',
    //     'factory-v2-29',  'factory-v2-30',  'factory-v2-31',  'factory-v2-32',
    //     'factory-v2-33',  'factory-v2-34',  'factory-v2-35',  'factory-v2-36',
    //     'factory-v2-37',  'factory-v2-38',  'factory-v2-39',  'factory-v2-40',
    //     'factory-v2-41',  'factory-v2-42',  'factory-v2-43',  'factory-v2-44',
    //     'factory-v2-45',  'factory-v2-46',  'factory-v2-47',  'factory-v2-48',
    //     'factory-v2-49',  'factory-v2-50',  'factory-v2-51',  'factory-v2-52',
    //     'factory-v2-53',  'factory-v2-54',  'factory-v2-55',  'factory-v2-56',
    //     'factory-v2-57',  'factory-v2-58',  'factory-v2-59',  'factory-v2-60',
    //     'factory-v2-61',  'factory-v2-62',  'factory-v2-63',  'factory-v2-64',
    //     'factory-v2-65',  'factory-v2-66',  'factory-v2-67',  'factory-v2-68',
    //     'factory-v2-69',  'factory-v2-70',  'factory-v2-71',  'factory-v2-72',
    //     'factory-v2-73',  'factory-v2-74',  'factory-v2-75',  'factory-v2-76',
    //     'factory-v2-77',  'factory-v2-78',  'factory-v2-79',  'factory-v2-80',
    //     'factory-v2-81',  'factory-v2-82',  'factory-v2-83',  'factory-v2-84',
    //     'factory-v2-85',  'factory-v2-86',  'factory-v2-87',  'factory-v2-88',
    //     'factory-v2-89',  'factory-v2-90',  'factory-v2-91',  'factory-v2-92',
    //     'factory-v2-93',  'factory-v2-94',  'factory-v2-95',  'factory-v2-96',
    //     'factory-v2-97',  'factory-v2-98',  'factory-v2-99',  'factory-v2-100',
    //     'factory-v2-101', 'factory-v2-102', 'factory-v2-103', 'factory-v2-104',
    //     ... 27 more items
    // ]

    curve.crvUSDFactory.getPoolList();
    // ['factory-crvusd-0',  'factory-crvusd-1',  'factory-crvusd-2', 'factory-crvusd-3']
    
    curve.cryptoFactory.getPoolList();
    // [
    //     'factory-crypto-0',  'factory-crypto-1',  'factory-crypto-2',
    //     'factory-crypto-3',  'factory-crypto-4',  'factory-crypto-5',
    //     'factory-crypto-6',  'factory-crypto-7',  'factory-crypto-8',
    //     'factory-crypto-9',  'factory-crypto-10', 'factory-crypto-11',
    //     'factory-crypto-12', 'factory-crypto-13', 'factory-crypto-14',
    //     'factory-crypto-15', 'factory-crypto-16', 'factory-crypto-17',
    //     'factory-crypto-18', 'factory-crypto-19', 'factory-crypto-20',
    //     'factory-crypto-21', 'factory-crypto-22', 'factory-crypto-23',
    //     'factory-crypto-24', 'factory-crypto-25', 'factory-crypto-26',
    //     'factory-crypto-27', 'factory-crypto-28', 'factory-crypto-29',
    //     'factory-crypto-30', 'factory-crypto-31', 'factory-crypto-32',
    //     'factory-crypto-33', 'factory-crypto-34', 'factory-crypto-35',
    //     'factory-crypto-36', 'factory-crypto-37', 'factory-crypto-38',
    //     'factory-crypto-39', 'factory-crypto-40', 'factory-crypto-41',
    //     'factory-crypto-42', 'factory-crypto-43', 'factory-crypto-44',
    //     'factory-crypto-45', 'factory-crypto-46', 'factory-crypto-47',
    //     'factory-crypto-48', 'factory-crypto-49', 'factory-crypto-50',
    //     'factory-crypto-51', 'factory-crypto-52', 'factory-crypto-53',
    //     'factory-crypto-54', 'factory-crypto-55', 'factory-crypto-56',
    //     'factory-crypto-57', 'factory-crypto-58', 'factory-crypto-59',
    //     'factory-crypto-60', 'factory-crypto-61', 'factory-crypto-62'
    // ]

    curve.twocryptoFactory.getPoolList();
    // ['factory-twocrypto-0', 'factory-twocrypto-1']
    
    curve.tricryptoFactory.getPoolList();
    // ['factory-tricrypto-0', 'factory-tricrypto-1']

    curve.stableNgFactory.getPoolList();
    // ['factory-stable-ng-0', 'factory-stable-ng-1']
    
    curve.getPoolList();
    // [
    //     'compound',      'usdt',          'y',             'busd',
    //     'susd',          'pax',           'ren',           'sbtc',
    //     'hbtc',          '3pool',         'gusd',          'husd',
    //     'usdk',          'usdn',          'musd',          'rsv',
    //     'tbtc',          'dusd',          'pbtc',          'bbtc',
    //     'obtc',          'seth',          'eurs',          'ust',
    //     'aave',          'steth',         'saave',         'ankreth',
    //     'usdp',          'ib',            'link',          'tusd',
    //     'frax',          'lusd',          'busdv2',        'reth',
    //     'alusd',         'mim',           'tricrypto2',    'eurt',
    //     'eurtusd',       'eursusd',       'crveth',        'rai',
    //     'cvxeth',        'xautusd',       'spelleth',      'teth',
    //     '2pool',         '4pool',         'fraxusdc',      'euroc',
    //     'frxeth',        'sbtc2',         'fraxusdp',      'wbeth',
    //     'factory-v2-2',  'factory-v2-3',  'factory-v2-5',  'factory-v2-7',
    //     'factory-v2-9',  'factory-v2-10', 'factory-v2-11', 'factory-v2-14',
    //     'factory-v2-21', 'factory-v2-22', 'factory-v2-23', 'factory-v2-24',
    //     'factory-v2-25', 'factory-v2-27', 'factory-v2-28', 'factory-v2-29',
    //     'factory-v2-30', 'factory-v2-31', 'factory-v2-32', 'factory-v2-33',
    //     'factory-v2-34', 'factory-v2-35', 'factory-v2-37', 'factory-v2-38',
    //     'factory-v2-41', 'factory-v2-42', 'factory-v2-43', 'factory-v2-44',
    //     'factory-v2-45', 'factory-v2-47', 'factory-v2-48', 'factory-v2-49',
    //     'factory-v2-50', 'factory-v2-51', 'factory-v2-52', 'factory-v2-53',
    //     'factory-v2-55', 'factory-v2-56', 'factory-v2-57', 'factory-v2-58',
    //     'factory-v2-59', 'factory-v2-60', 'factory-v2-61', 'factory-v2-62',
    //     ... 493 more items
    // ]
})()

Building a pool from external data (getPoolByData)

curve.getPoolByData(data) builds a fully working pool from an externally supplied descriptor, without calling fetchPools first. Use it when the pool metadata comes from your own source (backend, cache, DB) instead of Curve's API. curve resolves all the ABIs (swap / gauge / zap / LP) itself from poolType + implementationAddress + isMetaPool — you don't pass any ABI.

The descriptor (IExternalPoolData) mirrors the shape of the getPools/{network}/{poolType} API:

interface IExternalPoolData {
    poolType: 'factory' | 'factory-crvusd' | 'factory-crypto' | 'factory-twocrypto' | 'factory-tricrypto' | 'factory-stable-ng',
    address: string,                                                          // swap address
    coins: { address: string, symbol: string, decimals: number | string }[],
    id?: string,                                                              // registry handle; defaults to address
    name?: string,
    symbol?: string,
    lpTokenAddress?: string,                                                  // separate LP token for old crypto pools; defaults to address
    gaugeAddress?: string,
    implementationAddress?: string,                                           // REQUIRED for 'factory' (old stable) and 'factory-tricrypto'
    isMetaPool?: boolean,
    basePoolAddress?: string,                                                 // REQUIRED when isMetaPool
    assetTypeName?: string,
}
import curve from "@curvefi/api";

(async () => {
    await curve.init('JsonRpc', {}, { gasPrice: 0, maxFeePerGas: 0, maxPriorityFeePerGas: 0 });

    const pool = curve.getPoolByData({
        poolType: 'factory-stable-ng',
        address: '0x...',
        isMetaPool: false,
        coins: [
            { address: '0x...', symbol: 'USDC', decimals: 6 },
            { address: '0x...', symbol: 'USDT', decimals: 6 },
        ],
    });

    // From here the pool behaves exactly like one returned by curve.getPool(...)
    pool.underlyingCoins;      // ['USDC', 'USDT']
    await pool.deposit(['1', '1']);
})()

Meta pools: base pool dependencies

A meta pool is built on top of a base pool, and its descriptor does not carry the base pool's coins/decimals — so the base pool must already be present in the instance before you build the meta pool. If the base is a plain/main pool (e.g. 3pool) it is always available right after init, but if the base is itself a factory pool you must build it first.

Two helpers let the frontend resolve this without try/catch:

  • curve.isBasePoolsReady(data): boolean — true if the pool can be built right now (always true for non-meta pools).
  • curve.getRequiredBasePools(data): string[] — addresses of the base pools that still need to be built (empty ⇒ ready).

The base pool address is derived from the descriptor (basePoolAddress, or the last coin for crypto meta pools). The frontend looks that address up in its own data, builds it, and re-checks:

// Recursively make sure every base pool of `data` is initialized, then build the pool.
function ensurePool(data) {
    if (!curve.isBasePoolsReady(data)) {
        for (const baseAddress of curve.getRequiredBasePools(data)) {
            const baseData = myDataSource.getByAddress(baseAddress); // your descriptor for the base pool
            ensurePool(baseData);                                    // base may itself be a meta pool
        }
    }
    return curve.getPoolByData(data);
}

const pool = ensurePool(metaDescriptor);

The typical frontend loop:

if (!curve.isBasePoolsReady(desc)) {
    const need = curve.getRequiredBasePools(desc);        // e.g. ['0x383e…']
    need.forEach((addr) => curve.getPoolByData(myDataSource.getByAddress(addr)));
    // curve.isBasePoolsReady(desc) === true now
}
const pool = curve.getPoolByData(desc);

As a safety net, if you call getPoolByData on a meta pool before its base is ready it throws an error carrying the missing addresses on error.missingBasePools.

Pool fields

import curve from "@curvefi/api";

(async () => {
    await curve.init('JsonRpc', {}, { gasPrice: 0, maxFeePerGas: 0, maxPriorityFeePerGas: 0 });
    await curve.factory.fetchPools();
    await curve.crvUSDFactory.fetchPools();
    await curve.cryptoFactory.fetchPools();
    await curve.twocryptoFactory.fetchPools();
    await curve.tricryptoFactory.fetchPools();
    await curve.stableNgFactory.fetchPools();
    
    const pool = curve.getPool('factory-v2-11');

    pool.id;
    // factory-v2-11
    pool.name;
    // FEI Metapool
    pool.fullName;
    // Curve.finance Factory USD Metapool: FEI Metapool
    pool.symbol;
    // FEI3CRV3CRV-f
    pool.referenceAsset;
    // USD
    pool.address;
    // 0x06cb22615ba53e60d67bf6c341a0fd5e718e1655
    pool.lpToken;
    // 0x06cb22615ba53e60d67bf6c341a0fd5e718e1655
    pool.gauge;
    // 0xdc69d4cb5b86388fff0b51885677e258883534ae
    pool.zap;
    // 0xa79828df1850e8a3a3064576f380d90aecdd3359
    pool.sRewardContract;
    // null
    pool.rewardContract;
    // null
    pool.isPlain;
    // false
    pool.isLending;
    // false
    pool.isMeta;
    // true
    pool.isCrypto;
    // false
    pool.isFake;
    // false
    pool.isFactory;
    // true
    pool.basePool;
    // 3pool
    pool.underlyingCoins;
    // [ 'FEI', 'DAI', 'USDC', 'USDT' ]
    pool.wrappedCoins;
    // [ 'FEI', '3Crv' ]
    pool.underlyingCoinAddresses;
    // [
    //     '0x956f47f50a910163d8bf957cf5846d573e7f87ca',
    //     '0x6b175474e89094c44da98b954eedeac495271d0f',
    //     '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48',
    //     '0xdac17f958d2ee523a2206206994597c13d831ec7'
    // ]
    pool.wrappedCoinAddresses;
    // [
    //     '0x956f47f50a910163d8bf957cf5846d573e7f87ca',
    //     '0x6c3f90f043a72fa612cbac8115ee7e52bde6e490'
    // ]
    pool.underlyingDecimals;
    // [ 18, 18, 6, 6 ]
    pool.wrappedDecimals;
    // [ 18, 18 ]
    pool.useLending;
    // [ false, false, false, false ]
    pool.inApi;
    // true
    await pool.isGaugeKilled();
    // false
})()

Wallet balances for pool

import curve from "@curvefi/api";

(async () => {
    await curve.init('JsonRpc', {}, { gasPrice: 0, maxFeePerGas: 0, maxPriorityFeePerGas: 0 });
    
    const saave = curve.getPool('saave');
    
    // 1. Current address (signer) balances

    await saave.wallet.balances();
    // {
    //     lpToken: '0.0',
    //     gauge: '0.0',
    //     '0x6B175474E89094C44Da98b954EedeAC495271d0F': '10000.0',
    //     '0x57Ab1ec28D129707052df4dF418D58a2D46d5f51': '10000.0',
    //     '0x028171bCA77440897B824Ca71D1c56caC55b68A3': '10000.00017727177059715',
    //     '0x6c5024cd4f8a59110119c56f8933403a539555eb': '10000.000080108429034461'
    // }


    await saave.wallet.lpTokenBalances();
    // { lpToken: '0.0', gauge: '0.0' }

    await saave.wallet.underlyingCoinBalances();
    // {
    //     '0x6B175474E89094C44Da98b954EedeAC495271d0F': '10000.0',
    //     '0x57Ab1ec28D129707052df4dF418D58a2D46d5f51': '10000.0'
    // }

    await saave.wallet.wrappedCoinBalances();
    // {
    //     '0x028171bCA77440897B824Ca71D1c56caC55b68A3': '10000.00017727177059715',
    //     '0x6c5024cd4f8a59110119c56f8933403a539555eb': '10000.000080108429034461'
    // }

    await saave.wallet.allCoinBalances();
    // {
    //     '0x6B175474E89094C44Da98b954EedeAC495271d0F': '10000.0',
    //     '0x57Ab1ec28D129707052df4dF418D58a2D46d5f51': '10000.0',
    //     '0x028171bCA77440897B824Ca71D1c56caC55b68A3': '10000.00017727177059715',
    //     '0x6c5024cd4f8a59110119c56f8933403a539555eb': '10000.000080108429034461'
    // }


    // 2. For every method above you can specify the address
    
    await saave.wallet.balances("0x0063046686E46Dc6F15918b61AE2B121458534a5");
    // {
    //     lpToken: '0.0',
    //     gauge: '0.0',
    //     '0x6B175474E89094C44Da98b954EedeAC495271d0F': '0.0',
    //     '0x57Ab1ec28D129707052df4dF418D58a2D46d5f51': '0.0',
    //     '0x028171bCA77440897B824Ca71D1c56caC55b68A3': '0.0',
    //     '0x6c5024cd4f8a59110119c56f8933403a539555eb': '0.0'
    // }

    // Or several addresses
    await saave.wallet.balances("0x0063046686E46Dc6F15918b61AE2B121458534a5", "0x66aB6D9362d4F35596279692F0251Db635165871");
    // {
    //     '0x0063046686E46Dc6F15918b61AE2B121458534a5': {
    //         lpToken: '0.0',
    //         gauge: '0.0',
    //         '0x6B175474E89094C44Da98b954EedeAC495271d0F': '0.0',
    //         '0x57Ab1ec28D129707052df4dF418D58a2D46d5f51': '0.0',
    //         '0x028171bCA77440897B824Ca71D1c56caC55b68A3': '0.0',
    //         '0x6c5024cd4f8a59110119c56f8933403a539555eb': '0.0'
    //     },
    //     '0x66aB6D9362d4F35596279692F0251Db635165871': {
    //         lpToken: '0.0',
    //         gauge: '0.0',
    //         '0x6B175474E89094C44Da98b954EedeAC495271d0F': '10000.0',
    //         '0x57Ab1ec28D129707052df4dF418D58a2D46d5f51': '10000.0',
    //         '0x028171bCA77440897B824Ca71D1c56caC55b68A3': '10000.00017727177059715',
    //         '0x6c5024cd4f8a59110119c56f8933403a539555eb': '10000.000080108429034461'
    //     }
    // }
})()

Stats

import curve from "@curvefi/api";

(async () => {
    await curve.init('JsonRpc', {}, { gasPrice: 0, maxFeePerGas: 0, maxPriorityFeePerGas: 0 });
    
    
    // --- COMPOUND ---

    const compound = curve.getPool('compound');
    
    await compound.stats.parameters();
    // {
    //     lpTokenSupply: '66658430.461661546713781772',
    //     virtualPrice: '1.107067773320466717',
    //     fee: '0.04',
    //     adminFee: '0.02',
    //     A: '4500',
    //     future_A: '4500',
    //     initial_A: undefined,
    //     future_A_time: undefined,
    //     initial_A_time: undefined,
    //     gamma: undefined
    // }
    
    await compound.stats.underlyingBalances();
    // [ '66625943.103442629270215258', '33124832.500932' ]
    
    await compound.stats.wrappedBalances();
    // [ '3026076723.05777297', '1464830413.37972924' ]

    await compound.stats.totalLiquidity();
    // 99836271.3031733

    // --- STETH ---
    
    const steth = curve.getPool('steth');
    
    await steth.stats.volume();
    // 174737430.35185483

    await curve.getPoolVolumes();
    // {
    //     '0xa2b47e3d5c44877cca798226b7b8118f9bfb7a56': '123456789.123',
    //     '0xdc24316b9ae028f1497c275eb9192a3ea0f67022': '174737430.35185483',
    //     ...
    // }

    await steth.stats.baseApy();
    // { day: '3.1587592896017647', week: '2.6522145719060752' } (as %)
    
    await steth.stats.tokenApy();
    // [ '0.5918', '1.4796' ] (as %)
    
    await steth.stats.rewardsApy();
    // [
    //     {
    //         gaugeAddress: '0x182b723a58739a9c974cfdb385ceadb237453c28',
    //         tokenAddress: '0x5A98FcBEA516Cf06857215779Fd812CA3beF1B32',
    //         tokenPrice: 1.023,
    //         name: 'Lido DAO Token',
    //         symbol: 'LDO',
    //         decimals: '18',
    //         apy: 2.6446376845647155 (as %)
    //     }
    // ]
    
})()

Deposit

(async () => {
    await curve.init('JsonRpc', {}, { gasPrice: 0, maxFeePerGas: 0, maxPriorityFeePerGas: 0 });

    const pool = curve.getPool('mim');

    
    // --- UNDERLYING ---

    
    await pool.wallet.underlyingCoinBalances();
    // {
    //     '0x99d8a9c45b2eca8864373a26d1459e3dff1e17f3': '10000.0',
    //     '0x6b175474e89094c44da98b954eedeac495271d0f': '10000.0',
    //     '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48': '10000.0',
    //     '0xdac17f958d2ee523a2206206994597c13d831ec7': '10000.0',
    // }
    await pool.wallet.lpTokenBalances();
    // { lpToken: '0.0', gauge: '0.0' }

    await pool.depositBalancedAmounts();
    // [
    //     '10000.000000000000000000',
    //     '785.167649368248476094',
    //     '771.263652',
    //     '2234.662927'
    // ]
    await pool.depositExpected([100, 100, 100, 100]);
    // 397.546626854200557344
    await pool.depositBonus([100, 100, 100, 100]);
    // 0.04489060058668274
    await pool.depositIsApproved([100, 100, 100, 100]);
    // false
    await pool.depositApprove([100, 100, 100, 100]);
    // [
    //     '0xd3bb4266a9004b4c42d41984d65cce65050a216564dcefa852bbe29f0466bc32',
    //     '0xb2e67fb6cc0d4cef18e918bccf85248a30aa5c318220e8c3887f5f936599e639',
    //     '0x6d523d348ef1dc24e4a61830476f3c5e4450e8e2c91d903f9e0272efc73f5af8',
    //     '0xe2c7bd884b91011791d0e979b9511ca035efee60a5c23b7f5623d490250ca4b2'
    // ]
    await pool.deposit(['100', '100', '100', '100'], 0.1); // slippage = 0.1 %
    // 0x8202a2fd645d6b9bc2c6f47aa3475d61bcfd5905def125e8287cb47f3f86db75
    
    // {
    //     '0x99d8a9c45b2eca8864373a26d1459e3dff1e17f3': '9900.0',
    //     '0x6b175474e89094c44da98b954eedeac495271d0f': '9900.0',
    //     '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48': '9900.0',
    //     '0xdac17f958d2ee523a2206206994597c13d831ec7': '9900.0',
    // }
    // { lpToken: '397.465346370726773487', gauge: '0.0' }
    
    
    // --- WRAPPED ---
    
    
    await pool.wallet.wrappedCoinBalances();
    // {
    //     '0x99d8a9c45b2eca8864373a26d1459e3dff1e17f3': '9900.0',
    //     '0x6c3f90f043a72fa612cbac8115ee7e52bde6e490': '100000.0'
    // }
    await pool.wallet.lpTokenBalances();
    // { lpToken: '397.465346370726773487', gauge: '0.0' }
    
    await pool.depositWrappedBalancedAmounts();
    // [ '9900.000000000000000000', '3674.037213475177850341' ]
    await pool.depositWrappedExpected(['100', '100']);
    // 200.853415578798484973
    await pool.depositWrappedBonus([100, 100]);
    // 0.5057286575144729
    await pool.depositWrappedIsApproved([100, 100]);
    // false
    await pool.depositWrappedApprove([100, 100]);
    // [
    //     '0xe8eb519833d417dcd8da1ee3c4fcadf30dece560b7e1977a5f78c995f8e72b4b',
    //     '0xd7d02b26a052f755bed033a880745ff58775d4668d7620042b6e5973e90ba574'
    // ]
    await pool.depositWrapped([100, 100], 0.1); // slippage = 0.1 %
    // 0x78b943a9a1082cd07ddb0225b070e934740448bfa10444b00cd00e7368ad0601
    
    // {
    //     '0x99d8a9c45b2eca8864373a26d1459e3dff1e17f3': '9800.0',
    //     '0x6c3f90f043a72fa612cbac8115ee7e52bde6e490': '99900.0'
    // }
    // { lpToken: '598.300246031617065027', gauge: '0.0' }
})()

Staking

(async () => {
    await curve.init('JsonRpc', {}, { gasPrice: 0 });

    const pool = curve.getPool('mim');
    
    const balances = await pool.wallet.lpTokenBalances() as IDict<string>;
    // { lpToken: '598.300246031617065027', gauge: '0.0' }
    
    await pool.stakeIsApproved(balances.lpToken);
    // false
    await pool.stakeApprove(balances.lpToken);
    // [
    //     '0x9d5011800bb4afe82b3a97a56a55762f11b5e999c1de908f38a66f7425c0b0d0'
    // ]
    await pool.stake(balances.lpToken);
    // 0xf884b798be15295f090476eb9d13c46d09d8c05dc0e05d822a34120fa641f645

    await pool.wallet.lpTokenBalances();
    // { lpToken: '0.0', gauge: '598.300246031617065027' }
    
    await pool.unstake(balances.lpToken);
    // 0x802b96921f2fabb433e02489315850a81c1a2e180cd05d84a6d71ce9fc624020

    await pool.wallet.lpTokenBalances();
    // { lpToken: '598.300246031617065027', gauge: '0.0' }
})()

Withdraw

(async () => {
    await curve.init('JsonRpc', {}, { gasPrice: 0, maxFeePerGas: 0, maxPriorityFeePerGas: 0 });

    const pool = curve.getPool('mim');

    // --- UNDERLYING ---

    await pool.wallet.underlyingCoinBalances();
    // {
    //     '0x99d8a9c45b2eca8864373a26d1459e3dff1e17f3': '9800.0',
    //     '0x6b175474e89094c44da98b954eedeac495271d0f': '9900.0',
    //     '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48': '9900.0',
    //     '0xdac17f958d2ee523a2206206994597c13d831ec7': '9900.0'
    // }
    await pool.wallet.lpTokenBalances();
    // { lpToken: '598.300246031617065027', gauge: '0.0' }

    await pool.withdrawExpected(10);
    // [
    //     '7.299072252784503555',
    //     '0.573101727634383933',
    //     '0.562953',
    //     '1.631103'
    // ]
    await pool.withdrawIsApproved(10);
    // false
    await pool.withdrawApprove(10);
    // [
    //     '0xbc72529f860eab00ae6e72234a68c48c9bfa8e093813ecf6796d46de419badca'
    // ]
    await pool.withdraw('10', 0.1); // slippage = 0.1 %
    // 0x4dc3add45566e0f3404c2fa0b7aa27203688833ffbe9b985f36bf785d19e4fad

    // {
    //     '0x99d8a9c45b2eca8864373a26d1459e3dff1e17f3': '9807.299072252784503555',
    //     '0x6b175474e89094c44da98b954eedeac495271d0f': '9900.573101727634383932',
    //     '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48': '9900.562953',
    //     '0xdac17f958d2ee523a2206206994597c13d831ec7': '9901.631102'
    // }
    // { lpToken: '588.300246031617065027', gauge: '0.0' }

    // --- WRAPPED ---

    await pool.wallet.wrappedCoinBalances();
    // {
    //     '0x99d8a9c45b2eca8864373a26d1459e3dff1e17f3': '9807.299072252784503555',
    //     '0x6c3f90f043a72fa612cbac8115ee7e52bde6e490': '99900.0'
    // }
    await pool.wallet.lpTokenBalances();
    // { lpToken: '588.300246031617065027', gauge: '0.0' }

    await pool.withdrawWrappedExpected('10');
    // [ '7.299072252784503555', '2.708796226980363129' ]
    await pool.withdrawWrapped(10); // slippage = 0.5 % by default
    // 0x61f7b602bc52d20fdf473c8dd8cbea12f11918fdbd74c496235887c70321395a
    
    // {
    //     '0x99d8a9c45b2eca8864373a26d1459e3dff1e17f3': '9814.59814450556900711',
    //     '0x6c3f90f043a72fa612cbac8115ee7e52bde6e490': '99902.708796226980363129'
    // }
    // { lpToken: '578.300246031617065027', gauge: '0.0' }
})()

Withdraw imbalance

(async () => {
    await curve.init('JsonRpc', {}, { gasPrice: 0, maxFeePerGas: 0, maxPriorityFeePerGas: 0 });

    const pool = curve.getPool('mim');

    // --- UNDERLYING ---

    await pool.wallet.underlyingCoinBalances();
    // {
    //     '0x99d8a9c45b2eca8864373a26d1459e3dff1e17f3': '9814.59814450556900711',
    //     '0x6b175474e89094c44da98b954eedeac495271d0f': '9900.573101727634383932',
    //     '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48': '9900.562953',
    //     '0xdac17f958d2ee523a2206206994597c13d831ec7': '9901.631102'
    // }
    await pool.wallet.lpTokenBalances();
    // { lpToken: '578.300246031617065027', gauge: '0.0' }

    await pool.withdrawImbalanceExpected(['10', '10', '10', '10']);
    // 39.754662629184493064
    await pool.withdrawImbalanceBonus(['10', '10', '10', '10']);
    // -0.04487324436377509
    await pool.withdrawImbalanceIsApproved(['10', '10', '10', '10']);
    // true
    await pool.withdrawImbalanceApprove(['10', '10', '10', '10']);
    // []
    await pool.withdrawImbalance(['10', '10', '10', '10'], 0.1); // slippage = 0.1 %
    // 0xfba4dfb47cd5692ef01608e7b04439ec211cb28430b488e60fee5cadb77ac321

    // {
    //     '0x99d8a9c45b2eca8864373a26d1459e3dff1e17f3': '9824.59814450556900711',
    //     '0x6b175474e89094c44da98b954eedeac495271d0f': '9910.573101727634383932',
    //     '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48': '9910.562953',
    //     '0xdac17f958d2ee523a2206206994597c13d831ec7': '9911.631102'
    // }
    // { lpToken: '538.537454267261447723', gauge: '0.0' }

    // --- WRAPPED ---

    await pool.wallet.wrappedCoinBalances();
    // {
    //     '0x99d8a9c45b2eca8864373a26d1459e3dff1e17f3': '9824.59814450556900711',
    //     '0x6c3f90f043a72fa612cbac8115ee7e52bde6e490': '99902.708796226980363129'
    // }
    await pool.wallet.lpTokenBalances();
    // { lpToken: '538.537454267261447723', gauge: '0.0' }

    await pool.withdrawImbalanceWrappedExpected(['10', '10']);
    // 20.085341556879117658
    await pool.withdrawImbalanceWrappedBonus(['10', '10']);
    // -0.5031837243343519
    await pool.withdrawImbalanceWrapped(['10', '10'], 0.1); // slippage = 0.1 %
    // 0xb9e6174695152d7dbe274fec969ffd2d62c994cdbf58455e9954cddd0a8f7189

    // {
    //     '0x99d8a9c45b2eca8864373a26d1459e3dff1e17f3': '9834.59814450556900711',
    //     '0x6c3f90f043a72fa612cbac8115ee7e52bde6e490': '99912.708796226980363129'
    // }
    // { lpToken: '518.450261119283204342', gauge: '0.0' }
})()

Withdraw one coin

(async () => {
    await curve.init('JsonRpc', {}, { gasPrice: 0, maxFeePerGas: 0, maxPriorityFeePerGas: 0 });

    const pool = curve.getPool('mim');

    
    // --- UNDERLYING ---

    
    await pool.wallet.underlyingCoinBalances();
    // {
    //     '0x99d8a9c45b2eca8864373a26d1459e3dff1e17f3': '9834.59814450556900711',
    //     '0x6b175474e89094c44da98b954eedeac495271d0f': '9910.573101727634383932',
    //     '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48': '9910.562953',
    //     '0xdac17f958d2ee523a2206206994597c13d831ec7': '9911.631102'
    // }
    await pool.wallet.lpTokenBalances();
    // { lpToken: '518.450261119283204342', gauge: '0.0' }

    const underlyingExpected = await pool.withdrawOneCoinExpected(10, 'DAI');
    // OR const underlyingExpected = await pool.withdrawOneCoinExpected('10', '0x6B175474E89094C44Da98b954EedeAC495271d0F');
    // OR const underlyingExpected = await pool.withdrawOneCoinExpected('10', 1);
    console.log(underlyingExpected);
    // 10.053583529099204888
    await pool.withdrawOneCoinBonus(10, 'DAI');
    // -0.1256449500769996
    await pool.withdrawOneCoinIsApproved(10);
    // true
    await pool.withdrawOneCoinApprove(10);
    // []
    const underlyingTx = await pool.withdrawOneCoin(10, 'DAI', 0.1);
    // OR const underlyingTx = await pool.withdrawOneCoin('10', '0x6B175474E89094C44Da98b954EedeAC495271d0F');
    // OR const underlyingTx = await pool.withdrawOneCoin('10', 1);
    console.log(underlyingTx);
    //0x5b4c5ec49f53719b5440355439a2cad445935895b5c1034ae6092ebbe17f0328

    // {
    //     '0x99d8a9c45b2eca8864373a26d1459e3dff1e17f3': '9834.59814450556900711',
    //     '0x6b175474e89094c44da98b954eedeac495271d0f': '9920.62668525673358882',
    //     '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48': '9910.562953',
    //     '0xdac17f958d2ee523a2206206994597c13d831ec7': '9911.631102'
    // }
    // { lpToken: '508.450261119283204342', gauge: '0.0' }

    
    // --- WRAPPED ---

    
    await pool.wallet.wrappedCoinBalances();
    // {
    //     '0x99d8a9c45b2eca8864373a26d1459e3dff1e17f3': '9834.59814450556900711',
    //     '0x6c3f90f043a72fa612cbac8115ee7e52bde6e490': '99912.708796226980363129'
    // }
    await pool.wallet.lpTokenBalances();
    // { lpToken: '508.450261119283204342', gauge: '0.0' }

    const wrappedExpected = await pool.withdrawOneCoinWrappedExpected('10', 'MIM');
    // OR const wrappedExpected = await pool.withdrawOneCoinWrappedExpected('10', '0x99d8a9c45b2eca8864373a26d1459e3dff1e17f3');
    // OR const wrappedExpected = await pool.withdrawOneCoinWrappedExpected('10', 0);
    console.log(wrappedExpected)
    // 10.066854269984687383
    await pool.withdrawOneCoinWrappedBonus(10, 'MIM');
    // 0.5893939242941038
    const wrappedTx = await pool.withdrawOneCoinWrapped('10', 'MIM', 0.1);
    // OR await pool.withdrawOneCoinWrapped('10', '0x99d8a9c45b2eca8864373a26d1459e3dff1e17f3');
    // OR await pool.withdrawOneCoinWrapped('10', 0);
    console.log(wrappedTx);
    // 0xf82af519a3e4f0743c89fd1e93982934f1a2dde721221b00dd474f6b0a24f7f2

    // {
    //     '0x99d8a9c45b2eca8864373a26d1459e3dff1e17f3': '9844.664998775553694493',
    //     '0x6c3f90f043a72fa612cbac8115ee7e52bde6e490': '99912.708796226980363129'
    // }
    // { lpToken: '498.450261119283204342', gauge: '0.0' }
})()

Swap

(async () => {
    await curve.init('JsonRpc', {}, { gasPrice: 0, maxFeePerGas: 0, maxPriorityFeePerGas: 0 });

    const pool = curve.getPool('mim');

    
    // --- UNDERLYING ---

    
    await pool.wallet.underlyingCoinBalances();
    // {
    //     '0x99d8a9c45b2eca8864373a26d1459e3dff1e17f3': '9844.882755243317396535',
    //     '0x6b175474e89094c44da98b954eedeac495271d0f': '9930.611305190224186298',
    //     '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48': '9910.562953',
    //     '0xdac17f958d2ee523a2206206994597c13d831ec7': '9911.631102'
    // }

    const underlyingExpected = await pool.swapExpected('MIM','DAI', 10);
    // OR const underlyingExpected = await pool.swapExpected('0x99d8a9c45b2eca8864373a26d1459e3dff1e17f3', '0x6B175474E89094C44Da98b954EedeAC495271d0F', '10');
    // OR const underlyingExpected = await pool.swapExpected(0, 1, '10');
    console.log(underlyingExpected);
    // 9.984619933234026875
    const underlyingRequired = await pool.swapRequired('MIM', 'DAI', 10);
    // OR const underlyingRequired = await pool.swapRequired('0x99d8a9c45b2eca8864373a26d1459e3dff1e17f3', '0x6B175474E89094C44Da98b954EedeAC495271d0F', '10');
    // OR const underlyingRequired = await pool.swapRequired(0, 1, '10');
    console.log(underlyingRequired);
    //10.049378645129545758
    const underlyingPriceImpact = await pool.swapPriceImpact('MIM','DAI', 10);
    // OR const underlyingPriceImpact = await pool.swapPriceImpact('0x99d8a9c45b2eca8864373a26d1459e3dff1e17f3', '0x6B175474E89094C44Da98b954EedeAC495271d0F', '10');
    // OR const underlyingPriceImpact = await pool.swapPriceImpact(0, 1, '10');
    console.log(underlyingPriceImpact);
    // 0.000026 (as %)
    await pool.swapIsApproved('MIM', 10);
    // true
    await pool.swapApprove('MIM', 10);
    // []
    const swapTx = await pool.swap('MIM','DAI', 10, 0.1);
    // OR const swapTx = await pool.swap('0x99d8a9c45b2eca8864373a26d1459e3dff1e17f3', '0x6B175474E89094C44Da98b954EedeAC495271d0F', '10');
    // OR const swapTx = await pool.swap(0, 1, 10);
    console.log(swapTx);
    // 0xbcd0d1248e6a8571c2a45d4f7095bc1fece479b6e87219cdd7d239c4e1e0ca32

    // {
    //     '0x99d8a9c45b2eca8864373a26d1459e3dff1e17f3': '9834.882755243317396535',
    //     '0x6b175474e89094c44da98b954eedeac495271d0f': '9940.595925123458213173',
    //     '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48': '9910.562953',
    //     '0xdac17f958d2ee523a2206206994597c13d831ec7': '9911.631102'
    // }

    
    // --- WRAPPED ---

    
    await pool.wallet.wrappedCoinBalances();
    // {
    //     '0x99d8a9c45b2eca8864373a26d1459e3dff1e17f3': '9834.882755243317396535',
    //     '0x6c3f90f043a72fa612cbac8115ee7e52bde6e490': '99902.708796226980363129'
    // }

    const wrappedExpected = await pool.swapWrappedExpected('3crv','MIM', 10);
    // OR const wrappedExpected = await pool.swapWrappedExpected('0x6c3F90f043a72FA612cbac8115EE7e52BDe6E490', '0x99d8a9c45b2eca8864373a26d1459e3dff1e17f3', '10');
    // OR const wrappedExpected = await pool.swapWrappedExpected(1, 0, '10');
    console.log(wrappedExpected);
    // 10.217756467720521951
    const wrappedRequired = await pool.swapWrappedRequired('3crv', 'MIM', 10);
    // OR const wrappedRequired = await pool.swapWrappedRequired('0x6c3F90f043a72FA612cbac8115EE7e52BDe6E490', '0x99d8a9c45b2eca8864373a26d1459e3dff1e17f3', '10');
    // OR const wrappedRequired = await pool.swapWrappedRequired(1, 0, '10');
    console.log(wrappedRequired);
    //9.702940994847188442
    const wrappedPriceImpact = await pool.swapWrappedPriceImpact('3crv','MIM', 10);
    // OR const wrappedPriceImpact = await pool.swapWrappedPriceImpact('0x6c3F90f043a72FA612cbac8115EE7e52BDe6E490', '0x99d8a9c45b2eca8864373a26d1459e3dff1e17f3', '10');
    // OR const wrappedPriceImpact = await pool.swapWrappedPriceImpact(1, 0, '10');
    console.log(wrappedPriceImpact);
    // 0.000081 (as %)
    await pool.swapWrappedIsApproved('3crv', 10);
    // true
    await pool.swapWrappedApprove('3crv', 10);
    // []
    const swapWrappedTx = await pool.swapWrapped('3crv','MIM', 10, 0.1);
    // OR const swapWrappedTx = await pool.swapWrapped('0x6c3F90f043a72FA612cbac8115EE7e52BDe6E490', '0x99d8a9c45b2eca8864373a26d1459e3dff1e17f3', '10');
    // OR const swapWrappedTx = await pool.swapWrapped(1, 0, '10');
    console.log(swapWrappedTx);
    // 0x59ff5e44f083b57a1f612c1ad5ac7d3fe68b4c753ddd6400ab8bd6437485288c

    // {
    //     '0x99d8a9c45b2eca8864373a26d1459e3dff1e17f3': '9845.100511711037918486',
    //     '0x6c3f90f043a72fa612cbac8115ee7e52bde6e490': '99892.708796226980363129'
    // }
})()

BigInt methods

  • pool.swapExpectedBigInt(inputCoin, outputCoin, amount: bigint): Promise<bigint>
  • pool.swapWrappedExpectedBigInt(inputCoin, outputCoin, amount: bigint): Promise<bigint>
  • pool.depositExpectedBigInt(amounts: bigint[]): Promise<bigint>
  • pool.depositWrappedExpectedBigInt(amounts: bigint[]): Promise<bigint>
  • pool.withdrawExpectedBigInt(lpTokenAmount: bigint): Promise<bigint[]>
  • pool.withdrawWrappedExpectedBigInt(lpTokenAmount: bigint): Promise<bigint[]>
  • pool.withdrawOneCoinExpectedBigInt(lpTokenAmount: bigint, coin: string | number): Promise<bigint>
  • pool.withdrawOneCoinWrappedExpectedBigInt(lpTokenAmount: bigint, coin: string | number): Promise<bigint>

Getting method ABI metadata

(async () => {
    await curve.init('JsonRpc', {}, { gasPrice: 0, maxFeePerGas: 0, maxPriorityFeePerGas: 0 });

    const pool = curve.getPool('mim');

    // Get exact ABI information for deposit (underlying) without executing the transaction
    const depositInfo = await pool.abi.deposit();
    console.log(depositInfo);
    // {
    //     address: '0xa79828df1850e8a3a3064576f380d90aecdd3359',  // Contract address (zap or pool)
    //     method: 'add_liquidity',                                 // Method name
    //     abi: {
    //         type: 'function',
    //         name: 'add_liquidity',
    //         inputs: [
    //             { name: '_pool', type: 'address' },
    //             { name: '_deposit_amounts', type: 'uint256[4]' },
    //             { name: '_min_mint_amount', type: 'uint256' }
    //         ],
    //         outputs: [ { name: '', type: 'uint256' } ],
    //         stateMutability: 'nonpayable'
    //     }
    // }

    // Get exact ABI information for deposit wrapped without executing the transaction
    const depositWrappedInfo = await pool.abi.depositWrapped();
    console.log(depositWrappedInfo);
    // {
    //     address: '0x5a6a4d54456819380173272a5e8e9b9904bdf41b',  // Contract address (pool)
    //     method: 'add_liquidity',                                 // Method name
    //     abi: {
    //         type: 'function',
    //         name: 'add_liquidity',
    //         inputs: [
    //             { name: 'amounts', type: 'uint256[2]' },
    //             { name: 'min_mint_amount', type: 'uint256' }
    //         ],
    //         outputs: [ { name: '', type: 'uint256' } ],
    //         stateMutability: 'nonpayable'
    //     }
    // }

    // Get exact ABI information for withdrawOneCoin (underlying) without executing the transaction
    const withdrawOneCoinInfo = await pool.abi.withdrawOneCoin();
    console.log(withdrawOneCoinInfo);
    // {
    //     address: '0xa79828df1850e8a3a3064576f380d90aecdd3359',  // Contract address (zap or pool)
    //     method: 'remove_liquidity_one_coin',                     // Method name
    //     abi: {
    //         type: 'function',
    //         name: 'remove_liquidity_one_coin',
    //         inputs: [
    //             { name: '_pool', type: 'address' },
    //             { name: '_burn_amount', type: 'uint256' },
    //             { name: 'i', type: 'int128' },
    //             { name: '_min_amount', type: 'uint256' }
    //         ],
    //         outputs: [ { name: '', type: 'uint256' } ],
    //         stateMutability: 'nonpayable'
    //     }
    // }

    // Get exact ABI information for withdrawOneCoin wrapped without executing the transaction
    const withdrawOneCoinWrappedInfo = await pool.abi.withdrawOneCoinWrapped();
    console.log(withdrawOneCoinWrappedInfo);
    // {
    //     address: '0x5a6a4d54456819380173272a5e8e9b9904bdf41b',  // Contract address (pool)
    //     method: 'remove_liquidity_one_coin',                     // Method name
    //     abi: {
    //         type: 'function',
    //         name: 'remove_liquidity_one_coin',
    //         inputs: [
    //             { name: '_token_amount', type: 'uint256' },
    //             { name: 'i', type: 'int128' },
    //             { name: '_min_amount', type: 'uint256' }
    //         ],
    //         outputs: [ { name: '', type: 'uint256' } ],
    //         stateMutability: 'nonpayable'
    //     }
    // }

    // Get exact ABI information for swap (underlying) without executing the transaction
    const swapInfo = await pool.abi.swap();
    console.log(swapInfo);
    // {
    //     address: '0x5a6a4d54456819380173272a5e8e9b9904bdf41b',  // Contract address
    //     method: 'exchange_underlying',                           // Method name (exchange or exchange_underlying)
    //     abi: {
    //         type: 'function',
    //         name: 'exchange_underlying',
    //         inputs: [
    //             { name: 'i', type: 'int128' },
    //             { name: 'j', type: 'int128' },
    //             { name: 'dx', type: 'uint256' },
    //             { name: 'min_dy', type: 'uint256' }
    //         ],
    //         outputs: [ { name: '', type: 'uint256' } ],
    //         stateMutability: 'nonpayable'
    //     }
    // }

    // Get exact ABI information for swap wrapped without executing the transaction
    const swapWrappedInfo = await pool.abi.swapWrapped();
    console.log(swapWrappedInfo);
    // {
    //     address: '0x5a6a4d54456819380173272a5e8e9b9904bdf41b',  // Contract address
    //     method: 'exchange',                                      // Method name (always exchange for wrapped)
    //     abi: {
    //         type: 'function',
    //         name: 'exchange',
    //         inputs: [
    //             { name: 'i', type: 'int128' },
    //             { name: 'j', type: 'int128' },
    //             { name: 'dx', type: 'uint256' },
    //             { name: 'min_dy', type: 'uint256' }
    //         ],
    //         outputs: [ { name: '', type: 'uint256' } ],
    //         stateMutability: 'nonpayable'
    //     }
    // }
})()

Deposit & Stake

(async () => {
    await curve.init('JsonRpc', {}, { gasPrice: 0, maxFeePerGas: 0, maxPriorityFeePerGas: 0 });
    
    curve.hasDepositAndStake()
    // true
    
    const pool = curve.getPool('compound');
    const amounts = [1000, 1000];

    
    // --- UNDERLYING ---
    
    
    await pool.wallet.underlyingCoinBalances();
    // {
    //     '0x6b175474e89094c44da98b954eedeac495271d0f': '10000.0',
    //     '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48': '10000.0',
    // }
    await pool.wallet.lpTokenBalances();
    // { lpToken: '0.0', gauge: '0.0' }
    
    await pool.depositAndStakeExpected(amounts);
    // 1820.604572902286288394
    await pool.depositAndStakeBonus(amounts);
    // 0.0030482584681188
    await pool.depositAndStakeIsApproved(amounts);
    // false
    await pool.depositAndStakeApprove(amounts);
    // [
    //     '0xb363c95fb8e63f724d6a05dfa756ede38132ce3fc8faf80306d925856996669c',
    //     '0x53d01fd54fb607091c67f8b39ff9e2e7670396d831b856b1979caaa6ac6ea37b',
    //     '0xd69ca27c30fa6e5ba927d0382987f142895481710439dae358a1daeeb01c7248'
    // ]
    await pool.depositAndStake(amounts);
    // 0x3ec53842120be75f51e907803da844f4d3e8435766e0c25a40700085ed5b56c4

    // {
    //     '0x6b175474e89094c44da98b954eedeac495271d0f': '9000.0',
    //     '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48': '9000.0',
    // }
    // { lpToken: '0.0', gauge: '1820.556829935710883568' }

    
    // --- WRAPPED ---
    
    
    await pool.wallet.wrappedCoinBalances();
    // {
    //     '0x5d3a536e4d6dbd6114cc1ead35777bab948e3643': '10000.0',
    //     '0x39aa39c021dfbae8fac545936693ac917d5e7563': '10000.0'
    // }
    await pool.wallet.lpTokenBalances();
    // { lpToken: '0.0', gauge: '1820.556829935710883568' }

    await pool.depositAndStakeWrappedExpected(amounts);
    // 40.328408669183101673
    await pool.depositAndStakeWrappedBonus(amounts);
    // 0.46040576921447873
    await pool.depositAndStakeWrappedIsApproved(amounts);
    // false
    await pool.depositAndStakeWrappedApprove(amounts);
    // [
    //     '0x53035c46f877ed4d156aff5aee0f8e04c0e0701e40651e9e55f41976919b093d',
    //     '0x4743386669a6a21fbe09805ae50e281db22cf518d681ee1e5d0f81a1d761e79b',
    //     '0x8580b6bd88dfd0eeab77480e50d82ba14922fd4b431b0123a7ac425236e1db3a'
    // ]
    await pool.depositAndStakeWrapped(amounts);
    // 0xdb73e3176ab876806f99f71d70ad6ee93d7a865c15faa062ebaba2011b94b315

    // {
    //     '0x5d3a536e4d6dbd6114cc1ead35777bab948e3643': '9000.0',
    //     '0x39aa39c021dfbae8fac545936693ac917d5e7563': '9000.0'
    // }
    // { lpToken: '0.0', gauge: '1860.884096082215274556' }
})();

Router

import curve from "@curvefi/api";

(async () => {
    await curve.init('JsonRpc', {}, { gasPrice: 0, maxFeePerGas: 0, maxPriorityFeePerGas: 0 });
    await curve.factory.fetchPools();
    await curve.crvUSDFactory.fetchPools();
    await curve.cryptoFactory.fetchPools();
    await curve.twocryptoFactory.fetchPools();
    await curve.tricryptoFactory.fetchPools();
    await curve.stableNgFactory.fetchPools();

    curve.hasRouter();
    // true

    await curve.getBalances(['DAI', 'CRV']);
    // [ '9900.0', '100049.744832225238317557' ]

    const { route, output } = await curve.router.getBestRouteAndOutput('DAI', 'CRV', '1000');
    // OR await curve.router.getBestRouteAndOutput('0x6B175474E89094C44Da98b954EedeAC495271d0F', '0xD533a949740bb3306d119CC777fa900bA034cd52', '1000');
    const expected = await curve.router.expected('DAI', 'CRV', '1000');
    // OR await curve.router.expected('0x6B175474E89094C44Da98b954EedeAC495271d0F', '0xD533a949740bb3306d119CC777fa900bA034cd52', '1000');
    const required = await curve.router.required('DAI', 'CRV', expected);
    // OR await curve.router.required('0x6B175474E89094C44Da98b954EedeAC495271d0F', '0xD533a949740bb3306d119CC777fa900bA034cd52', expected);
    const priceImpact = await curve.router.priceImpact('DAI', 'CRV', '1000');
    // OR await curve.router.priceImpact('0x6B175474E89094C44Da98b954EedeAC495271d0F', '0xD533a949740bb3306d119CC777fa900bA034cd52', '1000');
    const args = curve.router.getArgs(route);

    console.log(route, output, expected, required, priceImpact, args);
    // route = [
    //     {
    //         poolId: 'mim',
    //         swapAddress: '0x5a6a4d54456819380173272a5e8e9b9904bdf41b',
    //         inputCoinAddress: '0x6b175474e89094c44da98b954eedeac495271d0f',
    //         outputCoinAddress: '0x99d8a9c45b2eca8864373a26d1459e3dff1e17f3',
    //         swapParams: [ 1, 0, 2, 1, 4 ],
    //         poolAddress: '0x5a6a4d54456819380173272a5e8e9b9904bdf41b',
    //         basePool: '0xbebc44782c7db0a1a60cb6fe97d0b483032ff1c7',
    //         baseToken: '0x6c3f90f043a72fa612cbac8115ee7e52bde6e490',
    //         secondBasePool: '0x0000000000000000000000000000000000000000',
    //         secondBaseToken: '0x0000000000000000000000000000000000000000'
    //     },
    //     {
    //         poolId: 'factory-crvusd-6',
    //         swapAddress: '0xbe426b0f37c112dd20d5866769c8034171567b31',
    //         inputCoinAddress: '0x99d8a9c45b2eca8864373a26d1459e3dff1e17f3',
    //         outputCoinAddress: '0xf939e0a03fb07f59a73314e73794be0e57ac1b4e',
    //         swapParams: [ 0, 1, 1, 1, 2 ],
    //         poolAddress: '0xbe426b0f37c112dd20d5866769c8034171567b31',
    //         basePool: '0x0000000000000000000000000000000000000000',
    //         baseToken: '0x0000000000000000000000000000000000000000',
    //         secondBasePool: '0x0000000000000000000000000000000000000000',
    //         secondBaseToken: '0x0000000000000000000000000000000000000000'
    //     },
    //     {
    //         poolId: 'factory-tricrypto-4',
    //         swapAddress: '0x4ebdf703948ddcea3b11f675b4d1fba9d2414a14',
    //         inputCoinAddress: '0xf939e0a03fb07f59a73314e73794be0e57ac1b4e',
    //         outputCoinAddress: '0xd533a949740bb3306d119cc777fa900ba034cd52',
    //         swapParams: [ 0, 2, 1, 3, 3 ],
    //         poolAddress: '0x4ebdf703948ddcea3b11f675b4d1fba9d2414a14',
    //         basePool: '0x0000000000000000000000000000000000000000',
    //         baseToken: '0x0000000000000000000000000000000000000000',
    //         secondBasePool: '0x0000000000000000000000000000000000000000',
    //         secondBaseToken: '0x0000000000000000000000000000000000000000'
    //     }
    // ]
    // 
    // output = expected = 2359.161199223806107003
    // required = 999.898950158673335108
    // priceImpact = 0.158012 %
    //
    // args = {
    //     _route: [
    //         '0x6b175474e89094c44da98b954eedeac495271d0f',
    //         '0x5a6a4d54456819380173272a5e8e9b9904bdf41b',
    //         '0x99d8a9c45b2eca8864373a26d1459e3dff1e17f3',
    //         '0xbe426b0f37c112dd20d5866769c8034171567b31',
    //         '0xf939e0a03fb07f59a73314e73794be0e57ac1b4e',
    //         '0x4ebdf703948ddcea3b11f675b4d1fba9d2414a14',
    //         '0xd533a949740bb3306d119cc777fa900ba034cd52',
    //         '0x0000000000000000000000000000000000000000',
    //         '0x0000000000000000000000000000000000000000',
    //         '0x0000000000000000000000000000000000000000',
    //         '0x0000000000000000000000000000000000000000'
    //     ],
    //         _swapParams: [
    //         [ 1, 0, 2, 1, 4 ],
    //         [ 0, 1, 1, 1, 2 ],
    //         [ 0, 2, 1, 3, 3 ],
    //         [ 0, 0, 0, 0, 0 ],
    //         [ 0, 0, 0, 0, 0 ]
    //     ],
    //         _pools: [
    //         '0x5a6a4d54456819380173272a5e8e9b9904bdf41b',
    //         '0xbe426b0f37c112dd20d5866769c8034171567b31',
    //         '0x4ebdf703948ddcea3b11f675b4d1fba9d2414a14',
    //         '0x0000000000000000000000000000000000000000',
    //         '0x0000000000000000000000000000000000000000'
    //     ],
    //         _basePools: [
    //         '0xbebc44782c7db0a1a60cb6fe97d0b483032ff1c7',
    //         '0x0000000000000000000000000000000000000000',
    //         '0x0000000000000000000000000000000000000000',
    //         '0x0000000000000000000000000000000000000000',
    //         '0x0000000000000000000000000000000000000000'
    //     ],
    //         _baseTokens: [
    //         '0x6c3f90f043a72fa612cbac8115ee7e52bde6e490',
    //         '0x0000000000000000000000000000000000000000',
    //         '0x0000000000000000000000000000000000000000',
    //         '0x0000000000000000000000000000000000000000',
    //         '0x0000000000000000000000000000000000000000'
    //     ],
    //         _secondBasePools: [
    //         '0x0000000000000000000000000000000000000000',
    //         '0x0000000000000000000000000000000000000000',
    //         '0x0000000000000000000000000000000000000000',
    //         '0x0000000000000000000000000000000000000000',
    //         '0x0000000000000000000000000000000000000000'
    //     ],
    //         _secondBaseTokens: [
    //         '0x0000000000000000000000000000000000000000',
    //         '0x0000000000000000000000000000000000000000',
    //         '0x0000000000000000000000000000000000000000',
    //         '0x0000000000000000000000000000000000000000',
    //         '0x0000000000000000000000000000000000000000'
    //     ]
    // }


    await curve.router.isApproved('DAI', 1000);
    // false
    await curve.router.approve('DAI', 1000);
    // [
    //     '0xc111e471715ae6f5437e12d3b94868a5b6542cd7304efca18b5782d315760ae5'
    // ]
    
    // Get populated transactions for approve (without executing)
    const approveTxs = await curve.router.populateApprove('DAI', 1000, false, userAddress);
    // OR const approveTxs = await curve.router.populateApprove('0x6B175474E89094C44Da98b954EedeAC495271d0F', 1000, false, userAddress);
    console.log(approveTxs);
    // [{ to: '0x6B17...', data: '0x...', ... }]
    // Returns array of TransactionLike objects
    const swapTx = await curve.router.swap('DAI', 'CRV', '1000');
    // OR const swapTx = await curve.router.swap('0x6B175474E89094C44Da98b954EedeAC495271d0F', '0xD533a949740bb3306d119CC777fa900bA034cd52', '1000');
    console.log(swapTx.hash);
    // 0xc7ba1d60871c0295ac5471bb602c37ec0f00a71543b3a041308ebd91833f26ba
    const swappedAmount = await curve.router.getSwappedAmount(swapTx, 'CRV');
    // 1573.668171170839785062

    await curve.getBalances(['DAI', 'CRV']);
    // [ '8900.0', '100428.626463428100672494' ]

    // Get calldata for swap (without executing transaction)
    // First, you need to call getBestRouteAndOutput to cache the route
    await curve.router.getBestRouteAndOutput('DAI', 'CRV', '1000');
    
    // Then get calldata
    const { data, to, from, amount } = await curve.router.populateSwap('DAI', 'CRV', '1000', 0.5);
    // OR const tx = await curve.router.populateSwap('0x6B175474E89094C44Da98b954EedeAC495271d0F', '0xD533a949740bb3306d119CC777fa900bA034cd52', '1000', 0.5);
    console.log(data);
    // 0x8f726f1c000000000000000000000000...
    
    // --- Execute swap from external calldata (e.g., from router API) ---
    
    // Swap using ready transaction data (from router API or any other provider)
    // Uses standard ethers.js TransactionRequest
ё    
    // Option 1: Use built-in approve methods
    await curve.router.isApproved('DAI', 1000);
    // false
    await curve.router.approve('DAI', 1000);
    // [ '0xc111e471715ae6f5437e12d3b94868a5b6542cd7304efca18b5782d315760ae5' ]
    
    // Option 2: Get populated approve transactions (for multisig, batching, etc.)
    const approveTxs = await curve.router.populateApprove('DAI', 1000, false, userAddress);
    // [{ to: '0x6B17...', data: '0x...', ... }]
    
    // Option 3: Execute approve from calldata (when API returns approve tx)
    const approveCalldata = {
        to: "0x6B175474E89094C44Da98b954EedeAC495271d0F",  // Token address
        data: "0x095ea7b3...",  // Approve calldata from API
    };
    const approveHash = await curve.router.approveFromCalldata(approveCalldata);
    // 0x1234...
    
    // Get swap transaction data from external API
    const swapCalldata = {
        to: "0x99a58482BD75cbab83b27EC03CA68fF489b5788f",  // Router contract address
        data: "0x5c9c18e2....",  // Swap calldata from API
        value: 0n  // Optional: amount of ETH to send
    };
    
    // Estimate gas
    const gasEstimateFromCalldata = await curve.router.estimateGas.swapFromCalldata(swapCalldata);
    console.log(gasEstimateFromCalldata);
    // 476904
    
    // Execute swap (returns transaction hash)
    const swapHash = await curve.router.swapFromCalldata(swapCalldata);
    console.log(swapHash);
    // 0xc7ba1d60871c0295ac5471bb602c37ec0f00a71543b3a041308ebd91833f26ba
    
    
    // --- Complete example: Generate calldata and execute with approveFromCalldata/swapFromCalldata ---
    
    // This example demonstrates a full workflow where you generate transaction calldata
    // internally and then execute it using the *FromCalldata methods. This pattern is useful
    // for transaction batching, multisig workflows, or when you need to store/forward
    // transaction data before execution.
    
    const inputCoin = '0xcbb7c0000ab88b473b1f5afd9ef808440eed33bf';  // cbBTC
    const outputCoin = '0xdac17f958d2ee523a2206206994597c13d831ec7'; // USDT
    const amount = 2;
    
    // Step 1: Find the best route and cache it
    await curve.router.getBestRouteAndOutput(inputCoin, outputCoin, amount);
    
    // Step 2: Generate swap transaction calldata
    const swapTx = await curve.router.populateSwap(inputCoin, outputCoin, amount);
    console.log(swapTx);
    // {
    //     to: '0x99a58482BD75cbab83b27EC03CA68fF489b5788f',
    //     data: '0x...',
    //     from: '0x...',
    //     amount: '2'
    // }
    
    // Step 3: Check if approval is needed
    const isApproved = await curve.router.isApproved(inputCoin, amount);
    console.log(isApproved);
    // false
    
    // Step 4: Generate approve transaction calldata
    const approveTxs = await curve.router.populateApprove(
        inputCoin,
        amount,
        false,
        curve.signerAddress
    );
    console.log(approveTxs);
    // [{ to: '0xcbb7c0...', data: '0x095ea7b3...', ... }]
    
    // Step 5: Execute approve using calldata
    const approveHash = await curve.router.approveFromCalldata(approveTxs[0]);
    console.log(approveHash);
    // 0xabc123...
    
    // Step 6: Verify approval
    const isNowApproved = await curve.router.isApproved(inputCoin, amount);
    console.log(isNowApproved);
    // true
    
    // Step 7: Estimate gas for swap
    const estimatedGas = await curve.router.estimateGas.swapFromCalldata(swapTx);
    console.log(estimatedGas);
    // 287654
    
    // Step 8: Execute swap using calldata
    const swapTxHash = await curve.router.swapFromCalldata(swapTx);
    console.log(swapTxHash);
    // 0xdef456...
})()

FastBridge

FastBridge allows bridging crvUSD from L2 networks (Arbitrum, Optimism, Fraxtal) to Ethereum mainnet.

import curve from "@curvefi/api";

(async () => {
    // Initialize on L2 network (Arbitrum, Optimism, or Fraxtal)
    await curve.init('JsonRpc', {}, { gasPrice: 0, maxFeePerGas: 0, maxPriorityFeePerGas: 0, chainId: 42161 }); // Arbitrum
    
    // Check if FastBridge is supported on current network
    curve.fastBridge.isSupported();
    // true (on Arbitrum, Optimism, Fraxtal)
    // false (on other networks)
    
    // Assert that FastBridge is supported (throws error if not)
    curve.fastBridge.assertIsSupported();
    // No error on supported networks
    // Throws "FastBridge is not available on this network" on unsupported networks
    
    // Get list of supported networks
    const supportedNetworks = curve.fastBridge.getSupportedNetworks();
    console.log(supportedNetworks);
    // [
    //     {
    //         chainId: 42161,
    //         name: 'Arbitrum',
    //         fastBridgeAddress: '0x1F2aF270029d028400265Ce1dd0919BA8780dAe1',
    //         crvUsdAddress: '0x498Bf2B1e120FeD3ad3D42EA2165E9b73f99C1e5'
    //     },
    //     {
    //         chainId: 10,
    //         name: 'Optimism',
    //         fastBridgeAddress: '0xD16d5eC345Dd86Fb63C6a9C43c517210F1027914',
    //         crvUsdAddress: '0x417Ac0e078398C154EdFadD9Ef675d30Be60Af93'
    //     },
    //     {
    //         chainId: 252,
    //         name: 'Fraxtal',
    //         fastBridgeAddress: '0x3fE593E651Cd0B383AD36b75F4159f30BB0631A6',
    //         crvUsdAddress

版本与发布记录

@curvefi/api 共发布 454 个版本,首次发布于 2021/08/01;过去 12 个月发布了 63 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
2.72.6latest2026/11/10今天
2.72.52026/11/064 天前
2.72.42026/11/064 天前
2.72.32026/11/065 天前
2.72.22026/11/056 天前
2.72.12026/11/046 天前

关于 @curvefi/api 的常见问题

@curvefi/api 是什么?

JavaScript library for curve.finance

如何安装 @curvefi/api?

在项目目录运行 npm install @curvefi/api,或使用 pnpm add / yarn add / bun add。

@curvefi/api 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@curvefi/api 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@curvefi/api 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js 24。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@curvefi/api 可以商用吗?

@curvefi/api 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@curvefi/api 的下载量有多少?

根据 npm 官方下载统计,@curvefi/api 在 2026/10/11 – 2026/11/09 这 30 天内被下载 11,852 次,日均约 395 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@curvefi/api 还在维护吗?

最新版本 2.72.6 发布于 2026/11/10(今天);至今共发布 454 个版本,其中过去 12 个月发布了 63 个;首次发布于 2021/08/01。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。