@talismn/balances 0.0.0-pr710-20230418132646 → 0.0.0-pr716-20230419110638

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/CHANGELOG.md CHANGED
@@ -1,16 +1,23 @@
1
1
  # @talismn/balances
2
2
 
3
- ## 0.0.0-pr710-20230418132646
3
+ ## 0.0.0-pr716-20230419110638
4
4
 
5
5
  ### Patch Changes
6
6
 
7
7
  - fb8ee962: feat: proxy dapp websocket requests to talisman wallet backend when available
8
+ - f7aca48b: eslint rules
9
+ - 01bf239b: feat: crowdloan and nom pool balances
10
+ - 01bf239b: fix: packages publishing with incorrect interdependency versions
8
11
  - Updated dependencies [fb8ee962]
9
12
  - Updated dependencies [c898da98]
10
- - @talismn/chain-connector@0.0.0-pr710-20230418132646
11
- - @talismn/chain-connector-evm@0.0.0-pr710-20230418132646
12
- - @talismn/chaindata-provider@0.0.0-pr710-20230418132646
13
- - @talismn/token-rates@0.0.0-pr710-20230418132646
13
+ - Updated dependencies [f7aca48b]
14
+ - Updated dependencies [01bf239b]
15
+ - Updated dependencies [01bf239b]
16
+ - @talismn/chain-connector@0.0.0-pr716-20230419110638
17
+ - @talismn/chain-connector-evm@0.0.0-pr716-20230419110638
18
+ - @talismn/chaindata-provider@0.0.0-pr716-20230419110638
19
+ - @talismn/token-rates@0.0.0-pr716-20230419110638
20
+ - @talismn/util@0.0.0-pr716-20230419110638
14
21
 
15
22
  ## 0.4.0
16
23
 
@@ -1,4 +1,5 @@
1
1
  import type { Registry } from "@polkadot/types-codec/types";
2
+ import { ChainConnector } from "@talismn/chain-connector";
2
3
  import { ChainId } from "@talismn/chaindata-provider";
3
4
  import { BalanceModule, DefaultChainMeta, DefaultModuleConfig, DefaultTransferParams, ExtendableChainMeta, ExtendableModuleConfig, ExtendableTokenType, ExtendableTransferParams } from "./BalanceModule";
4
5
  import { AddressesByToken, Balance, BalanceJson, Balances, SubscriptionCallback, UnsubscribeFn } from "./types";
