@talismn/balances 0.0.0-pr2091-20250721015613 → 0.0.0-pr2091-20250727075918

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
- import { EvmErc20TokenSchema, parseTokenId, parseEvmErc20TokenId, evmErc20TokenId, isTokenOfType, TokenBaseSchema, EvmNativeTokenSchema, evmNativeTokenId, EvmUniswapV2TokenSchema, evmUniswapV2TokenId, SolNativeTokenSchema, solNativeTokenId, 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, MINIMETADATA_VERSION, SubForeignAssetsTokenSchema, subForeignAssetTokenId, SubHydrationTokenSchema, subHydrationTokenId, SubNativeTokenSchema, subNativeTokenId, 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';
@@ -10,6 +10,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
12
  import { parseMetadataRpc, toHex, unifyMetadata, decAnyMetadata, getDynamicBuilder, getLookupFn, decodeScale, getStorageKeyPrefix, Twox128, compactMetadata, encodeMetadata, papiParse, papiStringify } from '@talismn/scale';
13
+ import { deserializeMetadata } from '@metaplex-foundation/mpl-token-metadata';
14
+ import { sol, publicKey } from '@metaplex-foundation/umi';
15
+ import { MintLayout } from '@solana/spl-token';
13
16
  import { newTokenRates } from '@talismn/token-rates';
14
17
  import { mergeUint8 } from '@polkadot-api/utils';
15
18
  import { Binary, Enum, AccountId } from 'polkadot-api';
@@ -21,8 +24,8 @@ import { u8aToHex, u8aConcatStrict, u8aToString, hexToNumber } from '@polkadot/u
21
24
  import PQueue from 'p-queue';
22
25
  import { fetchBestMetadata } from '@talismn/sapi';
23
26
 
24
- const MODULE_TYPE$9 = EvmErc20TokenSchema.shape.type.value;
25
- const PLATFORM$9 = EvmErc20TokenSchema.shape.platform.value;
27
+ const MODULE_TYPE$a = EvmErc20TokenSchema.shape.type.value;
28
+ const PLATFORM$a = EvmErc20TokenSchema.shape.platform.value;
26
29
 
27
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)"]);
28
31
 
