@talismn/balances 0.3.3 → 0.4.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.
@@ -4,19 +4,14 @@ Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var dexie = require('dexie');
6
6
  var types = require('@polkadot/types');
7
- var anylogger = require('anylogger');
8
7
  var util = require('@talismn/util');
9
- var memoize = require('lodash/memoize');
10
- var typescriptMemoize = require('typescript-memoize');
8
+ var groupBy = require('lodash/groupBy');
9
+ var anylogger = require('anylogger');
11
10
 
12
11
  function _interopDefault (e) { return e && e.__esModule ? e : { 'default': e }; }
13
12
 
13
+ var groupBy__default = /*#__PURE__*/_interopDefault(groupBy);
14
14
  var anylogger__default = /*#__PURE__*/_interopDefault(anylogger);
15
- var memoize__default = /*#__PURE__*/_interopDefault(memoize);
16
-
17
- //
18
- // exported
19
- //
20
15
 
21
16
  // TODO: Document default balances module purpose/usage
22
17
  const DefaultBalanceModule = type => ({
@@ -35,12 +30,15 @@ const DefaultBalanceModule = type => ({
35
30
  async fetchEvmChainTokens() {
36
31
  return Promise.resolve({});
37
32
  },
38
- async subscribeBalances(_chainConnectors, _chaindataProvider, _addressesByToken, callback) {
33
+ async subscribeBalances(_, callback) {
39
34
  callback(new Error("Balance subscriptions are not implemented in this module."));
40
35
  return () => {};
41
36
  },
42
37
  async fetchBalances() {
43
38
  throw new Error("Balance fetching is not implemented in this module.");
39
+ },
40
+ async transferToken() {
41
+ throw new Error("Token transfers are not implemented in this module.");
44
42
  }
45
43
  });
46
44
 
@@ -71,7 +69,7 @@ const db = new TalismanBalancesDatabase();
71
69
 
72
70
  var packageJson = {
73
71
  name: "@talismn/balances",
74
- version: "0.3.3",
72
+ version: "0.4.1",
75
73
  author: "Talisman",
76
74
  homepage: "https://talisman.xyz",
77
75
  license: "UNLICENSED",
@@ -90,36 +88,36 @@ var packageJson = {
90
88
  "/plugins"
91
89
  ],
92
90
  engines: {
93
- node: ">=14"
91
+ node: ">=18"
94
92
  },
95
93
  scripts: {
96
94
  test: "jest",
97
- lint: "eslint . --max-warnings 0",
95
+ lint: "eslint src --max-warnings 0",
98
96
  clean: "rm -rf dist && rm -rf .turbo rm -rf node_modules"
99
97
  },
100
98
  dependencies: {
101
- "@talismn/chain-connector": "workspace:^",
102
- "@talismn/chain-connector-evm": "workspace:^",
103
- "@talismn/chaindata-provider": "workspace:^",
104
- "@talismn/token-rates": "workspace:^",
105
- "@talismn/util": "workspace:^",
99
+ "@talismn/chain-connector": "workspace:*",
100
+ "@talismn/chain-connector-evm": "workspace:*",
101
+ "@talismn/chaindata-provider": "workspace:*",
102
+ "@talismn/token-rates": "workspace:*",
103
+ "@talismn/util": "workspace:*",
106
104
  anylogger: "^1.0.11",
107
- dexie: "^3.2.2",
108
- lodash: "^4.17.21",
109
- "typescript-memoize": "^1.1.0"
105
+ dexie: "^3.2.3",
106
+ lodash: "4.17.21"
110
107
  },
111
108
  devDependencies: {
112
- "@polkadot/types": "^9.10.5",
113
- "@talismn/eslint-config": "workspace:^",
114
- "@talismn/tsconfig": "workspace:^",
109
+ "@polkadot/types": "^10.1.4",
110
+ "@talismn/eslint-config": "workspace:*",
111
+ "@talismn/tsconfig": "workspace:*",
115
112
  "@types/jest": "^27.5.1",
113
+ "@types/lodash": "^4.14.180",
116
114
  eslint: "^8.4.0",
117
115
  jest: "^28.1.0",
118
116
  "ts-jest": "^28.0.2",
119
117
  typescript: "^4.6.4"
120
118
  },
121
119
  peerDependencies: {
122
- "@polkadot/types": "9.x"
120
+ "@polkadot/types": "10.x"
123
121
  },
124
122
  preconstruct: {
125
123
  entrypoints: [
@@ -137,18 +135,114 @@ var packageJson = {
137
135
 
138
136
  var log = anylogger__default["default"](packageJson.name);
139
137
 
140
- async function balances(balanceModule, chainConnectors, chaindataProvider, addressesByToken, callback) {
138
+ /**
139
+ * Wraps a BalanceModule's fetch/subscribe methods with a single `balances` method.
140
+ * This `balances` method will subscribe if a callback parameter is provided, or otherwise fetch.
141
+ */
142
+
143
+ async function balances(balanceModule, addressesByToken, callback) {
141
144
  // subscription request
142
- if (callback !== undefined) return await balanceModule.subscribeBalances(chainConnectors, chaindataProvider, addressesByToken, callback);
145
+ if (callback !== undefined) return await balanceModule.subscribeBalances(addressesByToken, callback);
143
146
 
144
147
  // one-off request
145
- return await balanceModule.fetchBalances(chainConnectors, chaindataProvider, addressesByToken);
148
+ return await balanceModule.fetchBalances(addressesByToken);
146
149
  }
150
+ const createTypeRegistryCache = () => {
151
+ const typeRegistryCache = new Map();
152
+ const getOrCreateTypeRegistry = (chainId, metadataRpc) => {
153
+ // TODO: Delete cache when metadataRpc is different from last time
154
+ const cached = typeRegistryCache.get(chainId);
155
+ if (cached) return cached;
156
+ const typeRegistry = new types.TypeRegistry();
157
+ if (typeof metadataRpc === "string") {
158
+ try {
159
+ const metadata = new types.Metadata(typeRegistry, metadataRpc);
160
+ metadata.registry.setMetadata(metadata);
161
+ } catch (cause) {
162
+ log.warn(new Error(`Failed to set metadata for chain ${chainId}`, {
163
+ cause
164
+ }), cause);
165
+ }
166
+ }
167
+ typeRegistryCache.set(chainId, typeRegistry);
168
+ return typeRegistry;
169
+ };
170
+ return {
171
+ getOrCreateTypeRegistry
172
+ };
173
+ };
174
+
175
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
176
+
177
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
178
+
179
+ /**
180
+ * The following `Infer*` collection of generic types can be used when you want to
181
+ * extract one of the generic type arguments from an existing BalanceModule.
182
+ *
183
+ * For example, you might want to write a function which can accept any BalanceModule
184
+ * as an input, and then return the specific TokenType for that module:
185
+ * function getTokens<T extends AnyBalanceModule>(module: T): InferTokenType<T>
186
+ *
187
+ * Or for another example, you might want a function which can take any BalanceModule `type`
188
+ * string as input, and then return some data associated with that module with the correct type:
189
+ * function getChainMeta<T extends AnyBalanceModule>(type: InferModuleType<T>): InferChainMeta<T> | undefined
190
+ */
191
+
192
+ /**
193
+ * Given a `moduleType` and a `chain` from a chaindataProvider, this function will find the chainMeta
194
+ * associated with the given balanceModule for the given chain.
195
+ */
196
+ const findChainMeta = (moduleType, chain) => {
197
+ return (chain?.balanceMetadata ?? []).find(meta => meta.moduleType === moduleType)?.metadata;
198
+ };
147
199
  const filterMirrorTokens = (balance, i, balances) => {
148
- // TODO implement a mirrorOf property, which should be set from chaindata
149
200
  const mirrorOf = balance.token?.mirrorOf;
150
201
  return !mirrorOf || !balances.find(b => b.tokenId === mirrorOf);
151
202
  };
203
+ const getValidSubscriptionIds = () => {
204
+ return new Set(localStorage.getItem("TalismanBalancesSubscriptionIds")?.split(",") ?? []);
205
+ };
206
+ const createSubscriptionId = () => {
207
+ // delete current id (if exists)
208
+ deleteSubscriptionId();
209
+
210
+ // create new id
211
+ const subscriptionId = Date.now().toString();
212
+ sessionStorage.setItem("TalismanBalancesSubscriptionId", subscriptionId);
213
+
214
+ // add to list of current ids
215
+ const subscriptionIds = getValidSubscriptionIds();
216
+ subscriptionIds.add(subscriptionId);
217
+ localStorage.setItem("TalismanBalancesSubscriptionIds", [...subscriptionIds].filter(Boolean).join(","));
218
+ return subscriptionId;
219
+ };
220
+ const deleteSubscriptionId = () => {
221
+ const subscriptionId = sessionStorage.getItem("TalismanBalancesSubscriptionId");
222
+ if (!subscriptionId) return;
223
+ const subscriptionIds = getValidSubscriptionIds();
224
+ subscriptionIds.delete(subscriptionId);
225
+ localStorage.setItem("TalismanBalancesSubscriptionIds", [...subscriptionIds].filter(Boolean).join(","));
226
+ };
227
+
228
+ /**
229
+ * Sets all balance statuses from `live-${string}` to either `live` or `cached`
230
+ */
231
+ const deriveStatuses = (validSubscriptionIds, balances) => balances.map(balance => {
232
+ if (balance.status === "live" || balance.status === "cache" || balance.status === "stale") return balance;
233
+ if (validSubscriptionIds.length < 1) return {
234
+ ...balance,
235
+ status: "cache"
236
+ };
237
+ if (!validSubscriptionIds.includes(balance.status.slice("live-".length))) return {
238
+ ...balance,
239
+ status: "cache"
240
+ };
241
+ return {
242
+ ...balance,
243
+ status: "live"
244
+ };
245
+ });
152
246
 
153
247
  /**
154
248
  * Used by a variety of balance modules to help encode and decode substrate state calls.
@@ -159,7 +253,11 @@ class StorageHelper {
159
253
  #module;
160
254
  #method;
161
255
  #parameters;
256
+
257
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
162
258
  tags = null;
259
+
260
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
163
261
  constructor(registry, module, method, ...parameters) {
164
262
  this.#registry = registry;
165
263
  this.#module = module;
@@ -193,6 +291,8 @@ class StorageHelper {
193
291
  get parameters() {
194
292
  return this.#parameters;
195
293
  }
294
+
295
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
196
296
  tag(tags) {
197
297
  this.tags = tags;
198
298
  return this;
@@ -231,34 +331,106 @@ class StorageHelper {
231
331
  }
232
332
  }
233
333
 
234
- function _applyDecoratedDescriptor(target, property, decorators, descriptor, context) {
235
- var desc = {};
236
- Object.keys(descriptor).forEach(function (key) {
237
- desc[key] = descriptor[key];
238
- });
239
- desc.enumerable = !!desc.enumerable;
240
- desc.configurable = !!desc.configurable;
241
- if ('value' in desc || desc.initializer) {
242
- desc.writable = true;
243
- }
244
- desc = decorators.slice().reverse().reduce(function (desc, decorator) {
245
- return decorator(target, property, desc) || desc;
246
- }, desc);
247
- if (context && desc.initializer !== void 0) {
248
- desc.value = desc.initializer ? desc.initializer.call(context) : void 0;
249
- desc.initializer = undefined;
250
- }
251
- if (desc.initializer === void 0) {
252
- Object.defineProperty(target, property, desc);
253
- desc = null;
254
- }
255
- return desc;
334
+ /**
335
+ * Pass some these into an `RpcStateQueryHelper` in order to easily batch multiple state queries into the one rpc call.
336
+ */
337
+
338
+ /**
339
+ * Used by a variety of balance modules to help batch multiple state queries into the one rpc call.
340
+ */
341
+ class RpcStateQueryHelper {
342
+ #chainConnector;
343
+ #queries;
344
+ constructor(chainConnector, queries) {
345
+ this.#chainConnector = chainConnector;
346
+ this.#queries = queries;
347
+ }
348
+ async subscribe(callback, timeout = false, subscribeMethod = "state_subscribeStorage", responseMethod = "state_storage", unsubscribeMethod = "state_unsubscribeStorage") {
349
+ const queriesByChain = groupBy__default["default"](this.#queries, "chainId");
350
+ const subscriptions = Object.entries(queriesByChain).map(([chainId, queries]) => {
351
+ const params = [queries.map(({
352
+ stateKey
353
+ }) => stateKey)];
354
+ const unsub = this.#chainConnector.subscribe(chainId, subscribeMethod, responseMethod, params, (error, result) => {
355
+ error ? callback(error) : callback(null, this.#distributeChangesToQueryDecoders.call(this, chainId, result));
356
+ }, timeout);
357
+ return () => unsub.then(unsubscribe => unsubscribe(unsubscribeMethod));
358
+ });
359
+ return () => subscriptions.forEach(unsubscribe => unsubscribe());
360
+ }
361
+ async fetch(method = "state_queryStorageAt") {
362
+ const queriesByChain = groupBy__default["default"](this.#queries, "chainId");
363
+ const resultsByChain = await Promise.all(Object.entries(queriesByChain).map(async ([chainId, queries]) => {
364
+ const params = [queries.map(({
365
+ stateKey
366
+ }) => stateKey)];
367
+ const result = (await this.#chainConnector.send(chainId, method, params))[0];
368
+ return this.#distributeChangesToQueryDecoders.call(this, chainId, result);
369
+ }));
370
+ return resultsByChain.flatMap(result => result);
371
+ }
372
+ #distributeChangesToQueryDecoders(chainId, result) {
373
+ if (typeof result !== "object" || result === null) return [];
374
+ if (!util.hasOwnProperty(result, "changes") || typeof result.changes !== "object") return [];
375
+ if (!Array.isArray(result.changes)) return [];
376
+ return result.changes.flatMap(([reference, change]) => {
377
+ if (typeof reference !== "string") {
378
+ log.warn(`Received non-string reference in RPC result: ${reference}`);
379
+ return [];
380
+ }
381
+ if (typeof change !== "string" && change !== null) {
382
+ log.warn(`Received non-string and non-null change in RPC result: ${reference} | ${change}`);
383
+ return [];
384
+ }
385
+ const query = this.#queries.find(({
386
+ chainId: cId,
387
+ stateKey
388
+ }) => cId === chainId && stateKey === reference);
389
+ if (!query) {
390
+ log.warn(`Failed to find query:\n${reference} in\n${this.#queries.map(({
391
+ stateKey
392
+ }) => stateKey)}`);
393
+ return [];
394
+ }
395
+ return [query.decodeResult(change)];
396
+ });
397
+ }
256
398
  }
257
399
 
400
+ /**
401
+ * `BalanceTypes` is an automatically determined sub-selection of `PluginBalanceTypes`.
402
+ *
403
+ * It is the same list, but with any invalid `BalanceType` definitions filtered out.
404
+ */
405
+
406
+ /**
407
+ * The `BalanceJson` sum type, which is a union of all of the possible `BalanceTypes`.
408
+ *
409
+ * Each variant comes from a plugin in use by the consuming app.
410
+ *
411
+ * For example, in an app with the `substrate-native`, `evm-native`, `substrate-orml` and `evm-erc20` plugins:
412
+ *
413
+ * type BalanceJson = SubNativeBalance | EvmNativeBalance | SubOrmlBalance | EvmErc20Balance
414
+ *
415
+ * If `BalanceTypes` is empty then `BalanceJson` will fall back to the common `IBalance` interface, which every balance must implement.
416
+ */
417
+
418
+ /** A collection of `BalanceJson` objects */
419
+
420
+ const BalanceStatusLive = subscriptionId => `live-${subscriptionId}`;
421
+
422
+ /** `IBalance` is a common interface which all balance types must implement. */
423
+
424
+ /** An unlabelled amount of a balance */
425
+
426
+ /** A labelled amount of a balance */
427
+
428
+ /** A labelled locked amount of a balance */
429
+
258
430
  function excludeFromTransferableAmount(locks) {
259
431
  if (typeof locks === "string") return BigInt(locks);
260
432
  if (!Array.isArray(locks)) locks = [locks];
261
- return locks.filter(lock => lock.includeInTransferable !== true).map(lock => BigInt(lock.amount)).reduce((max, lock) => util.BigMath.max(max, lock), BigInt("0"));
433
+ return locks.filter(lock => lock.includeInTransferable !== true).map(lock => BigInt(lock.amount)).reduce((max, lock) => util.BigMath.max(max, lock), 0n);
262
434
  }
263
435
  function excludeFromFeePayableLocks(locks) {
264
436
  if (typeof locks === "string") return [];
@@ -269,31 +441,29 @@ function excludeFromFeePayableLocks(locks) {
269
441
  /** A labelled extra amount of a balance */
270
442
 
271
443
  function includeInTotalExtraAmount(extra) {
272
- if (!extra) return BigInt("0");
444
+ if (!extra) return 0n;
273
445
  if (!Array.isArray(extra)) extra = [extra];
274
- return extra.filter(extra => extra.includeInTotal).map(extra => BigInt(extra.amount)).reduce((a, b) => a + b, BigInt("0"));
446
+ return extra.filter(extra => extra.includeInTotal).map(extra => BigInt(extra.amount)).reduce((a, b) => a + b, 0n);
275
447
  }
276
448
 
277
449
  /** Used by plugins to help define their custom `BalanceType` */
278
450
 
279
- var _dec, _dec2, _dec3, _class, _dec4, _dec5, _dec6, _dec7, _dec8, _dec9, _dec10, _class2, _dec11, _class3, _dec12, _dec13, _dec14, _dec15, _dec16, _dec17, _dec18, _class4;
280
-
281
451
  /**
282
452
  * Have the importing library define its Token and BalanceJson enums (as a sum type of all plugins) and pass them into some
283
453
  * internal global typescript context, which is then picked up on by this module.
284
454
  */
285
455
 
286
456
  /** A utility type used to extract the underlying `BalanceType` of a specific source from a generalised `BalanceJson` */
287
-
457
+ /** TODO: Remove this in favour of a frontend-friendly `ChaindataProvider` */
288
458
  /**
289
459
  * A collection of balances.
290
460
  */
291
- let Balances = (_dec = typescriptMemoize.Memoize(), _dec2 = typescriptMemoize.Memoize(), _dec3 = typescriptMemoize.Memoize(), (_class = class Balances {
461
+ class Balances {
292
462
  //
293
463
  // Properties
294
464
  //
295
465
 
296
- #balances = {};
466
+ #balances = [];
297
467
 
298
468
  //
299
469
  // Methods
@@ -301,7 +471,7 @@ let Balances = (_dec = typescriptMemoize.Memoize(), _dec2 = typescriptMemoize.Me
301
471
 
302
472
  constructor(balances, hydrate) {
303
473
  // handle Balances (convert to Balance[])
304
- if (balances instanceof Balances) return new Balances([...balances], hydrate);
474
+ if (balances instanceof Balances) return new Balances(balances.each, hydrate);
305
475
 
306
476
  // handle Balance (convert to Balance[])
307
477
  if (balances instanceof Balance) return new Balances([balances], hydrate);
@@ -316,19 +486,19 @@ let Balances = (_dec = typescriptMemoize.Memoize(), _dec2 = typescriptMemoize.Me
316
486
  if (!util.isArrayOf(balances, Balance)) return new Balances(balances.map(storage => new Balance(storage)), hydrate);
317
487
 
318
488
  // handle Balance[]
319
- this.#balances = Object.fromEntries(balances.map(balance => [balance.id, balance]));
489
+ this.#balances = balances;
320
490
  if (hydrate !== undefined) this.hydrate(hydrate);
321
491
  }
322
492
 
323
493
  /**
324
494
  * Calling toJSON on a collection of balances will return the underlying BalanceJsonList.
325
495
  */
326
- toJSON = () => Object.fromEntries(Object.entries(this.#balances).map(([id, balance]) => {
496
+ toJSON = () => Object.fromEntries(this.#balances.map(balance => {
327
497
  try {
328
- return [id, balance.toJSON()];
498
+ return [balance.id, balance.toJSON()];
329
499
  } catch (error) {
330
500
  log.error("Failed to convert balance to JSON", error, {
331
- id,
501
+ id: balance.id,
332
502
  balance
333
503
  });
334
504
  return null;
@@ -348,7 +518,7 @@ let Balances = (_dec = typescriptMemoize.Memoize(), _dec2 = typescriptMemoize.Me
348
518
  */
349
519
  [Symbol.iterator] = () =>
350
520
  // Create an array of the balances in this collection and return the result of its iterator.
351
- Object.values(this.#balances)[Symbol.iterator]();
521
+ this.#balances[Symbol.iterator]();
352
522
 
353
523
  /**
354
524
  * Hydrates all balances in this collection.
@@ -356,7 +526,7 @@ let Balances = (_dec = typescriptMemoize.Memoize(), _dec2 = typescriptMemoize.Me
356
526
  * @param sources - The sources to hydrate from.
357
527
  */
358
528
  hydrate = sources => {
359
- Object.values(this.#balances).map(balance => balance.hydrate(sources));
529
+ this.#balances.map(balance => balance.hydrate(sources));
360
530
  };
361
531
 
362
532
  /**
@@ -365,7 +535,7 @@ let Balances = (_dec = typescriptMemoize.Memoize(), _dec2 = typescriptMemoize.Me
365
535
  * @param id - The id of the balance to fetch.
366
536
  * @returns The balance if one exists, or none.
367
537
  */
368
- get = id => this.#balances[id] || null;
538
+ get = id => this.#balances.find(balance => balance.id === id) ?? null;
369
539
 
370
540
  /**
371
541
  * Retrieve balances from this collection by search query.
@@ -384,6 +554,27 @@ let Balances = (_dec = typescriptMemoize.Memoize(), _dec2 = typescriptMemoize.Me
384
554
  return new Balances([...this].filter(filter));
385
555
  };
386
556
 
557
+ /**
558
+ * Filters this collection to exclude token balances where the token has a `mirrorOf` field
559
+ * and another balance exists in this collection for the token specified by the `mirrorOf` field.
560
+ */
561
+ filterMirrorTokens = () => new Balances([...this].filter(filterMirrorTokens));
562
+
563
+ /**
564
+ * Filters this collection to only include balances which are not zero.
565
+ */
566
+ filterNonZero = type => {
567
+ const filter = balance => balance[type].planck > 0n;
568
+ return this.find(filter);
569
+ };
570
+ /**
571
+ * Filters this collection to only include balances which are not zero AND have a fiat conversion rate.
572
+ */
573
+ filterNonZeroFiat = (type, currency) => {
574
+ const filter = balance => (balance[type].fiat(currency) ?? 0) > 0;
575
+ return this.find(filter);
576
+ };
577
+
387
578
  /**
388
579
  * Add some balances to this collection.
389
580
  * Added balances take priority over existing balances.
@@ -398,10 +589,8 @@ let Balances = (_dec = typescriptMemoize.Memoize(), _dec2 = typescriptMemoize.Me
398
589
  if (balances instanceof Balance) return this.add(new Balances(balances));
399
590
 
400
591
  // merge balances
401
- const mergedBalances = {
402
- ...this.#balances
403
- };
404
- [...balances].forEach(balance => mergedBalances[balance.id] = balance);
592
+ const mergedBalances = Object.fromEntries(this.#balances.map(balance => [balance.id, balance]));
593
+ balances.each.forEach(balance => mergedBalances[balance.id] = balance);
405
594
 
406
595
  // return new balances
407
596
  return new Balances(Object.values(mergedBalances));
@@ -419,25 +608,23 @@ let Balances = (_dec = typescriptMemoize.Memoize(), _dec2 = typescriptMemoize.Me
419
608
  // handle single id
420
609
  if (!Array.isArray(ids)) return this.remove([ids]);
421
610
 
422
- // merge balances
423
- const removedBalances = {
424
- ...this.#balances
425
- };
426
- ids.forEach(id => delete removedBalances[id]);
427
-
428
- // return new balances
429
- return new Balances(Object.values(removedBalances));
611
+ // merge and return new balances
612
+ return new Balances(this.#balances.filter(balance => !ids.includes(balance.id)));
430
613
  };
431
614
 
432
615
  // TODO: Add some more useful aggregator methods
433
616
 
617
+ get each() {
618
+ return [...this];
619
+ }
620
+
434
621
  /**
435
622
  * Get an array of balances in this collection, sorted by chain sortIndex.
436
623
  *
437
624
  * @returns A sorted array of the balances in this collection.
438
625
  */
439
626
  get sorted() {
440
- return [...this].sort((a, b) => ((a.chain || a.evmNetwork)?.sortIndex || Number.MAX_SAFE_INTEGER) - ((b.chain || b.evmNetwork)?.sortIndex || Number.MAX_SAFE_INTEGER));
627
+ return [...this].sort((a, b) => ((a.chain || a.evmNetwork)?.sortIndex ?? Number.MAX_SAFE_INTEGER) - ((b.chain || b.evmNetwork)?.sortIndex ?? Number.MAX_SAFE_INTEGER));
441
628
  }
442
629
 
443
630
  /**
@@ -460,12 +647,12 @@ let Balances = (_dec = typescriptMemoize.Memoize(), _dec2 = typescriptMemoize.Me
460
647
  get sum() {
461
648
  return new SumBalancesFormatter(this);
462
649
  }
463
- }, (_applyDecoratedDescriptor(_class.prototype, "sorted", [_dec], Object.getOwnPropertyDescriptor(_class.prototype, "sorted"), _class.prototype), _applyDecoratedDescriptor(_class.prototype, "count", [_dec2], Object.getOwnPropertyDescriptor(_class.prototype, "count"), _class.prototype), _applyDecoratedDescriptor(_class.prototype, "sum", [_dec3], Object.getOwnPropertyDescriptor(_class.prototype, "sum"), _class.prototype)), _class));
650
+ }
464
651
 
465
652
  /**
466
653
  * An individual balance.
467
654
  */
468
- let Balance = (_dec4 = typescriptMemoize.Memoize(), _dec5 = typescriptMemoize.Memoize(), _dec6 = typescriptMemoize.Memoize(), _dec7 = typescriptMemoize.Memoize(), _dec8 = typescriptMemoize.Memoize(), _dec9 = typescriptMemoize.Memoize(), _dec10 = typescriptMemoize.Memoize(), (_class2 = class Balance {
655
+ class Balance {
469
656
  //
470
657
  // Properties
471
658
  //
@@ -479,7 +666,6 @@ let Balance = (_dec4 = typescriptMemoize.Memoize(), _dec5 = typescriptMemoize.Me
479
666
  //
480
667
 
481
668
  constructor(storage, hydrate) {
482
- this.#format = memoize__default["default"](this.#format);
483
669
  this.#storage = storage;
484
670
  if (hydrate !== undefined) this.hydrate(hydrate);
485
671
  }
@@ -511,13 +697,14 @@ let Balance = (_dec4 = typescriptMemoize.Memoize(), _dec5 = typescriptMemoize.Me
511
697
  get id() {
512
698
  const {
513
699
  source,
700
+ subSource,
514
701
  address,
515
702
  chainId,
516
703
  evmNetworkId,
517
704
  tokenId
518
705
  } = this.#storage;
519
706
  const locationId = chainId !== undefined ? chainId : evmNetworkId;
520
- return `${source}-${address}-${locationId}-${tokenId}`;
707
+ return [source, address, locationId, tokenId, subSource].filter(Boolean).join("-");
521
708
  }
522
709
  get source() {
523
710
  return this.#storage.source;
@@ -566,17 +753,43 @@ let Balance = (_dec4 = typescriptMemoize.Memoize(), _dec5 = typescriptMemoize.Me
566
753
  }
567
754
  /** The non-reserved balance of this token. Includes the frozen amount. Is included in the total. */
568
755
  get free() {
569
- return this.#format(typeof this.#storage.free === "string" ? BigInt(this.#storage.free) : Array.isArray(this.#storage.free) ? this.#storage.free.map(reserve => BigInt(reserve.amount)).reduce((a, b) => a + b, BigInt("0")) : BigInt(this.#storage.free?.amount || "0"));
756
+ return this.#format(typeof this.#storage.free === "string" ? BigInt(this.#storage.free) : Array.isArray(this.#storage.free) ? this.#storage.free.map(reserve => BigInt(reserve.amount)).reduce((a, b) => a + b, 0n) : BigInt(this.#storage.free?.amount || "0"));
570
757
  }
571
758
  /** The reserved balance of this token. Is included in the total. */
572
759
  get reserved() {
573
- return this.#format(typeof this.#storage.reserves === "string" ? BigInt(this.#storage.reserves) : Array.isArray(this.#storage.reserves) ? this.#storage.reserves.map(reserve => BigInt(reserve.amount)).reduce((a, b) => a + b, BigInt("0")) : BigInt(this.#storage.reserves?.amount || "0"));
760
+ return this.#format(typeof this.#storage.reserves === "string" ? BigInt(this.#storage.reserves) : Array.isArray(this.#storage.reserves) ? this.#storage.reserves.map(reserve => BigInt(reserve.amount)).reduce((a, b) => a + b, 0n) : BigInt(this.#storage.reserves?.amount || "0"));
761
+ }
762
+ get reserves() {
763
+ return (Array.isArray(this.#storage.reserves) ? this.#storage.reserves : [this.#storage.reserves]).flatMap(reserve => {
764
+ if (reserve === undefined) return [];
765
+ if (typeof reserve === "string") return {
766
+ label: "reserved",
767
+ amount: this.#format(reserve)
768
+ };
769
+ return {
770
+ ...reserve,
771
+ amount: this.#format(reserve.amount)
772
+ };
773
+ });
574
774
  }
575
775
  /** The frozen balance of this token. Is included in the free amount. */
576
776
  get locked() {
577
- return this.#format(typeof this.#storage.locks === "string" ? BigInt(this.#storage.locks) : Array.isArray(this.#storage.locks) ? this.#storage.locks.map(lock => BigInt(lock.amount)).reduce((a, b) => util.BigMath.max(a, b), BigInt("0")) : BigInt(this.#storage.locks?.amount || "0"));
777
+ return this.#format(typeof this.#storage.locks === "string" ? BigInt(this.#storage.locks) : Array.isArray(this.#storage.locks) ? this.#storage.locks.map(lock => BigInt(lock.amount)).reduce((a, b) => util.BigMath.max(a, b), 0n) : BigInt(this.#storage.locks?.amount || "0"));
778
+ }
779
+ get locks() {
780
+ return (Array.isArray(this.#storage.locks) ? this.#storage.locks : [this.#storage.locks]).flatMap(lock => {
781
+ if (lock === undefined) return [];
782
+ if (typeof lock === "string") return {
783
+ label: "other",
784
+ amount: this.#format(lock)
785
+ };
786
+ return {
787
+ ...lock,
788
+ amount: this.#format(lock.amount)
789
+ };
790
+ });
578
791
  }
579
- /** @depreacted - use balance.locked */
792
+ /** @deprecated Use balance.locked */
580
793
  get frozen() {
581
794
  return this.locked;
582
795
  }
@@ -589,7 +802,7 @@ let Balance = (_dec4 = typescriptMemoize.Memoize(), _dec5 = typescriptMemoize.Me
589
802
  const excludeAmount = excludeFromTransferableAmount(this.#storage.locks);
590
803
 
591
804
  // subtract the lock from the free amount (but don't go below 0)
592
- return this.#format(util.BigMath.max(this.free.planck - excludeAmount, BigInt("0")));
805
+ return this.#format(util.BigMath.max(this.free.planck - excludeAmount, 0n));
593
806
  }
594
807
  /** The feePayable balance of this token. Is generally the free amount - the feeFrozen amount. */
595
808
  get feePayable() {
@@ -597,13 +810,13 @@ let Balance = (_dec4 = typescriptMemoize.Memoize(), _dec5 = typescriptMemoize.Me
597
810
  if (!this.#storage.locks) return this.free;
598
811
 
599
812
  // find the largest lock which can't be used to pay tx fees
600
- const excludeAmount = excludeFromFeePayableLocks(this.#storage.locks).map(lock => BigInt(lock.amount)).reduce((max, lock) => util.BigMath.max(max, lock), BigInt("0"));
813
+ const excludeAmount = excludeFromFeePayableLocks(this.#storage.locks).map(lock => BigInt(lock.amount)).reduce((max, lock) => util.BigMath.max(max, lock), 0n);
601
814
 
602
815
  // subtract the lock from the free amount (but don't go below 0)
603
- return this.#format(util.BigMath.max(this.free.planck - excludeAmount, BigInt("0")));
816
+ return this.#format(util.BigMath.max(this.free.planck - excludeAmount, 0n));
604
817
  }
605
- }, (_applyDecoratedDescriptor(_class2.prototype, "total", [_dec4], Object.getOwnPropertyDescriptor(_class2.prototype, "total"), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, "free", [_dec5], Object.getOwnPropertyDescriptor(_class2.prototype, "free"), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, "reserved", [_dec6], Object.getOwnPropertyDescriptor(_class2.prototype, "reserved"), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, "locked", [_dec7], Object.getOwnPropertyDescriptor(_class2.prototype, "locked"), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, "frozen", [_dec8], Object.getOwnPropertyDescriptor(_class2.prototype, "frozen"), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, "transferable", [_dec9], Object.getOwnPropertyDescriptor(_class2.prototype, "transferable"), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, "feePayable", [_dec10], Object.getOwnPropertyDescriptor(_class2.prototype, "feePayable"), _class2.prototype)), _class2));
606
- let BalanceFormatter = (_dec11 = typescriptMemoize.Memoize(), (_class3 = class BalanceFormatter {
818
+ }
819
+ class BalanceFormatter {
607
820
  #planck;
608
821
  #decimals;
609
822
  #fiatRatios;
@@ -611,7 +824,6 @@ let BalanceFormatter = (_dec11 = typescriptMemoize.Memoize(), (_class3 = class B
611
824
  this.#planck = typeof planck === "bigint" ? planck.toString() : planck ?? "0";
612
825
  this.#decimals = decimals || 0;
613
826
  this.#fiatRatios = fiatRatios || null;
614
- this.fiat = memoize__default["default"](this.fiat);
615
827
  }
616
828
  toJSON = () => this.#planck;
617
829
  get planck() {
@@ -626,26 +838,66 @@ let BalanceFormatter = (_dec11 = typescriptMemoize.Memoize(), (_class3 = class B
626
838
  if (!ratio) return null;
627
839
  return parseFloat(this.tokens) * ratio;
628
840
  }
629
- }, (_applyDecoratedDescriptor(_class3.prototype, "tokens", [_dec11], Object.getOwnPropertyDescriptor(_class3.prototype, "tokens"), _class3.prototype)), _class3));
630
- let FiatSumBalancesFormatter = (_dec12 = typescriptMemoize.Memoize(), _dec13 = typescriptMemoize.Memoize(), _dec14 = typescriptMemoize.Memoize(), _dec15 = typescriptMemoize.Memoize(), _dec16 = typescriptMemoize.Memoize(), _dec17 = typescriptMemoize.Memoize(), _dec18 = typescriptMemoize.Memoize(), (_class4 = class FiatSumBalancesFormatter {
841
+ }
842
+ class PlanckSumBalancesFormatter {
843
+ #balances;
844
+ constructor(balances) {
845
+ this.#balances = balances;
846
+ }
847
+ #sum = balanceField => {
848
+ // a function to get a planck amount from a balance
849
+ const planck = balance => balance[balanceField].planck ?? 0n;
850
+ return this.#balances.filterMirrorTokens().each.reduce(
851
+ // add the total amount to the planck amount of each balance
852
+ (total, balance) => total + planck(balance),
853
+ // start with a total of 0
854
+ 0n);
855
+ };
856
+
857
+ /**
858
+ * The total balance of these tokens. Includes the free and the reserved amount.
859
+ */
860
+ get total() {
861
+ return this.#sum("total");
862
+ }
863
+ /** The non-reserved balance of these tokens. Includes the frozen amount. Is included in the total. */
864
+ get free() {
865
+ return this.#sum("free");
866
+ }
867
+ /** The reserved balance of these tokens. Is included in the total. */
868
+ get reserved() {
869
+ return this.#sum("reserved");
870
+ }
871
+ /** The frozen balance of these tokens. Is included in the free amount. */
872
+ get locked() {
873
+ return this.#sum("locked");
874
+ }
875
+ /** @deprecated Use balances.locked */
876
+ get frozen() {
877
+ return this.locked;
878
+ }
879
+ /** The transferable balance of these tokens. Is generally the free amount - the miscFrozen amount. */
880
+ get transferable() {
881
+ return this.#sum("transferable");
882
+ }
883
+ /** The feePayable balance of these tokens. Is generally the free amount - the feeFrozen amount. */
884
+ get feePayable() {
885
+ return this.#sum("feePayable");
886
+ }
887
+ }
888
+ class FiatSumBalancesFormatter {
631
889
  #balances;
632
890
  #currency;
633
891
  constructor(balances, currency) {
634
892
  this.#balances = balances;
635
893
  this.#currency = currency;
636
- this.#sum = memoize__default["default"](this.#sum);
637
894
  }
638
895
  #sum = balanceField => {
639
896
  // a function to get a fiat amount from a balance
640
- const fiat = balance => balance[balanceField].fiat(this.#currency) || 0;
641
-
642
- // a function to add two amounts
643
- const sum = (a, b) => a + b;
644
- return [...this.#balances].filter(filterMirrorTokens).reduce((total, balance) => sum(
645
- // add the total amount...
646
- total,
647
- // ...to the fiat amount of each balance
648
- fiat(balance)),
897
+ const fiat = balance => balance[balanceField].fiat(this.#currency) ?? 0;
898
+ return this.#balances.filterMirrorTokens().each.reduce(
899
+ // add the total amount to the fiat amount of each balance
900
+ (total, balance) => total + fiat(balance),
649
901
  // start with a total of 0
650
902
  0);
651
903
  };
@@ -668,7 +920,7 @@ let FiatSumBalancesFormatter = (_dec12 = typescriptMemoize.Memoize(), _dec13 = t
668
920
  get locked() {
669
921
  return this.#sum("locked");
670
922
  }
671
- /** @deprecated - use balances.locked */
923
+ /** @deprecated Use balances.locked */
672
924
  get frozen() {
673
925
  return this.locked;
674
926
  }
@@ -680,12 +932,14 @@ let FiatSumBalancesFormatter = (_dec12 = typescriptMemoize.Memoize(), _dec13 = t
680
932
  get feePayable() {
681
933
  return this.#sum("feePayable");
682
934
  }
683
- }, (_applyDecoratedDescriptor(_class4.prototype, "total", [_dec12], Object.getOwnPropertyDescriptor(_class4.prototype, "total"), _class4.prototype), _applyDecoratedDescriptor(_class4.prototype, "free", [_dec13], Object.getOwnPropertyDescriptor(_class4.prototype, "free"), _class4.prototype), _applyDecoratedDescriptor(_class4.prototype, "reserved", [_dec14], Object.getOwnPropertyDescriptor(_class4.prototype, "reserved"), _class4.prototype), _applyDecoratedDescriptor(_class4.prototype, "locked", [_dec15], Object.getOwnPropertyDescriptor(_class4.prototype, "locked"), _class4.prototype), _applyDecoratedDescriptor(_class4.prototype, "frozen", [_dec16], Object.getOwnPropertyDescriptor(_class4.prototype, "frozen"), _class4.prototype), _applyDecoratedDescriptor(_class4.prototype, "transferable", [_dec17], Object.getOwnPropertyDescriptor(_class4.prototype, "transferable"), _class4.prototype), _applyDecoratedDescriptor(_class4.prototype, "feePayable", [_dec18], Object.getOwnPropertyDescriptor(_class4.prototype, "feePayable"), _class4.prototype)), _class4));
935
+ }
684
936
  class SumBalancesFormatter {
685
937
  #balances;
686
938
  constructor(balances) {
687
939
  this.#balances = balances;
688
- this.fiat = memoize__default["default"](this.fiat);
940
+ }
941
+ get planck() {
942
+ return new PlanckSumBalancesFormatter(this.#balances);
689
943
  }
690
944
  fiat(currency) {
691
945
  return new FiatSumBalancesFormatter(this.#balances, currency);
@@ -694,15 +948,24 @@ class SumBalancesFormatter {
694
948
 
695
949
  exports.Balance = Balance;
696
950
  exports.BalanceFormatter = BalanceFormatter;
951
+ exports.BalanceStatusLive = BalanceStatusLive;
697
952
  exports.Balances = Balances;
698
953
  exports.DefaultBalanceModule = DefaultBalanceModule;
699
954
  exports.FiatSumBalancesFormatter = FiatSumBalancesFormatter;
955
+ exports.PlanckSumBalancesFormatter = PlanckSumBalancesFormatter;
956
+ exports.RpcStateQueryHelper = RpcStateQueryHelper;
700
957
  exports.StorageHelper = StorageHelper;
701
958
  exports.SumBalancesFormatter = SumBalancesFormatter;
702
959
  exports.TalismanBalancesDatabase = TalismanBalancesDatabase;
703
960
  exports.balances = balances;
961
+ exports.createSubscriptionId = createSubscriptionId;
962
+ exports.createTypeRegistryCache = createTypeRegistryCache;
704
963
  exports.db = db;
964
+ exports.deleteSubscriptionId = deleteSubscriptionId;
965
+ exports.deriveStatuses = deriveStatuses;
705
966
  exports.excludeFromFeePayableLocks = excludeFromFeePayableLocks;
706
967
  exports.excludeFromTransferableAmount = excludeFromTransferableAmount;
707
968
  exports.filterMirrorTokens = filterMirrorTokens;
969
+ exports.findChainMeta = findChainMeta;
970
+ exports.getValidSubscriptionIds = getValidSubscriptionIds;
708
971
  exports.includeInTotalExtraAmount = includeInTotalExtraAmount;