@talismn/balances 0.0.0-pr2043-20250626063312 → 0.0.0-pr2043-20250626133240

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.
@@ -126,7 +126,7 @@ class EvmTokenFetcher {
126
126
 
127
127
  var pkg = {
128
128
  name: "@talismn/balances",
129
- version: "0.0.0-pr2043-20250626063312"};
129
+ version: "0.0.0-pr2043-20250626133240"};
130
130
 
131
131
  var log = anylogger__default.default(pkg.name);
132
132
 
@@ -3659,11 +3659,18 @@ const getAddresssesByTokenByNetwork = addressesByToken => {
3659
3659
  };
3660
3660
 
3661
3661
  async function subscribeBase(queries, chainConnector, callback) {
3662
- const unsubscribe = await new RpcStateQueryHelper(chainConnector, queries).subscribe((error, result) => {
3663
- if (error) callback(error);
3664
- if (result && result.length > 0) callback(null, result);
3665
- });
3666
- return unsubscribe;
3662
+ try {
3663
+ const unsubscribe = await new RpcStateQueryHelper(chainConnector, queries).subscribe((error, result) => {
3664
+ if (error) callback(error);
3665
+ if (result && result.length > 0) callback(null, result);
3666
+ });
3667
+ return unsubscribe;
3668
+ } catch (err) {
3669
+ if (!util.isAbortError(err)) log.error("Error subscribing to base queries", {
3670
+ err
3671
+ });
3672
+ return () => {};
3673
+ }
3667
3674
  }
3668
3675
 