@@ -618,7 +621,7 @@ const getBalanceDefs = addressesByToken => {
618
621
  // if there is at least one storage entry, the results will be an array with a single object
619
622
  // if the storage has no entries in it (ex: Assets on ewx or moonbeam), the response will be an empty array
620
623
 
621
- const fetchBalances$9 = async ({
624
+ const fetchBalances$a = async ({
622
625
  networkId,
623
626
  tokensWithAddresses,
624
627
  connector
@@ -630,7 +633,7 @@ const fetchBalances$9 = async ({
630
633
  const client = await connector.getPublicClientForEvmNetwork(networkId);
631
634
  if (!client) throw new Error(`Could not get rpc provider for evm network ${networkId}`);
632
635
  for (const [token, addresses] of tokensWithAddresses) {
633
- 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}`);
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}`);
634
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}`);
635
638
  }
636
639
  const balanceDefs = getBalanceDefs(tokensWithAddresses);
@@ -660,7 +663,7 @@ const fetchWithoutAggregator = async (client, balanceDefs) => {
660
663
  address,
661
664
  tokenId: token.id,
662
665
  value: result.toString(),
663
- source: MODULE_TYPE$9,
666
+ source: MODULE_TYPE$a,
664
667
  networkId: parseEvmErc20TokenId(token.id).networkId,
665
668
  status: "live"
666
669
  };
@@ -703,7 +706,7 @@ const fetchWithAggregator = async (client, balanceDefs, erc20BalancesAggregatorA
703
706
  address: balanceDef.address,
704
707
  tokenId: balanceDef.token.id,
705
708
  value: erc20Balances[index].toString(),
706
- source: MODULE_TYPE$9,
709
+ source: MODULE_TYPE$a,
707
710
  networkId: parseTokenId(balanceDef.token.id).networkId,
708
711
  status: "live"
709
712
  }));
@@ -760,7 +763,7 @@ const getTypedContract$1 = (client, abi, contractAddress) => getContract({
760
763
  }
761
764
  });
762
765
 
763
- const TokenCacheSchema$1 = z.discriminatedUnion("isValid", [z.strictObject({
766
+ const TokenCacheSchema$2 = z.discriminatedUnion("isValid", [z.strictObject({
764
767
  id: EvmErc20TokenSchema.shape.id,
765
768
  isValid: z.literal(true),
766
769
  ...EvmErc20TokenSchema.pick({
@@ -772,7 +775,7 @@ const TokenCacheSchema$1 = z.discriminatedUnion("isValid", [z.strictObject({
772
775
  id: EvmErc20TokenSchema.shape.id,
773
776
  isValid: z.literal(false)
774
777
  })]);
775
- const fetchTokens$9 = async ({
778
+ const fetchTokens$a = async ({
776
779
  networkId,
777
780
  tokens,
778
781
  connector,
@@ -781,7 +784,7 @@ const fetchTokens$9 = async ({
781
784
  const result = [];
782
785
  for (const tokenConfig of tokens) {
783
786
  const tokenId = evmErc20TokenId(networkId, tokenConfig.contractAddress);
784
- const cached = cache[tokenId] && TokenCacheSchema$1.safeParse(cache[tokenId]).data;
787
+ const cached = cache[tokenId] && TokenCacheSchema$2.safeParse(cache[tokenId]).data;
785
788
  if (!cached) {
786
789
  const client = await connector.getPublicClientForEvmNetwork(networkId);
787
790
  if (!client) {
@@ -794,7 +797,7 @@ const fetchTokens$9 = async ({
794
797
  decimals,
795
798
  symbol
796
799
  } = await getErc20ContractData$1(client, tokenConfig.contractAddress);
797
- cache[tokenId] = TokenCacheSchema$1.parse({
800
+ cache[tokenId] = TokenCacheSchema$2.parse({
798
801
  id: tokenId,
799
802
  symbol,
800
803
  decimals,
@@ -812,11 +815,11 @@ const fetchTokens$9 = async ({
812
815
  }
813
816
  const base = {
814
817
  id: tokenId,
815
- type: MODULE_TYPE$9,
816
- platform: PLATFORM$9,
818
+ type: MODULE_TYPE$a,
819
+ platform: PLATFORM$a,
817
820
  networkId
818
821
  };
819
- const cached2 = cache[tokenId] && TokenCacheSchema$1.safeParse(cache[tokenId]).data;
822
+ const cached2 = cache[tokenId] && TokenCacheSchema$2.safeParse(cache[tokenId]).data;
820
823
  if (cached2?.isValid === false) continue;
821
824
  const token = assign(base, cached2?.isValid ? omit(cached2, ["isValid"]) : {}, tokenConfig);
822
825
  const parsed = EvmErc20TokenSchema.safeParse(token);
@@ -831,17 +834,17 @@ const fetchTokens$9 = async ({
831
834
  return result;
832
835
  };
833
836
 
834
- const getMiniMetadata$9 = () => {
837
+ const getMiniMetadata$a = () => {
835
838
  throw new Error("MiniMetadata is not supported for ethereum tokens");
836
839
  };
837
840
 
838
- const getTransferCallData$9 = ({
841
+ const getTransferCallData$a = ({
839
842
  from,
840
843
  to,
841
844
  value,
842
845
  token
843
846
  }) => {
844
- if (!isTokenOfType(token, MODULE_TYPE$9)) throw new Error(`Token type ${token.type} is not ${MODULE_TYPE$9}.`);
847
+ if (!isTokenOfType(token, MODULE_TYPE$a)) throw new Error(`Token type ${token.type} is not ${MODULE_TYPE$a}.`);
845
848
  if (!isEthereumAddress(from)) throw new Error("Invalid from address");
846
849
  if (!isEthereumAddress(to)) throw new Error("Invalid to address");
847
850
  const data = encodeFunctionData({
@@ -856,8 +859,8 @@ const getTransferCallData$9 = ({
856
859
  };
857
860
  };
858
861
 
859
- const SUBSCRIPTION_INTERVAL$5 = 6_000;
860
- const subscribeBalances$9 = ({
862
+ const SUBSCRIPTION_INTERVAL$6 = 6_000;
863
+ const subscribeBalances$a = ({
861
864
  networkId,
862
865
  tokensWithAddresses,
863
866
  connector
@@ -871,17 +874,17 @@ const subscribeBalances$9 = ({
871
874
  const poll = async () => {
872
875
  try {
873
876
  if (abortController.signal.aborted) return;
874
- const balances = await fetchBalances$9({
877
+ const balances = await fetchBalances$a({
875
878
  networkId,
876
879
  tokensWithAddresses: tokensWithAddresses,
877
880
  connector
878
881
  });
879
882
  if (abortController.signal.aborted) return;
880
883
  subscriber.next(balances);
881
- setTimeout(poll, SUBSCRIPTION_INTERVAL$5);
884
+ setTimeout(poll, SUBSCRIPTION_INTERVAL$6);
882
885
  } catch (error) {
883
886
  log.error("Error", {
884
- module: MODULE_TYPE$9,
887
+ module: MODULE_TYPE$a,
885
888
  networkId,
886
889
  addressesByToken: tokensWithAddresses,
887
890
  error
@@ -897,13 +900,13 @@ const subscribeBalances$9 = ({
897
900
  };
898
901
 
899
902
  const EvmErc20BalanceModule = {
900
- type: MODULE_TYPE$9,
901
- platform: PLATFORM$9,
902
- getMiniMetadata: getMiniMetadata$9,
903
- fetchTokens: fetchTokens$9,
904
- fetchBalances: fetchBalances$9,
905
- subscribeBalances: subscribeBalances$9,
906
- getTransferCallData: getTransferCallData$9
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
907
910
  };
908
911
 
909
912
  const TokenConfigBaseSchema = TokenBaseSchema.partial().omit({
@@ -916,10 +919,10 @@ const EvmErc20TokenConfigSchema = z.strictObject({
916
919
  ...TokenConfigBaseSchema.shape
917
920
  });
918
921
 
919
- const MODULE_TYPE$8 = EvmNativeTokenSchema.shape.type.value;
920
- const PLATFORM$8 = EvmNativeTokenSchema.shape.platform.value;
922
+ const MODULE_TYPE$9 = EvmNativeTokenSchema.shape.type.value;
923
+ const PLATFORM$9 = EvmNativeTokenSchema.shape.platform.value;
921
924
 
922
- const fetchBalances$8 = async ({
925
+ const fetchBalances$9 = async ({
923
926
  networkId,
924
927
  tokensWithAddresses,
925
928
  connector
@@ -931,7 +934,7 @@ const fetchBalances$8 = async ({
931
934
  const client = await connector.getPublicClientForEvmNetwork(networkId);
932
935
  if (!client) throw new Error(`Could not get rpc provider for evm network ${networkId}`);
933
936
  for (const [token, addresses] of tokensWithAddresses) {
934
- 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}`);
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}`);
935
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}`);
936
939
  }
937
940
  const balanceDefs = getBalanceDefs(tokensWithAddresses);
@@ -958,7 +961,7 @@ const fetchWithoutMulticall = async (client, balanceDefs) => {
958
961
  address,
959
962
  tokenId: token.id,
960
963
  value: result.toString(),
961
- source: MODULE_TYPE$8,
964
+ source: MODULE_TYPE$9,
962
965
  networkId: parseTokenId(token.id).networkId,
963
966
  status: "live"
964
967
  };
@@ -1004,7 +1007,7 @@ const fetchWithMulticall = async (client, balanceDefs, multicall3Address) => {
1004
1007
  address: balanceDefs[index].address,
1005
1008
  tokenId: balanceDefs[index].token.id,
1006
1009
  value: result.result.toString(),
1007
- source: MODULE_TYPE$8,
1010
+ source: MODULE_TYPE$9,
1008
1011
  networkId: parseTokenId(balanceDefs[index].token.id).networkId,
1009
1012
  status: "live"
1010
1013
  });
@@ -1034,7 +1037,7 @@ const fetchWithMulticall = async (client, balanceDefs, multicall3Address) => {
1034
1037
  }
1035
1038
  };
1036
1039
 
