@talismn/balances 1.0.9 → 1.2.0

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.
Files changed (24) hide show
  1. package/dist/declarations/src/BalancesProvider.d.ts +1 -0
  2. package/dist/declarations/src/modules/index.d.ts +12 -1
  3. package/dist/declarations/src/modules/substrate-dtao/alphaPrice.d.ts +5 -0
  4. package/dist/declarations/src/modules/substrate-dtao/config.d.ts +5 -0
  5. package/dist/declarations/src/modules/substrate-dtao/fetchBalances.d.ts +3 -0
  6. package/dist/declarations/src/modules/substrate-dtao/fetchTokens.d.ts +3 -0
  7. package/dist/declarations/src/modules/substrate-dtao/getDtaoTokenRates.d.ts +11 -0
  8. package/dist/declarations/src/modules/substrate-dtao/getMiniMetadata.d.ts +3 -0
  9. package/dist/declarations/src/modules/substrate-dtao/getTransferCallData.d.ts +3 -0
  10. package/dist/declarations/src/modules/substrate-dtao/index.d.ts +4 -0
  11. package/dist/declarations/src/modules/substrate-dtao/module.d.ts +3 -0
  12. package/dist/declarations/src/modules/substrate-dtao/subscribeBalances.d.ts +3 -0
  13. package/dist/declarations/src/modules/substrate-dtao/types.d.ts +17 -0
  14. package/dist/declarations/src/modules/substrate-native/index.d.ts +0 -1
  15. package/dist/declarations/src/modules/substrate-native/types.d.ts +0 -1
  16. package/dist/declarations/src/types/IBalanceModule.d.ts +4 -0
  17. package/dist/declarations/src/types/balances.d.ts +27 -10
  18. package/dist/declarations/src/types/balancetypes.d.ts +1 -1
  19. package/dist/talismn-balances.cjs.dev.js +629 -365
  20. package/dist/talismn-balances.cjs.prod.js +629 -365
  21. package/dist/talismn-balances.esm.js +625 -362
  22. package/package.json +4 -4
  23. package/dist/declarations/src/modules/substrate-native/bittensor/getSubtensorStakingBalances.d.ts +0 -9
  24. package/dist/declarations/src/modules/substrate-native/bittensor/subtensor.d.ts +0 -20
@@ -1,15 +1,15 @@
1
- import { EvmErc20TokenSchema, parseTokenId, parseEvmErc20TokenId, evmErc20TokenId, isTokenOfType, TokenBaseSchema, EvmNativeTokenSchema, evmNativeTokenId, EvmUniswapV2TokenSchema, evmUniswapV2TokenId, SolNativeTokenSchema, solNativeTokenId, SolSplTokenSchema, solSplTokenId, parseSolSplTokenId, SubAssetsTokenSchema, subAssetTokenId, MINIMETADATA_VERSION, SubForeignAssetsTokenSchema, subForeignAssetTokenId, SubHydrationTokenSchema, subHydrationTokenId, SubNativeTokenSchema, subNativeTokenId, SubPsp22TokenSchema, subPsp22TokenId, SubTokensTokenSchema, subTokensTokenId, isNetworkDot } from '@talismn/chaindata-provider';
1
+ import { EvmErc20TokenSchema, parseTokenId, parseEvmErc20TokenId, evmErc20TokenId, isTokenOfType, TokenBaseSchema, EvmNativeTokenSchema, evmNativeTokenId, EvmUniswapV2TokenSchema, evmUniswapV2TokenId, SolNativeTokenSchema, solNativeTokenId, SolSplTokenSchema, solSplTokenId, parseSolSplTokenId, SubAssetsTokenSchema, subAssetTokenId, SubDTaoTokenSchema, subDTaoTokenId, getCleanToken, TokenSchema, MINIMETADATA_VERSION, parseSubDTaoTokenId, subNativeTokenId, SubForeignAssetsTokenSchema, subForeignAssetTokenId, SubHydrationTokenSchema, subHydrationTokenId, SubNativeTokenSchema, SubPsp22TokenSchema, subPsp22TokenId, SubTokensTokenSchema, subTokensTokenId, isNetworkDot } from '@talismn/chaindata-provider';
2
2
  export { MINIMETADATA_VERSION } from '@talismn/chaindata-provider';
3
3
  import { isEthereumAddress, isSolanaAddress, normalizeAddress, getAccountPlatformFromAddress } from '@talismn/crypto';
4
4
  import { parseAbi, erc20Abi, getContract, ContractFunctionExecutionError, hexToString, erc20Abi_bytes32, encodeFunctionData, withRetry } from 'viem';
5
5
  import { assign, omit, isEqual, uniq, keyBy, toPairs, keys, fromPairs, values } from 'lodash-es';
6
6
  import z from 'zod/v4';
7
7
  import anylogger from 'anylogger';
8
- import { of, Observable, distinctUntilChanged, BehaviorSubject, map, timer, switchMap, from, firstValueFrom, combineLatest, shareReplay, startWith, filter, defer, catchError, EMPTY, tap } from 'rxjs';
8
+ import { of, Observable, distinctUntilChanged, BehaviorSubject, map, switchMap, shareReplay, combineLatest, timer, startWith, firstValueFrom, filter, defer, catchError, EMPTY, tap, from } from 'rxjs';
9
9
  import BigNumber from 'bignumber.js';
10
10
  import { PublicKey, SystemProgram } from '@solana/web3.js';
11
11
  import { isNotNil, BigMath, isArrayOf, isBigInt, planckToTokens, isAbortError, getSharedObservable, keepAlive, isTruthy } from '@talismn/util';
12
- import { parseMetadataRpc, toHex, unifyMetadata, decAnyMetadata, getDynamicBuilder, getLookupFn, decodeScale, getStorageKeyPrefix, Twox128, compactMetadata, encodeMetadata, papiParse, papiStringify } from '@talismn/scale';
12
+ import { parseMetadataRpc, toHex, unifyMetadata, decAnyMetadata, getDynamicBuilder, getLookupFn, decodeScale, getStorageKeyPrefix, compactMetadata, encodeMetadata, Twox128, papiParse, papiStringify } from '@talismn/scale';
13
13
  import { deserializeMetadata } from '@metaplex-foundation/mpl-token-metadata';
14
14
  import { sol, publicKey } from '@metaplex-foundation/umi';
15
15
  import { MintLayout, getAssociatedTokenAddress, createAssociatedTokenAccountInstruction, createTransferInstruction, TOKEN_PROGRAM_ID, getAccount } from '@solana/spl-token';
@@ -24,8 +24,8 @@ import { u8aToHex, u8aConcatStrict, u8aToString, hexToNumber } from '@polkadot/u
24
24
  import PQueue from 'p-queue';
25
25
  import { fetchBestMetadata } from '@talismn/sapi';
26
26
 
27
- const MODULE_TYPE$a = EvmErc20TokenSchema.shape.type.value;
28
- const PLATFORM$a = EvmErc20TokenSchema.shape.platform.value;
27
+ const MODULE_TYPE$b = EvmErc20TokenSchema.shape.type.value;
28
+ const PLATFORM$b = EvmErc20TokenSchema.shape.platform.value;
29
29
 
30
30
  const abiMulticall = parseAbi(["struct Call { address target; bytes callData; }", "struct Call3 { address target; bool allowFailure; bytes callData; }", "struct Call3Value { address target; bool allowFailure; uint256 value; bytes callData; }", "struct Result { bool success; bytes returnData; }", "function aggregate(Call[] calldata calls) public payable returns (uint256 blockNumber, bytes[] memory returnData)", "function aggregate3(Call3[] calldata calls) public payable returns (Result[] memory returnData)", "function aggregate3Value(Call3Value[] calldata calls) public payable returns (Result[] memory returnData)", "function blockAndAggregate(Call[] calldata calls) public payable returns (uint256 blockNumber, bytes32 blockHash, Result[] memory returnData)", "function getBasefee() view returns (uint256 basefee)", "function getBlockHash(uint256 blockNumber) view returns (bytes32 blockHash)", "function getBlockNumber() view returns (uint256 blockNumber)", "function getChainId() view returns (uint256 chainid)", "function getCurrentBlockCoinbase() view returns (address coinbase)", "function getCurrentBlockDifficulty() view returns (uint256 difficulty)", "function getCurrentBlockGasLimit() view returns (uint256 gaslimit)", "function getCurrentBlockTimestamp() view returns (uint256 timestamp)", "function getEthBalance(address addr) view returns (uint256 balance)", "function getLastBlockHash() view returns (bytes32 blockHash)", "function tryAggregate(bool requireSuccess, Call[] calldata calls) public payable returns (Result[] memory returnData)", "function tryBlockAndAggregate(bool requireSuccess, Call[] calldata calls) public payable returns (uint256 blockNumber, bytes32 blockHash, Result[] memory returnData)"]);
31
31
 
