@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.
@@ -288,11 +288,10 @@ class Balances {
288
288
  }
289
289
  const getBalanceId = balance => {
290
290
  const {
291
- source,
292
291
  address,
293
292
  tokenId
294
293
  } = balance;
295
- return [source, address, tokenId].join("::");
294
+ return [address, tokenId].join("::");
296
295
  };
297
296
 
298
297
  /**
@@ -1551,16 +1550,16 @@ const getBalanceDefs = addressesByToken => {
1551
1550
 
1552
1551
  const fetchBalances$c = async ({
1553
1552
  networkId,
1554
- addressesByToken,
1553
+ tokensWithAddresses,
1555
1554
  connector
1556
1555
  }) => {
1557
1556
  const client = await connector.getPublicClientForEvmNetwork(networkId);
1558
1557
  if (!client) throw new Error(`Could not get rpc provider for evm network ${networkId}`);
1559
- for (const [token, addresses] of addressesByToken) {
1558
+ for (const [token, addresses] of tokensWithAddresses) {
1560
1559
  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}`);
1561
1560
  for (const address of addresses) if (!util.isEthereumAddress(address)) throw new Error(`Invalid ethereum address for EVM ERC20 balance module: ${address} for token ${token.id}`);
1562
1561
  }
1563
- const balanceDefs = getBalanceDefs(addressesByToken);
1562
+ const balanceDefs = getBalanceDefs(tokensWithAddresses);
1564
1563
  if (client.chain?.contracts?.erc20Aggregator && balanceDefs.length > 1) {
1565
1564
  const erc20Aggregator = client.chain.contracts.erc20Aggregator;
1566
1565
  return fetchWithAggregator$1(client, balanceDefs, erc20Aggregator.address);
@@ -1780,10 +1779,10 @@ const getTransferCallData$8 = ({
1780
1779
  };
1781
1780
  };
1782
1781
 
1783
- const SUBSCRIPTION_INTERVAL$8 = 6_000;
1782
+ const SUBSCRIPTION_INTERVAL$7 = 6_000;
1784
1783
  const subscribeBalances$8 = ({
1785
1784
  networkId,
1786
- addressesByToken,
1785
+ tokensWithAddresses,
1787
1786
  connector
1788
1787
  }) => {
1789
1788
  return new rxjs.Observable(subscriber => {
@@ -1793,17 +1792,17 @@ const subscribeBalances$8 = ({
1793
1792
  if (abortController.signal.aborted) return;
1794
1793
  const balances = await fetchBalances$c({
1795
1794
  networkId,
1796
- addressesByToken,
1795
+ tokensWithAddresses: tokensWithAddresses,
1797
1796
  connector
1798
1797
  });
1799
1798
  if (abortController.signal.aborted) return;
1800
1799
  subscriber.next(balances);
1801
- setTimeout(poll, SUBSCRIPTION_INTERVAL$8);
1800
+ setTimeout(poll, SUBSCRIPTION_INTERVAL$7);
1802
1801
  } catch (error) {
1803
1802
  log.error("Error", {
1804
1803
  module: MODULE_TYPE$8,
1805
1804
  networkId,
1806
- addressesByToken,
1805
+ addressesByToken: tokensWithAddresses,
1807
1806
  error
1808
1807
  });
1809
1808
  subscriber.error(error);
@@ -1841,16 +1840,16 @@ const PLATFORM$7 = chaindataProvider.EvmNativeTokenSchema.shape.platform.value;
1841
1840
 
1842
1841
  const fetchBalances$b = async ({
1843
1842
  networkId,
1844
- addressesByToken,
1843
+ tokensWithAddresses,
1845
1844
  connector
1846
1845
  }) => {
1847
1846
  const client = await connector.getPublicClientForEvmNetwork(networkId);
1848
1847
  if (!client) throw new Error(`Could not get rpc provider for evm network ${networkId}`);
1849
- for (const [token, addresses] of addressesByToken) {
1848
+ for (const [token, addresses] of tokensWithAddresses) {
1850
1849
  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}`);
1851
1850
  for (const address of addresses) if (!util.isEthereumAddress(address)) throw new Error(`Invalid ethereum address for EVM ERC20 balance module: ${address} for token ${token.id}`);
1852
1851
  }
1853
- const balanceDefs = getBalanceDefs(addressesByToken);
1852
+ const balanceDefs = getBalanceDefs(tokensWithAddresses);
1854
1853
  if (client.chain?.contracts?.multicall3 && balanceDefs.length > 1) {
1855
1854
  const multicall3 = client.chain.contracts.multicall3;
1856
1855
  return fetchWithMulticall(client, balanceDefs, multicall3.address);
@@ -1994,10 +1993,10 @@ const getTransferCallData$7 = ({
1994
1993
  };
1995
1994
  };
1996
1995
 
1997
- const SUBSCRIPTION_INTERVAL$7 = 6_000;
1996
+ const SUBSCRIPTION_INTERVAL$6 = 6_000;
1998
1997
  const subscribeBalances$7 = ({
1999
1998
  networkId,
2000
- addressesByToken,
1999
+ tokensWithAddresses,
2001
2000
  connector
2002
2001
  }) => {
2003
2002
  return new rxjs.Observable(subscriber => {
@@ -2007,17 +2006,17 @@ const subscribeBalances$7 = ({
2007
2006
  if (abortController.signal.aborted) return;
2008
2007
  const balances = await fetchBalances$b({
2009
2008
  networkId,
2010
- addressesByToken,
2009
+ tokensWithAddresses: tokensWithAddresses,
2011
2010
  connector
2012
2011
  });
2013
2012
  if (abortController.signal.aborted) return;
2014
2013
  subscriber.next(balances);
2015
- setTimeout(poll, SUBSCRIPTION_INTERVAL$7);
2014
+ setTimeout(poll, SUBSCRIPTION_INTERVAL$6);
2016
2015
  } catch (error) {
2017
2016
  log.error("Error", {
2018
2017
  module: MODULE_TYPE$7,
2019
2018
  networkId,
2020
- addressesByToken,
2019
+ addressesByToken: tokensWithAddresses,
2021
2020
  error
2022
2021
  });
2023
2022
  subscriber.error(error);
@@ -2050,16 +2049,16 @@ const PLATFORM$6 = chaindataProvider.EvmUniswapV2TokenSchema.shape.platform.valu
2050
2049
 
2051
2050
  const fetchBalances$a = async ({
2052
2051
  networkId,
2053
- addressesByToken,
2052
+ tokensWithAddresses,
2054
2053
  connector
2055
2054
  }) => {
2056
2055
  const client = await connector.getPublicClientForEvmNetwork(networkId);
2057
2056
  if (!client) throw new Error(`Could not get rpc provider for evm network ${networkId}`);
2058
- for (const [token, addresses] of addressesByToken) {
2057
+ for (const [token, addresses] of tokensWithAddresses) {
2059
2058
  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}`);
2060
2059
  for (const address of addresses) if (!util.isEthereumAddress(address)) throw new Error(`Invalid ethereum address for EVM ERC20 balance module: ${address} for token ${token.id}`);
2061
2060
  }
2062
- const balanceDefs = getBalanceDefs(addressesByToken);
2061
+ const balanceDefs = getBalanceDefs(tokensWithAddresses);
2063
2062
  if (client.chain?.contracts?.erc20Aggregator && balanceDefs.length > 1) {
2064
2063
  const erc20Aggregator = client.chain.contracts.erc20Aggregator;
2065
2064
  return fetchWithAggregator(client, balanceDefs, erc20Aggregator.address);
@@ -2327,10 +2326,10 @@ const getTransferCallData$6 = ({
2327
2326
  };
2328
2327
  };
2329
2328
 
2330
- const SUBSCRIPTION_INTERVAL$6 = 6_000;
2329
+ const SUBSCRIPTION_INTERVAL$5 = 6_000;
2331
2330
  const subscribeBalances$6 = ({
2332
2331
  networkId,
2333
- addressesByToken,
2332
+ tokensWithAddresses,
2334
2333
  connector
2335
2334
  }) => {
2336
2335
  return new rxjs.Observable(subscriber => {
@@ -2340,17 +2339,17 @@ const subscribeBalances$6 = ({
2340
2339
  if (abortController.signal.aborted) return;
2341
2340
  const balances = await fetchBalances$a({
2342
2341
  networkId,
2343
- addressesByToken,
2342
+ tokensWithAddresses: tokensWithAddresses,
2344
2343
  connector
2345
2344
  });
2346
2345
  if (abortController.signal.aborted) return;
2347
2346
  subscriber.next(balances);
2348
- setTimeout(poll, SUBSCRIPTION_INTERVAL$6);
2347
+ setTimeout(poll, SUBSCRIPTION_INTERVAL$5);
2349
2348
  } catch (error) {
2350
2349
  log.error("Error", {
2351
2350
  module: MODULE_TYPE$6,
2352
2351
  networkId,
2353
- addressesByToken,
2352
+ addressesByToken: tokensWithAddresses,
2354
2353
  error
2355
2354
  });
2356
2355
  subscriber.error(error);
@@ -3472,13 +3471,13 @@ const decompress = data => {
3472
3471
 
3473
3472
  const fetchBalances$6 = async ({
3474
3473
  networkId,
3475
- addressesByToken,
3474
+ tokensWithAddresses,
3476
3475
  connector,
3477
3476
  miniMetadata
3478
3477
  }) => {
3479
- const balanceDefs = getBalanceDefs(addressesByToken);
3478
+ const balanceDefs = getBalanceDefs(tokensWithAddresses);
3480
3479
  if (!miniMetadata?.data) {
3481
- log.warn("MiniMetadata is required for fetching balances");
3480
+ log.warn(`MiniMetadata is required for fetching ${MODULE_TYPE$5} balances on ${networkId}.`);
3482
3481
  return {
3483
3482
  success: [],
3484
3483
  errors: balanceDefs.map(def => ({
@@ -3848,10 +3847,10 @@ const getTransferAllEncodedArgs$2 = (assetId, to, codec) => {
3848
3847
  })]);
3849
3848
  };
3850
3849
 
3851
- const SUBSCRIPTION_INTERVAL$5 = 6_000;
3850
+ const SUBSCRIPTION_INTERVAL$4 = 6_000;
3852
3851
  const subscribeBalances$5 = ({
3853
3852
  networkId,
3854
- addressesByToken,
3853
+ tokensWithAddresses,
3855
3854
  connector,
3856
3855
  miniMetadata
3857
3856
  }) => {
@@ -3865,19 +3864,19 @@ const subscribeBalances$5 = ({
3865
3864
  if (abortController.signal.aborted) return;
3866
3865
  const balances = await fetchBalances$6({
3867
3866
  networkId,
3868
- addressesByToken,
3867
+ tokensWithAddresses: tokensWithAddresses,
3869
3868
  connector,
3870
3869
  miniMetadata
3871
3870
  });
3872
3871
  if (abortController.signal.aborted) return;
3873
3872
  subscriber.next(balances);
3874
- setTimeout(poll, SUBSCRIPTION_INTERVAL$5);
3873
+ setTimeout(poll, SUBSCRIPTION_INTERVAL$4);
3875
3874
  } catch (error) {
3876
3875
  log.error("Error", {
3877
3876
  module: MODULE_TYPE$5,
3878
3877
  networkId,
3879
3878
  miniMetadata,
3880
- addressesByToken,
3879
+ addressesByToken: tokensWithAddresses,
3881
3880
  error
3882
3881
  });
3883
3882
  subscriber.error(error);
@@ -3911,13 +3910,13 @@ const PLATFORM$4 = chaindataProvider.SubForeignAssetsTokenSchema.shape.platform.
3911
3910
 
3912
3911
  const fetchBalances$5 = async ({
3913
3912
  networkId,
3914
- addressesByToken,
3913
+ tokensWithAddresses,
3915
3914
  connector,
3916
3915
  miniMetadata
3917
3916
  }) => {
3918
- const balanceDefs = getBalanceDefs(addressesByToken);
3917
+ const balanceDefs = getBalanceDefs(tokensWithAddresses);
3919
3918
  if (!miniMetadata?.data) {
3920
- log.warn("MiniMetadata is required for fetching balances");
3919
+ log.warn(`MiniMetadata is required for fetching ${MODULE_TYPE$4} balances on ${networkId}.`);
3921
3920
  return {
3922
3921
  success: [],
3923
3922
  errors: balanceDefs.map(def => ({
@@ -4246,10 +4245,10 @@ const getTransferAllEncodedArgs$1 = (onChainId, to, codec) => {
4246
4245
  })]);
4247
4246
  };
4248
4247
 
4249
- const SUBSCRIPTION_INTERVAL$4 = 6_000;
4248
+ const SUBSCRIPTION_INTERVAL$3 = 6_000;
4250
4249
  const subscribeBalances$4 = ({
4251
4250
  networkId,
4252
- addressesByToken,
4251
+ tokensWithAddresses,
4253
4252
  connector,
4254
4253
  miniMetadata
4255
4254
  }) => {
@@ -4263,19 +4262,19 @@ const subscribeBalances$4 = ({
4263
4262
  if (abortController.signal.aborted) return;
4264
4263
  const balances = await fetchBalances$5({
4265
4264
  networkId,
4266
- addressesByToken,
4265
+ tokensWithAddresses: tokensWithAddresses,
4267
4266
  connector,
4268
4267
  miniMetadata
4269
4268
  });
4270
4269
  if (abortController.signal.aborted) return;
4271
4270
  subscriber.next(balances);
4272
- setTimeout(poll, SUBSCRIPTION_INTERVAL$4);
4271
+ setTimeout(poll, SUBSCRIPTION_INTERVAL$3);
4273
4272
  } catch (error) {
4274
4273
  log.error("Error", {
4275
4274
  module: MODULE_TYPE$4,
4276
4275
  networkId,
4277
4276
  miniMetadata,
4278
- addressesByToken,
4277
+ addressesByToken: tokensWithAddresses,
4279
4278
  error
4280
4279
  });
4281
4280
  subscriber.error(error);
@@ -4339,13 +4338,13 @@ const tryGetConstantValue = (metadataRpc, pallet, constant) => {
4339
4338
 
4340
4339
  const fetchBalances$4 = async ({
4341
4340
  networkId,
4342
- addressesByToken,
4341
+ tokensWithAddresses,
4343
4342
  connector,
4344
4343
  miniMetadata
4345
4344
  }) => {
4346
- const balanceDefs = getBalanceDefs(addressesByToken);
4345
+ const balanceDefs = getBalanceDefs(tokensWithAddresses);
4347
4346
  if (!miniMetadata?.data) {
4348
- log.warn("MiniMetadata is required for fetching balances");
4347
+ log.warn(`MiniMetadata is required for fetching ${MODULE_TYPE$3} balances on ${networkId}.`);
4349
4348
  return {
4350
4349
  success: [],
4351
4350
  errors: balanceDefs.map(def => ({
@@ -4390,7 +4389,7 @@ const fetchBalances$4 = async ({
4390
4389
  })).filter(b => b.onChainId !== undefined);
4391
4390
  });
4392
4391
  const balancesByKey = lodash.keyBy(fetchedBalances, b => `${b.address}:${b.onChainId}`);
4393
- const success = addressesByToken.reduce((acc, [token, addresses]) => {
4392
+ const success = tokensWithAddresses.reduce((acc, [token, addresses]) => {
4394
4393
  if (token.type === MODULE_TYPE$3) for (const address of addresses) {
4395
4394
  const rawBalance = balancesByKey[`${address}:${token.onChainId}`];
4396
4395
 
@@ -4592,10 +4591,10 @@ const getTransferCallData$3 = ({
4592
4591
  };
4593
4592
  };
4594
4593
 
4595
- const SUBSCRIPTION_INTERVAL$3 = 6_000;
4594
+ const SUBSCRIPTION_INTERVAL$2 = 6_000;
4596
4595
  const subscribeBalances$3 = ({
4597
4596
  networkId,
4598
- addressesByToken,
4597
+ tokensWithAddresses,
4599
4598
  connector,
4600
4599
  miniMetadata
4601
4600
  }) => {
@@ -4609,19 +4608,19 @@ const subscribeBalances$3 = ({
4609
4608
  if (abortController.signal.aborted) return;
4610
4609
  const balances = await fetchBalances$4({
4611
4610
  networkId,
4612
- addressesByToken,
4611
+ tokensWithAddresses: tokensWithAddresses,
4613
4612
  connector,
4614
4613
  miniMetadata
4615
4614
  });
4616
4615
  if (abortController.signal.aborted) return;
4617
4616
  subscriber.next(balances);
4618
- setTimeout(poll, SUBSCRIPTION_INTERVAL$3);
4617
+ setTimeout(poll, SUBSCRIPTION_INTERVAL$2);
4619
4618
  } catch (error) {
4620
4619
  log.error("Error", {
4621
4620
  module: MODULE_TYPE$3,
4622
4621
  networkId,
4623
4622
  miniMetadata,
4624
- addressesByToken,
4623
+ addressesByToken: tokensWithAddresses,
4625
4624
  error
4626
4625
  });
4627
4626
  subscriber.error(error);
@@ -4647,140 +4646,54 @@ const SubHydrationBalanceModule = {
4647
4646
  const MODULE_TYPE$2 = chaindataProvider.SubNativeTokenSchema.shape.type.value;
4648
4647
  const PLATFORM$2 = chaindataProvider.SubNativeTokenSchema.shape.platform.value;
4649
4648
 
4650
- /**
4651
- * Pass some these into an `RpcStateQueryHelper` in order to easily batch multiple state queries into the one rpc call.
4652
- */
4653
-
4654
- const fetchQueriesPack = async (connector, networkId, queries) => {
4649
+ const fetchRpcQueryPack = async (connector, networkId, queries) => {
4655
4650
  const allStateKeys = queries.flatMap(({
4656
4651
  stateKeys
4657
4652
  }) => stateKeys).filter(util.isNotNil);
4658
4653
 
4659
- // doing a query with only null keys would throw an error => return early
4654
+ // doing a query without keys would throw an error => return early
4660
4655
  if (!allStateKeys.length) return queries.map(({
4661
4656
  stateKeys,
4662
4657
  decodeResult
4663
4658
  }) => decodeResult(stateKeys.map(() => null)));
4664
- const response = await connector.send(networkId, "state_queryStorageAt", [allStateKeys]);
4665
- const results = queries.reduce((acc, {
4659
+ const [result] = await connector.send(networkId, "state_queryStorageAt", [allStateKeys]);
4660
+ return decodeRpcQueryPack(queries, result);
4661
+ };
4662
+ const getRpcQueryPack$ = (connector, networkId, queries, timeout = false) => {
4663
+ const allStateKeys = queries.flatMap(({
4664
+ stateKeys
4665
+ }) => stateKeys).filter(util.isNotNil);
4666
+
4667
+ // doing a query without keys would throw an error => return early
4668
+ if (!allStateKeys.length) return rxjs.of(queries.map(({
4669
+ stateKeys,
4670
+ decodeResult
4671
+ }) => decodeResult(stateKeys.map(() => null))));
4672
+ return new rxjs.Observable(subscriber => {
4673
+ const promUnsub = connector.subscribe(networkId, "state_subscribeStorage", "state_storage", [allStateKeys], (error, result) => {
4674
+ if (error) subscriber.error(error);else subscriber.next(decodeRpcQueryPack(queries, result));
4675
+ }, timeout);
4676
+ return () => {
4677
+ promUnsub.then(unsub => unsub("state_unsubscribeStorage"));
4678
+ };
4679
+ });
4680
+ };
4681
+ const decodeRpcQueryPack = (queries, result) => {
4682
+ return queries.reduce((acc, {
4666
4683
  stateKeys,
4667
4684
  decodeResult
4668
4685
  }) => {
4669
4686
  const changes = stateKeys.map(stateKey => {
4670
4687
  if (!stateKey) return null;
4671
- const change = response[0].changes.find(([key]) => key === stateKey);
4688
+ const change = result.changes.find(([key]) => key === stateKey);
4672
4689
  if (!change) return null;
4673
4690
  return change[1];
4674
4691
  });
4675
4692
  acc.push(decodeResult(changes));
4676
4693
  return acc;
4677
4694
  }, []);
4678
- return results;
4679
4695
  };
4680
4696
 
4681
- /**
4682
- * Used by a variety of balance modules to help batch multiple state queries into the one rpc call.
4683
- */
4684
- // export class RpcStateQueriesHelper<T> {
4685
- // #connector: ChainConnector
4686
- // #queries: Array<RpcStateQueries<T>>
4687
-
4688
- // constructor(connector: ChainConnector, queries: Array<RpcStateQueries<T>>) {
4689
- // this.#connector = connector
4690
- // this.#queries = queries
4691
- // }
4692
-
4693
- // async subscribe(
4694
- // networkId: DotNetworkId,
4695
- // callback: SubscriptionCallback<T[]>,
4696
- // timeout: number | false = false,
4697
- // subscribeMethod = "state_subscribeStorage",
4698
- // responseMethod = "state_storage",
4699
- // unsubscribeMethod = "state_unsubscribeStorage",
4700
- // ): Promise<UnsubscribeFn> {
4701
- // const params = [this.#queries.flatMap(({ stateKeys }) => stateKeys)]
4702
-
4703
- // const unsub = this.#connector.subscribe(
4704
- // networkId,
4705
- // subscribeMethod,
4706
- // responseMethod,
4707
- // params,
4708
- // (error, result) => {
4709
- // error
4710
- // ? callback(error)
4711
- // : callback(null, this.#distributeChangesToQueryDecoders.call(this, chainId, result))
4712
- // },
4713
- // timeout,
4714
- // )
4715
-
4716
- // const subscriptions = queries.map(([chainId, queries]) => {
4717
- // const params = [queries.map(({ stateKey }) => stateKey)]
4718
-
4719
- // const unsub = this.#connector.subscribe(
4720
- // networkId,
4721
- // subscribeMethod,
4722
- // responseMethod,
4723
- // params,
4724
- // (error, result) => {
4725
- // error
4726
- // ? callback(error)
4727
- // : callback(null, this.#distributeChangesToQueryDecoders.call(this, chainId, result))
4728
- // },
4729
- // timeout,
4730
- // )
4731
-
4732
- // return () => unsub.then((unsubscribe) => unsubscribe(unsubscribeMethod))
4733
- // })
4734
-
4735
- // return () => subscriptions.forEach((unsubscribe) => unsubscribe())
4736
- // }
4737
-
4738
- // async fetch(method = "state_queryStorageAt"): Promise<T[]> {
4739
- // const queriesByChain = groupBy(this.#queries, "chainId")
4740
-
4741
- // const resultsByChain = await Promise.all(
4742
- // Object.entries(queriesByChain).map(async ([chainId, queries]) => {
4743
- // const params = [queries.map(({ stateKey }) => stateKey)]
4744
-
4745
- // const result = (await this.#connector.send(chainId, method, params))[0]
4746
- // return this.#distributeChangesToQueryDecoders.call(this, chainId, result)
4747
- // }),
4748
- // )
4749
-
4750
- // return resultsByChain.flatMap((result) => result)
4751
- // }
4752
-
4753
- // #distributeChangesToQueryDecoders(chainId: DotNetworkId, result: unknown): T[] {
4754
- // if (typeof result !== "object" || result === null) return []
4755
- // if (!hasOwnProperty(result, "changes") || typeof result.changes !== "object") return []
4756
- // if (!Array.isArray(result.changes)) return []
4757
-
4758
- // return result.changes.flatMap(([reference, change]: [unknown, unknown]): [T] | [] => {
4759
- // if (typeof reference !== "string") {
4760
- // log.warn(`Received non-string reference in RPC result: ${reference}`)
4761
- // return []
4762
- // }
4763
-
4764
- // if (typeof change !== "string" && change !== null) {
4765
- // log.warn(`Received non-string and non-null change in RPC result: ${reference} | ${change}`)
4766
- // return []
4767
- // }
4768
-
4769
- // const query = this.#queries.find(
4770
- // ({ chainId: cId, stateKey }) => cId === chainId && stateKey === reference,
4771
- // )
4772
- // if (!query) {
4773
- // log.warn(
4774
- // `Failed to find query:\n${reference} in\n${this.#queries.map(({ stateKey }) => stateKey)}`,
4775
- // )
4776
- // return []
4777
- // }
4778
-
4779
- // return [query.decodeResult(change)]
4780
- // })
4781
- // }
4782
- // }
4783
-
4784
4697
  const SUBTENSOR_ROOT_NETUID$1 = 0;
4785
4698
  const SUBTENSOR_MIN_STAKE_AMOUNT_PLANK$1 = 1000000n;
4786
4699
  const TAO_DECIMALS$1 = 9n;
@@ -5494,13 +5407,13 @@ const getNomPoolStateKeys = (coders, nomPoolMemberInfo, extra) => {
5494
5407
 
5495
5408
  const fetchBalances$3 = async ({
5496
5409
  networkId,
5497
- addressesByToken,
5410
+ tokensWithAddresses,
5498
5411
  connector,
5499
5412
  miniMetadata
5500
5413
  }) => {
5501
- const balanceDefs = getBalanceDefs(addressesByToken);
5414
+ const balanceDefs = getBalanceDefs(tokensWithAddresses);
5502
5415
  if (!miniMetadata?.data) {
5503
- log.warn("MiniMetadata is required for fetching balances");
5416
+ log.warn(`MiniMetadata is required for fetching ${MODULE_TYPE$2} balances on ${networkId}.`);
5504
5417
  return {
5505
5418
  success: [],
5506
5419
  errors: balanceDefs.map(def => ({
@@ -5532,12 +5445,12 @@ const fetchBalances$3 = async ({
5532
5445
  }))
5533
5446
  };
5534
5447
  }
5535
- const queries = buildBaseQueries(networkId, balanceDefs, miniMetadata);
5536
- const partialBalances = await fetchQueriesPack(connector, networkId, queries);
5448
+ const baseQueries = buildBaseQueries(networkId, balanceDefs, miniMetadata);
5449
+ const partialBalances = await fetchRpcQueryPack(connector, networkId, baseQueries);
5537
5450
 
5538
5451
  // now for each balance that includes nomPoolStaking, we need to fetch the metadata for the pool
5539
5452
  const nomPoolQueries = buildNomPoolQueries(networkId, partialBalances, miniMetadata);
5540
- const balances = await fetchQueriesPack(connector, networkId, nomPoolQueries);
5453
+ const balances = await fetchRpcQueryPack(connector, networkId, nomPoolQueries);
5541
5454
 
5542
5455
  // TODO ⚠️ dedupe locks
5543
5456
 
@@ -5773,46 +5686,32 @@ const getTransferAllEncodedArgs = (to, codec) => {
5773
5686
  })]);
5774
5687
  };
5775
5688
 
5776
- const SUBSCRIPTION_INTERVAL$2 = 6_000;
5777
5689
  const subscribeBalances$2 = ({
5778
5690
  networkId,
5779
- addressesByToken,
5691
+ tokensWithAddresses,
5780
5692
  connector,
5781
5693
  miniMetadata
5782
5694
  }) => {
5783
- return new rxjs.Observable(subscriber => {
5784
- const abortController = new AbortController();
5785
-
5786
- // on hydration balances are fetched using a runtimeApi, which can't be subscribed to.
5787
- // => poll values for each block
5788
- const poll = async () => {
5789
- try {
5790
- if (abortController.signal.aborted) return;
5791
- const balances = await fetchBalances$3({
5792
- networkId,
5793
- addressesByToken,
5794
- connector,
5795
- miniMetadata
5796
- });
5797
- if (abortController.signal.aborted) return;
5798
- subscriber.next(balances);
5799
- setTimeout(poll, SUBSCRIPTION_INTERVAL$2);
5800
- } catch (error) {
5801
- log.error("Error", {
5802
- module: MODULE_TYPE$2,
5803
- networkId,
5804
- miniMetadata,
5805
- addressesByToken,
5806
- error
5807
- });
5808
- subscriber.error(error);
5809
- }
5810
- };
5811
- poll();
5812
- return () => {
5813
- abortController.abort();
5695
+ // could be use as shared observable key if we decide to cache the sub
5696
+ const balanceDefs = getBalanceDefs(tokensWithAddresses);
5697
+ const baseQueries = buildBaseQueries(networkId, balanceDefs, miniMetadata);
5698
+ const baseBalances$ = getRpcQueryPack$(connector, networkId, baseQueries).pipe(rxjs.switchMap(partialBalances => {
5699
+ // now for each balance that includes nomPoolStaking, we need to fetch the metadata for the pool
5700
+ const nomPoolQueries = buildNomPoolQueries(networkId, partialBalances, miniMetadata);
5701
+ return getRpcQueryPack$(connector, networkId, nomPoolQueries);
5702
+ }));
5703
+ const subtensorBalancesByAddress$ = getSubtensorStakingBalances$(connector, networkId, balanceDefs, miniMetadata);
5704
+ return rxjs.combineLatest([baseBalances$, subtensorBalancesByAddress$]).pipe(rxjs.map(([baseBalances, subtensorBalancesByAddress]) => {
5705
+ // add subtensor balances to base balances
5706
+ for (const [address, subtensorBalances] of lodash.toPairs(subtensorBalancesByAddress)) {
5707
+ const balance = baseBalances.find(b => b.address === address);
5708
+ if (balance?.values) balance.values.push(...subtensorBalances);
5709
+ }
5710
+ return {
5711
+ success: baseBalances,
5712
+ errors: []
5814
5713
  };
5815
- }).pipe(rxjs.distinctUntilChanged(lodash.isEqual));
5714
+ }));
5816
5715
  };
5817
5716
 
5818
5717
  const SubNativeBalanceModule = {
@@ -6993,10 +6892,10 @@ var psp22Abi = {
6993
6892
 
6994
6893
  const fetchBalances$2 = async ({
6995
6894
  networkId,
6996
- addressesByToken,
6895
+ tokensWithAddresses,
6997
6896
  connector
6998
6897
  }) => {
6999
- const balanceDefs = getBalanceDefs(addressesByToken);
6898
+ const balanceDefs = getBalanceDefs(tokensWithAddresses);
7000
6899
  if (!balanceDefs.length) return {
7001
6900
  success: [],
7002
6901
  errors: []
@@ -7186,7 +7085,7 @@ const getTransferCallData$1 = async ({
7186
7085
  const SUBSCRIPTION_INTERVAL$1 = 6_000;
7187
7086
  const subscribeBalances$1 = ({
7188
7087
  networkId,
7189
- addressesByToken,
7088
+ tokensWithAddresses,
7190
7089
  connector,
7191
7090
  miniMetadata
7192
7091
  }) => {
@@ -7200,7 +7099,7 @@ const subscribeBalances$1 = ({
7200
7099
  if (abortController.signal.aborted) return;
7201
7100
  const balances = await fetchBalances$2({
7202
7101
  networkId,
7203
- addressesByToken,
7102
+ tokensWithAddresses: tokensWithAddresses,
7204
7103
  connector,
7205
7104
  miniMetadata
7206
7105
  });
@@ -7212,7 +7111,7 @@ const subscribeBalances$1 = ({
7212
7111
  module: MODULE_TYPE$1,
7213
7112
  networkId,
7214
7113
  miniMetadata,
7215
- addressesByToken,
7114
+ addressesByToken: tokensWithAddresses,
7216
7115
  error
7217
7116
  });
7218
7117
  subscriber.error(error);
@@ -7246,13 +7145,13 @@ const PLATFORM = chaindataProvider.SubTokensTokenSchema.shape.platform.value;
7246
7145
 
7247
7146
  const fetchBalances$1 = async ({
7248
7147
  networkId,
7249
- addressesByToken,
7148
+ tokensWithAddresses,
7250
7149
  connector,
7251
7150
  miniMetadata
7252
7151
  }) => {
7253
- const balanceDefs = getBalanceDefs(addressesByToken);
7152
+ const balanceDefs = getBalanceDefs(tokensWithAddresses);
7254
7153
  if (!miniMetadata?.data) {
7255
- log.warn("MiniMetadata is required for fetching balances");
7154
+ log.warn(`MiniMetadata is required for fetching ${MODULE_TYPE} balances on ${networkId}.`);
7256
7155
  return {
7257
7156
  success: [],
7258
7157
  errors: balanceDefs.map(def => ({
@@ -7576,7 +7475,7 @@ const getCallDataOptions = (to, token, value, type, config) => {
7576
7475
  const SUBSCRIPTION_INTERVAL = 6_000;
7577
7476
  const subscribeBalances = ({
7578
7477
  networkId,
7579
- addressesByToken,
7478
+ tokensWithAddresses,
7580
7479
  connector,
7581
7480
  miniMetadata
7582
7481
  }) => {
@@ -7590,7 +7489,7 @@ const subscribeBalances = ({
7590
7489
  if (abortController.signal.aborted) return;
7591
7490
  const balances = await fetchBalances$1({
7592
7491
  networkId,
7593
- addressesByToken,
7492
+ tokensWithAddresses: tokensWithAddresses,
7594
7493
  connector,
7595
7494
  miniMetadata
7596
7495
  });
@@ -7602,7 +7501,7 @@ const subscribeBalances = ({
7602
7501
  module: MODULE_TYPE,
7603
7502
  networkId,
7604
7503
  miniMetadata,
7605
- addressesByToken,
7504
+ addressesByToken: tokensWithAddresses,
7606
7505
  error
7607
7506
  });
7608
7507
  subscriber.error(error);
@@ -7706,6 +7605,7 @@ const getMiniMetadatas = async (chainConnector, chaindataProvider, networkId, sp
7706
7605
  if (CACHE.has(networkId)) return CACHE.get(networkId);
7707
7606
  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
7708
7607
  );
7608
+ if (specVersion === undefined) specVersion = await getSpecVersion(chainConnector, networkId);
7709
7609
  const pResult = POOL.add(() => fetchMiniMetadatas(chainConnector, chaindataProvider, networkId, specVersion), {
7710
7610
  signal
7711
7611
  });
@@ -7721,42 +7621,21 @@ const getMiniMetadatas = async (chainConnector, chaindataProvider, networkId, sp
7721
7621
  CACHE.delete(networkId);
7722
7622
  }
7723
7623
  };
7724
- const DotBalanceModuleTypeSchema = z__default.default.keyof(chaindataProvider.DotNetworkBalancesConfigSchema);
7725
- const fetchMiniMetadatas = async (chainConnector, chaindataProvider$1, chainId, specVersion, signal) => {
7624
+ const fetchMiniMetadatas = async (chainConnector, chaindataProvider, chainId, specVersion, signal) => {
7726
7625
  const start = performance.now();
7727
7626
  log.info("[miniMetadata] fetching minimetadatas for %s", chainId);
7728
7627
  try {
7628
+ const network = await chaindataProvider.getNetworkById(chainId, "polkadot");
7629
+ if (!network) throw new Error(`Network ${chainId} not found in chaindataProvider`);
7630
+ signal?.throwIfAborted();
7729
7631
  const metadataRpc = await getMetadataRpc(chainConnector, chainId);
7730
7632
  signal?.throwIfAborted();
7731
- const chainConnectors = {
7732
- substrate: chainConnector,
7733
- evm: {} // wont be used but workarounds error for module creation
7734
- };
7735
- const modules = defaultBalanceModules.map(mod => mod({
7736
- chainConnectors,
7737
- chaindataProvider: chaindataProvider$1
7738
- })).filter(mod => DotBalanceModuleTypeSchema.safeParse(mod.type).success);
7739
- return Promise.all(modules.map(async mod => {
7740
- const source = mod.type;
7741
- const chain = await chaindataProvider$1.getNetworkById(chainId, "polkadot");
7742
- const balancesConfig = chain?.balancesConfig?.[mod.type];
7743
- const chainMeta = await mod.fetchSubstrateChainMeta(chainId, balancesConfig,
7744
- // TODO better typing
7745
- metadataRpc);
7746
- return {
7747
- id: deriveMiniMetadataId({
7748
- source,
7749
- chainId,
7750
- specVersion
7751
- }),
7752
- source,
7753
- chainId,
7754
- specVersion,
7755
- version: chaindataProvider.MINIMETADATA_VERSION,
7756
- data: chainMeta?.miniMetadata ?? null,
7757
- extra: chainMeta?.extra ?? null
7758
- };
7759
- }));
7633
+ return Promise.all(BALANCE_MODULES.filter(m => m.platform === "polkadot").map(mod => mod.getMiniMetadata({
7634
+ networkId: chainId,
7635
+ metadataRpc,
7636
+ specVersion,
7637
+ config: network.balancesConfig?.[mod.type]
7638
+ })));
7760
7639
  } finally {
7761
7640
  log.debug("[miniMetadata] updated miniMetadatas for %s in %sms", chainId, (performance.now() - start).toFixed(2));
7762
7641
  }
@@ -10467,6 +10346,134 @@ async function buildQueries(chainConnector, chaindataProvider$1, addressesByToke
10467
10346
  const defaultBalanceModules = [EvmErc20Module, EvmNativeModule, EvmUniswapV2Module, SubAssetsModule, SubForeignAssetsModule, SubNativeModule, SubPsp22Module, SubTokensModule];
10468
10347
  const BALANCE_MODULES = [SubNativeBalanceModule, SubAssetsBalanceModule, SubHydrationBalanceModule, SubForeignAssetsBalanceModule, SubPsp22BalanceModule, SubTokensBalanceModule, EvmErc20BalanceModule, EvmUniswapV2BalanceModule, EvmNativeBalanceModule];
10469
10348
 
10349
+ const DEFAULT_STORAGE = {
10350
+ balances: [],
10351
+ miniMetadatas: []
10352
+ };
10353
+ class BalancesProvider {
10354
+ #chaindataProvider;
10355
+ #chainConnectors;
10356
+ #storage;
10357
+ constructor(chaindataProvider, chainConnectors, storage = DEFAULT_STORAGE) {
10358
+ this.#chaindataProvider = chaindataProvider;
10359
+ this.#chainConnectors = chainConnectors;
10360
+ this.#storage = new rxjs.BehaviorSubject({
10361
+ balances: lodash.keyBy(storage.balances.filter(util.isNotNil), b => getBalanceId(b)),
10362
+ miniMetadatas: lodash.keyBy(storage.miniMetadatas.filter(util.isNotNil), m => m.id)
10363
+ });
10364
+ }
10365
+ get storage$() {
10366
+ return this.#storage.pipe(rxjs.map(({
10367
+ balances,
10368
+ miniMetadatas
10369
+ }) => ({
10370
+ balances: lodash.values(balances).filter(util.isNotNil),
10371
+ miniMetadatas: lodash.values(miniMetadatas).filter(util.isNotNil)
10372
+ })));
10373
+ }
10374
+ getBalances$(addressesByToken) {
10375
+ const networkIds = lodash.uniq(lodash.keys(addressesByToken).map(tokenId => chaindataProvider.parseTokenId(tokenId).networkId));
10376
+ return rxjs.combineLatest(networkIds.map(networkId => this.getNetworkBalances$(networkId, addressesByToken))).pipe(rxjs.map(results => {
10377
+ return {
10378
+ status: results.some(({
10379
+ status
10380
+ }) => status === "initialising") ? "initialising" : "live",
10381
+ balances: results.flatMap(result => result.balances)
10382
+ };
10383
+ }), rxjs.startWith({
10384
+ status: "initialising",
10385
+ balances: this.getStoredBalances(addressesByToken)
10386
+ }), rxjs.distinctUntilChanged(lodash.isEqual));
10387
+ }
10388
+ getNetworkBalances$(networkId, addressesByTokenId) {
10389
+ const network$ = this.#chaindataProvider.getNetworkById$(networkId);
10390
+ const tokensMapById$ = this.#chaindataProvider.getTokensMapById$();
10391
+ const miniMetadatas$ = this.getNetworkMiniMetadatas$(networkId);
10392
+ return rxjs.combineLatest([network$, miniMetadatas$, tokensMapById$]).pipe(rxjs.switchMap(([network, miniMetadatas, tokensMapById]) => {
10393
+ const tokensAndAddresses = lodash.toPairs(addressesByTokenId).map(([tokenId, addresses]) => [tokensMapById[tokenId], addresses]);
10394
+ return rxjs.combineLatest(BALANCE_MODULES.filter(mod => mod.platform === network?.platform).map(mod => {
10395
+ const tokensWithAddresses = tokensAndAddresses.filter(([token]) => token.type === mod.type);
10396
+ const moduleAddressesByTokenId = lodash.fromPairs(tokensWithAddresses.map(([token, addresses]) => [token.id, addresses]));
10397
+ const miniMetadata = miniMetadatas.find(m => m.source === mod.type);
10398
+
10399
+ // all balance ids expected in result set
10400
+ const balanceIds = lodash.toPairs(moduleAddressesByTokenId).flatMap(([tokenId, addresses]) => addresses.map(address => getBalanceId({
10401
+ tokenId,
10402
+ address
10403
+ })));
10404
+ const initValue = {
10405
+ status: "initialising",
10406
+ balances: this.getStoredBalances(moduleAddressesByTokenId)
10407
+ };
10408
+ const updateStorage = results => {
10409
+ if (results.status !== "live") return;
10410
+ const storage = this.#storage.getValue();
10411
+ const balances = lodash.assign({}, storage.balances,
10412
+ // delete all balances expected in the result set. because if they are not present it means they are empty.
10413
+ lodash.fromPairs(balanceIds.map(balanceId => [balanceId, undefined])), lodash.keyBy(results.balances, b => getBalanceId(b)));
10414
+ this.#storage.next(lodash.assign({}, storage, {
10415
+ balances
10416
+ }));
10417
+ };
10418
+ switch (mod.platform) {
10419
+ case "ethereum":
10420
+ {
10421
+ if (!this.#chainConnectors.evm) return rxjs.of(initValue);
10422
+ return mod.subscribeBalances({
10423
+ networkId,
10424
+ tokensWithAddresses,
10425
+ connector: this.#chainConnectors.evm
10426
+ }).pipe(rxjs.map(results => ({
10427
+ status: "live",
10428
+ // exclude zero balances
10429
+ balances: results.success.filter(b => new Balance(b).total.planck > 0n)
10430
+ })), rxjs.tap(updateStorage), rxjs.startWith(initValue));
10431
+ }
10432
+ case "polkadot":
10433
+ if (!this.#chainConnectors.substrate || !miniMetadata) {
10434
+ log.debug("[balances] no substrate connector or miniMetadata for polkadot", mod.type);
10435
+ return rxjs.of(initValue);
10436
+ }
10437
+ return mod.subscribeBalances({
10438
+ networkId,
10439
+ tokensWithAddresses,
10440
+ connector: this.#chainConnectors.substrate,
10441
+ miniMetadata: miniMetadata
10442
+ }).pipe(rxjs.map(results => ({
10443
+ status: "live",
10444
+ // exclude zero balances
10445
+ balances: results.success.filter(b => new Balance(b).total.planck > 0n)
10446
+ })), rxjs.tap(updateStorage), rxjs.startWith(initValue));
10447
+ }
10448
+ }));
10449
+ }), rxjs.map(results => {
10450
+ return {
10451
+ status: results.some(({
10452
+ status
10453
+ }) => status === "initialising") ? "initialising" : "live",
10454
+ balances: results.flatMap(result => result.balances)
10455
+ };
10456
+ }));
10457
+ }
10458
+ getNetworkMiniMetadatas$(networkId) {
10459
+ return this.#chaindataProvider.getNetworkById$(networkId).pipe(rxjs.switchMap(network => chaindataProvider.isNetworkDot(network) && this.#chainConnectors.substrate ? rxjs.from(getMiniMetadatas(this.#chainConnectors.substrate, this.#chaindataProvider, networkId)) : rxjs.of([])));
10460
+ }
10461
+ getStoredBalances(addressesByToken) {
10462
+ const balanceDefs = lodash.toPairs(addressesByToken).flatMap(([tokenId, addresses]) => addresses.map(address => [tokenId, address]));
10463
+ return balanceDefs.map(([tokenId, address]) => this.#storage.value.balances[getBalanceId({
10464
+ address,
10465
+ tokenId
10466
+ })]).filter(util.isNotNil);
10467
+ }
10468
+ }
10469
+
10470
+ // const getStoredBalances = (
10471
+ // storedBalances: Record<string, IBalance>,
10472
+ // addressesByToken: Record<TokenId, Address[]>,
10473
+ // ): IBalance[] => {
10474
+
10475
+ // }
10476
+
10470
10477
  Object.defineProperty(exports, "MINIMETADATA_VERSION", {
10471
10478
  enumerable: true,
10472
10479
  get: function () { return chaindataProvider.MINIMETADATA_VERSION; }
@@ -10476,6 +10483,7 @@ exports.Balance = Balance;
10476
10483
  exports.BalanceFormatter = BalanceFormatter;
10477
10484
  exports.BalanceValueGetter = BalanceValueGetter;
10478
10485
  exports.Balances = Balances;
10486
+ exports.BalancesProvider = BalancesProvider;
10479
10487
  exports.Change24hCurrencyFormatter = Change24hCurrencyFormatter;
10480
10488
  exports.DefaultBalanceModule = DefaultBalanceModule;
10481
10489
  exports.EvmErc20BalanceModule = EvmErc20BalanceModule;