@@ -8,8 +9,9 @@ import { AddressesByToken, Balance, BalanceJson, Balances, SubscriptionCallback,
8
9
  */
9
10
  export declare function balances<TModuleType extends string, TTokenType extends ExtendableTokenType, TChainMeta extends ExtendableChainMeta = DefaultChainMeta, TModuleConfig extends ExtendableModuleConfig = DefaultModuleConfig, TTransferParams extends ExtendableTransferParams = DefaultTransferParams>(balanceModule: BalanceModule<TModuleType, TTokenType, TChainMeta, TModuleConfig, TTransferParams>, addressesByToken: AddressesByToken<TTokenType>): Promise<Balances>;
10
11
  export declare function balances<TModuleType extends string, TTokenType extends ExtendableTokenType, TChainMeta extends ExtendableChainMeta = DefaultChainMeta, TModuleConfig extends ExtendableModuleConfig = DefaultModuleConfig, TTransferParams extends ExtendableTransferParams = DefaultTransferParams>(balanceModule: BalanceModule<TModuleType, TTokenType, TChainMeta, TModuleConfig, TTransferParams>, addressesByToken: AddressesByToken<TTokenType>, callback: SubscriptionCallback<Balances>): Promise<UnsubscribeFn>;
12
+ export type GetOrCreateTypeRegistry = (chainId: ChainId, metadataRpc?: `0x${string}`) => Registry;
11
13
  export declare const createTypeRegistryCache: () => {
12
- getOrCreateTypeRegistry: (chainId: ChainId, metadataRpc?: `0x${string}`) => Registry;
14
+ getOrCreateTypeRegistry: GetOrCreateTypeRegistry;
13
15
  };
14
16
  export declare const filterMirrorTokens: (balance: Balance, i: number, balances: Balance[]) => boolean;
15
17
  export declare const getValidSubscriptionIds: () => Set<string>;
@@ -33,3 +35,20 @@ export declare class StorageHelper {
33
35
  tag(tags: any): this;
34
36
  decode(input?: string | null): import("@polkadot/types-codec/types").Codec | undefined;
35
37
  }
38
+ /**
39
+ * Pass some these into an `RpcStateQueryHelper` in order to easily batch multiple state queries into the one rpc call.
40
+ */
41
+ export type RpcStateQuery<T> = {
42
+ chainId: string;
43
+ stateKey: string;
44
+ decodeResult: (change: string | null) => T;
45
+ };
46
+ /**
47
+ * Used by a variety of balance modules to help batch multiple state queries into the one rpc call.
48
+ */
49
+ export declare class RpcStateQueryHelper<T> {
50
+ #private;
51
+ constructor(chainConnector: ChainConnector, queries: Array<RpcStateQuery<T>>);
52
+ subscribe(callback: SubscriptionCallback<T[]>, timeout?: number | false, subscribeMethod?: string, responseMethod?: string, unsubscribeMethod?: string): Promise<UnsubscribeFn>;
53
+ fetch(method?: string): Promise<T[]>;
54
+ }
@@ -61,6 +61,19 @@ export declare class Balances {
61
61
  * @returns All balances which match the query.
62
62
  */
63
63
  find: (query: BalanceSearchQuery | BalanceSearchQuery[]) => Balances;
64
+ /**
65
+ * Filters this collection to exclude token balances where the token has a `mirrorOf` field
66
+ * and another balance exists in this collection for the token specified by the `mirrorOf` field.
67
+ */
68
+ filterMirrorTokens: () => Balances;
69
+ /**
70
+ * Filters this collection to only include balances which are not zero.
71
+ */
72
+ filterNonZero: (type: "total" | "free" | "reserved" | "locked" | "frozen" | "transferable" | "feePayable") => Balances;
73
+ /**
74
+ * Filters this collection to only include balances which are not zero AND have a fiat conversion rate.
75
+ */
76
+ filterNonZeroFiat: (type: "total" | "free" | "reserved" | "locked" | "frozen" | "transferable" | "feePayable", currency: TokenRateCurrency) => Balances;
64
77
  /**
65
78
  * Add some balances to this collection.
66
79
  * Added balances take priority over existing balances.
@@ -134,9 +147,21 @@ export declare class Balance {
134
147
  get free(): BalanceFormatter;
135
148
  /** The reserved balance of this token. Is included in the total. */
136
149
  get reserved(): BalanceFormatter;
150
+ get reserves(): {
151
+ amount: BalanceFormatter;
152
+ label: string;
153
+ meta?: unknown;
154
+ }[];
137
155
  /** The frozen balance of this token. Is included in the free amount. */
138
156
  get locked(): BalanceFormatter;
139
- /** @depreacted - use balance.locked */
157
+ get locks(): {
158
+ amount: BalanceFormatter;
159
+ label: string;
160
+ meta?: unknown;
161
+ includeInTransferable?: boolean | undefined;
162
+ excludeFromFeePayable?: boolean | undefined;
163
+ }[];
164
+ /** @deprecated Use balance.locked */
140
165
  get frozen(): BalanceFormatter;
141
166
  /** The transferable balance of this token. Is generally the free amount - the miscFrozen amount. */
142
167
  get transferable(): BalanceFormatter;
@@ -151,6 +176,26 @@ export declare class BalanceFormatter {
151
176
  get tokens(): string;
152
177
  fiat(currency: TokenRateCurrency): number | null;
153
178
  }
179
+ export declare class PlanckSumBalancesFormatter {
180
+ #private;
181
+ constructor(balances: Balances);
182
+ /**
183
+ * The total balance of these tokens. Includes the free and the reserved amount.
184
+ */
185
+ get total(): bigint;
186
+ /** The non-reserved balance of these tokens. Includes the frozen amount. Is included in the total. */
187
+ get free(): bigint;
188
+ /** The reserved balance of these tokens. Is included in the total. */
189
+ get reserved(): bigint;
190
+ /** The frozen balance of these tokens. Is included in the free amount. */
191
+ get locked(): bigint;
192
+ /** @deprecated Use balances.locked */
193
+ get frozen(): bigint;
194
+ /** The transferable balance of these tokens. Is generally the free amount - the miscFrozen amount. */
195
+ get transferable(): bigint;
196
+ /** The feePayable balance of these tokens. Is generally the free amount - the feeFrozen amount. */
197
+ get feePayable(): bigint;
198
+ }
154
199
  export declare class FiatSumBalancesFormatter {
155
200
  #private;
156
201
  constructor(balances: Balances, currency: TokenRateCurrency);
@@ -164,7 +209,7 @@ export declare class FiatSumBalancesFormatter {
164
209
  get reserved(): number;
165
210
  /** The frozen balance of these tokens. Is included in the free amount. */
166
211
  get locked(): number;
167
- /** @deprecated - use balances.locked */
212
+ /** @deprecated Use balances.locked */
168
213
  get frozen(): number;
169
214
  /** The transferable balance of these tokens. Is generally the free amount - the miscFrozen amount. */
170
215
  get transferable(): number;
@@ -174,5 +219,6 @@ export declare class FiatSumBalancesFormatter {
174
219
  export declare class SumBalancesFormatter {
175
220
  #private;
176
221
  constructor(balances: Balances);
222
+ get planck(): PlanckSumBalancesFormatter;
177
223
  fiat(currency: TokenRateCurrency): FiatSumBalancesFormatter;
178
224
  }
@@ -30,6 +30,11 @@ export type BalanceStatus = BalanceStatusLive | "live" | "cache" | "stale";
30
30
  export type IBalance = {
31
31
  /** The module that this balance was retrieved by */
32
32
  source: string;
33
+ /**
34
+ * For modules which fetch balances via module sources, this is the sub-source
35
+ * e.g. `staking` or `crowdloans`
36
+ **/
37
+ subSource?: string;
33
38
  /** Has this balance never been fetched, or is it from a cache, or is it up to date? */
34
39
  status: BalanceStatus;
35
40
  /** The address of the account which owns this balance */
@@ -59,6 +64,7 @@ export type Amount = string;
59
64
  export type AmountWithLabel<TLabel extends string> = {
60
65
  label: TLabel;
61
66
  amount: Amount;
67
+ meta?: unknown;
62
68
  };
63
69
  /** A labelled locked amount of a balance */
64
70
  export type LockedAmount<TLabel extends string> = AmountWithLabel<TLabel> & {
@@ -4,11 +4,13 @@ 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');
8
+ var groupBy = require('lodash/groupBy');
9
+ var anylogger = require('anylogger');
9
10
 
10
11
  function _interopDefault (e) { return e && e.__esModule ? e : { 'default': e }; }
11
12
 
13
+ var groupBy__default = /*#__PURE__*/_interopDefault(groupBy);
12
14
  var anylogger__default = /*#__PURE__*/_interopDefault(anylogger);
13
15
 
14
16
  // TODO: Document default balances module purpose/usage
@@ -67,7 +69,7 @@ const db = new TalismanBalancesDatabase();
67
69
 
68
70
  var packageJson = {
69
71
  name: "@talismn/balances",
70
- version: "0.0.0-pr710-20230418132646",
72
+ version: "0.0.0-pr716-20230419110638",
71
73
  author: "Talisman",
72
74
  homepage: "https://talisman.xyz",
73
75
  license: "UNLICENSED",
@@ -90,30 +92,32 @@ var packageJson = {
90
92
  },
91
93
  scripts: {
92
94
  test: "jest",
93
- lint: "eslint . --max-warnings 0",
95
+ lint: "eslint src --max-warnings 0",
94
96
  clean: "rm -rf dist && rm -rf .turbo rm -rf node_modules"
95
97
  },
96
98
  dependencies: {
97
- "@talismn/chain-connector": "workspace:^",
98
- "@talismn/chain-connector-evm": "workspace:^",
99
- "@talismn/chaindata-provider": "workspace:^",
100
- "@talismn/token-rates": "workspace:^",
101
- "@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:*",
102
104
  anylogger: "^1.0.11",
103
- dexie: "^3.2.3"
105
+ dexie: "^3.2.3",
106
+ lodash: "4.17.21"
104
107
  },
105
108
  devDependencies: {
106
- "@polkadot/types": "^9.10.5",
107
- "@talismn/eslint-config": "workspace:^",
108
- "@talismn/tsconfig": "workspace:^",
109
+ "@polkadot/types": "^10.1.4",
110
+ "@talismn/eslint-config": "workspace:*",
111
+ "@talismn/tsconfig": "workspace:*",
109
112
  "@types/jest": "^27.5.1",
113
+ "@types/lodash": "^4.14.180",
110
114
  eslint: "^8.4.0",
111
115
  jest: "^28.1.0",
112
116
  "ts-jest": "^28.0.2",
113
117
  typescript: "^4.6.4"
114
118
  },
115
119
  peerDependencies: {
116
- "@polkadot/types": "9.x"
120
+ "@polkadot/types": "10.x"
117
121
  },
118
122
  preconstruct: {
119
123
  entrypoints: [
@@ -146,8 +150,14 @@ const createTypeRegistryCache = () => {
146
150
  if (cached) return cached;
147
151
  const typeRegistry = new types.TypeRegistry();
148
152
  if (typeof metadataRpc === "string") {
149
- const metadata = new types.Metadata(typeRegistry, metadataRpc);
150
- metadata.registry.setMetadata(metadata);
153
+ try {
154
+ const metadata = new types.Metadata(typeRegistry, metadataRpc);
155
+ metadata.registry.setMetadata(metadata);
156
+ } catch (cause) {
157
+ log.warn(new Error(`Failed to set metadata for chain ${chainId}`, {
158
+ cause
159
+ }), cause);
160
+ }
151
161
  }
152
162
  typeRegistryCache.set(chainId, typeRegistry);
153
163
  return typeRegistry;
@@ -214,7 +224,11 @@ class StorageHelper {
214
224
  #module;
215
225
  #method;
216
226
  #parameters;
227
+
228
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
217
229
  tags = null;
230
+
231
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
218
232
  constructor(registry, module, method, ...parameters) {
219
233
  this.#registry = registry;
220
234
  this.#module = module;
@@ -248,6 +262,8 @@ class StorageHelper {
248
262
  get parameters() {
249
263
  return this.#parameters;
250
264
  }
265
+
266
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
251
267
  tag(tags) {
252
268
  this.tags = tags;
253
269
  return this;
@@ -286,11 +302,77 @@ class StorageHelper {
286
302
  }
287
303
  }
288
304
 
305
+ /**
306
+ * Pass some these into an `RpcStateQueryHelper` in order to easily batch multiple state queries into the one rpc call.
307
+ */
308
+
309
+ /**
310
+ * Used by a variety of balance modules to help batch multiple state queries into the one rpc call.
311
+ */
312
+ class RpcStateQueryHelper {
313
+ #chainConnector;
314
+ #queries;
315
+ constructor(chainConnector, queries) {
316
+ this.#chainConnector = chainConnector;
317
+ this.#queries = queries;
318
+ }
319
+ async subscribe(callback, timeout = false, subscribeMethod = "state_subscribeStorage", responseMethod = "state_storage", unsubscribeMethod = "state_unsubscribeStorage") {
320
+ const queriesByChain = groupBy__default["default"](this.#queries, "chainId");
321
+ const subscriptions = Object.entries(queriesByChain).map(([chainId, queries]) => {
322
+ const params = [queries.map(({
323
+ stateKey
324
+ }) => stateKey)];
325
+ const unsub = this.#chainConnector.subscribe(chainId, subscribeMethod, responseMethod, params, (error, result) => {
326
+ error ? callback(error) : callback(null, this.#distributeChangesToQueryDecoders.call(this, chainId, result));
327
+ }, timeout);
328
+ return () => unsub.then(unsubscribe => unsubscribe(unsubscribeMethod));
329
+ });
330
+ return () => subscriptions.forEach(unsubscribe => unsubscribe());
331
+ }
332
+ async fetch(method = "state_queryStorageAt") {
333
+ const queriesByChain = groupBy__default["default"](this.#queries, "chainId");
334
+ const resultsByChain = await Promise.all(Object.entries(queriesByChain).map(async ([chainId, queries]) => {
335
+ const params = [queries.map(({
336
+ stateKey
337
+ }) => stateKey)];
338
+ const result = (await this.#chainConnector.send(chainId, method, params))[0];
339
+ return this.#distributeChangesToQueryDecoders.call(this, chainId, result);
340
+ }));
341
+ return resultsByChain.flatMap(result => result);
342
+ }
343
+ #distributeChangesToQueryDecoders(chainId, result) {
344
+ if (typeof result !== "object" || result === null) return [];
345
+ if (!util.hasOwnProperty(result, "changes") || typeof result.changes !== "object") return [];
346
+ if (!Array.isArray(result.changes)) return [];
347
+ return result.changes.flatMap(([reference, change]) => {
348
+ if (typeof reference !== "string") {
349
+ log.warn(`Received non-string reference in RPC result: ${reference}`);
350
+ return [];
351
+ }
352
+ if (typeof change !== "string" && change !== null) {
353
+ log.warn(`Received non-string and non-null change in RPC result: ${reference} | ${change}`);
354
+ return [];
355
+ }
356
+ const query = this.#queries.find(({
357
+ chainId: cId,
358
+ stateKey
359
+ }) => cId === chainId && stateKey === reference);
360
+ if (!query) {
361
+ log.warn(`Failed to find query:\n${reference} in\n${this.#queries.map(({
362
+ stateKey
363
+ }) => stateKey)}`);
364
+ return [];
365
+ }
366
+ return [query.decodeResult(change)];
367
+ });
368
+ }
369
+ }
370
+
289
371
  const BalanceStatusLive = subscriptionId => `live-${subscriptionId}`;
290
372
  function excludeFromTransferableAmount(locks) {
291
373
  if (typeof locks === "string") return BigInt(locks);
292
374
  if (!Array.isArray(locks)) locks = [locks];
293
- return locks.filter(lock => lock.includeInTransferable !== true).map(lock => BigInt(lock.amount)).reduce((max, lock) => util.BigMath.max(max, lock), BigInt("0"));
375
+ return locks.filter(lock => lock.includeInTransferable !== true).map(lock => BigInt(lock.amount)).reduce((max, lock) => util.BigMath.max(max, lock), 0n);
294
376
  }
295
377
  function excludeFromFeePayableLocks(locks) {
296
378
  if (typeof locks === "string") return [];
@@ -301,9 +383,9 @@ function excludeFromFeePayableLocks(locks) {
301
383
  /** A labelled extra amount of a balance */
302
384
 
303
385
  function includeInTotalExtraAmount(extra) {
304
- if (!extra) return BigInt("0");
386
+ if (!extra) return 0n;
305
387
  if (!Array.isArray(extra)) extra = [extra];
306
- return extra.filter(extra => extra.includeInTotal).map(extra => BigInt(extra.amount)).reduce((a, b) => a + b, BigInt("0"));
388
+ return extra.filter(extra => extra.includeInTotal).map(extra => BigInt(extra.amount)).reduce((a, b) => a + b, 0n);
307
389
  }
308
390
 
309
391
  /** Used by plugins to help define their custom `BalanceType` */
@@ -414,6 +496,27 @@ class Balances {
414
496
  return new Balances([...this].filter(filter));
415
497
  };
416
498
 
499
+ /**
500
+ * Filters this collection to exclude token balances where the token has a `mirrorOf` field
501
+ * and another balance exists in this collection for the token specified by the `mirrorOf` field.
502
+ */
503
+ filterMirrorTokens = () => new Balances([...this].filter(filterMirrorTokens));
504
+
505
+ /**
506
+ * Filters this collection to only include balances which are not zero.
507
+ */
508
+ filterNonZero = type => {
509
+ const filter = balance => balance[type].planck > 0n;
510
+ return this.find(filter);
511
+ };
512
+ /**
513
+ * Filters this collection to only include balances which are not zero AND have a fiat conversion rate.
514
+ */
515
+ filterNonZeroFiat = (type, currency) => {
516
+ const filter = balance => (balance[type].fiat(currency) ?? 0) > 0;
517
+ return this.find(filter);
518
+ };
519
+
417
520
  /**
418
521
  * Add some balances to this collection.
419
522
  * Added balances take priority over existing balances.
@@ -536,13 +639,14 @@ class Balance {
536
639
  get id() {
537
640
  const {
538
641
  source,
642
+ subSource,
539
643
  address,
540
644
  chainId,
541
645
  evmNetworkId,
542
646
  tokenId
543
647
  } = this.#storage;
544
648
  const locationId = chainId !== undefined ? chainId : evmNetworkId;
545
- return `${source}-${address}-${locationId}-${tokenId}`;
649
+ return [source, address, locationId, tokenId, subSource].filter(Boolean).join("-");
546
650
  }
547
651
  get source() {
548
652
  return this.#storage.source;
@@ -591,17 +695,43 @@ class Balance {
591
695
  }
592
696
  /** The non-reserved balance of this token. Includes the frozen amount. Is included in the total. */
593
697
  get free() {
594
- 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"));
698
+ 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"));
595
699
  }
596
700
  /** The reserved balance of this token. Is included in the total. */
597
701
  get reserved() {
598
- 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"));
702
+ 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"));
703
+ }
704
+ get reserves() {
705
+ return (Array.isArray(this.#storage.reserves) ? this.#storage.reserves : [this.#storage.reserves]).flatMap(reserve => {
706
+ if (reserve === undefined) return [];
707
+ if (typeof reserve === "string") return {
708
+ label: "reserved",
709
+ amount: this.#format(reserve)
710
+ };
711
+ return {
712
+ ...reserve,
713
+ amount: this.#format(reserve.amount)
714
+ };
715
+ });
599
716
  }
600
717
  /** The frozen balance of this token. Is included in the free amount. */
601
718
  get locked() {
602
- 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"));
719
+ 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"));
720
+ }
721
+ get locks() {
722
+ return (Array.isArray(this.#storage.locks) ? this.#storage.locks : [this.#storage.locks]).flatMap(lock => {
723
+ if (lock === undefined) return [];
724
+ if (typeof lock === "string") return {
725
+ label: "other",
726
+ amount: this.#format(lock)
727
+ };
728
+ return {
729
+ ...lock,
730
+ amount: this.#format(lock.amount)
731
+ };
732
+ });
603
733
  }
604
- /** @depreacted - use balance.locked */
734
+ /** @deprecated Use balance.locked */
605
735
  get frozen() {
606
736
  return this.locked;
607
737
  }
@@ -614,7 +744,7 @@ class Balance {
614
744
  const excludeAmount = excludeFromTransferableAmount(this.#storage.locks);
615
745
 
616
746
  // subtract the lock from the free amount (but don't go below 0)
617
- return this.#format(util.BigMath.max(this.free.planck - excludeAmount, BigInt("0")));
747
+ return this.#format(util.BigMath.max(this.free.planck - excludeAmount, 0n));
618
748
  }
619
749
  /** The feePayable balance of this token. Is generally the free amount - the feeFrozen amount. */
620
750
  get feePayable() {
@@ -622,10 +752,10 @@ class Balance {
622
752
  if (!this.#storage.locks) return this.free;
623
753
 
624
754
  // find the largest lock which can't be used to pay tx fees
625
- const excludeAmount = excludeFromFeePayableLocks(this.#storage.locks).map(lock => BigInt(lock.amount)).reduce((max, lock) => util.BigMath.max(max, lock), BigInt("0"));
755
+ const excludeAmount = excludeFromFeePayableLocks(this.#storage.locks).map(lock => BigInt(lock.amount)).reduce((max, lock) => util.BigMath.max(max, lock), 0n);
626
756
 
627
757
  // subtract the lock from the free amount (but don't go below 0)
628
- return this.#format(util.BigMath.max(this.free.planck - excludeAmount, BigInt("0")));
758
+ return this.#format(util.BigMath.max(this.free.planck - excludeAmount, 0n));
629
759
  }
630
760
  }
631
761
  class BalanceFormatter {
@@ -651,6 +781,52 @@ class BalanceFormatter {
651
781
  return parseFloat(this.tokens) * ratio;
652
782
  }
653
783
  }
784
+ class PlanckSumBalancesFormatter {
785
+ #balances;
786
+ constructor(balances) {
787
+ this.#balances = balances;
788
+ }
789
+ #sum = balanceField => {
790
+ // a function to get a planck amount from a balance
791
+ const planck = balance => balance[balanceField].planck ?? 0n;
792
+ return this.#balances.filterMirrorTokens().each.reduce(
793
+ // add the total amount to the planck amount of each balance
794
+ (total, balance) => total + planck(balance),
795
+ // start with a total of 0
796
+ 0n);
797
+ };
798
+
799
+ /**
800
+ * The total balance of these tokens. Includes the free and the reserved amount.
801
+ */
802
+ get total() {
803
+ return this.#sum("total");
804
+ }
805
+ /** The non-reserved balance of these tokens. Includes the frozen amount. Is included in the total. */
806
+ get free() {
807
+ return this.#sum("free");
808
+ }
809
+ /** The reserved balance of these tokens. Is included in the total. */
810
+ get reserved() {
811
+ return this.#sum("reserved");
812
+ }
813
+ /** The frozen balance of these tokens. Is included in the free amount. */
814
+ get locked() {
815
+ return this.#sum("locked");
816
+ }
817
+ /** @deprecated Use balances.locked */
818
+ get frozen() {
819
+ return this.locked;
820
+ }
821
+ /** The transferable balance of these tokens. Is generally the free amount - the miscFrozen amount. */
822
+ get transferable() {
823
+ return this.#sum("transferable");
824
+ }
825
+ /** The feePayable balance of these tokens. Is generally the free amount - the feeFrozen amount. */
826
+ get feePayable() {
827
+ return this.#sum("feePayable");
828
+ }
829
+ }
654
830
  class FiatSumBalancesFormatter {
655
831
  #balances;
656
832
  #currency;
@@ -660,15 +836,10 @@ class FiatSumBalancesFormatter {
660
836
  }
661
837
  #sum = balanceField => {
662
838
  // a function to get a fiat amount from a balance
663
- const fiat = balance => balance[balanceField].fiat(this.#currency) || 0;
664
-
665
- // a function to add two amounts
666
- const sum = (a, b) => a + b;
667
- return [...this.#balances].filter(filterMirrorTokens).reduce((total, balance) => sum(
668
- // add the total amount...
669
- total,
670
- // ...to the fiat amount of each balance
671
- fiat(balance)),
839
+ const fiat = balance => balance[balanceField].fiat(this.#currency) ?? 0;
840
+ return this.#balances.filterMirrorTokens().each.reduce(
841
+ // add the total amount to the fiat amount of each balance
842
+ (total, balance) => total + fiat(balance),
672
843
  // start with a total of 0
673
844
  0);
674
845
  };
@@ -691,7 +862,7 @@ class FiatSumBalancesFormatter {
691
862
  get locked() {
692
863
  return this.#sum("locked");
693
864
  }
694
- /** @deprecated - use balances.locked */
865
+ /** @deprecated Use balances.locked */
695
866
  get frozen() {
696
867
  return this.locked;
697
868
  }
@@ -709,6 +880,9 @@ class SumBalancesFormatter {
709
880
  constructor(balances) {
710
881
  this.#balances = balances;
711
882
  }
883
+ get planck() {
884
+ return new PlanckSumBalancesFormatter(this.#balances);
885
+ }
712
886
  fiat(currency) {
713
887
  return new FiatSumBalancesFormatter(this.#balances, currency);
714
888
  }
@@ -720,6 +894,8 @@ exports.BalanceStatusLive = BalanceStatusLive;
720
894
  exports.Balances = Balances;
721
895
  exports.DefaultBalanceModule = DefaultBalanceModule;
722
896
  exports.FiatSumBalancesFormatter = FiatSumBalancesFormatter;
897
+ exports.PlanckSumBalancesFormatter = PlanckSumBalancesFormatter;
898
+ exports.RpcStateQueryHelper = RpcStateQueryHelper;
723
899
  exports.StorageHelper = StorageHelper;
724
900
  exports.SumBalancesFormatter = SumBalancesFormatter;
725
901
  exports.TalismanBalancesDatabase = TalismanBalancesDatabase;