1037
- const fetchTokens$8 = async ({
1040
+ const fetchTokens$9 = async ({
1038
1041
  networkId,
1039
1042
  tokens
1040
1043
  }) => {
@@ -1042,8 +1045,8 @@ const fetchTokens$8 = async ({
1042
1045
  if (tokens.length !== 1) throw new Error("EVM Native module expects the nativeCurrency to be passed as a single token in the array");
1043
1046
  const token = assign({
1044
1047
  id: evmNativeTokenId(networkId),
1045
- type: MODULE_TYPE$8,
1046
- platform: PLATFORM$8,
1048
+ type: MODULE_TYPE$9,
1049
+ platform: PLATFORM$9,
1047
1050
  networkId,
1048
1051
  isDefault: true
1049
1052
  }, tokens[0]);
@@ -1055,17 +1058,17 @@ const fetchTokens$8 = async ({
1055
1058
  return [parsed.data];
1056
1059
  };
1057
1060
 
1058
- const getMiniMetadata$8 = () => {
1061
+ const getMiniMetadata$9 = () => {
1059
1062
  throw new Error("MiniMetadata is not supported for ethereum tokens");
1060
1063
  };
1061
1064
 
1062
- const getTransferCallData$8 = ({
1065
+ const getTransferCallData$9 = ({
1063
1066
  from,
1064
1067
  to,
1065
1068
  value,
1066
1069
  token
1067
1070
  }) => {
1068
- if (!isTokenOfType(token, MODULE_TYPE$8)) throw new Error(`Token type ${token.type} is not ${MODULE_TYPE$8}.`);
1071
+ if (!isTokenOfType(token, MODULE_TYPE$9)) throw new Error(`Token type ${token.type} is not ${MODULE_TYPE$9}.`);
1069
1072
  if (!isEthereumAddress(from)) throw new Error("Invalid from address");
1070
1073
  if (!isEthereumAddress(to)) throw new Error("Invalid to address");
1071
1074
  return {
@@ -1076,8 +1079,8 @@ const getTransferCallData$8 = ({
1076
1079
  };
1077
1080
  };
1078
1081
 
1079
- const SUBSCRIPTION_INTERVAL$4 = 6_000;
1080
- const subscribeBalances$8 = ({
1082
+ const SUBSCRIPTION_INTERVAL$5 = 6_000;
1083
+ const subscribeBalances$9 = ({
1081
1084
  networkId,
1082
1085
  tokensWithAddresses,
1083
1086
  connector
@@ -1091,17 +1094,17 @@ const subscribeBalances$8 = ({
1091
1094
  const poll = async () => {
1092
1095
  try {
1093
1096
  if (abortController.signal.aborted) return;
1094
- const balances = await fetchBalances$8({
1097
+ const balances = await fetchBalances$9({
1095
1098
  networkId,
1096
1099
  tokensWithAddresses: tokensWithAddresses,
1097
1100
  connector
1098
1101
  });
1099
1102
  if (abortController.signal.aborted) return;
1100
1103
  subscriber.next(balances);
1101
- setTimeout(poll, SUBSCRIPTION_INTERVAL$4);
1104
+ setTimeout(poll, SUBSCRIPTION_INTERVAL$5);
1102
1105
  } catch (error) {
1103
1106
  log.error("Error", {
1104
- module: MODULE_TYPE$8,
1107
+ module: MODULE_TYPE$9,
1105
1108
  networkId,
1106
1109
  addressesByToken: tokensWithAddresses,
1107
1110
  error
@@ -1117,13 +1120,13 @@ const subscribeBalances$8 = ({
1117
1120
  };
1118
1121
 
1119
1122
  const EvmNativeBalanceModule = {
1120
- type: MODULE_TYPE$8,
1121
- platform: PLATFORM$8,
1122
- getMiniMetadata: getMiniMetadata$8,
1123
- fetchTokens: fetchTokens$8,
1124
- fetchBalances: fetchBalances$8,
1125
- subscribeBalances: subscribeBalances$8,
1126
- getTransferCallData: getTransferCallData$8
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
1127
1130
  };
1128
1131
 
1129
1132
  // to be used by chaindata too
@@ -1131,10 +1134,10 @@ const EvmNativeTokenConfigSchema = z.strictObject({
1131
1134
  ...TokenConfigBaseSchema.shape
1132
1135
  });
1133
1136
 
1134
- const MODULE_TYPE$7 = EvmUniswapV2TokenSchema.shape.type.value;
1135
- const PLATFORM$7 = EvmUniswapV2TokenSchema.shape.platform.value;
1137
+ const MODULE_TYPE$8 = EvmUniswapV2TokenSchema.shape.type.value;
1138
+ const PLATFORM$8 = EvmUniswapV2TokenSchema.shape.platform.value;
1136
1139
 
1137
- const fetchBalances$7 = async ({
1140
+ const fetchBalances$8 = async ({
1138
1141
  networkId,
1139
1142
  tokensWithAddresses,
1140
1143
  connector
@@ -1146,7 +1149,7 @@ const fetchBalances$7 = async ({
1146
1149
  const client = await connector.getPublicClientForEvmNetwork(networkId);
1147
1150
  if (!client) throw new Error(`Could not get rpc provider for evm network ${networkId}`);
1148
1151
  for (const [token, addresses] of tokensWithAddresses) {
1149
- if (token.type !== MODULE_TYPE$7 || token.networkId !== networkId) throw new Error(`Invalid token type or networkId for EVM ERC20 balance module: ${token.type} on ${token.networkId}`);
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}`);
1150
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}`);
1151
1154
  }
1152
1155
  const balanceDefs = getBalanceDefs(tokensWithAddresses);
@@ -1233,7 +1236,7 @@ const fetchPoolBalances = async (client, balanceDefs) => {
1233
1236
  acc.success.push({
1234
1237
  address,
1235
1238
  tokenId: token.id,
1236
- source: MODULE_TYPE$7,
1239
+ source: MODULE_TYPE$8,
1237
1240
  networkId: parseTokenId(token.id).networkId,
1238
1241
  status: "live",
1239
1242
  values: [{
@@ -1293,7 +1296,7 @@ const getUniswapV2PairContractData = async (client, contractAddress) => {
1293
1296
  };
1294
1297
  };
1295
1298
 
1296
- const TokenCacheSchema = z.discriminatedUnion("isValid", [z.strictObject({
1299
+ const TokenCacheSchema$1 = z.discriminatedUnion("isValid", [z.strictObject({
1297
1300
  id: EvmUniswapV2TokenSchema.shape.id,
1298
1301
  isValid: z.literal(true),
1299
1302
  ...EvmUniswapV2TokenSchema.pick({
@@ -1311,7 +1314,7 @@ const TokenCacheSchema = z.discriminatedUnion("isValid", [z.strictObject({
1311
1314
  id: EvmUniswapV2TokenSchema.shape.id,
1312
1315
  isValid: z.literal(false)
1313
1316
  })]);
1314
- const fetchTokens$7 = async ({
1317
+ const fetchTokens$8 = async ({
1315
1318
  networkId,
1316
1319
  tokens,
1317
1320
  connector,
@@ -1320,7 +1323,7 @@ const fetchTokens$7 = async ({
1320
1323
  const result = [];
1321
1324
  for (const tokenConfig of tokens) {
1322
1325
  const tokenId = evmUniswapV2TokenId(networkId, tokenConfig.contractAddress);
1323
- const cached = cache[tokenId] && TokenCacheSchema.safeParse(cache[tokenId]).data;
1326
+ const cached = cache[tokenId] && TokenCacheSchema$1.safeParse(cache[tokenId]).data;
1324
1327
  if (!cached) {
1325
1328
  const client = await connector.getPublicClientForEvmNetwork(networkId);
1326
1329
  if (!client) {
@@ -1342,7 +1345,7 @@ const fetchTokens$7 = async ({
1342
1345
  symbol: symbol1,
1343
1346
  decimals: decimals1
1344
1347
  } = await getErc20ContractData(client, token1);
1345
- cache[tokenId] = TokenCacheSchema.parse({
1348
+ cache[tokenId] = TokenCacheSchema$1.parse({
1346
1349
  id: tokenId,
1347
1350
  symbol: `${symbol0}/${symbol1}`,
1348
1351
  decimals,
@@ -1370,11 +1373,11 @@ const fetchTokens$7 = async ({
1370
1373
  }
1371
1374
  const base = {
1372
1375
  id: tokenId,
1373
- type: MODULE_TYPE$7,
1374
- platform: PLATFORM$7,
1376
+ type: MODULE_TYPE$8,
1377
+ platform: PLATFORM$8,
1375
1378
  networkId
1376
1379
  };
1377
- const cached2 = cache[tokenId] && TokenCacheSchema.safeParse(cache[tokenId]).data;
1380
+ const cached2 = cache[tokenId] && TokenCacheSchema$1.safeParse(cache[tokenId]).data;
1378
1381
  if (cached2?.isValid === false) continue;
1379
1382
  const token = assign(base, cached2?.isValid ? omit(cached2, ["isValid"]) : {}, tokenConfig);
1380
1383
  const parsed = EvmUniswapV2TokenSchema.safeParse(token);
@@ -1387,17 +1390,17 @@ const fetchTokens$7 = async ({
1387
1390
  return result;
1388
1391
  };
1389
1392
 
1390
- const getMiniMetadata$7 = () => {
1393
+ const getMiniMetadata$8 = () => {
1391
1394
  throw new Error("MiniMetadata is not supported for ethereum tokens");
1392
1395
  };
1393
1396
 
1394
- const getTransferCallData$7 = ({
1397
+ const getTransferCallData$8 = ({
1395
1398
  from,
1396
1399
  to,
1397
1400
  value,
1398
1401
  token
1399
1402
  }) => {
1400
- if (!isTokenOfType(token, MODULE_TYPE$7)) throw new Error(`Token type ${token.type} is not ${MODULE_TYPE$7}.`);
1403
+ if (!isTokenOfType(token, MODULE_TYPE$8)) throw new Error(`Token type ${token.type} is not ${MODULE_TYPE$8}.`);
1401
1404
  if (!isEthereumAddress(from)) throw new Error("Invalid from address");
1402
1405
  if (!isEthereumAddress(to)) throw new Error("Invalid to address");
1403
1406
  const data = encodeFunctionData({
@@ -1412,8 +1415,8 @@ const getTransferCallData$7 = ({
1412
1415
  };
1413
1416
  };
1414
1417
 
1415
- const SUBSCRIPTION_INTERVAL$3 = 6_000;
1416
- const subscribeBalances$7 = ({
1418
+ const SUBSCRIPTION_INTERVAL$4 = 6_000;
1419
+ const subscribeBalances$8 = ({
1417
1420
  networkId,
1418
1421
  tokensWithAddresses,
1419
1422
  connector
@@ -1427,17 +1430,17 @@ const subscribeBalances$7 = ({
1427
1430
  const poll = async () => {
1428
1431
  try {
1429
1432
  if (abortController.signal.aborted) return;
1430
- const balances = await fetchBalances$7({
1433
+ const balances = await fetchBalances$8({
1431
1434
  networkId,
1432
1435
  tokensWithAddresses: tokensWithAddresses,
1433
1436
  connector
1434
1437
  });
1435
1438
  if (abortController.signal.aborted) return;
1436
1439
  subscriber.next(balances);
1437
- setTimeout(poll, SUBSCRIPTION_INTERVAL$3);
1440
+ setTimeout(poll, SUBSCRIPTION_INTERVAL$4);
1438
1441
  } catch (error) {
1439
1442
  log.error("Error", {
1440
- module: MODULE_TYPE$7,
1443
+ module: MODULE_TYPE$8,
1441
1444
  networkId,
1442
1445
  addressesByToken: tokensWithAddresses,
1443
1446
  error
@@ -1453,13 +1456,13 @@ const subscribeBalances$7 = ({
1453
1456
  };
1454
1457
 
1455
1458
  const EvmUniswapV2BalanceModule = {
1456
- type: MODULE_TYPE$7,
1457
- platform: PLATFORM$7,
1458
- getMiniMetadata: getMiniMetadata$7,
1459
- fetchTokens: fetchTokens$7,
1460
- fetchBalances: fetchBalances$7,
1461
- subscribeBalances: subscribeBalances$7,
1462
- getTransferCallData: getTransferCallData$7
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
1463
1466
  };
1464
1467
 
1465
1468
  // to be used by chaindata too
@@ -1468,10 +1471,10 @@ const EvmUniswapV2TokenConfigSchema = z.strictObject({
1468
1471
  ...TokenConfigBaseSchema.shape
1469
1472
  });
1470
1473
 
1471
- const MODULE_TYPE$6 = SolNativeTokenSchema.shape.type.value;
1472
- const PLATFORM$6 = SolNativeTokenSchema.shape.platform.value;
1474
+ const MODULE_TYPE$7 = SolNativeTokenSchema.shape.type.value;
1475
+ const PLATFORM$7 = SolNativeTokenSchema.shape.platform.value;
1473
1476
 
1474
- const fetchBalances$6 = async ({
1477
+ const fetchBalances$7 = async ({
1475
1478
  networkId,
1476
1479
  tokensWithAddresses,
1477
1480
  connector
@@ -1483,7 +1486,7 @@ const fetchBalances$6 = async ({
1483
1486
  const connection = await connector.getConnection(networkId);
1484
1487
  if (!connection) throw new Error(`Could not get rpc provider for sol network ${networkId}`);
1485
1488
  for (const [token, addresses] of tokensWithAddresses) {
1486
- if (token.type !== MODULE_TYPE$6 || 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$7 || token.networkId !== networkId) throw new Error(`Invalid token type or networkId for balance module: ${token.type} on ${token.networkId}`);
1487
1490
  for (const address of addresses) if (!isSolanaAddress(address)) throw new Error(`Invalid solana address for balance module: ${address} for token ${token.id}`);
1488
1491
  }
1489
1492
  const balanceDefs = getBalanceDefs(tokensWithAddresses);
@@ -1498,7 +1501,7 @@ const fetchBalances$6 = async ({
1498
1501
  address: address,
1499
1502
  tokenId: token.id,
1500
1503
  value: lamports.toString(),
1501
- source: MODULE_TYPE$6,
1504
+ source: MODULE_TYPE$7,
1502
1505
  networkId: token.networkId,
1503
1506
  status: "live"
1504
1507
  };
@@ -1522,7 +1525,7 @@ const fetchBalances$6 = async ({
1522
1525
  });
1523
1526
  };
1524
1527
 
1525
- const fetchTokens$6 = async ({
1528
+ const fetchTokens$7 = async ({
1526
1529
  networkId,
1527
1530
  tokens
1528
1531
  }) => {
@@ -1530,8 +1533,8 @@ const fetchTokens$6 = async ({
1530
1533
  if (tokens.length !== 1) throw new Error("EVM Native module expects the nativeCurrency to be passed as a single token in the array");
1531
1534
  const token = assign({
1532
1535
  id: solNativeTokenId(networkId),
1533
- type: MODULE_TYPE$6,
1534
- platform: PLATFORM$6,
1536
+ type: MODULE_TYPE$7,
1537
+ platform: PLATFORM$7,
1535
1538
  networkId,
1536
1539
  isDefault: true
1537
1540
  }, tokens[0]);
@@ -1543,17 +1546,17 @@ const fetchTokens$6 = async ({
1543
1546
  return [parsed.data];
1544
1547
  };
1545
1548
 
1546
- const getMiniMetadata$6 = () => {
1549
+ const getMiniMetadata$7 = () => {
1547
1550
  throw new Error("MiniMetadata is not supported for sol-native tokens");
1548
1551
  };
1549
1552
 
1550
- const getTransferCallData$6 = ({
1553
+ const getTransferCallData$7 = ({
1551
1554
  from,
1552
1555
  to,
1553
1556
  value,
1554
1557
  token
1555
1558
  }) => {
1556
- if (!isTokenOfType(token, MODULE_TYPE$6)) throw new Error(`Token type ${token.type} is not ${MODULE_TYPE$6}.`);
1559
+ if (!isTokenOfType(token, MODULE_TYPE$7)) throw new Error(`Token type ${token.type} is not ${MODULE_TYPE$7}.`);
1557
1560
  const fromPubkey = new PublicKey(from);
1558
1561
  const transferIx = SystemProgram.transfer({
1559
1562
  fromPubkey,
@@ -1563,8 +1566,8 @@ const getTransferCallData$6 = ({
1563
1566
  return transferIx;
1564
1567
  };
1565
1568
 
1566
- const SUBSCRIPTION_INTERVAL$2 = 6_000;
1567
- const subscribeBalances$6 = ({
1569
+ const SUBSCRIPTION_INTERVAL$3 = 6_000;
1570
+ const subscribeBalances$7 = ({
1568
1571
  networkId,
1569
1572
  tokensWithAddresses,
1570
1573
  connector
@@ -1578,17 +1581,17 @@ const subscribeBalances$6 = ({
1578
1581
  const poll = async () => {
1579
1582
  try {
1580
1583
  if (abortController.signal.aborted) return;
1581
- const balances = await fetchBalances$6({
1584
+ const balances = await fetchBalances$7({
1582
1585
  networkId,
1583
1586
  tokensWithAddresses,
1584
1587
  connector
1585
1588
  });
1586
1589
  if (abortController.signal.aborted) return;
1587
1590
  subscriber.next(balances);
1588
- setTimeout(poll, SUBSCRIPTION_INTERVAL$2);
1591
+ setTimeout(poll, SUBSCRIPTION_INTERVAL$3);
1589
1592
  } catch (error) {
1590
1593
  log.error("Error", {
1591
- module: MODULE_TYPE$6,
1594
+ module: MODULE_TYPE$7,
1592
1595
  networkId,
1593
1596
  tokensWithAddresses,
1594
1597
  error
@@ -1604,13 +1607,13 @@ const subscribeBalances$6 = ({
1604
1607
  };
1605
1608
 
1606
1609
  const SolNativeBalanceModule = {
1607
- type: MODULE_TYPE$6,
1608
- platform: PLATFORM$6,
1609
- getMiniMetadata: getMiniMetadata$6,
1610
- fetchTokens: fetchTokens$6,
1611
- fetchBalances: fetchBalances$6,
1612
- subscribeBalances: subscribeBalances$6,
1613
- getTransferCallData: getTransferCallData$6
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
1614
1617
  };
1615
1618
 
1616
1619
  // to be used by chaindata too
@@ -1618,8 +1621,61 @@ const SolNativeTokenConfigSchema = z.strictObject({
1618
1621
  ...TokenConfigBaseSchema.shape
1619
1622
  });
1620
1623
 
1621
- const MODULE_TYPE$5 = SubAssetsTokenSchema.shape.type.value;
1622
- const PLATFORM$5 = SubAssetsTokenSchema.shape.platform.value;
1624
+ const MODULE_TYPE$6 = SolSplTokenSchema.shape.type.value;
1625
+ const PLATFORM$6 = SolSplTokenSchema.shape.platform.value;
1626
+
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);
1634
+ };
1635
+
1636
+ const hasStorageItem = (metadata, palletName, itemName) => {
1637
+ const pallet = metadata.pallets.find(p => p.name === palletName);
1638
+ if (!pallet || !pallet.storage) return false;
1639
+ return pallet.storage.items.some(item => item.name === itemName);
1640
+ };
1641
+ const hasStorageItems = (metadata, palletName, itemNames) => {
1642
+ const pallet = metadata.pallets.find(p => p.name === palletName);
1643
+ if (!pallet || !pallet.storage) return false;
1644
+ return itemNames.every(itemName => pallet.storage?.items.some(item => item.name === itemName));
1645
+ };
1646
+ const hasRuntimeApi = (metadata, apiName, method) => {
1647
+ const api = metadata.apis.find(api => api.name === apiName);
1648
+ if (!api || !api.methods) return false;
1649
+ return api.methods.some(m => m.name === method);
1650
+ };
1651
+ const getConstantValue = (metadataRpc, pallet, constant) => {
1652
+ const {
1653
+ unifiedMetadata,
1654
+ builder
1655
+ } = parseMetadataRpc(metadataRpc);
1656
+ const codec = builder.buildConstant(pallet, constant);
1657
+ const encodedValue = unifiedMetadata.pallets.find(({
1658
+ name
1659
+ }) => name === pallet)?.constants.find(({
1660
+ name
1661
+ }) => name === constant)?.value;
1662
+ if (!encodedValue) throw new Error(`Constant ${pallet}.${constant} not found`);
1663
+ return codec.dec(encodedValue);
1664
+ };
1665
+ const tryGetConstantValue = (metadataRpc, pallet, constant) => {
1666
+ const {
1667
+ unifiedMetadata,
1668
+ builder
1669
+ } = parseMetadataRpc(metadataRpc);
1670
+ const encodedValue = unifiedMetadata.pallets.find(({
1671
+ name
1672
+ }) => name === pallet)?.constants.find(({
1673
+ name
1674
+ }) => name === constant)?.value;
1675
+ if (!encodedValue) return null;
1676
+ const codec = builder.buildConstant(pallet, constant);
1677
+ return codec.dec(encodedValue);
1678
+ };
1623
1679
 
1624
1680
  const fetchRpcQueryPack = async (connector, networkId, queries) => {
1625
1681
  const allStateKeys = queries.flatMap(({
@@ -1684,59 +1740,6 @@ const decodeRpcQueryPack = (queries, result) => {
1684
1740
  }, []);
1685
1741
  };
1686
1742
 
1687
- const fetchRuntimeCallResult = async (connector, networkId, metadataRpc, apiName, method, args) => {
1688
- const {
1689
- builder
1690
- } = parseMetadataRpc(metadataRpc);
1691
- const call = builder.buildRuntimeCall(apiName, method);
1692
- const hex = await connector.send(networkId, "state_call", [`${apiName}_${method}`, toHex(call.args.enc(args))]);
1693
- return call.value.dec(hex);
1694
- };
1695
-
1696
- const hasStorageItem = (metadata, palletName, itemName) => {
1697
- const pallet = metadata.pallets.find(p => p.name === palletName);
1698
- if (!pallet || !pallet.storage) return false;
1699
- return pallet.storage.items.some(item => item.name === itemName);
1700
- };
1701
- const hasStorageItems = (metadata, palletName, itemNames) => {
1702
- const pallet = metadata.pallets.find(p => p.name === palletName);
1703
- if (!pallet || !pallet.storage) return false;
1704
- return itemNames.every(itemName => pallet.storage?.items.some(item => item.name === itemName));
1705
- };
1706
- const hasRuntimeApi = (metadata, apiName, method) => {
1707
- const api = metadata.apis.find(api => api.name === apiName);
1708
- if (!api || !api.methods) return false;
1709
- return api.methods.some(m => m.name === method);
1710
- };
1711
- const getConstantValue = (metadataRpc, pallet, constant) => {
1712
- const {
1713
- unifiedMetadata,
1714
- builder
1715
- } = parseMetadataRpc(metadataRpc);
1716
- const codec = builder.buildConstant(pallet, constant);
1717
- const encodedValue = unifiedMetadata.pallets.find(({
1718
- name
1719
- }) => name === pallet)?.constants.find(({
1720
- name
1721
- }) => name === constant)?.value;
1722
- if (!encodedValue) throw new Error(`Constant ${pallet}.${constant} not found`);
1723
- return codec.dec(encodedValue);
1724
- };
1725
- const tryGetConstantValue = (metadataRpc, pallet, constant) => {
1726
- const {
1727
- unifiedMetadata,
1728
- builder
1729
- } = parseMetadataRpc(metadataRpc);
1730
- const encodedValue = unifiedMetadata.pallets.find(({
1731
- name
1732
- }) => name === pallet)?.constants.find(({
1733
- name
1734
- }) => name === constant)?.value;
1735
- if (!encodedValue) return null;
1736
- const codec = builder.buildConstant(pallet, constant);
1737
- return codec.dec(encodedValue);
1738
- };
1739
-
1740
1743
  const buildNetworkStorageCoders = (chainId, miniMetadata, coders) => {
1741
1744
  if (!miniMetadata.data) return null;
1742
1745
  const metadata = unifyMetadata(decAnyMetadata(miniMetadata.data));
@@ -1760,6 +1763,258 @@ const buildNetworkStorageCoders = (chainId, miniMetadata, coders) => {
1760
1763
  return null;
1761
1764
  };
1762
1765
 
1766
+ const fetchBalances$6 = async ({
1767
+ networkId,
1768
+ tokensWithAddresses,
1769
+ connector
1770
+ }) => {
1771
+ if (!tokensWithAddresses.length) return {
1772
+ success: [],
1773
+ errors: []
1774
+ };
1775
+ const connection = await connector.getConnection(networkId);
1776
+ if (!connection) throw new Error(`Could not get connection for Solana network ${networkId}`);
1777
+
1778
+ // fetch balances for each address and output the ones for which we have a token
1779
+
1780
+ const accountAddresses = uniq(tokensWithAddresses.flatMap(([, addresses]) => addresses));
1781
+
1782
+ // TODO look for a way to fetch balances for all accounts in one request
1783
+ // hint: connection.getProgramAccounts
1784
+
1785
+ const balancesPerAddress = await Promise.all(accountAddresses.map(async address => {
1786
+ const tokenAccounts = await connection.getParsedTokenAccountsByOwner(new PublicKey(address), {
1787
+ programId: new PublicKey("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA") // SPL Token Program ID
1788
+ });
1789
+ const balances = tokenAccounts.value.map(d => {
1790
+ try {
1791
+ const mintAddress = d.account.data.parsed.info.mint;
1792
+ const value = d.account.data.parsed.info.tokenAmount.amount ?? "0";
1793
+ return {
1794
+ tokenId: solSplTokenId(networkId, mintAddress),
1795
+ networkId,
1796
+ address,
1797
+ source: MODULE_TYPE$6,
1798
+ status: "live",
1799
+ value
1800
+ };
1801
+ } catch (err) {
1802
+ log.warn("Failed to parse token amount", {
1803
+ address,
1804
+ d
1805
+ });
1806
+ return null;
1807
+ }
1808
+ }).filter(isNotNil);
1809
+ return [address, balances];
1810
+ }));
1811
+ const allBalancesByKey = keyBy(balancesPerAddress.flatMap(([, addressBalances]) => addressBalances), b => getBalanceKey(b.tokenId, b.address));
1812
+ const balanceDefs = getBalanceDefs(tokensWithAddresses);
1813
+
1814
+ // return a balance entry for all token/address pairs that were requested
1815
+ const success = balanceDefs.map(bd => {
1816
+ const found = allBalancesByKey[getBalanceKey(bd.token.id, bd.address)];
1817
+ return found ?? {
1818
+ tokenId: bd.token.id,
1819
+ networkId: bd.token.networkId,
1820
+ address: bd.address,
1821
+ source: MODULE_TYPE$6,
1822
+ status: "live",
1823
+ value: "0"
1824
+ };
1825
+ });
1826
+
1827
+ // return only the balances that match the tokens we are interested in
1828
+ return {
1829
+ success,
1830
+ errors: []
1831
+ }; // TODO output errors if any
1832
+ };
1833
+ const getBalanceKey = (tokenId, address) => `${tokenId}:${address}`;
1834
+
1835
+ const TokenCacheSchema = z.discriminatedUnion("isValid", [z.strictObject({
1836
+ id: SolSplTokenSchema.shape.id,
1837
+ isValid: z.literal(true),
1838
+ ...SolSplTokenSchema.pick({
1839
+ symbol: true,
1840
+ decimals: true,
1841
+ name: true,
1842
+ logo: true
1843
+ }).shape
1844
+ }), z.strictObject({
1845
+ id: SolSplTokenSchema.shape.id,
1846
+ isValid: z.literal(false)
1847
+ })]);
1848
+ const METAPLEX_PROGRAM_ID = new PublicKey("metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s");
1849
+ const fetchTokens$6 = async ({
1850
+ networkId,
1851
+ tokens,
1852
+ connector,
1853
+ cache
1854
+ }) => {
1855
+ const result = [];
1856
+ for (const tokenConfig of tokens) {
1857
+ const tokenId = solSplTokenId(networkId, tokenConfig.mintAddress);
1858
+ let cached = cache[tokenId] && TokenCacheSchema.safeParse(cache[tokenId]).data;
1859
+ if (!cached) {
1860
+ const tokenInfo = await fetchOnChainTokenData(connector, tokenId);
1861
+ if (tokenInfo) cache[tokenId] = tokenInfo;
1862
+ }
1863
+ cached = cache[tokenId] && TokenCacheSchema.safeParse(cache[tokenId]).data;
1864
+ if (cached?.isValid === false) continue;
1865
+ const base = {
1866
+ id: tokenId,
1867
+ type: MODULE_TYPE$6,
1868
+ platform: PLATFORM$6,
1869
+ networkId
1870
+ };
1871
+ const token = assign(base, cached?.isValid ? omit(cached, ["isValid"]) : {}, tokenConfig);
1872
+ const parsed = SolSplTokenSchema.safeParse(token);
1873
+ if (!parsed.success) {
1874
+ log.warn("Ignoring token with invalid SolSplTokenSchema", {
1875
+ token
1876
+ });
1877
+ continue;
1878
+ }
1879
+ result.push(parsed.data);
1880
+ }
1881
+ return result;
1882
+ };
1883
+ const ERROR_NO_MINT = "No mint info available";
1884
+ const ERROR_NO_METADATA = "No metadata account found ";
1885
+ const fetchOnChainTokenData = async (connector, tokenId) => {
1886
+ try {
1887
+ const {
1888
+ networkId,
1889
+ mintAddress
1890
+ } = parseSolSplTokenId(tokenId);
1891
+ const connection = await connector.getConnection(networkId);
1892
+ if (!connection) {
1893
+ log.warn(`No connection found for network ${networkId}`);
1894
+ return null;
1895
+ }
1896
+ const mintPubKey = new PublicKey(mintAddress);
1897
+ const mintInfo = await connection.getAccountInfo(mintPubKey); // connection.getParsedAccountInfo(mint)
1898
+ if (!mintInfo?.data) throw new Error(ERROR_NO_MINT);
1899
+ const mint = MintLayout.decode(mintInfo.data);
1900
+ const [metadataPDA] = PublicKey.findProgramAddressSync([Buffer.from("metadata"), METAPLEX_PROGRAM_ID.toBuffer(), mintPubKey.toBuffer()], METAPLEX_PROGRAM_ID);
1901
+
1902
+ // 3. Fetch metadata account directly (traditional way)
1903
+ const metadataAccount = await connection.getAccountInfo(new PublicKey(metadataPDA));
1904
+ if (!metadataAccount) throw new Error(ERROR_NO_METADATA);
1905
+ const metadata = deserializeMetadata({
1906
+ publicKey: publicKey(metadataPDA),
1907
+ executable: metadataAccount.executable,
1908
+ owner: publicKey(metadataAccount.owner),
1909
+ lamports: sol(metadataAccount.lamports),
1910
+ data: metadataAccount.data
1911
+ });
1912
+ return TokenCacheSchema.parse({
1913
+ id: tokenId,
1914
+ symbol: metadata.symbol.trim(),
1915
+ name: metadata.name.trim(),
1916
+ decimals: mint.decimals,
1917
+ isValid: true
1918
+ });
1919
+ } catch (err) {
1920
+ const msg = err.message;
1921
+ if ([ERROR_NO_MINT, ERROR_NO_METADATA].includes(msg)) return TokenCacheSchema.parse({
1922
+ id: tokenId,
1923
+ isValid: false
1924
+ });
1925
+ log.warn("Failed to fetch sol-spl token data for %s", tokenId, {
1926
+ err
1927
+ });
1928
+ }
1929
+ return null;
1930
+ };
1931
+
1932
+ const getMiniMetadata$6 = () => {
1933
+ throw new Error("MiniMetadata is not supported for solana tokens");
1934
+ };
1935
+
1936
+ const getTransferCallData$6 = () =>
1937
+ // {
1938
+ // from,
1939
+ // to,
1940
+ // value,
1941
+ // token,
1942
+ // }
1943
+ {
1944
+ throw new Error("Not implemented");
1945
+ // if (!isTokenOfType(token, MODULE_TYPE))
1946
+ // throw new Error(`Token type ${token.type} is not ${MODULE_TYPE}.`)
1947
+ // if (!isEthereumAddress(from)) throw new Error("Invalid from address")
1948
+ // if (!isEthereumAddress(to)) throw new Error("Invalid to address")
1949
+
1950
+ // const data = encodeFunctionData({
1951
+ // abi: erc20Abi,
1952
+ // functionName: "transfer",
1953
+ // args: [to, BigInt(value)],
1954
+ // })
1955
+
1956
+ // return { from, to: token.contractAddress, data }
1957
+ };
1958
+
1959
+ const SUBSCRIPTION_INTERVAL$2 = 6_000;
1960
+ const subscribeBalances$6 = ({
1961
+ networkId,
1962
+ tokensWithAddresses,
1963
+ connector
1964
+ }) => {
1965
+ if (!tokensWithAddresses.length) return of({
1966
+ success: [],
1967
+ errors: []
1968
+ });
1969
+ return new Observable(subscriber => {
1970
+ const abortController = new AbortController();
1971
+ const poll = async () => {
1972
+ try {
1973
+ if (abortController.signal.aborted) return;
1974
+ const balances = await fetchBalances$6({
1975
+ networkId,
1976
+ tokensWithAddresses: tokensWithAddresses,
1977
+ connector
1978
+ });
1979
+ if (abortController.signal.aborted) return;
1980
+ subscriber.next(balances);
1981
+ setTimeout(poll, SUBSCRIPTION_INTERVAL$2);
1982
+ } catch (error) {
1983
+ log.error("Error", {
1984
+ module: MODULE_TYPE$6,
1985
+ networkId,
1986
+ addressesByToken: tokensWithAddresses,
1987
+ error
1988
+ });
1989
+ subscriber.error(error);
1990
+ }
1991
+ };
1992
+ poll();
1993
+ return () => {
1994
+ abortController.abort();
1995
+ };
1996
+ }).pipe(distinctUntilChanged(isEqual));
1997
+ };
1998
+
1999
+ const SolSplBalanceModule = {
2000
+ type: MODULE_TYPE$6,
2001
+ platform: PLATFORM$6,
2002
+ getMiniMetadata: getMiniMetadata$6,
2003
+ fetchTokens: fetchTokens$6,
2004
+ fetchBalances: fetchBalances$6,
2005
+ subscribeBalances: subscribeBalances$6,
2006
+ getTransferCallData: getTransferCallData$6
2007
+ };
2008
+
2009
+ // to be used by chaindata too
2010
+ const SolSplTokenConfigSchema = z.strictObject({
2011
+ mintAddress: SolSplTokenSchema.shape.mintAddress,
2012
+ ...TokenConfigBaseSchema.shape
2013
+ });
2014
+
2015
+ const MODULE_TYPE$5 = SubAssetsTokenSchema.shape.type.value;
2016
+ const PLATFORM$5 = SubAssetsTokenSchema.shape.platform.value;
2017
+
1763
2018
  const buildQueries$2 = (networkId, balanceDefs, miniMetadata) => {
1764
2019
  const networkStorageCoders = buildNetworkStorageCoders(networkId, miniMetadata, {
1765
2020
  storage: ["Assets", "Account"]
@@ -6294,7 +6549,7 @@ const SubTokensMiniMetadataExtraSchema = z.strictObject({
6294
6549
  palletId: z.string()
6295
6550
  });
6296
6551
 
6297
- const BALANCE_MODULES = [SubNativeBalanceModule, SubAssetsBalanceModule, SubHydrationBalanceModule, SubForeignAssetsBalanceModule, SubPsp22BalanceModule, SubTokensBalanceModule, EvmErc20BalanceModule, EvmUniswapV2BalanceModule, EvmNativeBalanceModule, SolNativeBalanceModule];
6552
+ const BALANCE_MODULES = [SubNativeBalanceModule, SubAssetsBalanceModule, SubHydrationBalanceModule, SubForeignAssetsBalanceModule, SubPsp22BalanceModule, SubTokensBalanceModule, EvmErc20BalanceModule, EvmUniswapV2BalanceModule, EvmNativeBalanceModule, SolNativeBalanceModule, SolSplBalanceModule];
6298
6553
 
6299
6554
  // share requests as all modules will call this at once
6300
6555
  const CACHE$1 = new Map();
@@ -6801,4 +7056,4 @@ const isAddressCompatibleWithNetwork = (network, address) => {
6801
7056
  const sortByBalanceId = (a, b) => getBalanceId(a).localeCompare(getBalanceId(b));
6802
7057
  const sortByMiniMetadataId = (a, b) => a.id.localeCompare(b.id);
6803
7058
 
6804
- 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, 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 };
7059
+ 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 };