@defillama/sdk 5.0.209 → 5.0.212

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.
@@ -3,6 +3,10 @@ import { Chain } from "./general";
3
3
  type BalancesOptions = {
4
4
  skipChain?: boolean;
5
5
  label?: string;
6
+ tags?: string[];
7
+ tag?: string;
8
+ id?: string;
9
+ isUSDValue?: boolean;
6
10
  };
7
11
  type BalancesOptionsWithLabel = BalancesOptions | string;
8
12
  export declare class Balances {
@@ -13,6 +17,10 @@ export declare class Balances {
13
17
  _breakdownBalances: {
14
18
  [key: string]: Balances;
15
19
  };
20
+ _taggedBalances: {
21
+ [tag: string]: Balances;
22
+ };
23
+ _usdBalances: BalancesV1;
16
24
  constructor(params: {
17
25
  chain?: Chain | string;
18
26
  timestamp?: number;
@@ -45,6 +53,9 @@ export declare class Balances {
45
53
  labelBreakdown?: {
46
54
  [key: string]: number;
47
55
  };
56
+ tagBreakdown?: {
57
+ [key: string]: number;
58
+ };
48
59
  debugData?: {
49
60
  tokenData: {
50
61
  balance: string | number;
@@ -67,6 +78,9 @@ export declare class Balances {
67
78
  labelBreakdown?: {
68
79
  [key: string]: number;
69
80
  };
81
+ tagBreakdown?: {
82
+ [key: string]: number;
83
+ };
70
84
  debugData?: {
71
85
  tokenData: {
72
86
  balance: string | number;
@@ -109,10 +123,17 @@ export declare class Balances {
109
123
  _breakdownBalancesAction(action: string, args?: any[]): Promise<{
110
124
  [key: string]: any;
111
125
  }>;
126
+ _taggedBalancesAction(action: string, args?: any[]): Promise<{
127
+ [key: string]: any;
128
+ }>;
112
129
  hasBreakdownBalances(): boolean;
130
+ hasTaggedBalances(): boolean;
113
131
  isEmpty(): boolean;
114
132
  getBreakdownBalances(): {
115
133
  [key: string]: Balances;
116
134
  };
135
+ getTaggedBalances(): {
136
+ [tag: string]: Balances;
137
+ };
117
138
  }
118
139
  export default Balances;
package/build/Balances.js CHANGED
@@ -27,6 +27,11 @@ function getOptions({ optionsOrLabel = {}, options = {} } = {}) {
27
27
  label,
28
28
  };
29
29
  }
30
+ // Duck-type check that also works across module boundaries (when the same package
31
+ // is loaded from two different node_modules copies, `instanceof Balances` returns false).
32
+ function isLlamaBalancesObject(o) {
33
+ return typeof o === 'object' && o !== null && o._llamaBalancesObject === true;
34
+ }
30
35
  class Balances {
31
36
  constructor(params) {
32
37
  var _a;
@@ -34,11 +39,15 @@ class Balances {
34
39
  this.timestamp = params.timestamp;
35
40
  this._balances = {};
36
41
  this._breakdownBalances = {};
42
+ this._taggedBalances = {};
43
+ this._usdBalances = {};
37
44
  this._llamaBalancesObject = true;
38
45
  }
39
46
  _add(token, balance, optionsOrLabel, options) {
40
47
  var _a;
41
- const { label, skipChain } = getOptions({ optionsOrLabel, options });
48
+ const { label, skipChain, tag, tags = [], isUSDValue } = getOptions({ optionsOrLabel, options });
49
+ if (tag && typeof tag === 'string' && !tags.includes(tag))
50
+ tags.push(tag);
42
51
  token = token.replace(/\//g, ':');
43
52
  const isIBCToken = token.startsWith('ibc:');
44
53
  let chain = this.chain;
@@ -53,14 +62,26 @@ class Balances {
53
62
  if (!skipChain && this.chain === 'starknet' && token.length === 65) {
54
63
  token = token.replace('0x', '0x0');
55
64
  }
56
- (0, generalUtil_1.sumSingleBalance)(this._balances, token, balance, chain);
65
+ if (isUSDValue) {
66
+ (0, generalUtil_1.sumSingleBalance)(this._usdBalances, token, balance, chain);
67
+ }
68
+ else {
69
+ (0, generalUtil_1.sumSingleBalance)(this._balances, token, balance, chain);
70
+ }
57
71
  if (label) {
58
72
  this._breakdownBalances[label] = (_a = this._breakdownBalances[label]) !== null && _a !== void 0 ? _a : new Balances({ chain: this.chain, timestamp: this.timestamp });
59
- this._breakdownBalances[label]._add(token, balance, { skipChain });
73
+ this._breakdownBalances[label]._add(token, balance, { skipChain, isUSDValue });
74
+ }
75
+ if (tags.length > 0) {
76
+ tags.forEach((tag) => {
77
+ var _a;
78
+ this._taggedBalances[tag] = (_a = this._taggedBalances[tag]) !== null && _a !== void 0 ? _a : new Balances({ chain: this.chain, timestamp: this.timestamp });
79
+ this._taggedBalances[tag]._add(token, balance, { skipChain, isUSDValue });
80
+ });
60
81
  }
61
82
  }
62
83
  add(token, balance, optionsOrLabel, options) {
63
- if (token instanceof Balances) {
84
+ if (isLlamaBalancesObject(token)) {
64
85
  if (typeof optionsOrLabel === 'string')
65
86
  throw new Error('When adding a Balances instance, optionsOrLabel must be an object with options, not a string');
66
87
  this.addBalances(token, balance, optionsOrLabel);
@@ -103,6 +124,10 @@ class Balances {
103
124
  }
104
125
  addUSDValue(balance, optionsOrLabel, options) {
105
126
  options = getOptions({ optionsOrLabel, options });
127
+ if (options.id) {
128
+ this.add(options.id, balance, { ...options, isUSDValue: true, skipChain: true });
129
+ return;
130
+ }
106
131
  this.addCGToken('tether', balance, { ...options, skipChain: true });
107
132
  }
108
133
  addTokens(tokens, balances, optionsOrLabel, options) {
@@ -116,22 +141,37 @@ class Balances {
116
141
  tokens.forEach((v, i) => this._add(v, balances[i], options));
117
142
  }
118
143
  addBalances(balances, optionsOrLabel, options) {
119
- var _a;
144
+ var _a, _b;
120
145
  options = getOptions({ optionsOrLabel, options });
121
- if (balances instanceof Balances) {
122
- if (balances === this)
146
+ if (isLlamaBalancesObject(balances)) {
147
+ const balancesInstance = balances;
148
+ if (balancesInstance === this)
123
149
  return;
124
150
  // if balances object has breakdown by label, and overall label is not set, we copy existing breakdown balances into this instance
125
- if (balances.hasBreakdownBalances() && !options.skipBreakdown && !options.label) {
151
+ if (balancesInstance.hasBreakdownBalances() && !options.skipBreakdown && !options.label) {
126
152
  this._breakdownBalances = (_a = this._breakdownBalances) !== null && _a !== void 0 ? _a : {};
127
153
  const { label, ...restOptions } = options;
128
- Object.entries(balances.getBreakdownBalances()).forEach(([label, breakdown]) => {
154
+ Object.entries(balancesInstance.getBreakdownBalances()).forEach(([label, breakdown]) => {
129
155
  var _a;
130
156
  this._breakdownBalances[label] = (_a = this._breakdownBalances[label]) !== null && _a !== void 0 ? _a : new Balances({ chain: this.chain, timestamp: this.timestamp });
131
157
  this._breakdownBalances[label].addBalances(breakdown, restOptions);
132
158
  });
133
159
  }
134
- balances = balances.getBalances();
160
+ if (balancesInstance.hasTaggedBalances()) {
161
+ this._taggedBalances = (_b = this._taggedBalances) !== null && _b !== void 0 ? _b : {};
162
+ const { label, ...restOptions } = options;
163
+ Object.entries(balancesInstance.getTaggedBalances()).forEach(([tag, taggedBalance]) => {
164
+ var _a;
165
+ this._taggedBalances[tag] = (_a = this._taggedBalances[tag]) !== null && _a !== void 0 ? _a : new Balances({ chain: this.chain, timestamp: this.timestamp });
166
+ this._taggedBalances[tag].addBalances(taggedBalance, restOptions);
167
+ });
168
+ }
169
+ if (Object.keys(balancesInstance._usdBalances).length > 0) {
170
+ Object.entries(balancesInstance._usdBalances).forEach(([token, balance]) => {
171
+ this._add(token, balance, { ...options, skipChain: true, isUSDValue: true });
172
+ });
173
+ }
174
+ balances = balancesInstance.getBalances();
135
175
  }
136
176
  if (balances === this._balances)
137
177
  return;
@@ -146,18 +186,32 @@ class Balances {
146
186
  if (regex.test(i))
147
187
  delete this._balances[i];
148
188
  });
189
+ Object.keys(this._usdBalances).forEach((i) => {
190
+ if (regex.test(i))
191
+ delete this._usdBalances[i];
192
+ });
149
193
  this._breakdownBalancesAction('removeTokenBalance', [token]);
194
+ this._taggedBalancesAction('removeTokenBalance', [token]);
150
195
  }
151
196
  async getUSDValue() {
152
- const { usdTvl } = await (0, computeTVL_1.default)(this.getBalances(), this.timestamp);
197
+ let { usdTvl } = await (0, computeTVL_1.default)(this.getBalances(), this.timestamp);
198
+ usdTvl = Object.values(this._usdBalances).reduce((a, b) => a + b, usdTvl);
153
199
  return usdTvl;
154
200
  }
155
201
  async getUSDString() {
156
202
  return Number(await this.getUSDValue()).toFixed(0);
157
203
  }
158
204
  async getUSDJSONs({ debug = false, debugOptions: { printTokenTable = true, minTokenUSDValue } = {} } = {}) {
159
- const { usdTvl, usdTokenBalances, debugData } = await (0, computeTVL_1.default)(this.getBalances(), this.timestamp, { debug });
205
+ let { usdTvl, usdTokenBalances, debugData } = await (0, computeTVL_1.default)(this.getBalances(), this.timestamp, { debug });
160
206
  const response = { usdTvl, usdTokenBalances, rawTokenBalances: this.getBalances(), labelBreakdown: {} };
207
+ // add the USD value of tokens that were directly added as USD value (instead of raw token balances that need to be converted to USD value using price cache)
208
+ Object.entries(this._usdBalances).forEach(([symbol, balance]) => {
209
+ usdTvl += Number(balance);
210
+ (0, generalUtil_1.sumSingleBalance)(usdTokenBalances, symbol, balance);
211
+ // skipping it from debug table, unlikely that we would mix raw token balances and direct USD value in the same Balances instance, but if we do, it's cleaner to skip these from debug table since they are already in USD value and don't have price/confidence/decimals data
212
+ // if (debug && !isNaN(Number(balance))) debugData.tokenData.push({ symbol, value: Number(balance), token: symbol, price: 1, confidence: 1, balance, decimals: 0 })
213
+ });
214
+ response.usdTvl = usdTvl;
161
215
  if (debug) {
162
216
  response.debugData = debugData;
163
217
  if (!minTokenUSDValue && minTokenUSDValue !== 0) {
@@ -178,11 +232,18 @@ class Balances {
178
232
  });
179
233
  debugData.tokenData = tokenData;
180
234
  }
181
- if (!this.hasBreakdownBalances())
182
- return response;
183
- for (const [label, breakdown] of Object.entries(this.getBreakdownBalances())) {
184
- const breakdownUSD = await breakdown.getUSDValue();
185
- response.labelBreakdown[label] = breakdownUSD;
235
+ if (this.hasBreakdownBalances()) {
236
+ for (const [label, breakdown] of Object.entries(this.getBreakdownBalances())) {
237
+ const breakdownUSD = await breakdown.getUSDValue();
238
+ response.labelBreakdown[label] = breakdownUSD;
239
+ }
240
+ }
241
+ if (this.hasTaggedBalances()) {
242
+ response.tagBreakdown = {};
243
+ for (const [tag, taggedBalance] of Object.entries(this.getTaggedBalances())) {
244
+ const taggedUSD = await taggedBalance.getUSDValue();
245
+ response.tagBreakdown[tag] = taggedUSD;
246
+ }
186
247
  }
187
248
  return response;
188
249
  }
@@ -193,7 +254,11 @@ class Balances {
193
254
  Object.keys(this._balances).forEach((token) => {
194
255
  this._balances[token] = Number(this._balances[token]) * ratio;
195
256
  });
257
+ Object.keys(this._usdBalances).forEach((token) => {
258
+ this._usdBalances[token] = Number(this._usdBalances[token]) * ratio;
259
+ });
196
260
  this._breakdownBalancesAction('resizeBy', [ratio]);
261
+ this._taggedBalancesAction('resizeBy', [ratio]);
197
262
  return this;
198
263
  }
199
264
  static async getUSDValue(balances, timestamp) {
@@ -219,10 +284,14 @@ class Balances {
219
284
  }
220
285
  subtract(balances, optionsOrLabel, options) {
221
286
  options = getOptions({ optionsOrLabel, options });
222
- if (typeof balances === 'object' && balances !== null && balances._llamaBalancesObject) {
287
+ if (isLlamaBalancesObject(balances)) {
223
288
  if (balances === this)
224
289
  return;
225
- balances = balances.getBalances();
290
+ const balancesInstance = balances;
291
+ Object.entries(balancesInstance._usdBalances).forEach(([token, balance]) => {
292
+ this._add(token, Number(balance) * -1, { skipChain: true, label: options.label, isUSDValue: true });
293
+ });
294
+ balances = balancesInstance.getBalances();
226
295
  }
227
296
  Object.entries(balances).forEach(([token, balance]) => {
228
297
  this._add(token, Number(balance) * -1, { skipChain: true, label: options.label });
@@ -237,9 +306,12 @@ class Balances {
237
306
  if (Number(this._balances[token]) <= 0)
238
307
  delete this._balances[token];
239
308
  });
240
- if (this._breakdownBalances) {
241
- Object.values(this._breakdownBalances).forEach((breakdown) => breakdown.removeNegativeBalances());
242
- }
309
+ Object.keys(this._usdBalances).forEach((token) => {
310
+ if (Number(this._usdBalances[token]) <= 0)
311
+ delete this._usdBalances[token];
312
+ });
313
+ this._breakdownBalancesAction('removeNegativeBalances');
314
+ this._taggedBalancesAction('removeNegativeBalances');
243
315
  }
244
316
  async _breakdownBalancesAction(action, args = []) {
245
317
  if (!this._breakdownBalances)
@@ -256,15 +328,36 @@ class Balances {
256
328
  }
257
329
  return response;
258
330
  }
331
+ async _taggedBalancesAction(action, args = []) {
332
+ if (!this._taggedBalances)
333
+ return {};
334
+ const response = {};
335
+ const entries = Object.entries(this._taggedBalances);
336
+ for (const [label, breakdown] of entries) {
337
+ if (typeof breakdown[action] === 'function') {
338
+ response[label] = breakdown[action](...args);
339
+ if (response[label] instanceof Promise) {
340
+ response[label] = await response[label];
341
+ }
342
+ }
343
+ }
344
+ return response;
345
+ }
259
346
  hasBreakdownBalances() {
260
347
  return Object.keys(this._breakdownBalances).length > 0 && Object.values(this._breakdownBalances).some(b => !b.isEmpty());
261
348
  }
349
+ hasTaggedBalances() {
350
+ return Object.keys(this._taggedBalances).length > 0 && Object.values(this._taggedBalances).some(b => !b.isEmpty());
351
+ }
262
352
  isEmpty() {
263
- return Object.keys(this._balances).length === 0;
353
+ return Object.keys(this._balances).length === 0 && Object.keys(this._usdBalances).length === 0;
264
354
  }
265
355
  getBreakdownBalances() {
266
356
  return this._breakdownBalances;
267
357
  }
358
+ getTaggedBalances() {
359
+ return this._taggedBalances;
360
+ }
268
361
  }
269
362
  exports.Balances = Balances;
270
363
  exports.default = Balances;
@@ -95,6 +95,9 @@ export declare class ChainApi {
95
95
  labelBreakdown?: {
96
96
  [key: string]: number;
97
97
  };
98
+ tagBreakdown?: {
99
+ [key: string]: number;
100
+ };
98
101
  debugData?: {
99
102
  tokenData: {
100
103
  balance: string | number;
@@ -371,6 +371,7 @@ function multicallAddress(chainId) {
371
371
  case 728126428: return 'TEazPvZwDjDtFeJupyo7QunvnrnUjPH8ED'; // silicon_zk
372
372
  case 1110: return '0x114575812CF34299cd65BD251C798608fa805433'; // grx
373
373
  case 1990: return '0xfD4014ba4dDB610A1587501378Fa52eee6C3a07B'; // qiev3
374
+ case 38833: return '0x7B2Fa3e6CE90Ce6037395630a4C6DF45B7ef25Af'; // igra
374
375
  default:
375
376
  return null;
376
377
  }
@@ -214,6 +214,7 @@ const DEPLOYMENT_BLOCK = {
214
214
  tempo: 1,
215
215
  edegex: 1,
216
216
  wchain: 2207643,
217
+ fluent: 754598
217
218
  };
218
219
  async function makeMultiCall(functionABI, calls, chain, block) {
219
220
  if (!functionABI)
@@ -324,7 +325,6 @@ const CUSTOM_MULTICALL_ADDRESSES = {
324
325
  'taiko': '0xcb2436774C3e191c85056d248EF4260ce5f27A9D',
325
326
  'qom': '0x7A52370716ea730585884F5BDB0f6E60C39b8C64',
326
327
  'matchain': '0xDa91510Bd8c50bfa54FC2BE2dD6dAbE03eA8496c',
327
- 'morph': '0x33A213b1049D5AD2eeE6e61dAe040955e60383D4',
328
328
  'ace': '0x025A2B4fCE1E0bD736D5cebe6C8a52229795376B',
329
329
  'sophon': '0x5f4867441d2416cA88B1b3fd38f21811680CD2C8',
330
330
  'vana': '0xFe92b91F3326e58557478c28EeAe1936E0c7148a',
@@ -1,7 +1,8 @@
1
1
  import * as blocks from "./computeTVL/blocks";
2
+ import * as discord from "./util/discord";
2
3
  import * as humanizeNumber from "./computeTVL/humanizeNumber";
3
4
  export { sliceIntoChunks, normalizeAddress, getTimestamp, tableToString, } from "./util";
4
5
  export { isEvmChain, getEVMChainSet, getEVMProvidersConfigMap, } from "./util/LlamaProvider";
5
6
  export { runInPromisePool } from "./util/promisePool";
6
7
  export { sumMultiBalanceOf, sumSingleBalance, mergeBalances, removeTokenBalance, sumChainTvls, getUniqueAddresses, convertToBigInt, getProviderUrl, formError, formErrorString, shortenString, fetchJson, postJson, tronToEvmAddress, evmToTronAddress, sleep, sleepRandom, getHash, } from './util/common';
7
- export { blocks, humanizeNumber, };
8
+ export { blocks, humanizeNumber, discord, };
@@ -33,9 +33,11 @@ var __importStar = (this && this.__importStar) || (function () {
33
33
  };
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.humanizeNumber = exports.blocks = exports.getHash = exports.sleepRandom = exports.sleep = exports.evmToTronAddress = exports.tronToEvmAddress = exports.postJson = exports.fetchJson = exports.shortenString = exports.formErrorString = exports.formError = exports.getProviderUrl = exports.convertToBigInt = exports.getUniqueAddresses = exports.sumChainTvls = exports.removeTokenBalance = exports.mergeBalances = exports.sumSingleBalance = exports.sumMultiBalanceOf = exports.runInPromisePool = exports.getEVMProvidersConfigMap = exports.getEVMChainSet = exports.isEvmChain = exports.tableToString = exports.getTimestamp = exports.normalizeAddress = exports.sliceIntoChunks = void 0;
36
+ exports.discord = exports.humanizeNumber = exports.blocks = exports.getHash = exports.sleepRandom = exports.sleep = exports.evmToTronAddress = exports.tronToEvmAddress = exports.postJson = exports.fetchJson = exports.shortenString = exports.formErrorString = exports.formError = exports.getProviderUrl = exports.convertToBigInt = exports.getUniqueAddresses = exports.sumChainTvls = exports.removeTokenBalance = exports.mergeBalances = exports.sumSingleBalance = exports.sumMultiBalanceOf = exports.runInPromisePool = exports.getEVMProvidersConfigMap = exports.getEVMChainSet = exports.isEvmChain = exports.tableToString = exports.getTimestamp = exports.normalizeAddress = exports.sliceIntoChunks = void 0;
37
37
  const blocks = __importStar(require("./computeTVL/blocks"));
38
38
  exports.blocks = blocks;
39
+ const discord = __importStar(require("./util/discord"));
40
+ exports.discord = discord;
39
41
  const humanizeNumber = __importStar(require("./computeTVL/humanizeNumber"));
40
42
  exports.humanizeNumber = humanizeNumber;
41
43
  var util_1 = require("./util");