@talismn/balances 0.4.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +40 -0
- package/dist/declarations/src/helpers.d.ts +62 -4
- package/dist/declarations/src/types/balances.d.ts +48 -2
- package/dist/declarations/src/types/balancetypes.d.ts +9 -1
- package/dist/talismn-balances.cjs.dev.js +322 -38
- package/dist/talismn-balances.cjs.prod.js +322 -38
- package/dist/talismn-balances.esm.js +314 -39
- package/package.json +14 -12
@@ -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.
|
72
|
+
version: "0.5.0",
|
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
|
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": "^
|
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": "
|
120
|
+
"@polkadot/types": "10.x"
|
117
121
|
},
|
118
122
|
preconstruct: {
|
119
123
|
entrypoints: [
|
@@ -131,6 +135,11 @@ var packageJson = {
|
|
131
135
|
|
132
136
|
var log = anylogger__default["default"](packageJson.name);
|
133
137
|
|
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
|
+
|
134
143
|
async function balances(balanceModule, addressesByToken, callback) {
|
135
144
|
// subscription request
|
136
145
|
if (callback !== undefined) return await balanceModule.subscribeBalances(addressesByToken, callback);
|
@@ -146,8 +155,14 @@ const createTypeRegistryCache = () => {
|
|
146
155
|
if (cached) return cached;
|
147
156
|
const typeRegistry = new types.TypeRegistry();
|
148
157
|
if (typeof metadataRpc === "string") {
|
149
|
-
|
150
|
-
|
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
|
+
}
|
151
166
|
}
|
152
167
|
typeRegistryCache.set(chainId, typeRegistry);
|
153
168
|
return typeRegistry;
|
@@ -156,11 +171,78 @@ const createTypeRegistryCache = () => {
|
|
156
171
|
getOrCreateTypeRegistry
|
157
172
|
};
|
158
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
|
+
};
|
159
199
|
const filterMirrorTokens = (balance, i, balances) => {
|
160
|
-
// TODO: implement a mirrorOf property, which should be set from chaindata
|
161
200
|
const mirrorOf = balance.token?.mirrorOf;
|
162
201
|
return !mirrorOf || !balances.find(b => b.tokenId === mirrorOf);
|
163
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
|
+
});
|
164
246
|
|
165
247
|
/**
|
166
248
|
* Used by a variety of balance modules to help encode and decode substrate state calls.
|
@@ -171,7 +253,11 @@ class StorageHelper {
|
|
171
253
|
#module;
|
172
254
|
#method;
|
173
255
|
#parameters;
|
256
|
+
|
257
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
174
258
|
tags = null;
|
259
|
+
|
260
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
175
261
|
constructor(registry, module, method, ...parameters) {
|
176
262
|
this.#registry = registry;
|
177
263
|
this.#module = module;
|
@@ -205,6 +291,8 @@ class StorageHelper {
|
|
205
291
|
get parameters() {
|
206
292
|
return this.#parameters;
|
207
293
|
}
|
294
|
+
|
295
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
208
296
|
tag(tags) {
|
209
297
|
this.tags = tags;
|
210
298
|
return this;
|
@@ -243,10 +331,106 @@ class StorageHelper {
|
|
243
331
|
}
|
244
332
|
}
|
245
333
|
|
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
|
+
}
|
398
|
+
}
|
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
|
+
|
246
430
|
function excludeFromTransferableAmount(locks) {
|
247
431
|
if (typeof locks === "string") return BigInt(locks);
|
248
432
|
if (!Array.isArray(locks)) locks = [locks];
|
249
|
-
return locks.filter(lock => lock.includeInTransferable !== true).map(lock => BigInt(lock.amount)).reduce((max, lock) => util.BigMath.max(max, lock),
|
433
|
+
return locks.filter(lock => lock.includeInTransferable !== true).map(lock => BigInt(lock.amount)).reduce((max, lock) => util.BigMath.max(max, lock), 0n);
|
250
434
|
}
|
251
435
|
function excludeFromFeePayableLocks(locks) {
|
252
436
|
if (typeof locks === "string") return [];
|
@@ -257,9 +441,9 @@ function excludeFromFeePayableLocks(locks) {
|
|
257
441
|
/** A labelled extra amount of a balance */
|
258
442
|
|
259
443
|
function includeInTotalExtraAmount(extra) {
|
260
|
-
if (!extra) return
|
444
|
+
if (!extra) return 0n;
|
261
445
|
if (!Array.isArray(extra)) extra = [extra];
|
262
|
-
return extra.filter(extra => extra.includeInTotal).map(extra => BigInt(extra.amount)).reduce((a, b) => a + b,
|
446
|
+
return extra.filter(extra => extra.includeInTotal).map(extra => BigInt(extra.amount)).reduce((a, b) => a + b, 0n);
|
263
447
|
}
|
264
448
|
|
265
449
|
/** Used by plugins to help define their custom `BalanceType` */
|
@@ -270,7 +454,7 @@ function includeInTotalExtraAmount(extra) {
|
|
270
454
|
*/
|
271
455
|
|
272
456
|
/** A utility type used to extract the underlying `BalanceType` of a specific source from a generalised `BalanceJson` */
|
273
|
-
|
457
|
+
/** TODO: Remove this in favour of a frontend-friendly `ChaindataProvider` */
|
274
458
|
/**
|
275
459
|
* A collection of balances.
|
276
460
|
*/
|
@@ -370,6 +554,27 @@ class Balances {
|
|
370
554
|
return new Balances([...this].filter(filter));
|
371
555
|
};
|
372
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
|
+
|
373
578
|
/**
|
374
579
|
* Add some balances to this collection.
|
375
580
|
* Added balances take priority over existing balances.
|
@@ -492,13 +697,14 @@ class Balance {
|
|
492
697
|
get id() {
|
493
698
|
const {
|
494
699
|
source,
|
700
|
+
subSource,
|
495
701
|
address,
|
496
702
|
chainId,
|
497
703
|
evmNetworkId,
|
498
704
|
tokenId
|
499
705
|
} = this.#storage;
|
500
706
|
const locationId = chainId !== undefined ? chainId : evmNetworkId;
|
501
|
-
return
|
707
|
+
return [source, address, locationId, tokenId, subSource].filter(Boolean).join("-");
|
502
708
|
}
|
503
709
|
get source() {
|
504
710
|
return this.#storage.source;
|
@@ -547,17 +753,43 @@ class Balance {
|
|
547
753
|
}
|
548
754
|
/** The non-reserved balance of this token. Includes the frozen amount. Is included in the total. */
|
549
755
|
get free() {
|
550
|
-
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,
|
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"));
|
551
757
|
}
|
552
758
|
/** The reserved balance of this token. Is included in the total. */
|
553
759
|
get reserved() {
|
554
|
-
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,
|
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
|
+
});
|
555
774
|
}
|
556
775
|
/** The frozen balance of this token. Is included in the free amount. */
|
557
776
|
get locked() {
|
558
|
-
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),
|
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
|
+
});
|
559
791
|
}
|
560
|
-
/** @
|
792
|
+
/** @deprecated Use balance.locked */
|
561
793
|
get frozen() {
|
562
794
|
return this.locked;
|
563
795
|
}
|
@@ -570,7 +802,7 @@ class Balance {
|
|
570
802
|
const excludeAmount = excludeFromTransferableAmount(this.#storage.locks);
|
571
803
|
|
572
804
|
// subtract the lock from the free amount (but don't go below 0)
|
573
|
-
return this.#format(util.BigMath.max(this.free.planck - excludeAmount,
|
805
|
+
return this.#format(util.BigMath.max(this.free.planck - excludeAmount, 0n));
|
574
806
|
}
|
575
807
|
/** The feePayable balance of this token. Is generally the free amount - the feeFrozen amount. */
|
576
808
|
get feePayable() {
|
@@ -578,10 +810,10 @@ class Balance {
|
|
578
810
|
if (!this.#storage.locks) return this.free;
|
579
811
|
|
580
812
|
// find the largest lock which can't be used to pay tx fees
|
581
|
-
const excludeAmount = excludeFromFeePayableLocks(this.#storage.locks).map(lock => BigInt(lock.amount)).reduce((max, lock) => util.BigMath.max(max, lock),
|
813
|
+
const excludeAmount = excludeFromFeePayableLocks(this.#storage.locks).map(lock => BigInt(lock.amount)).reduce((max, lock) => util.BigMath.max(max, lock), 0n);
|
582
814
|
|
583
815
|
// subtract the lock from the free amount (but don't go below 0)
|
584
|
-
return this.#format(util.BigMath.max(this.free.planck - excludeAmount,
|
816
|
+
return this.#format(util.BigMath.max(this.free.planck - excludeAmount, 0n));
|
585
817
|
}
|
586
818
|
}
|
587
819
|
class BalanceFormatter {
|
@@ -607,6 +839,52 @@ class BalanceFormatter {
|
|
607
839
|
return parseFloat(this.tokens) * ratio;
|
608
840
|
}
|
609
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
|
+
}
|
610
888
|
class FiatSumBalancesFormatter {
|
611
889
|
#balances;
|
612
890
|
#currency;
|
@@ -616,15 +894,10 @@ class FiatSumBalancesFormatter {
|
|
616
894
|
}
|
617
895
|
#sum = balanceField => {
|
618
896
|
// a function to get a fiat amount from a balance
|
619
|
-
const fiat = balance => balance[balanceField].fiat(this.#currency)
|
620
|
-
|
621
|
-
//
|
622
|
-
|
623
|
-
return [...this.#balances].filter(filterMirrorTokens).reduce((total, balance) => sum(
|
624
|
-
// add the total amount...
|
625
|
-
total,
|
626
|
-
// ...to the fiat amount of each balance
|
627
|
-
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),
|
628
901
|
// start with a total of 0
|
629
902
|
0);
|
630
903
|
};
|
@@ -647,7 +920,7 @@ class FiatSumBalancesFormatter {
|
|
647
920
|
get locked() {
|
648
921
|
return this.#sum("locked");
|
649
922
|
}
|
650
|
-
/** @deprecated
|
923
|
+
/** @deprecated Use balances.locked */
|
651
924
|
get frozen() {
|
652
925
|
return this.locked;
|
653
926
|
}
|
@@ -665,6 +938,9 @@ class SumBalancesFormatter {
|
|
665
938
|
constructor(balances) {
|
666
939
|
this.#balances = balances;
|
667
940
|
}
|
941
|
+
get planck() {
|
942
|
+
return new PlanckSumBalancesFormatter(this.#balances);
|
943
|
+
}
|
668
944
|
fiat(currency) {
|
669
945
|
return new FiatSumBalancesFormatter(this.#balances, currency);
|
670
946
|
}
|
@@ -672,16 +948,24 @@ class SumBalancesFormatter {
|
|
672
948
|
|
673
949
|
exports.Balance = Balance;
|
674
950
|
exports.BalanceFormatter = BalanceFormatter;
|
951
|
+
exports.BalanceStatusLive = BalanceStatusLive;
|
675
952
|
exports.Balances = Balances;
|
676
953
|
exports.DefaultBalanceModule = DefaultBalanceModule;
|
677
954
|
exports.FiatSumBalancesFormatter = FiatSumBalancesFormatter;
|
955
|
+
exports.PlanckSumBalancesFormatter = PlanckSumBalancesFormatter;
|
956
|
+
exports.RpcStateQueryHelper = RpcStateQueryHelper;
|
678
957
|
exports.StorageHelper = StorageHelper;
|
679
958
|
exports.SumBalancesFormatter = SumBalancesFormatter;
|
680
959
|
exports.TalismanBalancesDatabase = TalismanBalancesDatabase;
|
681
960
|
exports.balances = balances;
|
961
|
+
exports.createSubscriptionId = createSubscriptionId;
|
682
962
|
exports.createTypeRegistryCache = createTypeRegistryCache;
|
683
963
|
exports.db = db;
|
964
|
+
exports.deleteSubscriptionId = deleteSubscriptionId;
|
965
|
+
exports.deriveStatuses = deriveStatuses;
|
684
966
|
exports.excludeFromFeePayableLocks = excludeFromFeePayableLocks;
|
685
967
|
exports.excludeFromTransferableAmount = excludeFromTransferableAmount;
|
686
968
|
exports.filterMirrorTokens = filterMirrorTokens;
|
969
|
+
exports.findChainMeta = findChainMeta;
|
970
|
+
exports.getValidSubscriptionIds = getValidSubscriptionIds;
|
687
971
|
exports.includeInTotalExtraAmount = includeInTotalExtraAmount;
|