@talismn/balances 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md ADDED
@@ -0,0 +1,26 @@
1
+ # @talismn/balances
2
+
3
+ ## 0.1.1
4
+
5
+ ### Patch Changes
6
+
7
+ - Fixed publish config
8
+ - Updated dependencies
9
+ - @talismn/chain-connector@0.1.1
10
+ - @talismn/chaindata-provider@0.1.1
11
+ - @talismn/token-rates@0.1.1
12
+ - @talismn/util@0.1.1
13
+
14
+ ## 0.1.0
15
+
16
+ ### Minor Changes
17
+
18
+ - 43c1a3a: Initial release
19
+
20
+ ### Patch Changes
21
+
22
+ - Updated dependencies [43c1a3a]
23
+ - @talismn/chain-connector@0.1.0
24
+ - @talismn/chaindata-provider@0.1.0
25
+ - @talismn/token-rates@0.1.0
26
+ - @talismn/util@0.1.0
package/README.md ADDED
@@ -0,0 +1 @@
1
+ # @talismn/balances
@@ -0,0 +1,36 @@
1
+ import { ChainConnector } from "@talismn/chain-connector";
2
+ import { ChainId, ChaindataProvider, IToken } from "@talismn/chaindata-provider";
3
+ import { AddressesByToken, Balances, SubscriptionCallback, UnsubscribeFn } from "./types";
4
+ export interface BalanceModule<TModuleType extends string, TTokenType extends ExtendableTokenType, TChainMeta extends ExtendableChainMeta = DefaultChainMeta, TModuleConfig extends ExtendableModuleConfig = DefaultModuleConfig> extends BalanceModuleSubstrate<TModuleType, TTokenType, TChainMeta, TModuleConfig>, BalanceModuleEvm<TModuleType, TTokenType, TChainMeta, TModuleConfig> {
5
+ }
6
+ export declare const DefaultBalanceModule: <TModuleType extends string, TTokenType extends IToken, TChainMeta extends ExtendableChainMeta = undefined, TModuleConfig extends ExtendableModuleConfig = undefined>(type: TModuleType) => BalanceModule<TModuleType, TTokenType, TChainMeta, TModuleConfig>;
7
+ export declare type ExtendableTokenType = IToken;
8
+ export declare type ExtendableChainMeta = Record<string, unknown> | undefined;
9
+ export declare type DefaultChainMeta = undefined;
10
+ export declare type ExtendableModuleConfig = Record<string, unknown> | undefined;
11
+ export declare type DefaultModuleConfig = undefined;
12
+ interface BalanceModuleSubstrate<TModuleType extends string, TTokenType extends ExtendableTokenType, TChainMeta extends ExtendableChainMeta = DefaultChainMeta, TModuleConfig extends ExtendableModuleConfig = DefaultModuleConfig> extends BalanceModuleCommon<TModuleType, TTokenType, TChainMeta, TModuleConfig> {
13
+ /** Pre-processes any substrate chain metadata required by this module ahead of time */
14
+ fetchSubstrateChainMeta(chainConnector: ChainConnector, chainId: ChainId): Promise<TChainMeta | null>;
15
+ /** Detects which tokens are available on a given substrate chain */
16
+ fetchSubstrateChainTokens(chainConnector: ChainConnector, chainId: ChainId, chainMeta: TChainMeta): Promise<Record<TTokenType["id"], TTokenType>>;
17
+ }
18
+ interface BalanceModuleEvm<TModuleType extends string, TTokenType extends ExtendableTokenType, TChainMeta extends ExtendableChainMeta = DefaultChainMeta, TModuleConfig extends ExtendableModuleConfig = DefaultModuleConfig> extends BalanceModuleCommon<TModuleType, TTokenType, TChainMeta, TModuleConfig> {
19
+ /** Pre-processes any evm chain metadata required by this module ahead of time */
20
+ fetchEvmChainMeta(chainConnector: ChainConnector, chainId: ChainId): Promise<TChainMeta | null>;
21
+ /** Detects which tokens are available on a given evm chain */
22
+ fetchEvmChainTokens(chainConnector: ChainConnector, chainId: ChainId, chainMeta: TChainMeta): Promise<Record<TTokenType["id"], TTokenType>>;
23
+ }
24
+ interface BalanceModuleCommon<TModuleType extends string, TTokenType extends ExtendableTokenType, TChainMeta extends ExtendableChainMeta = DefaultChainMeta, TModuleConfig extends ExtendableModuleConfig = DefaultModuleConfig> {
25
+ get type(): TModuleType;
26
+ /**
27
+ * Subscribe to balances for this module with optional filtering.
28
+ *
29
+ * If subscriptions are not possible, this function should poll at some reasonable interval.
30
+ */
31
+ subscribeBalances(chainConnector: ChainConnector, chaindataProvider: ChaindataProvider, addressesByToken: AddressesByToken<TTokenType>, callback: SubscriptionCallback<Balances>): Promise<UnsubscribeFn>;
32
+ /** Fetch balances for this module with optional filtering */
33
+ fetchBalances(chainConnector: ChainConnector, chaindataProvider: ChaindataProvider, addressesByToken: AddressesByToken<TTokenType>): Promise<Balances>;
34
+ [x: string | number | symbol]: unknown;
35
+ }
36
+ export {};
@@ -0,0 +1,46 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ // TODO: Document default balances module purpose/usage
11
+ export const DefaultBalanceModule = (type) => ({
12
+ get type() {
13
+ return type;
14
+ },
15
+ fetchSubstrateChainMeta() {
16
+ return __awaiter(this, void 0, void 0, function* () {
17
+ return null;
18
+ });
19
+ },
20
+ fetchEvmChainMeta() {
21
+ return __awaiter(this, void 0, void 0, function* () {
22
+ return null;
23
+ });
24
+ },
25
+ fetchSubstrateChainTokens(chainConnector, chainId, chainMeta) {
26
+ return __awaiter(this, void 0, void 0, function* () {
27
+ return Promise.resolve({});
28
+ });
29
+ },
30
+ fetchEvmChainTokens(chainConnector, chainId, chainMeta) {
31
+ return __awaiter(this, void 0, void 0, function* () {
32
+ return Promise.resolve({});
33
+ });
34
+ },
35
+ subscribeBalances(chainConnector, chaindataProvider, addressesByToken, callback) {
36
+ return __awaiter(this, void 0, void 0, function* () {
37
+ callback(new Error("Balance subscriptions are not implemented in this module."));
38
+ return () => { };
39
+ });
40
+ },
41
+ fetchBalances(chainConnector, chaindataProvider, addressesByToken) {
42
+ return __awaiter(this, void 0, void 0, function* () {
43
+ throw new Error("Balance fetching is not implemented in this module.");
44
+ });
45
+ },
46
+ });
@@ -0,0 +1,10 @@
1
+ import { ChainConnector } from "@talismn/chain-connector";
2
+ import { ChaindataProvider } from "@talismn/chaindata-provider";
3
+ import { BalanceModule, DefaultChainMeta, DefaultModuleConfig, ExtendableChainMeta, ExtendableModuleConfig, ExtendableTokenType } from "./BalanceModule";
4
+ import { AddressesByToken, Balances, SubscriptionCallback, UnsubscribeFn } from "./types";
5
+ /**
6
+ * Wraps a BalanceModule's fetch/subscribe methods with a single `balances` method.
7
+ * This `balances` method will subscribe if a callback parameter is provided, or otherwise fetch.
8
+ */
9
+ export declare function balances<TModuleType extends string, TTokenType extends ExtendableTokenType, TChainMeta extends ExtendableChainMeta = DefaultChainMeta, TModuleConfig extends ExtendableModuleConfig = DefaultModuleConfig>(balanceModule: BalanceModule<TModuleType, TTokenType, TChainMeta, TModuleConfig>, chainConnector: ChainConnector, chaindataProvider: ChaindataProvider, addressesByToken: AddressesByToken<TTokenType>): Promise<Balances>;
10
+ export declare function balances<TModuleType extends string, TTokenType extends ExtendableTokenType, TChainMeta extends ExtendableChainMeta = DefaultChainMeta, TModuleConfig extends ExtendableModuleConfig = DefaultModuleConfig>(balanceModule: BalanceModule<TModuleType, TTokenType, TChainMeta, TModuleConfig>, chainConnector: ChainConnector, chaindataProvider: ChaindataProvider, addressesByToken: AddressesByToken<TTokenType>, callback: SubscriptionCallback<Balances>): Promise<UnsubscribeFn>;
@@ -0,0 +1,18 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ export function balances(balanceModule, chainConnector, chaindataProvider, addressesByToken, callback) {
11
+ return __awaiter(this, void 0, void 0, function* () {
12
+ // subscription request
13
+ if (callback !== undefined)
14
+ return yield balanceModule.subscribeBalances(chainConnector, chaindataProvider, addressesByToken, callback);
15
+ // one-off request
16
+ return yield balanceModule.fetchBalances(chainConnector, chaindataProvider, addressesByToken);
17
+ });
18
+ }
@@ -0,0 +1,3 @@
1
+ export * from "./BalanceModule";
2
+ export * from "./helpers";
3
+ export * from "./types";
package/dist/index.js ADDED
@@ -0,0 +1,14 @@
1
+ //
2
+ // NOTE: Do not export `./plugins` from here!
3
+ // Doing so will introduce a circular dependency!
4
+ // It is a separate entrypoint meant to be used like this:
5
+ //
6
+ // import { PluginBalanceTypes } from '@talismn/balances/plugins'
7
+ //
8
+ // Not this:
9
+ //
10
+ // import { PluginBalanceTypes } from '@talismn/balances'
11
+ //
12
+ export * from "./BalanceModule";
13
+ export * from "./helpers";
14
+ export * from "./types";
@@ -0,0 +1,17 @@
1
+ /**
2
+ * `PluginBalanceTypes` is a collection of plugin-provided balance definitions.
3
+ *
4
+ * By hacking declaration merging (typescript magic) we can add variants to this type from within other modules.
5
+ *
6
+ * For more details on this process, see:
7
+ * - https://www.typescriptlang.org/docs/handbook/declaration-merging.html
8
+ * - https://stackoverflow.com/a/58261244/3926156
9
+ * - https://stackoverflow.com/a/56099769/3926156
10
+ * - https://stackoverflow.com/a/56516998/3926156
11
+ * - https://pqina.nl/blog/typescript-interface-merging-and-extending-modules/
12
+ *
13
+ * As a result, consumers of this api will have type information for the `BalanceJson` type
14
+ * based on the selection of plugins they are using in their app.
15
+ */
16
+ export interface PluginBalanceTypes {
17
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,4 @@
1
+ export declare type Address = string;
2
+ export declare type AddressesByToken<TTokenType extends {
3
+ id: string;
4
+ }> = Record<TTokenType["id"], Address[]>;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,174 @@
1
+ import { ChainList, EvmNetworkList, TokenList } from "@talismn/chaindata-provider";
2
+ import { TokenRateCurrency, TokenRates } from "@talismn/token-rates";
3
+ import { NonFunctionProperties } from "@talismn/util";
4
+ import { BalanceJson, BalanceJsonList, IBalance } from "./balancetypes";
5
+ /**
6
+ * Have the importing library define its Token and BalanceJson enums (as a sum type of all plugins) and pass them into some
7
+ * internal global typescript context, which is then picked up on by this module.
8
+ */
9
+ /** A utility type used to extract the underlying `BalanceType` of a specific source from a generalised `BalanceJson` */
10
+ export declare type NarrowBalanceType<S extends IBalance, P> = S extends {
11
+ source: P;
12
+ } ? S : never;
13
+ export declare type BalanceSource = BalanceJson["source"];
14
+ /** TODO: Remove this in favour of a frontend-friendly `ChaindataProvider` */
15
+ export declare type HydrateDb = Partial<{
16
+ chains: ChainList;
17
+ evmNetworks: EvmNetworkList;
18
+ tokens: TokenList;
19
+ }>;
20
+ export declare type BalanceSearchQuery = Partial<NonFunctionProperties<Balance>> | ((balance: Balance) => boolean);
21
+ /**
22
+ * A collection of balances.
23
+ */
24
+ export declare class Balances {
25
+ #private;
26
+ constructor(balances: Balances | BalanceJsonList | Balance[] | BalanceJson[] | Balance, hydrate?: HydrateDb);
27
+ /**
28
+ * Calling toJSON on a collection of balances will return the underlying BalanceJsonList.
29
+ */
30
+ toJSON: () => BalanceJsonList;
31
+ /**
32
+ * Allows the collection to be iterated over.
33
+ *
34
+ * @example
35
+ * [...balances].forEach(balance => { // do something // })
36
+ *
37
+ * @example
38
+ * for (const balance of balances) {
39
+ * // do something
40
+ * }
41
+ */
42
+ [Symbol.iterator]: () => IterableIterator<Balance>;
43
+ /**
44
+ * Hydrates all balances in this collection.
45
+ *
46
+ * @param sources - The sources to hydrate from.
47
+ */
48
+ hydrate: (sources: HydrateDb) => void;
49
+ /**
50
+ * Retrieve a balance from this collection by id.
51
+ *
52
+ * @param id - The id of the balance to fetch.
53
+ * @returns The balance if one exists, or none.
54
+ */
55
+ get: (id: string) => Balance | null;
56
+ /**
57
+ * Retrieve balances from this collection by search query.
58
+ *
59
+ * @param query - The search query.
60
+ * @returns All balances which match the query.
61
+ */
62
+ find: (query: BalanceSearchQuery | BalanceSearchQuery[]) => Balances;
63
+ /**
64
+ * Add some balances to this collection.
65
+ * Added balances take priority over existing balances.
66
+ * The aggregation of the two collections is returned.
67
+ * The original collection is not mutated.
68
+ *
69
+ * @param balances - Either a balance or collection of balances to add.
70
+ * @returns The new collection of balances.
71
+ */
72
+ add: (balances: Balances | Balance) => Balances;
73
+ /**
74
+ * Remove balances from this collection by id.
75
+ * A new collection without these balances is returned.
76
+ * The original collection is not mutated.
77
+ *
78
+ * @param ids - The id(s) of the balances to remove.
79
+ * @returns The new collection of balances.
80
+ */
81
+ remove: (ids: string[] | string) => Balances;
82
+ /**
83
+ * Get an array of balances in this collection, sorted by chain sortIndex.
84
+ *
85
+ * @returns A sorted array of the balances in this collection.
86
+ */
87
+ get sorted(): Balance[];
88
+ /**
89
+ * Get the number of balances in this collection.
90
+ *
91
+ * @returns The number of balances in this collection.
92
+ */
93
+ get count(): number;
94
+ /**
95
+ * Get the summed value of balances in this collection.
96
+ *
97
+ * @example
98
+ * // Get the sum of all transferable balances in usd.
99
+ * balances.sum.fiat('usd').transferable
100
+ */
101
+ get sum(): SumBalancesFormatter;
102
+ }
103
+ /**
104
+ * An individual balance.
105
+ */
106
+ export declare class Balance {
107
+ #private;
108
+ constructor(storage: BalanceJson, hydrate?: HydrateDb);
109
+ toJSON: () => BalanceJson;
110
+ isSource: (source: BalanceSource) => boolean;
111
+ hydrate: (hydrate?: HydrateDb) => void;
112
+ get id(): string;
113
+ get source(): string;
114
+ get status(): import("./balancetypes").BalanceStatus;
115
+ get address(): string;
116
+ get chainId(): string | undefined;
117
+ get chain(): import("@talismn/chaindata-provider").Chain | null;
118
+ get evmNetworkId(): number | undefined;
119
+ get evmNetwork(): import("@talismn/chaindata-provider").EvmNetwork | null;
120
+ get tokenId(): string;
121
+ get token(): import("@talismn/chaindata-provider").IToken | null;
122
+ get decimals(): number | null;
123
+ /**
124
+ * The total balance of this token.
125
+ * Includes the free and the reserved amount.
126
+ * The balance will be reaped if this goes below the existential deposit.
127
+ */
128
+ get total(): BalanceFormatter;
129
+ /** The non-reserved balance of this token. Includes the frozen amount. Is included in the total. */
130
+ get free(): BalanceFormatter;
131
+ /** The reserved balance of this token. Is included in the total. */
132
+ get reserved(): BalanceFormatter;
133
+ /** The frozen balance of this token. Is included in the free amount. */
134
+ get locked(): BalanceFormatter;
135
+ /** @depreacted - use balance.locked */
136
+ get frozen(): BalanceFormatter;
137
+ /** The transferable balance of this token. Is generally the free amount - the miscFrozen amount. */
138
+ get transferable(): BalanceFormatter;
139
+ /** The feePayable balance of this token. Is generally the free amount - the feeFrozen amount. */
140
+ get feePayable(): BalanceFormatter;
141
+ }
142
+ export declare class BalanceFormatter {
143
+ #private;
144
+ constructor(planck: string | bigint, decimals?: number, fiatRatios?: TokenRates);
145
+ toJSON: () => string;
146
+ get planck(): bigint;
147
+ get tokens(): string;
148
+ fiat(currency: TokenRateCurrency): number | null;
149
+ }
150
+ export declare class FiatSumBalancesFormatter {
151
+ #private;
152
+ constructor(balances: Balances, currency: TokenRateCurrency);
153
+ /**
154
+ * The total balance of these tokens. Includes the free and the reserved amount.
155
+ */
156
+ get total(): number;
157
+ /** The non-reserved balance of these tokens. Includes the frozen amount. Is included in the total. */
158
+ get free(): number;
159
+ /** The reserved balance of these tokens. Is included in the total. */
160
+ get reserved(): number;
161
+ /** The frozen balance of these tokens. Is included in the free amount. */
162
+ get locked(): number;
163
+ /** @deprecated - use balances.locked */
164
+ get frozen(): number;
165
+ /** The transferable balance of these tokens. Is generally the free amount - the miscFrozen amount. */
166
+ get transferable(): number;
167
+ /** The feePayable balance of these tokens. Is generally the free amount - the feeFrozen amount. */
168
+ get feePayable(): number;
169
+ }
170
+ export declare class SumBalancesFormatter {
171
+ #private;
172
+ constructor(balances: Balances);
173
+ fiat(currency: TokenRateCurrency): FiatSumBalancesFormatter;
174
+ }
@@ -0,0 +1,490 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
8
+ if (kind === "m") throw new TypeError("Private method is not writable");
9
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
10
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
11
+ return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
12
+ };
13
+ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
14
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
15
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
16
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
17
+ };
18
+ var _Balances_balances, _a, _Balance_storage, _Balance_db, _Balance_format, _BalanceFormatter_planck, _BalanceFormatter_decimals, _BalanceFormatter_fiatRatios, _FiatSumBalancesFormatter_balances, _FiatSumBalancesFormatter_currency, _FiatSumBalancesFormatter_sum, _SumBalancesFormatter_balances;
19
+ import { BigMath, isArrayOf, planckToTokens } from "@talismn/util";
20
+ import memoize from "lodash/memoize";
21
+ import { Memoize } from "typescript-memoize";
22
+ import { excludeFromFeePayableLocks, excludeFromTransferableAmount, includeInTotalExtraAmount, } from "./balancetypes";
23
+ /**
24
+ * A collection of balances.
25
+ */
26
+ export class Balances {
27
+ //
28
+ // Methods
29
+ //
30
+ constructor(balances, hydrate) {
31
+ //
32
+ // Properties
33
+ //
34
+ _Balances_balances.set(this, {}
35
+ //
36
+ // Methods
37
+ //
38
+ );
39
+ /**
40
+ * Calling toJSON on a collection of balances will return the underlying BalanceJsonList.
41
+ */
42
+ this.toJSON = () => Object.fromEntries(Object.entries(__classPrivateFieldGet(this, _Balances_balances, "f")).map(([id, balance]) => [id, balance.toJSON()]));
43
+ /**
44
+ * Allows the collection to be iterated over.
45
+ *
46
+ * @example
47
+ * [...balances].forEach(balance => { // do something // })
48
+ *
49
+ * @example
50
+ * for (const balance of balances) {
51
+ * // do something
52
+ * }
53
+ */
54
+ this[_a] = () =>
55
+ // Create an array of the balances in this collection and return the result of its iterator.
56
+ Object.values(__classPrivateFieldGet(this, _Balances_balances, "f"))[Symbol.iterator]();
57
+ /**
58
+ * Hydrates all balances in this collection.
59
+ *
60
+ * @param sources - The sources to hydrate from.
61
+ */
62
+ this.hydrate = (sources) => {
63
+ Object.values(__classPrivateFieldGet(this, _Balances_balances, "f")).map((balance) => balance.hydrate(sources));
64
+ };
65
+ /**
66
+ * Retrieve a balance from this collection by id.
67
+ *
68
+ * @param id - The id of the balance to fetch.
69
+ * @returns The balance if one exists, or none.
70
+ */
71
+ this.get = (id) => __classPrivateFieldGet(this, _Balances_balances, "f")[id] || null;
72
+ /**
73
+ * Retrieve balances from this collection by search query.
74
+ *
75
+ * @param query - The search query.
76
+ * @returns All balances which match the query.
77
+ */
78
+ this.find = (query) => {
79
+ // construct filter
80
+ const orQueries = (Array.isArray(query) ? query : [query]).map((query) => typeof query === "function" ? query : Object.entries(query));
81
+ // filter balances
82
+ const filter = (balance) => orQueries.some((query) => typeof query === "function"
83
+ ? query(balance)
84
+ : query.every(([key, value]) => balance[key] === value));
85
+ // return filter matches
86
+ return new Balances([...this].filter(filter));
87
+ };
88
+ /**
89
+ * Add some balances to this collection.
90
+ * Added balances take priority over existing balances.
91
+ * The aggregation of the two collections is returned.
92
+ * The original collection is not mutated.
93
+ *
94
+ * @param balances - Either a balance or collection of balances to add.
95
+ * @returns The new collection of balances.
96
+ */
97
+ this.add = (balances) => {
98
+ // handle single balance
99
+ if (balances instanceof Balance)
100
+ return this.add(new Balances(balances));
101
+ // merge balances
102
+ const mergedBalances = Object.assign({}, __classPrivateFieldGet(this, _Balances_balances, "f"));
103
+ [...balances].forEach((balance) => (mergedBalances[balance.id] = balance));
104
+ // return new balances
105
+ return new Balances(Object.values(mergedBalances));
106
+ };
107
+ /**
108
+ * Remove balances from this collection by id.
109
+ * A new collection without these balances is returned.
110
+ * The original collection is not mutated.
111
+ *
112
+ * @param ids - The id(s) of the balances to remove.
113
+ * @returns The new collection of balances.
114
+ */
115
+ this.remove = (ids) => {
116
+ // handle single id
117
+ if (!Array.isArray(ids))
118
+ return this.remove([ids]);
119
+ // merge balances
120
+ const removedBalances = Object.assign({}, __classPrivateFieldGet(this, _Balances_balances, "f"));
121
+ ids.forEach((id) => delete removedBalances[id]);
122
+ // return new balances
123
+ return new Balances(Object.values(removedBalances));
124
+ };
125
+ // handle Balances (convert to Balance[])
126
+ if (balances instanceof Balances)
127
+ return new Balances([...balances], hydrate);
128
+ // handle Balance (convert to Balance[])
129
+ if (balances instanceof Balance)
130
+ return new Balances([balances], hydrate);
131
+ // handle BalanceJsonList (the only remaining non-array type of balances) (convert to BalanceJson[])
132
+ if (!Array.isArray(balances))
133
+ return new Balances(Object.values(balances), hydrate);
134
+ // handle no balances
135
+ if (balances.length === 0)
136
+ return this;
137
+ // handle BalanceJson[]
138
+ if (!isArrayOf(balances, Balance))
139
+ return new Balances(balances.map((storage) => new Balance(storage)), hydrate);
140
+ // handle Balance[]
141
+ __classPrivateFieldSet(this, _Balances_balances, Object.fromEntries(balances.map((balance) => [balance.id, balance])), "f");
142
+ if (hydrate !== undefined)
143
+ this.hydrate(hydrate);
144
+ }
145
+ // TODO: Add some more useful aggregator methods
146
+ /**
147
+ * Get an array of balances in this collection, sorted by chain sortIndex.
148
+ *
149
+ * @returns A sorted array of the balances in this collection.
150
+ */
151
+ get sorted() {
152
+ return [...this].sort((a, b) => {
153
+ var _b, _c;
154
+ return (((_b = (a.chain || a.evmNetwork)) === null || _b === void 0 ? void 0 : _b.sortIndex) || Number.MAX_SAFE_INTEGER) -
155
+ (((_c = (b.chain || b.evmNetwork)) === null || _c === void 0 ? void 0 : _c.sortIndex) || Number.MAX_SAFE_INTEGER);
156
+ });
157
+ }
158
+ /**
159
+ * Get the number of balances in this collection.
160
+ *
161
+ * @returns The number of balances in this collection.
162
+ */
163
+ get count() {
164
+ return [...this].length;
165
+ }
166
+ /**
167
+ * Get the summed value of balances in this collection.
168
+ *
169
+ * @example
170
+ * // Get the sum of all transferable balances in usd.
171
+ * balances.sum.fiat('usd').transferable
172
+ */
173
+ get sum() {
174
+ return new SumBalancesFormatter(this);
175
+ }
176
+ }
177
+ _Balances_balances = new WeakMap(), _a = Symbol.iterator;
178
+ __decorate([
179
+ Memoize()
180
+ ], Balances.prototype, "sorted", null);
181
+ __decorate([
182
+ Memoize()
183
+ ], Balances.prototype, "count", null);
184
+ __decorate([
185
+ Memoize()
186
+ ], Balances.prototype, "sum", null);
187
+ /**
188
+ * An individual balance.
189
+ */
190
+ export class Balance {
191
+ //
192
+ // Methods
193
+ //
194
+ constructor(storage, hydrate) {
195
+ //
196
+ // Properties
197
+ //
198
+ /** The underlying data for this balance */
199
+ _Balance_storage.set(this, void 0);
200
+ _Balance_db.set(this, null
201
+ //
202
+ // Methods
203
+ //
204
+ );
205
+ this.toJSON = () => __classPrivateFieldGet(this, _Balance_storage, "f");
206
+ this.isSource = (source) => __classPrivateFieldGet(this, _Balance_storage, "f").source === source;
207
+ // // TODO: Fix this method, the types don't work with our plugin architecture.
208
+ // // Specifically, the `BalanceJson` type is compiled down to `IBalance` in the following way:
209
+ // //
210
+ // // toJSON: () => BalanceJson // works
211
+ // // isSource: (source: BalanceSource) => boolean // works
212
+ // // asSource: <P extends string>(source: P) => NarrowBalanceType<IBalance, P> | null // Doesn't work! IBalance should just be BalanceJson!
213
+ // //
214
+ // // `IBalance` won't match the type of `BalanceSource` after `PluginBalanceTypes` has been extended by balance plugins.
215
+ // // As a result, typescript will think that the returned #storage is not a BalanceJson.
216
+ // asSource = <P extends BalanceSource>(source: P): NarrowBalanceType<BalanceJson, P> | null => {
217
+ // if (this.#storage.source === source) return this.#storage as NarrowBalanceType<BalanceJson, P>
218
+ // return null
219
+ // }
220
+ this.hydrate = (hydrate) => {
221
+ if (hydrate !== undefined)
222
+ __classPrivateFieldSet(this, _Balance_db, hydrate, "f");
223
+ };
224
+ _Balance_format.set(this, (balance) => {
225
+ var _b;
226
+ return new BalanceFormatter(typeof balance === "bigint" ? balance.toString() : balance, this.decimals || undefined, ((_b = this.token) === null || _b === void 0 ? void 0 : _b.rates) || undefined);
227
+ }
228
+ //
229
+ // Accessors
230
+ //
231
+ );
232
+ __classPrivateFieldSet(this, _Balance_format, memoize(__classPrivateFieldGet(this, _Balance_format, "f")), "f");
233
+ __classPrivateFieldSet(this, _Balance_storage, storage, "f");
234
+ if (hydrate !== undefined)
235
+ this.hydrate(hydrate);
236
+ }
237
+ //
238
+ // Accessors
239
+ //
240
+ get id() {
241
+ const { source, address, chainId, evmNetworkId, tokenId } = __classPrivateFieldGet(this, _Balance_storage, "f");
242
+ const locationId = chainId !== undefined ? chainId : evmNetworkId;
243
+ return `${source}-${address}-${locationId}-${tokenId}`;
244
+ }
245
+ get source() {
246
+ return __classPrivateFieldGet(this, _Balance_storage, "f").source;
247
+ }
248
+ get status() {
249
+ return __classPrivateFieldGet(this, _Balance_storage, "f").status;
250
+ }
251
+ get address() {
252
+ return __classPrivateFieldGet(this, _Balance_storage, "f").address;
253
+ }
254
+ get chainId() {
255
+ return __classPrivateFieldGet(this, _Balance_storage, "f").chainId;
256
+ }
257
+ get chain() {
258
+ var _b, _c;
259
+ return (((_b = __classPrivateFieldGet(this, _Balance_db, "f")) === null || _b === void 0 ? void 0 : _b.chains) && this.chainId && ((_c = __classPrivateFieldGet(this, _Balance_db, "f")) === null || _c === void 0 ? void 0 : _c.chains[this.chainId])) || null;
260
+ }
261
+ get evmNetworkId() {
262
+ return __classPrivateFieldGet(this, _Balance_storage, "f").evmNetworkId;
263
+ }
264
+ get evmNetwork() {
265
+ var _b, _c;
266
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
267
+ return (((_b = __classPrivateFieldGet(this, _Balance_db, "f")) === null || _b === void 0 ? void 0 : _b.evmNetworks) && ((_c = __classPrivateFieldGet(this, _Balance_db, "f")) === null || _c === void 0 ? void 0 : _c.evmNetworks[this.evmNetworkId])) || null;
268
+ }
269
+ get tokenId() {
270
+ return __classPrivateFieldGet(this, _Balance_storage, "f").tokenId;
271
+ }
272
+ get token() {
273
+ var _b, _c;
274
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
275
+ return (((_b = __classPrivateFieldGet(this, _Balance_db, "f")) === null || _b === void 0 ? void 0 : _b.tokens) && ((_c = __classPrivateFieldGet(this, _Balance_db, "f")) === null || _c === void 0 ? void 0 : _c.tokens[this.tokenId])) || null;
276
+ }
277
+ get decimals() {
278
+ var _b;
279
+ return ((_b = this.token) === null || _b === void 0 ? void 0 : _b.decimals) || null;
280
+ }
281
+ /**
282
+ * The total balance of this token.
283
+ * Includes the free and the reserved amount.
284
+ * The balance will be reaped if this goes below the existential deposit.
285
+ */
286
+ get total() {
287
+ const extra = includeInTotalExtraAmount(__classPrivateFieldGet(this, _Balance_storage, "f").extra);
288
+ return __classPrivateFieldGet(this, _Balance_format, "f").call(this, this.free.planck + this.reserved.planck + extra);
289
+ }
290
+ /** The non-reserved balance of this token. Includes the frozen amount. Is included in the total. */
291
+ get free() {
292
+ var _b;
293
+ return __classPrivateFieldGet(this, _Balance_format, "f").call(this, typeof __classPrivateFieldGet(this, _Balance_storage, "f").free === "string"
294
+ ? BigInt(__classPrivateFieldGet(this, _Balance_storage, "f").free)
295
+ : Array.isArray(__classPrivateFieldGet(this, _Balance_storage, "f").free)
296
+ ? __classPrivateFieldGet(this, _Balance_storage, "f").free
297
+ .map((reserve) => BigInt(reserve.amount))
298
+ .reduce((a, b) => a + b, BigInt("0"))
299
+ : BigInt(((_b = __classPrivateFieldGet(this, _Balance_storage, "f").free) === null || _b === void 0 ? void 0 : _b.amount) || "0"));
300
+ }
301
+ /** The reserved balance of this token. Is included in the total. */
302
+ get reserved() {
303
+ var _b;
304
+ return __classPrivateFieldGet(this, _Balance_format, "f").call(this, typeof __classPrivateFieldGet(this, _Balance_storage, "f").reserves === "string"
305
+ ? BigInt(__classPrivateFieldGet(this, _Balance_storage, "f").reserves)
306
+ : Array.isArray(__classPrivateFieldGet(this, _Balance_storage, "f").reserves)
307
+ ? __classPrivateFieldGet(this, _Balance_storage, "f").reserves
308
+ .map((reserve) => BigInt(reserve.amount))
309
+ .reduce((a, b) => a + b, BigInt("0"))
310
+ : BigInt(((_b = __classPrivateFieldGet(this, _Balance_storage, "f").reserves) === null || _b === void 0 ? void 0 : _b.amount) || "0"));
311
+ }
312
+ /** The frozen balance of this token. Is included in the free amount. */
313
+ get locked() {
314
+ var _b;
315
+ return __classPrivateFieldGet(this, _Balance_format, "f").call(this, typeof __classPrivateFieldGet(this, _Balance_storage, "f").locks === "string"
316
+ ? BigInt(__classPrivateFieldGet(this, _Balance_storage, "f").locks)
317
+ : Array.isArray(__classPrivateFieldGet(this, _Balance_storage, "f").locks)
318
+ ? __classPrivateFieldGet(this, _Balance_storage, "f").locks
319
+ .map((lock) => BigInt(lock.amount))
320
+ .reduce((a, b) => BigMath.max(a, b), BigInt("0"))
321
+ : BigInt(((_b = __classPrivateFieldGet(this, _Balance_storage, "f").locks) === null || _b === void 0 ? void 0 : _b.amount) || "0"));
322
+ }
323
+ /** @depreacted - use balance.locked */
324
+ get frozen() {
325
+ return this.locked;
326
+ }
327
+ /** The transferable balance of this token. Is generally the free amount - the miscFrozen amount. */
328
+ get transferable() {
329
+ // if no locks exist, transferable is equal to the free amount
330
+ if (!__classPrivateFieldGet(this, _Balance_storage, "f").locks)
331
+ return this.free;
332
+ // find the largest lock (but ignore any locks which are marked as `includeInTransferable`)
333
+ const excludeAmount = excludeFromTransferableAmount(__classPrivateFieldGet(this, _Balance_storage, "f").locks);
334
+ // subtract the lock from the free amount (but don't go below 0)
335
+ return __classPrivateFieldGet(this, _Balance_format, "f").call(this, BigMath.max(this.free.planck - excludeAmount, BigInt("0")));
336
+ }
337
+ /** The feePayable balance of this token. Is generally the free amount - the feeFrozen amount. */
338
+ get feePayable() {
339
+ // if no locks exist, feePayable is equal to the free amount
340
+ if (!__classPrivateFieldGet(this, _Balance_storage, "f").locks)
341
+ return this.free;
342
+ // find the largest lock which can't be used to pay tx fees
343
+ const excludeAmount = excludeFromFeePayableLocks(__classPrivateFieldGet(this, _Balance_storage, "f").locks)
344
+ .map((lock) => BigInt(lock.amount))
345
+ .reduce((max, lock) => BigMath.max(max, lock), BigInt("0"));
346
+ // subtract the lock from the free amount (but don't go below 0)
347
+ return __classPrivateFieldGet(this, _Balance_format, "f").call(this, BigMath.max(this.free.planck - excludeAmount, BigInt("0")));
348
+ }
349
+ }
350
+ _Balance_storage = new WeakMap(), _Balance_db = new WeakMap(), _Balance_format = new WeakMap();
351
+ __decorate([
352
+ Memoize()
353
+ ], Balance.prototype, "total", null);
354
+ __decorate([
355
+ Memoize()
356
+ ], Balance.prototype, "free", null);
357
+ __decorate([
358
+ Memoize()
359
+ ], Balance.prototype, "reserved", null);
360
+ __decorate([
361
+ Memoize()
362
+ ], Balance.prototype, "locked", null);
363
+ __decorate([
364
+ Memoize()
365
+ ], Balance.prototype, "frozen", null);
366
+ __decorate([
367
+ Memoize()
368
+ ], Balance.prototype, "transferable", null);
369
+ __decorate([
370
+ Memoize()
371
+ ], Balance.prototype, "feePayable", null);
372
+ export class BalanceFormatter {
373
+ constructor(planck, decimals, fiatRatios) {
374
+ _BalanceFormatter_planck.set(this, void 0);
375
+ _BalanceFormatter_decimals.set(this, void 0);
376
+ _BalanceFormatter_fiatRatios.set(this, void 0);
377
+ this.toJSON = () => __classPrivateFieldGet(this, _BalanceFormatter_planck, "f");
378
+ __classPrivateFieldSet(this, _BalanceFormatter_planck, typeof planck === "bigint" ? planck.toString() : planck, "f");
379
+ __classPrivateFieldSet(this, _BalanceFormatter_decimals, decimals || 0, "f");
380
+ __classPrivateFieldSet(this, _BalanceFormatter_fiatRatios, fiatRatios || null, "f");
381
+ this.fiat = memoize(this.fiat);
382
+ }
383
+ get planck() {
384
+ return BigInt(__classPrivateFieldGet(this, _BalanceFormatter_planck, "f"));
385
+ }
386
+ get tokens() {
387
+ return planckToTokens(__classPrivateFieldGet(this, _BalanceFormatter_planck, "f"), __classPrivateFieldGet(this, _BalanceFormatter_decimals, "f"));
388
+ }
389
+ fiat(currency) {
390
+ if (!__classPrivateFieldGet(this, _BalanceFormatter_fiatRatios, "f"))
391
+ return null;
392
+ const ratio = __classPrivateFieldGet(this, _BalanceFormatter_fiatRatios, "f")[currency];
393
+ if (!ratio)
394
+ return null;
395
+ return parseFloat(this.tokens) * ratio;
396
+ }
397
+ }
398
+ _BalanceFormatter_planck = new WeakMap(), _BalanceFormatter_decimals = new WeakMap(), _BalanceFormatter_fiatRatios = new WeakMap();
399
+ __decorate([
400
+ Memoize()
401
+ ], BalanceFormatter.prototype, "tokens", null);
402
+ export class FiatSumBalancesFormatter {
403
+ constructor(balances, currency) {
404
+ _FiatSumBalancesFormatter_balances.set(this, void 0);
405
+ _FiatSumBalancesFormatter_currency.set(this, void 0);
406
+ _FiatSumBalancesFormatter_sum.set(this, (balanceField) => {
407
+ // a function to get a fiat amount from a balance
408
+ const fiat = (balance) => balance[balanceField].fiat(__classPrivateFieldGet(this, _FiatSumBalancesFormatter_currency, "f")) || 0;
409
+ // a function to add two amounts
410
+ const sum = (a, b) => a + b;
411
+ return [...__classPrivateFieldGet(this, _FiatSumBalancesFormatter_balances, "f")].reduce((total, balance) => sum(
412
+ // add the total amount...
413
+ total,
414
+ // ...to the fiat amount of each balance
415
+ fiat(balance)),
416
+ // start with a total of 0
417
+ 0);
418
+ }
419
+ /**
420
+ * The total balance of these tokens. Includes the free and the reserved amount.
421
+ */
422
+ );
423
+ __classPrivateFieldSet(this, _FiatSumBalancesFormatter_balances, balances, "f");
424
+ __classPrivateFieldSet(this, _FiatSumBalancesFormatter_currency, currency, "f");
425
+ __classPrivateFieldSet(this, _FiatSumBalancesFormatter_sum, memoize(__classPrivateFieldGet(this, _FiatSumBalancesFormatter_sum, "f")), "f");
426
+ }
427
+ /**
428
+ * The total balance of these tokens. Includes the free and the reserved amount.
429
+ */
430
+ get total() {
431
+ return __classPrivateFieldGet(this, _FiatSumBalancesFormatter_sum, "f").call(this, "total");
432
+ }
433
+ /** The non-reserved balance of these tokens. Includes the frozen amount. Is included in the total. */
434
+ get free() {
435
+ return __classPrivateFieldGet(this, _FiatSumBalancesFormatter_sum, "f").call(this, "free");
436
+ }
437
+ /** The reserved balance of these tokens. Is included in the total. */
438
+ get reserved() {
439
+ return __classPrivateFieldGet(this, _FiatSumBalancesFormatter_sum, "f").call(this, "reserved");
440
+ }
441
+ /** The frozen balance of these tokens. Is included in the free amount. */
442
+ get locked() {
443
+ return __classPrivateFieldGet(this, _FiatSumBalancesFormatter_sum, "f").call(this, "locked");
444
+ }
445
+ /** @deprecated - use balances.locked */
446
+ get frozen() {
447
+ return this.locked;
448
+ }
449
+ /** The transferable balance of these tokens. Is generally the free amount - the miscFrozen amount. */
450
+ get transferable() {
451
+ return __classPrivateFieldGet(this, _FiatSumBalancesFormatter_sum, "f").call(this, "transferable");
452
+ }
453
+ /** The feePayable balance of these tokens. Is generally the free amount - the feeFrozen amount. */
454
+ get feePayable() {
455
+ return __classPrivateFieldGet(this, _FiatSumBalancesFormatter_sum, "f").call(this, "feePayable");
456
+ }
457
+ }
458
+ _FiatSumBalancesFormatter_balances = new WeakMap(), _FiatSumBalancesFormatter_currency = new WeakMap(), _FiatSumBalancesFormatter_sum = new WeakMap();
459
+ __decorate([
460
+ Memoize()
461
+ ], FiatSumBalancesFormatter.prototype, "total", null);
462
+ __decorate([
463
+ Memoize()
464
+ ], FiatSumBalancesFormatter.prototype, "free", null);
465
+ __decorate([
466
+ Memoize()
467
+ ], FiatSumBalancesFormatter.prototype, "reserved", null);
468
+ __decorate([
469
+ Memoize()
470
+ ], FiatSumBalancesFormatter.prototype, "locked", null);
471
+ __decorate([
472
+ Memoize()
473
+ ], FiatSumBalancesFormatter.prototype, "frozen", null);
474
+ __decorate([
475
+ Memoize()
476
+ ], FiatSumBalancesFormatter.prototype, "transferable", null);
477
+ __decorate([
478
+ Memoize()
479
+ ], FiatSumBalancesFormatter.prototype, "feePayable", null);
480
+ export class SumBalancesFormatter {
481
+ constructor(balances) {
482
+ _SumBalancesFormatter_balances.set(this, void 0);
483
+ __classPrivateFieldSet(this, _SumBalancesFormatter_balances, balances, "f");
484
+ this.fiat = memoize(this.fiat);
485
+ }
486
+ fiat(currency) {
487
+ return new FiatSumBalancesFormatter(__classPrivateFieldGet(this, _SumBalancesFormatter_balances, "f"), currency);
488
+ }
489
+ }
490
+ _SumBalancesFormatter_balances = new WeakMap();
@@ -0,0 +1,88 @@
1
+ import { ChainId, EvmNetworkId, MultiChainId, TokenId } from "@talismn/chaindata-provider";
2
+ import { PluginBalanceTypes } from "../plugins";
3
+ import { Address } from "./addresses";
4
+ /**
5
+ * `BalanceTypes` is an automatically determined sub-selection of `PluginBalanceTypes`.
6
+ *
7
+ * It is the same list, but with any invalid `BalanceType` definitions filtered out.
8
+ */
9
+ export declare type BalanceTypes = {
10
+ [BalanceType in keyof PluginBalanceTypes]: PluginBalanceTypes[BalanceType] extends IBalance ? PluginBalanceTypes[BalanceType] : never;
11
+ };
12
+ /**
13
+ * The `BalanceJson` sum type, which is a union of all of the possible `BalanceTypes`.
14
+ *
15
+ * Each variant comes from a plugin in use by the consuming app.
16
+ *
17
+ * For example, in an app with the `substrate-native`, `evm-native`, `substrate-orml` and `evm-erc20` plugins:
18
+ *
19
+ * type BalanceJson = SubNativeBalance | EvmNativeBalance | SubOrmlBalance | EvmErc20Balance
20
+ *
21
+ * If `BalanceTypes` is empty then `BalanceJson` will fall back to the common `IBalance` interface, which every balance must implement.
22
+ */
23
+ export declare type BalanceJson = BalanceTypes[keyof BalanceTypes] extends never ? IBalance : BalanceTypes[keyof BalanceTypes];
24
+ /** A collection of `BalanceJson` objects */
25
+ export declare type BalanceJsonList = Record<string, BalanceJson>;
26
+ export declare type BalanceStatus = "live" | "cache";
27
+ /** `IBalance` is a common interface which all balance types must implement. */
28
+ export declare type IBalance = {
29
+ /** The module that this balance was retrieved by */
30
+ source: string;
31
+ /** Has this balance never been fetched, or is it from a cache, or is it up to date? */
32
+ status: BalanceStatus;
33
+ /** The address of the account which owns this balance */
34
+ address: Address;
35
+ /** The token this balance is for */
36
+ tokenId: TokenId;
37
+ /** WIP, use `chainId` or `evmNetworkId` for now */
38
+ multiChainId: MultiChainId;
39
+ /** The substrate chain this balance is on */
40
+ chainId?: ChainId;
41
+ /** The evm chain this balance is on */
42
+ evmNetworkId?: EvmNetworkId;
43
+ } & IBalanceAmounts;
44
+ export declare type IBalanceAmounts = {
45
+ /** The portion of a balance that is not reserved. The free balance is the only balance that matters for most operations. */
46
+ free?: Amount | AmountWithLabel<string> | Array<AmountWithLabel<string>>;
47
+ /** The portion of a balance that is owned by the account but is reserved/suspended/unavailable. Reserved balance can still be slashed, but only after all the free balance has been slashed. */
48
+ reserves?: Amount | AmountWithLabel<string> | Array<AmountWithLabel<string>>;
49
+ /** A freeze on a specified amount of an account's free balance until a specified block number. Multiple locks always operate over the same funds, so they overlay rather than stack. */
50
+ locks?: Amount | LockedAmount<string> | Array<LockedAmount<string>>;
51
+ /** Additional balances held by an account. By default these will not be included in the account total. Dapps may choose to add support for showing extra amounts on a case by case basis. */
52
+ extra?: ExtraAmount<string> | Array<ExtraAmount<string>>;
53
+ };
54
+ /** An unlabelled amount of a balance */
55
+ export declare type Amount = string;
56
+ /** A labelled amount of a balance */
57
+ export declare type AmountWithLabel<TLabel extends string> = {
58
+ label: TLabel;
59
+ amount: Amount;
60
+ };
61
+ /** A labelled locked amount of a balance */
62
+ export declare type LockedAmount<TLabel extends string> = AmountWithLabel<TLabel> & {
63
+ /**
64
+ * By default, the largest locked amount is subtrated from the transferable amount of this balance.
65
+ * If this property is set to true, this particular lock will be skipped when making this calculation.
66
+ * As such, this locked amount will be included in the calculated transferable amount.
67
+ */
68
+ includeInTransferable?: boolean;
69
+ /**
70
+ * By default, tx fees can be deducted from locked amounts of balance.
71
+ * As such, locked amounts are ignored when calculating if the user has enough funds to pay tx fees.
72
+ * If this property is set to true, this particular lock will be subtracted from the available funds when making this calculation.
73
+ * As such, this locked amount will not be included in the calculated available funds.
74
+ */
75
+ excludeFromFeePayable?: boolean;
76
+ };
77
+ export declare function excludeFromTransferableAmount(locks: Amount | LockedAmount<string> | Array<LockedAmount<string>>): bigint;
78
+ export declare function excludeFromFeePayableLocks(locks: Amount | LockedAmount<string> | Array<LockedAmount<string>>): Array<LockedAmount<string>>;
79
+ /** A labelled extra amount of a balance */
80
+ export declare type ExtraAmount<TLabel extends string> = AmountWithLabel<TLabel> & {
81
+ /** If set to true, this extra amount will be included in the calculation of the total amount of this balance. */
82
+ includeInTotal?: boolean;
83
+ };
84
+ export declare function includeInTotalExtraAmount(extra?: ExtraAmount<string> | Array<ExtraAmount<string>>): bigint;
85
+ /** Used by plugins to help define their custom `BalanceType` */
86
+ export declare type NewBalanceType<TModuleType extends string, T extends IBalanceAmounts> = IBalance & {
87
+ source: TModuleType;
88
+ } & T;
@@ -0,0 +1,28 @@
1
+ import { BigMath } from "@talismn/util";
2
+ export function excludeFromTransferableAmount(locks) {
3
+ if (typeof locks === "string")
4
+ return BigInt(locks);
5
+ if (!Array.isArray(locks))
6
+ locks = [locks];
7
+ return locks
8
+ .filter((lock) => lock.includeInTransferable !== true)
9
+ .map((lock) => BigInt(lock.amount))
10
+ .reduce((max, lock) => BigMath.max(max, lock), BigInt("0"));
11
+ }
12
+ export function excludeFromFeePayableLocks(locks) {
13
+ if (typeof locks === "string")
14
+ return [];
15
+ if (!Array.isArray(locks))
16
+ locks = [locks];
17
+ return locks.filter((lock) => lock.excludeFromFeePayable);
18
+ }
19
+ export function includeInTotalExtraAmount(extra) {
20
+ if (!extra)
21
+ return BigInt("0");
22
+ if (!Array.isArray(extra))
23
+ extra = [extra];
24
+ return extra
25
+ .filter((extra) => extra.includeInTotal)
26
+ .map((extra) => BigInt(extra.amount))
27
+ .reduce((a, b) => a + b, BigInt("0"));
28
+ }
@@ -0,0 +1,4 @@
1
+ export * from "./addresses";
2
+ export * from "./balances";
3
+ export * from "./balancetypes";
4
+ export * from "./subscriptions";
@@ -0,0 +1,4 @@
1
+ export * from "./addresses";
2
+ export * from "./balances";
3
+ export * from "./balancetypes";
4
+ export * from "./subscriptions";
@@ -0,0 +1,11 @@
1
+ /**
2
+ * A callback with either an error or a result.
3
+ */
4
+ export interface SubscriptionCallback<Result> {
5
+ (error: null, result: Result): void;
6
+ (error: any, result?: never): void;
7
+ }
8
+ /**
9
+ * A function which cancels a subscription when called.
10
+ */
11
+ export declare type UnsubscribeFn = () => void;
@@ -0,0 +1 @@
1
+ export {};
package/package.json ADDED
@@ -0,0 +1,56 @@
1
+ {
2
+ "name": "@talismn/balances",
3
+ "version": "0.1.1",
4
+ "author": "Talisman",
5
+ "homepage": "https://talisman.xyz",
6
+ "license": "UNLICENSED",
7
+ "publishConfig": {
8
+ "access": "public"
9
+ },
10
+ "repository": {
11
+ "directory": "packages/balances",
12
+ "type": "git",
13
+ "url": "https://github.com/talismansociety/talisman.git"
14
+ },
15
+ "main": "dist/index.js",
16
+ "types": "dist/index.d.ts",
17
+ "files": [
18
+ "/dist",
19
+ "/plugins"
20
+ ],
21
+ "engines": {
22
+ "node": ">=14"
23
+ },
24
+ "scripts": {
25
+ "dev": "tsc --watch --declarationMap",
26
+ "build": "tsc --declarationMap",
27
+ "build:packages:prod": "rm -rf dist && tsc",
28
+ "prepack": "yarn build:packages:prod",
29
+ "test": "jest",
30
+ "lint": "eslint . --max-warnings 0",
31
+ "clean": "rm -rf dist && rm -rf .turbo rm -rf node_modules"
32
+ },
33
+ "dependencies": {
34
+ "@talismn/chain-connector": "^0.1.1",
35
+ "@talismn/chaindata-provider": "^0.1.1",
36
+ "@talismn/token-rates": "^0.1.1",
37
+ "@talismn/util": "^0.1.1",
38
+ "lodash": "^4.17.21",
39
+ "typescript-memoize": "^1.1.0"
40
+ },
41
+ "devDependencies": {
42
+ "@talismn/eslint-config": "^0.0.0",
43
+ "@talismn/tsconfig": "^0.0.0",
44
+ "@types/jest": "^27.5.1",
45
+ "eslint": "^8.4.0",
46
+ "jest": "^28.1.0",
47
+ "ts-jest": "^28.0.2",
48
+ "typescript": "^4.6.4"
49
+ },
50
+ "eslintConfig": {
51
+ "root": true,
52
+ "extends": [
53
+ "@talismn/eslint-config"
54
+ ]
55
+ }
56
+ }
@@ -0,0 +1,5 @@
1
+ {
2
+ "internal": true,
3
+ "main": "../dist/plugins.js",
4
+ "types": "../dist/plugins.d.ts"
5
+ }