@talismn/balances 0.0.0-pr2075-20250707160526 → 0.0.0-pr2075-20250708125508

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.
@@ -1,6 +1,6 @@
1
1
  import { Dexie } from 'dexie';
2
2
  import anylogger from 'anylogger';
3
- import { evmErc20TokenId, MINIMETADATA_VERSION, EvmErc20TokenSchema, parseTokenId, parseEvmErc20TokenId, isTokenOfType, TokenBaseSchema, EvmNativeTokenSchema, evmNativeTokenId, EvmUniswapV2TokenSchema, evmUniswapV2TokenId, networkIdFromTokenId, getGithubTokenLogoUrl, SubAssetsTokenSchema, subAssetTokenId, SubForeignAssetsTokenSchema, subForeignAssetTokenId, SubHydrationTokenSchema, subHydrationTokenId, SubNativeTokenSchema, subNativeTokenId, SubPsp22TokenSchema, subPsp22TokenId, SubTokensTokenSchema, subTokensTokenId, DotNetworkBalancesConfigSchema, parseSubAssetTokenId, parseSubForeignAssetTokenId, parseSubTokensTokenId } from '@talismn/chaindata-provider';
3
+ import { evmErc20TokenId, MINIMETADATA_VERSION, EvmErc20TokenSchema, parseTokenId, parseEvmErc20TokenId, isTokenOfType, TokenBaseSchema, EvmNativeTokenSchema, evmNativeTokenId, EvmUniswapV2TokenSchema, evmUniswapV2TokenId, networkIdFromTokenId, getGithubTokenLogoUrl, SubAssetsTokenSchema, subAssetTokenId, SubForeignAssetsTokenSchema, subForeignAssetTokenId, SubHydrationTokenSchema, subHydrationTokenId, SubNativeTokenSchema, subNativeTokenId, SubPsp22TokenSchema, subPsp22TokenId, SubTokensTokenSchema, subTokensTokenId, parseSubAssetTokenId, parseSubForeignAssetTokenId, parseSubTokensTokenId, isNetworkDot } from '@talismn/chaindata-provider';
4
4
  export { MINIMETADATA_VERSION } from '@talismn/chaindata-provider';
5
5
  import { newTokenRates } from '@talismn/token-rates';
6
6
  import { isBigInt, BigMath, planckToTokens, isArrayOf, isTruthy, isEthereumAddress, hasOwnProperty, isNotNil, isAbortError, decodeAnyAddress, blake2Concat, Deferred } from '@talismn/util';
@@ -11,7 +11,7 @@ import pako from 'pako';
11
11
  import { parseAbi, erc20Abi, getContract, ContractFunctionExecutionError, hexToString, erc20Abi_bytes32, encodeFunctionData, isHex, hexToBigInt, withRetry } from 'viem';
12
12
  import { assign, omit, isEqual, fromPairs, toPairs, keys, keyBy, uniq, values, groupBy as groupBy$1 } from 'lodash';
13
13
  import z from 'zod/v4';
14
- import { Observable, distinctUntilChanged, of, timer, switchMap, from, firstValueFrom, scan, share, map, switchAll, combineLatest, mergeMap, toArray, interval, startWith, exhaustMap, BehaviorSubject, debounceTime, takeUntil, withLatestFrom, concatMap } from 'rxjs';
14
+ import { Observable, distinctUntilChanged, of, timer, switchMap, from, firstValueFrom, combineLatest, map, scan, share, switchAll, mergeMap, toArray, interval, startWith, exhaustMap, BehaviorSubject, debounceTime, takeUntil, withLatestFrom, concatMap, tap } from 'rxjs';
15
15
  import isEqual$1 from 'lodash/isEqual';
16
16
  import { unifyMetadata, decAnyMetadata, getDynamicBuilder, getLookupFn, decodeScale, parseMetadataRpc, getStorageKeyPrefix, compactMetadata, encodeMetadata, papiParse, papiStringify, toHex, getMetadataVersion, encodeStateKey } from '@talismn/scale';
17
17
  import { Metadata, TypeRegistry } from '@polkadot/types';
@@ -275,11 +275,10 @@ class Balances {
275
275
  }
276
276
  const getBalanceId = balance => {
277
277
  const {
278
- source,
279
278
  address,
280
279
  tokenId
281
280
  } = balance;
282
- return [source, address, tokenId].join("::");
281
+ return [address, tokenId].join("::");
283
282
  };
284
283
 