3669
3676
  /**
@@ -3700,284 +3707,291 @@ const nompoolStashAccountId = (palletId, poolId) => nompoolAccountId(palletId, p
3700
3707
 
3701
3708
  // TODO make this method chain-specific
3702
3709
  async function subscribeNompoolStaking(chaindataProvider$1, chainConnector, addressesByToken, callback, signal) {
3703
- const allChains = await chaindataProvider$1.getNetworksMapById("polkadot");
3704
- const tokens = await chaindataProvider$1.getTokensMapById();
3705
-
3706
- // there should be only one network here when subscribing to balances, we've split it up by network at the top level
3707
- const networkIds = lodash.keys(addressesByToken).map(tokenId => chaindataProvider.parseTokenId(tokenId).networkId);
3708
- const miniMetadatas = new Map();
3709
- for (const networkId of networkIds) {
3710
- const miniMetadata = await getMiniMetadata(chaindataProvider$1, chainConnector, networkId, "substrate-native");
3711
- miniMetadatas.set(networkId, miniMetadata);
3712
- }
3713
- signal?.throwIfAborted();
3714
- const nomPoolTokenIds = Object.entries(tokens).filter(([, token]) => {
3715
- // ignore non-native tokens
3716
- if (token.type !== "substrate-native") return false;
3717
-
3718
- // ignore tokens on chains with no nompools pallet
3719
- const miniMetadata = miniMetadatas.get(token.networkId);
3720
- return typeof miniMetadata?.extra?.nominationPoolsPalletId === "string";
3721
- }).map(([tokenId]) => tokenId);
3722
-
3723
- // staking can only be done by the native token on chains with the staking pallet
3724
- const addressesByNomPoolToken = Object.fromEntries(Object.entries(addressesByToken)
3725
- // remove ethereum addresses
3726
- .map(([tokenId, addresses]) => [tokenId, addresses.filter(address => !util.isEthereumAddress(address))])
3727
- // remove tokens which aren't nom pool tokens
3728
- .filter(([tokenId]) => nomPoolTokenIds.includes(tokenId)));
3729
- const uniqueChainIds = getUniqueChainIds(addressesByNomPoolToken, tokens);
3730
- const chains = Object.fromEntries(Object.entries(allChains).filter(([chainId]) => uniqueChainIds.includes(chainId)));
3731
- const chainStorageCoders = buildStorageCoders({
3732
- chainIds: uniqueChainIds,
3733
- chains,
3734
- miniMetadatas,
3735
- coders: {
3736
- poolMembers: ["NominationPools", "PoolMembers"],
3737
- bondedPools: ["NominationPools", "BondedPools"],
3738
- ledger: ["Staking", "Ledger"],
3739
- metadata: ["NominationPools", "Metadata"]
3740
- }
3741
- });
3742
- const resultUnsubscribes = [];
3743
- for (const [tokenId, addresses] of Object.entries(addressesByNomPoolToken)) {
3744
- const token = tokens[tokenId];
3745
- if (!token) {
3746
- log.warn(`Token ${tokenId} not found`);
3747
- continue;
3748
- }
3749
- if (token.type !== "substrate-native") {
3750
- log.debug(`This module doesn't handle tokens of type ${token.type}`);
3751
- continue;
3752
- }
3753
- const chainId = token.networkId;
3754
- if (!chainId) {
3755
- log.warn(`Token ${tokenId} has no chain`);
3756
- continue;
3757
- }
3758
- const chain = chains[chainId];
3759
- if (!chain) {
3760
- log.warn(`Chain ${chainId} for token ${tokenId} not found`);
3761
- continue;
3710
+ try {
3711
+ const allChains = await chaindataProvider$1.getNetworksMapById("polkadot");
3712
+ const tokens = await chaindataProvider$1.getTokensMapById();
3713
+
3714
+ // there should be only one network here when subscribing to balances, we've split it up by network at the top level
3715
+ const networkIds = lodash.keys(addressesByToken).map(tokenId => chaindataProvider.parseTokenId(tokenId).networkId);
3716
+ const miniMetadatas = new Map();
3717
+ for (const networkId of networkIds) {
3718
+ const miniMetadata = await getMiniMetadata(chaindataProvider$1, chainConnector, networkId, "substrate-native");
3719
+ miniMetadatas.set(networkId, miniMetadata);
3762
3720
  }
3763
- const miniMetadata = miniMetadatas.get(chainId);
3764
- const {
3765
- nominationPoolsPalletId
3766
- } = miniMetadata?.extra ?? {};
3767
- const subscribePoolMembers = (addresses, callback) => {
3768
- const scaleCoder = chainStorageCoders.get(chainId)?.poolMembers;
3769
- const queries = addresses.flatMap(address => {
3770
- const stateKey = scale.encodeStateKey(scaleCoder, `Invalid address in ${chainId} poolMembers query ${address}`, address);
3771
- if (!stateKey) return [];
3772
- const decodeResult = change => {
3773
- /** NOTE: This type is only a hint for typescript, the chain can actually return whatever it wants to */
3774
-
3775
- const decoded = scale.decodeScale(scaleCoder, change, `Failed to decode poolMembers on chain ${chainId}`);
3776
- const poolId = decoded?.pool_id?.toString?.();
3777
- const points = decoded?.points?.toString?.();
3778
- const unbondingEras = Array.from(decoded?.unbonding_eras ?? []).flatMap(entry => {
3779
- if (entry === undefined) return [];
3780
- const [key, value] = Array.from(entry);
3781
- const era = key?.toString?.();
3782
- const amount = value?.toString?.();
3783
- if (typeof era !== "string" || typeof amount !== "string") return [];
3721
+ signal?.throwIfAborted();
3722
+ const nomPoolTokenIds = Object.entries(tokens).filter(([, token]) => {
3723
+ // ignore non-native tokens
3724
+ if (token.type !== "substrate-native") return false;
3725
+
3726
+ // ignore tokens on chains with no nompools pallet
3727
+ const miniMetadata = miniMetadatas.get(token.networkId);
3728
+ return typeof miniMetadata?.extra?.nominationPoolsPalletId === "string";
3729
+ }).map(([tokenId]) => tokenId);
3730
+
3731
+ // staking can only be done by the native token on chains with the staking pallet
3732
+ const addressesByNomPoolToken = Object.fromEntries(Object.entries(addressesByToken)
3733
+ // remove ethereum addresses
3734
+ .map(([tokenId, addresses]) => [tokenId, addresses.filter(address => !util.isEthereumAddress(address))])
3735
+ // remove tokens which aren't nom pool tokens
3736
+ .filter(([tokenId]) => nomPoolTokenIds.includes(tokenId)));
3737
+ const uniqueChainIds = getUniqueChainIds(addressesByNomPoolToken, tokens);
3738
+ const chains = Object.fromEntries(Object.entries(allChains).filter(([chainId]) => uniqueChainIds.includes(chainId)));
3739
+ const chainStorageCoders = buildStorageCoders({
3740
+ chainIds: uniqueChainIds,
3741
+ chains,
3742
+ miniMetadatas,
3743
+ coders: {
3744
+ poolMembers: ["NominationPools", "PoolMembers"],
3745
+ bondedPools: ["NominationPools", "BondedPools"],
3746
+ ledger: ["Staking", "Ledger"],
3747
+ metadata: ["NominationPools", "Metadata"]
3748
+ }
3749
+ });
3750
+ const resultUnsubscribes = [];
3751
+ for (const [tokenId, addresses] of Object.entries(addressesByNomPoolToken)) {
3752
+ const token = tokens[tokenId];
3753
+ if (!token) {
3754
+ log.warn(`Token ${tokenId} not found`);
3755
+ continue;
3756
+ }
3757
+ if (token.type !== "substrate-native") {
3758
+ log.debug(`This module doesn't handle tokens of type ${token.type}`);
3759
+ continue;
3760
+ }
3761
+ const chainId = token.networkId;
3762
+ if (!chainId) {
3763
+ log.warn(`Token ${tokenId} has no chain`);
3764
+ continue;
3765
+ }
3766
+ const chain = chains[chainId];
3767
+ if (!chain) {
3768
+ log.warn(`Chain ${chainId} for token ${tokenId} not found`);
3769
+ continue;
3770
+ }
3771
+ const miniMetadata = miniMetadatas.get(chainId);
3772
+ const {
3773
+ nominationPoolsPalletId
3774
+ } = miniMetadata?.extra ?? {};
3775
+ const subscribePoolMembers = (addresses, callback) => {
3776
+ const scaleCoder = chainStorageCoders.get(chainId)?.poolMembers;
3777
+ const queries = addresses.flatMap(address => {
3778
+ const stateKey = scale.encodeStateKey(scaleCoder, `Invalid address in ${chainId} poolMembers query ${address}`, address);
3779
+ if (!stateKey) return [];
3780
+ const decodeResult = change => {
3781
+ /** NOTE: This type is only a hint for typescript, the chain can actually return whatever it wants to */
3782
+
3783
+ const decoded = scale.decodeScale(scaleCoder, change, `Failed to decode poolMembers on chain ${chainId}`);
3784
+ const poolId = decoded?.pool_id?.toString?.();
3785
+ const points = decoded?.points?.toString?.();
3786
+ const unbondingEras = Array.from(decoded?.unbonding_eras ?? []).flatMap(entry => {
3787
+ if (entry === undefined) return [];
3788
+ const [key, value] = Array.from(entry);
3789
+ const era = key?.toString?.();
3790
+ const amount = value?.toString?.();
3791
+ if (typeof era !== "string" || typeof amount !== "string") return [];
3792
+ return {
3793
+ era,
3794
+ amount
3795
+ };
3796
+ });
3784
3797
  return {
3785
- era,
3786
- amount
3798
+ tokenId,
3799
+ address,
3800
+ poolId,
3801
+ points,
3802
+ unbondingEras
3787
3803
  };
3788
- });
3804
+ };
3789
3805
  return {
3790
- tokenId,
3791
- address,
3806
+ chainId,
3807
+ stateKey,
3808
+ decodeResult
3809
+ };
3810
+ });
3811
+ const subscription = new RpcStateQueryHelper(chainConnector, queries).subscribe(callback);
3812
+ return () => subscription.then(unsubscribe => unsubscribe());
3813
+ };
3814
+ const subscribePoolPoints = (poolIds, callback) => {
3815
+ if (poolIds.length === 0) callback(null, []);
3816
+ const scaleCoder = chainStorageCoders.get(chainId)?.bondedPools;
3817
+ const queries = poolIds.flatMap(poolId => {
3818
+ const stateKey = scale.encodeStateKey(scaleCoder, `Invalid poolId in ${chainId} bondedPools query ${poolId}`, poolId);
3819
+ if (!stateKey) return [];
3820
+ const decodeResult = change => {
3821
+ /** NOTE: This type is only a hint for typescript, the chain can actually return whatever it wants to */
3822
+
3823
+ const decoded = scale.decodeScale(scaleCoder, change, `Failed to decode bondedPools on chain ${chainId}`);
3824
+ const points = decoded?.points?.toString?.();
3825
+ return {
3826
+ poolId,
3827
+ points
3828
+ };
3829
+ };
3830
+ return {
3831
+ chainId,
3832
+ stateKey,
3833
+ decodeResult
3834
+ };
3835
+ });
3836
+ const subscription = new RpcStateQueryHelper(chainConnector, queries).subscribe(callback);
3837
+ return () => subscription.then(unsubscribe => unsubscribe());
3838
+ };
3839
+ const subscribePoolStake = (poolIds, callback) => {
3840
+ if (poolIds.length === 0) callback(null, []);
3841
+ const scaleCoder = chainStorageCoders.get(chainId)?.ledger;
3842
+ const queries = poolIds.flatMap(poolId => {
3843
+ if (!nominationPoolsPalletId) return [];
3844
+ const stashAddress = nompoolStashAccountId(nominationPoolsPalletId, poolId);
3845
+ const stateKey = scale.encodeStateKey(scaleCoder, `Invalid address in ${chainId} ledger query ${stashAddress}`, stashAddress);
3846
+ if (!stateKey) return [];
3847
+ const decodeResult = change => {
3848
+ /** NOTE: This type is only a hint for typescript, the chain can actually return whatever it wants to */
3849
+
3850
+ const decoded = scale.decodeScale(scaleCoder, change, `Failed to decode ledger on chain ${chainId}`);
3851
+ const activeStake = decoded?.active?.toString?.();
3852
+ return {
3853
+ poolId,
3854
+ activeStake
3855
+ };
3856
+ };
3857
+ return {
3858
+ chainId,
3859
+ stateKey,
3860
+ decodeResult
3861
+ };
3862
+ });
3863
+ const subscription = new RpcStateQueryHelper(chainConnector, queries).subscribe(callback);
3864
+ return () => subscription.then(unsubscribe => unsubscribe());
3865
+ };
3866
+ const subscribePoolMetadata = (poolIds, callback) => {
3867
+ if (poolIds.length === 0) callback(null, []);
3868
+ const scaleCoder = chainStorageCoders.get(chainId)?.metadata;
3869
+ const queries = poolIds.flatMap(poolId => {
3870
+ if (!nominationPoolsPalletId) return [];
3871
+ const stateKey = scale.encodeStateKey(scaleCoder, `Invalid poolId in ${chainId} metadata query ${poolId}`, poolId);
3872
+ if (!stateKey) return [];
3873
+ const decodeResult = change => {
3874
+ /** NOTE: This type is only a hint for typescript, the chain can actually return whatever it wants to */
3875
+
3876
+ const decoded = scale.decodeScale(scaleCoder, change, `Failed to decode metadata on chain ${chainId}`);
3877
+ const metadata = decoded?.asText?.();
3878
+ return {
3879
+ poolId,
3880
+ metadata
3881
+ };
3882
+ };
3883
+ return {
3884
+ chainId,
3885
+ stateKey,
3886
+ decodeResult
3887
+ };
3888
+ });
3889
+ const subscription = new RpcStateQueryHelper(chainConnector, queries).subscribe(callback);
3890
+ return () => subscription.then(unsubscribe => unsubscribe());
3891
+ };
3892
+ const poolMembersByAddress$ = asObservable(subscribePoolMembers)(addresses).pipe(rxjs.scan((state, next) => {
3893
+ for (const poolMembers of next) {
3894
+ const {
3792
3895
  poolId,
3793
3896
  points,
3794
3897
  unbondingEras
3795
- };
3796
- };
3797
- return {
3798
- chainId,
3799
- stateKey,
3800
- decodeResult
3801
- };
3802
- });
3803
- const subscription = new RpcStateQueryHelper(chainConnector, queries).subscribe(callback);
3804
- return () => subscription.then(unsubscribe => unsubscribe());
3805
- };
3806
- const subscribePoolPoints = (poolIds, callback) => {
3807
- if (poolIds.length === 0) callback(null, []);
3808
- const scaleCoder = chainStorageCoders.get(chainId)?.bondedPools;
3809
- const queries = poolIds.flatMap(poolId => {
3810
- const stateKey = scale.encodeStateKey(scaleCoder, `Invalid poolId in ${chainId} bondedPools query ${poolId}`, poolId);
3811
- if (!stateKey) return [];
3812
- const decodeResult = change => {
3813
- /** NOTE: This type is only a hint for typescript, the chain can actually return whatever it wants to */
3814
-
3815
- const decoded = scale.decodeScale(scaleCoder, change, `Failed to decode bondedPools on chain ${chainId}`);
3816
- const points = decoded?.points?.toString?.();
3817
- return {
3898
+ } = poolMembers;
3899
+ if (typeof poolId === "string" && typeof points === "string") state.set(poolMembers.address, {
3900
+ poolId,
3901
+ points,
3902
+ unbondingEras
3903
+ });else state.set(poolMembers.address, null);
3904
+ }
3905
+ return state;
3906
+ }, new Map()), rxjs.share());
3907
+ const poolIdByAddress$ = poolMembersByAddress$.pipe(rxjs.map(pm => new Map(Array.from(pm).map(([address, pm]) => [address, pm?.poolId ?? null]))));
3908
+ const pointsByAddress$ = poolMembersByAddress$.pipe(rxjs.map(pm => new Map(Array.from(pm).map(([address, pm]) => [address, pm?.points ?? null]))));
3909
+ const unbondingErasByAddress$ = poolMembersByAddress$.pipe(rxjs.map(pm => new Map(Array.from(pm).map(([address, pm]) => [address, pm?.unbondingEras ?? null]))));
3910
+ const poolIds$ = poolIdByAddress$.pipe(rxjs.map(byAddress => [...new Set(Array.from(byAddress.values()).flatMap(poolId => poolId ?? []))]));
3911
+ const pointsByPool$ = poolIds$.pipe(rxjs.map(poolIds => asObservable(subscribePoolPoints)(poolIds)), rxjs.switchAll(), rxjs.scan((state, next) => {
3912
+ for (const poolPoints of next) {
3913
+ const {
3818
3914
  poolId,
3819
3915
  points
3820
- };
3821
- };
3822
- return {
3823
- chainId,
3824
- stateKey,
3825
- decodeResult
3826
- };
3827
- });
3828
- const subscription = new RpcStateQueryHelper(chainConnector, queries).subscribe(callback);
3829
- return () => subscription.then(unsubscribe => unsubscribe());
3830
- };
3831
- const subscribePoolStake = (poolIds, callback) => {
3832
- if (poolIds.length === 0) callback(null, []);
3833
- const scaleCoder = chainStorageCoders.get(chainId)?.ledger;
3834
- const queries = poolIds.flatMap(poolId => {
3835
- if (!nominationPoolsPalletId) return [];
3836
- const stashAddress = nompoolStashAccountId(nominationPoolsPalletId, poolId);
3837
- const stateKey = scale.encodeStateKey(scaleCoder, `Invalid address in ${chainId} ledger query ${stashAddress}`, stashAddress);
3838
- if (!stateKey) return [];
3839
- const decodeResult = change => {
3840
- /** NOTE: This type is only a hint for typescript, the chain can actually return whatever it wants to */
3841
-
3842
- const decoded = scale.decodeScale(scaleCoder, change, `Failed to decode ledger on chain ${chainId}`);
3843
- const activeStake = decoded?.active?.toString?.();
3844
- return {
3916
+ } = poolPoints;
3917
+ if (typeof points === "string") state.set(poolId, points);else state.delete(poolId);
3918
+ }
3919
+ return state;
3920
+ }, new Map()));
3921
+ const stakeByPool$ = poolIds$.pipe(rxjs.map(poolIds => asObservable(subscribePoolStake)(poolIds)), rxjs.switchAll(), rxjs.scan((state, next) => {
3922
+ for (const poolStake of next) {
3923
+ const {
3845
3924
  poolId,
3846
3925
  activeStake
3847
- };
3848
- };
3849
- return {
3850
- chainId,
3851
- stateKey,
3852
- decodeResult
3853
- };
3854
- });
3855
- const subscription = new RpcStateQueryHelper(chainConnector, queries).subscribe(callback);
3856
- return () => subscription.then(unsubscribe => unsubscribe());
3857
- };
3858
- const subscribePoolMetadata = (poolIds, callback) => {
3859
- if (poolIds.length === 0) callback(null, []);
3860
- const scaleCoder = chainStorageCoders.get(chainId)?.metadata;
3861
- const queries = poolIds.flatMap(poolId => {
3862
- if (!nominationPoolsPalletId) return [];
3863
- const stateKey = scale.encodeStateKey(scaleCoder, `Invalid poolId in ${chainId} metadata query ${poolId}`, poolId);
3864
- if (!stateKey) return [];
3865
- const decodeResult = change => {
3866
- /** NOTE: This type is only a hint for typescript, the chain can actually return whatever it wants to */
3867
-
3868
- const decoded = scale.decodeScale(scaleCoder, change, `Failed to decode metadata on chain ${chainId}`);
3869
- const metadata = decoded?.asText?.();
3870
- return {
3926
+ } = poolStake;
3927
+ if (typeof activeStake === "string") state.set(poolId, activeStake);else state.delete(poolId);
3928
+ }
3929
+ return state;
3930
+ }, new Map()));
3931
+ const metadataByPool$ = poolIds$.pipe(rxjs.map(poolIds => asObservable(subscribePoolMetadata)(poolIds)), rxjs.switchAll(), rxjs.scan((state, next) => {
3932
+ for (const poolMetadata of next) {
3933
+ const {
3871
3934
  poolId,
3872
3935
  metadata
3873
- };
3874
- };
3875
- return {
3876
- chainId,
3877
- stateKey,
3878
- decodeResult
3879
- };
3880
- });
3881
- const subscription = new RpcStateQueryHelper(chainConnector, queries).subscribe(callback);
3882
- return () => subscription.then(unsubscribe => unsubscribe());
3883
- };
3884
- const poolMembersByAddress$ = asObservable(subscribePoolMembers)(addresses).pipe(rxjs.scan((state, next) => {
3885
- for (const poolMembers of next) {
3886
- const {
3887
- poolId,
3888
- points,
3889
- unbondingEras
3890
- } = poolMembers;
3891
- if (typeof poolId === "string" && typeof points === "string") state.set(poolMembers.address, {
3892
- poolId,
3893
- points,
3894
- unbondingEras
3895
- });else state.set(poolMembers.address, null);
3896
- }
3897
- return state;
3898
- }, new Map()), rxjs.share());
3899
- const poolIdByAddress$ = poolMembersByAddress$.pipe(rxjs.map(pm => new Map(Array.from(pm).map(([address, pm]) => [address, pm?.poolId ?? null]))));
3900
- const pointsByAddress$ = poolMembersByAddress$.pipe(rxjs.map(pm => new Map(Array.from(pm).map(([address, pm]) => [address, pm?.points ?? null]))));
3901
- const unbondingErasByAddress$ = poolMembersByAddress$.pipe(rxjs.map(pm => new Map(Array.from(pm).map(([address, pm]) => [address, pm?.unbondingEras ?? null]))));
3902
- const poolIds$ = poolIdByAddress$.pipe(rxjs.map(byAddress => [...new Set(Array.from(byAddress.values()).flatMap(poolId => poolId ?? []))]));
3903
- const pointsByPool$ = poolIds$.pipe(rxjs.map(poolIds => asObservable(subscribePoolPoints)(poolIds)), rxjs.switchAll(), rxjs.scan((state, next) => {
3904
- for (const poolPoints of next) {
3905
- const {
3906
- poolId,
3907
- points
3908
- } = poolPoints;
3909
- if (typeof points === "string") state.set(poolId, points);else state.delete(poolId);
3910
- }
3911
- return state;
3912
- }, new Map()));
3913
- const stakeByPool$ = poolIds$.pipe(rxjs.map(poolIds => asObservable(subscribePoolStake)(poolIds)), rxjs.switchAll(), rxjs.scan((state, next) => {
3914
- for (const poolStake of next) {
3915
- const {
3916
- poolId,
3917
- activeStake
3918
- } = poolStake;
3919
- if (typeof activeStake === "string") state.set(poolId, activeStake);else state.delete(poolId);
3920
- }
3921
- return state;
3922
- }, new Map()));
3923
- const metadataByPool$ = poolIds$.pipe(rxjs.map(poolIds => asObservable(subscribePoolMetadata)(poolIds)), rxjs.switchAll(), rxjs.scan((state, next) => {
3924
- for (const poolMetadata of next) {
3925
- const {
3926
- poolId,
3927
- metadata
3928
- } = poolMetadata;
3929
- if (typeof metadata === "string") state.set(poolId, metadata);else state.delete(poolId);
3930
- }
3931
- return state;
3932
- }, new Map()));
3933
- const subscription = rxjs.combineLatest([poolIdByAddress$, pointsByAddress$, unbondingErasByAddress$, pointsByPool$, stakeByPool$, metadataByPool$]).subscribe({
3934
- next: ([poolIdByAddress, pointsByAddress, unbondingErasByAddress, pointsByPool, stakeByPool, metadataByPool]) => {
3935
- const balances = Array.from(poolIdByAddress).map(([address, poolId]) => {
3936
- const parsedPoolId = poolId === null ? undefined : parseInt(poolId);
3937
- const points = pointsByAddress.get(address) ?? "0";
3938
- const poolPoints = pointsByPool.get(poolId ?? "") ?? "0";
3939
- const poolStake = stakeByPool.get(poolId ?? "") ?? "0";
3940
- const poolMetadata = poolId ? metadataByPool.get(poolId) ?? `Pool ${poolId}` : undefined;
3941
- const amount = points === "0" || poolPoints === "0" || poolStake === "0" ? 0n : BigInt(poolStake) * BigInt(points) / BigInt(poolPoints);
3942
- const unbondingAmount = (unbondingErasByAddress.get(address) ?? []).reduce((total, {
3943
- amount
3944
- }) => total + BigInt(amount ?? "0"), 0n);
3945
- return {
3946
- source: "substrate-native",
3947
- status: "live",
3948
- address,
3949
- networkId: chainId,
3950
- tokenId,
3951
- values: [{
3952
- source: "nompools-staking",
3953
- type: "nompool",
3954
- label: "nompools-staking",
3955
- amount: amount.toString(),
3956
- meta: {
3936
+ } = poolMetadata;
3937
+ if (typeof metadata === "string") state.set(poolId, metadata);else state.delete(poolId);
3938
+ }
3939
+ return state;
3940
+ }, new Map()));
3941
+ const subscription = rxjs.combineLatest([poolIdByAddress$, pointsByAddress$, unbondingErasByAddress$, pointsByPool$, stakeByPool$, metadataByPool$]).subscribe({
3942
+ next: ([poolIdByAddress, pointsByAddress, unbondingErasByAddress, pointsByPool, stakeByPool, metadataByPool]) => {
3943
+ const balances = Array.from(poolIdByAddress).map(([address, poolId]) => {
3944
+ const parsedPoolId = poolId === null ? undefined : parseInt(poolId);
3945
+ const points = pointsByAddress.get(address) ?? "0";
3946
+ const poolPoints = pointsByPool.get(poolId ?? "") ?? "0";
3947
+ const poolStake = stakeByPool.get(poolId ?? "") ?? "0";
3948
+ const poolMetadata = poolId ? metadataByPool.get(poolId) ?? `Pool ${poolId}` : undefined;
3949
+ const amount = points === "0" || poolPoints === "0" || poolStake === "0" ? 0n : BigInt(poolStake) * BigInt(points) / BigInt(poolPoints);
3950
+ const unbondingAmount = (unbondingErasByAddress.get(address) ?? []).reduce((total, {
3951
+ amount
3952
+ }) => total + BigInt(amount ?? "0"), 0n);
3953
+ return {
3954
+ source: "substrate-native",
3955
+ status: "live",
3956
+ address,
3957
+ networkId: chainId,
3958
+ tokenId,
3959
+ values: [{
3960
+ source: "nompools-staking",
3957
3961
  type: "nompool",
3958
- poolId: parsedPoolId,
3959
- description: poolMetadata
3960
- }
3961
- }, {
3962
- source: "nompools-staking",
3963
- type: "nompool",
3964
- label: "nompools-unbonding",
3965
- amount: unbondingAmount.toString(),
3966
- meta: {
3967
- poolId: parsedPoolId,
3968
- description: poolMetadata,
3969
- unbonding: true
3970
- }
3971
- }]
3972
- };
3973
- }).filter(util.isNotNil);
3974
- if (balances.length > 0) callback(null, balances);
3975
- },
3976
- error: error => callback(error)
3962
+ label: "nompools-staking",
3963
+ amount: amount.toString(),
3964
+ meta: {
3965
+ type: "nompool",
3966
+ poolId: parsedPoolId,
3967
+ description: poolMetadata
3968
+ }
3969
+ }, {
3970
+ source: "nompools-staking",
3971
+ type: "nompool",
3972
+ label: "nompools-unbonding",
3973
+ amount: unbondingAmount.toString(),
3974
+ meta: {
3975
+ poolId: parsedPoolId,
3976
+ description: poolMetadata,
3977
+ unbonding: true
3978
+ }
3979
+ }]
3980
+ };
3981
+ }).filter(util.isNotNil);
3982
+ if (balances.length > 0) callback(null, balances);
3983
+ },
3984
+ error: error => callback(error)
3985
+ });
3986
+ resultUnsubscribes.push(() => subscription.unsubscribe());
3987
+ }
3988
+ return () => resultUnsubscribes.forEach(unsub => unsub());
3989
+ } catch (err) {
3990
+ if (!util.isAbortError(err)) log.error("Error subscribing to nom pool staking", {
3991
+ err
3977
3992
  });
3978
- resultUnsubscribes.push(() => subscription.unsubscribe());
3993
+ return () => {};
3979
3994
  }
