@curvefi/api 2.52.4 → 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.
- package/README.md +485 -2
- package/lib/constants/abis/circulating_supply.json +114 -0
- package/lib/constants/abis/voting_proposal.json +1086 -0
- package/lib/constants/aliases.js +3 -0
- package/lib/curve.js +8 -1
- package/lib/dao.d.ts +44 -0
- package/lib/dao.js +675 -0
- package/lib/external-api.d.ts +4 -10
- package/lib/external-api.js +33 -0
- package/lib/index.d.ts +53 -0
- package/lib/index.js +57 -0
- package/lib/interfaces.d.ts +66 -0
- package/lib/pools/PoolTemplate.d.ts +5 -1
- package/lib/pools/PoolTemplate.js +159 -59
- package/lib/utils.d.ts +1 -0
- package/lib/utils.js +26 -10
- package/package.json +1 -1
package/lib/external-api.d.ts
CHANGED
|
@@ -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>>;
|
package/lib/external-api.js
CHANGED
|
@@ -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
|
@@ -99,8 +99,14 @@ declare const curve: {
|
|
|
99
99
|
getPoolList: () => string[];
|
|
100
100
|
deployPlainPool: (name: string, symbol: string, coins: string[], A: string | number, fee: string | number, offpegFeeMultiplier: string | number, assetTypes: (0 | 1 | 2 | 3)[], implementationIdx: 0, emaTime: number, oracleAddresses: string[], methodNames: string[]) => Promise<ethers.ContractTransactionResponse>;
|
|
101
101
|
deployMetaPool: (basePool: string, name: string, symbol: string, coin: string, A: string | number, fee: string | number, offpegFeeMultiplier: string | number, emaTime: number, implementationIdx: 0, assetType: 0 | 1 | 2 | 3, methodName: string, oracleAddress: string) => Promise<ethers.ContractTransactionResponse>;
|
|
102
|
+
deployGauge: (poolAddress: string) => Promise<ethers.ContractTransactionResponse>;
|
|
103
|
+
deployGaugeSidechain: (poolAddress: string, salt: string) => Promise<ethers.ContractTransactionResponse>;
|
|
104
|
+
deployGaugeMirror: (chainId: number, salt: string) => Promise<ethers.ContractTransactionResponse>;
|
|
102
105
|
getDeployedPlainPoolAddress: (tx: ethers.ContractTransactionResponse) => Promise<string>;
|
|
103
106
|
getDeployedMetaPoolAddress: (tx: ethers.ContractTransactionResponse) => Promise<string>;
|
|
107
|
+
getDeployedGaugeAddress: (tx: ethers.ContractTransactionResponse) => Promise<string>;
|
|
108
|
+
getDeployedGaugeMirrorAddress: (chainId: number) => Promise<string>;
|
|
109
|
+
getDeployedGaugeMirrorAddressByTx: (tx: ethers.ContractTransactionResponse) => Promise<string>;
|
|
104
110
|
fetchRecentlyDeployedPool: (poolAddress: string) => Promise<string>;
|
|
105
111
|
estimateGas: {
|
|
106
112
|
deployPlainPool: (name: string, symbol: string, coins: string[], A: string | number, fee: string | number, offpegFeeMultiplier: string | number, assetTypes: (0 | 1 | 2 | 3)[], implementationIdx: 0, emaTime: number, oracleAddresses: string[], methodNames: string[]) => Promise<number>;
|
|
@@ -221,5 +227,52 @@ declare const curve: {
|
|
|
221
227
|
swap: (inputCoin: string, outputCoin: string, amount: string | number) => Promise<number | number[]>;
|
|
222
228
|
};
|
|
223
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
|
+
};
|
|
224
277
|
};
|
|
225
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 () {
|
|
@@ -139,8 +140,20 @@ var curve = {
|
|
|
139
140
|
getPoolList: _curve.getStableNgFactoryPoolList,
|
|
140
141
|
deployPlainPool: deployStableNgPlainPool,
|
|
141
142
|
deployMetaPool: deployStableNgMetaPool,
|
|
143
|
+
deployGauge: function (poolAddress) { return __awaiter(void 0, void 0, void 0, function () { return __generator(this, function (_a) {
|
|
144
|
+
return [2 /*return*/, deployGauge(poolAddress, _curve.constants.ALIASES.stable_ng_factory)];
|
|
145
|
+
}); }); },
|
|
146
|
+
deployGaugeSidechain: function (poolAddress, salt) { return __awaiter(void 0, void 0, void 0, function () { return __generator(this, function (_a) {
|
|
147
|
+
return [2 /*return*/, deployGaugeSidechain(poolAddress, salt)];
|
|
148
|
+
}); }); },
|
|
149
|
+
deployGaugeMirror: function (chainId, salt) { return __awaiter(void 0, void 0, void 0, function () { return __generator(this, function (_a) {
|
|
150
|
+
return [2 /*return*/, deployGaugeMirror(chainId, salt)];
|
|
151
|
+
}); }); },
|
|
142
152
|
getDeployedPlainPoolAddress: getDeployedStablePlainPoolAddress,
|
|
143
153
|
getDeployedMetaPoolAddress: getDeployedStableMetaPoolAddress,
|
|
154
|
+
getDeployedGaugeAddress: getDeployedGaugeAddress,
|
|
155
|
+
getDeployedGaugeMirrorAddress: getDeployedGaugeMirrorAddress,
|
|
156
|
+
getDeployedGaugeMirrorAddressByTx: getDeployedGaugeMirrorAddressByTx,
|
|
144
157
|
fetchRecentlyDeployedPool: _curve.fetchRecentlyDeployedStableNgFactoryPool,
|
|
145
158
|
estimateGas: {
|
|
146
159
|
deployPlainPool: deployStableNgPlainPoolEstimateGas,
|
|
@@ -268,5 +281,49 @@ var curve = {
|
|
|
268
281
|
swap: swapEstimateGas,
|
|
269
282
|
},
|
|
270
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
|
+
},
|
|
271
328
|
};
|
|
272
329
|
export default curve;
|
package/lib/interfaces.d.ts
CHANGED
|
@@ -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
|
-
|
|
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
|
|
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.
|
|
297
|
-
if (
|
|
296
|
+
this._calcTokenApy = function (futureWorkingSupplyBN) {
|
|
297
|
+
if (futureWorkingSupplyBN === void 0) { futureWorkingSupplyBN = null; }
|
|
298
298
|
return __awaiter(_this, void 0, void 0, function () {
|
|
299
|
-
var
|
|
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
|
-
|
|
302
|
-
|
|
303
|
-
|
|
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
|
-
|
|
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*/,
|
|
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
|
|
330
|
-
_d = (
|
|
331
|
-
if (!inflationRateBN.eq(0)) return [3 /*break*/,
|
|
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
|
|
350
|
-
_e = (
|
|
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
|
-
|
|
353
|
-
case
|
|
341
|
+
_f.label = 7;
|
|
342
|
+
case 7:
|
|
354
343
|
if (inflationRateBN.eq(0))
|
|
355
344
|
return [2 /*return*/, [0, 0]];
|
|
356
|
-
|
|
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
|
|
359
|
-
crvPrice =
|
|
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.
|
|
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
|
-
|
|
605
|
-
|
|
606
|
-
|
|
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,
|
|
695
|
+
var _c, minApy, maxApy, boost;
|
|
628
696
|
return __generator(this, function (_d) {
|
|
629
697
|
switch (_d.label) {
|
|
630
698
|
case 0:
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
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(),
|
|
637
|
-
return [4 /*yield*/, this.
|
|
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(
|
|
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
|
|
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([
|
|
@@ -1403,27 +1496,34 @@ var PoolTemplate = /** @class */ (function () {
|
|
|
1403
1496
|
};
|
|
1404
1497
|
PoolTemplate.prototype.depositBonus = function (amounts) {
|
|
1405
1498
|
return __awaiter(this, void 0, void 0, function () {
|
|
1406
|
-
var amountsBN, prices, pricesBN, balancesBN, balancedAmounts, expectedBN,
|
|
1407
|
-
return __generator(this, function (
|
|
1408
|
-
switch (
|
|
1499
|
+
var amountsBN, prices, _c, pricesBN, balancesBN, balancedAmounts, expectedBN, _d, balancedExpectedBN, _e;
|
|
1500
|
+
return __generator(this, function (_f) {
|
|
1501
|
+
switch (_f.label) {
|
|
1409
1502
|
case 0:
|
|
1410
1503
|
amountsBN = amounts.map(BN);
|
|
1504
|
+
if (!(this.isCrypto || this.id === 'wsteth' || this.id === 'factory-crvusd-24')) return [3 /*break*/, 2];
|
|
1411
1505
|
return [4 /*yield*/, this._underlyingPrices()];
|
|
1412
1506
|
case 1:
|
|
1413
|
-
|
|
1507
|
+
_c = _f.sent();
|
|
1508
|
+
return [3 /*break*/, 3];
|
|
1509
|
+
case 2:
|
|
1510
|
+
_c = this.underlyingCoins.map(function () { return 1; });
|
|
1511
|
+
_f.label = 3;
|
|
1512
|
+
case 3:
|
|
1513
|
+
prices = _c;
|
|
1414
1514
|
pricesBN = prices.map(BN);
|
|
1415
1515
|
return [4 /*yield*/, this.stats.underlyingBalances()];
|
|
1416
|
-
case
|
|
1417
|
-
balancesBN = (
|
|
1516
|
+
case 4:
|
|
1517
|
+
balancesBN = (_f.sent()).map(BN);
|
|
1418
1518
|
balancedAmounts = this._balancedAmountsWithSameValue(amountsBN, pricesBN, balancesBN);
|
|
1419
|
-
_c = BN;
|
|
1420
|
-
return [4 /*yield*/, this.depositExpected(amounts)];
|
|
1421
|
-
case 3:
|
|
1422
|
-
expectedBN = _c.apply(void 0, [_e.sent()]);
|
|
1423
1519
|
_d = BN;
|
|
1520
|
+
return [4 /*yield*/, this.depositExpected(amounts)];
|
|
1521
|
+
case 5:
|
|
1522
|
+
expectedBN = _d.apply(void 0, [_f.sent()]);
|
|
1523
|
+
_e = BN;
|
|
1424
1524
|
return [4 /*yield*/, this.depositExpected(balancedAmounts)];
|
|
1425
|
-
case
|
|
1426
|
-
balancedExpectedBN =
|
|
1525
|
+
case 6:
|
|
1526
|
+
balancedExpectedBN = _e.apply(void 0, [_f.sent()]);
|
|
1427
1527
|
return [2 /*return*/, String(expectedBN.minus(balancedExpectedBN).div(balancedExpectedBN).times(100))];
|
|
1428
1528
|
}
|
|
1429
1529
|
});
|
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[]>;
|