285
284
  /**
@@ -1538,16 +1537,16 @@ const getBalanceDefs = addressesByToken => {
1538
1537
 
1539
1538
  const fetchBalances$c = async ({
1540
1539
  networkId,
1541
- addressesByToken,
1540
+ tokensWithAddresses,
1542
1541
  connector
1543
1542
  }) => {
1544
1543
  const client = await connector.getPublicClientForEvmNetwork(networkId);
1545
1544
  if (!client) throw new Error(`Could not get rpc provider for evm network ${networkId}`);
1546
- for (const [token, addresses] of addressesByToken) {
1545
+ for (const [token, addresses] of tokensWithAddresses) {
1547
1546
  if (token.type !== MODULE_TYPE$8 || token.networkId !== networkId) throw new Error(`Invalid token type or networkId for EVM ERC20 balance module: ${token.type} on ${token.networkId}`);
1548
1547
  for (const address of addresses) if (!isEthereumAddress(address)) throw new Error(`Invalid ethereum address for EVM ERC20 balance module: ${address} for token ${token.id}`);
1549
1548
  }
1550
- const balanceDefs = getBalanceDefs(addressesByToken);
1549
+ const balanceDefs = getBalanceDefs(tokensWithAddresses);
1551
1550
  if (client.chain?.contracts?.erc20Aggregator && balanceDefs.length > 1) {
1552
1551
  const erc20Aggregator = client.chain.contracts.erc20Aggregator;
1553
1552
  return fetchWithAggregator$1(client, balanceDefs, erc20Aggregator.address);
@@ -1767,10 +1766,10 @@ const getTransferCallData$8 = ({
1767
1766
  };
1768
1767
  };
1769
1768
 
1770
- const SUBSCRIPTION_INTERVAL$8 = 6_000;
1769
+ const SUBSCRIPTION_INTERVAL$7 = 6_000;
1771
1770
  const subscribeBalances$8 = ({
1772
1771
  networkId,
1773
- addressesByToken,
1772
+ tokensWithAddresses,
1774
1773
  connector
1775
1774
  }) => {
1776
1775
  return new Observable(subscriber => {
@@ -1780,17 +1779,17 @@ const subscribeBalances$8 = ({
1780
1779
  if (abortController.signal.aborted) return;
1781
1780
  const balances = await fetchBalances$c({
1782
1781
  networkId,
1783
- addressesByToken,
1782
+ tokensWithAddresses: tokensWithAddresses,
1784
1783
  connector
1785
1784
  });
1786
1785
  if (abortController.signal.aborted) return;
1787
1786
  subscriber.next(balances);
1788
- setTimeout(poll, SUBSCRIPTION_INTERVAL$8);
1787
+ setTimeout(poll, SUBSCRIPTION_INTERVAL$7);
1789
1788
  } catch (error) {
1790
1789
  log.error("Error", {
1791
1790
  module: MODULE_TYPE$8,
1792
1791
  networkId,
1793
- addressesByToken,
1792
+ addressesByToken: tokensWithAddresses,
1794
1793
  error
1795
1794
  });
1796
1795
  subscriber.error(error);
@@ -1828,16 +1827,16 @@ const PLATFORM$7 = EvmNativeTokenSchema.shape.platform.value;
1828
1827
 
1829
1828
  const fetchBalances$b = async ({
1830
1829
  networkId,
1831
- addressesByToken,
1830
+ tokensWithAddresses,
1832
1831
  connector
1833
1832
  }) => {
1834
1833
  const client = await connector.getPublicClientForEvmNetwork(networkId);
1835
1834
  if (!client) throw new Error(`Could not get rpc provider for evm network ${networkId}`);
1836
- for (const [token, addresses] of addressesByToken) {
1835
+ for (const [token, addresses] of tokensWithAddresses) {
1837
1836
  if (token.type !== MODULE_TYPE$7 || token.networkId !== networkId) throw new Error(`Invalid token type or networkId for EVM ERC20 balance module: ${token.type} on ${token.networkId}`);
1838
1837
  for (const address of addresses) if (!isEthereumAddress(address)) throw new Error(`Invalid ethereum address for EVM ERC20 balance module: ${address} for token ${token.id}`);
1839
1838
  }
1840
- const balanceDefs = getBalanceDefs(addressesByToken);
1839
+ const balanceDefs = getBalanceDefs(tokensWithAddresses);
1841
1840
  if (client.chain?.contracts?.multicall3 && balanceDefs.length > 1) {
1842
1841
  const multicall3 = client.chain.contracts.multicall3;
1843
1842
  return fetchWithMulticall(client, balanceDefs, multicall3.address);
@@ -1981,10 +1980,10 @@ const getTransferCallData$7 = ({
1981
1980
  };
1982
1981
  };
1983
1982
 
1984
- const SUBSCRIPTION_INTERVAL$7 = 6_000;
1983
+ const SUBSCRIPTION_INTERVAL$6 = 6_000;
1985
1984
  const subscribeBalances$7 = ({
1986
1985
  networkId,
1987
- addressesByToken,
1986
+ tokensWithAddresses,
1988
1987
  connector
1989
1988
  }) => {
1990
1989
  return new Observable(subscriber => {
@@ -1994,17 +1993,17 @@ const subscribeBalances$7 = ({
1994
1993
  if (abortController.signal.aborted) return;
1995
1994
  const balances = await fetchBalances$b({
1996
1995
  networkId,
1997
- addressesByToken,
1996
+ tokensWithAddresses: tokensWithAddresses,
1998
1997
  connector
1999
1998
  });
2000
1999
  if (abortController.signal.aborted) return;
2001
2000
  subscriber.next(balances);
2002
- setTimeout(poll, SUBSCRIPTION_INTERVAL$7);
2001
+ setTimeout(poll, SUBSCRIPTION_INTERVAL$6);
2003
2002
  } catch (error) {
2004
2003
  log.error("Error", {
2005
2004
  module: MODULE_TYPE$7,
2006
2005
  networkId,
2007
- addressesByToken,
2006
+ addressesByToken: tokensWithAddresses,
2008
2007
  error
2009
2008
  });
2010
2009
  subscriber.error(error);
@@ -2037,16 +2036,16 @@ const PLATFORM$6 = EvmUniswapV2TokenSchema.shape.platform.value;
2037
2036
 
2038
2037
  const fetchBalances$a = async ({
2039
2038
  networkId,
2040
- addressesByToken,
2039
+ tokensWithAddresses,
2041
2040
  connector
2042
2041
  }) => {
2043
2042
  const client = await connector.getPublicClientForEvmNetwork(networkId);
2044
2043
  if (!client) throw new Error(`Could not get rpc provider for evm network ${networkId}`);
2045
- for (const [token, addresses] of addressesByToken) {
2044
+ for (const [token, addresses] of tokensWithAddresses) {
2046
2045
  if (token.type !== MODULE_TYPE$6 || token.networkId !== networkId) throw new Error(`Invalid token type or networkId for EVM ERC20 balance module: ${token.type} on ${token.networkId}`);
2047
2046
  for (const address of addresses) if (!isEthereumAddress(address)) throw new Error(`Invalid ethereum address for EVM ERC20 balance module: ${address} for token ${token.id}`);
2048
2047
  }
2049
- const balanceDefs = getBalanceDefs(addressesByToken);
2048
+ const balanceDefs = getBalanceDefs(tokensWithAddresses);
2050
2049
  if (client.chain?.contracts?.erc20Aggregator && balanceDefs.length > 1) {
2051
2050
  const erc20Aggregator = client.chain.contracts.erc20Aggregator;
2052
2051
  return fetchWithAggregator(client, balanceDefs, erc20Aggregator.address);
@@ -2314,10 +2313,10 @@ const getTransferCallData$6 = ({
2314
2313
  };
2315
2314
  };
2316
2315
 
2317
- const SUBSCRIPTION_INTERVAL$6 = 6_000;
2316
+ const SUBSCRIPTION_INTERVAL$5 = 6_000;
2318
2317
  const subscribeBalances$6 = ({
2319
2318
  networkId,
2320
- addressesByToken,
2319
+ tokensWithAddresses,
2321
2320
  connector
2322
2321
  }) => {
2323
2322
  return new Observable(subscriber => {
@@ -2327,17 +2326,17 @@ const subscribeBalances$6 = ({
2327
2326
  if (abortController.signal.aborted) return;
2328
2327
  const balances = await fetchBalances$a({
2329
2328
  networkId,
2330
- addressesByToken,
2329
+ tokensWithAddresses: tokensWithAddresses,
2331
2330
  connector
2332
2331
  });
2333
2332
  if (abortController.signal.aborted) return;
2334
2333
  subscriber.next(balances);
2335
- setTimeout(poll, SUBSCRIPTION_INTERVAL$6);
2334
+ setTimeout(poll, SUBSCRIPTION_INTERVAL$5);
2336
2335
  } catch (error) {
2337
2336
  log.error("Error", {
2338
2337
  module: MODULE_TYPE$6,
2339
2338
  networkId,
2340
- addressesByToken,
2339
+ addressesByToken: tokensWithAddresses,
2341
2340
  error
2342
2341
  });
2343
2342
  subscriber.error(error);
@@ -3459,13 +3458,13 @@ const decompress = data => {
3459
3458
 
3460
3459
  const fetchBalances$6 = async ({
3461
3460
  networkId,
3462
- addressesByToken,
3461
+ tokensWithAddresses,
3463
3462
  connector,
3464
3463
  miniMetadata
3465
3464
  }) => {
3466
- const balanceDefs = getBalanceDefs(addressesByToken);
3465
+ const balanceDefs = getBalanceDefs(tokensWithAddresses);
3467
3466
  if (!miniMetadata?.data) {
3468
- log.warn("MiniMetadata is required for fetching balances");
3467
+ log.warn(`MiniMetadata is required for fetching ${MODULE_TYPE$5} balances on ${networkId}.`);
3469
3468
  return {
3470
3469
  success: [],
3471
3470
  errors: balanceDefs.map(def => ({
@@ -3835,10 +3834,10 @@ const getTransferAllEncodedArgs$2 = (assetId, to, codec) => {
3835
3834
  })]);
3836
3835
  };
3837
3836
 
3838
- const SUBSCRIPTION_INTERVAL$5 = 6_000;
3837
+ const SUBSCRIPTION_INTERVAL$4 = 6_000;
3839
3838
  const subscribeBalances$5 = ({
3840
3839
  networkId,
3841
- addressesByToken,
3840
+ tokensWithAddresses,
3842
3841
  connector,
3843
3842
  miniMetadata
3844
3843
  }) => {
@@ -3852,19 +3851,19 @@ const subscribeBalances$5 = ({
3852
3851
  if (abortController.signal.aborted) return;
3853
3852
  const balances = await fetchBalances$6({
3854
3853
  networkId,
3855
- addressesByToken,
3854
+ tokensWithAddresses: tokensWithAddresses,
3856
3855
  connector,
3857
3856
  miniMetadata
3858
3857
  });
3859
3858
  if (abortController.signal.aborted) return;
3860
3859
  subscriber.next(balances);
3861
- setTimeout(poll, SUBSCRIPTION_INTERVAL$5);
3860
+ setTimeout(poll, SUBSCRIPTION_INTERVAL$4);
3862
3861
  } catch (error) {
3863
3862
  log.error("Error", {
3864
3863
  module: MODULE_TYPE$5,
3865
3864
  networkId,
3866
3865
  miniMetadata,
3867
- addressesByToken,
3866
+ addressesByToken: tokensWithAddresses,
3868
3867
  error
3869
3868
  });
3870
3869
  subscriber.error(error);
@@ -3898,13 +3897,13 @@ const PLATFORM$4 = SubForeignAssetsTokenSchema.shape.platform.value;
3898
3897
 
3899
3898
  const fetchBalances$5 = async ({
3900
3899
  networkId,
3901
- addressesByToken,
3900
+ tokensWithAddresses,
3902
3901
  connector,
3903
3902
  miniMetadata
3904
3903
  }) => {
3905
- const balanceDefs = getBalanceDefs(addressesByToken);
3904
+ const balanceDefs = getBalanceDefs(tokensWithAddresses);
3906
3905
  if (!miniMetadata?.data) {
3907
- log.warn("MiniMetadata is required for fetching balances");
3906
+ log.warn(`MiniMetadata is required for fetching ${MODULE_TYPE$4} balances on ${networkId}.`);
3908
3907
  return {
3909
3908
  success: [],
3910
3909
  errors: balanceDefs.map(def => ({
@@ -4233,10 +4232,10 @@ const getTransferAllEncodedArgs$1 = (onChainId, to, codec) => {
4233
4232
  })]);
4234
4233
  };
4235
4234
 
4236
- const SUBSCRIPTION_INTERVAL$4 = 6_000;
4235
+ const SUBSCRIPTION_INTERVAL$3 = 6_000;
4237
4236
  const subscribeBalances$4 = ({
4238
4237
  networkId,
4239
- addressesByToken,
4238
+ tokensWithAddresses,
4240
4239
  connector,
4241
4240
  miniMetadata
4242
4241
  }) => {
@@ -4250,19 +4249,19 @@ const subscribeBalances$4 = ({
4250
4249
  if (abortController.signal.aborted) return;
4251
4250
  const balances = await fetchBalances$5({
4252
4251
  networkId,
4253
- addressesByToken,
4252
+ tokensWithAddresses: tokensWithAddresses,
4254
4253
  connector,
4255
4254
  miniMetadata
4256
4255
  });
4257
4256
  if (abortController.signal.aborted) return;
4258
4257
  subscriber.next(balances);
4259
- setTimeout(poll, SUBSCRIPTION_INTERVAL$4);
4258
+ setTimeout(poll, SUBSCRIPTION_INTERVAL$3);
4260
4259
  } catch (error) {
4261
4260
  log.error("Error", {
4262
4261
  module: MODULE_TYPE$4,
4263
4262
  networkId,
4264
4263
  miniMetadata,
4265
- addressesByToken,
4264
+ addressesByToken: tokensWithAddresses,
4266
4265
  error
4267
4266
  });
4268
4267
  subscriber.error(error);
@@ -4326,13 +4325,13 @@ const tryGetConstantValue = (metadataRpc, pallet, constant) => {
4326
4325
 
4327
4326
  const fetchBalances$4 = async ({
4328
4327
  networkId,
4329
- addressesByToken,
4328
+ tokensWithAddresses,
4330
4329
  connector,
4331
4330
  miniMetadata
4332
4331
  }) => {
4333
- const balanceDefs = getBalanceDefs(addressesByToken);
4332
+ const balanceDefs = getBalanceDefs(tokensWithAddresses);
4334
4333
  if (!miniMetadata?.data) {
4335
- log.warn("MiniMetadata is required for fetching balances");
4334
+ log.warn(`MiniMetadata is required for fetching ${MODULE_TYPE$3} balances on ${networkId}.`);
4336
4335
  return {
4337
4336
  success: [],
4338
4337
  errors: balanceDefs.map(def => ({
@@ -4377,7 +4376,7 @@ const fetchBalances$4 = async ({
4377
4376
  })).filter(b => b.onChainId !== undefined);
4378
4377
  });
4379
4378
  const balancesByKey = keyBy(fetchedBalances, b => `${b.address}:${b.onChainId}`);
4380
- const success = addressesByToken.reduce((acc, [token, addresses]) => {
4379
+ const success = tokensWithAddresses.reduce((acc, [token, addresses]) => {
4381
4380
  if (token.type === MODULE_TYPE$3) for (const address of addresses) {
4382
4381
  const rawBalance = balancesByKey[`${address}:${token.onChainId}`];
4383
4382
 
@@ -4579,10 +4578,10 @@ const getTransferCallData$3 = ({
4579
4578
  };
4580
4579
  };
4581
4580
 
4582
- const SUBSCRIPTION_INTERVAL$3 = 6_000;
4581
+ const SUBSCRIPTION_INTERVAL$2 = 6_000;
4583
4582
  const subscribeBalances$3 = ({
4584
4583
  networkId,
4585
- addressesByToken,
4584
+ tokensWithAddresses,
4586
4585
  connector,
4587
4586
  miniMetadata
4588
4587
  }) => {
@@ -4596,19 +4595,19 @@ const subscribeBalances$3 = ({
4596
4595
  if (abortController.signal.aborted) return;
4597
4596
  const balances = await fetchBalances$4({
4598
4597
  networkId,
4599
- addressesByToken,
4598
+ tokensWithAddresses: tokensWithAddresses,
4600
4599
  connector,
4601
4600
  miniMetadata
4602
4601
  });
4603
4602
  if (abortController.signal.aborted) return;
4604
4603
  subscriber.next(balances);
4605
- setTimeout(poll, SUBSCRIPTION_INTERVAL$3);
4604
+ setTimeout(poll, SUBSCRIPTION_INTERVAL$2);
4606
4605
  } catch (error) {
4607
4606
  log.error("Error", {
4608
4607
  module: MODULE_TYPE$3,
4609
4608
  networkId,
4610
4609
  miniMetadata,
4611
- addressesByToken,
4610
+ addressesByToken: tokensWithAddresses,
4612
4611
  error
4613
4612
  });
4614
4613
  subscriber.error(error);
@@ -4634,140 +4633,54 @@ const SubHydrationBalanceModule = {
4634
4633
  const MODULE_TYPE$2 = SubNativeTokenSchema.shape.type.value;
4635
4634
  const PLATFORM$2 = SubNativeTokenSchema.shape.platform.value;
4636
4635
 
4637
- /**
4638
- * Pass some these into an `RpcStateQueryHelper` in order to easily batch multiple state queries into the one rpc call.
4639
- */
4640
-
4641
- const fetchQueriesPack = async (connector, networkId, queries) => {
4636
+ const fetchRpcQueryPack = async (connector, networkId, queries) => {
4642
4637
  const allStateKeys = queries.flatMap(({
4643
4638
  stateKeys
4644
4639
  }) => stateKeys).filter(isNotNil);
4645
4640
 
4646
- // doing a query with only null keys would throw an error => return early
4641
+ // doing a query without keys would throw an error => return early
4647
4642
  if (!allStateKeys.length) return queries.map(({
4648
4643
  stateKeys,
4649
4644
  decodeResult
4650
4645
  }) => decodeResult(stateKeys.map(() => null)));
4651
- const response = await connector.send(networkId, "state_queryStorageAt", [allStateKeys]);
4652
- const results = queries.reduce((acc, {
4646
+ const [result] = await connector.send(networkId, "state_queryStorageAt", [allStateKeys]);
4647
+ return decodeRpcQueryPack(queries, result);
4648
+ };
4649
+ const getRpcQueryPack$ = (connector, networkId, queries, timeout = false) => {
4650
+ const allStateKeys = queries.flatMap(({
4651
+ stateKeys
4652
+ }) => stateKeys).filter(isNotNil);
4653
+
4654
+ // doing a query without keys would throw an error => return early
4655
+ if (!allStateKeys.length) return of(queries.map(({
4656
+ stateKeys,
4657
+ decodeResult
4658
+ }) => decodeResult(stateKeys.map(() => null))));
4659
+ return new Observable(subscriber => {
4660
+ const promUnsub = connector.subscribe(networkId, "state_subscribeStorage", "state_storage", [allStateKeys], (error, result) => {
4661
+ if (error) subscriber.error(error);else subscriber.next(decodeRpcQueryPack(queries, result));
4662
+ }, timeout);
4663
+ return () => {
4664
+ promUnsub.then(unsub => unsub("state_unsubscribeStorage"));
4665
+ };
4666
+ });
4667
+ };
4668
+ const decodeRpcQueryPack = (queries, result) => {
4669
+ return queries.reduce((acc, {
4653
4670
  stateKeys,
4654
4671
  decodeResult
4655
4672
  }) => {
4656
4673
  const changes = stateKeys.map(stateKey => {
4657
4674
  if (!stateKey) return null;
4658
- const change = response[0].changes.find(([key]) => key === stateKey);
4675
+ const change = result.changes.find(([key]) => key === stateKey);
4659
4676
  if (!change) return null;
4660
4677
  return change[1];
4661
4678
  });
4662
4679
  acc.push(decodeResult(changes));
4663
4680
  return acc;
4664
4681
  }, []);
4665
- return results;
4666
4682
  };
4667
4683
 
4668
- /**
4669
- * Used by a variety of balance modules to help batch multiple state queries into the one rpc call.
4670
- */
4671
- // export class RpcStateQueriesHelper<T> {
4672
- // #connector: ChainConnector
4673
- // #queries: Array<RpcStateQueries<T>>
4674
-
4675
- // constructor(connector: ChainConnector, queries: Array<RpcStateQueries<T>>) {
4676
- // this.#connector = connector
4677
- // this.#queries = queries
4678
- // }
4679
-
4680
- // async subscribe(
4681
- // networkId: DotNetworkId,
4682
- // callback: SubscriptionCallback<T[]>,
4683
- // timeout: number | false = false,
4684
- // subscribeMethod = "state_subscribeStorage",
4685
- // responseMethod = "state_storage",
4686
- // unsubscribeMethod = "state_unsubscribeStorage",
4687
- // ): Promise<UnsubscribeFn> {
4688
- // const params = [this.#queries.flatMap(({ stateKeys }) => stateKeys)]
4689
-
4690
- // const unsub = this.#connector.subscribe(
4691
- // networkId,
4692
- // subscribeMethod,
4693
- // responseMethod,
4694
- // params,
4695
- // (error, result) => {
4696
- // error
4697
- // ? callback(error)
4698
- // : callback(null, this.#distributeChangesToQueryDecoders.call(this, chainId, result))
4699
- // },
4700
- // timeout,
4701
- // )
4702
-
4703
- // const subscriptions = queries.map(([chainId, queries]) => {
4704
- // const params = [queries.map(({ stateKey }) => stateKey)]
4705
-
4706
- // const unsub = this.#connector.subscribe(
4707
- // networkId,
4708
- // subscribeMethod,
4709
- // responseMethod,
4710
- // params,
4711
- // (error, result) => {
4712
- // error
4713
- // ? callback(error)
4714
- // : callback(null, this.#distributeChangesToQueryDecoders.call(this, chainId, result))
4715
- // },
4716
- // timeout,
4717
- // )
4718
-
4719
- // return () => unsub.then((unsubscribe) => unsubscribe(unsubscribeMethod))
4720
- // })
4721
-
4722
- // return () => subscriptions.forEach((unsubscribe) => unsubscribe())
4723
- // }
4724
-
4725
- // async fetch(method = "state_queryStorageAt"): Promise<T[]> {
4726
- // const queriesByChain = groupBy(this.#queries, "chainId")
4727
-
4728
- // const resultsByChain = await Promise.all(
4729
- // Object.entries(queriesByChain).map(async ([chainId, queries]) => {
4730
- // const params = [queries.map(({ stateKey }) => stateKey)]
4731
-
4732
- // const result = (await this.#connector.send(chainId, method, params))[0]
4733
- // return this.#distributeChangesToQueryDecoders.call(this, chainId, result)
4734
- // }),
4735
- // )
4736
-
4737
- // return resultsByChain.flatMap((result) => result)
4738
- // }
4739
-
4740
- // #distributeChangesToQueryDecoders(chainId: DotNetworkId, result: unknown): T[] {
4741
- // if (typeof result !== "object" || result === null) return []
4742
- // if (!hasOwnProperty(result, "changes") || typeof result.changes !== "object") return []
4743
- // if (!Array.isArray(result.changes)) return []
4744
-
4745
- // return result.changes.flatMap(([reference, change]: [unknown, unknown]): [T] | [] => {
4746
- // if (typeof reference !== "string") {
4747
- // log.warn(`Received non-string reference in RPC result: ${reference}`)
4748
- // return []
4749
- // }
4750
-
4751
- // if (typeof change !== "string" && change !== null) {
4752
- // log.warn(`Received non-string and non-null change in RPC result: ${reference} | ${change}`)
4753
- // return []
4754
- // }
4755
-
4756
- // const query = this.#queries.find(
4757
- // ({ chainId: cId, stateKey }) => cId === chainId && stateKey === reference,
4758
- // )
4759
- // if (!query) {
4760
- // log.warn(
4761
- // `Failed to find query:\n${reference} in\n${this.#queries.map(({ stateKey }) => stateKey)}`,
4762
- // )
4763
- // return []
4764
- // }
4765
-
4766
- // return [query.decodeResult(change)]
4767
- // })
4768
- // }
4769
- // }
4770
-
4771
4684
  const SUBTENSOR_ROOT_NETUID$1 = 0;
4772
4685
  const SUBTENSOR_MIN_STAKE_AMOUNT_PLANK$1 = 1000000n;
4773
4686
  const TAO_DECIMALS$1 = 9n;
@@ -5481,13 +5394,13 @@ const getNomPoolStateKeys = (coders, nomPoolMemberInfo, extra) => {
5481
5394
 
5482
5395
  const fetchBalances$3 = async ({
5483
5396
  networkId,
5484
- addressesByToken,
5397
+ tokensWithAddresses,
5485
5398
  connector,
5486
5399
  miniMetadata
5487
5400
  }) => {
5488
- const balanceDefs = getBalanceDefs(addressesByToken);
5401
+ const balanceDefs = getBalanceDefs(tokensWithAddresses);
5489
5402
  if (!miniMetadata?.data) {
5490
- log.warn("MiniMetadata is required for fetching balances");
5403
+ log.warn(`MiniMetadata is required for fetching ${MODULE_TYPE$2} balances on ${networkId}.`);
5491
5404
  return {
5492
5405
  success: [],
5493
5406
  errors: balanceDefs.map(def => ({
@@ -5519,12 +5432,12 @@ const fetchBalances$3 = async ({
5519
5432
  }))
5520
5433
  };
5521
5434
  }
5522
- const queries = buildBaseQueries(networkId, balanceDefs, miniMetadata);
5523
- const partialBalances = await fetchQueriesPack(connector, networkId, queries);
5435
+ const baseQueries = buildBaseQueries(networkId, balanceDefs, miniMetadata);
5436
+ const partialBalances = await fetchRpcQueryPack(connector, networkId, baseQueries);
5524
5437
 
5525
5438
  // now for each balance that includes nomPoolStaking, we need to fetch the metadata for the pool
5526
5439
  const nomPoolQueries = buildNomPoolQueries(networkId, partialBalances, miniMetadata);
5527
- const balances = await fetchQueriesPack(connector, networkId, nomPoolQueries);
5440
+ const balances = await fetchRpcQueryPack(connector, networkId, nomPoolQueries);
5528
5441
 
5529
5442
  // TODO ⚠️ dedupe locks
5530
5443
 
@@ -5760,46 +5673,32 @@ const getTransferAllEncodedArgs = (to, codec) => {
5760
5673
  })]);
5761
5674
  };
5762
5675
 
5763
- const SUBSCRIPTION_INTERVAL$2 = 6_000;
5764
5676
  const subscribeBalances$2 = ({
5765
5677
  networkId,
5766
- addressesByToken,
5678
+ tokensWithAddresses,
5767
5679
  connector,
5768
5680
  miniMetadata
5769
5681
  }) => {
5770
- return new Observable(subscriber => {
5771
- const abortController = new AbortController();
5772
-
5773
- // on hydration balances are fetched using a runtimeApi, which can't be subscribed to.
5774
- // => poll values for each block
5775
- const poll = async () => {
5776
- try {
5777
- if (abortController.signal.aborted) return;
5778
- const balances = await fetchBalances$3({
5779
- networkId,
5780
- addressesByToken,
5781
- connector,
5782
- miniMetadata
5783
- });
5784
- if (abortController.signal.aborted) return;
5785
- subscriber.next(balances);
5786
- setTimeout(poll, SUBSCRIPTION_INTERVAL$2);
5787
- } catch (error) {
5788
- log.error("Error", {
5789
- module: MODULE_TYPE$2,
5790
- networkId,
5791
- miniMetadata,
5792
- addressesByToken,
5793
- error
5794
- });
5795
- subscriber.error(error);
5796
- }
5797
- };
5798
- poll();
5799
- return () => {
5800
- abortController.abort();
5682
+ // could be use as shared observable key if we decide to cache the sub
5683
+ const balanceDefs = getBalanceDefs(tokensWithAddresses);
5684
+ const baseQueries = buildBaseQueries(networkId, balanceDefs, miniMetadata);
5685
+ const baseBalances$ = getRpcQueryPack$(connector, networkId, baseQueries).pipe(switchMap(partialBalances => {
5686
+ // now for each balance that includes nomPoolStaking, we need to fetch the metadata for the pool
5687
+ const nomPoolQueries = buildNomPoolQueries(networkId, partialBalances, miniMetadata);
5688
+ return getRpcQueryPack$(connector, networkId, nomPoolQueries);
5689
+ }));
5690
+ const subtensorBalancesByAddress$ = getSubtensorStakingBalances$(connector, networkId, balanceDefs, miniMetadata);
5691
+ return combineLatest([baseBalances$, subtensorBalancesByAddress$]).pipe(map(([baseBalances, subtensorBalancesByAddress]) => {
5692
+ // add subtensor balances to base balances
5693
+ for (const [address, subtensorBalances] of toPairs(subtensorBalancesByAddress)) {
5694
+ const balance = baseBalances.find(b => b.address === address);
5695
+ if (balance?.values) balance.values.push(...subtensorBalances);
5696
+ }
5697
+ return {
5698
+ success: baseBalances,
5699
+ errors: []
5801
5700
  };
5802
- }).pipe(distinctUntilChanged(isEqual));
5701
+ }));
5803
5702
  };
5804
5703
 
5805
5704
  const SubNativeBalanceModule = {
@@ -6980,10 +6879,10 @@ var psp22Abi = {
6980
6879
 
6981
6880
  const fetchBalances$2 = async ({
6982
6881
  networkId,
6983
- addressesByToken,
6882
+ tokensWithAddresses,
6984
6883
  connector
6985
6884
  }) => {
6986
- const balanceDefs = getBalanceDefs(addressesByToken);
6885
+ const balanceDefs = getBalanceDefs(tokensWithAddresses);
6987
6886
  if (!balanceDefs.length) return {
6988
6887
  success: [],
6989
6888
  errors: []
@@ -7173,7 +7072,7 @@ const getTransferCallData$1 = async ({
7173
7072
  const SUBSCRIPTION_INTERVAL$1 = 6_000;
7174
7073
  const subscribeBalances$1 = ({
7175
7074
  networkId,
7176
- addressesByToken,
7075
+ tokensWithAddresses,
7177
7076
  connector,
7178
7077
  miniMetadata
7179
7078
  }) => {
@@ -7187,7 +7086,7 @@ const subscribeBalances$1 = ({
7187
7086
  if (abortController.signal.aborted) return;
7188
7087
  const balances = await fetchBalances$2({
7189
7088
  networkId,
7190
- addressesByToken,
7089
+ tokensWithAddresses: tokensWithAddresses,
7191
7090
  connector,
7192
7091
  miniMetadata
7193
7092
  });
@@ -7199,7 +7098,7 @@ const subscribeBalances$1 = ({
7199
7098
  module: MODULE_TYPE$1,
7200
7099
  networkId,
7201
7100
  miniMetadata,
7202
- addressesByToken,
7101
+ addressesByToken: tokensWithAddresses,
7203
7102
  error
7204
7103
  });
7205
7104
  subscriber.error(error);
@@ -7233,13 +7132,13 @@ const PLATFORM = SubTokensTokenSchema.shape.platform.value;
7233
7132
 
7234
7133
  const fetchBalances$1 = async ({
7235
7134
  networkId,
7236
- addressesByToken,
7135
+ tokensWithAddresses,
7237
7136
  connector,
7238
7137
  miniMetadata
7239
7138
  }) => {
7240
- const balanceDefs = getBalanceDefs(addressesByToken);
7139
+ const balanceDefs = getBalanceDefs(tokensWithAddresses);
7241
7140
  if (!miniMetadata?.data) {
7242
- log.warn("MiniMetadata is required for fetching balances");
7141
+ log.warn(`MiniMetadata is required for fetching ${MODULE_TYPE} balances on ${networkId}.`);
7243
7142
  return {
7244
7143
  success: [],
7245
7144
  errors: balanceDefs.map(def => ({
@@ -7563,7 +7462,7 @@ const getCallDataOptions = (to, token, value, type, config) => {
7563
7462
  const SUBSCRIPTION_INTERVAL = 6_000;
7564
7463
  const subscribeBalances = ({
7565
7464
  networkId,
7566
- addressesByToken,
7465
+ tokensWithAddresses,
7567
7466
  connector,
7568
7467
  miniMetadata
7569
7468
  }) => {
@@ -7577,7 +7476,7 @@ const subscribeBalances = ({
7577
7476
  if (abortController.signal.aborted) return;
7578
7477
  const balances = await fetchBalances$1({
7579
7478
  networkId,
7580
- addressesByToken,
7479
+ tokensWithAddresses: tokensWithAddresses,
7581
7480
  connector,
7582
7481
  miniMetadata
7583
7482
  });
@@ -7589,7 +7488,7 @@ const subscribeBalances = ({
7589
7488
  module: MODULE_TYPE,
7590
7489
  networkId,
7591
7490
  miniMetadata,
7592
- addressesByToken,
7491
+ addressesByToken: tokensWithAddresses,
7593
7492
  error
7594
7493
  });
7595
7494
  subscriber.error(error);
@@ -7693,6 +7592,7 @@ const getMiniMetadatas = async (chainConnector, chaindataProvider, networkId, sp
7693
7592
  if (CACHE.has(networkId)) return CACHE.get(networkId);
7694
7593
  if (!signal) log.warn("[miniMetadata] getMiniMetadatas called without signal, this may hang the updates", new Error("No signal provided") // this will show the stack trace
7695
7594
  );
7595
+ if (specVersion === undefined) specVersion = await getSpecVersion(chainConnector, networkId);
7696
7596
  const pResult = POOL.add(() => fetchMiniMetadatas(chainConnector, chaindataProvider, networkId, specVersion), {
7697
7597
  signal
7698
7598
  });
@@ -7708,42 +7608,21 @@ const getMiniMetadatas = async (chainConnector, chaindataProvider, networkId, sp
7708
7608
  CACHE.delete(networkId);
7709
7609
  }
7710
7610
  };
7711
- const DotBalanceModuleTypeSchema = z.keyof(DotNetworkBalancesConfigSchema);
7712
7611
  const fetchMiniMetadatas = async (chainConnector, chaindataProvider, chainId, specVersion, signal) => {
7713
7612
  const start = performance.now();
7714
7613
  log.info("[miniMetadata] fetching minimetadatas for %s", chainId);
7715
7614
  try {
7615
+ const network = await chaindataProvider.getNetworkById(chainId, "polkadot");
7616
+ if (!network) throw new Error(`Network ${chainId} not found in chaindataProvider`);
7617
+ signal?.throwIfAborted();
7716
7618
  const metadataRpc = await getMetadataRpc(chainConnector, chainId);
7717
7619
  signal?.throwIfAborted();
7718
- const chainConnectors = {
7719
- substrate: chainConnector,
7720
- evm: {} // wont be used but workarounds error for module creation
7721
- };
7722
- const modules = defaultBalanceModules.map(mod => mod({
7723
- chainConnectors,
7724
- chaindataProvider
7725
- })).filter(mod => DotBalanceModuleTypeSchema.safeParse(mod.type).success);
7726
- return Promise.all(modules.map(async mod => {
7727
- const source = mod.type;
7728
- const chain = await chaindataProvider.getNetworkById(chainId, "polkadot");
7729
- const balancesConfig = chain?.balancesConfig?.[mod.type];
7730
- const chainMeta = await mod.fetchSubstrateChainMeta(chainId, balancesConfig,
7731
- // TODO better typing
7732
- metadataRpc);
7733
- return {
7734
- id: deriveMiniMetadataId({
7735
- source,
7736
- chainId,
7737
- specVersion
7738
- }),
7739
- source,
7740
- chainId,
7741
- specVersion,
7742
- version: MINIMETADATA_VERSION,
7743
- data: chainMeta?.miniMetadata ?? null,
7744
- extra: chainMeta?.extra ?? null
7745
- };
7746
- }));
7620
+ return Promise.all(BALANCE_MODULES.filter(m => m.platform === "polkadot").map(mod => mod.getMiniMetadata({
7621
+ networkId: chainId,
7622
+ metadataRpc,
7623
+ specVersion,
7624
+ config: network.balancesConfig?.[mod.type]
7625
+ })));
7747
7626
  } finally {
7748
7627
  log.debug("[miniMetadata] updated miniMetadatas for %s in %sms", chainId, (performance.now() - start).toFixed(2));
7749
7628
  }
@@ -10454,4 +10333,132 @@ async function buildQueries(chainConnector, chaindataProvider, addressesByToken,
10454
10333
  const defaultBalanceModules = [EvmErc20Module, EvmNativeModule, EvmUniswapV2Module, SubAssetsModule, SubForeignAssetsModule, SubNativeModule, SubPsp22Module, SubTokensModule];
10455
10334
  const BALANCE_MODULES = [SubNativeBalanceModule, SubAssetsBalanceModule, SubHydrationBalanceModule, SubForeignAssetsBalanceModule, SubPsp22BalanceModule, SubTokensBalanceModule, EvmErc20BalanceModule, EvmUniswapV2BalanceModule, EvmNativeBalanceModule];
10456
10335
 
10457
- export { BALANCE_MODULES, Balance, BalanceFormatter, BalanceValueGetter, Balances, Change24hCurrencyFormatter, DefaultBalanceModule, EvmErc20BalanceModule, EvmErc20TokenConfigSchema, EvmNativeBalanceModule, EvmNativeTokenConfigSchema, EvmUniswapV2BalanceModule, EvmUniswapV2TokenConfigSchema, FiatSumBalancesFormatter, ONE_ALPHA_TOKEN$1 as ONE_ALPHA_TOKEN, PlanckSumBalancesFormatter, RpcStateQueryHelper, SCALE_FACTOR$1 as SCALE_FACTOR, SUBTENSOR_MIN_STAKE_AMOUNT_PLANK$1 as SUBTENSOR_MIN_STAKE_AMOUNT_PLANK, SUBTENSOR_ROOT_NETUID$1 as SUBTENSOR_ROOT_NETUID, SubAssetsBalanceModule, SubAssetsTokenConfigSchema, SubForeignAssetsBalanceModule, SubForeignAssetsTokenConfigSchema, SubHydrationBalanceModule, SubHydrationTokenConfigSchema, SubNativeBalanceModule, SubNativeMiniMetadataExtraSchema, SubNativeModuleConfigSchema, SubNativeTokenConfigSchema, SubPsp22BalanceModule, SubPsp22TokenConfigSchema, SubTokensBalanceModule, SubTokensMiniMetadataExtraSchema, SubTokensModuleConfigSchema, SubTokensTokenConfigSchema, SumBalancesFormatter, TalismanBalancesDatabase, abiMulticall, balances, buildNetworkStorageCoders, buildStorageCoders, calculateAlphaPrice$1 as calculateAlphaPrice, calculateTaoAmountFromAlpha$1 as calculateTaoAmountFromAlpha, calculateTaoFromDynamicInfo$1 as calculateTaoFromDynamicInfo, compress, configureStore, db, decodeOutput, decompress, defaultBalanceModules, deriveMiniMetadataId, detectTransferMethod, erc20BalancesAggregatorAbi, excludeFromFeePayableLocks, excludeFromTransferableAmount, filterBaseLocks, filterMirrorTokens, getBalanceId, getLockTitle, getLockedType$1 as getLockedType, getUniqueChainIds, getValueId, includeInTotalExtraAmount, makeContractCaller, uniswapV2PairAbi };
10336
+ const DEFAULT_STORAGE = {
10337
+ balances: [],
10338
+ miniMetadatas: []
10339
+ };
10340
+ class BalancesProvider {
10341
+ #chaindataProvider;
10342
+ #chainConnectors;
10343
+ #storage;
10344
+ constructor(chaindataProvider, chainConnectors, storage = DEFAULT_STORAGE) {
10345
+ this.#chaindataProvider = chaindataProvider;
10346
+ this.#chainConnectors = chainConnectors;
10347
+ this.#storage = new BehaviorSubject({
10348
+ balances: keyBy(storage.balances.filter(isNotNil), b => getBalanceId(b)),
10349
+ miniMetadatas: keyBy(storage.miniMetadatas.filter(isNotNil), m => m.id)
10350
+ });
10351
+ }
10352
+ get storage$() {
10353
+ return this.#storage.pipe(map(({
10354
+ balances,
10355
+ miniMetadatas
10356
+ }) => ({
10357
+ balances: values(balances).filter(isNotNil),
10358
+ miniMetadatas: values(miniMetadatas).filter(isNotNil)
10359
+ })));
10360
+ }
10361
+ getBalances$(addressesByToken) {
10362
+ const networkIds = uniq(keys(addressesByToken).map(tokenId => parseTokenId(tokenId).networkId));
10363
+ return combineLatest(networkIds.map(networkId => this.getNetworkBalances$(networkId, addressesByToken))).pipe(map(results => {
10364
+ return {
10365
+ status: results.some(({
10366
+ status
10367
+ }) => status === "initialising") ? "initialising" : "live",
10368
+ balances: results.flatMap(result => result.balances)
10369
+ };
10370
+ }), startWith({
10371
+ status: "initialising",
10372
+ balances: this.getStoredBalances(addressesByToken)
10373
+ }), distinctUntilChanged(isEqual));
10374
+ }
10375
+ getNetworkBalances$(networkId, addressesByTokenId) {
10376
+ const network$ = this.#chaindataProvider.getNetworkById$(networkId);
10377
+ const tokensMapById$ = this.#chaindataProvider.getTokensMapById$();
10378
+ const miniMetadatas$ = this.getNetworkMiniMetadatas$(networkId);
10379
+ return combineLatest([network$, miniMetadatas$, tokensMapById$]).pipe(switchMap(([network, miniMetadatas, tokensMapById]) => {
10380
+ const tokensAndAddresses = toPairs(addressesByTokenId).map(([tokenId, addresses]) => [tokensMapById[tokenId], addresses]);
10381
+ return combineLatest(BALANCE_MODULES.filter(mod => mod.platform === network?.platform).map(mod => {
10382
+ const tokensWithAddresses = tokensAndAddresses.filter(([token]) => token.type === mod.type);
10383
+ const moduleAddressesByTokenId = fromPairs(tokensWithAddresses.map(([token, addresses]) => [token.id, addresses]));
10384
+ const miniMetadata = miniMetadatas.find(m => m.source === mod.type);
10385
+
10386
+ // all balance ids expected in result set
10387
+ const balanceIds = toPairs(moduleAddressesByTokenId).flatMap(([tokenId, addresses]) => addresses.map(address => getBalanceId({
10388
+ tokenId,
10389
+ address
10390
+ })));
10391
+ const initValue = {
10392
+ status: "initialising",
10393
+ balances: this.getStoredBalances(moduleAddressesByTokenId)
10394
+ };
10395
+ const updateStorage = results => {
10396
+ if (results.status !== "live") return;
10397
+ const storage = this.#storage.getValue();
10398
+ const balances = assign({}, storage.balances,
10399
+ // delete all balances expected in the result set. because if they are not present it means they are empty.
10400
+ fromPairs(balanceIds.map(balanceId => [balanceId, undefined])), keyBy(results.balances, b => getBalanceId(b)));
10401
+ this.#storage.next(assign({}, storage, {
10402
+ balances
10403
+ }));
10404
+ };
10405
+ switch (mod.platform) {
10406
+ case "ethereum":
10407
+ {
10408
+ if (!this.#chainConnectors.evm) return of(initValue);
10409
+ return mod.subscribeBalances({
10410
+ networkId,
10411
+ tokensWithAddresses,
10412
+ connector: this.#chainConnectors.evm
10413
+ }).pipe(map(results => ({
10414
+ status: "live",
10415
+ // exclude zero balances
10416
+ balances: results.success.filter(b => new Balance(b).total.planck > 0n)
10417
+ })), tap(updateStorage), startWith(initValue));
10418
+ }
10419
+ case "polkadot":
10420
+ if (!this.#chainConnectors.substrate || !miniMetadata) {
10421
+ log.debug("[balances] no substrate connector or miniMetadata for polkadot", mod.type);
10422
+ return of(initValue);
10423
+ }
10424
+ return mod.subscribeBalances({
10425
+ networkId,
10426
+ tokensWithAddresses,
10427
+ connector: this.#chainConnectors.substrate,
10428
+ miniMetadata: miniMetadata
10429
+ }).pipe(map(results => ({
10430
+ status: "live",
10431
+ // exclude zero balances
10432
+ balances: results.success.filter(b => new Balance(b).total.planck > 0n)
10433
+ })), tap(updateStorage), startWith(initValue));
10434
+ }
10435
+ }));
10436
+ }), map(results => {
10437
+ return {
10438
+ status: results.some(({
10439
+ status
10440
+ }) => status === "initialising") ? "initialising" : "live",
10441
+ balances: results.flatMap(result => result.balances)
10442
+ };
10443
+ }));
10444
+ }
10445
+ getNetworkMiniMetadatas$(networkId) {
10446
+ return this.#chaindataProvider.getNetworkById$(networkId).pipe(switchMap(network => isNetworkDot(network) && this.#chainConnectors.substrate ? from(getMiniMetadatas(this.#chainConnectors.substrate, this.#chaindataProvider, networkId)) : of([])));
10447
+ }
10448
+ getStoredBalances(addressesByToken) {
10449
+ const balanceDefs = toPairs(addressesByToken).flatMap(([tokenId, addresses]) => addresses.map(address => [tokenId, address]));
10450
+ return balanceDefs.map(([tokenId, address]) => this.#storage.value.balances[getBalanceId({
10451
+ address,
10452
+ tokenId
10453
+ })]).filter(isNotNil);
10454
+ }
10455
+ }
10456
+
10457
+ // const getStoredBalances = (
10458
+ // storedBalances: Record<string, IBalance>,
10459
+ // addressesByToken: Record<TokenId, Address[]>,
10460
+ // ): IBalance[] => {
10461
+
10462
+ // }
10463
+
10464
+ export { BALANCE_MODULES, Balance, BalanceFormatter, BalanceValueGetter, Balances, BalancesProvider, Change24hCurrencyFormatter, DefaultBalanceModule, EvmErc20BalanceModule, EvmErc20TokenConfigSchema, EvmNativeBalanceModule, EvmNativeTokenConfigSchema, EvmUniswapV2BalanceModule, EvmUniswapV2TokenConfigSchema, FiatSumBalancesFormatter, ONE_ALPHA_TOKEN$1 as ONE_ALPHA_TOKEN, PlanckSumBalancesFormatter, RpcStateQueryHelper, SCALE_FACTOR$1 as SCALE_FACTOR, SUBTENSOR_MIN_STAKE_AMOUNT_PLANK$1 as SUBTENSOR_MIN_STAKE_AMOUNT_PLANK, SUBTENSOR_ROOT_NETUID$1 as SUBTENSOR_ROOT_NETUID, SubAssetsBalanceModule, SubAssetsTokenConfigSchema, SubForeignAssetsBalanceModule, SubForeignAssetsTokenConfigSchema, SubHydrationBalanceModule, SubHydrationTokenConfigSchema, SubNativeBalanceModule, SubNativeMiniMetadataExtraSchema, SubNativeModuleConfigSchema, SubNativeTokenConfigSchema, SubPsp22BalanceModule, SubPsp22TokenConfigSchema, SubTokensBalanceModule, SubTokensMiniMetadataExtraSchema, SubTokensModuleConfigSchema, SubTokensTokenConfigSchema, SumBalancesFormatter, TalismanBalancesDatabase, abiMulticall, balances, buildNetworkStorageCoders, buildStorageCoders, calculateAlphaPrice$1 as calculateAlphaPrice, calculateTaoAmountFromAlpha$1 as calculateTaoAmountFromAlpha, calculateTaoFromDynamicInfo$1 as calculateTaoFromDynamicInfo, compress, configureStore, db, decodeOutput, decompress, defaultBalanceModules, deriveMiniMetadataId, detectTransferMethod, erc20BalancesAggregatorAbi, excludeFromFeePayableLocks, excludeFromTransferableAmount, filterBaseLocks, filterMirrorTokens, getBalanceId, getLockTitle, getLockedType$1 as getLockedType, getUniqueChainIds, getValueId, includeInTotalExtraAmount, makeContractCaller, uniswapV2PairAbi };