3980
- return () => resultUnsubscribes.forEach(unsub => unsub());
3981
3995
  }
3982
3996
 
3983
3997
  const SUBTENSOR_ROOT_NETUID = 0;
@@ -4021,227 +4035,234 @@ const calculateTaoFromDynamicInfo = ({
4021
4035
 
4022
4036
  // TODO make this method chain-specific
4023
4037
  async function subscribeSubtensorStaking(chaindataProvider$1, chainConnector, addressesByToken, callback, signal) {
4024
- const allChains = await chaindataProvider$1.getNetworksMapById("polkadot");
4025
- const tokens = await chaindataProvider$1.getTokensMapById();
4026
-
4027
- // there should be only one network here when subscribing to balances, we've split it up by network at the top level
4028
- const networkIds = lodash.keys(addressesByToken).map(tokenId => chaindataProvider.parseTokenId(tokenId).networkId);
4029
- const miniMetadatas = new Map();
4030
- for (const networkId of networkIds) {
4031
- const miniMetadata = await getMiniMetadata(chaindataProvider$1, chainConnector, networkId, "substrate-native", signal);
4032
- miniMetadatas.set(networkId, miniMetadata);
4033
- }
4034
- signal?.throwIfAborted();
4035
- const subtensorTokenIds = Object.entries(tokens).filter(([, token]) => {
4036
- // ignore non-native tokens
4037
- if (token.type !== "substrate-native") return false;
4038
- // ignore tokens on chains with no subtensor pallet
4039
- const miniMetadata = miniMetadatas.get(token.networkId);
4040
- return miniMetadata?.extra?.hasSubtensorPallet === true;
4041
- }).map(([tokenId]) => tokenId);
4042
-
4043
- // staking can only be done by the native token on chains with the subtensor pallet
4044
- const addressesBySubtensorToken = Object.fromEntries(Object.entries(addressesByToken)
4045
- // remove ethereum addresses
4046
- .map(([tokenId, addresses]) => [tokenId, addresses.filter(address => !util.isEthereumAddress(address))])
4047
- // remove tokens which aren't subtensor staking tokens
4048
- .filter(([tokenId]) => subtensorTokenIds.includes(tokenId)));
4049
- const uniqueChainIds = getUniqueChainIds(addressesBySubtensorToken, tokens);
4050
- const chains = Object.fromEntries(Object.entries(allChains).filter(([chainId]) => uniqueChainIds.includes(chainId)));
4051
- const abortController = new AbortController();
4052
- for (const [tokenId, addresses] of Object.entries(addressesBySubtensorToken)) {
4053
- const token = tokens[tokenId];
4054
- if (!token) {
4055
- log.warn(`Token ${tokenId} not found`);
4056
- continue;
4057
- }
4058
- if (token.type !== "substrate-native") {
4059
- log.debug(`This module doesn't handle tokens of type ${token.type}`);
4060
- continue;
4061
- }
4062
- const chainId = token.networkId;
4063
- const chain = chains[chainId];
4064
- if (!chain) {
4065
- log.warn(`Chain ${chainId} for token ${tokenId} not found`);
4066
- continue;
4067
- }
4068
- const miniMetadata = miniMetadatas.get(token.networkId);
4069
- if (!miniMetadata?.data) {
4070
- log.warn(`MiniMetadata for chain ${chainId} not found`);
4071
- continue;
4038
+ try {
4039
+ const allChains = await chaindataProvider$1.getNetworksMapById("polkadot");
4040
+ const tokens = await chaindataProvider$1.getTokensMapById();
4041
+
4042
+ // there should be only one network here when subscribing to balances, we've split it up by network at the top level
4043
+ const networkIds = lodash.keys(addressesByToken).map(tokenId => chaindataProvider.parseTokenId(tokenId).networkId);
4044
+ const miniMetadatas = new Map();
4045
+ for (const networkId of networkIds) {
4046
+ const miniMetadata = await getMiniMetadata(chaindataProvider$1, chainConnector, networkId, "substrate-native", signal);
4047
+ miniMetadatas.set(networkId, miniMetadata);
4072
4048
  }
4073
- const scaleApi = sapi.getScaleApi({
4074
- chainId,
4075
- send: (...args) => chainConnector.send(chainId, ...args, {
4076
- expectErrors: true
4077
- } // don't pollute the wallet logs when this request fails
4078
- )
4079
- }, miniMetadata.data, token, chain.hasCheckMetadataHash, chain.signedExtensions, chain.registryTypes);
4080
-
4081
- // sets the number of addresses to query in parallel (per chain, since each chain runs in parallel to the others)
4082
- const concurrency = 4;
4083
- // In-memory cache for successful dynamic info results
4084
- const dynamicInfoCache = new Map();
4085
- const fetchDynamicInfoForNetuids = async uniqueNetuids => {
4086
- const MAX_RETRIES = 3;
4087
- const RETRY_DELAY_MS = 500;
4088
- const delay = ms => new Promise(resolve => setTimeout(resolve, ms));
4089
- const fetchInfo = async netuid => {
4090
- if (netuid === 0) return null;
4091
- for (let attempt = 1; attempt <= MAX_RETRIES; attempt++) {
4092
- try {
4093
- const params = [netuid];
4094
- const result = await scaleApi.getRuntimeCallValue("SubnetInfoRuntimeApi", "get_dynamic_info", params);
4095
- dynamicInfoCache.set(netuid, result); // Cache successful response
4096
- return result;
4097
- } catch (error) {
4098
- log.trace(`Attempt ${attempt} failed for netuid ${netuid}:`, error);
4099
- if (attempt < MAX_RETRIES) {
4100
- const backoffTime = RETRY_DELAY_MS * 2 ** (attempt - 1);
4101
- log.trace(`Retrying in ${backoffTime}ms...`);
4102
- await delay(backoffTime);
4049
+ signal?.throwIfAborted();
4050
+ const subtensorTokenIds = Object.entries(tokens).filter(([, token]) => {
4051
+ // ignore non-native tokens
4052
+ if (token.type !== "substrate-native") return false;
4053
+ // ignore tokens on chains with no subtensor pallet
4054
+ const miniMetadata = miniMetadatas.get(token.networkId);
4055
+ return miniMetadata?.extra?.hasSubtensorPallet === true;
4056
+ }).map(([tokenId]) => tokenId);
4057
+
4058
+ // staking can only be done by the native token on chains with the subtensor pallet
4059
+ const addressesBySubtensorToken = Object.fromEntries(Object.entries(addressesByToken)
4060
+ // remove ethereum addresses
4061
+ .map(([tokenId, addresses]) => [tokenId, addresses.filter(address => !util.isEthereumAddress(address))])
4062
+ // remove tokens which aren't subtensor staking tokens
4063
+ .filter(([tokenId]) => subtensorTokenIds.includes(tokenId)));
4064
+ const uniqueChainIds = getUniqueChainIds(addressesBySubtensorToken, tokens);
4065
+ const chains = Object.fromEntries(Object.entries(allChains).filter(([chainId]) => uniqueChainIds.includes(chainId)));
4066
+ const abortController = new AbortController();
4067
+ for (const [tokenId, addresses] of Object.entries(addressesBySubtensorToken)) {
4068
+ const token = tokens[tokenId];
4069
+ if (!token) {
4070
+ log.warn(`Token ${tokenId} not found`);
4071
+ continue;
4072
+ }
4073
+ if (token.type !== "substrate-native") {
4074
+ log.debug(`This module doesn't handle tokens of type ${token.type}`);
4075
+ continue;
4076
+ }
4077
+ const chainId = token.networkId;
4078
+ const chain = chains[chainId];
4079
+ if (!chain) {
4080
+ log.warn(`Chain ${chainId} for token ${tokenId} not found`);
4081
+ continue;
4082
+ }
4083
+ const miniMetadata = miniMetadatas.get(token.networkId);
4084
+ if (!miniMetadata?.data) {
4085
+ log.warn(`MiniMetadata for chain ${chainId} not found`);
4086
+ continue;
4087
+ }
4088
+ const scaleApi = sapi.getScaleApi({
4089
+ chainId,
4090
+ send: (...args) => chainConnector.send(chainId, ...args, {
4091
+ expectErrors: true
4092
+ } // don't pollute the wallet logs when this request fails
4093
+ )
4094
+ }, miniMetadata.data, token, chain.hasCheckMetadataHash, chain.signedExtensions, chain.registryTypes);
4095
+
4096
+ // sets the number of addresses to query in parallel (per chain, since each chain runs in parallel to the others)
4097
+ const concurrency = 4;
4098
+ // In-memory cache for successful dynamic info results
4099
+ const dynamicInfoCache = new Map();
4100
+ const fetchDynamicInfoForNetuids = async uniqueNetuids => {
4101
+ const MAX_RETRIES = 3;
4102
+ const RETRY_DELAY_MS = 500;
4103
+ const delay = ms => new Promise(resolve => setTimeout(resolve, ms));
4104
+ const fetchInfo = async netuid => {
4105
+ if (netuid === 0) return null;
4106
+ for (let attempt = 1; attempt <= MAX_RETRIES; attempt++) {
4107
+ try {
4108
+ const params = [netuid];
4109
+ const result = await scaleApi.getRuntimeCallValue("SubnetInfoRuntimeApi", "get_dynamic_info", params);
4110
+ dynamicInfoCache.set(netuid, result); // Cache successful response
4111
+ return result;
4112
+ } catch (error) {
4113
+ log.trace(`Attempt ${attempt} failed for netuid ${netuid}:`, error);
4114
+ if (attempt < MAX_RETRIES) {
4115
+ const backoffTime = RETRY_DELAY_MS * 2 ** (attempt - 1);
4116
+ log.trace(`Retrying in ${backoffTime}ms...`);
4117
+ await delay(backoffTime);
4118
+ }
4103
4119
  }
4104
4120
  }
4105
- }
4106
- if (dynamicInfoCache.has(netuid)) {
4107
- return dynamicInfoCache.get(netuid); // Use cached value on failure
4108
- }
4109
- log.trace(`Failed to fetch dynamic info for netuid ${netuid} after ${MAX_RETRIES} attempts.`);
4110
- return null;
4121
+ if (dynamicInfoCache.has(netuid)) {
4122
+ return dynamicInfoCache.get(netuid); // Use cached value on failure
4123
+ }
4124
+ log.trace(`Failed to fetch dynamic info for netuid ${netuid} after ${MAX_RETRIES} attempts.`);
4125
+ return null;
4126
+ };
4127
+ return Promise.all(uniqueNetuids.map(fetchInfo));
4111
4128
  };
4112
- return Promise.all(uniqueNetuids.map(fetchInfo));
4113
- };
4114
- const subtensorQueries = rxjs.from(addresses).pipe(
4115
- // mergeMap lets us run N concurrent queries, where N is the value of `concurrency`
4116
- rxjs.mergeMap(async address => {
4117
- const queryMethods = [async () => {
4118
- if (chain.isTestnet) return [];
4119
- const params = [address];
4120
- const result = await scaleApi.getRuntimeCallValue("StakeInfoRuntimeApi", "get_stake_info_for_coldkey", params);
4121
- if (!Array.isArray(result)) return [];
4122
- const uniqueNetuids = Array.from(new Set(result.map(item => Number(item.netuid)).filter(netuid => netuid !== SUBTENSOR_ROOT_NETUID)));
4123
- await fetchDynamicInfoForNetuids(uniqueNetuids);
4124
- const stakes = result?.map(({
4125
- coldkey,
4126
- hotkey,
4127
- netuid,
4128
- stake
4129
- }) => {
4130
- return {
4131
- address: coldkey,
4129
+ const subtensorQueries = rxjs.from(addresses).pipe(
4130
+ // mergeMap lets us run N concurrent queries, where N is the value of `concurrency`
4131
+ rxjs.mergeMap(async address => {
4132
+ const queryMethods = [async () => {
4133
+ if (chain.isTestnet) return [];
4134
+ const params = [address];
4135
+ const result = await scaleApi.getRuntimeCallValue("StakeInfoRuntimeApi", "get_stake_info_for_coldkey", params);
4136
+ if (!Array.isArray(result)) return [];
4137
+ const uniqueNetuids = Array.from(new Set(result.map(item => Number(item.netuid)).filter(netuid => netuid !== SUBTENSOR_ROOT_NETUID)));
4138
+ await fetchDynamicInfoForNetuids(uniqueNetuids);
4139
+ const stakes = result?.map(({
4140
+ coldkey,
4132
4141
  hotkey,
4133
- netuid: Number(netuid),
4134
- stake: BigInt(stake),
4135
- dynamicInfo: dynamicInfoCache.get(Number(netuid))
4136
- };
4137
- }).filter(({
4138
- stake
4139
- }) => stake >= SUBTENSOR_MIN_STAKE_AMOUNT_PLANK);
4140
- return stakes;
4141
- }];
4142
- const errors = [];
4143
- for (const queryMethod of queryMethods) {
4144
- try {
4145
- // try each query method
4146
- return await queryMethod();
4147
- } catch (cause) {
4148
- // if it fails, keep track of the error and try the next one
4149
- errors.push(cause);
4142
+ netuid,
4143
+ stake
4144
+ }) => {
4145
+ return {
4146
+ address: coldkey,
4147
+ hotkey,
4148
+ netuid: Number(netuid),
4149
+ stake: BigInt(stake),
4150
+ dynamicInfo: dynamicInfoCache.get(Number(netuid))
4151
+ };
4152
+ }).filter(({
4153
+ stake
4154
+ }) => stake >= SUBTENSOR_MIN_STAKE_AMOUNT_PLANK);
4155
+ return stakes;
4156
+ }];
4157
+ const errors = [];
4158
+ for (const queryMethod of queryMethods) {
4159
+ try {
4160
+ // try each query method
4161
+ return await queryMethod();
4162
+ } catch (cause) {
4163
+ // if it fails, keep track of the error and try the next one
4164
+ errors.push(cause);
4165
+ }
4150
4166
  }
4151
- }
4152
4167
 
4153
- // if we get to here, that means that all query methods failed
4154
- // let's throw the errors back to the native balance module
4155
- throw new Error([`Failed to fetch ${tokenId} subtensor staked balance for ${address}:`, ...errors.map(error => String(error))].join("\n\t"));
4156
- }, concurrency),
4157
- // instead of emitting each balance as it's fetched, toArray waits for them all to fetch and then it collects them into an array
4158
- rxjs.toArray(),
4159
- // this mergeMap flattens our Array<Array<Stakes>> into just an Array<Stakes>
4160
- rxjs.mergeMap(stakes => stakes),
4161
- // convert our Array<Stakes> into Array<Balances>, which we can then return to the native balance module
4162
- rxjs.map(stakes => stakes.map(({
4163
- address,
4164
- hotkey,
4165
- stake,
4166
- netuid,
4167
- dynamicInfo
4168
- }) => {
4169
- const {
4170
- token_symbol,
4171
- subnet_name,
4172
- subnet_identity
4173
- } = dynamicInfo ?? {};
4174
- const tokenSymbol = new TextDecoder().decode(Uint8Array.from(token_symbol ?? []));
4175
- const subnetName = new TextDecoder().decode(Uint8Array.from(subnet_name ?? []));
4176
-
4177
- /** Map from Record<string, Binary> to Record<string, string> */
4178
- const binaryToText = input => Object.entries(input).reduce((acc, [key, value]) => {
4179
- acc[key] = value.asText();
4180
- return acc;
4181
- }, {});
4182
- const subnetIdentity = subnet_identity ? binaryToText(subnet_identity) : undefined;
4183
-
4184
- // Add 1n balance if failed to fetch dynamic info, so the position is not ignored by Balance lib and is displayed in the UI.
4185
- const alphaStakedInTao = dynamicInfo ? calculateTaoFromDynamicInfo({
4186
- dynamicInfo,
4187
- alphaStaked: stake
4188
- }) : 1n;
4189
- const alphaToTaoRate = calculateTaoFromDynamicInfo({
4190
- dynamicInfo: dynamicInfo ?? null,
4191
- alphaStaked: ONE_ALPHA_TOKEN
4192
- }).toString();
4193
- const stakeByNetuid = Number(netuid) === SUBTENSOR_ROOT_NETUID ? stake : alphaStakedInTao;
4194
- return {
4195
- source: "substrate-native",
4196
- status: "live",
4168
+ // if we get to here, that means that all query methods failed
4169
+ // let's throw the errors back to the native balance module
4170
+ throw new Error([`Failed to fetch ${tokenId} subtensor staked balance for ${address}:`, ...errors.map(error => String(error))].join("\n\t"));
4171
+ }, concurrency),
4172
+ // instead of emitting each balance as it's fetched, toArray waits for them all to fetch and then it collects them into an array
4173
+ rxjs.toArray(),
4174
+ // this mergeMap flattens our Array<Array<Stakes>> into just an Array<Stakes>
4175
+ rxjs.mergeMap(stakes => stakes),
4176
+ // convert our Array<Stakes> into Array<Balances>, which we can then return to the native balance module
4177
+ rxjs.map(stakes => stakes.map(({
4197
4178
  address,
4198
- networkId: chainId,
4199
- tokenId,
4200
- values: [{
4201
- source: "subtensor-staking",
4202
- type: "subtensor",
4203
- label: "subtensor-staking",
4204
- amount: stakeByNetuid.toString(),
4205
- meta: {
4206
- type: "subtensor-staking",
4207
- hotkey,
4208
- netuid,
4209
- amountStaked: stake.toString(),
4210
- alphaToTaoRate,
4211
- dynamicInfo: {
4212
- tokenSymbol,
4213
- subnetName,
4214
- subnetIdentity: {
4215
- ...subnetIdentity,
4216
- subnetName: subnetIdentity?.subnet_name || subnetName
4179
+ hotkey,
4180
+ stake,
4181
+ netuid,
4182
+ dynamicInfo
4183
+ }) => {
4184
+ const {
4185
+ token_symbol,
4186
+ subnet_name,
4187
+ subnet_identity
4188
+ } = dynamicInfo ?? {};
4189
+ const tokenSymbol = new TextDecoder().decode(Uint8Array.from(token_symbol ?? []));
4190
+ const subnetName = new TextDecoder().decode(Uint8Array.from(subnet_name ?? []));
4191
+
4192
+ /** Map from Record<string, Binary> to Record<string, string> */
4193
+ const binaryToText = input => Object.entries(input).reduce((acc, [key, value]) => {
4194
+ acc[key] = value.asText();
4195
+ return acc;
4196
+ }, {});
4197
+ const subnetIdentity = subnet_identity ? binaryToText(subnet_identity) : undefined;
4198
+
4199
+ // Add 1n balance if failed to fetch dynamic info, so the position is not ignored by Balance lib and is displayed in the UI.
4200
+ const alphaStakedInTao = dynamicInfo ? calculateTaoFromDynamicInfo({
4201
+ dynamicInfo,
4202
+ alphaStaked: stake
4203
+ }) : 1n;
4204
+ const alphaToTaoRate = calculateTaoFromDynamicInfo({
4205
+ dynamicInfo: dynamicInfo ?? null,
4206
+ alphaStaked: ONE_ALPHA_TOKEN
4207
+ }).toString();
4208
+ const stakeByNetuid = Number(netuid) === SUBTENSOR_ROOT_NETUID ? stake : alphaStakedInTao;
4209
+ return {
4210
+ source: "substrate-native",
4211
+ status: "live",
4212
+ address,
4213
+ networkId: chainId,
4214
+ tokenId,
4215
+ values: [{
4216
+ source: "subtensor-staking",
4217
+ type: "subtensor",
4218
+ label: "subtensor-staking",
4219
+ amount: stakeByNetuid.toString(),
4220
+ meta: {
4221
+ type: "subtensor-staking",
4222
+ hotkey,
4223
+ netuid,
4224
+ amountStaked: stake.toString(),
4225
+ alphaToTaoRate,
4226
+ dynamicInfo: {
4227
+ tokenSymbol,
4228
+ subnetName,
4229
+ subnetIdentity: {
4230
+ ...subnetIdentity,
4231
+ subnetName: subnetIdentity?.subnet_name || subnetName
4232
+ }
4217
4233
  }
4218
4234
  }
4219
- }
4220
- }]
4221
- };
4222
- })));
4223
-
4224
- // This observable will run the subtensorQueries on a 30s (30_000ms) interval.
4225
- // However, if the last run has not yet completed (e.g. its been 30s but we're still fetching some balances),
4226
- // then exhaustMap will wait until the next interval (so T: 60s, T: 90s, T: 120s, etc) before re-executing the subtensorQueries.
4227
- const subtensorQueriesInterval = rxjs.interval(30_000).pipe(rxjs.startWith(0),
4228
- // start immediately
4229
- rxjs.exhaustMap(() => {
4230
- return subtensorQueries;
4231
- }));
4235
+ }]
4236
+ };
4237
+ })));
4238
+
4239
+ // This observable will run the subtensorQueries on a 30s (30_000ms) interval.
4240
+ // However, if the last run has not yet completed (e.g. its been 30s but we're still fetching some balances),
4241
+ // then exhaustMap will wait until the next interval (so T: 60s, T: 90s, T: 120s, etc) before re-executing the subtensorQueries.
4242
+ const subtensorQueriesInterval = rxjs.interval(30_000).pipe(rxjs.startWith(0),
4243
+ // start immediately
4244
+ rxjs.exhaustMap(() => {
4245
+ return subtensorQueries;
4246
+ }));
4232
4247
 
4233
- // subscribe to the balances
4234
- const subscription = subtensorQueriesInterval.subscribe({
4235
- next: balances => callback(null, balances),
4236
- error: error => callback(error)
4237
- });
4248
+ // subscribe to the balances
4249
+ const subscription = subtensorQueriesInterval.subscribe({
4250
+ next: balances => callback(null, balances),
4251
+ error: error => callback(error)
4252
+ });
4238
4253
 
4239
- // use the abortController to tear the subscription down when we don't need it anymore
4240
- abortController.signal.addEventListener("abort", () => {
4241
- subscription.unsubscribe();
4254
+ // use the abortController to tear the subscription down when we don't need it anymore
4255
+ abortController.signal.addEventListener("abort", () => {
4256
+ subscription.unsubscribe();
4257
+ });
4258
+ }
4259
+ return () => abortController.abort();
4260
+ } catch (err) {
4261
+ if (!util.isAbortError(err)) log.error("Error subscribing to subtensor staking", {
4262
+ err
4242
4263
  });
4264
+ return () => {};
4243
4265
  }
4244
- return () => abortController.abort();
4245
4266
  }
4246
4267
 
4247
4268
  const getOtherType = input => `other-${input}`;
@@ -4920,17 +4941,9 @@ const SubNativeModule = hydrate => {
4920
4941
  if (!chainConnectors.substrate) return;
4921
4942
  const unsubSubtensorStaking = subscribeSubtensorStaking(chaindataProvider$1, chainConnectors.substrate, newAddressesByToken, handleUpdateForSource("subtensor-staking"), signal);
4922
4943
  const unsubNompoolStaking = subscribeNompoolStaking(chaindataProvider$1, chainConnectors.substrate, newAddressesByToken, handleUpdateForSource("nompools-staking"), signal);
4923
- // const unsubCrowdloans = subscribeCrowdloans(
4924
- // chaindataProvider,
4925
- // chainConnectors.substrate,
4926
- // newAddressesByToken,
4927
- // handleUpdateForSource("crowdloan"),
4928
- // signal,
4929
- // )
4930
4944
  const unsubBase = subscribeBase(baseQueries, chainConnectors.substrate, handleUpdateForSource("base"));
4931
4945
  subscriber.add(async () => (await unsubSubtensorStaking)());
4932
4946
  subscriber.add(async () => (await unsubNompoolStaking)());
4933
- // subscriber.add(async () => (await unsubCrowdloans)())
4934
4947
  subscriber.add(async () => (await unsubBase)());
4935
4948
  });
4936
4949
  }));