@curvefi/api 2.52.5 → 2.53.0

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.
@@ -1,5 +1,5 @@
1
1
  import memoize from "memoizee";
2
- import { IExtendedPoolDataFromApi, ISubgraphPoolData, IDict, INetworkName, IPoolType } from "./interfaces";
2
+ import { IExtendedPoolDataFromApi, ISubgraphPoolData, IDict, INetworkName, IPoolType, IGaugesDataFromApi, IDaoProposal, IDaoProposalListItem } from "./interfaces";
3
3
  export declare const _getPoolsFromApi: ((network: INetworkName, poolType: IPoolType) => Promise<IExtendedPoolDataFromApi>) & memoize.Memoized<(network: INetworkName, poolType: IPoolType) => Promise<IExtendedPoolDataFromApi>>;
4
4
  export declare const _getAllPoolsFromApi: (network: INetworkName) => Promise<IExtendedPoolDataFromApi[]>;
5
5
  export declare const _getSubgraphData: ((network: INetworkName) => Promise<{
@@ -35,15 +35,7 @@ export declare const _getFactoryAPYsAndVolumes: ((network: string) => Promise<{
35
35
  apy: number;
36
36
  volume: number;
37
37
  }[]>>;
38
- export declare const _getAllGauges: (() => Promise<IDict<{
39
- gauge: string;
40
- is_killed?: boolean;
41
- gaugeStatus?: Record<string, boolean> | null;
42
- }>>) & memoize.Memoized<() => Promise<IDict<{
43
- gauge: string;
44
- is_killed?: boolean;
45
- gaugeStatus?: Record<string, boolean> | null;
46
- }>>>;
38
+ export declare const _getAllGauges: (() => Promise<IDict<IGaugesDataFromApi>>) & memoize.Memoized<() => Promise<IDict<IGaugesDataFromApi>>>;
47
39
  export declare const _getHiddenPools: (() => Promise<IDict<string[]>>) & memoize.Memoized<() => Promise<IDict<string[]>>>;
48
40
  export declare const _generateBoostingProof: ((block: number, address: string) => Promise<{
49
41
  block_header_rlp: string;
@@ -52,3 +44,5 @@ export declare const _generateBoostingProof: ((block: number, address: string) =
52
44
  block_header_rlp: string;
53
45
  proof_rlp: string;
54
46
  }>>;
47
+ export declare const _getDaoProposalList: (() => Promise<IDaoProposalListItem[]>) & memoize.Memoized<() => Promise<IDaoProposalListItem[]>>;
48
+ export declare const _getDaoProposal: ((type: "PARAMETER" | "OWNERSHIP", id: number) => Promise<IDaoProposal>) & memoize.Memoized<(type: "PARAMETER" | "OWNERSHIP", id: number) => Promise<IDaoProposal>>;
@@ -186,3 +186,36 @@ export var _generateBoostingProof = memoize(function (block, address) { return _
186
186
  promise: true,
187
187
  maxAge: 5 * 60 * 1000, // 5m
188
188
  });
189
+ // --- DAO ---
190
+ export var _getDaoProposalList = memoize(function () { return __awaiter(void 0, void 0, void 0, function () {
191
+ var url, response;
192
+ return __generator(this, function (_a) {
193
+ switch (_a.label) {
194
+ case 0:
195
+ url = "https://api-py.llama.airforce/curve/v1/dao/proposals";
196
+ return [4 /*yield*/, axios.get(url, { validateStatus: function () { return true; } })];
197
+ case 1:
198
+ response = _a.sent();
199
+ return [2 /*return*/, response.data.proposals];
200
+ }
201
+ });
202
+ }); }, {
203
+ promise: true,
204
+ maxAge: 5 * 60 * 1000, // 5m
205
+ });
206
+ export var _getDaoProposal = memoize(function (type, id) { return __awaiter(void 0, void 0, void 0, function () {
207
+ var url, response;
208
+ return __generator(this, function (_a) {
209
+ switch (_a.label) {
210
+ case 0:
211
+ url = "https://api-py.llama.airforce/curve/v1/dao/proposals/".concat(type.toLowerCase(), "/").concat(id);
212
+ return [4 /*yield*/, axios.get(url, { validateStatus: function () { return true; } })];
213
+ case 1:
214
+ response = _a.sent();
215
+ return [2 /*return*/, response.data];
216
+ }
217
+ });
218
+ }); }, {
219
+ promise: true,
220
+ maxAge: 5 * 60 * 1000, // 5m
221
+ });
package/lib/index.d.ts CHANGED
@@ -227,5 +227,52 @@ declare const curve: {
227
227
  swap: (inputCoin: string, outputCoin: string, amount: string | number) => Promise<number | number[]>;
228
228
  };
229
229
  };
230
+ dao: {
231
+ crvSupplyStats: () => Promise<{
232
+ circulating: string;
233
+ locked: string;
234
+ total: string;
235
+ veCrv: string;
236
+ averageLockTime: string;
237
+ }>;
238
+ userCrv: (address?: string) => Promise<string>;
239
+ userVeCrv: (address?: string) => Promise<{
240
+ veCrv: string;
241
+ veCrvPct: string;
242
+ lockedCrv: string;
243
+ unlockTime: number;
244
+ }>;
245
+ crvLockIsApproved: (amount: string | number) => Promise<boolean>;
246
+ calcCrvUnlockTime: (days: string | number, start?: string | number) => number;
247
+ claimableFees: (address?: string) => Promise<string>;
248
+ crvLockApprove: (amount: string | number) => Promise<string[]>;
249
+ createCrvLock: (amount: string | number, days: string | number) => Promise<string>;
250
+ increaseCrvLockedAmount: (amount: string | number) => Promise<string>;
251
+ increaseCrvUnlockTime: (days: string | number) => Promise<string>;
252
+ withdrawLockedCrv: () => Promise<string>;
253
+ claimFees: (address?: string) => Promise<string>;
254
+ getVotingGaugeList: () => Promise<import("./interfaces.js").IVotingGauge[]>;
255
+ userGaugeVotes: (address?: string) => Promise<{
256
+ gauges: import("./interfaces.js").IGaugeUserVote[];
257
+ powerUsed: string;
258
+ veCrvUsed: string;
259
+ }>;
260
+ voteForGaugeNextTime: (gauge: string) => Promise<number>;
261
+ voteForGauge: (gauge: string, power: string | number) => Promise<string>;
262
+ getProposalList: () => Promise<import("./interfaces.js").IDaoProposalListItem[]>;
263
+ getProposal: (type: "PARAMETER" | "OWNERSHIP", id: number) => Promise<import("./interfaces.js").IDaoProposal>;
264
+ userProposalVotes: (address?: string) => Promise<import("./interfaces.js").IDaoProposalUserListItem[]>;
265
+ voteForProposal: (type: "PARAMETER" | "OWNERSHIP", id: number, support: boolean) => Promise<string>;
266
+ estimateGas: {
267
+ crvLockApprove: (amount: string | number) => Promise<number | number[]>;
268
+ createCrvLock: (amount: string | number, days: string | number) => Promise<number | number[]>;
269
+ increaseCrvLockedAmount: (amount: string | number) => Promise<number | number[]>;
270
+ increaseCrvUnlockTime: (days: string | number) => Promise<number | number[]>;
271
+ withdrawLockedCrv: () => Promise<number | number[]>;
272
+ claimFees: (address?: string) => Promise<number | number[]>;
273
+ voteForGauge: (gauge: string, power: string | number) => Promise<number | number[]>;
274
+ voteForProposal: (type: "PARAMETER" | "OWNERSHIP", id: number, support: boolean) => Promise<number | number[]>;
275
+ };
276
+ };
230
277
  };
231
278
  export default curve;
package/lib/index.js CHANGED
@@ -41,6 +41,7 @@ import { curve as _curve } from "./curve.js";
41
41
  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, } from "./boosting.js";
42
42
  import { getBalances, getAllowance, hasAllowance, ensureAllowanceEstimateGas, ensureAllowance, getUsdRate, getGasPriceFromL1, getGasPriceFromL2, getTVL, getCoinsData, getVolume, hasDepositAndStake, hasRouter, } from "./utils.js";
43
43
  import { deployStablePlainPool, deployStablePlainPoolEstimateGas, getDeployedStablePlainPoolAddress, setOracle, setOracleEstimateGas, deployStableMetaPool, deployStableMetaPoolEstimateGas, getDeployedStableMetaPoolAddress, deployCryptoPool, deployCryptoPoolEstimateGas, getDeployedCryptoPoolAddress, deployTricryptoPool, deployTricryptoPoolEstimateGas, getDeployedTricryptoPoolAddress, deployGauge, deployGaugeEstimateGas, getDeployedGaugeAddress, deployGaugeSidechain, deployGaugeSidechainEstimateGas, deployGaugeMirror, deployGaugeMirrorEstimateGas, getDeployedGaugeMirrorAddress, getDeployedGaugeMirrorAddressByTx, deployStableNgPlainPool, deployStableNgPlainPoolEstimateGas, deployStableNgMetaPool, deployStableNgMetaPoolEstimateGas, } from './factory/deploy.js';
44
+ import { crvSupplyStats, userCrv, userVeCrv, crvLockIsApproved, crvLockApproveEstimateGas, crvLockApprove, calcCrvUnlockTime, createCrvLockEstimateGas, createCrvLock, increaseCrvLockedAmountEstimateGas, increaseCrvLockedAmount, increaseCrvUnlockTimeEstimateGas, increaseCrvUnlockTime, withdrawLockedCrvEstimateGas as daoWithdrawLockedCrvEstimateGas, withdrawLockedCrv as daoWithdrawLockedCrv, claimableFees as daoClaimableFees, claimFeesEstimateGas as daoClaimFeesEstimateGas, claimFees as daoClaimFees, getVotingGaugeList, userGaugeVotes, voteForGaugeNextTime, voteForGaugeEstimateGas, voteForGauge, getProposalList, getProposal, userProposalVotes, voteForProposalEstimateGas, voteForProposal, } from "./dao.js";
44
45
  function init(providerType, providerSettings, options) {
45
46
  if (options === void 0) { options = {}; }
46
47
  return __awaiter(this, void 0, void 0, function () {
@@ -280,5 +281,49 @@ var curve = {
280
281
  swap: swapEstimateGas,
281
282
  },
282
283
  },
284
+ dao: {
285
+ // --- CRV lock ---
286
+ // View methods
287
+ crvSupplyStats: crvSupplyStats,
288
+ userCrv: userCrv,
289
+ userVeCrv: userVeCrv,
290
+ crvLockIsApproved: crvLockIsApproved,
291
+ calcCrvUnlockTime: calcCrvUnlockTime,
292
+ claimableFees: daoClaimableFees,
293
+ // Transaction methods
294
+ crvLockApprove: crvLockApprove,
295
+ createCrvLock: createCrvLock,
296
+ increaseCrvLockedAmount: increaseCrvLockedAmount,
297
+ increaseCrvUnlockTime: increaseCrvUnlockTime,
298
+ withdrawLockedCrv: daoWithdrawLockedCrv,
299
+ claimFees: daoClaimFees,
300
+ // --- Gauge voting ---
301
+ // View methods
302
+ getVotingGaugeList: getVotingGaugeList,
303
+ userGaugeVotes: userGaugeVotes,
304
+ voteForGaugeNextTime: voteForGaugeNextTime,
305
+ // Transaction methods
306
+ voteForGauge: voteForGauge,
307
+ // --- Proposal voting ---
308
+ // View methods
309
+ getProposalList: getProposalList,
310
+ getProposal: getProposal,
311
+ userProposalVotes: userProposalVotes,
312
+ // Transaction methods
313
+ voteForProposal: voteForProposal,
314
+ estimateGas: {
315
+ // --- CRV lock ---
316
+ crvLockApprove: crvLockApproveEstimateGas,
317
+ createCrvLock: createCrvLockEstimateGas,
318
+ increaseCrvLockedAmount: increaseCrvLockedAmountEstimateGas,
319
+ increaseCrvUnlockTime: increaseCrvUnlockTimeEstimateGas,
320
+ withdrawLockedCrv: daoWithdrawLockedCrvEstimateGas,
321
+ claimFees: daoClaimFeesEstimateGas,
322
+ // --- Gauge voting ---
323
+ voteForGauge: voteForGaugeEstimateGas,
324
+ // --- Proposal voting ---
325
+ voteForProposal: voteForProposalEstimateGas,
326
+ },
327
+ },
283
328
  };
284
329
  export default curve;
@@ -180,3 +180,69 @@ export interface IProfit {
180
180
  symbol: string;
181
181
  price: number;
182
182
  }
183
+ export interface IGaugesDataFromApi {
184
+ gauge: string;
185
+ swap: string;
186
+ swap_token: string;
187
+ shortName: string;
188
+ gauge_controller: {
189
+ gauge_relative_weight: string;
190
+ get_gauge_weight: string;
191
+ };
192
+ poolUrls: {
193
+ swap: string[];
194
+ };
195
+ is_killed?: boolean;
196
+ hasNoCrv?: boolean;
197
+ gaugeStatus?: Record<string, boolean> | null;
198
+ }
199
+ export interface IVotingGauge {
200
+ poolUrl: string;
201
+ network: string;
202
+ gaugeAddress: string;
203
+ poolAddress: string;
204
+ lpTokenAddress: string;
205
+ poolName: string;
206
+ totalVeCrv: string;
207
+ relativeWeight: string;
208
+ isKilled: boolean;
209
+ }
210
+ export interface IGaugeUserVote {
211
+ userPower: string;
212
+ userVeCrv: string;
213
+ userFutureVeCrv: string;
214
+ expired: boolean;
215
+ gaugeData: IVotingGauge;
216
+ }
217
+ export interface IDaoProposalListItem {
218
+ voteId: number;
219
+ voteType: "PARAMETER" | "OWNERSHIP";
220
+ creator: string;
221
+ startDate: number;
222
+ snapshotBlock: number;
223
+ ipfsMetadata: string;
224
+ metadata: string;
225
+ votesFor: string;
226
+ votesAgainst: string;
227
+ voteCount: number;
228
+ supportRequired: string;
229
+ minAcceptQuorum: string;
230
+ totalSupply: string;
231
+ executed: boolean;
232
+ }
233
+ export interface IDaoProposalUserListItem extends IDaoProposalListItem {
234
+ userVote: "yes" | "no" | "even";
235
+ }
236
+ export interface IDaoProposalVote {
237
+ tx: string;
238
+ voteId: number;
239
+ voter: string;
240
+ supports: boolean;
241
+ stake: number;
242
+ }
243
+ export interface IDaoProposal extends IDaoProposalListItem {
244
+ tx: string;
245
+ creatorVotingPower: number;
246
+ script: string;
247
+ votes: IDaoProposalVote[];
248
+ }
@@ -103,6 +103,7 @@ export declare class PoolTemplate {
103
103
  private statsTotalLiquidity;
104
104
  private statsVolume;
105
105
  private statsBaseApy;
106
+ private _calcTokenApy;
106
107
  private statsTokenApy;
107
108
  private statsRewardsApy;
108
109
  private _pureCalcLpTokenAmount;
@@ -139,8 +140,11 @@ export declare class PoolTemplate {
139
140
  claimableCrv(address?: string): Promise<string>;
140
141
  claimCrvEstimateGas(): Promise<number | number[]>;
141
142
  claimCrv(): Promise<string>;
142
- boost: (address?: string) => Promise<string>;
143
+ userBoost: (address?: string) => Promise<string>;
144
+ private _userFutureBoostAndWorkingSupply;
145
+ userFutureBoost: (address?: string) => Promise<string>;
143
146
  userCrvApy: (address?: string) => Promise<number>;
147
+ userFutureCrvApy: (address?: string) => Promise<number>;
144
148
  maxBoostedStake: (...addresses: string[]) => Promise<IDict<string> | string>;
145
149
  rewardTokens: ((useApi?: any) => Promise<{
146
150
  token: string;
@@ -56,8 +56,8 @@ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
56
56
  };
57
57
  import memoize from "memoizee";
58
58
  import { _getPoolsFromApi, _getSubgraphData, _getFactoryAPYsAndVolumes, _getLegacyAPYsAndVolumes } from '../external-api.js';
59
- import { _getCoinAddresses, _getBalances, _prepareAddresses, _ensureAllowance, _getUsdRate, hasAllowance, ensureAllowance, ensureAllowanceEstimateGas, BN, toBN, toStringFromBN, parseUnits, getEthIndex, fromBN, _cutZeros, _setContracts, _get_small_x, _get_price_impact, checkNumber, _getCrvApyFromApi, _getRewardsFromApi, mulBy1_3, smartNumber, DIGas, } from '../utils.js';
60
- import { curve as _curve, curve } from "../curve.js";
59
+ import { _getCoinAddresses, _getBalances, _prepareAddresses, _ensureAllowance, _getUsdRate, hasAllowance, ensureAllowance, ensureAllowanceEstimateGas, BN, toBN, toStringFromBN, parseUnits, getEthIndex, fromBN, _cutZeros, _setContracts, _get_small_x, _get_price_impact, checkNumber, _getCrvApyFromApi, _getRewardsFromApi, mulBy1_3, smartNumber, DIGas, _getAddress, } from '../utils.js';
60
+ import { curve } from "../curve.js";
61
61
  import ERC20Abi from '../constants/abis/ERC20.json' assert { type: 'json' };
62
62
  var DAY = 86400;
63
63
  var WEEK = 7 * DAY;
@@ -293,30 +293,19 @@ var PoolTemplate = /** @class */ (function () {
293
293
  }
294
294
  });
295
295
  }); };
296
- this.statsTokenApy = function (useApi) {
297
- if (useApi === void 0) { useApi = true; }
296
+ this._calcTokenApy = function (futureWorkingSupplyBN) {
297
+ if (futureWorkingSupplyBN === void 0) { futureWorkingSupplyBN = null; }
298
298
  return __awaiter(_this, void 0, void 0, function () {
299
- var isDisabledChain, crvAPYs, poolCrvApy, totalLiquidityUSD, inflationRateBN, workingSupplyBN, totalSupplyBN, gaugeContract, lpTokenContract, crvContract, currentWeek, _c, gaugeContract, lpTokenContract, gaugeControllerContract, weightBN, rateBN, crvPrice, baseApyBN, boostedApyBN;
299
+ var totalLiquidityUSD, inflationRateBN, workingSupplyBN, totalSupplyBN, gaugeContract, lpTokenContract, crvContract, currentWeek, _c, gaugeContract, lpTokenContract, gaugeControllerContract, weightBN, rateBN, crvPrice, baseApyBN, boostedApyBN;
300
300
  var _d, _e;
301
- var _f;
302
- return __generator(this, function (_g) {
303
- switch (_g.label) {
304
- case 0:
305
- if (this.rewardsOnly())
306
- throw Error("".concat(this.name, " has Rewards-Only Gauge. Use stats.rewardsApy instead"));
307
- isDisabledChain = [1313161554].includes(curve.chainId);
308
- if (!(useApi && !isDisabledChain)) return [3 /*break*/, 2];
309
- return [4 /*yield*/, _getCrvApyFromApi()];
301
+ return __generator(this, function (_f) {
302
+ switch (_f.label) {
303
+ case 0: return [4 /*yield*/, this.statsTotalLiquidity()];
310
304
  case 1:
311
- crvAPYs = _g.sent();
312
- poolCrvApy = (_f = crvAPYs[this.gauge]) !== null && _f !== void 0 ? _f : [0, 0];
313
- return [2 /*return*/, [poolCrvApy[0], poolCrvApy[1]]];
314
- case 2: return [4 /*yield*/, this.statsTotalLiquidity()];
315
- case 3:
316
- totalLiquidityUSD = _g.sent();
305
+ totalLiquidityUSD = _f.sent();
317
306
  if (Number(totalLiquidityUSD) === 0)
318
307
  return [2 /*return*/, [0, 0]];
319
- if (!(curve.chainId !== 1)) return [3 /*break*/, 7];
308
+ if (!(curve.chainId !== 1)) return [3 /*break*/, 5];
320
309
  gaugeContract = curve.contracts[this.gauge].multicallContract;
321
310
  lpTokenContract = curve.contracts[this.lpToken].multicallContract;
322
311
  crvContract = curve.contracts[curve.constants.ALIASES.crv].contract;
@@ -326,16 +315,16 @@ var PoolTemplate = /** @class */ (function () {
326
315
  gaugeContract.working_supply(),
327
316
  lpTokenContract.totalSupply(),
328
317
  ])];
329
- case 4:
330
- _d = (_g.sent()).map(function (value) { return toBN(value); }), inflationRateBN = _d[0], workingSupplyBN = _d[1], totalSupplyBN = _d[2];
331
- if (!inflationRateBN.eq(0)) return [3 /*break*/, 6];
318
+ case 2:
319
+ _d = (_f.sent()).map(function (value) { return toBN(value); }), inflationRateBN = _d[0], workingSupplyBN = _d[1], totalSupplyBN = _d[2];
320
+ if (!inflationRateBN.eq(0)) return [3 /*break*/, 4];
332
321
  _c = toBN;
333
322
  return [4 /*yield*/, crvContract.balanceOf(this.gauge, curve.constantOptions)];
323
+ case 3:
324
+ inflationRateBN = _c.apply(void 0, [_f.sent()]).div(WEEK);
325
+ _f.label = 4;
326
+ case 4: return [3 /*break*/, 7];
334
327
  case 5:
335
- inflationRateBN = _c.apply(void 0, [_g.sent()]).div(WEEK);
336
- _g.label = 6;
337
- case 6: return [3 /*break*/, 9];
338
- case 7:
339
328
  gaugeContract = curve.contracts[this.gauge].multicallContract;
340
329
  lpTokenContract = curve.contracts[this.lpToken].multicallContract;
341
330
  gaugeControllerContract = curve.contracts[curve.constants.ALIASES.gauge_controller].multicallContract;
@@ -346,17 +335,19 @@ var PoolTemplate = /** @class */ (function () {
346
335
  gaugeContract.working_supply(),
347
336
  lpTokenContract.totalSupply(),
348
337
  ])];
349
- case 8:
350
- _e = (_g.sent()).map(function (value) { return toBN(value); }), inflationRateBN = _e[0], weightBN = _e[1], workingSupplyBN = _e[2], totalSupplyBN = _e[3];
338
+ case 6:
339
+ _e = (_f.sent()).map(function (value) { return toBN(value); }), inflationRateBN = _e[0], weightBN = _e[1], workingSupplyBN = _e[2], totalSupplyBN = _e[3];
351
340
  inflationRateBN = inflationRateBN.times(weightBN);
352
- _g.label = 9;
353
- case 9:
341
+ _f.label = 7;
342
+ case 7:
354
343
  if (inflationRateBN.eq(0))
355
344
  return [2 /*return*/, [0, 0]];
356
- rateBN = inflationRateBN.times(31536000).times(0.4).div(workingSupplyBN).times(totalSupplyBN).div(Number(totalLiquidityUSD));
345
+ if (futureWorkingSupplyBN !== null)
346
+ workingSupplyBN = futureWorkingSupplyBN;
347
+ rateBN = inflationRateBN.times(31536000).div(workingSupplyBN).times(totalSupplyBN).div(Number(totalLiquidityUSD)).times(0.4);
357
348
  return [4 /*yield*/, _getUsdRate(curve.constants.ALIASES.crv)];
358
- case 10:
359
- crvPrice = _g.sent();
349
+ case 8:
350
+ crvPrice = _f.sent();
360
351
  baseApyBN = rateBN.times(crvPrice);
361
352
  boostedApyBN = baseApyBN.times(2.5);
362
353
  return [2 /*return*/, [baseApyBN.times(100).toNumber(), boostedApyBN.times(100).toNumber()]];
@@ -364,6 +355,29 @@ var PoolTemplate = /** @class */ (function () {
364
355
  });
365
356
  });
366
357
  };
358
+ this.statsTokenApy = function (useApi) {
359
+ if (useApi === void 0) { useApi = true; }
360
+ return __awaiter(_this, void 0, void 0, function () {
361
+ var isDisabledChain, crvAPYs, poolCrvApy;
362
+ var _c;
363
+ return __generator(this, function (_d) {
364
+ switch (_d.label) {
365
+ case 0:
366
+ if (this.rewardsOnly())
367
+ throw Error("".concat(this.name, " has Rewards-Only Gauge. Use stats.rewardsApy instead"));
368
+ isDisabledChain = [1313161554].includes(curve.chainId);
369
+ if (!(useApi && !isDisabledChain)) return [3 /*break*/, 2];
370
+ return [4 /*yield*/, _getCrvApyFromApi()];
371
+ case 1:
372
+ crvAPYs = _d.sent();
373
+ poolCrvApy = (_c = crvAPYs[this.gauge]) !== null && _c !== void 0 ? _c : [0, 0];
374
+ return [2 /*return*/, [poolCrvApy[0], poolCrvApy[1]]];
375
+ case 2: return [4 /*yield*/, this._calcTokenApy()];
376
+ case 3: return [2 /*return*/, _d.sent()];
377
+ }
378
+ });
379
+ });
380
+ };
367
381
  this.statsRewardsApy = function (useApi) {
368
382
  if (useApi === void 0) { useApi = true; }
369
383
  return __awaiter(_this, void 0, void 0, function () {
@@ -592,7 +606,7 @@ var PoolTemplate = /** @class */ (function () {
592
606
  });
593
607
  });
594
608
  };
595
- this.boost = function (address) {
609
+ this.userBoost = function (address) {
596
610
  if (address === void 0) { address = ""; }
597
611
  return __awaiter(_this, void 0, void 0, function () {
598
612
  var gaugeContract, _c, workingBalanceBN, balanceBN, boostBN;
@@ -601,9 +615,9 @@ var PoolTemplate = /** @class */ (function () {
601
615
  case 0:
602
616
  if (this.gauge === curve.constants.ZERO_ADDRESS)
603
617
  throw Error("".concat(this.name, " doesn't have gauge"));
604
- address = address || curve.signerAddress;
605
- if (!address)
606
- throw Error("Need to connect wallet or pass address into args");
618
+ if (this.rewardsOnly())
619
+ throw Error("".concat(this.name, " has Rewards-Only Gauge. Use stats.rewardsApy instead"));
620
+ address = _getAddress(address);
607
621
  gaugeContract = curve.contracts[this.gauge].multicallContract;
608
622
  return [4 /*yield*/, curve.multicallProvider.all([
609
623
  gaugeContract.working_balances(address),
@@ -621,27 +635,106 @@ var PoolTemplate = /** @class */ (function () {
621
635
  });
622
636
  });
623
637
  };
638
+ this._userFutureBoostAndWorkingSupply = function (address) { return __awaiter(_this, void 0, void 0, function () {
639
+ var veContractMulticall, gaugeContractMulticall, calls, _c, _votingBalance, _votingTotal, _gaugeBalance, _gaugeTotal, _workingBalance, _workingSupply, _futureWorkingBalance, _futureWorkingSupply, futureWorkingBalanceBN, balanceBN, boostBN;
640
+ return __generator(this, function (_d) {
641
+ switch (_d.label) {
642
+ case 0:
643
+ veContractMulticall = curve.contracts[curve.constants.ALIASES.voting_escrow].multicallContract;
644
+ gaugeContractMulticall = curve.contracts[this.gauge].multicallContract;
645
+ calls = [
646
+ veContractMulticall.balanceOf(address),
647
+ veContractMulticall.totalSupply(),
648
+ gaugeContractMulticall.balanceOf(address),
649
+ gaugeContractMulticall.totalSupply(),
650
+ gaugeContractMulticall.working_balances(address),
651
+ gaugeContractMulticall.working_supply(),
652
+ ];
653
+ return [4 /*yield*/, curve.multicallProvider.all(calls)];
654
+ case 1:
655
+ _c = _d.sent(), _votingBalance = _c[0], _votingTotal = _c[1], _gaugeBalance = _c[2], _gaugeTotal = _c[3], _workingBalance = _c[4], _workingSupply = _c[5];
656
+ _futureWorkingBalance = _gaugeBalance * BigInt(40) / BigInt(100);
657
+ if (_votingTotal > BigInt(0)) {
658
+ _futureWorkingBalance += _gaugeTotal * _votingBalance / _votingTotal * BigInt(60) / BigInt(100);
659
+ }
660
+ if (_futureWorkingBalance > _gaugeBalance)
661
+ _futureWorkingBalance = _gaugeBalance;
662
+ _futureWorkingSupply = _workingSupply - _workingBalance + _futureWorkingBalance;
663
+ futureWorkingBalanceBN = toBN(_futureWorkingBalance);
664
+ balanceBN = toBN(_gaugeBalance);
665
+ boostBN = futureWorkingBalanceBN.div(0.4).div(balanceBN);
666
+ return [2 /*return*/, [boostBN, toBN(_futureWorkingSupply)]];
667
+ }
668
+ });
669
+ }); };
670
+ this.userFutureBoost = function (address) {
671
+ if (address === void 0) { address = ""; }
672
+ return __awaiter(_this, void 0, void 0, function () {
673
+ var boostBN;
674
+ return __generator(this, function (_c) {
675
+ switch (_c.label) {
676
+ case 0:
677
+ if (this.rewardsOnly())
678
+ throw Error("".concat(this.name, " has Rewards-Only Gauge. Use stats.rewardsApy instead"));
679
+ address = _getAddress(address);
680
+ return [4 /*yield*/, this._userFutureBoostAndWorkingSupply(address)];
681
+ case 1:
682
+ boostBN = (_c.sent())[0];
683
+ if (boostBN.lt(1))
684
+ return [2 /*return*/, '1.0'];
685
+ if (boostBN.gt(2.5))
686
+ return [2 /*return*/, '2.5'];
687
+ return [2 /*return*/, boostBN.toFixed(4).replace(/([0-9])0+$/, '$1')];
688
+ }
689
+ });
690
+ });
691
+ };
624
692
  this.userCrvApy = function (address) {
625
693
  if (address === void 0) { address = ""; }
626
694
  return __awaiter(_this, void 0, void 0, function () {
627
- var _c, baseApy, maxApy, boost;
695
+ var _c, minApy, maxApy, boost;
628
696
  return __generator(this, function (_d) {
629
697
  switch (_d.label) {
630
698
  case 0:
631
- address = address || curve.signerAddress;
632
- if (!address)
633
- throw Error("Need to connect wallet or pass address into args");
699
+ if (this.rewardsOnly())
700
+ throw Error("".concat(this.name, " has Rewards-Only Gauge. Use stats.rewardsApy instead"));
701
+ address = _getAddress(address);
634
702
  return [4 /*yield*/, this.statsTokenApy()];
635
703
  case 1:
636
- _c = _d.sent(), baseApy = _c[0], maxApy = _c[1];
637
- return [4 /*yield*/, this.boost(address)];
704
+ _c = _d.sent(), minApy = _c[0], maxApy = _c[1];
705
+ return [4 /*yield*/, this.userBoost(address)];
638
706
  case 2:
639
707
  boost = _d.sent();
640
708
  if (boost == "2.5")
641
709
  return [2 /*return*/, maxApy];
642
710
  if (boost === "NaN")
643
711
  return [2 /*return*/, NaN];
644
- return [2 /*return*/, BN(baseApy).times(BN(boost)).toNumber()];
712
+ return [2 /*return*/, BN(minApy).times(BN(boost)).toNumber()];
713
+ }
714
+ });
715
+ });
716
+ };
717
+ this.userFutureCrvApy = function (address) {
718
+ if (address === void 0) { address = ""; }
719
+ return __awaiter(_this, void 0, void 0, function () {
720
+ var _c, boostBN, futureWorkingSupplyBN, _d, minApy, maxApy;
721
+ return __generator(this, function (_e) {
722
+ switch (_e.label) {
723
+ case 0:
724
+ if (this.rewardsOnly())
725
+ throw Error("".concat(this.name, " has Rewards-Only Gauge. Use stats.rewardsApy instead"));
726
+ address = _getAddress(address);
727
+ return [4 /*yield*/, this._userFutureBoostAndWorkingSupply(address)];
728
+ case 1:
729
+ _c = _e.sent(), boostBN = _c[0], futureWorkingSupplyBN = _c[1];
730
+ return [4 /*yield*/, this._calcTokenApy(futureWorkingSupplyBN)];
731
+ case 2:
732
+ _d = _e.sent(), minApy = _d[0], maxApy = _d[1];
733
+ if (boostBN.lt(1))
734
+ return [2 /*return*/, minApy];
735
+ if (boostBN.gt(2.5))
736
+ return [2 /*return*/, maxApy];
737
+ return [2 /*return*/, BN(minApy).times(boostBN).toNumber()];
645
738
  }
646
739
  });
647
740
  });
@@ -825,7 +918,7 @@ var PoolTemplate = /** @class */ (function () {
825
918
  return [3 /*break*/, 3];
826
919
  case 6: return [3 /*break*/, 14];
827
920
  case 7:
828
- if (!(this.sRewardContract && "rewardRate()" in _curve.contracts[this.sRewardContract].contract && "periodFinish()" && rewardTokens.length === 1)) return [3 /*break*/, 10];
921
+ if (!(this.sRewardContract && "rewardRate()" in curve.contracts[this.sRewardContract].contract && "periodFinish()" && rewardTokens.length === 1)) return [3 /*break*/, 10];
829
922
  rewardToken = rewardTokens[0];
830
923
  sRewardContract = curve.contracts[this.sRewardContract].multicallContract;
831
924
  return [4 /*yield*/, curve.multicallProvider.all([
package/lib/utils.d.ts CHANGED
@@ -23,6 +23,7 @@ export declare const _getCoinAddresses: (...coins: string[] | string[][]) => str
23
23
  export declare const _getCoinDecimals: (...coinAddresses: string[] | string[][]) => number[];
24
24
  export declare const _getBalances: (coins: string[], addresses: string[]) => Promise<IDict<string[]>>;
25
25
  export declare const _prepareAddresses: (addresses: string[] | string[][]) => string[];
26
+ export declare const _getAddress: (address: string) => string;
26
27
  export declare const getBalances: (coins: string[], ...addresses: string[] | string[][]) => Promise<IDict<string[]> | string[]>;
27
28
  export declare const _getAllowance: (coins: string[], address: string, spender: string) => Promise<bigint[]>;
28
29
  export declare const getAllowance: (coins: string[], address: string, spender: string) => Promise<string[]>;
package/lib/utils.js CHANGED
@@ -234,6 +234,12 @@ export var _prepareAddresses = function (addresses) {
234
234
  addresses = addresses;
235
235
  return addresses.filter(function (val, idx, arr) { return arr.indexOf(val) === idx; });
236
236
  };
237
+ export var _getAddress = function (address) {
238
+ address = address || curve.signerAddress;
239
+ if (!address)
240
+ throw Error("Need to connect wallet or pass address into args");
241
+ return address;
242
+ };
237
243
  export var getBalances = function (coins) {
238
244
  var addresses = [];
239
245
  for (var _i = 1; _i < arguments.length; _i++) {
@@ -369,7 +375,7 @@ export var _ensureAllowance = function (coins, amounts, spender, isMax) {
369
375
  export var ensureAllowanceEstimateGas = function (coins, amounts, spender, isMax) {
370
376
  if (isMax === void 0) { isMax = true; }
371
377
  return __awaiter(void 0, void 0, void 0, function () {
372
- var coinAddresses, decimals, _amounts, address, allowance, gas, i, contract, _approveAmount, currentGas_1, _a, currentGas, _b;
378
+ var coinAddresses, decimals, _amounts, address, _allowance, gas, i, contract, _approveAmount, currentGas, _a, currentGas, _b;
373
379
  return __generator(this, function (_c) {
374
380
  switch (_c.label) {
375
381
  case 0:
@@ -379,22 +385,29 @@ export var ensureAllowanceEstimateGas = function (coins, amounts, spender, isMax
379
385
  address = curve.signerAddress;
380
386
  return [4 /*yield*/, _getAllowance(coinAddresses, address, spender)];
381
387
  case 1:
382
- allowance = _c.sent();
388
+ _allowance = _c.sent();
383
389
  gas = [0, 0];
384
390
  i = 0;
385
391
  _c.label = 2;
386
392
  case 2:
387
- if (!(i < allowance.length)) return [3 /*break*/, 7];
388
- if (!(allowance[i] < _amounts[i])) return [3 /*break*/, 6];
393
+ if (!(i < _allowance.length)) return [3 /*break*/, 7];
394
+ if (!(_allowance[i] < _amounts[i])) return [3 /*break*/, 6];
389
395
  contract = curve.contracts[coinAddresses[i]].contract;
390
396
  _approveAmount = isMax ? MAX_ALLOWANCE : _amounts[i];
391
- if (!(allowance[i] > curve.parseUnits("0"))) return [3 /*break*/, 4];
397
+ if (!(_allowance[i] > curve.parseUnits("0"))) return [3 /*break*/, 4];
392
398
  _a = smartNumber;
393
399
  return [4 /*yield*/, contract.approve.estimateGas(spender, curve.parseUnits("0"), curve.constantOptions)];
394
400
  case 3:
395
- currentGas_1 = _a.apply(void 0, [_c.sent()]);
396
- gas = gasSum(gas, currentGas_1);
397
- _c.label = 4;
401
+ currentGas = _a.apply(void 0, [_c.sent()]);
402
+ // For some coins (crv for example ) we can't estimate the second tx gas (approve: 0 --> amount), so we assume it will cost the same amount of gas
403
+ if (typeof currentGas === "number") {
404
+ currentGas = currentGas * 2;
405
+ }
406
+ else {
407
+ currentGas = currentGas.map(function (g) { return g * 2; });
408
+ }
409
+ gas = gasSum(gas, currentGas);
410
+ return [3 /*break*/, 6];
398
411
  case 4:
399
412
  _b = smartNumber;
400
413
  return [4 /*yield*/, contract.approve.estimateGas(spender, _approveAmount, curve.constantOptions)];
@@ -429,10 +442,13 @@ export var ensureAllowance = function (coins, amounts, spender, isMax) {
429
442
  };
430
443
  export var getPoolIdBySwapAddress = function (swapAddress) {
431
444
  var poolsData = curve.getPoolsData();
432
- return Object.entries(poolsData).filter(function (_a) {
445
+ var poolIds = Object.entries(poolsData).filter(function (_a) {
433
446
  var _ = _a[0], poolData = _a[1];
434
447
  return poolData.swap_address.toLowerCase() === swapAddress.toLowerCase();
435
- })[0][0];
448
+ });
449
+ if (poolIds.length === 0)
450
+ return "";
451
+ return poolIds[0][0];
436
452
  };
437
453
  var _getTokenAddressBySwapAddress = function (swapAddress) {
438
454
  var poolsData = curve.getPoolsData();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@curvefi/api",
3
- "version": "2.52.5",
3
+ "version": "2.53.0",
4
4
  "description": "JavaScript library for curve.fi",
5
5
  "main": "lib/index.js",
6
6
  "author": "Macket",