@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.
- package/dist/declarations/src/modules/index.d.ts +12 -0
- package/dist/declarations/src/modules/sol-spl/config.d.ts +3 -0
- package/dist/declarations/src/modules/sol-spl/fetchBalances.d.ts +3 -0
- package/dist/declarations/src/modules/sol-spl/fetchTokens.d.ts +3 -0
- package/dist/declarations/src/modules/sol-spl/getMiniMetadata.d.ts +3 -0
- package/dist/declarations/src/modules/sol-spl/getTransferCallData.d.ts +3 -0
- package/dist/declarations/src/modules/sol-spl/index.d.ts +2 -0
- package/dist/declarations/src/modules/sol-spl/module.d.ts +3 -0
- package/dist/declarations/src/modules/sol-spl/subscribeBalances.d.ts +3 -0
- package/dist/declarations/src/modules/sol-spl/types.d.ts +14 -0
- package/dist/declarations/src/types/balances.d.ts +15 -0
- package/dist/talismn-balances.cjs.dev.js +415 -158
- package/dist/talismn-balances.cjs.prod.js +415 -158
- package/dist/talismn-balances.esm.js +415 -160
- package/package.json +13 -10
@@ -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$
|
25
|
-
const PLATFORM$
|
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$
|
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$
|
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$
|
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$
|
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$
|
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$
|
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$
|
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$
|
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$
|
816
|
-
platform: PLATFORM$
|
818
|
+
type: MODULE_TYPE$a,
|
819
|
+
platform: PLATFORM$a,
|
817
820
|
networkId
|
818
821
|
};
|
819
|
-
const cached2 = cache[tokenId] && TokenCacheSchema$
|
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$
|
837
|
+
const getMiniMetadata$a = () => {
|
835
838
|
throw new Error("MiniMetadata is not supported for ethereum tokens");
|
836
839
|
};
|
837
840
|
|
838
|
-
const getTransferCallData$
|
841
|
+
const getTransferCallData$a = ({
|
839
842
|
from,
|
840
843
|
to,
|
841
844
|
value,
|
842
845
|
token
|
843
846
|
}) => {
|
844
|
-
if (!isTokenOfType(token, MODULE_TYPE$
|
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$
|
860
|
-
const subscribeBalances$
|
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$
|
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$
|
884
|
+
setTimeout(poll, SUBSCRIPTION_INTERVAL$6);
|
882
885
|
} catch (error) {
|
883
886
|
log.error("Error", {
|
884
|
-
module: MODULE_TYPE$
|
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$
|
901
|
-
platform: PLATFORM$
|
902
|
-
getMiniMetadata: getMiniMetadata$
|
903
|
-
fetchTokens: fetchTokens$
|
904
|
-
fetchBalances: fetchBalances$
|
905
|
-
subscribeBalances: subscribeBalances$
|
906
|
-
getTransferCallData: getTransferCallData$
|
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$
|
920
|
-
const PLATFORM$
|
922
|
+
const MODULE_TYPE$9 = EvmNativeTokenSchema.shape.type.value;
|
923
|
+
const PLATFORM$9 = EvmNativeTokenSchema.shape.platform.value;
|
921
924
|
|
922
|
-
const fetchBalances$
|
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$
|
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$
|
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$
|
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$
|
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$
|
1046
|
-
platform: PLATFORM$
|
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$
|
1061
|
+
const getMiniMetadata$9 = () => {
|
1059
1062
|
throw new Error("MiniMetadata is not supported for ethereum tokens");
|
1060
1063
|
};
|
1061
1064
|
|
1062
|
-
const getTransferCallData$
|
1065
|
+
const getTransferCallData$9 = ({
|
1063
1066
|
from,
|
1064
1067
|
to,
|
1065
1068
|
value,
|
1066
1069
|
token
|
1067
1070
|
}) => {
|
1068
|
-
if (!isTokenOfType(token, MODULE_TYPE$
|
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$
|
1080
|
-
const subscribeBalances$
|
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$
|
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$
|
1104
|
+
setTimeout(poll, SUBSCRIPTION_INTERVAL$5);
|
1102
1105
|
} catch (error) {
|
1103
1106
|
log.error("Error", {
|
1104
|
-
module: MODULE_TYPE$
|
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$
|
1121
|
-
platform: PLATFORM$
|
1122
|
-
getMiniMetadata: getMiniMetadata$
|
1123
|
-
fetchTokens: fetchTokens$
|
1124
|
-
fetchBalances: fetchBalances$
|
1125
|
-
subscribeBalances: subscribeBalances$
|
1126
|
-
getTransferCallData: getTransferCallData$
|
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$
|
1135
|
-
const PLATFORM$
|
1137
|
+
const MODULE_TYPE$8 = EvmUniswapV2TokenSchema.shape.type.value;
|
1138
|
+
const PLATFORM$8 = EvmUniswapV2TokenSchema.shape.platform.value;
|
1136
1139
|
|
1137
|
-
const fetchBalances$
|
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$
|
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$
|
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$
|
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$
|
1374
|
-
platform: PLATFORM$
|
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$
|
1393
|
+
const getMiniMetadata$8 = () => {
|
1391
1394
|
throw new Error("MiniMetadata is not supported for ethereum tokens");
|
1392
1395
|
};
|
1393
1396
|
|
1394
|
-
const getTransferCallData$
|
1397
|
+
const getTransferCallData$8 = ({
|
1395
1398
|
from,
|
1396
1399
|
to,
|
1397
1400
|
value,
|
1398
1401
|
token
|
1399
1402
|
}) => {
|
1400
|
-
if (!isTokenOfType(token, MODULE_TYPE$
|
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$
|
1416
|
-
const subscribeBalances$
|
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$
|
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$
|
1440
|
+
setTimeout(poll, SUBSCRIPTION_INTERVAL$4);
|
1438
1441
|
} catch (error) {
|
1439
1442
|
log.error("Error", {
|
1440
|
-
module: MODULE_TYPE$
|
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$
|
1457
|
-
platform: PLATFORM$
|
1458
|
-
getMiniMetadata: getMiniMetadata$
|
1459
|
-
fetchTokens: fetchTokens$
|
1460
|
-
fetchBalances: fetchBalances$
|
1461
|
-
subscribeBalances: subscribeBalances$
|
1462
|
-
getTransferCallData: getTransferCallData$
|
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$
|
1472
|
-
const PLATFORM$
|
1474
|
+
const MODULE_TYPE$7 = SolNativeTokenSchema.shape.type.value;
|
1475
|
+
const PLATFORM$7 = SolNativeTokenSchema.shape.platform.value;
|
1473
1476
|
|
1474
|
-
const fetchBalances$
|
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$
|
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$
|
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$
|
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$
|
1534
|
-
platform: PLATFORM$
|
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$
|
1549
|
+
const getMiniMetadata$7 = () => {
|
1547
1550
|
throw new Error("MiniMetadata is not supported for sol-native tokens");
|
1548
1551
|
};
|
1549
1552
|
|
1550
|
-
const getTransferCallData$
|
1553
|
+
const getTransferCallData$7 = ({
|
1551
1554
|
from,
|
1552
1555
|
to,
|
1553
1556
|
value,
|
1554
1557
|
token
|
1555
1558
|
}) => {
|
1556
|
-
if (!isTokenOfType(token, MODULE_TYPE$
|
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$
|
1567
|
-
const subscribeBalances$
|
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$
|
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$
|
1591
|
+
setTimeout(poll, SUBSCRIPTION_INTERVAL$3);
|
1589
1592
|
} catch (error) {
|
1590
1593
|
log.error("Error", {
|
1591
|
-
module: MODULE_TYPE$
|
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$
|
1608
|
-
platform: PLATFORM$
|
1609
|
-
getMiniMetadata: getMiniMetadata$
|
1610
|
-
fetchTokens: fetchTokens$
|
1611
|
-
fetchBalances: fetchBalances$
|
1612
|
-
subscribeBalances: subscribeBalances$
|
1613
|
-
getTransferCallData: getTransferCallData$
|
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$
|
1622
|
-
const PLATFORM$
|
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 };
|