@curvefi/api 2.68.27 → 2.68.29
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +100 -0
- package/lib/index.d.ts +8 -0
- package/lib/index.js +5 -1
- package/lib/pools/poolConstructor.js +7 -14
- package/lib/router.d.ts +4 -0
- package/lib/router.js +44 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1277,6 +1277,106 @@ import curve from "@curvefi/api";
|
|
|
1277
1277
|
// OR const tx = await curve.router.populateSwap('0x6B175474E89094C44Da98b954EedeAC495271d0F', '0xD533a949740bb3306d119CC777fa900bA034cd52', '1000', 0.5);
|
|
1278
1278
|
console.log(data);
|
|
1279
1279
|
// 0x8f726f1c000000000000000000000000...
|
|
1280
|
+
|
|
1281
|
+
// --- Execute swap from external calldata (e.g., from router API) ---
|
|
1282
|
+
|
|
1283
|
+
// Swap using ready transaction data (from router API or any other provider)
|
|
1284
|
+
// Uses standard ethers.js TransactionRequest
|
|
1285
|
+
ё
|
|
1286
|
+
// Option 1: Use built-in approve methods
|
|
1287
|
+
await curve.router.isApproved('DAI', 1000);
|
|
1288
|
+
// false
|
|
1289
|
+
await curve.router.approve('DAI', 1000);
|
|
1290
|
+
// [ '0xc111e471715ae6f5437e12d3b94868a5b6542cd7304efca18b5782d315760ae5' ]
|
|
1291
|
+
|
|
1292
|
+
// Option 2: Get populated approve transactions (for multisig, batching, etc.)
|
|
1293
|
+
const approveTxs = await curve.router.populateApprove('DAI', 1000, false, userAddress);
|
|
1294
|
+
// [{ to: '0x6B17...', data: '0x...', ... }]
|
|
1295
|
+
|
|
1296
|
+
// Option 3: Execute approve from calldata (when API returns approve tx)
|
|
1297
|
+
const approveCalldata = {
|
|
1298
|
+
to: "0x6B175474E89094C44Da98b954EedeAC495271d0F", // Token address
|
|
1299
|
+
data: "0x095ea7b3...", // Approve calldata from API
|
|
1300
|
+
};
|
|
1301
|
+
const approveHash = await curve.router.approveFromCalldata(approveCalldata);
|
|
1302
|
+
// 0x1234...
|
|
1303
|
+
|
|
1304
|
+
// Get swap transaction data from external API
|
|
1305
|
+
const swapCalldata = {
|
|
1306
|
+
to: "0x99a58482BD75cbab83b27EC03CA68fF489b5788f", // Router contract address
|
|
1307
|
+
data: "0x5c9c18e2....", // Swap calldata from API
|
|
1308
|
+
value: 0n // Optional: amount of ETH to send
|
|
1309
|
+
};
|
|
1310
|
+
|
|
1311
|
+
// Estimate gas
|
|
1312
|
+
const gasEstimateFromCalldata = await curve.router.estimateGas.swapFromCalldata(swapCalldata);
|
|
1313
|
+
console.log(gasEstimateFromCalldata);
|
|
1314
|
+
// 476904
|
|
1315
|
+
|
|
1316
|
+
// Execute swap (returns transaction hash)
|
|
1317
|
+
const swapHash = await curve.router.swapFromCalldata(swapCalldata);
|
|
1318
|
+
console.log(swapHash);
|
|
1319
|
+
// 0xc7ba1d60871c0295ac5471bb602c37ec0f00a71543b3a041308ebd91833f26ba
|
|
1320
|
+
|
|
1321
|
+
|
|
1322
|
+
// --- Complete example: Generate calldata and execute with approveFromCalldata/swapFromCalldata ---
|
|
1323
|
+
|
|
1324
|
+
// This example demonstrates a full workflow where you generate transaction calldata
|
|
1325
|
+
// internally and then execute it using the *FromCalldata methods. This pattern is useful
|
|
1326
|
+
// for transaction batching, multisig workflows, or when you need to store/forward
|
|
1327
|
+
// transaction data before execution.
|
|
1328
|
+
|
|
1329
|
+
const inputCoin = '0xcbb7c0000ab88b473b1f5afd9ef808440eed33bf'; // cbBTC
|
|
1330
|
+
const outputCoin = '0xdac17f958d2ee523a2206206994597c13d831ec7'; // USDT
|
|
1331
|
+
const amount = 2;
|
|
1332
|
+
|
|
1333
|
+
// Step 1: Find the best route and cache it
|
|
1334
|
+
await curve.router.getBestRouteAndOutput(inputCoin, outputCoin, amount);
|
|
1335
|
+
|
|
1336
|
+
// Step 2: Generate swap transaction calldata
|
|
1337
|
+
const swapTx = await curve.router.populateSwap(inputCoin, outputCoin, amount);
|
|
1338
|
+
console.log(swapTx);
|
|
1339
|
+
// {
|
|
1340
|
+
// to: '0x99a58482BD75cbab83b27EC03CA68fF489b5788f',
|
|
1341
|
+
// data: '0x...',
|
|
1342
|
+
// from: '0x...',
|
|
1343
|
+
// amount: '2'
|
|
1344
|
+
// }
|
|
1345
|
+
|
|
1346
|
+
// Step 3: Check if approval is needed
|
|
1347
|
+
const isApproved = await curve.router.isApproved(inputCoin, amount);
|
|
1348
|
+
console.log(isApproved);
|
|
1349
|
+
// false
|
|
1350
|
+
|
|
1351
|
+
// Step 4: Generate approve transaction calldata
|
|
1352
|
+
const approveTxs = await curve.router.populateApprove(
|
|
1353
|
+
inputCoin,
|
|
1354
|
+
amount,
|
|
1355
|
+
false,
|
|
1356
|
+
curve.signerAddress
|
|
1357
|
+
);
|
|
1358
|
+
console.log(approveTxs);
|
|
1359
|
+
// [{ to: '0xcbb7c0...', data: '0x095ea7b3...', ... }]
|
|
1360
|
+
|
|
1361
|
+
// Step 5: Execute approve using calldata
|
|
1362
|
+
const approveHash = await curve.router.approveFromCalldata(approveTxs[0]);
|
|
1363
|
+
console.log(approveHash);
|
|
1364
|
+
// 0xabc123...
|
|
1365
|
+
|
|
1366
|
+
// Step 6: Verify approval
|
|
1367
|
+
const isNowApproved = await curve.router.isApproved(inputCoin, amount);
|
|
1368
|
+
console.log(isNowApproved);
|
|
1369
|
+
// true
|
|
1370
|
+
|
|
1371
|
+
// Step 7: Estimate gas for swap
|
|
1372
|
+
const estimatedGas = await curve.router.estimateGas.swapFromCalldata(swapTx);
|
|
1373
|
+
console.log(estimatedGas);
|
|
1374
|
+
// 287654
|
|
1375
|
+
|
|
1376
|
+
// Step 8: Execute swap using calldata
|
|
1377
|
+
const swapTxHash = await curve.router.swapFromCalldata(swapTx);
|
|
1378
|
+
console.log(swapTxHash);
|
|
1379
|
+
// 0xdef456...
|
|
1280
1380
|
})()
|
|
1281
1381
|
```
|
|
1282
1382
|
|
package/lib/index.d.ts
CHANGED
|
@@ -259,9 +259,13 @@ export declare const createCurve: () => {
|
|
|
259
259
|
swap: (inputCoin: string, outputCoin: string, amount: string | number, slippage?: number | undefined) => Promise<ethers.ContractTransactionResponse>;
|
|
260
260
|
populateSwap: (inputCoin: string, outputCoin: string, amount: string | number, slippage?: number | undefined) => Promise<ethers.TransactionLike<string>>;
|
|
261
261
|
getSwappedAmount: (tx: ethers.ContractTransactionResponse, outputCoin: string) => Promise<string>;
|
|
262
|
+
approveFromCalldata: (tx: ethers.TransactionRequest) => Promise<string>;
|
|
263
|
+
swapFromCalldata: (tx: ethers.TransactionRequest) => Promise<string>;
|
|
262
264
|
estimateGas: {
|
|
263
265
|
approve: (inputCoin: string, amount: string | number) => Promise<number | number[]>;
|
|
264
266
|
swap: (inputCoin: string, outputCoin: string, amount: string | number) => Promise<number | number[]>;
|
|
267
|
+
approveFromCalldata: (tx: ethers.TransactionRequest) => Promise<number | number[]>;
|
|
268
|
+
swapFromCalldata: (tx: ethers.TransactionRequest) => Promise<number | number[]>;
|
|
265
269
|
};
|
|
266
270
|
};
|
|
267
271
|
dao: {
|
|
@@ -572,9 +576,13 @@ declare const _default: {
|
|
|
572
576
|
swap: (inputCoin: string, outputCoin: string, amount: string | number, slippage?: number | undefined) => Promise<ethers.ContractTransactionResponse>;
|
|
573
577
|
populateSwap: (inputCoin: string, outputCoin: string, amount: string | number, slippage?: number | undefined) => Promise<ethers.TransactionLike<string>>;
|
|
574
578
|
getSwappedAmount: (tx: ethers.ContractTransactionResponse, outputCoin: string) => Promise<string>;
|
|
579
|
+
approveFromCalldata: (tx: ethers.TransactionRequest) => Promise<string>;
|
|
580
|
+
swapFromCalldata: (tx: ethers.TransactionRequest) => Promise<string>;
|
|
575
581
|
estimateGas: {
|
|
576
582
|
approve: (inputCoin: string, amount: string | number) => Promise<number | number[]>;
|
|
577
583
|
swap: (inputCoin: string, outputCoin: string, amount: string | number) => Promise<number | number[]>;
|
|
584
|
+
approveFromCalldata: (tx: ethers.TransactionRequest) => Promise<number | number[]>;
|
|
585
|
+
swapFromCalldata: (tx: ethers.TransactionRequest) => Promise<number | number[]>;
|
|
578
586
|
};
|
|
579
587
|
};
|
|
580
588
|
dao: {
|
package/lib/index.js
CHANGED
|
@@ -9,7 +9,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
9
9
|
};
|
|
10
10
|
import { PoolTemplate, getPool } from "./pools/index.js";
|
|
11
11
|
import { getUserPoolListByLiquidity, getUserPoolListByClaimable, getUserPoolList, getUserLiquidityUSD, getUserClaimable, } from "./pools/utils.js";
|
|
12
|
-
import { getBestRouteAndOutput, getArgs, swapExpected, swapRequired, swapPriceImpact, swapIsApproved, swapApproveEstimateGas, swapApprove, swapPopulateApprove, swapEstimateGas, swap, populateSwap, getSwappedAmount, } from "./router.js";
|
|
12
|
+
import { getBestRouteAndOutput, getArgs, swapExpected, swapRequired, swapPriceImpact, swapIsApproved, swapApproveEstimateGas, swapApprove, swapPopulateApprove, swapEstimateGas, swap, populateSwap, getSwappedAmount, approveFromCalldata, approveFromCalldataEstimateGas, swapFromCalldata, swapFromCalldataEstimateGas, } from "./router.js";
|
|
13
13
|
import { Curve } from "./curve.js";
|
|
14
14
|
import { getCrv, getLockedAmountAndUnlockTime, getVeCrv, getVeCrvPct, calcUnlockTime, createLockEstimateGas, createLock, isApproved, approveEstimateGas, approve, increaseAmountEstimateGas, increaseAmount, increaseUnlockTimeEstimateGas, increaseUnlockTime, withdrawLockedCrvEstimateGas, withdrawLockedCrv, claimableFees, claimFeesEstimateGas, claimFees, lastEthBlock, getAnycallBalance, topUpAnycall, topUpAnycallEstimateGas, lastBlockSent, blockToSend, sendBlockhash, sendBlockhashEstimateGas, submitProof, submitProofEstimateGas, claimFeesCrvUSDEstimateGas, claimableFeesCrvUSD, claimFeesCrvUSD, calculateVeCrv, } from "./boosting.js";
|
|
15
15
|
import { getBalances, getAllowance, hasAllowance, ensureAllowanceEstimateGas, ensureAllowance, populateApprove, getUsdRate, getGasPriceFromL1, getGasPriceFromL2, getGasInfoForL2, getTVL, getCoinsData, getVolume, hasDepositAndStake, hasRouter, getBasePools, getGasPrice, getCurveLiteNetworks, } from "./utils.js";
|
|
@@ -233,9 +233,13 @@ export const createCurve = () => {
|
|
|
233
233
|
swap: swap.bind(_curve),
|
|
234
234
|
populateSwap: populateSwap.bind(_curve),
|
|
235
235
|
getSwappedAmount: getSwappedAmount.bind(_curve),
|
|
236
|
+
approveFromCalldata: approveFromCalldata.bind(_curve),
|
|
237
|
+
swapFromCalldata: swapFromCalldata.bind(_curve),
|
|
236
238
|
estimateGas: {
|
|
237
239
|
approve: swapApproveEstimateGas.bind(_curve),
|
|
238
240
|
swap: swapEstimateGas.bind(_curve),
|
|
241
|
+
approveFromCalldata: approveFromCalldataEstimateGas.bind(_curve),
|
|
242
|
+
swapFromCalldata: swapFromCalldataEstimateGas.bind(_curve),
|
|
239
243
|
},
|
|
240
244
|
},
|
|
241
245
|
dao: {
|
|
@@ -17,22 +17,15 @@ import { swapWrappedExpectedAndApproveMixin, swapWrappedMixin, swapWrappedRequir
|
|
|
17
17
|
import { findAbiSignature, getCountArgsOfMethodByAbi, getPoolIdBySwapAddress } from "../utils.js";
|
|
18
18
|
import { StatsPool } from "./subClasses/statsPool.js";
|
|
19
19
|
export function getPool(poolIdOrAddress) {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
poolId = getPoolIdBySwapAddress.call(this, _poolIdOrAddress);
|
|
24
|
-
if (!poolId || !this.getPoolsData()[poolId]) {
|
|
25
|
-
throw new Error(`Pool with address ${_poolIdOrAddress} not found`);
|
|
26
|
-
}
|
|
20
|
+
const poolId = poolIdOrAddress.toLowerCase().startsWith('0x') ? getPoolIdBySwapAddress.call(this, poolIdOrAddress.toLowerCase()) : poolIdOrAddress;
|
|
21
|
+
if (!poolId) {
|
|
22
|
+
throw new Error(`Pool with address ${poolIdOrAddress} not found`);
|
|
27
23
|
}
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
if (!poolsData[poolId]) {
|
|
32
|
-
throw new Error(`Pool with id ${_poolIdOrAddress} not found`);
|
|
33
|
-
}
|
|
24
|
+
const poolData = (this.getPoolsData())[poolId];
|
|
25
|
+
if (!poolData) {
|
|
26
|
+
throw new Error(`Pool with id ${poolIdOrAddress} not found`);
|
|
34
27
|
}
|
|
35
|
-
const poolDummy = new PoolTemplate(poolId, this);
|
|
28
|
+
const poolDummy = new PoolTemplate(poolId, this, poolData);
|
|
36
29
|
class Pool extends PoolTemplate {
|
|
37
30
|
constructor(poolId, curve) {
|
|
38
31
|
super(poolId, curve);
|
package/lib/router.d.ts
CHANGED
|
@@ -25,3 +25,7 @@ export declare function swapEstimateGas(this: Curve, inputCoin: string, outputCo
|
|
|
25
25
|
export declare function swap(this: Curve, inputCoin: string, outputCoin: string, amount: number | string, slippage?: number): Promise<ethers.ContractTransactionResponse>;
|
|
26
26
|
export declare function populateSwap(this: Curve, inputCoin: string, outputCoin: string, amount: number | string, slippage?: number): Promise<TransactionLike>;
|
|
27
27
|
export declare function getSwappedAmount(this: Curve, tx: ethers.ContractTransactionResponse, outputCoin: string): Promise<string>;
|
|
28
|
+
export declare function approveFromCalldataEstimateGas(this: Curve, tx: ethers.TransactionRequest): Promise<number | number[]>;
|
|
29
|
+
export declare function approveFromCalldata(this: Curve, tx: ethers.TransactionRequest): Promise<string>;
|
|
30
|
+
export declare function swapFromCalldataEstimateGas(this: Curve, tx: ethers.TransactionRequest): Promise<number | number[]>;
|
|
31
|
+
export declare function swapFromCalldata(this: Curve, tx: ethers.TransactionRequest): Promise<string>;
|
package/lib/router.js
CHANGED
|
@@ -458,3 +458,47 @@ export function getSwappedAmount(tx, outputCoin) {
|
|
|
458
458
|
return this.formatUnits(res[res.length - 1], outputCoinDecimals);
|
|
459
459
|
});
|
|
460
460
|
}
|
|
461
|
+
function _approveFromCalldata(tx_1) {
|
|
462
|
+
return __awaiter(this, arguments, void 0, function* (tx, estimateGas = false) {
|
|
463
|
+
if (!this.signer) {
|
|
464
|
+
throw new Error("Signer is not available");
|
|
465
|
+
}
|
|
466
|
+
const gas = yield this.signer.estimateGas(Object.assign(Object.assign({}, tx), this.constantOptions));
|
|
467
|
+
if (estimateGas)
|
|
468
|
+
return smartNumber(gas);
|
|
469
|
+
yield this.updateFeeData();
|
|
470
|
+
return (yield this.signer.sendTransaction(Object.assign(Object.assign({}, tx), this.options))).hash;
|
|
471
|
+
});
|
|
472
|
+
}
|
|
473
|
+
export function approveFromCalldataEstimateGas(tx) {
|
|
474
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
475
|
+
return yield _approveFromCalldata.call(this, tx, true);
|
|
476
|
+
});
|
|
477
|
+
}
|
|
478
|
+
export function approveFromCalldata(tx) {
|
|
479
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
480
|
+
return yield _approveFromCalldata.call(this, tx, false);
|
|
481
|
+
});
|
|
482
|
+
}
|
|
483
|
+
function _swapFromCalldata(tx_1) {
|
|
484
|
+
return __awaiter(this, arguments, void 0, function* (tx, estimateGas = false) {
|
|
485
|
+
if (!this.signer) {
|
|
486
|
+
throw new Error("Signer is not available");
|
|
487
|
+
}
|
|
488
|
+
const gas = yield this.signer.estimateGas(Object.assign(Object.assign({}, tx), this.constantOptions));
|
|
489
|
+
if (estimateGas)
|
|
490
|
+
return smartNumber(gas);
|
|
491
|
+
yield this.updateFeeData();
|
|
492
|
+
return (yield this.signer.sendTransaction(Object.assign(Object.assign({}, tx), this.options))).hash;
|
|
493
|
+
});
|
|
494
|
+
}
|
|
495
|
+
export function swapFromCalldataEstimateGas(tx) {
|
|
496
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
497
|
+
return yield _swapFromCalldata.call(this, tx, true);
|
|
498
|
+
});
|
|
499
|
+
}
|
|
500
|
+
export function swapFromCalldata(tx) {
|
|
501
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
502
|
+
return yield _swapFromCalldata.call(this, tx, false);
|
|
503
|
+
});
|
|
504
|
+
}
|