@talismn/balances 0.0.0-pr2075-20250708110002 → 0.0.0-pr2075-20250708143919

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.
@@ -1779,7 +1779,7 @@ const getTransferCallData$8 = ({
1779
1779
  };
1780
1780
  };
1781
1781
 
1782
- const SUBSCRIPTION_INTERVAL$8 = 6_000;
1782
+ const SUBSCRIPTION_INTERVAL$6 = 6_000;
1783
1783
  const subscribeBalances$8 = ({
1784
1784
  networkId,
1785
1785
  tokensWithAddresses,
@@ -1797,7 +1797,7 @@ const subscribeBalances$8 = ({
1797
1797
  });
1798
1798
  if (abortController.signal.aborted) return;
1799
1799
  subscriber.next(balances);
1800
- setTimeout(poll, SUBSCRIPTION_INTERVAL$8);
1800
+ setTimeout(poll, SUBSCRIPTION_INTERVAL$6);
1801
1801
  } catch (error) {
1802
1802
  log.error("Error", {
1803
1803
  module: MODULE_TYPE$8,
@@ -1993,7 +1993,7 @@ const getTransferCallData$7 = ({
1993
1993
  };
1994
1994
  };
1995
1995
 
1996
- const SUBSCRIPTION_INTERVAL$7 = 6_000;
1996
+ const SUBSCRIPTION_INTERVAL$5 = 6_000;
1997
1997
  const subscribeBalances$7 = ({
1998
1998
  networkId,
1999
1999
  tokensWithAddresses,
@@ -2011,7 +2011,7 @@ const subscribeBalances$7 = ({
2011
2011
  });
2012
2012
  if (abortController.signal.aborted) return;
2013
2013
  subscriber.next(balances);
2014
- setTimeout(poll, SUBSCRIPTION_INTERVAL$7);
2014
+ setTimeout(poll, SUBSCRIPTION_INTERVAL$5);
2015
2015
  } catch (error) {
2016
2016
  log.error("Error", {
2017
2017
  module: MODULE_TYPE$7,
@@ -2326,7 +2326,7 @@ const getTransferCallData$6 = ({
2326
2326
  };
2327
2327
  };
2328
2328
 
2329
- const SUBSCRIPTION_INTERVAL$6 = 6_000;
2329
+ const SUBSCRIPTION_INTERVAL$4 = 6_000;
2330
2330
  const subscribeBalances$6 = ({
2331
2331
  networkId,
2332
2332
  tokensWithAddresses,
@@ -2344,7 +2344,7 @@ const subscribeBalances$6 = ({
2344
2344
  });
2345
2345
  if (abortController.signal.aborted) return;
2346
2346
  subscriber.next(balances);
2347
- setTimeout(poll, SUBSCRIPTION_INTERVAL$6);
2347
+ setTimeout(poll, SUBSCRIPTION_INTERVAL$4);
2348
2348
  } catch (error) {
2349
2349
  log.error("Error", {
2350
2350
  module: MODULE_TYPE$6,
@@ -3477,7 +3477,7 @@ const fetchBalances$6 = async ({
3477
3477
  }) => {
3478
3478
  const balanceDefs = getBalanceDefs(tokensWithAddresses);
3479
3479
  if (!miniMetadata?.data) {
3480
- log.warn("MiniMetadata is required for fetching balances");
3480
+ log.warn(`MiniMetadata is required for fetching ${MODULE_TYPE$5} balances on ${networkId}.`);
3481
3481
  return {
3482
3482
  success: [],
3483
3483
  errors: balanceDefs.map(def => ({
@@ -3509,7 +3509,7 @@ const fetchBalances$6 = async ({
3509
3509
  }))
3510
3510
  };
3511
3511
  }
3512
- const queries = buildQueries$6(networkId, balanceDefs, miniMetadata);
3512
+ const queries = buildQueries$7(networkId, balanceDefs, miniMetadata);
3513
3513
  const balances = await new RpcStateQueryHelper(connector, queries).fetch();
3514
3514
  return balanceDefs.reduce((acc, def) => {
3515
3515
  const balance = balances.find(b => b?.address === def.address && b?.tokenId === def.token.id);
@@ -3537,7 +3537,7 @@ const fetchBalances$6 = async ({
3537
3537
  errors: []
3538
3538
  });
3539
3539
  };
3540
- const buildQueries$6 = (networkId, balanceDefs, miniMetadata) => {
3540
+ const buildQueries$7 = (networkId, balanceDefs, miniMetadata) => {
3541
3541
  const networkStorageCoders = buildNetworkStorageCoders(networkId, miniMetadata, {
3542
3542
  storage: ["Assets", "Account"]
3543
3543
  });
@@ -3546,9 +3546,9 @@ const buildQueries$6 = (networkId, balanceDefs, miniMetadata) => {
3546
3546
  address
3547
3547
  }) => {
3548
3548
  const scaleCoder = networkStorageCoders?.storage;
3549
- const stateKey = tryEncode$1(scaleCoder, Number(token.assetId), address) ??
3549
+ const stateKey = tryEncode$2(scaleCoder, Number(token.assetId), address) ??
3550
3550
  // Asset Hub
3551
- tryEncode$1(scaleCoder, BigInt(token.assetId), address); // Astar
3551
+ tryEncode$2(scaleCoder, BigInt(token.assetId), address); // Astar
3552
3552
 
3553
3553
  if (!stateKey) {
3554
3554
  log.warn(`Invalid assetId / address in ${networkId} storage query ${token.assetId} / ${address}`);
@@ -3604,7 +3604,7 @@ const buildQueries$6 = (networkId, balanceDefs, miniMetadata) => {
3604
3604
  };
3605
3605
  }).filter(util.isNotNil);
3606
3606
  };
3607
- const tryEncode$1 = (scaleCoder, ...args) => {
3607
+ const tryEncode$2 = (scaleCoder, ...args) => {
3608
3608
  try {
3609
3609
  return scaleCoder?.keys?.enc?.(...args);
3610
3610
  } catch {
@@ -3847,46 +3847,163 @@ const getTransferAllEncodedArgs$2 = (assetId, to, codec) => {
3847
3847
  })]);
3848
3848
  };
3849
3849
 
3850
- const SUBSCRIPTION_INTERVAL$5 = 6_000;
3850
+ const fetchRuntimeCallResult = async (connector, networkId, metadataRpc, apiName, method, args) => {
3851
+ const {
3852
+ builder
3853
+ } = scale.parseMetadataRpc(metadataRpc);
3854
+ const call = builder.buildRuntimeCall(apiName, method);
3855
+ const hex = await connector.send(networkId, "state_call", [`${apiName}_${method}`, scale.toHex(call.args.enc(args))]);
3856
+ return call.value.dec(hex);
3857
+ };
3858
+
3859
+ const tryGetConstantValue = (metadataRpc, pallet, constant) => {
3860
+ const {
3861
+ unifiedMetadata,
3862
+ builder
3863
+ } = scale.parseMetadataRpc(metadataRpc);
3864
+ const encodedValue = unifiedMetadata.pallets.find(({
3865
+ name
3866
+ }) => name === pallet)?.constants.find(({
3867
+ name
3868
+ }) => name === constant)?.value;
3869
+ if (!encodedValue) return null;
3870
+ const codec = builder.buildConstant(pallet, constant);
3871
+ return codec.dec(encodedValue);
3872
+ };
3873
+
3874
+ const fetchRpcQueryPack = async (connector, networkId, queries) => {
3875
+ const allStateKeys = queries.flatMap(({
3876
+ stateKeys
3877
+ }) => stateKeys).filter(util.isNotNil);
3878
+
3879
+ // doing a query without keys would throw an error => return early
3880
+ if (!allStateKeys.length) return queries.map(({
3881
+ stateKeys,
3882
+ decodeResult
3883
+ }) => decodeResult(stateKeys.map(() => null)));
3884
+ const [result] = await connector.send(networkId, "state_queryStorageAt", [allStateKeys]);
3885
+ return decodeRpcQueryPack(queries, result);
3886
+ };
3887
+ const getRpcQueryPack$ = (connector, networkId, queries, timeout = false) => {
3888
+ const allStateKeys = queries.flatMap(({
3889
+ stateKeys
3890
+ }) => stateKeys).filter(util.isNotNil);
3891
+
3892
+ // doing a query without keys would throw an error => return early
3893
+ if (!allStateKeys.length) return rxjs.of(queries.map(({
3894
+ stateKeys,
3895
+ decodeResult
3896
+ }) => decodeResult(stateKeys.map(() => null))));
3897
+ return new rxjs.Observable(subscriber => {
3898
+ const promUnsub = connector.subscribe(networkId, "state_subscribeStorage", "state_storage", [allStateKeys], (error, result) => {
3899
+ if (error) subscriber.error(error);else subscriber.next(decodeRpcQueryPack(queries, result));
3900
+ }, timeout);
3901
+ return () => {
3902
+ promUnsub.then(unsub => unsub("state_unsubscribeStorage"));
3903
+ };
3904
+ });
3905
+ };
3906
+ const decodeRpcQueryPack = (queries, result) => {
3907
+ return queries.reduce((acc, {
3908
+ stateKeys,
3909
+ decodeResult
3910
+ }) => {
3911
+ const changes = stateKeys.map(stateKey => {
3912
+ if (!stateKey) return null;
3913
+ const change = result.changes.find(([key]) => key === stateKey);
3914
+ if (!change) return null;
3915
+ return change[1];
3916
+ });
3917
+ acc.push(decodeResult(changes));
3918
+ return acc;
3919
+ }, []);
3920
+ };
3921
+
3851
3922
  const subscribeBalances$5 = ({
3852
3923
  networkId,
3853
3924
  tokensWithAddresses,
3854
3925
  connector,
3855
3926
  miniMetadata
3856
3927
  }) => {
3857
- return new rxjs.Observable(subscriber => {
3858
- const abortController = new AbortController();
3928
+ const balanceDefs = getBalanceDefs(tokensWithAddresses);
3929
+ const queries = buildQueries$6(networkId, balanceDefs, miniMetadata);
3930
+ return getRpcQueryPack$(connector, networkId, queries).pipe(rxjs.map(balances => ({
3931
+ success: balances,
3932
+ errors: []
3933
+ })));
3934
+ };
3935
+ const buildQueries$6 = (networkId, balanceDefs, miniMetadata) => {
3936
+ const networkStorageCoders = buildNetworkStorageCoders(networkId, miniMetadata, {
3937
+ storage: ["Assets", "Account"]
3938
+ });
3939
+ return balanceDefs.map(({
3940
+ token,
3941
+ address
3942
+ }) => {
3943
+ const scaleCoder = networkStorageCoders?.storage;
3944
+ const stateKey = tryEncode$1(scaleCoder, Number(token.assetId), address) ??
3945
+ // Asset Hub
3946
+ tryEncode$1(scaleCoder, BigInt(token.assetId), address); // Astar
3859
3947
 
3860
- // on hydration balances are fetched using a runtimeApi, which can't be subscribed to.
3861
- // => poll values for each block
3862
- const poll = async () => {
3863
- try {
3864
- if (abortController.signal.aborted) return;
3865
- const balances = await fetchBalances$6({
3866
- networkId,
3867
- tokensWithAddresses: tokensWithAddresses,
3868
- connector,
3869
- miniMetadata
3870
- });
3871
- if (abortController.signal.aborted) return;
3872
- subscriber.next(balances);
3873
- setTimeout(poll, SUBSCRIPTION_INTERVAL$5);
3874
- } catch (error) {
3875
- log.error("Error", {
3876
- module: MODULE_TYPE$5,
3877
- networkId,
3878
- miniMetadata,
3879
- addressesByToken: tokensWithAddresses,
3880
- error
3881
- });
3882
- subscriber.error(error);
3883
- }
3948
+ if (!stateKey) {
3949
+ log.warn(`Invalid assetId / address in ${networkId} storage query ${token.assetId} / ${address}`);
3950
+ return null;
3951
+ } else log.log(`VALID assetId / address in ${networkId} storage query ${token.assetId} / ${address}`);
3952
+ const decodeResult = changes => {
3953
+ /** NOTE: This type is only a hint for typescript, the chain can actually return whatever it wants to */
3954
+
3955
+ const decoded = scale.decodeScale(scaleCoder, changes[0], `Failed to decode substrate-assets balance on chain ${networkId}`) ?? {
3956
+ balance: 0n,
3957
+ status: {
3958
+ type: "Liquid"
3959
+ }};
3960
+ const isFrozen = decoded?.status?.type === "Frozen";
3961
+ const amount = (decoded?.balance ?? 0n).toString();
3962
+
3963
+ // due to the following balance calculations, which are made in the `Balance` type:
3964
+ //
3965
+ // total balance = (free balance) + (reserved balance)
3966
+ // transferable balance = (free balance) - (frozen balance)
3967
+ //
3968
+ // when `isFrozen` is true we need to set **both** the `free` and `frozen` amounts
3969
+ // of this balance to the value we received from the RPC.
3970
+ //
3971
+ // if we only set the `frozen` amount, then the `total` calculation will be incorrect!
3972
+ const free = amount;
3973
+ const frozen = token.isFrozen || isFrozen ? amount : "0";
3974
+
3975
+ // include balance values even if zero, so that newly-zero values overwrite old values
3976
+ const balanceValues = [{
3977
+ type: "free",
3978
+ label: "free",
3979
+ amount: free.toString()
3980
+ }, {
3981
+ type: "locked",
3982
+ label: "frozen",
3983
+ amount: frozen.toString()
3984
+ }];
3985
+ const balance = {
3986
+ source: "substrate-assets",
3987
+ status: "live",
3988
+ address,
3989
+ networkId,
3990
+ tokenId: token.id,
3991
+ values: balanceValues
3992
+ };
3993
+ return balance;
3884
3994
  };
3885
- poll();
3886
- return () => {
3887
- abortController.abort();
3995
+ return {
3996
+ stateKeys: [stateKey],
3997
+ decodeResult
3888
3998
  };
3889
- }).pipe(rxjs.distinctUntilChanged(lodash.isEqual));
3999
+ }).filter(util.isNotNil);
4000
+ };
4001
+ const tryEncode$1 = (scaleCoder, ...args) => {
4002
+ try {
4003
+ return scaleCoder?.keys?.enc?.(...args);
4004
+ } catch {
4005
+ return null;
4006
+ }
3890
4007
  };
3891
4008
 
3892
4009
  const SubAssetsBalanceModule = {
@@ -3916,7 +4033,7 @@ const fetchBalances$5 = async ({
3916
4033
  }) => {
3917
4034
  const balanceDefs = getBalanceDefs(tokensWithAddresses);
3918
4035
  if (!miniMetadata?.data) {
3919
- log.warn("MiniMetadata is required for fetching balances");
4036
+ log.warn(`MiniMetadata is required for fetching ${MODULE_TYPE$4} balances on ${networkId}.`);
3920
4037
  return {
3921
4038
  success: [],
3922
4039
  errors: balanceDefs.map(def => ({
@@ -4245,7 +4362,7 @@ const getTransferAllEncodedArgs$1 = (onChainId, to, codec) => {
4245
4362
  })]);
4246
4363
  };
4247
4364
 
4248
- const SUBSCRIPTION_INTERVAL$4 = 6_000;
4365
+ const SUBSCRIPTION_INTERVAL$3 = 6_000;
4249
4366
  const subscribeBalances$4 = ({
4250
4367
  networkId,
4251
4368
  tokensWithAddresses,
@@ -4268,7 +4385,7 @@ const subscribeBalances$4 = ({
4268
4385
  });
4269
4386
  if (abortController.signal.aborted) return;
4270
4387
  subscriber.next(balances);
4271
- setTimeout(poll, SUBSCRIPTION_INTERVAL$4);
4388
+ setTimeout(poll, SUBSCRIPTION_INTERVAL$3);
4272
4389
  } catch (error) {
4273
4390
  log.error("Error", {
4274
4391
  module: MODULE_TYPE$4,
@@ -4312,30 +4429,6 @@ const SubHydrationTokenConfigSchema = z__default.default.strictObject({
4312
4429
  const MODULE_TYPE$3 = chaindataProvider.SubHydrationTokenSchema.shape.type.value;
4313
4430
  const PLATFORM$3 = chaindataProvider.SubHydrationTokenSchema.shape.platform.value;
4314
4431
 
4315
- const fetchRuntimeCallResult = async (connector, networkId, metadataRpc, apiName, method, args) => {
4316
- const {
4317
- builder
4318
- } = scale.parseMetadataRpc(metadataRpc);
4319
- const call = builder.buildRuntimeCall(apiName, method);
4320
- const hex = await connector.send(networkId, "state_call", [`${apiName}_${method}`, scale.toHex(call.args.enc(args))]);
4321
- return call.value.dec(hex);
4322
- };
4323
-
4324
- const tryGetConstantValue = (metadataRpc, pallet, constant) => {
4325
- const {
4326
- unifiedMetadata,
4327
- builder
4328
- } = scale.parseMetadataRpc(metadataRpc);
4329
- const encodedValue = unifiedMetadata.pallets.find(({
4330
- name
4331
- }) => name === pallet)?.constants.find(({
4332
- name
4333
- }) => name === constant)?.value;
4334
- if (!encodedValue) return null;
4335
- const codec = builder.buildConstant(pallet, constant);
4336
- return codec.dec(encodedValue);
4337
- };
4338
-
4339
4432
  const fetchBalances$4 = async ({
4340
4433
  networkId,
4341
4434
  tokensWithAddresses,
@@ -4344,7 +4437,7 @@ const fetchBalances$4 = async ({
4344
4437
  }) => {
4345
4438
  const balanceDefs = getBalanceDefs(tokensWithAddresses);
4346
4439
  if (!miniMetadata?.data) {
4347
- log.warn("MiniMetadata is required for fetching balances");
4440
+ log.warn(`MiniMetadata is required for fetching ${MODULE_TYPE$3} balances on ${networkId}.`);
4348
4441
  return {
4349
4442
  success: [],
4350
4443
  errors: balanceDefs.map(def => ({
@@ -4591,7 +4684,7 @@ const getTransferCallData$3 = ({
4591
4684
  };
4592
4685
  };
4593
4686
 
4594
- const SUBSCRIPTION_INTERVAL$3 = 6_000;
4687
+ const SUBSCRIPTION_INTERVAL$2 = 6_000;
4595
4688
  const subscribeBalances$3 = ({
4596
4689
  networkId,
4597
4690
  tokensWithAddresses,
@@ -4614,7 +4707,7 @@ const subscribeBalances$3 = ({
4614
4707
  });
4615
4708
  if (abortController.signal.aborted) return;
4616
4709
  subscriber.next(balances);
4617
- setTimeout(poll, SUBSCRIPTION_INTERVAL$3);
4710
+ setTimeout(poll, SUBSCRIPTION_INTERVAL$2);
4618
4711
  } catch (error) {
4619
4712
  log.error("Error", {
4620
4713
  module: MODULE_TYPE$3,
@@ -4646,140 +4739,6 @@ const SubHydrationBalanceModule = {
4646
4739
  const MODULE_TYPE$2 = chaindataProvider.SubNativeTokenSchema.shape.type.value;
4647
4740
  const PLATFORM$2 = chaindataProvider.SubNativeTokenSchema.shape.platform.value;
4648
4741
 
4649
- /**
4650
- * Pass some these into an `RpcStateQueryHelper` in order to easily batch multiple state queries into the one rpc call.
4651
- */
4652
-
4653
- const fetchQueriesPack = async (connector, networkId, queries) => {
4654
- const allStateKeys = queries.flatMap(({
4655
- stateKeys
4656
- }) => stateKeys).filter(util.isNotNil);
4657
-
4658
- // doing a query with only null keys would throw an error => return early
4659
- if (!allStateKeys.length) return queries.map(({
4660
- stateKeys,
4661
- decodeResult
4662
- }) => decodeResult(stateKeys.map(() => null)));
4663
- const response = await connector.send(networkId, "state_queryStorageAt", [allStateKeys]);
4664
- const results = queries.reduce((acc, {
4665
- stateKeys,
4666
- decodeResult
4667
- }) => {
4668
- const changes = stateKeys.map(stateKey => {
4669
- if (!stateKey) return null;
4670
- const change = response[0].changes.find(([key]) => key === stateKey);
4671
- if (!change) return null;
4672
- return change[1];
4673
- });
4674
- acc.push(decodeResult(changes));
4675
- return acc;
4676
- }, []);
4677
- return results;
4678
- };
4679
-
4680
- /**
4681
- * Used by a variety of balance modules to help batch multiple state queries into the one rpc call.
4682
- */
4683
- // export class RpcStateQueriesHelper<T> {
4684
- // #connector: ChainConnector
4685
- // #queries: Array<RpcStateQueries<T>>
4686
-
4687
- // constructor(connector: ChainConnector, queries: Array<RpcStateQueries<T>>) {
4688
- // this.#connector = connector
4689
- // this.#queries = queries
4690
- // }
4691
-
4692
- // async subscribe(
4693
- // networkId: DotNetworkId,
4694
- // callback: SubscriptionCallback<T[]>,
4695
- // timeout: number | false = false,
4696
- // subscribeMethod = "state_subscribeStorage",
4697
- // responseMethod = "state_storage",
4698
- // unsubscribeMethod = "state_unsubscribeStorage",
4699
- // ): Promise<UnsubscribeFn> {
4700
- // const params = [this.#queries.flatMap(({ stateKeys }) => stateKeys)]
4701
-
4702
- // const unsub = this.#connector.subscribe(
4703
- // networkId,
4704
- // subscribeMethod,
4705
- // responseMethod,
4706
- // params,
4707
- // (error, result) => {
4708
- // error
4709
- // ? callback(error)
4710
- // : callback(null, this.#distributeChangesToQueryDecoders.call(this, chainId, result))
4711
- // },
4712
- // timeout,
4713
- // )
4714
-
4715
- // const subscriptions = queries.map(([chainId, queries]) => {
4716
- // const params = [queries.map(({ stateKey }) => stateKey)]
4717
-
4718
- // const unsub = this.#connector.subscribe(
4719
- // networkId,
4720
- // subscribeMethod,
4721
- // responseMethod,
4722
- // params,
4723
- // (error, result) => {
4724
- // error
4725
- // ? callback(error)
4726
- // : callback(null, this.#distributeChangesToQueryDecoders.call(this, chainId, result))
4727
- // },
4728
- // timeout,
4729
- // )
4730
-
4731
- // return () => unsub.then((unsubscribe) => unsubscribe(unsubscribeMethod))
4732
- // })
4733
-
4734
- // return () => subscriptions.forEach((unsubscribe) => unsubscribe())
4735
- // }
4736
-
4737
- // async fetch(method = "state_queryStorageAt"): Promise<T[]> {
4738
- // const queriesByChain = groupBy(this.#queries, "chainId")
4739
-
4740
- // const resultsByChain = await Promise.all(
4741
- // Object.entries(queriesByChain).map(async ([chainId, queries]) => {
4742
- // const params = [queries.map(({ stateKey }) => stateKey)]
4743
-
4744
- // const result = (await this.#connector.send(chainId, method, params))[0]
4745
- // return this.#distributeChangesToQueryDecoders.call(this, chainId, result)
4746
- // }),
4747
- // )
4748
-
4749
- // return resultsByChain.flatMap((result) => result)
4750
- // }
4751
-
4752
- // #distributeChangesToQueryDecoders(chainId: DotNetworkId, result: unknown): T[] {
4753
- // if (typeof result !== "object" || result === null) return []
4754
- // if (!hasOwnProperty(result, "changes") || typeof result.changes !== "object") return []
4755
- // if (!Array.isArray(result.changes)) return []
4756
-
4757
- // return result.changes.flatMap(([reference, change]: [unknown, unknown]): [T] | [] => {
4758
- // if (typeof reference !== "string") {
4759
- // log.warn(`Received non-string reference in RPC result: ${reference}`)
4760
- // return []
4761
- // }
4762
-
4763
- // if (typeof change !== "string" && change !== null) {
4764
- // log.warn(`Received non-string and non-null change in RPC result: ${reference} | ${change}`)
4765
- // return []
4766
- // }
4767
-
4768
- // const query = this.#queries.find(
4769
- // ({ chainId: cId, stateKey }) => cId === chainId && stateKey === reference,
4770
- // )
4771
- // if (!query) {
4772
- // log.warn(
4773
- // `Failed to find query:\n${reference} in\n${this.#queries.map(({ stateKey }) => stateKey)}`,
4774
- // )
4775
- // return []
4776
- // }
4777
-
4778
- // return [query.decodeResult(change)]
4779
- // })
4780
- // }
4781
- // }
4782
-
4783
4742
  const SUBTENSOR_ROOT_NETUID$1 = 0;
4784
4743
  const SUBTENSOR_MIN_STAKE_AMOUNT_PLANK$1 = 1000000n;
4785
4744
  const TAO_DECIMALS$1 = 9n;
@@ -5499,7 +5458,7 @@ const fetchBalances$3 = async ({
5499
5458
  }) => {
5500
5459
  const balanceDefs = getBalanceDefs(tokensWithAddresses);
5501
5460
  if (!miniMetadata?.data) {
5502
- log.warn("MiniMetadata is required for fetching balances");
5461
+ log.warn(`MiniMetadata is required for fetching ${MODULE_TYPE$2} balances on ${networkId}.`);
5503
5462
  return {
5504
5463
  success: [],
5505
5464
  errors: balanceDefs.map(def => ({
@@ -5531,12 +5490,12 @@ const fetchBalances$3 = async ({
5531
5490
  }))
5532
5491
  };
5533
5492
  }
5534
- const queries = buildBaseQueries(networkId, balanceDefs, miniMetadata);
5535
- const partialBalances = await fetchQueriesPack(connector, networkId, queries);
5493
+ const baseQueries = buildBaseQueries(networkId, balanceDefs, miniMetadata);
5494
+ const partialBalances = await fetchRpcQueryPack(connector, networkId, baseQueries);
5536
5495
 
5537
5496
  // now for each balance that includes nomPoolStaking, we need to fetch the metadata for the pool
5538
5497
  const nomPoolQueries = buildNomPoolQueries(networkId, partialBalances, miniMetadata);
5539
- const balances = await fetchQueriesPack(connector, networkId, nomPoolQueries);
5498
+ const balances = await fetchRpcQueryPack(connector, networkId, nomPoolQueries);
5540
5499
 
5541
5500
  // TODO ⚠️ dedupe locks
5542
5501
 
@@ -5772,46 +5731,32 @@ const getTransferAllEncodedArgs = (to, codec) => {
5772
5731
  })]);
5773
5732
  };
5774
5733
 
5775
- const SUBSCRIPTION_INTERVAL$2 = 6_000;
5776
5734
  const subscribeBalances$2 = ({
5777
5735
  networkId,
5778
5736
  tokensWithAddresses,
5779
5737
  connector,
5780
5738
  miniMetadata
5781
5739
  }) => {
5782
- return new rxjs.Observable(subscriber => {
5783
- const abortController = new AbortController();
5784
-
5785
- // on hydration balances are fetched using a runtimeApi, which can't be subscribed to.
5786
- // => poll values for each block
5787
- const poll = async () => {
5788
- try {
5789
- if (abortController.signal.aborted) return;
5790
- const balances = await fetchBalances$3({
5791
- networkId,
5792
- tokensWithAddresses: tokensWithAddresses,
5793
- connector,
5794
- miniMetadata
5795
- });
5796
- if (abortController.signal.aborted) return;
5797
- subscriber.next(balances);
5798
- setTimeout(poll, SUBSCRIPTION_INTERVAL$2);
5799
- } catch (error) {
5800
- log.error("Error", {
5801
- module: MODULE_TYPE$2,
5802
- networkId,
5803
- miniMetadata,
5804
- addressesByToken: tokensWithAddresses,
5805
- error
5806
- });
5807
- subscriber.error(error);
5808
- }
5809
- };
5810
- poll();
5811
- return () => {
5812
- abortController.abort();
5740
+ // could be use as shared observable key if we decide to cache the sub
5741
+ const balanceDefs = getBalanceDefs(tokensWithAddresses);
5742
+ const baseQueries = buildBaseQueries(networkId, balanceDefs, miniMetadata);
5743
+ const baseBalances$ = getRpcQueryPack$(connector, networkId, baseQueries).pipe(rxjs.switchMap(partialBalances => {
5744
+ // now for each balance that includes nomPoolStaking, we need to fetch the metadata for the pool
5745
+ const nomPoolQueries = buildNomPoolQueries(networkId, partialBalances, miniMetadata);
5746
+ return getRpcQueryPack$(connector, networkId, nomPoolQueries);
5747
+ }));
5748
+ const subtensorBalancesByAddress$ = getSubtensorStakingBalances$(connector, networkId, balanceDefs, miniMetadata);
5749
+ return rxjs.combineLatest([baseBalances$, subtensorBalancesByAddress$]).pipe(rxjs.map(([baseBalances, subtensorBalancesByAddress]) => {
5750
+ // add subtensor balances to base balances
5751
+ for (const [address, subtensorBalances] of lodash.toPairs(subtensorBalancesByAddress)) {
5752
+ const balance = baseBalances.find(b => b.address === address);
5753
+ if (balance?.values) balance.values.push(...subtensorBalances);
5754
+ }
5755
+ return {
5756
+ success: baseBalances,
5757
+ errors: []
5813
5758
  };
5814
- }).pipe(rxjs.distinctUntilChanged(lodash.isEqual));
5759
+ }));
5815
5760
  };
5816
5761
 
5817
5762
  const SubNativeBalanceModule = {
@@ -7251,7 +7196,7 @@ const fetchBalances$1 = async ({
7251
7196
  }) => {
7252
7197
  const balanceDefs = getBalanceDefs(tokensWithAddresses);
7253
7198
  if (!miniMetadata?.data) {
7254
- log.warn("MiniMetadata is required for fetching balances");
7199
+ log.warn(`MiniMetadata is required for fetching ${MODULE_TYPE} balances on ${networkId}.`);
7255
7200
  return {
7256
7201
  success: [],
7257
7202
  errors: balanceDefs.map(def => ({
@@ -10471,9 +10416,17 @@ class BalancesProvider {
10471
10416
  miniMetadatas: lodash.values(miniMetadatas).filter(util.isNotNil)
10472
10417
  })));
10473
10418
  }
10474
- getBalances$(addressesByToken) {
10475
- const networkIds = lodash.uniq(lodash.keys(addressesByToken).map(tokenId => chaindataProvider.parseTokenId(tokenId).networkId));
10476
- return rxjs.combineLatest(networkIds.map(networkId => this.getNetworkBalances$(networkId, addressesByToken))).pipe(rxjs.map(results => {
10419
+
10420
+ // this is the only public method
10421
+ getBalances$(addressesByTokenId) {
10422
+ // split by network
10423
+ const addressesByTokenIdByNetworkId = lodash.toPairs(addressesByTokenId).reduce((acc, [tokenId, addresses]) => {
10424
+ const networkId = chaindataProvider.parseTokenId(tokenId).networkId;
10425
+ if (!acc[networkId]) acc[networkId] = {};
10426
+ acc[networkId][tokenId] = addresses;
10427
+ return acc;
10428
+ }, {});
10429
+ return rxjs.combineLatest(lodash.toPairs(addressesByTokenIdByNetworkId).map(([networkId]) => this.getNetworkBalances$(networkId, addressesByTokenIdByNetworkId[networkId]))).pipe(rxjs.map(results => {
10477
10430
  return {
10478
10431
  status: results.some(({
10479
10432
  status
@@ -10482,9 +10435,17 @@ class BalancesProvider {
10482
10435
  };
10483
10436
  }), rxjs.startWith({
10484
10437
  status: "initialising",
10485
- balances: this.getStoredBalances(addressesByToken)
10438
+ balances: this.getStoredBalances(addressesByTokenId)
10486
10439
  }), rxjs.distinctUntilChanged(lodash.isEqual));
10487
10440
  }
10441
+ fetchBalances(addressesByTokenId) {
10442
+ // TODO: better
10443
+ return rxjs.firstValueFrom(this.getBalances$(addressesByTokenId).pipe(rxjs.filter(({
10444
+ status
10445
+ }) => status === "live"), rxjs.map(({
10446
+ balances
10447
+ }) => balances)));
10448
+ }
10488
10449
  getNetworkBalances$(networkId, addressesByTokenId) {
10489
10450
  const network$ = this.#chaindataProvider.getNetworkById$(networkId);
10490
10451
  const tokensMapById$ = this.#chaindataProvider.getTokensMapById$();
@@ -10556,7 +10517,42 @@ class BalancesProvider {
10556
10517
  }));
10557
10518
  }
10558
10519
  getNetworkMiniMetadatas$(networkId) {
10559
- 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([])));
10520
+ return this.#chaindataProvider.getNetworkById$(networkId).pipe(rxjs.switchMap(network => chaindataProvider.isNetworkDot(network) && this.#chainConnectors.substrate ? rxjs.from(getSpecVersion(this.#chainConnectors.substrate, networkId)).pipe(rxjs.switchMap(specVersion => this.getMiniMetadatas$(networkId, specVersion))) : rxjs.of([])));
10521
+ }
10522
+ getMiniMetadatas$(networkId, specVersion) {
10523
+ return rxjs.combineLatest({
10524
+ defaultMiniMetadatas: this.getDefaultMiniMetadatas$(networkId, specVersion),
10525
+ storedMiniMetadatas: this.getStoredMiniMetadatas$(networkId, specVersion)
10526
+ }).pipe(rxjs.switchMap(({
10527
+ storedMiniMetadatas,
10528
+ defaultMiniMetadatas
10529
+ }) => {
10530
+ if (defaultMiniMetadatas.length) return rxjs.of(defaultMiniMetadatas);
10531
+ if (storedMiniMetadatas.length) return rxjs.of(storedMiniMetadatas);
10532
+ if (!this.#chainConnectors.substrate) return rxjs.of([]);
10533
+ return rxjs.from(
10534
+ // fetch them from the chain
10535
+ getMiniMetadatas(this.#chainConnectors.substrate, this.#chaindataProvider, networkId)).pipe(
10536
+ // and persist in storage for later reuse
10537
+ rxjs.tap(newMiniMetadatas => {
10538
+ if (!newMiniMetadatas.length) return;
10539
+ const storage = this.#storage.getValue();
10540
+ const miniMetadatas = lodash.assign(
10541
+ // keep minimetadatas of other networks
10542
+ lodash.keyBy(lodash.values(storage.miniMetadatas).filter(m => m.chainId !== networkId), m => m.id),
10543
+ // add the ones for our network
10544
+ lodash.keyBy(newMiniMetadatas, m => m.id));
10545
+ this.#storage.next(lodash.assign({}, storage, {
10546
+ miniMetadatas
10547
+ }));
10548
+ }));
10549
+ }));
10550
+ }
10551
+ getStoredMiniMetadatas$(networkId, specVersion) {
10552
+ return this.storage$.pipe(rxjs.map(storage => storage.miniMetadatas.filter(m => m.chainId === networkId && m.specVersion === specVersion && m.version === chaindataProvider.MINIMETADATA_VERSION)), rxjs.distinctUntilChanged(lodash.isEqual));
10553
+ }
10554
+ getDefaultMiniMetadatas$(networkId, specVersion) {
10555
+ return this.#chaindataProvider.miniMetadatas$.pipe(rxjs.map(miniMetadatas => miniMetadatas.filter(m => m.chainId === networkId && m.specVersion === specVersion && m.version === chaindataProvider.MINIMETADATA_VERSION)), rxjs.distinctUntilChanged(lodash.isEqual));
10560
10556
  }
10561
10557
  getStoredBalances(addressesByToken) {
10562
10558
  const balanceDefs = lodash.toPairs(addressesByToken).flatMap(([tokenId, addresses]) => addresses.map(address => [tokenId, address]));
@@ -10567,13 +10563,6 @@ class BalancesProvider {
10567
10563
  }
10568
10564
  }
10569
10565
 
10570
- // const getStoredBalances = (
10571
- // storedBalances: Record<string, IBalance>,
10572
- // addressesByToken: Record<TokenId, Address[]>,
10573
- // ): IBalance[] => {
10574
-
10575
- // }
10576
-
10577
10566
  Object.defineProperty(exports, "MINIMETADATA_VERSION", {
10578
10567
  enumerable: true,
10579
10568
  get: function () { return chaindataProvider.MINIMETADATA_VERSION; }