@curvefi/llamalend-api 1.0.21 → 1.0.22-beta.1

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/src/utils.ts CHANGED
@@ -3,7 +3,7 @@ import { Call } from "@curvefi/ethcall";
3
3
  import BigNumber from 'bignumber.js';
4
4
  import { ICurveContract, IDict, TGas } from "./interfaces.js";
5
5
  import { _getUsdPricesFromApi } from "./external-api.js";
6
- import { llamalend } from "./llamalend.js";
6
+ import type { Llamalend } from "./llamalend.js";
7
7
  import { JsonFragment } from "ethers/lib.esm";
8
8
  import { L2Networks } from "./constants/L2Networks.js";
9
9
  import memoize from "memoizee";
@@ -116,8 +116,8 @@ export const gasSum = (gas: number[], currentGas: number | number[]): number[] =
116
116
  return gas;
117
117
  }
118
118
 
119
- export const _getAddress = (address: string): string => {
120
- address = address || llamalend.signerAddress;
119
+ export const _getAddress = function (this: Llamalend, address: string): string {
120
+ address = address || this.signerAddress;
121
121
  if (!address) throw Error("Need to connect wallet or pass address into args");
122
122
 
123
123
  return address
@@ -133,15 +133,15 @@ export const handleMultiCallResponse = (callsMap: string[], response: any[]) =>
133
133
  }
134
134
 
135
135
  // coins can be either addresses or symbols
136
- export const _getCoinAddressesNoCheck = (...coins: string[] | string[][]): string[] => {
136
+ export const _getCoinAddressesNoCheck = function (this: Llamalend, ...coins: string[] | string[][]): string[] {
137
137
  if (coins.length == 1 && Array.isArray(coins[0])) coins = coins[0];
138
138
  coins = coins as string[];
139
- return coins.map((c) => c.toLowerCase()).map((c) => llamalend.constants.COINS[c] || c);
139
+ return coins.map((c) => c.toLowerCase()).map((c) => this.constants.COINS[c] || c);
140
140
  }
141
141
 
142
- export const _getCoinAddresses = (coins: string[]): string[] => {
143
- const coinAddresses = _getCoinAddressesNoCheck(coins);
144
- const availableAddresses = Object.keys(llamalend.constants.DECIMALS);
142
+ export const _getCoinAddresses = function (this: Llamalend, coins: string[]): string[] {
143
+ const coinAddresses = _getCoinAddressesNoCheck.call(this, coins);
144
+ const availableAddresses = Object.keys(this.constants.DECIMALS);
145
145
  for (const coinAddr of coinAddresses) {
146
146
  if (!availableAddresses.includes(coinAddr)) throw Error(`Coin with address '${coinAddr}' is not available`);
147
147
  }
@@ -149,15 +149,15 @@ export const _getCoinAddresses = (coins: string[]): string[] => {
149
149
  return coinAddresses
150
150
  }
151
151
 
152
- export const _getCoinDecimals = (coinAddresses: string[]): number[] => {
153
- return coinAddresses.map((coinAddr) => llamalend.constants.DECIMALS[coinAddr.toLowerCase()] ?? 18);
152
+ export const _getCoinDecimals = function (this: Llamalend, coinAddresses: string[]): number[] {
153
+ return coinAddresses.map((coinAddr) => this.constants.DECIMALS[coinAddr.toLowerCase()] ?? 18);
154
154
  }
155
155
 
156
156
 
157
157
  // --- BALANCES ---
158
158
 
159
- export const _getBalances = async (coinAddresses: string[], address = ""): Promise<bigint[]> => {
160
- address = _getAddress(address);
159
+ export const _getBalances = async function (this: Llamalend, coinAddresses: string[], address = ""): Promise<bigint[]> {
160
+ address = _getAddress.call(this, address);
161
161
  const _coinAddresses = [...coinAddresses];
162
162
  const ethIndex = getEthIndex(_coinAddresses);
163
163
  if (ethIndex !== -1) {
@@ -166,27 +166,27 @@ export const _getBalances = async (coinAddresses: string[], address = ""): Promi
166
166
 
167
167
  const contractCalls = [];
168
168
  for (const coinAddr of _coinAddresses) {
169
- contractCalls.push(llamalend.contracts[coinAddr].multicallContract.balanceOf(address));
169
+ contractCalls.push(this.contracts[coinAddr].multicallContract.balanceOf(address));
170
170
  }
171
- const _balances: bigint[] = await llamalend.multicallProvider.all(contractCalls);
171
+ const _balances: bigint[] = await this.multicallProvider.all(contractCalls);
172
172
 
173
173
  if (ethIndex !== -1) {
174
- const ethBalance: bigint = await llamalend.provider.getBalance(address);
174
+ const ethBalance: bigint = await this.provider.getBalance(address);
175
175
  _balances.splice(ethIndex, 0, ethBalance);
176
176
  }
177
177
 
178
178
  return _balances
179
179
  }
180
180
 
181
- export const getBalances = async (coins: string[], address = ""): Promise<string[]> => {
182
- const coinAddresses = _getCoinAddresses(coins);
183
- const decimals = _getCoinDecimals(coinAddresses).map((item) => Number(item));
184
- const _balances = await _getBalances(coinAddresses, address);
181
+ export const getBalances = async function (this: Llamalend, coins: string[], address = ""): Promise<string[]> {
182
+ const coinAddresses = _getCoinAddresses.call(this, coins);
183
+ const decimals = _getCoinDecimals.call(this, coinAddresses).map((item) => Number(item));
184
+ const _balances = await _getBalances.call(this, coinAddresses, address);
185
185
 
186
186
  return _balances.map((_b, i: number ) => formatUnits(_b, decimals[i]));
187
187
  }
188
188
 
189
- export const _getAllowance = memoize(async (coins: string[], address: string, spender: string): Promise<bigint[]> => {
189
+ const _getAllowanceMemoized = memoize(async function (coins: string[], address: string, spender: string, contracts: any, multicallProvider: any, constantOptions: any): Promise<bigint[]> {
190
190
  const _coins = [...coins]
191
191
  const ethIndex = getEthIndex(_coins);
192
192
  if (ethIndex !== -1) {
@@ -195,10 +195,10 @@ export const _getAllowance = memoize(async (coins: string[], address: string, sp
195
195
 
196
196
  let allowance: bigint[];
197
197
  if (_coins.length === 1) {
198
- allowance = [await llamalend.contracts[_coins[0]].contract.allowance(address, spender, llamalend.constantOptions)];
198
+ allowance = [await contracts[_coins[0]].contract.allowance(address, spender, constantOptions)];
199
199
  } else {
200
- const contractCalls = _coins.map((coinAddr) => llamalend.contracts[coinAddr].multicallContract.allowance(address, spender));
201
- allowance = await llamalend.multicallProvider.all(contractCalls);
200
+ const contractCalls = _coins.map((coinAddr) => contracts[coinAddr].multicallContract.allowance(address, spender));
201
+ allowance = await multicallProvider.all(contractCalls);
202
202
  }
203
203
 
204
204
  if (ethIndex !== -1) {
@@ -206,45 +206,48 @@ export const _getAllowance = memoize(async (coins: string[], address: string, sp
206
206
  }
207
207
 
208
208
  return allowance;
209
- },
210
- {
209
+ }, {
211
210
  promise: true,
212
211
  maxAge: 5 * 1000, // 5s
213
212
  primitive: true,
214
- length: 3,
213
+ length: 6,
215
214
  });
216
215
 
216
+ export async function _getAllowance(this: Llamalend, coins: string[], address: string, spender: string): Promise<bigint[]> {
217
+ return _getAllowanceMemoized(coins, address, spender, this.contracts, this.multicallProvider, this.constantOptions);
218
+ }
219
+
217
220
  // coins can be either addresses or symbols
218
- export const getAllowance = async (coins: string[], address: string, spender: string): Promise<string[]> => {
219
- const coinAddresses = _getCoinAddresses(coins);
220
- const decimals = _getCoinDecimals(coinAddresses).map((item) => Number(item));
221
- const _allowance = await _getAllowance(coinAddresses, address, spender);
221
+ export const getAllowance = async function (this: Llamalend, coins: string[], address: string, spender: string): Promise<string[]> {
222
+ const coinAddresses = _getCoinAddresses.call(this, coins);
223
+ const decimals = _getCoinDecimals.call(this, coinAddresses).map((item) => Number(item));
224
+ const _allowance = await _getAllowance.call(this, coinAddresses, address, spender);
222
225
 
223
- return _allowance.map((a, i) => llamalend.formatUnits(a, decimals[i]))
226
+ return _allowance.map((a, i) => this.formatUnits(a, decimals[i]))
224
227
  }
225
228
 
226
229
  // coins can be either addresses or symbols
227
- export const hasAllowance = async (coins: string[], amounts: (number | string)[], address: string, spender: string): Promise<boolean> => {
228
- const coinAddresses = _getCoinAddresses(coins);
229
- const decimals = _getCoinDecimals(coinAddresses).map((item) => Number(item));
230
- const _allowance = await _getAllowance(coinAddresses, address, spender);
230
+ export const hasAllowance = async function (this: Llamalend, coins: string[], amounts: (number | string)[], address: string, spender: string): Promise<boolean> {
231
+ const coinAddresses = _getCoinAddresses.call(this, coins);
232
+ const decimals = _getCoinDecimals.call(this, coinAddresses).map((item) => Number(item));
233
+ const _allowance = await _getAllowance.call(this, coinAddresses, address, spender);
231
234
  const _amounts = amounts.map((a, i) => parseUnits(a, decimals[i]));
232
235
 
233
236
  return _allowance.map((a, i) => a >= _amounts[i]).reduce((a, b) => a && b);
234
237
  }
235
238
 
236
- export const _ensureAllowance = async (coins: string[], _amounts: bigint[], spender: string, isMax = true): Promise<string[]> => {
237
- const address = llamalend.signerAddress;
238
- const _allowance: bigint[] = await _getAllowance(coins, address, spender);
239
+ export const _ensureAllowance = async function (this: Llamalend, coins: string[], _amounts: bigint[], spender: string, isMax = true): Promise<string[]> {
240
+ const address = this.signerAddress;
241
+ const _allowance: bigint[] = await _getAllowance.call(this, coins, address, spender);
239
242
 
240
243
  const txHashes: string[] = []
241
244
  for (let i = 0; i < _allowance.length; i++) {
242
245
  if (_allowance[i] < _amounts[i]) {
243
- const contract = llamalend.contracts[coins[i]].contract;
246
+ const contract = this.contracts[coins[i]].contract;
244
247
  const _approveAmount = isMax ? MAX_ALLOWANCE : _amounts[i];
245
- await llamalend.updateFeeData();
246
- const gasLimit = _mulBy1_3(DIGas(await contract.approve.estimateGas(spender, _approveAmount, llamalend.constantOptions)));
247
- txHashes.push((await contract.approve(spender, _approveAmount, { ...llamalend.options, gasLimit })).hash);
248
+ await this.updateFeeData();
249
+ const gasLimit = _mulBy1_3(DIGas(await contract.approve.estimateGas(spender, _approveAmount, this.constantOptions)));
250
+ txHashes.push((await contract.approve(spender, _approveAmount, { ...this.options, gasLimit })).hash);
248
251
  }
249
252
  }
250
253
 
@@ -252,18 +255,18 @@ export const _ensureAllowance = async (coins: string[], _amounts: bigint[], spen
252
255
  }
253
256
 
254
257
  // coins can be either addresses or symbols
255
- export const ensureAllowanceEstimateGas = async (coins: string[], amounts: (number | string)[], spender: string, isMax = true): Promise<TGas> => {
256
- const coinAddresses = _getCoinAddresses(coins);
257
- const decimals = _getCoinDecimals(coinAddresses).map((item) => Number(item));
258
+ export const ensureAllowanceEstimateGas = async function (this: Llamalend, coins: string[], amounts: (number | string)[], spender: string, isMax = true): Promise<TGas> {
259
+ const coinAddresses = _getCoinAddresses.call(this, coins);
260
+ const decimals = _getCoinDecimals.call(this, coinAddresses).map((item) => Number(item));
258
261
  const _amounts = amounts.map((a, i) => parseUnits(a, decimals[i]));
259
- const _allowance: bigint[] = await _getAllowance(coinAddresses, llamalend.signerAddress, spender);
262
+ const _allowance: bigint[] = await _getAllowance.call(this, coinAddresses, this.signerAddress, spender);
260
263
 
261
264
  let gas = [0,0];
262
265
  for (let i = 0; i < _allowance.length; i++) {
263
266
  if (_allowance[i] < _amounts[i]) {
264
- const contract = llamalend.contracts[coinAddresses[i]].contract;
267
+ const contract = this.contracts[coinAddresses[i]].contract;
265
268
  const _approveAmount = isMax ? MAX_ALLOWANCE : _amounts[i];
266
- const currentGas = smartNumber(await contract.approve.estimateGas(spender, _approveAmount, llamalend.constantOptions));
269
+ const currentGas = smartNumber(await contract.approve.estimateGas(spender, _approveAmount, this.constantOptions));
267
270
  gas = gasSum(gas, currentGas);
268
271
  }
269
272
  }
@@ -272,21 +275,21 @@ export const ensureAllowanceEstimateGas = async (coins: string[], amounts: (numb
272
275
  }
273
276
 
274
277
  // coins can be either addresses or symbols
275
- export const ensureAllowance = async (coins: string[], amounts: (number | string)[], spender: string, isMax = true): Promise<string[]> => {
276
- const coinAddresses = _getCoinAddresses(coins);
277
- const decimals = _getCoinDecimals(coinAddresses).map((item) => Number(item));
278
+ export const ensureAllowance = async function (this: Llamalend, coins: string[], amounts: (number | string)[], spender: string, isMax = true): Promise<string[]> {
279
+ const coinAddresses = _getCoinAddresses.call(this, coins);
280
+ const decimals = _getCoinDecimals.call(this, coinAddresses).map((item) => Number(item));
278
281
  const _amounts = amounts.map((a, i) => parseUnits(a, decimals[i]));
279
282
 
280
- return await _ensureAllowance(coinAddresses, _amounts, spender, isMax)
283
+ return await _ensureAllowance.call(this, coinAddresses, _amounts, spender, isMax)
281
284
  }
282
285
 
283
286
  const _usdRatesCache: IDict<{ rate: number, time: number }> = {}
284
- export const _getUsdRate = async (assetId: string): Promise<number> => {
285
- if (llamalend.chainId === 1 && assetId.toLowerCase() === '0x8762db106b2c2a0bccb3a80d1ed41273552616e8') return 0; // RSR
286
- const pricesFromApi = await _getUsdPricesFromApi();
287
+ export const _getUsdRate = async function (this: Llamalend, assetId: string): Promise<number> {
288
+ if (this.chainId === 1 && assetId.toLowerCase() === '0x8762db106b2c2a0bccb3a80d1ed41273552616e8') return 0; // RSR
289
+ const pricesFromApi = await _getUsdPricesFromApi.call(this);
287
290
  if (assetId.toLowerCase() in pricesFromApi) return pricesFromApi[assetId.toLowerCase()];
288
291
 
289
- if (assetId === 'USD' || (llamalend.chainId === 137 && (assetId.toLowerCase() === llamalend.constants.COINS.am3crv.toLowerCase()))) return 1
292
+ if (assetId === 'USD' || (this.chainId === 137 && (assetId.toLowerCase() === this.constants.COINS.am3crv.toLowerCase()))) return 1
290
293
 
291
294
  let chainName = {
292
295
  1: 'ethereum',
@@ -307,7 +310,7 @@ export const _getUsdRate = async (assetId: string): Promise<number> => {
307
310
  43114: 'avalanche',
308
311
  42161: 'arbitrum-one',
309
312
  1313161554: 'aurora',
310
- }[llamalend.chainId];
313
+ }[this.chainId];
311
314
 
312
315
  const nativeTokenName = {
313
316
  1: 'ethereum',
@@ -328,7 +331,7 @@ export const _getUsdRate = async (assetId: string): Promise<number> => {
328
331
  43114: 'avalanche-2',
329
332
  42161: 'ethereum',
330
333
  1313161554: 'ethereum',
331
- }[llamalend.chainId] as string;
334
+ }[this.chainId] as string;
332
335
 
333
336
  if (chainName === undefined) {
334
337
  throw Error('curve object is not initialized')
@@ -344,13 +347,13 @@ export const _getUsdRate = async (assetId: string): Promise<number> => {
344
347
  assetId = isEth(assetId) ? nativeTokenName : assetId.toLowerCase();
345
348
 
346
349
  // No EURT on Coingecko Polygon
347
- if (llamalend.chainId === 137 && assetId.toLowerCase() === llamalend.constants.COINS.eurt) {
350
+ if (this.chainId === 137 && assetId.toLowerCase() === this.constants.COINS.eurt) {
348
351
  chainName = 'ethereum';
349
352
  assetId = '0xC581b735A1688071A1746c968e0798D642EDE491'.toLowerCase(); // EURT Ethereum
350
353
  }
351
354
 
352
355
  // CRV
353
- if (assetId.toLowerCase() === llamalend.constants.ALIASES.crv) {
356
+ if (assetId.toLowerCase() === this.constants.ALIASES.crv) {
354
357
  assetId = 'curve-dao-token';
355
358
  }
356
359
 
@@ -370,13 +373,13 @@ export const _getUsdRate = async (assetId: string): Promise<number> => {
370
373
  return _usdRatesCache[assetId]['rate']
371
374
  }
372
375
 
373
- export const getUsdRate = async (coin: string): Promise<number> => {
374
- const [coinAddress] = _getCoinAddressesNoCheck(coin);
375
- return await _getUsdRate(coinAddress);
376
+ export const getUsdRate = async function (this: Llamalend, coin: string): Promise<number> {
377
+ const [coinAddress] = _getCoinAddressesNoCheck.call(this, coin);
378
+ return await _getUsdRate.call(this, coinAddress);
376
379
  }
377
380
 
378
- export const getBaseFeeByLastBlock = async () => {
379
- const provider = llamalend.provider;
381
+ export const getBaseFeeByLastBlock = async function (this: Llamalend): Promise<number> {
382
+ const provider = this.provider;
380
383
 
381
384
  try {
382
385
  const block = await provider.getBlock('latest');
@@ -390,18 +393,18 @@ export const getBaseFeeByLastBlock = async () => {
390
393
  }
391
394
  }
392
395
 
393
- export const getGasPriceFromL1 = async (): Promise<number> => {
394
- if(L2Networks.includes(llamalend.chainId) && llamalend.L1WeightedGasPrice) {
395
- return llamalend.L1WeightedGasPrice + 1e9; // + 1 gwei
396
+ export const getGasPriceFromL1 = async function (this: Llamalend): Promise<number> {
397
+ if(L2Networks.includes(this.chainId) && this.L1WeightedGasPrice) {
398
+ return this.L1WeightedGasPrice + 1e9; // + 1 gwei
396
399
  } else {
397
400
  throw Error("This method exists only for L2 networks");
398
401
  }
399
402
  }
400
403
 
401
- export const getGasPriceFromL2 = async (): Promise<number> => {
402
- if(llamalend.chainId === 42161) {
404
+ export async function getGasPriceFromL2(this: Llamalend): Promise<number> {
405
+ if(this.chainId === 42161) {
403
406
  try {
404
- return await getBaseFeeByLastBlock()
407
+ return await getBaseFeeByLastBlock.call(this)
405
408
  } catch (e: any) {
406
409
  throw Error(e)
407
410
  }
@@ -410,10 +413,10 @@ export const getGasPriceFromL2 = async (): Promise<number> => {
410
413
  }
411
414
  }
412
415
 
413
- export const getGasInfoForL2 = async (): Promise<Record<string, number>> => {
414
- if(llamalend.chainId === 42161) {
416
+ export const getGasInfoForL2 = async function (this: Llamalend): Promise<Record<string, number>> {
417
+ if(this.chainId === 42161) {
415
418
  try {
416
- const baseFee = await getBaseFeeByLastBlock()
419
+ const baseFee = await getBaseFeeByLastBlock.call(this)
417
420
 
418
421
  return {
419
422
  maxFeePerGas: Number(((baseFee * 1.1) + 0.01).toFixed(2)),
@@ -427,20 +430,20 @@ export const getGasInfoForL2 = async (): Promise<Record<string, number>> => {
427
430
  }
428
431
  }
429
432
 
430
- export const totalSupply = async (): Promise<{ total: string, minted: string, pegKeepersDebt: string }> => {
433
+ export const totalSupply = async function (this: Llamalend): Promise<{ total: string, minted: string, pegKeepersDebt: string }> {
431
434
  const calls = [];
432
- for (const llammaId of llamalend.getMintMarketList()) {
433
- const controllerAddress = llamalend.constants.LLAMMAS[llammaId].controller_address;
434
- const controllerContract = llamalend.contracts[controllerAddress].multicallContract;
435
+ for (const llammaId of this.getMintMarketList()) {
436
+ const controllerAddress = this.constants.LLAMMAS[llammaId].controller_address;
437
+ const controllerContract = this.contracts[controllerAddress].multicallContract;
435
438
  calls.push(controllerContract.minted(), controllerContract.redeemed());
436
439
  }
437
- for (const pegKeeper of llamalend.constants.PEG_KEEPERS) {
438
- calls.push(llamalend.contracts[pegKeeper].multicallContract.debt());
440
+ for (const pegKeeper of this.constants.PEG_KEEPERS) {
441
+ calls.push(this.contracts[pegKeeper].multicallContract.debt());
439
442
  }
440
- const res: bigint[] = await llamalend.multicallProvider.all(calls);
443
+ const res: bigint[] = await this.multicallProvider.all(calls);
441
444
 
442
445
  let mintedBN = BN(0);
443
- for (let i = 0; i < llamalend.getMintMarketList().length; i++) {
446
+ for (let i = 0; i < this.getMintMarketList().length; i++) {
444
447
  const [_minted, _redeemed] = res.splice(0, 2);
445
448
  mintedBN = toBN(_minted).minus(toBN(_redeemed)).plus(mintedBN);
446
449
  }