@@ -621,7 +621,7 @@ const getBalanceDefs = addressesByToken => {
621
621
  // if there is at least one storage entry, the results will be an array with a single object
622
622
  // if the storage has no entries in it (ex: Assets on ewx or moonbeam), the response will be an empty array
623
623
 
624
- const fetchBalances$a = async ({
624
+ const fetchBalances$b = async ({
625
625
  networkId,
626
626
  tokensWithAddresses,
627
627
  connector
@@ -633,7 +633,7 @@ const fetchBalances$a = async ({
633
633
  const client = await connector.getPublicClientForEvmNetwork(networkId);
634
634
  if (!client) throw new Error(`Could not get rpc provider for evm network ${networkId}`);
635
635
  for (const [token, addresses] of tokensWithAddresses) {
636
- if (token.type !== MODULE_TYPE$a || token.networkId !== networkId) throw new Error(`Invalid token type or networkId for EVM ERC20 balance module: ${token.type} on ${token.networkId}`);
636
+ if (token.type !== MODULE_TYPE$b || token.networkId !== networkId) throw new Error(`Invalid token type or networkId for EVM ERC20 balance module: ${token.type} on ${token.networkId}`);
637
637
  for (const address of addresses) if (!isEthereumAddress(address)) throw new Error(`Invalid ethereum address for EVM ERC20 balance module: ${address} for token ${token.id}`);
638
638
  }
639
639
  const balanceDefs = getBalanceDefs(tokensWithAddresses);
@@ -663,7 +663,7 @@ const fetchWithoutAggregator = async (client, balanceDefs) => {
663
663
  address,
664
664
  tokenId: token.id,
665
665
  value: result.toString(),
666
- source: MODULE_TYPE$a,
666
+ source: MODULE_TYPE$b,
667
667
  networkId: parseEvmErc20TokenId(token.id).networkId,
668
668
  status: "live"
669
669
  };
@@ -706,7 +706,7 @@ const fetchWithAggregator = async (client, balanceDefs, erc20BalancesAggregatorA
706
706
  address: balanceDef.address,
707
707
  tokenId: balanceDef.token.id,
708
708
  value: erc20Balances[index].toString(),
709
- source: MODULE_TYPE$a,
709
+ source: MODULE_TYPE$b,
710
710
  networkId: parseTokenId(balanceDef.token.id).networkId,
711
711
  status: "live"
712
712
  }));
@@ -775,7 +775,7 @@ const TokenCacheSchema$2 = z.discriminatedUnion("isValid", [z.strictObject({
775
775
  id: EvmErc20TokenSchema.shape.id,
776
776
  isValid: z.literal(false)
777
777
  })]);
778
- const fetchTokens$a = async ({
778
+ const fetchTokens$b = async ({
779
779
  networkId,
780
780
  tokens,
781
781
  connector,
@@ -815,8 +815,8 @@ const fetchTokens$a = async ({
815
815
  }
816
816
  const base = {
817
817
  id: tokenId,
818
- type: MODULE_TYPE$a,
819
- platform: PLATFORM$a,
818
+ type: MODULE_TYPE$b,
819
+ platform: PLATFORM$b,
820
820
  networkId
821
821
  };
822
822
  const cached2 = cache[tokenId] && TokenCacheSchema$2.safeParse(cache[tokenId]).data;
@@ -834,17 +834,17 @@ const fetchTokens$a = async ({
834
834
  return result;
835
835
  };
836
836
 
837
- const getMiniMetadata$a = () => {
837
+ const getMiniMetadata$b = () => {
838
838
  throw new Error("MiniMetadata is not supported for ethereum tokens");
839
839
  };
840
840
 
841
- const getTransferCallData$a = ({
841
+ const getTransferCallData$b = ({
842
842
  from,
843
843
  to,
844
844
  value,
845
845
  token
846
846
  }) => {
847
- if (!isTokenOfType(token, MODULE_TYPE$a)) throw new Error(`Token type ${token.type} is not ${MODULE_TYPE$a}.`);
847
+ if (!isTokenOfType(token, MODULE_TYPE$b)) throw new Error(`Token type ${token.type} is not ${MODULE_TYPE$b}.`);
848
848
  if (!isEthereumAddress(from)) throw new Error("Invalid from address");
849
849
  if (!isEthereumAddress(to)) throw new Error("Invalid to address");
850
850
  const data = encodeFunctionData({
@@ -859,8 +859,8 @@ const getTransferCallData$a = ({
859
859
  };
860
860
  };
861
861
 
862
- const SUBSCRIPTION_INTERVAL$6 = 6_000;
863
- const subscribeBalances$a = ({
862
+ const SUBSCRIPTION_INTERVAL$7 = 6_000;
863
+ const subscribeBalances$b = ({
864
864
  networkId,
865
865
  tokensWithAddresses,
866
866
  connector
@@ -874,17 +874,17 @@ const subscribeBalances$a = ({
874
874
  const poll = async () => {
875
875
  try {
876
876
  if (abortController.signal.aborted) return;
877
- const balances = await fetchBalances$a({
877
+ const balances = await fetchBalances$b({
878
878
  networkId,
879
879
  tokensWithAddresses: tokensWithAddresses,
880
880
  connector
881
881
  });
882
882
  if (abortController.signal.aborted) return;
883
883
  subscriber.next(balances);
884
- setTimeout(poll, SUBSCRIPTION_INTERVAL$6);
884
+ setTimeout(poll, SUBSCRIPTION_INTERVAL$7);
885
885
  } catch (error) {
886
886
  log.error("Error", {
887
- module: MODULE_TYPE$a,
887
+ module: MODULE_TYPE$b,
888
888
  networkId,
889
889
  addressesByToken: tokensWithAddresses,
890
890
  error
@@ -900,13 +900,13 @@ const subscribeBalances$a = ({
900
900
  };
901
901
 
902
902
  const EvmErc20BalanceModule = {
903
- type: MODULE_TYPE$a,
904
- platform: PLATFORM$a,
905
- getMiniMetadata: getMiniMetadata$a,
906
- fetchTokens: fetchTokens$a,
907
- fetchBalances: fetchBalances$a,
908
- subscribeBalances: subscribeBalances$a,
909
- getTransferCallData: getTransferCallData$a
903
+ type: MODULE_TYPE$b,
904
+ platform: PLATFORM$b,
905
+ getMiniMetadata: getMiniMetadata$b,
906
+ fetchTokens: fetchTokens$b,
907
+ fetchBalances: fetchBalances$b,
908
+ subscribeBalances: subscribeBalances$b,
909
+ getTransferCallData: getTransferCallData$b
910
910
  };
911
911
 
912
912
  const TokenConfigBaseSchema = TokenBaseSchema.partial().omit({
@@ -919,10 +919,10 @@ const EvmErc20TokenConfigSchema = z.strictObject({
919
919
  ...TokenConfigBaseSchema.shape
920
920
  });
921
921
 
922
- const MODULE_TYPE$9 = EvmNativeTokenSchema.shape.type.value;
923
- const PLATFORM$9 = EvmNativeTokenSchema.shape.platform.value;
922
+ const MODULE_TYPE$a = EvmNativeTokenSchema.shape.type.value;
923
+ const PLATFORM$a = EvmNativeTokenSchema.shape.platform.value;
924
924
 
925
- const fetchBalances$9 = async ({
925
+ const fetchBalances$a = async ({
926
926
  networkId,
927
927
  tokensWithAddresses,
928
928
  connector
@@ -934,7 +934,7 @@ const fetchBalances$9 = async ({
934
934
  const client = await connector.getPublicClientForEvmNetwork(networkId);
935
935
  if (!client) throw new Error(`Could not get rpc provider for evm network ${networkId}`);
936
936
  for (const [token, addresses] of tokensWithAddresses) {
937
- if (token.type !== MODULE_TYPE$9 || token.networkId !== networkId) throw new Error(`Invalid token type or networkId for EVM ERC20 balance module: ${token.type} on ${token.networkId}`);
937
+ if (token.type !== MODULE_TYPE$a || token.networkId !== networkId) throw new Error(`Invalid token type or networkId for EVM ERC20 balance module: ${token.type} on ${token.networkId}`);
938
938
  for (const address of addresses) if (!isEthereumAddress(address)) throw new Error(`Invalid ethereum address for EVM ERC20 balance module: ${address} for token ${token.id}`);
939
939
  }
940
940
  const balanceDefs = getBalanceDefs(tokensWithAddresses);
@@ -961,7 +961,7 @@ const fetchWithoutMulticall = async (client, balanceDefs) => {
961
961
  address,
962
962
  tokenId: token.id,
963
963
  value: result.toString(),
964
- source: MODULE_TYPE$9,
964
+ source: MODULE_TYPE$a,
965
965
  networkId: parseTokenId(token.id).networkId,
966
966
  status: "live"
967
967
  };
@@ -1007,7 +1007,7 @@ const fetchWithMulticall = async (client, balanceDefs, multicall3Address) => {
1007
1007
  address: balanceDefs[index].address,
1008
1008
  tokenId: balanceDefs[index].token.id,
1009
1009
  value: result.result.toString(),
1010
- source: MODULE_TYPE$9,
1010
+ source: MODULE_TYPE$a,
1011
1011
  networkId: parseTokenId(balanceDefs[index].token.id).networkId,
1012
1012
  status: "live"
1013
1013
  });
@@ -1037,7 +1037,7 @@ const fetchWithMulticall = async (client, balanceDefs, multicall3Address) => {
1037
1037
  }
1038
1038
  };
1039
1039
 
1040
- const fetchTokens$9 = async ({
1040
+ const fetchTokens$a = async ({
1041
1041
  networkId,
1042
1042
  tokens
1043
1043
  }) => {
@@ -1045,8 +1045,8 @@ const fetchTokens$9 = async ({
1045
1045
  if (tokens.length !== 1) throw new Error("EVM Native module expects the nativeCurrency to be passed as a single token in the array");
1046
1046
  const token = assign({
1047
1047
  id: evmNativeTokenId(networkId),
1048
- type: MODULE_TYPE$9,
1049
- platform: PLATFORM$9,
1048
+ type: MODULE_TYPE$a,
1049
+ platform: PLATFORM$a,
1050
1050
  networkId,
1051
1051
  isDefault: true
1052
1052
  }, tokens[0]);
@@ -1058,17 +1058,17 @@ const fetchTokens$9 = async ({
1058
1058
  return [parsed.data];
1059
1059
  };
1060
1060
 
1061
- const getMiniMetadata$9 = () => {
1061
+ const getMiniMetadata$a = () => {
1062
1062
  throw new Error("MiniMetadata is not supported for ethereum tokens");
1063
1063
  };
1064
1064
 
1065
- const getTransferCallData$9 = ({
1065
+ const getTransferCallData$a = ({
1066
1066
  from,
1067
1067
  to,
1068
1068
  value,
1069
1069
  token
1070
1070
  }) => {
1071
- if (!isTokenOfType(token, MODULE_TYPE$9)) throw new Error(`Token type ${token.type} is not ${MODULE_TYPE$9}.`);
1071
+ if (!isTokenOfType(token, MODULE_TYPE$a)) throw new Error(`Token type ${token.type} is not ${MODULE_TYPE$a}.`);
1072
1072
  if (!isEthereumAddress(from)) throw new Error("Invalid from address");
1073
1073
  if (!isEthereumAddress(to)) throw new Error("Invalid to address");
1074
1074
  return {
@@ -1079,8 +1079,8 @@ const getTransferCallData$9 = ({
1079
1079
  };
1080
1080
  };
1081
1081
 
1082
- const SUBSCRIPTION_INTERVAL$5 = 6_000;
1083
- const subscribeBalances$9 = ({
1082
+ const SUBSCRIPTION_INTERVAL$6 = 6_000;
1083
+ const subscribeBalances$a = ({
1084
1084
  networkId,
1085
1085
  tokensWithAddresses,
1086
1086
  connector
@@ -1094,17 +1094,17 @@ const subscribeBalances$9 = ({
1094
1094
  const poll = async () => {
1095
1095
  try {
1096
1096
  if (abortController.signal.aborted) return;
1097
- const balances = await fetchBalances$9({
1097
+ const balances = await fetchBalances$a({
1098
1098
  networkId,
1099
1099
  tokensWithAddresses: tokensWithAddresses,
1100
1100
  connector
1101
1101
  });
1102
1102
  if (abortController.signal.aborted) return;
1103
1103
  subscriber.next(balances);
1104
- setTimeout(poll, SUBSCRIPTION_INTERVAL$5);
1104
+ setTimeout(poll, SUBSCRIPTION_INTERVAL$6);
1105
1105
  } catch (error) {
1106
1106
  log.error("Error", {
1107
- module: MODULE_TYPE$9,
1107
+ module: MODULE_TYPE$a,
1108
1108
  networkId,
1109
1109
  addressesByToken: tokensWithAddresses,
1110
1110
  error
@@ -1120,13 +1120,13 @@ const subscribeBalances$9 = ({
1120
1120
  };
1121
1121
 
1122
1122
  const EvmNativeBalanceModule = {
1123
- type: MODULE_TYPE$9,
1124
- platform: PLATFORM$9,
1125
- getMiniMetadata: getMiniMetadata$9,
1126
- fetchTokens: fetchTokens$9,
1127
- fetchBalances: fetchBalances$9,
1128
- subscribeBalances: subscribeBalances$9,
1129
- getTransferCallData: getTransferCallData$9
1123
+ type: MODULE_TYPE$a,
1124
+ platform: PLATFORM$a,
1125
+ getMiniMetadata: getMiniMetadata$a,
1126
+ fetchTokens: fetchTokens$a,
1127
+ fetchBalances: fetchBalances$a,
1128
+ subscribeBalances: subscribeBalances$a,
1129
+ getTransferCallData: getTransferCallData$a
1130
1130
  };
1131
1131
 
1132
1132
  // to be used by chaindata too
@@ -1134,10 +1134,10 @@ const EvmNativeTokenConfigSchema = z.strictObject({
1134
1134
  ...TokenConfigBaseSchema.shape
1135
1135
  });
1136
1136
 
1137
- const MODULE_TYPE$8 = EvmUniswapV2TokenSchema.shape.type.value;
1138
- const PLATFORM$8 = EvmUniswapV2TokenSchema.shape.platform.value;
1137
+ const MODULE_TYPE$9 = EvmUniswapV2TokenSchema.shape.type.value;
1138
+ const PLATFORM$9 = EvmUniswapV2TokenSchema.shape.platform.value;
1139
1139
 
1140
- const fetchBalances$8 = async ({
1140
+ const fetchBalances$9 = async ({
1141
1141
  networkId,
1142
1142
  tokensWithAddresses,
1143
1143
  connector
@@ -1149,7 +1149,7 @@ const fetchBalances$8 = async ({
1149
1149
  const client = await connector.getPublicClientForEvmNetwork(networkId);
1150
1150
  if (!client) throw new Error(`Could not get rpc provider for evm network ${networkId}`);
1151
1151
  for (const [token, addresses] of tokensWithAddresses) {
1152
- 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}`);
1152
+ if (token.type !== MODULE_TYPE$9 || token.networkId !== networkId) throw new Error(`Invalid token type or networkId for EVM ERC20 balance module: ${token.type} on ${token.networkId}`);
1153
1153
  for (const address of addresses) if (!isEthereumAddress(address)) throw new Error(`Invalid ethereum address for EVM ERC20 balance module: ${address} for token ${token.id}`);
1154
1154
  }
1155
1155
  const balanceDefs = getBalanceDefs(tokensWithAddresses);
@@ -1236,7 +1236,7 @@ const fetchPoolBalances = async (client, balanceDefs) => {
1236
1236
  acc.success.push({
1237
1237
  address,
1238
1238
  tokenId: token.id,
1239
- source: MODULE_TYPE$8,
1239
+ source: MODULE_TYPE$9,
1240
1240
  networkId: parseTokenId(token.id).networkId,
1241
1241
  status: "live",
1242
1242
  values: [{
@@ -1314,7 +1314,7 @@ const TokenCacheSchema$1 = z.discriminatedUnion("isValid", [z.strictObject({
1314
1314
  id: EvmUniswapV2TokenSchema.shape.id,
1315
1315
  isValid: z.literal(false)
1316
1316
  })]);
1317
- const fetchTokens$8 = async ({
1317
+ const fetchTokens$9 = async ({
1318
1318
  networkId,
1319
1319
  tokens,
1320
1320
  connector,
@@ -1373,8 +1373,8 @@ const fetchTokens$8 = async ({
1373
1373
  }
1374
1374
  const base = {
1375
1375
  id: tokenId,
1376
- type: MODULE_TYPE$8,
1377
- platform: PLATFORM$8,
1376
+ type: MODULE_TYPE$9,
1377
+ platform: PLATFORM$9,
1378
1378
  networkId
1379
1379
  };
1380
1380
  const cached2 = cache[tokenId] && TokenCacheSchema$1.safeParse(cache[tokenId]).data;
@@ -1390,17 +1390,17 @@ const fetchTokens$8 = async ({
1390
1390
  return result;
1391
1391
  };
1392
1392
 
1393
- const getMiniMetadata$8 = () => {
1393
+ const getMiniMetadata$9 = () => {
1394
1394
  throw new Error("MiniMetadata is not supported for ethereum tokens");
1395
1395
  };
1396
1396
 
1397
- const getTransferCallData$8 = ({
1397
+ const getTransferCallData$9 = ({
1398
1398
  from,
1399
1399
  to,
1400
1400
  value,
1401
1401
  token
1402
1402
  }) => {
1403
- if (!isTokenOfType(token, MODULE_TYPE$8)) throw new Error(`Token type ${token.type} is not ${MODULE_TYPE$8}.`);
1403
+ if (!isTokenOfType(token, MODULE_TYPE$9)) throw new Error(`Token type ${token.type} is not ${MODULE_TYPE$9}.`);
1404
1404
  if (!isEthereumAddress(from)) throw new Error("Invalid from address");
1405
1405
  if (!isEthereumAddress(to)) throw new Error("Invalid to address");
1406
1406
  const data = encodeFunctionData({
@@ -1415,8 +1415,8 @@ const getTransferCallData$8 = ({
1415
1415
  };
1416
1416
  };
1417
1417
 
1418
- const SUBSCRIPTION_INTERVAL$4 = 6_000;
1419
- const subscribeBalances$8 = ({
1418
+ const SUBSCRIPTION_INTERVAL$5 = 6_000;
1419
+ const subscribeBalances$9 = ({
1420
1420
  networkId,
1421
1421
  tokensWithAddresses,
1422
1422
  connector
@@ -1430,17 +1430,17 @@ const subscribeBalances$8 = ({
1430
1430
  const poll = async () => {
1431
1431
  try {
1432
1432
  if (abortController.signal.aborted) return;
1433
- const balances = await fetchBalances$8({
1433
+ const balances = await fetchBalances$9({
1434
1434
  networkId,
1435
1435
  tokensWithAddresses: tokensWithAddresses,
1436
1436
  connector
1437
1437
  });
1438
1438
  if (abortController.signal.aborted) return;
1439
1439
  subscriber.next(balances);
1440
- setTimeout(poll, SUBSCRIPTION_INTERVAL$4);
1440
+ setTimeout(poll, SUBSCRIPTION_INTERVAL$5);
1441
1441
  } catch (error) {
1442
1442
  log.error("Error", {
1443
- module: MODULE_TYPE$8,
1443
+ module: MODULE_TYPE$9,
1444
1444
  networkId,
1445
1445
  addressesByToken: tokensWithAddresses,
1446
1446
  error
@@ -1456,13 +1456,13 @@ const subscribeBalances$8 = ({
1456
1456
  };
1457
1457
 
1458
1458
  const EvmUniswapV2BalanceModule = {
1459
- type: MODULE_TYPE$8,
1460
- platform: PLATFORM$8,
1461
- getMiniMetadata: getMiniMetadata$8,
1462
- fetchTokens: fetchTokens$8,
1463
- fetchBalances: fetchBalances$8,
1464
- subscribeBalances: subscribeBalances$8,
1465
- getTransferCallData: getTransferCallData$8
1459
+ type: MODULE_TYPE$9,
1460
+ platform: PLATFORM$9,
1461
+ getMiniMetadata: getMiniMetadata$9,
1462
+ fetchTokens: fetchTokens$9,
1463
+ fetchBalances: fetchBalances$9,
1464
+ subscribeBalances: subscribeBalances$9,
1465
+ getTransferCallData: getTransferCallData$9
1466
1466
  };
1467
1467
 
1468
1468
  // to be used by chaindata too
@@ -1471,10 +1471,10 @@ const EvmUniswapV2TokenConfigSchema = z.strictObject({
1471
1471
  ...TokenConfigBaseSchema.shape
1472
1472
  });
1473
1473
 
1474
- const MODULE_TYPE$7 = SolNativeTokenSchema.shape.type.value;
1475
- const PLATFORM$7 = SolNativeTokenSchema.shape.platform.value;
1474
+ const MODULE_TYPE$8 = SolNativeTokenSchema.shape.type.value;
1475
+ const PLATFORM$8 = SolNativeTokenSchema.shape.platform.value;
1476
1476
 
1477
- const fetchBalances$7 = async ({
1477
+ const fetchBalances$8 = async ({
1478
1478
  networkId,
1479
1479
  tokensWithAddresses,
1480
1480
  connector
@@ -1486,7 +1486,7 @@ const fetchBalances$7 = async ({
1486
1486
  const connection = await connector.getConnection(networkId);
1487
1487
  if (!connection) throw new Error(`Could not get rpc provider for sol network ${networkId}`);
1488
1488
  for (const [token, addresses] of tokensWithAddresses) {
1489
- if (token.type !== MODULE_TYPE$7 || token.networkId !== networkId) throw new Error(`Invalid token type or networkId for balance module: ${token.type} on ${token.networkId}`);
1489
+ if (token.type !== MODULE_TYPE$8 || token.networkId !== networkId) throw new Error(`Invalid token type or networkId for balance module: ${token.type} on ${token.networkId}`);
1490
1490
  for (const address of addresses) if (!isSolanaAddress(address)) throw new Error(`Invalid solana address for balance module: ${address} for token ${token.id}`);
1491
1491
  }
1492
1492
  const balanceDefs = getBalanceDefs(tokensWithAddresses);
@@ -1501,7 +1501,7 @@ const fetchBalances$7 = async ({
1501
1501
  address: address,
1502
1502
  tokenId: token.id,
1503
1503
  value: lamports.toString(),
1504
- source: MODULE_TYPE$7,
1504
+ source: MODULE_TYPE$8,
1505
1505
  networkId: token.networkId,
1506
1506
  status: "live"
1507
1507
  };
@@ -1525,7 +1525,7 @@ const fetchBalances$7 = async ({
1525
1525
  });
1526
1526
  };
1527
1527
 
1528
- const fetchTokens$7 = async ({
1528
+ const fetchTokens$8 = async ({
1529
1529
  networkId,
1530
1530
  tokens
1531
1531
  }) => {
@@ -1533,8 +1533,8 @@ const fetchTokens$7 = async ({
1533
1533
  if (tokens.length !== 1) throw new Error("EVM Native module expects the nativeCurrency to be passed as a single token in the array");
1534
1534
  const token = assign({
1535
1535
  id: solNativeTokenId(networkId),
1536
- type: MODULE_TYPE$7,
1537
- platform: PLATFORM$7,
1536
+ type: MODULE_TYPE$8,
1537
+ platform: PLATFORM$8,
1538
1538
  networkId,
1539
1539
  isDefault: true
1540
1540
  }, tokens[0]);
@@ -1546,17 +1546,17 @@ const fetchTokens$7 = async ({
1546
1546
  return [parsed.data];
1547
1547
  };
1548
1548
 
1549
- const getMiniMetadata$7 = () => {
1549
+ const getMiniMetadata$8 = () => {
1550
1550
  throw new Error("MiniMetadata is not supported for sol-native tokens");
1551
1551
  };
1552
1552
 
1553
- const getTransferCallData$7 = ({
1553
+ const getTransferCallData$8 = ({
1554
1554
  from,
1555
1555
  to,
1556
1556
  value,
1557
1557
  token
1558
1558
  }) => {
1559
- if (!isTokenOfType(token, MODULE_TYPE$7)) throw new Error(`Token type ${token.type} is not ${MODULE_TYPE$7}.`);
1559
+ if (!isTokenOfType(token, MODULE_TYPE$8)) throw new Error(`Token type ${token.type} is not ${MODULE_TYPE$8}.`);
1560
1560
  const fromPubkey = new PublicKey(from);
1561
1561
  const transferIx = SystemProgram.transfer({
1562
1562
  fromPubkey,
@@ -1566,8 +1566,8 @@ const getTransferCallData$7 = ({
1566
1566
  return [transferIx];
1567
1567
  };
1568
1568
 
1569
- const SUBSCRIPTION_INTERVAL$3 = 6_000;
1570
- const subscribeBalances$7 = ({
1569
+ const SUBSCRIPTION_INTERVAL$4 = 6_000;
1570
+ const subscribeBalances$8 = ({
1571
1571
  networkId,
1572
1572
  tokensWithAddresses,
1573
1573
  connector
@@ -1581,17 +1581,17 @@ const subscribeBalances$7 = ({
1581
1581
  const poll = async () => {
1582
1582
  try {
1583
1583
  if (abortController.signal.aborted) return;
1584
- const balances = await fetchBalances$7({
1584
+ const balances = await fetchBalances$8({
1585
1585
  networkId,
1586
1586
  tokensWithAddresses,
1587
1587
  connector
1588
1588
  });
1589
1589
  if (abortController.signal.aborted) return;
1590
1590
  subscriber.next(balances);
1591
- setTimeout(poll, SUBSCRIPTION_INTERVAL$3);
1591
+ setTimeout(poll, SUBSCRIPTION_INTERVAL$4);
1592
1592
  } catch (error) {
1593
1593
  log.error("Error", {
1594
- module: MODULE_TYPE$7,
1594
+ module: MODULE_TYPE$8,
1595
1595
  networkId,
1596
1596
  tokensWithAddresses,
1597
1597
  error
@@ -1607,13 +1607,13 @@ const subscribeBalances$7 = ({
1607
1607
  };
1608
1608
 
1609
1609
  const SolNativeBalanceModule = {
1610
- type: MODULE_TYPE$7,
1611
- platform: PLATFORM$7,
1612
- getMiniMetadata: getMiniMetadata$7,
1613
- fetchTokens: fetchTokens$7,
1614
- fetchBalances: fetchBalances$7,
1615
- subscribeBalances: subscribeBalances$7,
1616
- getTransferCallData: getTransferCallData$7
1610
+ type: MODULE_TYPE$8,
1611
+ platform: PLATFORM$8,
1612
+ getMiniMetadata: getMiniMetadata$8,
1613
+ fetchTokens: fetchTokens$8,
1614
+ fetchBalances: fetchBalances$8,
1615
+ subscribeBalances: subscribeBalances$8,
1616
+ getTransferCallData: getTransferCallData$8
1617
1617
  };
1618
1618
 
1619
1619
  // to be used by chaindata too
@@ -1621,16 +1621,22 @@ const SolNativeTokenConfigSchema = z.strictObject({
1621
1621
  ...TokenConfigBaseSchema.shape
1622
1622
  });
1623
1623
 
1624
- const MODULE_TYPE$6 = SolSplTokenSchema.shape.type.value;
1625
- const PLATFORM$6 = SolSplTokenSchema.shape.platform.value;
1624
+ const MODULE_TYPE$7 = SolSplTokenSchema.shape.type.value;
1625
+ const PLATFORM$7 = SolSplTokenSchema.shape.platform.value;
1626
1626
 
1627
1627
  const fetchRuntimeCallResult = async (connector, networkId, metadataRpc, apiName, method, args) => {
1628
- const {
1629
- builder
1630
- } = parseMetadataRpc(metadataRpc);
1631
- const call = builder.buildRuntimeCall(apiName, method);
1632
- const hex = await connector.send(networkId, "state_call", [`${apiName}_${method}`, toHex(call.args.enc(args))]);
1633
- return call.value.dec(hex);
1628
+ try {
1629
+ const {
1630
+ builder
1631
+ } = parseMetadataRpc(metadataRpc);
1632
+ const call = builder.buildRuntimeCall(apiName, method);
1633
+ const hex = await connector.send(networkId, "state_call", [`${apiName}_${method}`, toHex(call.args.enc(args))]);
1634
+ return call.value.dec(hex);
1635
+ } catch (cause) {
1636
+ throw new Error(`Error fetching runtime call on ${networkId} for ${apiName}.${method}`, {
1637
+ cause
1638
+ });
1639
+ }
1634
1640
  };
1635
1641
 
1636
1642
  const hasStorageItem = (metadata, palletName, itemName) => {
@@ -1775,7 +1781,7 @@ const setDetectedTokenIds = (address, type, tokenIds) => {
1775
1781
  const getDetectedTokensIds$ = address => tokenIdsByAddress.pipe(map(ownedTokens => ownedTokens[address] ?? []), distinctUntilChanged(isEqual));
1776
1782
 
1777
1783
  const SPL_PROGRAM_ID = "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA";
1778
- const fetchBalances$6 = async ({
1784
+ const fetchBalances$7 = async ({
1779
1785
  networkId,
1780
1786
  tokensWithAddresses,
1781
1787
  connector
@@ -1799,7 +1805,7 @@ const fetchBalances$6 = async ({
1799
1805
  tokenId: solSplTokenId(networkId, mintAddress),
1800
1806
  networkId,
1801
1807
  address,
1802
- source: MODULE_TYPE$6,
1808
+ source: MODULE_TYPE$7,
1803
1809
  status: "live",
1804
1810
  value
1805
1811
  };
@@ -1813,7 +1819,7 @@ const fetchBalances$6 = async ({
1813
1819
  }).filter(isNotNil);
1814
1820
 
1815
1821
  // allows the wallet to detect new tokens, and enable them automatically
1816
- setDetectedTokenIds(address, MODULE_TYPE$6, balances.map(b => b.tokenId));
1822
+ setDetectedTokenIds(address, MODULE_TYPE$7, balances.map(b => b.tokenId));
1817
1823
  return [address, balances];
1818
1824
  }));
1819
1825
  const allBalancesByKey = keyBy(balancesPerAddress.flatMap(([, addressBalances]) => addressBalances), b => getBalanceKey(b.tokenId, b.address));
@@ -1826,7 +1832,7 @@ const fetchBalances$6 = async ({
1826
1832
  tokenId: bd.token.id,
1827
1833
  networkId: bd.token.networkId,
1828
1834
  address: bd.address,
1829
- source: MODULE_TYPE$6,
1835
+ source: MODULE_TYPE$7,
1830
1836
  status: "live",
1831
1837
  value: "0"
1832
1838
  };
@@ -1854,7 +1860,7 @@ const TokenCacheSchema = z.discriminatedUnion("isValid", [z.strictObject({
1854
1860
  isValid: z.literal(false)
1855
1861
  })]);
1856
1862
  const METAPLEX_PROGRAM_ID = new PublicKey("metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s");
1857
- const fetchTokens$6 = async ({
1863
+ const fetchTokens$7 = async ({
1858
1864
  networkId,
1859
1865
  tokens,
1860
1866
  connector,
@@ -1872,8 +1878,8 @@ const fetchTokens$6 = async ({
1872
1878
  if (cached?.isValid === false) continue;
1873
1879
  const base = {
1874
1880
  id: tokenId,
1875
- type: MODULE_TYPE$6,
1876
- platform: PLATFORM$6,
1881
+ type: MODULE_TYPE$7,
1882
+ platform: PLATFORM$7,
1877
1883
  networkId
1878
1884
  };
1879
1885
  const token = assign(base, cached?.isValid ? omit(cached, ["isValid"]) : {}, tokenConfig);
@@ -1940,18 +1946,18 @@ const fetchOnChainTokenData = async (connector, tokenId) => {
1940
1946
  return null;
1941
1947
  };
1942
1948
 
1943
- const getMiniMetadata$6 = () => {
1949
+ const getMiniMetadata$7 = () => {
1944
1950
  throw new Error("MiniMetadata is not supported for solana tokens");
1945
1951
  };
1946
1952
 
1947
- const getTransferCallData$6 = async ({
1953
+ const getTransferCallData$7 = async ({
1948
1954
  from,
1949
1955
  to,
1950
1956
  value,
1951
1957
  token,
1952
1958
  connector
1953
1959
  }) => {
1954
- if (!isTokenOfType(token, MODULE_TYPE$6)) throw new Error(`Token type ${token.type} is not ${MODULE_TYPE$6}.`);
1960
+ if (!isTokenOfType(token, MODULE_TYPE$7)) throw new Error(`Token type ${token.type} is not ${MODULE_TYPE$7}.`);
1955
1961
  const connection = await connector.getConnection(token.networkId);
1956
1962
  const instructions = [];
1957
1963
  const mint = new PublicKey(token.mintAddress);
@@ -1982,8 +1988,8 @@ const tokenAccountExists = async (connection, address) => {
1982
1988
  }
1983
1989
  };
1984
1990
 
1985
- const SUBSCRIPTION_INTERVAL$2 = 6_000;
1986
- const subscribeBalances$6 = ({
1991
+ const SUBSCRIPTION_INTERVAL$3 = 6_000;
1992
+ const subscribeBalances$7 = ({
1987
1993
  networkId,
1988
1994
  tokensWithAddresses,
1989
1995
  connector
@@ -1997,17 +2003,17 @@ const subscribeBalances$6 = ({
1997
2003
  const poll = async () => {
1998
2004
  try {
1999
2005
  if (abortController.signal.aborted) return;
2000
- const balances = await fetchBalances$6({
2006
+ const balances = await fetchBalances$7({
2001
2007
  networkId,
2002
2008
  tokensWithAddresses: tokensWithAddresses,
2003
2009
  connector
2004
2010
  });
2005
2011
  if (abortController.signal.aborted) return;
2006
2012
  subscriber.next(balances);
2007
- setTimeout(poll, SUBSCRIPTION_INTERVAL$2);
2013
+ setTimeout(poll, SUBSCRIPTION_INTERVAL$3);
2008
2014
  } catch (error) {
2009
2015
  log.error("Error", {
2010
- module: MODULE_TYPE$6,
2016
+ module: MODULE_TYPE$7,
2011
2017
  networkId,
2012
2018
  addressesByToken: tokensWithAddresses,
2013
2019
  error
@@ -2023,13 +2029,13 @@ const subscribeBalances$6 = ({
2023
2029
  };
2024
2030
 
2025
2031
  const SolSplBalanceModule = {
2026
- type: MODULE_TYPE$6,
2027
- platform: PLATFORM$6,
2028
- getMiniMetadata: getMiniMetadata$6,
2029
- fetchTokens: fetchTokens$6,
2030
- fetchBalances: fetchBalances$6,
2031
- subscribeBalances: subscribeBalances$6,
2032
- getTransferCallData: getTransferCallData$6
2032
+ type: MODULE_TYPE$7,
2033
+ platform: PLATFORM$7,
2034
+ getMiniMetadata: getMiniMetadata$7,
2035
+ fetchTokens: fetchTokens$7,
2036
+ fetchBalances: fetchBalances$7,
2037
+ subscribeBalances: subscribeBalances$7,
2038
+ getTransferCallData: getTransferCallData$7
2033
2039
  };
2034
2040
 
2035
2041
  // to be used by chaindata too
@@ -2038,8 +2044,8 @@ const SolSplTokenConfigSchema = z.strictObject({
2038
2044
  ...TokenConfigBaseSchema.shape
2039
2045
  });
2040
2046
 
2041
- const MODULE_TYPE$5 = SubAssetsTokenSchema.shape.type.value;
2042
- const PLATFORM$5 = SubAssetsTokenSchema.shape.platform.value;
2047
+ const MODULE_TYPE$6 = SubAssetsTokenSchema.shape.type.value;
2048
+ const PLATFORM$6 = SubAssetsTokenSchema.shape.platform.value;
2043
2049
 
2044
2050
  const buildQueries$2 = (networkId, balanceDefs, miniMetadata) => {
2045
2051
  const networkStorageCoders = buildNetworkStorageCoders(networkId, miniMetadata, {
@@ -2115,7 +2121,7 @@ const tryEncode = (scaleCoder, ...args) => {
2115
2121
  }
2116
2122
  };
2117
2123
 
2118
- const fetchBalances$5 = async ({
2124
+ const fetchBalances$6 = async ({
2119
2125
  networkId,
2120
2126
  tokensWithAddresses,
2121
2127
  connector,
@@ -2127,7 +2133,7 @@ const fetchBalances$5 = async ({
2127
2133
  };
2128
2134
  const balanceDefs = getBalanceDefs(tokensWithAddresses);
2129
2135
  if (!miniMetadata?.data) {
2130
- log.warn(`MiniMetadata is required for fetching ${MODULE_TYPE$5} balances on ${networkId}.`);
2136
+ log.warn(`MiniMetadata is required for fetching ${MODULE_TYPE$6} balances on ${networkId}.`);
2131
2137
  return {
2132
2138
  success: [],
2133
2139
  errors: balanceDefs.map(def => ({
@@ -2137,19 +2143,19 @@ const fetchBalances$5 = async ({
2137
2143
  }))
2138
2144
  };
2139
2145
  }
2140
- if (miniMetadata.source !== MODULE_TYPE$5) {
2141
- log.warn(`Ignoring miniMetadata with source ${miniMetadata.source} in ${MODULE_TYPE$5}.`);
2146
+ if (miniMetadata.source !== MODULE_TYPE$6) {
2147
+ log.warn(`Ignoring miniMetadata with source ${miniMetadata.source} in ${MODULE_TYPE$6}.`);
2142
2148
  return {
2143
2149
  success: [],
2144
2150
  errors: balanceDefs.map(def => ({
2145
2151
  tokenId: def.token.id,
2146
2152
  address: def.address,
2147
- error: new Error(`Invalid request: miniMetadata source is not ${MODULE_TYPE$5}`)
2153
+ error: new Error(`Invalid request: miniMetadata source is not ${MODULE_TYPE$6}`)
2148
2154
  }))
2149
2155
  };
2150
2156
  }
2151
2157
  if (miniMetadata.chainId !== networkId) {
2152
- log.warn(`Ignoring miniMetadata with chainId ${miniMetadata.chainId} in ${MODULE_TYPE$5}. Expected chainId is ${networkId}`);
2158
+ log.warn(`Ignoring miniMetadata with chainId ${miniMetadata.chainId} in ${MODULE_TYPE$6}. Expected chainId is ${networkId}`);
2153
2159
  return {
2154
2160
  success: [],
2155
2161
  errors: balanceDefs.map(def => ({
@@ -2169,7 +2175,7 @@ const fetchBalances$5 = async ({
2169
2175
  address: def.address,
2170
2176
  networkId,
2171
2177
  tokenId: def.token.id,
2172
- source: MODULE_TYPE$5,
2178
+ source: MODULE_TYPE$6,
2173
2179
  status: "live",
2174
2180
  values: [{
2175
2181
  type: "free",
@@ -2188,7 +2194,7 @@ const fetchBalances$5 = async ({
2188
2194
  });
2189
2195
  };
2190
2196
 
2191
- const fetchTokens$5 = async ({
2197
+ const fetchTokens$6 = async ({
2192
2198
  networkId,
2193
2199
  tokens,
2194
2200
  connector,
@@ -2229,7 +2235,7 @@ const fetchTokens$5 = async ({
2229
2235
  const configTokenByAssetId = keyBy(tokens, t => t.assetId);
2230
2236
  return allTokens.map(asset => ({
2231
2237
  id: subAssetTokenId(networkId, String(asset.assetId)),
2232
- type: MODULE_TYPE$5,
2238
+ type: MODULE_TYPE$6,
2233
2239
  platform: "polkadot",
2234
2240
  networkId,
2235
2241
  assetId: String(asset.assetId),
@@ -2260,6 +2266,394 @@ const fetchTokens$5 = async ({
2260
2266
  });
2261
2267
  };
2262
2268
 
2269
+ const MODULE_TYPE$5 = SubDTaoTokenSchema.shape.type.value;
2270
+ const PLATFORM$5 = SubDTaoTokenSchema.shape.platform.value;
2271
+
2272
+ const TAO_DECIMALS = 9n;
2273
+
2274
+ // manipulating price as bigint requires using at least as many decimals as TAO itself
2275
+ const ALPHA_PRICE_SCALE = 10n ** TAO_DECIMALS;
2276
+ const getScaledAlphaPrice = (alphaIn, taoIn) => {
2277
+ if (!alphaIn || !taoIn) return 0n;
2278
+ return taoIn * ALPHA_PRICE_SCALE / alphaIn;
2279
+ };
2280
+ const alphaToTao = (alpha, scaledAlphaPrice) => {
2281
+ if (!alpha || !scaledAlphaPrice) return 0n;
2282
+ return alpha * scaledAlphaPrice / ALPHA_PRICE_SCALE;
2283
+ };
2284
+ const taoToAlpha = (tao, scaledAlphaPrice) => {
2285
+ if (!tao || !scaledAlphaPrice) return 0n;
2286
+ return tao * ALPHA_PRICE_SCALE / scaledAlphaPrice;
2287
+ };
2288
+
2289
+ const fetchBalances$5 = async ({
2290
+ networkId,
2291
+ tokensWithAddresses,
2292
+ connector,
2293
+ miniMetadata
2294
+ }) => {
2295
+ if (!tokensWithAddresses.length) return {
2296
+ success: [],
2297
+ errors: []
2298
+ };
2299
+ const balanceDefs = getBalanceDefs(tokensWithAddresses);
2300
+ if (!miniMetadata?.data) {
2301
+ log.warn(`MiniMetadata is required for fetching ${MODULE_TYPE$5} balances on ${networkId}.`, {
2302
+ tokensWithAddresses
2303
+ });
2304
+ return {
2305
+ success: [],
2306
+ errors: balanceDefs.map(def => ({
2307
+ tokenId: def.token.id,
2308
+ address: def.address,
2309
+ error: new Error("Minimetadata is required for fetching balances")
2310
+ }))
2311
+ };
2312
+ }
2313
+ if (miniMetadata.source !== MODULE_TYPE$5) {
2314
+ log.warn(`Ignoring miniMetadata with source ${miniMetadata.source} in ${MODULE_TYPE$5}.`);
2315
+ return {
2316
+ success: [],
2317
+ errors: balanceDefs.map(def => ({
2318
+ tokenId: def.token.id,
2319
+ address: def.address,
2320
+ error: new Error(`Invalid request: miniMetadata source is not ${MODULE_TYPE$5}`)
2321
+ }))
2322
+ };
2323
+ }
2324
+ if (miniMetadata.chainId !== networkId) {
2325
+ log.warn(`Ignoring miniMetadata with chainId ${miniMetadata.chainId} in ${MODULE_TYPE$5}. Expected chainId is ${networkId}`);
2326
+ return {
2327
+ success: [],
2328
+ errors: balanceDefs.map(def => ({
2329
+ tokenId: def.token.id,
2330
+ address: def.address,
2331
+ error: new Error(`Invalid request: Expected chainId is ${networkId}`)
2332
+ }))
2333
+ };
2334
+ }
2335
+ const addresses = uniq(balanceDefs.map(def => def.address));
2336
+ try {
2337
+ const [stakeInfos, dynamicInfos] = await Promise.all([fetchRuntimeCallResult(connector, networkId, miniMetadata.data, "StakeInfoRuntimeApi", "get_stake_info_for_coldkeys", [addresses]), fetchRuntimeCallResult(connector, networkId, miniMetadata.data, "SubnetInfoRuntimeApi", "get_all_dynamic_info", [])]);
2338
+ const dynamicInfoByNetuid = keyBy(dynamicInfos.filter(isNotNil), info => info.netuid);
2339
+ const balances = stakeInfos.flatMap(([address, stakes]) => stakes.map(stake => {
2340
+ const dynamicInfo = dynamicInfoByNetuid[stake.netuid];
2341
+ const scaledAlphaPrice = dynamicInfo ? getScaledAlphaPrice(dynamicInfo.alpha_in, dynamicInfo.tao_in) : 0n;
2342
+ return {
2343
+ address,
2344
+ tokenId: subDTaoTokenId(networkId, stake.netuid, stake.hotkey),
2345
+ baseTokenId: subDTaoTokenId(networkId, stake.netuid),
2346
+ stake: stake.stake,
2347
+ hotkey: stake.hotkey,
2348
+ netuid: stake.netuid,
2349
+ scaledAlphaPrice
2350
+ };
2351
+ }));
2352
+ const tokensById = keyBy(tokensWithAddresses.map(([token]) => token), t => t.id);
2353
+ const dynamicTokens = [];
2354
+
2355
+ // identify tokens that were not requested but have balances
2356
+ // BalanceProvider will be register them in ChaindataProvider at runtime, so they will be requested on next call
2357
+ for (const bal of balances) {
2358
+ if (!balanceDefs.some(def => def.token.id === bal.tokenId)) {
2359
+ const baseToken = tokensById[bal.baseTokenId];
2360
+ // define a token specific to this staking hotkey
2361
+ if (baseToken) {
2362
+ const cleanToken = getCleanToken(baseToken);
2363
+ const newToken = TokenSchema.parse({
2364
+ ...cleanToken,
2365
+ id: bal.tokenId,
2366
+ hotkey: bal.hotkey
2367
+ });
2368
+ dynamicTokens.push(newToken);
2369
+ }
2370
+ }
2371
+ }
2372
+ const success = balanceDefs.map(def => {
2373
+ const stake = balances.find(b => b.address === def.address && b.tokenId === def.token.id);
2374
+ const meta = {
2375
+ scaledAlphaPrice: stake?.scaledAlphaPrice.toString() ?? "0"
2376
+ };
2377
+ const balanceValue = {
2378
+ type: "free",
2379
+ label: stake?.netuid === 0 ? "Root Staking" : `Subnet Staking`,
2380
+ amount: stake?.stake.toString() ?? "0",
2381
+ meta
2382
+ };
2383
+ return {
2384
+ address: def.address,
2385
+ networkId,
2386
+ tokenId: def.token.id,
2387
+ source: MODULE_TYPE$5,
2388
+ status: "live",
2389
+ values: [balanceValue]
2390
+ };
2391
+ });
2392
+ return {
2393
+ success,
2394
+ errors: [],
2395
+ dynamicTokens
2396
+ };
2397
+ } catch (err) {
2398
+ log.warn("Failed to fetch balances for substrate-dtao", {
2399
+ err
2400
+ });
2401
+ const errors = balanceDefs.map(def => ({
2402
+ tokenId: def.token.id,
2403
+ address: def.address,
2404
+ error: new Error(`Failed to fetch balance for ${def.address} on ${networkId}`)
2405
+ }));
2406
+ return {
2407
+ success: [],
2408
+ errors
2409
+ };
2410
+ }
2411
+ };
2412
+
2413
+ // hardcoded because we dont have access to native tokens from the balance module
2414
+ const NATIVE_TOKEN_SYMBOLS = {
2415
+ "bittensor": "TAO",
2416
+ "bittensor-testnet": "testTAO"
2417
+ };
2418
+ const fetchTokens$5 = async ({
2419
+ networkId,
2420
+ connector,
2421
+ tokens,
2422
+ miniMetadata
2423
+ }) => {
2424
+ const anyMiniMetadata = miniMetadata;
2425
+ if (!anyMiniMetadata?.data) return [];
2426
+ const [transferableTokensMap, dynamicInfos] = await Promise.all([fetchTransferableTokensMap(connector, anyMiniMetadata.data, networkId), fetchRuntimeCallResult(connector, networkId, anyMiniMetadata.data, "SubnetInfoRuntimeApi", "get_all_dynamic_info", [])]);
2427
+ return dynamicInfos.filter(isNotNil).map(info => {
2428
+ const config = tokens.find(t => t.netuid === info.netuid);
2429
+ let symbol = new TextDecoder().decode(Uint8Array.from(info.token_symbol));
2430
+ const subnetName = info.subnet_identity?.subnet_name?.asText() ?? (info.netuid === 0 ? "Root" : `Subnet ${info.netuid}`);
2431
+ const name = `SN${info.netuid} | ${subnetName} ${symbol}`;
2432
+
2433
+ // for root we want same symbol as native so they can be grouped together in portfolio
2434
+ if (info.netuid === 0 && NATIVE_TOKEN_SYMBOLS[networkId]) symbol = NATIVE_TOKEN_SYMBOLS[networkId];
2435
+
2436
+ // if not stage in storage, consider transferable
2437
+ const isTransferable = transferableTokensMap[info.netuid] ?? true;
2438
+ const token = {
2439
+ id: subDTaoTokenId(networkId, info.netuid),
2440
+ type: MODULE_TYPE$5,
2441
+ platform: PLATFORM$5,
2442
+ networkId,
2443
+ netuid: info.netuid,
2444
+ isDefault: true,
2445
+ symbol,
2446
+ decimals: 9,
2447
+ name,
2448
+ subnetName,
2449
+ isTransferable
2450
+ };
2451
+ return Object.assign({}, token, config);
2452
+ }).filter(t => {
2453
+ const parsed = SubDTaoTokenSchema.safeParse(t);
2454
+ return parsed.success;
2455
+ });
2456
+ };
2457
+ const fetchTransferableTokensMap = async (connector, metadata, networkId) => {
2458
+ const {
2459
+ builder
2460
+ } = parseMetadataRpc(metadata);
2461
+ const transferToggleCodec = builder.buildStorage("SubtensorModule", "TransferToggle");
2462
+ const transferToggleKeys = await connector.send(networkId, "state_getKeys", [getStorageKeyPrefix("SubtensorModule", "TransferToggle")]);
2463
+ const transferToggleResults = await connector.send(networkId, "state_queryStorageAt", [transferToggleKeys]);
2464
+ const transferToggleEntries = transferToggleResults.length ? transferToggleResults[0].changes : [];
2465
+ return fromPairs(transferToggleEntries.map(([key, value]) => {
2466
+ const [netuid] = transferToggleCodec.keys.dec(key);
2467
+ const isTransferable = transferToggleCodec.value.dec(value);
2468
+ return [netuid, isTransferable];
2469
+ }));
2470
+ };
2471
+
2472
+ const getMiniMetadata$6 = ({
2473
+ networkId,
2474
+ specVersion,
2475
+ metadataRpc
2476
+ }) => {
2477
+ const source = MODULE_TYPE$5;
2478
+ const chainId = networkId;
2479
+ const systemVersion = getConstantValue(metadataRpc, "System", "Version");
2480
+ if (specVersion !== systemVersion.spec_version) throw new Error(`specVersion mismatch: expected ${specVersion}, metadata got ${systemVersion.spec_version}`);
2481
+ const id = deriveMiniMetadataId({
2482
+ source,
2483
+ chainId,
2484
+ specVersion
2485
+ });
2486
+ const {
2487
+ unifiedMetadata
2488
+ } = parseMetadataRpc(metadataRpc);
2489
+ if (unifiedMetadata.version < 14) throw new Error(`Unsupported metadata version: ${unifiedMetadata.version}. Minimum required is 14.`);
2490
+ return {
2491
+ id,
2492
+ source,
2493
+ chainId,
2494
+ specVersion,
2495
+ version: MINIMETADATA_VERSION,
2496
+ data: getData$4(metadataRpc),
2497
+ extra: null
2498
+ };
2499
+ };
2500
+ const getData$4 = metadataRpc => {
2501
+ const {
2502
+ metadata,
2503
+ unifiedMetadata
2504
+ } = parseMetadataRpc(metadataRpc);
2505
+ const isBittensor = unifiedMetadata.pallets.some(({
2506
+ name
2507
+ }) => name === "SubtensorModule");
2508
+ if (!isBittensor) return null;
2509
+ compactMetadata(metadata, [{
2510
+ pallet: "SubtensorModule",
2511
+ items: ["TransferToggle"]
2512
+ }], [{
2513
+ runtimeApi: "StakeInfoRuntimeApi",
2514
+ methods: ["get_stake_info_for_coldkeys"]
2515
+ }, {
2516
+ runtimeApi: "SubnetInfoRuntimeApi",
2517
+ methods: ["get_all_dynamic_info"]
2518
+ }]);
2519
+ return encodeMetadata(metadata);
2520
+ };
2521
+
2522
+ const getTransferCallData$6 = ({
2523
+ from,
2524
+ to,
2525
+ value,
2526
+ token,
2527
+ metadataRpc
2528
+ }) => {
2529
+ if (!isTokenOfType(token, MODULE_TYPE$5)) throw new Error(`Token type ${token.type} is not ${MODULE_TYPE$5}.`);
2530
+ const {
2531
+ netuid: subnetId,
2532
+ hotkey
2533
+ } = parseSubDTaoTokenId(token.id);
2534
+ if (!hotkey) throw new Error(`Missing hotkey`);
2535
+ const {
2536
+ builder
2537
+ } = parseMetadataRpc(metadataRpc);
2538
+ const {
2539
+ codec,
2540
+ location
2541
+ } = builder.buildCall("SubtensorModule", "transfer_stake");
2542
+ const args = codec.enc({
2543
+ origin_netuid: subnetId,
2544
+ hotkey,
2545
+ destination_coldkey: to,
2546
+ destination_netuid: subnetId,
2547
+ alpha_amount: value
2548
+ });
2549
+ const callData = Binary.fromBytes(mergeUint8([new Uint8Array(location), args]));
2550
+ return {
2551
+ address: from,
2552
+ method: callData.asHex()
2553
+ };
2554
+ };
2555
+
2556
+ const SUBSCRIPTION_INTERVAL$2 = 6_000;
2557
+ const subscribeBalances$6 = ({
2558
+ networkId,
2559
+ tokensWithAddresses,
2560
+ connector,
2561
+ miniMetadata
2562
+ }) => {
2563
+ if (!tokensWithAddresses.length) return of({
2564
+ success: [],
2565
+ errors: []
2566
+ });
2567
+ return new Observable(subscriber => {
2568
+ const abortController = new AbortController();
2569
+
2570
+ // on hydration balances are fetched using a runtimeApi, which can't be subscribed to.
2571
+ // => poll values for each block
2572
+ const poll = async () => {
2573
+ try {
2574
+ if (abortController.signal.aborted) return;
2575
+ const balances = await fetchBalances$5({
2576
+ networkId,
2577
+ tokensWithAddresses: tokensWithAddresses,
2578
+ connector,
2579
+ miniMetadata
2580
+ });
2581
+ if (abortController.signal.aborted) return;
2582
+ subscriber.next(balances);
2583
+ setTimeout(poll, SUBSCRIPTION_INTERVAL$2);
2584
+ } catch (error) {
2585
+ log.error("Error", {
2586
+ module: MODULE_TYPE$5,
2587
+ networkId,
2588
+ miniMetadata,
2589
+ addressesByToken: tokensWithAddresses,
2590
+ error
2591
+ });
2592
+ subscriber.error(error);
2593
+ }
2594
+ };
2595
+ poll();
2596
+ return () => {
2597
+ abortController.abort();
2598
+ };
2599
+ }).pipe(distinctUntilChanged(isEqual));
2600
+ };
2601
+
2602
+ const SubDTaoBalanceModule = {
2603
+ type: MODULE_TYPE$5,
2604
+ platform: PLATFORM$5,
2605
+ getMiniMetadata: getMiniMetadata$6,
2606
+ fetchTokens: fetchTokens$5,
2607
+ fetchBalances: fetchBalances$5,
2608
+ subscribeBalances: subscribeBalances$6,
2609
+ getTransferCallData: getTransferCallData$6
2610
+ };
2611
+
2612
+ // to be used by chaindata too
2613
+ const SubDTaoTokenConfigSchema = z.strictObject({
2614
+ netuid: SubDTaoTokenSchema.shape.netuid,
2615
+ ...TokenConfigBaseSchema.shape
2616
+ });
2617
+
2618
+ const ONE_ALPHA = 10n ** TAO_DECIMALS;
2619
+
2620
+ /**
2621
+ * To be used for tokens that don't have a coingecko id
2622
+ *
2623
+ * @param token
2624
+ * @param tokenRates
2625
+ * @param scaledAlphaPrice
2626
+ * @returns
2627
+ */
2628
+ const getDTaoTokenRates = (token, tokenRates, scaledAlphaPrice) => {
2629
+ try {
2630
+ const taoTokenId = subNativeTokenId(token.networkId);
2631
+ const taoTokenRates = tokenRates[taoTokenId];
2632
+ if (!taoTokenRates) return null;
2633
+
2634
+ // for root subnet, same rates as TAO
2635
+ if (token.netuid === 0) return structuredClone(taoTokenRates);
2636
+ const alphaRates = newTokenRates();
2637
+ for (const [currency, taoRate] of Object.entries(taoTokenRates)) {
2638
+ if (!taoRate) {
2639
+ alphaRates[currency] = null;
2640
+ } else {
2641
+ const taoPrice = alphaToTao(ONE_ALPHA, BigInt(scaledAlphaPrice));
2642
+ const priceRatio = Number(taoPrice) / Number(ALPHA_PRICE_SCALE);
2643
+ alphaRates[currency] = {
2644
+ price: taoRate.price * priceRatio,
2645
+ marketCap: taoRate.marketCap ? taoRate.marketCap * priceRatio : undefined,
2646
+ change24h: undefined // cannot be determined from TAO rates alone
2647
+ };
2648
+ }
2649
+ }
2650
+ return alphaRates;
2651
+ } catch (err) {
2652
+ log.error(err);
2653
+ return null;
2654
+ }
2655
+ };
2656
+
2263
2657
  function excludeFromTransferableAmount(locks) {
2264
2658
  if (typeof locks === "string") return BigInt(locks);
2265
2659
  if (!Array.isArray(locks)) locks = [locks];
@@ -2588,6 +2982,16 @@ class Balance {
2588
2982
  return lpTokenRates;
2589
2983
  }
2590
2984
 
2985
+ // dTAO balances need to be converted to the native token to compute their rate, unless we have a coingeckoId
2986
+ if (this.token?.type === "substrate-dtao" && !this.token.coingeckoId) {
2987
+ if (!this.#db?.tokenRates) return null;
2988
+ const balances = this.#valueGetter.get("free");
2989
+ if (!balances.length) return null;
2990
+ const balanceMeta = balances[0].meta;
2991
+ if (!balanceMeta?.scaledAlphaPrice) return null;
2992
+ return getDTaoTokenRates(this.token, this.#db.tokenRates, balanceMeta.scaledAlphaPrice);
2993
+ }
2994
+
2591
2995
  // other tokens can just pick from the tokenRates db using the tokenId
2592
2996
  return this.#db?.tokenRates && this.#db.tokenRates[this.tokenId] || null;
2593
2997
  }
@@ -2634,9 +3038,7 @@ class Balance {
2634
3038
  const nomPoolStakedPlancks = this.locks.some(lock => lock.source === "substrate-native-holds" && lock.label === "DelegatedStaking") ? 0n : this.nompools.map(({
2635
3039
  amount
2636
3040
  }) => amount.planck).reduce((a, b) => a + b, 0n);
2637
- return this.#format(this.free.planck + this.reserved.planck + nomPoolStakedPlancks + this.subtensor.map(({
2638
- amount
2639
- }) => amount.planck).reduce((a, b) => a + b, 0n) + includeInTotalExtraAmount(extra));
3041
+ return this.#format(this.free.planck + this.reserved.planck + nomPoolStakedPlancks + includeInTotalExtraAmount(extra));
2640
3042
  }
2641
3043
  /** The non-reserved balance of this token. Includes the frozen amount. Is included in the total. */
2642
3044
  get free() {
@@ -2673,9 +3075,6 @@ class Balance {
2673
3075
  get nompools() {
2674
3076
  return this.getValue("nompool");
2675
3077
  }
2676
- get subtensor() {
2677
- return this.getValue("subtensor");
2678
- }
2679
3078
 
2680
3079
  /** The extra balance of this token */
2681
3080
  get extra() {
@@ -2748,8 +3147,7 @@ class Balance {
2748
3147
  const nomPoolStakedPlancks = this.locks.some(lock => lock.source === "substrate-native-holds" && lock.label === "DelegatedStaking") ? 0n : this.nompools.map(({
2749
3148
  amount
2750
3149
  }) => amount.planck).reduce((a, b) => a + b, 0n);
2751
- const otherUnavailable = nomPoolStakedPlancks + this.subtensor.reduce((total, each) => total + each.amount.planck, 0n);
2752
- return this.#format(baseUnavailable + otherUnavailable);
3150
+ return this.#format(baseUnavailable + nomPoolStakedPlancks);
2753
3151
  }
2754
3152
 
2755
3153
  /** The feePayable balance of this token. Is generally the free amount - the feeFrozen amount. */
@@ -2996,13 +3394,6 @@ const getValueId = amount => {
2996
3394
  const meta = amount.meta;
2997
3395
  if (!meta) return "";
2998
3396
  if (amount.type === "nompool") return meta.poolId?.toString() ?? "";
2999
- if (amount.type === "subtensor") {
3000
- const {
3001
- hotkey,
3002
- netuid
3003
- } = meta;
3004
- if (hotkey && netuid !== undefined) return `${hotkey.toString()}${netuid.toString()}`;
3005
- }
3006
3397
  return "";
3007
3398
  };
3008
3399
  return [amount.label, amount.type, amount.source, getMetaId()].join("::");
@@ -3024,7 +3415,7 @@ const getMiniMetadata$5 = ({
3024
3415
  specVersion,
3025
3416
  metadataRpc
3026
3417
  }) => {
3027
- const source = MODULE_TYPE$5;
3418
+ const source = MODULE_TYPE$6;
3028
3419
  const chainId = networkId;
3029
3420
  const systemVersion = getConstantValue(metadataRpc, "System", "Version");
3030
3421
  if (specVersion !== systemVersion.spec_version) throw new Error(`specVersion mismatch: expected ${specVersion}, metadata got ${systemVersion.spec_version}`);
@@ -3070,7 +3461,7 @@ const getTransferCallData$5 = ({
3070
3461
  type,
3071
3462
  metadataRpc
3072
3463
  }) => {
3073
- if (!isTokenOfType(token, MODULE_TYPE$5)) throw new Error(`Token type ${token.type} is not ${MODULE_TYPE$5}.`);
3464
+ if (!isTokenOfType(token, MODULE_TYPE$6)) throw new Error(`Token type ${token.type} is not ${MODULE_TYPE$6}.`);
3074
3465
  const {
3075
3466
  builder
3076
3467
  } = parseMetadataRpc(metadataRpc);
@@ -3178,11 +3569,11 @@ const subscribeBalances$5 = ({
3178
3569
  };
3179
3570
 
3180
3571
  const SubAssetsBalanceModule = {
3181
- type: MODULE_TYPE$5,
3182
- platform: PLATFORM$5,
3572
+ type: MODULE_TYPE$6,
3573
+ platform: PLATFORM$6,
3183
3574
  getMiniMetadata: getMiniMetadata$5,
3184
- fetchTokens: fetchTokens$5,
3185
- fetchBalances: fetchBalances$5,
3575
+ fetchTokens: fetchTokens$6,
3576
+ fetchBalances: fetchBalances$6,
3186
3577
  subscribeBalances: subscribeBalances$5,
3187
3578
  getTransferCallData: getTransferCallData$5
3188
3579
  };
@@ -3903,154 +4294,6 @@ const SubHydrationBalanceModule = {
3903
4294
  const MODULE_TYPE$2 = SubNativeTokenSchema.shape.type.value;
3904
4295
  const PLATFORM$2 = SubNativeTokenSchema.shape.platform.value;
3905
4296
 
3906
- const SUBTENSOR_ROOT_NETUID = 0;
3907
- const SUBTENSOR_MIN_STAKE_AMOUNT_PLANK = 1000000n;
3908
- const TAO_DECIMALS = 9n;
3909
- const SCALE_FACTOR = 10n ** TAO_DECIMALS; // Equivalent to 10e9 for precision
3910
- const ONE_ALPHA_TOKEN = SCALE_FACTOR;
3911
- const calculateAlphaPrice = ({
3912
- dynamicInfo
3913
- }) => {
3914
- if (!dynamicInfo) return 0n;
3915
- const {
3916
- alpha_in,
3917
- tao_in
3918
- } = dynamicInfo;
3919
-
3920
- // Scale taoIn before division to preserve precision
3921
- const result = tao_in * SCALE_FACTOR / alpha_in;
3922
- return result; // Scaled price as bigint
3923
- };
3924
- const calculateTaoAmountFromAlpha = ({
3925
- alphaPrice,
3926
- alphaStaked
3927
- }) => {
3928
- if (!alphaStaked || !alphaPrice) return 0n;
3929
- const expectedAlpha = alphaStaked * alphaPrice;
3930
- return expectedAlpha / SCALE_FACTOR;
3931
- };
3932
- const calculateTaoFromDynamicInfo = ({
3933
- dynamicInfo,
3934
- alphaStaked
3935
- }) => {
3936
- const alphaPrice = calculateAlphaPrice({
3937
- dynamicInfo
3938
- });
3939
- return calculateTaoAmountFromAlpha({
3940
- alphaPrice,
3941
- alphaStaked
3942
- });
3943
- };
3944
-
3945
- // per address, lists of values to add to the native balance
3946
-
3947
- const getSubtensorStakingBalances$ = (connector, networkId, balanceDefs, miniMetadata) => {
3948
- const addresses = balanceDefs.map(def => def.address);
3949
- const token = balanceDefs[0].token;
3950
- if (!addresses.length || !token || !miniMetadata.extra.hasSubtensorPallet || !miniMetadata.data) return of({});
3951
-
3952
- // we are only doing runtime calls, there is no way to subscribe to changes, except polling
3953
- // => start immediately, then repeat every 30 seconds
3954
- return timer(0, 30000).pipe(switchMap(() => from(fetchStakeInfoByAddress(connector, networkId, miniMetadata, addresses)).pipe(switchMap(stakeInfoByAddress => fetchStakingBalanceValuesByAddress(connector, networkId, miniMetadata, stakeInfoByAddress)))));
3955
- };
3956
- const fetchStakingBalanceValuesByAddress = async (connector, networkId, miniMetadata, stakeInfoByAddress) => {
3957
- const uniqueNetuids = uniq(values(stakeInfoByAddress).flatMap(infos => infos.map(info => info.netuid))).filter(netuid => netuid !== SUBTENSOR_ROOT_NETUID);
3958
- const dynamicInfoByNetuid = await fetchDynamicInfoByNetuid(connector, networkId, miniMetadata, uniqueNetuids);
3959
- return fromPairs(toPairs(stakeInfoByAddress).map(([address, stakeInfos]) => {
3960
- const stakesBalances = stakeInfos.filter(({
3961
- stake
3962
- }) => stake >= SUBTENSOR_MIN_STAKE_AMOUNT_PLANK).map(({
3963
- hotkey,
3964
- netuid,
3965
- stake
3966
- }) => ({
3967
- hotkey,
3968
- netuid: Number(netuid),
3969
- stake: BigInt(stake),
3970
- dynamicInfo: dynamicInfoByNetuid[Number(netuid)]
3971
- })).map(({
3972
- hotkey,
3973
- stake,
3974
- netuid,
3975
- dynamicInfo
3976
- }) => {
3977
- const {
3978
- token_symbol,
3979
- subnet_name,
3980
- subnet_identity
3981
- } = dynamicInfo ?? {};
3982
- const tokenSymbol = new TextDecoder().decode(Uint8Array.from(token_symbol ?? []));
3983
- const subnetName = new TextDecoder().decode(Uint8Array.from(subnet_name ?? []));
3984
- const subnetIdentity = subnet_identity ? fromPairs(toPairs(subnet_identity).map(([key, binary]) => [key, binary.asText()])) : undefined;
3985
-
3986
- // Add 1n balance if failed to fetch dynamic info, so the position is not ignored by Balance lib and is displayed in the UI.
3987
- const alphaStakedInTao = dynamicInfo ? calculateTaoFromDynamicInfo({
3988
- dynamicInfo,
3989
- alphaStaked: stake
3990
- }) : 1n;
3991
- const alphaToTaoRate = calculateTaoFromDynamicInfo({
3992
- dynamicInfo: dynamicInfo ?? null,
3993
- alphaStaked: ONE_ALPHA_TOKEN
3994
- }).toString();
3995
- const stakeByNetuid = Number(netuid) === SUBTENSOR_ROOT_NETUID ? stake : alphaStakedInTao;
3996
- const balanceValue = {
3997
- source: "subtensor-staking",
3998
- type: "subtensor",
3999
- label: "subtensor-staking",
4000
- amount: stakeByNetuid.toString(),
4001
- meta: {
4002
- type: "subtensor-staking",
4003
- hotkey,
4004
- netuid,
4005
- amountStaked: stake.toString(),
4006
- alphaToTaoRate,
4007
- dynamicInfo: {
4008
- tokenSymbol,
4009
- subnetName,
4010
- subnetIdentity: {
4011
- ...subnetIdentity,
4012
- subnetName: subnetIdentity?.subnet_name || subnetName
4013
- }
4014
- }
4015
- }
4016
- };
4017
- return balanceValue;
4018
- });
4019
- return [address, stakesBalances];
4020
- }));
4021
- };
4022
- const fetchStakeInfoByAddress = async (connector, networkId, miniMetadata, addresses) => {
4023
- const pairs = await Promise.all(addresses.map(async address => [address, await withRetry(() => fetchRuntimeCallResult(connector, networkId, miniMetadata.data, "StakeInfoRuntimeApi", "get_stake_info_for_coldkey", [address]), {
4024
- delay: 500,
4025
- retryCount: 3
4026
- })]));
4027
- return fromPairs(pairs);
4028
- };
4029
-
4030
- // assume dynamic info doesnt change over the course of a browser session
4031
- const dynamicInfoCache = new Map();
4032
- const getCacheKey$1 = (networkId, netuid) => `${networkId}:${netuid}`;
4033
- const fetchDynamicInfoByNetuid = async (connector, networkId, miniMetadata, uniqueNetuids) => {
4034
- const fetchInfo = async netuid => {
4035
- if (netuid === SUBTENSOR_ROOT_NETUID) return null;
4036
- const cacheKey = getCacheKey$1(networkId, netuid);
4037
- if (!dynamicInfoCache.has(cacheKey)) {
4038
- await withRetry(async () => {
4039
- const result = await fetchRuntimeCallResult(connector, networkId, miniMetadata.data, "SubnetInfoRuntimeApi", "get_dynamic_info", [netuid]);
4040
- dynamicInfoCache.set(cacheKey, result); // Cache successful response
4041
-
4042
- return result;
4043
- }, {
4044
- delay: 500,
4045
- retryCount: 3
4046
- });
4047
- }
4048
- return dynamicInfoCache.get(cacheKey) ?? null;
4049
- };
4050
- const results = await Promise.all(uniqueNetuids.map(async netuid => [netuid, await fetchInfo(netuid)]));
4051
- return fromPairs(results);
4052
- };
4053
-
4054
4297
  const getOtherType = input => `other-${input}`;
4055
4298
 
4056
4299
  /**
@@ -4491,17 +4734,6 @@ const fetchBalances$2 = async ({
4491
4734
  // now for each balance that includes nomPoolStaking, we need to fetch the metadata for the pool
4492
4735
  const nomPoolQueries = buildNomPoolQueries(networkId, partialBalances, miniMetadata);
4493
4736
  const balances = await fetchRpcQueryPack(connector, networkId, nomPoolQueries);
4494
-
4495
- // TODO ⚠️ dedupe locks
4496
-
4497
- const subtensorBalances$ = getSubtensorStakingBalances$(connector, networkId, balanceDefs, miniMetadata);
4498
- const subtensorBalancesByAddress = await firstValueFrom(subtensorBalances$);
4499
- for (const [address, subtensorBalances] of Object.entries(subtensorBalancesByAddress)) {
4500
- const balance = balances.find(b => b.address === address);
4501
- if (balance?.values) balance.values = [...balance.values.filter(({
4502
- source
4503
- }) => source !== "subtensor-staking"), ...subtensorBalances];
4504
- }
4505
4737
  return {
4506
4738
  success: balances,
4507
4739
  errors: []
@@ -4590,7 +4822,6 @@ const getMiniMetadata$2 = ({
4590
4822
  };
4591
4823
  const existentialDeposit = tryGetConstantValue(metadataRpc, "Balances", "ExistentialDeposit")?.toString();
4592
4824
  const nominationPoolsPalletId = tryGetConstantValue(metadataRpc, "NominationPools", "PalletId")?.asText();
4593
- const hasSubtensorPallet = !!tryGetConstantValue(metadataRpc, "SubtensorModule", "KeySwapCost");
4594
4825
  const hasFreezesItem = Boolean(unifiedMetadata.pallets.find(({
4595
4826
  name
4596
4827
  }) => name === "Balances")?.storage?.items.find(({
@@ -4610,15 +4841,6 @@ const getMiniMetadata$2 = ({
4610
4841
  }, {
4611
4842
  pallet: "Staking",
4612
4843
  items: ["Ledger"]
4613
- }, {
4614
- pallet: "SubtensorModule",
4615
- items: ["StakingHotkeys", "Stake"]
4616
- }], [{
4617
- runtimeApi: "StakeInfoRuntimeApi",
4618
- methods: ["get_stake_info_for_coldkey"]
4619
- }, {
4620
- runtimeApi: "SubnetInfoRuntimeApi",
4621
- methods: ["get_dynamic_info"]
4622
4844
  }]);
4623
4845
  return {
4624
4846
  id,
@@ -4630,8 +4852,7 @@ const getMiniMetadata$2 = ({
4630
4852
  extra: {
4631
4853
  useLegacyTransferableCalculation,
4632
4854
  existentialDeposit,
4633
- nominationPoolsPalletId,
4634
- hasSubtensorPallet
4855
+ nominationPoolsPalletId
4635
4856
  }
4636
4857
  };
4637
4858
  };
@@ -4741,19 +4962,12 @@ const subscribeBalances$2 = ({
4741
4962
  // could be use as shared observable key if we decide to cache the sub
4742
4963
  const balanceDefs = getBalanceDefs(tokensWithAddresses);
4743
4964
  const baseQueries = buildBaseQueries(networkId, balanceDefs, miniMetadata);
4744
- const baseBalances$ = getRpcQueryPack$(connector, networkId, baseQueries).pipe(switchMap(partialBalances => {
4965
+ return getRpcQueryPack$(connector, networkId, baseQueries).pipe(switchMap(partialBalances => {
4745
4966
  // now for each balance that includes nomPoolStaking, we need to fetch the metadata for the pool
4746
4967
  const nomPoolQueries = buildNomPoolQueries(networkId, partialBalances, miniMetadata);
4747
4968
  return getRpcQueryPack$(connector, networkId, nomPoolQueries);
4748
- }));
4749
- const subtensorBalancesByAddress$ = getSubtensorStakingBalances$(connector, networkId, balanceDefs, miniMetadata);
4750
- return combineLatest([baseBalances$, subtensorBalancesByAddress$]).pipe(map(([baseBalances, subtensorBalancesByAddress]) => ({
4751
- success: [...baseBalances.map(b => ({
4752
- ...b,
4753
- values: [...(b.values?.filter(({
4754
- source
4755
- }) => source !== "subtensor-staking") ?? []), ...(subtensorBalancesByAddress[b.address] ?? [])]
4756
- }))],
4969
+ }), map(balances => ({
4970
+ success: balances,
4757
4971
  errors: []
4758
4972
  })));
4759
4973
  };
@@ -4785,8 +4999,7 @@ const SubNativeMiniMetadataExtraSchema = z.strictObject({
4785
4999
  disable: z.boolean().optional(),
4786
5000
  useLegacyTransferableCalculation: z.boolean().optional(),
4787
5001
  existentialDeposit: z.string().optional(),
4788
- nominationPoolsPalletId: z.string().optional(),
4789
- hasSubtensorPallet: z.boolean().optional()
5002
+ nominationPoolsPalletId: z.string().optional()
4790
5003
  });
4791
5004
 
4792
5005
  // Do not use this type outside of this module
@@ -6589,7 +6802,7 @@ const SubTokensMiniMetadataExtraSchema = z.strictObject({
6589
6802
  palletId: z.string()
6590
6803
  });
6591
6804
 
6592
- const BALANCE_MODULES = [SubNativeBalanceModule, SubAssetsBalanceModule, SubHydrationBalanceModule, SubForeignAssetsBalanceModule, SubPsp22BalanceModule, SubTokensBalanceModule, EvmErc20BalanceModule, EvmUniswapV2BalanceModule, EvmNativeBalanceModule, SolNativeBalanceModule, SolSplBalanceModule];
6805
+ const BALANCE_MODULES = [SubNativeBalanceModule, SubAssetsBalanceModule, SubDTaoBalanceModule, SubHydrationBalanceModule, SubForeignAssetsBalanceModule, SubPsp22BalanceModule, SubTokensBalanceModule, EvmErc20BalanceModule, EvmUniswapV2BalanceModule, EvmNativeBalanceModule, SolNativeBalanceModule, SolSplBalanceModule];
6593
6806
 
6594
6807
  // share requests as all modules will call this at once
6595
6808
  const CACHE$1 = new Map();
@@ -6745,7 +6958,8 @@ class BalancesProvider {
6745
6958
  balances: results.flatMap(result => result.balances.map(b => isStale && b.status !== "live" ? {
6746
6959
  ...b,
6747
6960
  status: "stale"
6748
- } : b)).sort(sortByBalanceId)
6961
+ } : b)).sort(sortByBalanceId),
6962
+ failedBalanceIds: results.flatMap(result => result.failedBalanceIds)
6749
6963
  })), distinctUntilChanged(isEqual));
6750
6964
  }
6751
6965
  fetchBalances(addressesByTokenId) {
@@ -6786,17 +7000,25 @@ class BalancesProvider {
6786
7000
  });
6787
7001
  return of({
6788
7002
  status: "live",
6789
- balances: []
7003
+ balances: [],
7004
+ failedBalanceIds: []
6790
7005
  });
6791
7006
  }
6792
7007
  }
6793
7008
  }));
6794
7009
  }), map(results => {
7010
+ // for each balance that could not be fetched, see if we have a stored balance and return it, marked as stale
7011
+ const errorBalanceIds = results.flatMap(result => result.failedBalanceIds);
7012
+ const staleBalances = errorBalanceIds.map(balanceId => this.#storage.value.balances[balanceId]).filter(isNotNil).map(b => ({
7013
+ ...b,
7014
+ status: "stale"
7015
+ }));
6795
7016
  return {
6796
7017
  status: results.some(({
6797
7018
  status
6798
7019
  }) => status === "initialising") ? "initialising" : "live",
6799
- balances: results.flatMap(result => result.balances).sort(sortByBalanceId)
7020
+ balances: results.flatMap(result => result.balances).concat(staleBalances).sort(sortByBalanceId),
7021
+ failedBalanceIds: []
6800
7022
  };
6801
7023
  }), distinctUntilChanged(isEqual));
6802
7024
  }
@@ -6808,7 +7030,8 @@ class BalancesProvider {
6808
7030
  }, () => {
6809
7031
  if (!tokensWithAddresses.length) return of({
6810
7032
  status: "live",
6811
- balances: []
7033
+ balances: [],
7034
+ failedBalanceIds: []
6812
7035
  });
6813
7036
  const moduleAddressesByTokenId = fromPairs(tokensWithAddresses.map(([token, addresses]) => [token.id, addresses]));
6814
7037
 
@@ -6821,7 +7044,8 @@ class BalancesProvider {
6821
7044
  log.warn("[balances] no substrate connector or miniMetadata for module", mod.type);
6822
7045
  return defer(() => of({
6823
7046
  status: "initialising",
6824
- balances: this.getStoredBalances(moduleAddressesByTokenId)
7047
+ balances: this.getStoredBalances(moduleAddressesByTokenId),
7048
+ failedBalanceIds: []
6825
7049
  }));
6826
7050
  }
6827
7051
  const moduleBalances$ = this.getNetworkMiniMetadatas$(networkId).pipe(map(miniMetadatas => miniMetadatas.find(m => m.source === mod.type)), switchMap(miniMetadata => mod.subscribeBalances({
@@ -6831,10 +7055,22 @@ class BalancesProvider {
6831
7055
  miniMetadata: miniMetadata
6832
7056
  })), catchError(() => EMPTY),
6833
7057
  // don't emit, let provider mark balances stale
6834
- map(results => ({
7058
+ tap(results => {
7059
+ if (results.dynamicTokens?.length) {
7060
+ // register missing tokens in the chaindata provider
7061
+ this.#chaindataProvider.registerDynamicTokens(results.dynamicTokens);
7062
+ }
7063
+ }), map(results => ({
6835
7064
  status: "live",
6836
7065
  // exclude zero balances
6837
- balances: results.success.filter(b => new Balance(b).total.planck > 0n)
7066
+ balances: results.success.filter(b => new Balance(b).total.planck > 0n),
7067
+ failedBalanceIds: results.errors.map(({
7068
+ tokenId,
7069
+ address
7070
+ }) => getBalanceId({
7071
+ tokenId,
7072
+ address
7073
+ }))
6838
7074
  })), tap(results => {
6839
7075
  this.updateStorage$(balanceIds, results);
6840
7076
  }),
@@ -6847,7 +7083,8 @@ class BalancesProvider {
6847
7083
  // defer the startWith call to start with up to date balances each time the observable is re-subscribed to
6848
7084
  return defer(() => moduleBalances$.pipe(startWith({
6849
7085
  status: "initialising",
6850
- balances: this.getStoredBalances(moduleAddressesByTokenId)
7086
+ balances: this.getStoredBalances(moduleAddressesByTokenId),
7087
+ failedBalanceIds: []
6851
7088
  })));
6852
7089
  });
6853
7090
  }
@@ -6859,7 +7096,8 @@ class BalancesProvider {
6859
7096
  }, () => {
6860
7097
  if (!tokensWithAddresses.length) return of({
6861
7098
  status: "live",
6862
- balances: []
7099
+ balances: [],
7100
+ failedBalanceIds: []
6863
7101
  });
6864
7102
  const moduleAddressesByTokenId = fromPairs(tokensWithAddresses.map(([token, addresses]) => [token.id, addresses]));
6865
7103
 
@@ -6872,7 +7110,8 @@ class BalancesProvider {
6872
7110
  log.warn("[balances] no ethereum connector for module", mod.type);
6873
7111
  return defer(() => of({
6874
7112
  status: "initialising",
6875
- balances: this.getStoredBalances(moduleAddressesByTokenId)
7113
+ balances: this.getStoredBalances(moduleAddressesByTokenId),
7114
+ failedBalanceIds: []
6876
7115
  }));
6877
7116
  }
6878
7117
  const moduleBalances$ = mod.subscribeBalances({
@@ -6884,7 +7123,14 @@ class BalancesProvider {
6884
7123
  map(results => ({
6885
7124
  status: "live",
6886
7125
  // exclude zero balances
6887
- balances: results.success.filter(b => new Balance(b).total.planck > 0n)
7126
+ balances: results.success.filter(b => new Balance(b).total.planck > 0n),
7127
+ failedBalanceIds: results.errors.map(({
7128
+ tokenId,
7129
+ address
7130
+ }) => getBalanceId({
7131
+ tokenId,
7132
+ address
7133
+ }))
6888
7134
  })), tap(results => {
6889
7135
  this.updateStorage$(balanceIds, results);
6890
7136
  }),
@@ -6897,7 +7143,8 @@ class BalancesProvider {
6897
7143
  // defer the startWith call to start with up to date balances each time the observable is re-subscribed to
6898
7144
  return defer(() => moduleBalances$.pipe(startWith({
6899
7145
  status: "initialising",
6900
- balances: this.getStoredBalances(moduleAddressesByTokenId)
7146
+ balances: this.getStoredBalances(moduleAddressesByTokenId),
7147
+ failedBalanceIds: []
6901
7148
  })));
6902
7149
  });
6903
7150
  }
@@ -6909,7 +7156,8 @@ class BalancesProvider {
6909
7156
  }, () => {
6910
7157
  if (!tokensWithAddresses.length) return of({
6911
7158
  status: "live",
6912
- balances: []
7159
+ balances: [],
7160
+ failedBalanceIds: []
6913
7161
  });
6914
7162
  const moduleAddressesByTokenId = fromPairs(tokensWithAddresses.map(([token, addresses]) => [token.id, addresses]));
6915
7163
 
@@ -6922,7 +7170,8 @@ class BalancesProvider {
6922
7170
  log.warn("[balances] no solana connector for module", mod.type);
6923
7171
  return defer(() => of({
6924
7172
  status: "initialising",
6925
- balances: this.getStoredBalances(moduleAddressesByTokenId)
7173
+ balances: this.getStoredBalances(moduleAddressesByTokenId),
7174
+ failedBalanceIds: []
6926
7175
  }));
6927
7176
  }
6928
7177
  const moduleBalances$ = mod.subscribeBalances({
@@ -6934,7 +7183,14 @@ class BalancesProvider {
6934
7183
  map(results => ({
6935
7184
  status: "live",
6936
7185
  // exclude zero balances
6937
- balances: results.success.filter(b => new Balance(b).total.planck > 0n)
7186
+ balances: results.success.filter(b => new Balance(b).total.planck > 0n),
7187
+ failedBalanceIds: results.errors.map(({
7188
+ tokenId,
7189
+ address
7190
+ }) => getBalanceId({
7191
+ tokenId,
7192
+ address
7193
+ }))
6938
7194
  })), tap(results => {
6939
7195
  this.updateStorage$(balanceIds, results);
6940
7196
  }),
@@ -6947,7 +7203,8 @@ class BalancesProvider {
6947
7203
  // defer the startWith call to start with up to date balances each time the observable is re-subscribed to
6948
7204
  return defer(() => moduleBalances$.pipe(startWith({
6949
7205
  status: "initialising",
6950
- balances: this.getStoredBalances(moduleAddressesByTokenId)
7206
+ balances: this.getStoredBalances(moduleAddressesByTokenId),
7207
+ failedBalanceIds: []
6951
7208
  })));
6952
7209
  });
6953
7210
  }
@@ -6955,13 +7212,19 @@ class BalancesProvider {
6955
7212
  if (balancesResult.status !== "live") return;
6956
7213
  const storage = this.#storage.getValue();
6957
7214
  const balances = assign({}, storage.balances,
6958
- // delete all balances expected in the result set. because if they are not present it means they are empty.
6959
- fromPairs(balanceIds.map(balanceId => [balanceId, undefined])), keyBy(
7215
+ // delete all balances expected in the result set (except the ones that failed). because if they are not present it means they are empty.
7216
+ fromPairs(balanceIds.filter(bid => !balancesResult.failedBalanceIds.includes(bid)).map(balanceId => [balanceId, undefined])), keyBy(
6960
7217
  // storage balances must have status "cache", because they are used as start value when initialising subsequent subscriptions
6961
7218
  balancesResult.balances.map(b => ({
6962
7219
  ...b,
6963
7220
  status: "cache"
6964
7221
  })), b => getBalanceId(b)));
7222
+
7223
+ // update status of stale balances
7224
+ for (const errorBalanceId of balancesResult.failedBalanceIds) {
7225
+ const balance = balances[errorBalanceId];
7226
+ if (balance) balance.status = "stale";
7227
+ }
6965
7228
  this.#storage.next(assign({}, storage, {
6966
7229
  balances
6967
7230
  }));
@@ -7099,4 +7362,4 @@ const isAddressCompatibleWithNetwork = (network, address) => {
7099
7362
  const sortByBalanceId = (a, b) => getBalanceId(a).localeCompare(getBalanceId(b));
7100
7363
  const sortByMiniMetadataId = (a, b) => a.id.localeCompare(b.id);
7101
7364
 
7102
- export { BALANCE_MODULES, Balance, BalanceFormatter, BalanceValueGetter, Balances, BalancesProvider, Change24hCurrencyFormatter, EvmErc20BalanceModule, EvmErc20TokenConfigSchema, EvmNativeBalanceModule, EvmNativeTokenConfigSchema, EvmUniswapV2BalanceModule, EvmUniswapV2TokenConfigSchema, FiatSumBalancesFormatter, ONE_ALPHA_TOKEN, PlanckSumBalancesFormatter, SCALE_FACTOR, SUBTENSOR_MIN_STAKE_AMOUNT_PLANK, SUBTENSOR_ROOT_NETUID, SolNativeBalanceModule, SolNativeTokenConfigSchema, SolSplBalanceModule, SolSplTokenConfigSchema, SubAssetsBalanceModule, SubAssetsTokenConfigSchema, SubForeignAssetsBalanceModule, SubForeignAssetsTokenConfigSchema, SubHydrationBalanceModule, SubHydrationTokenConfigSchema, SubNativeBalanceModule, SubNativeMiniMetadataExtraSchema, SubNativeModuleConfigSchema, SubNativeTokenConfigSchema, SubPsp22BalanceModule, SubPsp22TokenConfigSchema, SubTokensBalanceModule, SubTokensMiniMetadataExtraSchema, SubTokensModuleConfigSchema, SubTokensTokenConfigSchema, SumBalancesFormatter, abiMulticall, calculateAlphaPrice, calculateTaoAmountFromAlpha, calculateTaoFromDynamicInfo, deriveMiniMetadataId, erc20BalancesAggregatorAbi, excludeFromFeePayableLocks, excludeFromTransferableAmount, filterBaseLocks, filterMirrorTokens, getBalanceId, getLockTitle, getLockedType, getValueId, includeInTotalExtraAmount, uniswapV2PairAbi };
7365
+ export { ALPHA_PRICE_SCALE, BALANCE_MODULES, Balance, BalanceFormatter, BalanceValueGetter, Balances, BalancesProvider, Change24hCurrencyFormatter, EvmErc20BalanceModule, EvmErc20TokenConfigSchema, EvmNativeBalanceModule, EvmNativeTokenConfigSchema, EvmUniswapV2BalanceModule, EvmUniswapV2TokenConfigSchema, FiatSumBalancesFormatter, PlanckSumBalancesFormatter, SolNativeBalanceModule, SolNativeTokenConfigSchema, SolSplBalanceModule, SolSplTokenConfigSchema, SubAssetsBalanceModule, SubAssetsTokenConfigSchema, SubDTaoBalanceModule, SubDTaoTokenConfigSchema, SubForeignAssetsBalanceModule, SubForeignAssetsTokenConfigSchema, SubHydrationBalanceModule, SubHydrationTokenConfigSchema, SubNativeBalanceModule, SubNativeMiniMetadataExtraSchema, SubNativeModuleConfigSchema, SubNativeTokenConfigSchema, SubPsp22BalanceModule, SubPsp22TokenConfigSchema, SubTokensBalanceModule, SubTokensMiniMetadataExtraSchema, SubTokensModuleConfigSchema, SubTokensTokenConfigSchema, SumBalancesFormatter, TAO_DECIMALS, abiMulticall, alphaToTao, deriveMiniMetadataId, erc20BalancesAggregatorAbi, excludeFromFeePayableLocks, excludeFromTransferableAmount, filterBaseLocks, filterMirrorTokens, getBalanceId, getDTaoTokenRates, getLockTitle, getLockedType, getScaledAlphaPrice, getValueId, includeInTotalExtraAmount, taoToAlpha, uniswapV2PairAbi };