@talismn/balances 1.0.8 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/declarations/src/modules/index.d.ts +12 -1
- package/dist/declarations/src/modules/substrate-dtao/alphaPrice.d.ts +5 -0
- package/dist/declarations/src/modules/substrate-dtao/config.d.ts +5 -0
- package/dist/declarations/src/modules/substrate-dtao/fetchBalances.d.ts +3 -0
- package/dist/declarations/src/modules/substrate-dtao/fetchTokens.d.ts +3 -0
- package/dist/declarations/src/modules/substrate-dtao/getDtaoTokenRates.d.ts +11 -0
- package/dist/declarations/src/modules/substrate-dtao/getMiniMetadata.d.ts +3 -0
- package/dist/declarations/src/modules/substrate-dtao/getTransferCallData.d.ts +3 -0
- package/dist/declarations/src/modules/substrate-dtao/index.d.ts +4 -0
- package/dist/declarations/src/modules/substrate-dtao/module.d.ts +3 -0
- package/dist/declarations/src/modules/substrate-dtao/subscribeBalances.d.ts +3 -0
- package/dist/declarations/src/modules/substrate-dtao/types.d.ts +17 -0
- package/dist/declarations/src/modules/substrate-native/index.d.ts +0 -1
- package/dist/declarations/src/modules/substrate-native/types.d.ts +0 -1
- package/dist/declarations/src/types/IBalanceModule.d.ts +4 -0
- package/dist/declarations/src/types/balances.d.ts +26 -10
- package/dist/declarations/src/types/balancetypes.d.ts +1 -1
- package/dist/talismn-balances.cjs.dev.js +568 -348
- package/dist/talismn-balances.cjs.prod.js +568 -348
- package/dist/talismn-balances.esm.js +565 -346
- package/package.json +6 -6
- package/dist/declarations/src/modules/substrate-native/bittensor/getSubtensorStakingBalances.d.ts +0 -9
- package/dist/declarations/src/modules/substrate-native/bittensor/subtensor.d.ts +0 -20
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import { EvmErc20TokenSchema, parseTokenId, parseEvmErc20TokenId, evmErc20TokenId, isTokenOfType, TokenBaseSchema, EvmNativeTokenSchema, evmNativeTokenId, EvmUniswapV2TokenSchema, evmUniswapV2TokenId, SolNativeTokenSchema, solNativeTokenId, SolSplTokenSchema, solSplTokenId, parseSolSplTokenId, SubAssetsTokenSchema, subAssetTokenId, MINIMETADATA_VERSION, SubForeignAssetsTokenSchema, subForeignAssetTokenId, SubHydrationTokenSchema, subHydrationTokenId, SubNativeTokenSchema,
|
|
1
|
+
import { EvmErc20TokenSchema, parseTokenId, parseEvmErc20TokenId, evmErc20TokenId, isTokenOfType, TokenBaseSchema, EvmNativeTokenSchema, evmNativeTokenId, EvmUniswapV2TokenSchema, evmUniswapV2TokenId, SolNativeTokenSchema, solNativeTokenId, SolSplTokenSchema, solSplTokenId, parseSolSplTokenId, SubAssetsTokenSchema, subAssetTokenId, SubDTaoTokenSchema, subDTaoTokenId, getCleanToken, TokenSchema, MINIMETADATA_VERSION, parseSubDTaoTokenId, subNativeTokenId, SubForeignAssetsTokenSchema, subForeignAssetTokenId, SubHydrationTokenSchema, subHydrationTokenId, SubNativeTokenSchema, SubPsp22TokenSchema, subPsp22TokenId, SubTokensTokenSchema, subTokensTokenId, isNetworkDot } from '@talismn/chaindata-provider';
|
|
2
2
|
export { MINIMETADATA_VERSION } from '@talismn/chaindata-provider';
|
|
3
3
|
import { isEthereumAddress, isSolanaAddress, normalizeAddress, getAccountPlatformFromAddress } from '@talismn/crypto';
|
|
4
4
|
import { parseAbi, erc20Abi, getContract, ContractFunctionExecutionError, hexToString, erc20Abi_bytes32, encodeFunctionData, withRetry } from 'viem';
|
|
5
|
-
import { assign, omit, isEqual, uniq, keyBy, toPairs, keys,
|
|
5
|
+
import { assign, omit, isEqual, uniq, keyBy, toPairs, keys, values, fromPairs } from 'lodash-es';
|
|
6
6
|
import z from 'zod/v4';
|
|
7
7
|
import anylogger from 'anylogger';
|
|
8
|
-
import { of, Observable, distinctUntilChanged, BehaviorSubject, map,
|
|
8
|
+
import { of, Observable, distinctUntilChanged, BehaviorSubject, map, switchMap, shareReplay, combineLatest, timer, startWith, firstValueFrom, filter, defer, catchError, EMPTY, tap, from } from 'rxjs';
|
|
9
9
|
import BigNumber from 'bignumber.js';
|
|
10
10
|
import { PublicKey, SystemProgram } from '@solana/web3.js';
|
|
11
11
|
import { isNotNil, BigMath, isArrayOf, isBigInt, planckToTokens, isAbortError, getSharedObservable, keepAlive, isTruthy } from '@talismn/util';
|
|
12
|
-
import { parseMetadataRpc, toHex, unifyMetadata, decAnyMetadata, getDynamicBuilder, getLookupFn, decodeScale, getStorageKeyPrefix,
|
|
12
|
+
import { parseMetadataRpc, toHex, unifyMetadata, decAnyMetadata, getDynamicBuilder, getLookupFn, decodeScale, getStorageKeyPrefix, compactMetadata, encodeMetadata, Twox128, papiParse, papiStringify } from '@talismn/scale';
|
|
13
13
|
import { deserializeMetadata } from '@metaplex-foundation/mpl-token-metadata';
|
|
14
14
|
import { sol, publicKey } from '@metaplex-foundation/umi';
|
|
15
15
|
import { MintLayout, getAssociatedTokenAddress, createAssociatedTokenAccountInstruction, createTransferInstruction, TOKEN_PROGRAM_ID, getAccount } from '@solana/spl-token';
|
|
@@ -24,8 +24,8 @@ import { u8aToHex, u8aConcatStrict, u8aToString, hexToNumber } from '@polkadot/u
|
|
|
24
24
|
import PQueue from 'p-queue';
|
|
25
25
|
import { fetchBestMetadata } from '@talismn/sapi';
|
|
26
26
|
|
|
27
|
-
const MODULE_TYPE$
|
|
28
|
-
const PLATFORM$
|
|
27
|
+
const MODULE_TYPE$b = EvmErc20TokenSchema.shape.type.value;
|
|
28
|
+
const PLATFORM$b = EvmErc20TokenSchema.shape.platform.value;
|
|
29
29
|
|
|
30
30
|
const abiMulticall = parseAbi(["struct Call { address target; bytes callData; }", "struct Call3 { address target; bool allowFailure; bytes callData; }", "struct Call3Value { address target; bool allowFailure; uint256 value; bytes callData; }", "struct Result { bool success; bytes returnData; }", "function aggregate(Call[] calldata calls) public payable returns (uint256 blockNumber, bytes[] memory returnData)", "function aggregate3(Call3[] calldata calls) public payable returns (Result[] memory returnData)", "function aggregate3Value(Call3Value[] calldata calls) public payable returns (Result[] memory returnData)", "function blockAndAggregate(Call[] calldata calls) public payable returns (uint256 blockNumber, bytes32 blockHash, Result[] memory returnData)", "function getBasefee() view returns (uint256 basefee)", "function getBlockHash(uint256 blockNumber) view returns (bytes32 blockHash)", "function getBlockNumber() view returns (uint256 blockNumber)", "function getChainId() view returns (uint256 chainid)", "function getCurrentBlockCoinbase() view returns (address coinbase)", "function getCurrentBlockDifficulty() view returns (uint256 difficulty)", "function getCurrentBlockGasLimit() view returns (uint256 gaslimit)", "function getCurrentBlockTimestamp() view returns (uint256 timestamp)", "function getEthBalance(address addr) view returns (uint256 balance)", "function getLastBlockHash() view returns (bytes32 blockHash)", "function tryAggregate(bool requireSuccess, Call[] calldata calls) public payable returns (Result[] memory returnData)", "function tryBlockAndAggregate(bool requireSuccess, Call[] calldata calls) public payable returns (uint256 blockNumber, bytes32 blockHash, Result[] memory returnData)"]);
|
|
31
31
|
|
|
@@ -621,7 +621,7 @@ const getBalanceDefs = addressesByToken => {
|
|
|
621
621
|
// if there is at least one storage entry, the results will be an array with a single object
|
|
622
622
|
// if the storage has no entries in it (ex: Assets on ewx or moonbeam), the response will be an empty array
|
|
623
623
|
|
|
624
|
-
const fetchBalances$
|
|
624
|
+
const fetchBalances$b = async ({
|
|
625
625
|
networkId,
|
|
626
626
|
tokensWithAddresses,
|
|
627
627
|
connector
|
|
@@ -633,7 +633,7 @@ const fetchBalances$a = async ({
|
|
|
633
633
|
const client = await connector.getPublicClientForEvmNetwork(networkId);
|
|
634
634
|
if (!client) throw new Error(`Could not get rpc provider for evm network ${networkId}`);
|
|
635
635
|
for (const [token, addresses] of tokensWithAddresses) {
|
|
636
|
-
if (token.type !== MODULE_TYPE$
|
|
636
|
+
if (token.type !== MODULE_TYPE$b || token.networkId !== networkId) throw new Error(`Invalid token type or networkId for EVM ERC20 balance module: ${token.type} on ${token.networkId}`);
|
|
637
637
|
for (const address of addresses) if (!isEthereumAddress(address)) throw new Error(`Invalid ethereum address for EVM ERC20 balance module: ${address} for token ${token.id}`);
|
|
638
638
|
}
|
|
639
639
|
const balanceDefs = getBalanceDefs(tokensWithAddresses);
|
|
@@ -663,7 +663,7 @@ const fetchWithoutAggregator = async (client, balanceDefs) => {
|
|
|
663
663
|
address,
|
|
664
664
|
tokenId: token.id,
|
|
665
665
|
value: result.toString(),
|
|
666
|
-
source: MODULE_TYPE$
|
|
666
|
+
source: MODULE_TYPE$b,
|
|
667
667
|
networkId: parseEvmErc20TokenId(token.id).networkId,
|
|
668
668
|
status: "live"
|
|
669
669
|
};
|
|
@@ -706,7 +706,7 @@ const fetchWithAggregator = async (client, balanceDefs, erc20BalancesAggregatorA
|
|
|
706
706
|
address: balanceDef.address,
|
|
707
707
|
tokenId: balanceDef.token.id,
|
|
708
708
|
value: erc20Balances[index].toString(),
|
|
709
|
-
source: MODULE_TYPE$
|
|
709
|
+
source: MODULE_TYPE$b,
|
|
710
710
|
networkId: parseTokenId(balanceDef.token.id).networkId,
|
|
711
711
|
status: "live"
|
|
712
712
|
}));
|
|
@@ -775,7 +775,7 @@ const TokenCacheSchema$2 = z.discriminatedUnion("isValid", [z.strictObject({
|
|
|
775
775
|
id: EvmErc20TokenSchema.shape.id,
|
|
776
776
|
isValid: z.literal(false)
|
|
777
777
|
})]);
|
|
778
|
-
const fetchTokens$
|
|
778
|
+
const fetchTokens$b = async ({
|
|
779
779
|
networkId,
|
|
780
780
|
tokens,
|
|
781
781
|
connector,
|
|
@@ -815,8 +815,8 @@ const fetchTokens$a = async ({
|
|
|
815
815
|
}
|
|
816
816
|
const base = {
|
|
817
817
|
id: tokenId,
|
|
818
|
-
type: MODULE_TYPE$
|
|
819
|
-
platform: PLATFORM$
|
|
818
|
+
type: MODULE_TYPE$b,
|
|
819
|
+
platform: PLATFORM$b,
|
|
820
820
|
networkId
|
|
821
821
|
};
|
|
822
822
|
const cached2 = cache[tokenId] && TokenCacheSchema$2.safeParse(cache[tokenId]).data;
|
|
@@ -834,17 +834,17 @@ const fetchTokens$a = async ({
|
|
|
834
834
|
return result;
|
|
835
835
|
};
|
|
836
836
|
|
|
837
|
-
const getMiniMetadata$
|
|
837
|
+
const getMiniMetadata$b = () => {
|
|
838
838
|
throw new Error("MiniMetadata is not supported for ethereum tokens");
|
|
839
839
|
};
|
|
840
840
|
|
|
841
|
-
const getTransferCallData$
|
|
841
|
+
const getTransferCallData$b = ({
|
|
842
842
|
from,
|
|
843
843
|
to,
|
|
844
844
|
value,
|
|
845
845
|
token
|
|
846
846
|
}) => {
|
|
847
|
-
if (!isTokenOfType(token, MODULE_TYPE$
|
|
847
|
+
if (!isTokenOfType(token, MODULE_TYPE$b)) throw new Error(`Token type ${token.type} is not ${MODULE_TYPE$b}.`);
|
|
848
848
|
if (!isEthereumAddress(from)) throw new Error("Invalid from address");
|
|
849
849
|
if (!isEthereumAddress(to)) throw new Error("Invalid to address");
|
|
850
850
|
const data = encodeFunctionData({
|
|
@@ -859,8 +859,8 @@ const getTransferCallData$a = ({
|
|
|
859
859
|
};
|
|
860
860
|
};
|
|
861
861
|
|
|
862
|
-
const SUBSCRIPTION_INTERVAL$
|
|
863
|
-
const subscribeBalances$
|
|
862
|
+
const SUBSCRIPTION_INTERVAL$7 = 6_000;
|
|
863
|
+
const subscribeBalances$b = ({
|
|
864
864
|
networkId,
|
|
865
865
|
tokensWithAddresses,
|
|
866
866
|
connector
|
|
@@ -874,17 +874,17 @@ const subscribeBalances$a = ({
|
|
|
874
874
|
const poll = async () => {
|
|
875
875
|
try {
|
|
876
876
|
if (abortController.signal.aborted) return;
|
|
877
|
-
const balances = await fetchBalances$
|
|
877
|
+
const balances = await fetchBalances$b({
|
|
878
878
|
networkId,
|
|
879
879
|
tokensWithAddresses: tokensWithAddresses,
|
|
880
880
|
connector
|
|
881
881
|
});
|
|
882
882
|
if (abortController.signal.aborted) return;
|
|
883
883
|
subscriber.next(balances);
|
|
884
|
-
setTimeout(poll, SUBSCRIPTION_INTERVAL$
|
|
884
|
+
setTimeout(poll, SUBSCRIPTION_INTERVAL$7);
|
|
885
885
|
} catch (error) {
|
|
886
886
|
log.error("Error", {
|
|
887
|
-
module: MODULE_TYPE$
|
|
887
|
+
module: MODULE_TYPE$b,
|
|
888
888
|
networkId,
|
|
889
889
|
addressesByToken: tokensWithAddresses,
|
|
890
890
|
error
|
|
@@ -900,13 +900,13 @@ const subscribeBalances$a = ({
|
|
|
900
900
|
};
|
|
901
901
|
|
|
902
902
|
const EvmErc20BalanceModule = {
|
|
903
|
-
type: MODULE_TYPE$
|
|
904
|
-
platform: PLATFORM$
|
|
905
|
-
getMiniMetadata: getMiniMetadata$
|
|
906
|
-
fetchTokens: fetchTokens$
|
|
907
|
-
fetchBalances: fetchBalances$
|
|
908
|
-
subscribeBalances: subscribeBalances$
|
|
909
|
-
getTransferCallData: getTransferCallData$
|
|
903
|
+
type: MODULE_TYPE$b,
|
|
904
|
+
platform: PLATFORM$b,
|
|
905
|
+
getMiniMetadata: getMiniMetadata$b,
|
|
906
|
+
fetchTokens: fetchTokens$b,
|
|
907
|
+
fetchBalances: fetchBalances$b,
|
|
908
|
+
subscribeBalances: subscribeBalances$b,
|
|
909
|
+
getTransferCallData: getTransferCallData$b
|
|
910
910
|
};
|
|
911
911
|
|
|
912
912
|
const TokenConfigBaseSchema = TokenBaseSchema.partial().omit({
|
|
@@ -919,10 +919,10 @@ const EvmErc20TokenConfigSchema = z.strictObject({
|
|
|
919
919
|
...TokenConfigBaseSchema.shape
|
|
920
920
|
});
|
|
921
921
|
|
|
922
|
-
const MODULE_TYPE$
|
|
923
|
-
const PLATFORM$
|
|
922
|
+
const MODULE_TYPE$a = EvmNativeTokenSchema.shape.type.value;
|
|
923
|
+
const PLATFORM$a = EvmNativeTokenSchema.shape.platform.value;
|
|
924
924
|
|
|
925
|
-
const fetchBalances$
|
|
925
|
+
const fetchBalances$a = async ({
|
|
926
926
|
networkId,
|
|
927
927
|
tokensWithAddresses,
|
|
928
928
|
connector
|
|
@@ -934,7 +934,7 @@ const fetchBalances$9 = async ({
|
|
|
934
934
|
const client = await connector.getPublicClientForEvmNetwork(networkId);
|
|
935
935
|
if (!client) throw new Error(`Could not get rpc provider for evm network ${networkId}`);
|
|
936
936
|
for (const [token, addresses] of tokensWithAddresses) {
|
|
937
|
-
if (token.type !== MODULE_TYPE$
|
|
937
|
+
if (token.type !== MODULE_TYPE$a || token.networkId !== networkId) throw new Error(`Invalid token type or networkId for EVM ERC20 balance module: ${token.type} on ${token.networkId}`);
|
|
938
938
|
for (const address of addresses) if (!isEthereumAddress(address)) throw new Error(`Invalid ethereum address for EVM ERC20 balance module: ${address} for token ${token.id}`);
|
|
939
939
|
}
|
|
940
940
|
const balanceDefs = getBalanceDefs(tokensWithAddresses);
|
|
@@ -961,7 +961,7 @@ const fetchWithoutMulticall = async (client, balanceDefs) => {
|
|
|
961
961
|
address,
|
|
962
962
|
tokenId: token.id,
|
|
963
963
|
value: result.toString(),
|
|
964
|
-
source: MODULE_TYPE$
|
|
964
|
+
source: MODULE_TYPE$a,
|
|
965
965
|
networkId: parseTokenId(token.id).networkId,
|
|
966
966
|
status: "live"
|
|
967
967
|
};
|
|
@@ -1007,7 +1007,7 @@ const fetchWithMulticall = async (client, balanceDefs, multicall3Address) => {
|
|
|
1007
1007
|
address: balanceDefs[index].address,
|
|
1008
1008
|
tokenId: balanceDefs[index].token.id,
|
|
1009
1009
|
value: result.result.toString(),
|
|
1010
|
-
source: MODULE_TYPE$
|
|
1010
|
+
source: MODULE_TYPE$a,
|
|
1011
1011
|
networkId: parseTokenId(balanceDefs[index].token.id).networkId,
|
|
1012
1012
|
status: "live"
|
|
1013
1013
|
});
|
|
@@ -1037,7 +1037,7 @@ const fetchWithMulticall = async (client, balanceDefs, multicall3Address) => {
|
|
|
1037
1037
|
}
|
|
1038
1038
|
};
|
|
1039
1039
|
|
|
1040
|
-
const fetchTokens$
|
|
1040
|
+
const fetchTokens$a = async ({
|
|
1041
1041
|
networkId,
|
|
1042
1042
|
tokens
|
|
1043
1043
|
}) => {
|
|
@@ -1045,8 +1045,8 @@ const fetchTokens$9 = async ({
|
|
|
1045
1045
|
if (tokens.length !== 1) throw new Error("EVM Native module expects the nativeCurrency to be passed as a single token in the array");
|
|
1046
1046
|
const token = assign({
|
|
1047
1047
|
id: evmNativeTokenId(networkId),
|
|
1048
|
-
type: MODULE_TYPE$
|
|
1049
|
-
platform: PLATFORM$
|
|
1048
|
+
type: MODULE_TYPE$a,
|
|
1049
|
+
platform: PLATFORM$a,
|
|
1050
1050
|
networkId,
|
|
1051
1051
|
isDefault: true
|
|
1052
1052
|
}, tokens[0]);
|
|
@@ -1058,17 +1058,17 @@ const fetchTokens$9 = async ({
|
|
|
1058
1058
|
return [parsed.data];
|
|
1059
1059
|
};
|
|
1060
1060
|
|
|
1061
|
-
const getMiniMetadata$
|
|
1061
|
+
const getMiniMetadata$a = () => {
|
|
1062
1062
|
throw new Error("MiniMetadata is not supported for ethereum tokens");
|
|
1063
1063
|
};
|
|
1064
1064
|
|
|
1065
|
-
const getTransferCallData$
|
|
1065
|
+
const getTransferCallData$a = ({
|
|
1066
1066
|
from,
|
|
1067
1067
|
to,
|
|
1068
1068
|
value,
|
|
1069
1069
|
token
|
|
1070
1070
|
}) => {
|
|
1071
|
-
if (!isTokenOfType(token, MODULE_TYPE$
|
|
1071
|
+
if (!isTokenOfType(token, MODULE_TYPE$a)) throw new Error(`Token type ${token.type} is not ${MODULE_TYPE$a}.`);
|
|
1072
1072
|
if (!isEthereumAddress(from)) throw new Error("Invalid from address");
|
|
1073
1073
|
if (!isEthereumAddress(to)) throw new Error("Invalid to address");
|
|
1074
1074
|
return {
|
|
@@ -1079,8 +1079,8 @@ const getTransferCallData$9 = ({
|
|
|
1079
1079
|
};
|
|
1080
1080
|
};
|
|
1081
1081
|
|
|
1082
|
-
const SUBSCRIPTION_INTERVAL$
|
|
1083
|
-
const subscribeBalances$
|
|
1082
|
+
const SUBSCRIPTION_INTERVAL$6 = 6_000;
|
|
1083
|
+
const subscribeBalances$a = ({
|
|
1084
1084
|
networkId,
|
|
1085
1085
|
tokensWithAddresses,
|
|
1086
1086
|
connector
|
|
@@ -1094,17 +1094,17 @@ const subscribeBalances$9 = ({
|
|
|
1094
1094
|
const poll = async () => {
|
|
1095
1095
|
try {
|
|
1096
1096
|
if (abortController.signal.aborted) return;
|
|
1097
|
-
const balances = await fetchBalances$
|
|
1097
|
+
const balances = await fetchBalances$a({
|
|
1098
1098
|
networkId,
|
|
1099
1099
|
tokensWithAddresses: tokensWithAddresses,
|
|
1100
1100
|
connector
|
|
1101
1101
|
});
|
|
1102
1102
|
if (abortController.signal.aborted) return;
|
|
1103
1103
|
subscriber.next(balances);
|
|
1104
|
-
setTimeout(poll, SUBSCRIPTION_INTERVAL$
|
|
1104
|
+
setTimeout(poll, SUBSCRIPTION_INTERVAL$6);
|
|
1105
1105
|
} catch (error) {
|
|
1106
1106
|
log.error("Error", {
|
|
1107
|
-
module: MODULE_TYPE$
|
|
1107
|
+
module: MODULE_TYPE$a,
|
|
1108
1108
|
networkId,
|
|
1109
1109
|
addressesByToken: tokensWithAddresses,
|
|
1110
1110
|
error
|
|
@@ -1120,13 +1120,13 @@ const subscribeBalances$9 = ({
|
|
|
1120
1120
|
};
|
|
1121
1121
|
|
|
1122
1122
|
const EvmNativeBalanceModule = {
|
|
1123
|
-
type: MODULE_TYPE$
|
|
1124
|
-
platform: PLATFORM$
|
|
1125
|
-
getMiniMetadata: getMiniMetadata$
|
|
1126
|
-
fetchTokens: fetchTokens$
|
|
1127
|
-
fetchBalances: fetchBalances$
|
|
1128
|
-
subscribeBalances: subscribeBalances$
|
|
1129
|
-
getTransferCallData: getTransferCallData$
|
|
1123
|
+
type: MODULE_TYPE$a,
|
|
1124
|
+
platform: PLATFORM$a,
|
|
1125
|
+
getMiniMetadata: getMiniMetadata$a,
|
|
1126
|
+
fetchTokens: fetchTokens$a,
|
|
1127
|
+
fetchBalances: fetchBalances$a,
|
|
1128
|
+
subscribeBalances: subscribeBalances$a,
|
|
1129
|
+
getTransferCallData: getTransferCallData$a
|
|
1130
1130
|
};
|
|
1131
1131
|
|
|
1132
1132
|
// to be used by chaindata too
|
|
@@ -1134,10 +1134,10 @@ const EvmNativeTokenConfigSchema = z.strictObject({
|
|
|
1134
1134
|
...TokenConfigBaseSchema.shape
|
|
1135
1135
|
});
|
|
1136
1136
|
|
|
1137
|
-
const MODULE_TYPE$
|
|
1138
|
-
const PLATFORM$
|
|
1137
|
+
const MODULE_TYPE$9 = EvmUniswapV2TokenSchema.shape.type.value;
|
|
1138
|
+
const PLATFORM$9 = EvmUniswapV2TokenSchema.shape.platform.value;
|
|
1139
1139
|
|
|
1140
|
-
const fetchBalances$
|
|
1140
|
+
const fetchBalances$9 = async ({
|
|
1141
1141
|
networkId,
|
|
1142
1142
|
tokensWithAddresses,
|
|
1143
1143
|
connector
|
|
@@ -1149,7 +1149,7 @@ const fetchBalances$8 = async ({
|
|
|
1149
1149
|
const client = await connector.getPublicClientForEvmNetwork(networkId);
|
|
1150
1150
|
if (!client) throw new Error(`Could not get rpc provider for evm network ${networkId}`);
|
|
1151
1151
|
for (const [token, addresses] of tokensWithAddresses) {
|
|
1152
|
-
if (token.type !== MODULE_TYPE$
|
|
1152
|
+
if (token.type !== MODULE_TYPE$9 || token.networkId !== networkId) throw new Error(`Invalid token type or networkId for EVM ERC20 balance module: ${token.type} on ${token.networkId}`);
|
|
1153
1153
|
for (const address of addresses) if (!isEthereumAddress(address)) throw new Error(`Invalid ethereum address for EVM ERC20 balance module: ${address} for token ${token.id}`);
|
|
1154
1154
|
}
|
|
1155
1155
|
const balanceDefs = getBalanceDefs(tokensWithAddresses);
|
|
@@ -1236,7 +1236,7 @@ const fetchPoolBalances = async (client, balanceDefs) => {
|
|
|
1236
1236
|
acc.success.push({
|
|
1237
1237
|
address,
|
|
1238
1238
|
tokenId: token.id,
|
|
1239
|
-
source: MODULE_TYPE$
|
|
1239
|
+
source: MODULE_TYPE$9,
|
|
1240
1240
|
networkId: parseTokenId(token.id).networkId,
|
|
1241
1241
|
status: "live",
|
|
1242
1242
|
values: [{
|
|
@@ -1314,7 +1314,7 @@ const TokenCacheSchema$1 = z.discriminatedUnion("isValid", [z.strictObject({
|
|
|
1314
1314
|
id: EvmUniswapV2TokenSchema.shape.id,
|
|
1315
1315
|
isValid: z.literal(false)
|
|
1316
1316
|
})]);
|
|
1317
|
-
const fetchTokens$
|
|
1317
|
+
const fetchTokens$9 = async ({
|
|
1318
1318
|
networkId,
|
|
1319
1319
|
tokens,
|
|
1320
1320
|
connector,
|
|
@@ -1373,8 +1373,8 @@ const fetchTokens$8 = async ({
|
|
|
1373
1373
|
}
|
|
1374
1374
|
const base = {
|
|
1375
1375
|
id: tokenId,
|
|
1376
|
-
type: MODULE_TYPE$
|
|
1377
|
-
platform: PLATFORM$
|
|
1376
|
+
type: MODULE_TYPE$9,
|
|
1377
|
+
platform: PLATFORM$9,
|
|
1378
1378
|
networkId
|
|
1379
1379
|
};
|
|
1380
1380
|
const cached2 = cache[tokenId] && TokenCacheSchema$1.safeParse(cache[tokenId]).data;
|
|
@@ -1390,17 +1390,17 @@ const fetchTokens$8 = async ({
|
|
|
1390
1390
|
return result;
|
|
1391
1391
|
};
|
|
1392
1392
|
|
|
1393
|
-
const getMiniMetadata$
|
|
1393
|
+
const getMiniMetadata$9 = () => {
|
|
1394
1394
|
throw new Error("MiniMetadata is not supported for ethereum tokens");
|
|
1395
1395
|
};
|
|
1396
1396
|
|
|
1397
|
-
const getTransferCallData$
|
|
1397
|
+
const getTransferCallData$9 = ({
|
|
1398
1398
|
from,
|
|
1399
1399
|
to,
|
|
1400
1400
|
value,
|
|
1401
1401
|
token
|
|
1402
1402
|
}) => {
|
|
1403
|
-
if (!isTokenOfType(token, MODULE_TYPE$
|
|
1403
|
+
if (!isTokenOfType(token, MODULE_TYPE$9)) throw new Error(`Token type ${token.type} is not ${MODULE_TYPE$9}.`);
|
|
1404
1404
|
if (!isEthereumAddress(from)) throw new Error("Invalid from address");
|
|
1405
1405
|
if (!isEthereumAddress(to)) throw new Error("Invalid to address");
|
|
1406
1406
|
const data = encodeFunctionData({
|
|
@@ -1415,8 +1415,8 @@ const getTransferCallData$8 = ({
|
|
|
1415
1415
|
};
|
|
1416
1416
|
};
|
|
1417
1417
|
|
|
1418
|
-
const SUBSCRIPTION_INTERVAL$
|
|
1419
|
-
const subscribeBalances$
|
|
1418
|
+
const SUBSCRIPTION_INTERVAL$5 = 6_000;
|
|
1419
|
+
const subscribeBalances$9 = ({
|
|
1420
1420
|
networkId,
|
|
1421
1421
|
tokensWithAddresses,
|
|
1422
1422
|
connector
|
|
@@ -1430,17 +1430,17 @@ const subscribeBalances$8 = ({
|
|
|
1430
1430
|
const poll = async () => {
|
|
1431
1431
|
try {
|
|
1432
1432
|
if (abortController.signal.aborted) return;
|
|
1433
|
-
const balances = await fetchBalances$
|
|
1433
|
+
const balances = await fetchBalances$9({
|
|
1434
1434
|
networkId,
|
|
1435
1435
|
tokensWithAddresses: tokensWithAddresses,
|
|
1436
1436
|
connector
|
|
1437
1437
|
});
|
|
1438
1438
|
if (abortController.signal.aborted) return;
|
|
1439
1439
|
subscriber.next(balances);
|
|
1440
|
-
setTimeout(poll, SUBSCRIPTION_INTERVAL$
|
|
1440
|
+
setTimeout(poll, SUBSCRIPTION_INTERVAL$5);
|
|
1441
1441
|
} catch (error) {
|
|
1442
1442
|
log.error("Error", {
|
|
1443
|
-
module: MODULE_TYPE$
|
|
1443
|
+
module: MODULE_TYPE$9,
|
|
1444
1444
|
networkId,
|
|
1445
1445
|
addressesByToken: tokensWithAddresses,
|
|
1446
1446
|
error
|
|
@@ -1456,13 +1456,13 @@ const subscribeBalances$8 = ({
|
|
|
1456
1456
|
};
|
|
1457
1457
|
|
|
1458
1458
|
const EvmUniswapV2BalanceModule = {
|
|
1459
|
-
type: MODULE_TYPE$
|
|
1460
|
-
platform: PLATFORM$
|
|
1461
|
-
getMiniMetadata: getMiniMetadata$
|
|
1462
|
-
fetchTokens: fetchTokens$
|
|
1463
|
-
fetchBalances: fetchBalances$
|
|
1464
|
-
subscribeBalances: subscribeBalances$
|
|
1465
|
-
getTransferCallData: getTransferCallData$
|
|
1459
|
+
type: MODULE_TYPE$9,
|
|
1460
|
+
platform: PLATFORM$9,
|
|
1461
|
+
getMiniMetadata: getMiniMetadata$9,
|
|
1462
|
+
fetchTokens: fetchTokens$9,
|
|
1463
|
+
fetchBalances: fetchBalances$9,
|
|
1464
|
+
subscribeBalances: subscribeBalances$9,
|
|
1465
|
+
getTransferCallData: getTransferCallData$9
|
|
1466
1466
|
};
|
|
1467
1467
|
|
|
1468
1468
|
// to be used by chaindata too
|
|
@@ -1471,10 +1471,10 @@ const EvmUniswapV2TokenConfigSchema = z.strictObject({
|
|
|
1471
1471
|
...TokenConfigBaseSchema.shape
|
|
1472
1472
|
});
|
|
1473
1473
|
|
|
1474
|
-
const MODULE_TYPE$
|
|
1475
|
-
const PLATFORM$
|
|
1474
|
+
const MODULE_TYPE$8 = SolNativeTokenSchema.shape.type.value;
|
|
1475
|
+
const PLATFORM$8 = SolNativeTokenSchema.shape.platform.value;
|
|
1476
1476
|
|
|
1477
|
-
const fetchBalances$
|
|
1477
|
+
const fetchBalances$8 = async ({
|
|
1478
1478
|
networkId,
|
|
1479
1479
|
tokensWithAddresses,
|
|
1480
1480
|
connector
|
|
@@ -1486,7 +1486,7 @@ const fetchBalances$7 = async ({
|
|
|
1486
1486
|
const connection = await connector.getConnection(networkId);
|
|
1487
1487
|
if (!connection) throw new Error(`Could not get rpc provider for sol network ${networkId}`);
|
|
1488
1488
|
for (const [token, addresses] of tokensWithAddresses) {
|
|
1489
|
-
if (token.type !== MODULE_TYPE$
|
|
1489
|
+
if (token.type !== MODULE_TYPE$8 || token.networkId !== networkId) throw new Error(`Invalid token type or networkId for balance module: ${token.type} on ${token.networkId}`);
|
|
1490
1490
|
for (const address of addresses) if (!isSolanaAddress(address)) throw new Error(`Invalid solana address for balance module: ${address} for token ${token.id}`);
|
|
1491
1491
|
}
|
|
1492
1492
|
const balanceDefs = getBalanceDefs(tokensWithAddresses);
|
|
@@ -1501,7 +1501,7 @@ const fetchBalances$7 = async ({
|
|
|
1501
1501
|
address: address,
|
|
1502
1502
|
tokenId: token.id,
|
|
1503
1503
|
value: lamports.toString(),
|
|
1504
|
-
source: MODULE_TYPE$
|
|
1504
|
+
source: MODULE_TYPE$8,
|
|
1505
1505
|
networkId: token.networkId,
|
|
1506
1506
|
status: "live"
|
|
1507
1507
|
};
|
|
@@ -1525,7 +1525,7 @@ const fetchBalances$7 = async ({
|
|
|
1525
1525
|
});
|
|
1526
1526
|
};
|
|
1527
1527
|
|
|
1528
|
-
const fetchTokens$
|
|
1528
|
+
const fetchTokens$8 = async ({
|
|
1529
1529
|
networkId,
|
|
1530
1530
|
tokens
|
|
1531
1531
|
}) => {
|
|
@@ -1533,8 +1533,8 @@ const fetchTokens$7 = async ({
|
|
|
1533
1533
|
if (tokens.length !== 1) throw new Error("EVM Native module expects the nativeCurrency to be passed as a single token in the array");
|
|
1534
1534
|
const token = assign({
|
|
1535
1535
|
id: solNativeTokenId(networkId),
|
|
1536
|
-
type: MODULE_TYPE$
|
|
1537
|
-
platform: PLATFORM$
|
|
1536
|
+
type: MODULE_TYPE$8,
|
|
1537
|
+
platform: PLATFORM$8,
|
|
1538
1538
|
networkId,
|
|
1539
1539
|
isDefault: true
|
|
1540
1540
|
}, tokens[0]);
|
|
@@ -1546,17 +1546,17 @@ const fetchTokens$7 = async ({
|
|
|
1546
1546
|
return [parsed.data];
|
|
1547
1547
|
};
|
|
1548
1548
|
|
|
1549
|
-
const getMiniMetadata$
|
|
1549
|
+
const getMiniMetadata$8 = () => {
|
|
1550
1550
|
throw new Error("MiniMetadata is not supported for sol-native tokens");
|
|
1551
1551
|
};
|
|
1552
1552
|
|
|
1553
|
-
const getTransferCallData$
|
|
1553
|
+
const getTransferCallData$8 = ({
|
|
1554
1554
|
from,
|
|
1555
1555
|
to,
|
|
1556
1556
|
value,
|
|
1557
1557
|
token
|
|
1558
1558
|
}) => {
|
|
1559
|
-
if (!isTokenOfType(token, MODULE_TYPE$
|
|
1559
|
+
if (!isTokenOfType(token, MODULE_TYPE$8)) throw new Error(`Token type ${token.type} is not ${MODULE_TYPE$8}.`);
|
|
1560
1560
|
const fromPubkey = new PublicKey(from);
|
|
1561
1561
|
const transferIx = SystemProgram.transfer({
|
|
1562
1562
|
fromPubkey,
|
|
@@ -1566,8 +1566,8 @@ const getTransferCallData$7 = ({
|
|
|
1566
1566
|
return [transferIx];
|
|
1567
1567
|
};
|
|
1568
1568
|
|
|
1569
|
-
const SUBSCRIPTION_INTERVAL$
|
|
1570
|
-
const subscribeBalances$
|
|
1569
|
+
const SUBSCRIPTION_INTERVAL$4 = 6_000;
|
|
1570
|
+
const subscribeBalances$8 = ({
|
|
1571
1571
|
networkId,
|
|
1572
1572
|
tokensWithAddresses,
|
|
1573
1573
|
connector
|
|
@@ -1581,17 +1581,17 @@ const subscribeBalances$7 = ({
|
|
|
1581
1581
|
const poll = async () => {
|
|
1582
1582
|
try {
|
|
1583
1583
|
if (abortController.signal.aborted) return;
|
|
1584
|
-
const balances = await fetchBalances$
|
|
1584
|
+
const balances = await fetchBalances$8({
|
|
1585
1585
|
networkId,
|
|
1586
1586
|
tokensWithAddresses,
|
|
1587
1587
|
connector
|
|
1588
1588
|
});
|
|
1589
1589
|
if (abortController.signal.aborted) return;
|
|
1590
1590
|
subscriber.next(balances);
|
|
1591
|
-
setTimeout(poll, SUBSCRIPTION_INTERVAL$
|
|
1591
|
+
setTimeout(poll, SUBSCRIPTION_INTERVAL$4);
|
|
1592
1592
|
} catch (error) {
|
|
1593
1593
|
log.error("Error", {
|
|
1594
|
-
module: MODULE_TYPE$
|
|
1594
|
+
module: MODULE_TYPE$8,
|
|
1595
1595
|
networkId,
|
|
1596
1596
|
tokensWithAddresses,
|
|
1597
1597
|
error
|
|
@@ -1607,13 +1607,13 @@ const subscribeBalances$7 = ({
|
|
|
1607
1607
|
};
|
|
1608
1608
|
|
|
1609
1609
|
const SolNativeBalanceModule = {
|
|
1610
|
-
type: MODULE_TYPE$
|
|
1611
|
-
platform: PLATFORM$
|
|
1612
|
-
getMiniMetadata: getMiniMetadata$
|
|
1613
|
-
fetchTokens: fetchTokens$
|
|
1614
|
-
fetchBalances: fetchBalances$
|
|
1615
|
-
subscribeBalances: subscribeBalances$
|
|
1616
|
-
getTransferCallData: getTransferCallData$
|
|
1610
|
+
type: MODULE_TYPE$8,
|
|
1611
|
+
platform: PLATFORM$8,
|
|
1612
|
+
getMiniMetadata: getMiniMetadata$8,
|
|
1613
|
+
fetchTokens: fetchTokens$8,
|
|
1614
|
+
fetchBalances: fetchBalances$8,
|
|
1615
|
+
subscribeBalances: subscribeBalances$8,
|
|
1616
|
+
getTransferCallData: getTransferCallData$8
|
|
1617
1617
|
};
|
|
1618
1618
|
|
|
1619
1619
|
// to be used by chaindata too
|
|
@@ -1621,16 +1621,22 @@ const SolNativeTokenConfigSchema = z.strictObject({
|
|
|
1621
1621
|
...TokenConfigBaseSchema.shape
|
|
1622
1622
|
});
|
|
1623
1623
|
|
|
1624
|
-
const MODULE_TYPE$
|
|
1625
|
-
const PLATFORM$
|
|
1624
|
+
const MODULE_TYPE$7 = SolSplTokenSchema.shape.type.value;
|
|
1625
|
+
const PLATFORM$7 = SolSplTokenSchema.shape.platform.value;
|
|
1626
1626
|
|
|
1627
1627
|
const fetchRuntimeCallResult = async (connector, networkId, metadataRpc, apiName, method, args) => {
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1628
|
+
try {
|
|
1629
|
+
const {
|
|
1630
|
+
builder
|
|
1631
|
+
} = parseMetadataRpc(metadataRpc);
|
|
1632
|
+
const call = builder.buildRuntimeCall(apiName, method);
|
|
1633
|
+
const hex = await connector.send(networkId, "state_call", [`${apiName}_${method}`, toHex(call.args.enc(args))]);
|
|
1634
|
+
return call.value.dec(hex);
|
|
1635
|
+
} catch (cause) {
|
|
1636
|
+
throw new Error(`Error fetching runtime call on ${networkId} for ${apiName}.${method}`, {
|
|
1637
|
+
cause
|
|
1638
|
+
});
|
|
1639
|
+
}
|
|
1634
1640
|
};
|
|
1635
1641
|
|
|
1636
1642
|
const hasStorageItem = (metadata, palletName, itemName) => {
|
|
@@ -1775,7 +1781,7 @@ const setDetectedTokenIds = (address, type, tokenIds) => {
|
|
|
1775
1781
|
const getDetectedTokensIds$ = address => tokenIdsByAddress.pipe(map(ownedTokens => ownedTokens[address] ?? []), distinctUntilChanged(isEqual));
|
|
1776
1782
|
|
|
1777
1783
|
const SPL_PROGRAM_ID = "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA";
|
|
1778
|
-
const fetchBalances$
|
|
1784
|
+
const fetchBalances$7 = async ({
|
|
1779
1785
|
networkId,
|
|
1780
1786
|
tokensWithAddresses,
|
|
1781
1787
|
connector
|
|
@@ -1799,7 +1805,7 @@ const fetchBalances$6 = async ({
|
|
|
1799
1805
|
tokenId: solSplTokenId(networkId, mintAddress),
|
|
1800
1806
|
networkId,
|
|
1801
1807
|
address,
|
|
1802
|
-
source: MODULE_TYPE$
|
|
1808
|
+
source: MODULE_TYPE$7,
|
|
1803
1809
|
status: "live",
|
|
1804
1810
|
value
|
|
1805
1811
|
};
|
|
@@ -1813,7 +1819,7 @@ const fetchBalances$6 = async ({
|
|
|
1813
1819
|
}).filter(isNotNil);
|
|
1814
1820
|
|
|
1815
1821
|
// allows the wallet to detect new tokens, and enable them automatically
|
|
1816
|
-
setDetectedTokenIds(address, MODULE_TYPE$
|
|
1822
|
+
setDetectedTokenIds(address, MODULE_TYPE$7, balances.map(b => b.tokenId));
|
|
1817
1823
|
return [address, balances];
|
|
1818
1824
|
}));
|
|
1819
1825
|
const allBalancesByKey = keyBy(balancesPerAddress.flatMap(([, addressBalances]) => addressBalances), b => getBalanceKey(b.tokenId, b.address));
|
|
@@ -1826,7 +1832,7 @@ const fetchBalances$6 = async ({
|
|
|
1826
1832
|
tokenId: bd.token.id,
|
|
1827
1833
|
networkId: bd.token.networkId,
|
|
1828
1834
|
address: bd.address,
|
|
1829
|
-
source: MODULE_TYPE$
|
|
1835
|
+
source: MODULE_TYPE$7,
|
|
1830
1836
|
status: "live",
|
|
1831
1837
|
value: "0"
|
|
1832
1838
|
};
|
|
@@ -1854,7 +1860,7 @@ const TokenCacheSchema = z.discriminatedUnion("isValid", [z.strictObject({
|
|
|
1854
1860
|
isValid: z.literal(false)
|
|
1855
1861
|
})]);
|
|
1856
1862
|
const METAPLEX_PROGRAM_ID = new PublicKey("metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s");
|
|
1857
|
-
const fetchTokens$
|
|
1863
|
+
const fetchTokens$7 = async ({
|
|
1858
1864
|
networkId,
|
|
1859
1865
|
tokens,
|
|
1860
1866
|
connector,
|
|
@@ -1872,8 +1878,8 @@ const fetchTokens$6 = async ({
|
|
|
1872
1878
|
if (cached?.isValid === false) continue;
|
|
1873
1879
|
const base = {
|
|
1874
1880
|
id: tokenId,
|
|
1875
|
-
type: MODULE_TYPE$
|
|
1876
|
-
platform: PLATFORM$
|
|
1881
|
+
type: MODULE_TYPE$7,
|
|
1882
|
+
platform: PLATFORM$7,
|
|
1877
1883
|
networkId
|
|
1878
1884
|
};
|
|
1879
1885
|
const token = assign(base, cached?.isValid ? omit(cached, ["isValid"]) : {}, tokenConfig);
|
|
@@ -1940,18 +1946,18 @@ const fetchOnChainTokenData = async (connector, tokenId) => {
|
|
|
1940
1946
|
return null;
|
|
1941
1947
|
};
|
|
1942
1948
|
|
|
1943
|
-
const getMiniMetadata$
|
|
1949
|
+
const getMiniMetadata$7 = () => {
|
|
1944
1950
|
throw new Error("MiniMetadata is not supported for solana tokens");
|
|
1945
1951
|
};
|
|
1946
1952
|
|
|
1947
|
-
const getTransferCallData$
|
|
1953
|
+
const getTransferCallData$7 = async ({
|
|
1948
1954
|
from,
|
|
1949
1955
|
to,
|
|
1950
1956
|
value,
|
|
1951
1957
|
token,
|
|
1952
1958
|
connector
|
|
1953
1959
|
}) => {
|
|
1954
|
-
if (!isTokenOfType(token, MODULE_TYPE$
|
|
1960
|
+
if (!isTokenOfType(token, MODULE_TYPE$7)) throw new Error(`Token type ${token.type} is not ${MODULE_TYPE$7}.`);
|
|
1955
1961
|
const connection = await connector.getConnection(token.networkId);
|
|
1956
1962
|
const instructions = [];
|
|
1957
1963
|
const mint = new PublicKey(token.mintAddress);
|
|
@@ -1982,8 +1988,8 @@ const tokenAccountExists = async (connection, address) => {
|
|
|
1982
1988
|
}
|
|
1983
1989
|
};
|
|
1984
1990
|
|
|
1985
|
-
const SUBSCRIPTION_INTERVAL$
|
|
1986
|
-
const subscribeBalances$
|
|
1991
|
+
const SUBSCRIPTION_INTERVAL$3 = 6_000;
|
|
1992
|
+
const subscribeBalances$7 = ({
|
|
1987
1993
|
networkId,
|
|
1988
1994
|
tokensWithAddresses,
|
|
1989
1995
|
connector
|
|
@@ -1997,17 +2003,17 @@ const subscribeBalances$6 = ({
|
|
|
1997
2003
|
const poll = async () => {
|
|
1998
2004
|
try {
|
|
1999
2005
|
if (abortController.signal.aborted) return;
|
|
2000
|
-
const balances = await fetchBalances$
|
|
2006
|
+
const balances = await fetchBalances$7({
|
|
2001
2007
|
networkId,
|
|
2002
2008
|
tokensWithAddresses: tokensWithAddresses,
|
|
2003
2009
|
connector
|
|
2004
2010
|
});
|
|
2005
2011
|
if (abortController.signal.aborted) return;
|
|
2006
2012
|
subscriber.next(balances);
|
|
2007
|
-
setTimeout(poll, SUBSCRIPTION_INTERVAL$
|
|
2013
|
+
setTimeout(poll, SUBSCRIPTION_INTERVAL$3);
|
|
2008
2014
|
} catch (error) {
|
|
2009
2015
|
log.error("Error", {
|
|
2010
|
-
module: MODULE_TYPE$
|
|
2016
|
+
module: MODULE_TYPE$7,
|
|
2011
2017
|
networkId,
|
|
2012
2018
|
addressesByToken: tokensWithAddresses,
|
|
2013
2019
|
error
|
|
@@ -2023,13 +2029,13 @@ const subscribeBalances$6 = ({
|
|
|
2023
2029
|
};
|
|
2024
2030
|
|
|
2025
2031
|
const SolSplBalanceModule = {
|
|
2026
|
-
type: MODULE_TYPE$
|
|
2027
|
-
platform: PLATFORM$
|
|
2028
|
-
getMiniMetadata: getMiniMetadata$
|
|
2029
|
-
fetchTokens: fetchTokens$
|
|
2030
|
-
fetchBalances: fetchBalances$
|
|
2031
|
-
subscribeBalances: subscribeBalances$
|
|
2032
|
-
getTransferCallData: getTransferCallData$
|
|
2032
|
+
type: MODULE_TYPE$7,
|
|
2033
|
+
platform: PLATFORM$7,
|
|
2034
|
+
getMiniMetadata: getMiniMetadata$7,
|
|
2035
|
+
fetchTokens: fetchTokens$7,
|
|
2036
|
+
fetchBalances: fetchBalances$7,
|
|
2037
|
+
subscribeBalances: subscribeBalances$7,
|
|
2038
|
+
getTransferCallData: getTransferCallData$7
|
|
2033
2039
|
};
|
|
2034
2040
|
|
|
2035
2041
|
// to be used by chaindata too
|
|
@@ -2038,8 +2044,8 @@ const SolSplTokenConfigSchema = z.strictObject({
|
|
|
2038
2044
|
...TokenConfigBaseSchema.shape
|
|
2039
2045
|
});
|
|
2040
2046
|
|
|
2041
|
-
const MODULE_TYPE$
|
|
2042
|
-
const PLATFORM$
|
|
2047
|
+
const MODULE_TYPE$6 = SubAssetsTokenSchema.shape.type.value;
|
|
2048
|
+
const PLATFORM$6 = SubAssetsTokenSchema.shape.platform.value;
|
|
2043
2049
|
|
|
2044
2050
|
const buildQueries$2 = (networkId, balanceDefs, miniMetadata) => {
|
|
2045
2051
|
const networkStorageCoders = buildNetworkStorageCoders(networkId, miniMetadata, {
|
|
@@ -2115,7 +2121,7 @@ const tryEncode = (scaleCoder, ...args) => {
|
|
|
2115
2121
|
}
|
|
2116
2122
|
};
|
|
2117
2123
|
|
|
2118
|
-
const fetchBalances$
|
|
2124
|
+
const fetchBalances$6 = async ({
|
|
2119
2125
|
networkId,
|
|
2120
2126
|
tokensWithAddresses,
|
|
2121
2127
|
connector,
|
|
@@ -2127,7 +2133,7 @@ const fetchBalances$5 = async ({
|
|
|
2127
2133
|
};
|
|
2128
2134
|
const balanceDefs = getBalanceDefs(tokensWithAddresses);
|
|
2129
2135
|
if (!miniMetadata?.data) {
|
|
2130
|
-
log.warn(`MiniMetadata is required for fetching ${MODULE_TYPE$
|
|
2136
|
+
log.warn(`MiniMetadata is required for fetching ${MODULE_TYPE$6} balances on ${networkId}.`);
|
|
2131
2137
|
return {
|
|
2132
2138
|
success: [],
|
|
2133
2139
|
errors: balanceDefs.map(def => ({
|
|
@@ -2137,19 +2143,19 @@ const fetchBalances$5 = async ({
|
|
|
2137
2143
|
}))
|
|
2138
2144
|
};
|
|
2139
2145
|
}
|
|
2140
|
-
if (miniMetadata.source !== MODULE_TYPE$
|
|
2141
|
-
log.warn(`Ignoring miniMetadata with source ${miniMetadata.source} in ${MODULE_TYPE$
|
|
2146
|
+
if (miniMetadata.source !== MODULE_TYPE$6) {
|
|
2147
|
+
log.warn(`Ignoring miniMetadata with source ${miniMetadata.source} in ${MODULE_TYPE$6}.`);
|
|
2142
2148
|
return {
|
|
2143
2149
|
success: [],
|
|
2144
2150
|
errors: balanceDefs.map(def => ({
|
|
2145
2151
|
tokenId: def.token.id,
|
|
2146
2152
|
address: def.address,
|
|
2147
|
-
error: new Error(`Invalid request: miniMetadata source is not ${MODULE_TYPE$
|
|
2153
|
+
error: new Error(`Invalid request: miniMetadata source is not ${MODULE_TYPE$6}`)
|
|
2148
2154
|
}))
|
|
2149
2155
|
};
|
|
2150
2156
|
}
|
|
2151
2157
|
if (miniMetadata.chainId !== networkId) {
|
|
2152
|
-
log.warn(`Ignoring miniMetadata with chainId ${miniMetadata.chainId} in ${MODULE_TYPE$
|
|
2158
|
+
log.warn(`Ignoring miniMetadata with chainId ${miniMetadata.chainId} in ${MODULE_TYPE$6}. Expected chainId is ${networkId}`);
|
|
2153
2159
|
return {
|
|
2154
2160
|
success: [],
|
|
2155
2161
|
errors: balanceDefs.map(def => ({
|
|
@@ -2169,7 +2175,7 @@ const fetchBalances$5 = async ({
|
|
|
2169
2175
|
address: def.address,
|
|
2170
2176
|
networkId,
|
|
2171
2177
|
tokenId: def.token.id,
|
|
2172
|
-
source: MODULE_TYPE$
|
|
2178
|
+
source: MODULE_TYPE$6,
|
|
2173
2179
|
status: "live",
|
|
2174
2180
|
values: [{
|
|
2175
2181
|
type: "free",
|
|
@@ -2188,7 +2194,7 @@ const fetchBalances$5 = async ({
|
|
|
2188
2194
|
});
|
|
2189
2195
|
};
|
|
2190
2196
|
|
|
2191
|
-
const fetchTokens$
|
|
2197
|
+
const fetchTokens$6 = async ({
|
|
2192
2198
|
networkId,
|
|
2193
2199
|
tokens,
|
|
2194
2200
|
connector,
|
|
@@ -2229,7 +2235,7 @@ const fetchTokens$5 = async ({
|
|
|
2229
2235
|
const configTokenByAssetId = keyBy(tokens, t => t.assetId);
|
|
2230
2236
|
return allTokens.map(asset => ({
|
|
2231
2237
|
id: subAssetTokenId(networkId, String(asset.assetId)),
|
|
2232
|
-
type: MODULE_TYPE$
|
|
2238
|
+
type: MODULE_TYPE$6,
|
|
2233
2239
|
platform: "polkadot",
|
|
2234
2240
|
networkId,
|
|
2235
2241
|
assetId: String(asset.assetId),
|
|
@@ -2260,6 +2266,374 @@ const fetchTokens$5 = async ({
|
|
|
2260
2266
|
});
|
|
2261
2267
|
};
|
|
2262
2268
|
|
|
2269
|
+
const MODULE_TYPE$5 = SubDTaoTokenSchema.shape.type.value;
|
|
2270
|
+
const PLATFORM$5 = SubDTaoTokenSchema.shape.platform.value;
|
|
2271
|
+
|
|
2272
|
+
const TAO_DECIMALS = 9n;
|
|
2273
|
+
|
|
2274
|
+
// manipulating price as bigint requires using at least as many decimals as TAO itself
|
|
2275
|
+
const ALPHA_PRICE_SCALE = 10n ** TAO_DECIMALS;
|
|
2276
|
+
const getScaledAlphaPrice = (alphaIn, taoIn) => {
|
|
2277
|
+
if (!alphaIn || !taoIn) return 0n;
|
|
2278
|
+
return taoIn * ALPHA_PRICE_SCALE / alphaIn;
|
|
2279
|
+
};
|
|
2280
|
+
const alphaToTao = (alpha, scaledAlphaPrice) => {
|
|
2281
|
+
if (!alpha || !scaledAlphaPrice) return 0n;
|
|
2282
|
+
return alpha * scaledAlphaPrice / ALPHA_PRICE_SCALE;
|
|
2283
|
+
};
|
|
2284
|
+
const taoToAlpha = (tao, scaledAlphaPrice) => {
|
|
2285
|
+
if (!tao || !scaledAlphaPrice) return 0n;
|
|
2286
|
+
return tao * ALPHA_PRICE_SCALE / scaledAlphaPrice;
|
|
2287
|
+
};
|
|
2288
|
+
|
|
2289
|
+
const fetchBalances$5 = async ({
|
|
2290
|
+
networkId,
|
|
2291
|
+
tokensWithAddresses,
|
|
2292
|
+
connector,
|
|
2293
|
+
miniMetadata
|
|
2294
|
+
}) => {
|
|
2295
|
+
if (!tokensWithAddresses.length) return {
|
|
2296
|
+
success: [],
|
|
2297
|
+
errors: []
|
|
2298
|
+
};
|
|
2299
|
+
const balanceDefs = getBalanceDefs(tokensWithAddresses);
|
|
2300
|
+
if (!miniMetadata?.data) {
|
|
2301
|
+
log.warn(`MiniMetadata is required for fetching ${MODULE_TYPE$5} balances on ${networkId}.`, {
|
|
2302
|
+
tokensWithAddresses
|
|
2303
|
+
});
|
|
2304
|
+
return {
|
|
2305
|
+
success: [],
|
|
2306
|
+
errors: balanceDefs.map(def => ({
|
|
2307
|
+
tokenId: def.token.id,
|
|
2308
|
+
address: def.address,
|
|
2309
|
+
error: new Error("Minimetadata is required for fetching balances")
|
|
2310
|
+
}))
|
|
2311
|
+
};
|
|
2312
|
+
}
|
|
2313
|
+
if (miniMetadata.source !== MODULE_TYPE$5) {
|
|
2314
|
+
log.warn(`Ignoring miniMetadata with source ${miniMetadata.source} in ${MODULE_TYPE$5}.`);
|
|
2315
|
+
return {
|
|
2316
|
+
success: [],
|
|
2317
|
+
errors: balanceDefs.map(def => ({
|
|
2318
|
+
tokenId: def.token.id,
|
|
2319
|
+
address: def.address,
|
|
2320
|
+
error: new Error(`Invalid request: miniMetadata source is not ${MODULE_TYPE$5}`)
|
|
2321
|
+
}))
|
|
2322
|
+
};
|
|
2323
|
+
}
|
|
2324
|
+
if (miniMetadata.chainId !== networkId) {
|
|
2325
|
+
log.warn(`Ignoring miniMetadata with chainId ${miniMetadata.chainId} in ${MODULE_TYPE$5}. Expected chainId is ${networkId}`);
|
|
2326
|
+
return {
|
|
2327
|
+
success: [],
|
|
2328
|
+
errors: balanceDefs.map(def => ({
|
|
2329
|
+
tokenId: def.token.id,
|
|
2330
|
+
address: def.address,
|
|
2331
|
+
error: new Error(`Invalid request: Expected chainId is ${networkId}`)
|
|
2332
|
+
}))
|
|
2333
|
+
};
|
|
2334
|
+
}
|
|
2335
|
+
const addresses = uniq(balanceDefs.map(def => def.address));
|
|
2336
|
+
try {
|
|
2337
|
+
const [stakeInfos, dynamicInfos] = await Promise.all([fetchRuntimeCallResult(connector, networkId, miniMetadata.data, "StakeInfoRuntimeApi", "get_stake_info_for_coldkeys", [addresses]), fetchRuntimeCallResult(connector, networkId, miniMetadata.data, "SubnetInfoRuntimeApi", "get_all_dynamic_info", [])]);
|
|
2338
|
+
const dynamicInfoByNetuid = keyBy(dynamicInfos.filter(isNotNil), info => info.netuid);
|
|
2339
|
+
const balances = stakeInfos.flatMap(([address, stakes]) => stakes.map(stake => {
|
|
2340
|
+
const dynamicInfo = dynamicInfoByNetuid[stake.netuid];
|
|
2341
|
+
const scaledAlphaPrice = dynamicInfo ? getScaledAlphaPrice(dynamicInfo.alpha_in, dynamicInfo.tao_in) : 0n;
|
|
2342
|
+
return {
|
|
2343
|
+
address,
|
|
2344
|
+
tokenId: subDTaoTokenId(networkId, stake.netuid, stake.hotkey),
|
|
2345
|
+
baseTokenId: subDTaoTokenId(networkId, stake.netuid),
|
|
2346
|
+
stake: stake.stake,
|
|
2347
|
+
hotkey: stake.hotkey,
|
|
2348
|
+
netuid: stake.netuid,
|
|
2349
|
+
scaledAlphaPrice
|
|
2350
|
+
};
|
|
2351
|
+
}));
|
|
2352
|
+
const tokensById = keyBy(tokensWithAddresses.map(([token]) => token), t => t.id);
|
|
2353
|
+
const dynamicTokens = [];
|
|
2354
|
+
|
|
2355
|
+
// identify tokens that were not requested but have balances
|
|
2356
|
+
// BalanceProvider will be register them in ChaindataProvider at runtime, so they will be requested on next call
|
|
2357
|
+
for (const bal of balances) {
|
|
2358
|
+
if (!balanceDefs.some(def => def.token.id === bal.tokenId)) {
|
|
2359
|
+
const baseToken = tokensById[bal.baseTokenId];
|
|
2360
|
+
// define a token specific to this staking hotkey
|
|
2361
|
+
if (baseToken) {
|
|
2362
|
+
const cleanToken = getCleanToken(baseToken);
|
|
2363
|
+
const newToken = TokenSchema.parse({
|
|
2364
|
+
...cleanToken,
|
|
2365
|
+
id: bal.tokenId,
|
|
2366
|
+
hotkey: bal.hotkey
|
|
2367
|
+
});
|
|
2368
|
+
dynamicTokens.push(newToken);
|
|
2369
|
+
}
|
|
2370
|
+
}
|
|
2371
|
+
}
|
|
2372
|
+
const success = balanceDefs.map(def => {
|
|
2373
|
+
const stake = balances.find(b => b.address === def.address && b.tokenId === def.token.id);
|
|
2374
|
+
const meta = {
|
|
2375
|
+
scaledAlphaPrice: stake?.scaledAlphaPrice.toString() ?? "0"
|
|
2376
|
+
};
|
|
2377
|
+
const balanceValue = {
|
|
2378
|
+
type: "free",
|
|
2379
|
+
label: stake?.netuid === 0 ? "Root Staking" : `Subnet Staking`,
|
|
2380
|
+
amount: stake?.stake.toString() ?? "0",
|
|
2381
|
+
meta
|
|
2382
|
+
};
|
|
2383
|
+
return {
|
|
2384
|
+
address: def.address,
|
|
2385
|
+
networkId,
|
|
2386
|
+
tokenId: def.token.id,
|
|
2387
|
+
source: MODULE_TYPE$5,
|
|
2388
|
+
status: "live",
|
|
2389
|
+
values: [balanceValue]
|
|
2390
|
+
};
|
|
2391
|
+
});
|
|
2392
|
+
return {
|
|
2393
|
+
success,
|
|
2394
|
+
errors: [],
|
|
2395
|
+
dynamicTokens
|
|
2396
|
+
};
|
|
2397
|
+
} catch (err) {
|
|
2398
|
+
log.warn("Failed to fetch balances for substrate-dtao", {
|
|
2399
|
+
err
|
|
2400
|
+
});
|
|
2401
|
+
const errors = balanceDefs.map(def => ({
|
|
2402
|
+
tokenId: def.token.id,
|
|
2403
|
+
address: def.address,
|
|
2404
|
+
error: new Error(`Failed to fetch balance for ${def.address} on ${networkId}`)
|
|
2405
|
+
}));
|
|
2406
|
+
return {
|
|
2407
|
+
success: [],
|
|
2408
|
+
errors
|
|
2409
|
+
};
|
|
2410
|
+
}
|
|
2411
|
+
};
|
|
2412
|
+
|
|
2413
|
+
// hardcoded because we dont have access to native tokens from the balance module
|
|
2414
|
+
const NATIVE_TOKEN_SYMBOLS = {
|
|
2415
|
+
"bittensor": "TAO",
|
|
2416
|
+
"bittensor-testnet": "testTAO"
|
|
2417
|
+
};
|
|
2418
|
+
const fetchTokens$5 = async ({
|
|
2419
|
+
networkId,
|
|
2420
|
+
connector,
|
|
2421
|
+
tokens,
|
|
2422
|
+
miniMetadata
|
|
2423
|
+
}) => {
|
|
2424
|
+
const anyMiniMetadata = miniMetadata;
|
|
2425
|
+
if (!anyMiniMetadata?.data) return [];
|
|
2426
|
+
const dynamicInfos = await fetchRuntimeCallResult(connector, networkId, anyMiniMetadata.data, "SubnetInfoRuntimeApi", "get_all_dynamic_info", []);
|
|
2427
|
+
return dynamicInfos.filter(isNotNil).map(info => {
|
|
2428
|
+
const config = tokens.find(t => t.netuid === info.netuid);
|
|
2429
|
+
let symbol = new TextDecoder().decode(Uint8Array.from(info.token_symbol));
|
|
2430
|
+
const subnetName = info.subnet_identity?.subnet_name?.asText() ?? (info.netuid === 0 ? "Root" : `Subnet ${info.netuid}`);
|
|
2431
|
+
const name = `SN${info.netuid} | ${subnetName} ${symbol}`;
|
|
2432
|
+
|
|
2433
|
+
// for root we want same symbol as native so they can be grouped together in portfolio
|
|
2434
|
+
if (info.netuid === 0 && NATIVE_TOKEN_SYMBOLS[networkId]) symbol = NATIVE_TOKEN_SYMBOLS[networkId];
|
|
2435
|
+
return Object.assign({}, {
|
|
2436
|
+
id: subDTaoTokenId(networkId, info.netuid),
|
|
2437
|
+
type: MODULE_TYPE$5,
|
|
2438
|
+
platform: PLATFORM$5,
|
|
2439
|
+
networkId,
|
|
2440
|
+
netuid: info.netuid,
|
|
2441
|
+
isDefault: true,
|
|
2442
|
+
symbol,
|
|
2443
|
+
decimals: 9,
|
|
2444
|
+
name,
|
|
2445
|
+
subnetName
|
|
2446
|
+
}, config);
|
|
2447
|
+
}).filter(t => {
|
|
2448
|
+
const parsed = SubDTaoTokenSchema.safeParse(t);
|
|
2449
|
+
return parsed.success;
|
|
2450
|
+
});
|
|
2451
|
+
};
|
|
2452
|
+
|
|
2453
|
+
const getMiniMetadata$6 = ({
|
|
2454
|
+
networkId,
|
|
2455
|
+
specVersion,
|
|
2456
|
+
metadataRpc
|
|
2457
|
+
}) => {
|
|
2458
|
+
const source = MODULE_TYPE$5;
|
|
2459
|
+
const chainId = networkId;
|
|
2460
|
+
const systemVersion = getConstantValue(metadataRpc, "System", "Version");
|
|
2461
|
+
if (specVersion !== systemVersion.spec_version) throw new Error(`specVersion mismatch: expected ${specVersion}, metadata got ${systemVersion.spec_version}`);
|
|
2462
|
+
const id = deriveMiniMetadataId({
|
|
2463
|
+
source,
|
|
2464
|
+
chainId,
|
|
2465
|
+
specVersion
|
|
2466
|
+
});
|
|
2467
|
+
const {
|
|
2468
|
+
unifiedMetadata
|
|
2469
|
+
} = parseMetadataRpc(metadataRpc);
|
|
2470
|
+
if (unifiedMetadata.version < 14) throw new Error(`Unsupported metadata version: ${unifiedMetadata.version}. Minimum required is 14.`);
|
|
2471
|
+
return {
|
|
2472
|
+
id,
|
|
2473
|
+
source,
|
|
2474
|
+
chainId,
|
|
2475
|
+
specVersion,
|
|
2476
|
+
version: MINIMETADATA_VERSION,
|
|
2477
|
+
data: getData$4(metadataRpc),
|
|
2478
|
+
extra: null
|
|
2479
|
+
};
|
|
2480
|
+
};
|
|
2481
|
+
const getData$4 = metadataRpc => {
|
|
2482
|
+
const {
|
|
2483
|
+
metadata,
|
|
2484
|
+
unifiedMetadata
|
|
2485
|
+
} = parseMetadataRpc(metadataRpc);
|
|
2486
|
+
const isBittensor = unifiedMetadata.pallets.some(({
|
|
2487
|
+
name
|
|
2488
|
+
}) => name === "SubtensorModule");
|
|
2489
|
+
if (!isBittensor) return null;
|
|
2490
|
+
compactMetadata(metadata, [
|
|
2491
|
+
// { pallet: "SubtensorModule", items: ["StakingHotkeys", "Stake"] }
|
|
2492
|
+
], [{
|
|
2493
|
+
runtimeApi: "StakeInfoRuntimeApi",
|
|
2494
|
+
methods: ["get_stake_info_for_coldkeys"]
|
|
2495
|
+
}, {
|
|
2496
|
+
runtimeApi: "SubnetInfoRuntimeApi",
|
|
2497
|
+
methods: ["get_all_dynamic_info"]
|
|
2498
|
+
}]);
|
|
2499
|
+
return encodeMetadata(metadata);
|
|
2500
|
+
};
|
|
2501
|
+
|
|
2502
|
+
const getTransferCallData$6 = ({
|
|
2503
|
+
from,
|
|
2504
|
+
to,
|
|
2505
|
+
value,
|
|
2506
|
+
token,
|
|
2507
|
+
metadataRpc
|
|
2508
|
+
}) => {
|
|
2509
|
+
if (!isTokenOfType(token, MODULE_TYPE$5)) throw new Error(`Token type ${token.type} is not ${MODULE_TYPE$5}.`);
|
|
2510
|
+
const {
|
|
2511
|
+
netuid: subnetId,
|
|
2512
|
+
hotkey
|
|
2513
|
+
} = parseSubDTaoTokenId(token.id);
|
|
2514
|
+
if (!hotkey) throw new Error(`Missing hotkey`);
|
|
2515
|
+
const {
|
|
2516
|
+
builder
|
|
2517
|
+
} = parseMetadataRpc(metadataRpc);
|
|
2518
|
+
const {
|
|
2519
|
+
codec,
|
|
2520
|
+
location
|
|
2521
|
+
} = builder.buildCall("SubtensorModule", "transfer_stake");
|
|
2522
|
+
const args = codec.enc({
|
|
2523
|
+
origin_netuid: subnetId,
|
|
2524
|
+
hotkey,
|
|
2525
|
+
destination_coldkey: to,
|
|
2526
|
+
destination_netuid: subnetId,
|
|
2527
|
+
alpha_amount: value
|
|
2528
|
+
});
|
|
2529
|
+
const callData = Binary.fromBytes(mergeUint8([new Uint8Array(location), args]));
|
|
2530
|
+
return {
|
|
2531
|
+
address: from,
|
|
2532
|
+
method: callData.asHex()
|
|
2533
|
+
};
|
|
2534
|
+
};
|
|
2535
|
+
|
|
2536
|
+
const SUBSCRIPTION_INTERVAL$2 = 6_000;
|
|
2537
|
+
const subscribeBalances$6 = ({
|
|
2538
|
+
networkId,
|
|
2539
|
+
tokensWithAddresses,
|
|
2540
|
+
connector,
|
|
2541
|
+
miniMetadata
|
|
2542
|
+
}) => {
|
|
2543
|
+
if (!tokensWithAddresses.length) return of({
|
|
2544
|
+
success: [],
|
|
2545
|
+
errors: []
|
|
2546
|
+
});
|
|
2547
|
+
return new Observable(subscriber => {
|
|
2548
|
+
const abortController = new AbortController();
|
|
2549
|
+
|
|
2550
|
+
// on hydration balances are fetched using a runtimeApi, which can't be subscribed to.
|
|
2551
|
+
// => poll values for each block
|
|
2552
|
+
const poll = async () => {
|
|
2553
|
+
try {
|
|
2554
|
+
if (abortController.signal.aborted) return;
|
|
2555
|
+
const balances = await fetchBalances$5({
|
|
2556
|
+
networkId,
|
|
2557
|
+
tokensWithAddresses: tokensWithAddresses,
|
|
2558
|
+
connector,
|
|
2559
|
+
miniMetadata
|
|
2560
|
+
});
|
|
2561
|
+
if (abortController.signal.aborted) return;
|
|
2562
|
+
subscriber.next(balances);
|
|
2563
|
+
setTimeout(poll, SUBSCRIPTION_INTERVAL$2);
|
|
2564
|
+
} catch (error) {
|
|
2565
|
+
log.error("Error", {
|
|
2566
|
+
module: MODULE_TYPE$5,
|
|
2567
|
+
networkId,
|
|
2568
|
+
miniMetadata,
|
|
2569
|
+
addressesByToken: tokensWithAddresses,
|
|
2570
|
+
error
|
|
2571
|
+
});
|
|
2572
|
+
subscriber.error(error);
|
|
2573
|
+
}
|
|
2574
|
+
};
|
|
2575
|
+
poll();
|
|
2576
|
+
return () => {
|
|
2577
|
+
abortController.abort();
|
|
2578
|
+
};
|
|
2579
|
+
}).pipe(distinctUntilChanged(isEqual));
|
|
2580
|
+
};
|
|
2581
|
+
|
|
2582
|
+
const SubDTaoBalanceModule = {
|
|
2583
|
+
type: MODULE_TYPE$5,
|
|
2584
|
+
platform: PLATFORM$5,
|
|
2585
|
+
getMiniMetadata: getMiniMetadata$6,
|
|
2586
|
+
fetchTokens: fetchTokens$5,
|
|
2587
|
+
fetchBalances: fetchBalances$5,
|
|
2588
|
+
subscribeBalances: subscribeBalances$6,
|
|
2589
|
+
getTransferCallData: getTransferCallData$6
|
|
2590
|
+
};
|
|
2591
|
+
|
|
2592
|
+
// to be used by chaindata too
|
|
2593
|
+
const SubDTaoTokenConfigSchema = z.strictObject({
|
|
2594
|
+
netuid: SubDTaoTokenSchema.shape.netuid,
|
|
2595
|
+
...TokenConfigBaseSchema.shape
|
|
2596
|
+
});
|
|
2597
|
+
|
|
2598
|
+
const ONE_ALPHA = 10n ** TAO_DECIMALS;
|
|
2599
|
+
|
|
2600
|
+
/**
|
|
2601
|
+
* To be used for tokens that don't have a coingecko id
|
|
2602
|
+
*
|
|
2603
|
+
* @param token
|
|
2604
|
+
* @param tokenRates
|
|
2605
|
+
* @param scaledAlphaPrice
|
|
2606
|
+
* @returns
|
|
2607
|
+
*/
|
|
2608
|
+
const getDTaoTokenRates = (token, tokenRates, scaledAlphaPrice) => {
|
|
2609
|
+
try {
|
|
2610
|
+
const taoTokenId = subNativeTokenId(token.networkId);
|
|
2611
|
+
const taoTokenRates = tokenRates[taoTokenId];
|
|
2612
|
+
if (!taoTokenRates) return null;
|
|
2613
|
+
|
|
2614
|
+
// for root subnet, same rates as TAO
|
|
2615
|
+
if (token.netuid === 0) return structuredClone(taoTokenRates);
|
|
2616
|
+
const alphaRates = newTokenRates();
|
|
2617
|
+
for (const [currency, taoRate] of Object.entries(taoTokenRates)) {
|
|
2618
|
+
if (!taoRate) {
|
|
2619
|
+
alphaRates[currency] = null;
|
|
2620
|
+
} else {
|
|
2621
|
+
const taoPrice = alphaToTao(ONE_ALPHA, BigInt(scaledAlphaPrice));
|
|
2622
|
+
const priceRatio = Number(taoPrice) / Number(ALPHA_PRICE_SCALE);
|
|
2623
|
+
alphaRates[currency] = {
|
|
2624
|
+
price: taoRate.price * priceRatio,
|
|
2625
|
+
marketCap: taoRate.marketCap ? taoRate.marketCap * priceRatio : undefined,
|
|
2626
|
+
change24h: undefined // cannot be determined from TAO rates alone
|
|
2627
|
+
};
|
|
2628
|
+
}
|
|
2629
|
+
}
|
|
2630
|
+
return alphaRates;
|
|
2631
|
+
} catch (err) {
|
|
2632
|
+
log.error(err);
|
|
2633
|
+
return null;
|
|
2634
|
+
}
|
|
2635
|
+
};
|
|
2636
|
+
|
|
2263
2637
|
function excludeFromTransferableAmount(locks) {
|
|
2264
2638
|
if (typeof locks === "string") return BigInt(locks);
|
|
2265
2639
|
if (!Array.isArray(locks)) locks = [locks];
|
|
@@ -2588,6 +2962,16 @@ class Balance {
|
|
|
2588
2962
|
return lpTokenRates;
|
|
2589
2963
|
}
|
|
2590
2964
|
|
|
2965
|
+
// dTAO balances need to be converted to the native token to compute their rate, unless we have a coingeckoId
|
|
2966
|
+
if (this.token?.type === "substrate-dtao" && !this.token.coingeckoId) {
|
|
2967
|
+
if (!this.#db?.tokenRates) return null;
|
|
2968
|
+
const balances = this.#valueGetter.get("free");
|
|
2969
|
+
if (!balances.length) return null;
|
|
2970
|
+
const balanceMeta = balances[0].meta;
|
|
2971
|
+
if (!balanceMeta?.scaledAlphaPrice) return null;
|
|
2972
|
+
return getDTaoTokenRates(this.token, this.#db.tokenRates, balanceMeta.scaledAlphaPrice);
|
|
2973
|
+
}
|
|
2974
|
+
|
|
2591
2975
|
// other tokens can just pick from the tokenRates db using the tokenId
|
|
2592
2976
|
return this.#db?.tokenRates && this.#db.tokenRates[this.tokenId] || null;
|
|
2593
2977
|
}
|
|
@@ -2634,9 +3018,7 @@ class Balance {
|
|
|
2634
3018
|
const nomPoolStakedPlancks = this.locks.some(lock => lock.source === "substrate-native-holds" && lock.label === "DelegatedStaking") ? 0n : this.nompools.map(({
|
|
2635
3019
|
amount
|
|
2636
3020
|
}) => amount.planck).reduce((a, b) => a + b, 0n);
|
|
2637
|
-
return this.#format(this.free.planck + this.reserved.planck + nomPoolStakedPlancks +
|
|
2638
|
-
amount
|
|
2639
|
-
}) => amount.planck).reduce((a, b) => a + b, 0n) + includeInTotalExtraAmount(extra));
|
|
3021
|
+
return this.#format(this.free.planck + this.reserved.planck + nomPoolStakedPlancks + includeInTotalExtraAmount(extra));
|
|
2640
3022
|
}
|
|
2641
3023
|
/** The non-reserved balance of this token. Includes the frozen amount. Is included in the total. */
|
|
2642
3024
|
get free() {
|
|
@@ -2673,9 +3055,6 @@ class Balance {
|
|
|
2673
3055
|
get nompools() {
|
|
2674
3056
|
return this.getValue("nompool");
|
|
2675
3057
|
}
|
|
2676
|
-
get subtensor() {
|
|
2677
|
-
return this.getValue("subtensor");
|
|
2678
|
-
}
|
|
2679
3058
|
|
|
2680
3059
|
/** The extra balance of this token */
|
|
2681
3060
|
get extra() {
|
|
@@ -2748,8 +3127,7 @@ class Balance {
|
|
|
2748
3127
|
const nomPoolStakedPlancks = this.locks.some(lock => lock.source === "substrate-native-holds" && lock.label === "DelegatedStaking") ? 0n : this.nompools.map(({
|
|
2749
3128
|
amount
|
|
2750
3129
|
}) => amount.planck).reduce((a, b) => a + b, 0n);
|
|
2751
|
-
|
|
2752
|
-
return this.#format(baseUnavailable + otherUnavailable);
|
|
3130
|
+
return this.#format(baseUnavailable + nomPoolStakedPlancks);
|
|
2753
3131
|
}
|
|
2754
3132
|
|
|
2755
3133
|
/** The feePayable balance of this token. Is generally the free amount - the feeFrozen amount. */
|
|
@@ -2996,13 +3374,6 @@ const getValueId = amount => {
|
|
|
2996
3374
|
const meta = amount.meta;
|
|
2997
3375
|
if (!meta) return "";
|
|
2998
3376
|
if (amount.type === "nompool") return meta.poolId?.toString() ?? "";
|
|
2999
|
-
if (amount.type === "subtensor") {
|
|
3000
|
-
const {
|
|
3001
|
-
hotkey,
|
|
3002
|
-
netuid
|
|
3003
|
-
} = meta;
|
|
3004
|
-
if (hotkey && netuid !== undefined) return `${hotkey.toString()}${netuid.toString()}`;
|
|
3005
|
-
}
|
|
3006
3377
|
return "";
|
|
3007
3378
|
};
|
|
3008
3379
|
return [amount.label, amount.type, amount.source, getMetaId()].join("::");
|
|
@@ -3024,7 +3395,7 @@ const getMiniMetadata$5 = ({
|
|
|
3024
3395
|
specVersion,
|
|
3025
3396
|
metadataRpc
|
|
3026
3397
|
}) => {
|
|
3027
|
-
const source = MODULE_TYPE$
|
|
3398
|
+
const source = MODULE_TYPE$6;
|
|
3028
3399
|
const chainId = networkId;
|
|
3029
3400
|
const systemVersion = getConstantValue(metadataRpc, "System", "Version");
|
|
3030
3401
|
if (specVersion !== systemVersion.spec_version) throw new Error(`specVersion mismatch: expected ${specVersion}, metadata got ${systemVersion.spec_version}`);
|
|
@@ -3070,7 +3441,7 @@ const getTransferCallData$5 = ({
|
|
|
3070
3441
|
type,
|
|
3071
3442
|
metadataRpc
|
|
3072
3443
|
}) => {
|
|
3073
|
-
if (!isTokenOfType(token, MODULE_TYPE$
|
|
3444
|
+
if (!isTokenOfType(token, MODULE_TYPE$6)) throw new Error(`Token type ${token.type} is not ${MODULE_TYPE$6}.`);
|
|
3074
3445
|
const {
|
|
3075
3446
|
builder
|
|
3076
3447
|
} = parseMetadataRpc(metadataRpc);
|
|
@@ -3087,6 +3458,7 @@ const getTransferCallData$5 = ({
|
|
|
3087
3458
|
};
|
|
3088
3459
|
};
|
|
3089
3460
|
const getTransferMethod$3 = type => {
|
|
3461
|
+
// TODO handle the case where transfer_all does not exist
|
|
3090
3462
|
switch (type) {
|
|
3091
3463
|
case "keep-alive":
|
|
3092
3464
|
return "transfer_keep_alive";
|
|
@@ -3132,6 +3504,11 @@ const getTransferEncodedArgs$2 = (assetId, to, value, codec) => {
|
|
|
3132
3504
|
// for Astar
|
|
3133
3505
|
target: Enum("Id", to),
|
|
3134
3506
|
amount: BigInt(value)
|
|
3507
|
+
}), () => ({
|
|
3508
|
+
id: BigInt(assetId),
|
|
3509
|
+
// for Neuroweb
|
|
3510
|
+
target: to,
|
|
3511
|
+
amount: BigInt(value)
|
|
3135
3512
|
})]);
|
|
3136
3513
|
};
|
|
3137
3514
|
const getTransferAllEncodedArgs$2 = (assetId, to, codec) => {
|
|
@@ -3145,6 +3522,11 @@ const getTransferAllEncodedArgs$2 = (assetId, to, codec) => {
|
|
|
3145
3522
|
// for Astar
|
|
3146
3523
|
dest: Enum("Id", to),
|
|
3147
3524
|
keep_alive: false
|
|
3525
|
+
}), () => ({
|
|
3526
|
+
id: BigInt(assetId),
|
|
3527
|
+
// for Neuroweb (although transfer_all does not exist)
|
|
3528
|
+
dest: to,
|
|
3529
|
+
keep_alive: false
|
|
3148
3530
|
})]);
|
|
3149
3531
|
};
|
|
3150
3532
|
|
|
@@ -3167,11 +3549,11 @@ const subscribeBalances$5 = ({
|
|
|
3167
3549
|
};
|
|
3168
3550
|
|
|
3169
3551
|
const SubAssetsBalanceModule = {
|
|
3170
|
-
type: MODULE_TYPE$
|
|
3171
|
-
platform: PLATFORM$
|
|
3552
|
+
type: MODULE_TYPE$6,
|
|
3553
|
+
platform: PLATFORM$6,
|
|
3172
3554
|
getMiniMetadata: getMiniMetadata$5,
|
|
3173
|
-
fetchTokens: fetchTokens$
|
|
3174
|
-
fetchBalances: fetchBalances$
|
|
3555
|
+
fetchTokens: fetchTokens$6,
|
|
3556
|
+
fetchBalances: fetchBalances$6,
|
|
3175
3557
|
subscribeBalances: subscribeBalances$5,
|
|
3176
3558
|
getTransferCallData: getTransferCallData$5
|
|
3177
3559
|
};
|
|
@@ -3515,6 +3897,11 @@ const getTransferEncodedArgs$1 = (onChainId, to, value, codec) => {
|
|
|
3515
3897
|
// for most networks
|
|
3516
3898
|
target: Enum("Id", to),
|
|
3517
3899
|
amount: BigInt(value)
|
|
3900
|
+
}), () => ({
|
|
3901
|
+
id: papiParse(onChainId),
|
|
3902
|
+
// for Neuroweb
|
|
3903
|
+
target: to,
|
|
3904
|
+
amount: BigInt(value)
|
|
3518
3905
|
})]);
|
|
3519
3906
|
};
|
|
3520
3907
|
const getTransferAllEncodedArgs$1 = (onChainId, to, codec) => {
|
|
@@ -3523,6 +3910,11 @@ const getTransferAllEncodedArgs$1 = (onChainId, to, codec) => {
|
|
|
3523
3910
|
// for most networks
|
|
3524
3911
|
dest: Enum("Id", to),
|
|
3525
3912
|
keep_alive: false
|
|
3913
|
+
}), () => ({
|
|
3914
|
+
id: papiParse(onChainId),
|
|
3915
|
+
// for Neuroweb
|
|
3916
|
+
dest: to,
|
|
3917
|
+
keep_alive: false
|
|
3526
3918
|
})]);
|
|
3527
3919
|
};
|
|
3528
3920
|
|
|
@@ -3882,154 +4274,6 @@ const SubHydrationBalanceModule = {
|
|
|
3882
4274
|
const MODULE_TYPE$2 = SubNativeTokenSchema.shape.type.value;
|
|
3883
4275
|
const PLATFORM$2 = SubNativeTokenSchema.shape.platform.value;
|
|
3884
4276
|
|
|
3885
|
-
const SUBTENSOR_ROOT_NETUID = 0;
|
|
3886
|
-
const SUBTENSOR_MIN_STAKE_AMOUNT_PLANK = 1000000n;
|
|
3887
|
-
const TAO_DECIMALS = 9n;
|
|
3888
|
-
const SCALE_FACTOR = 10n ** TAO_DECIMALS; // Equivalent to 10e9 for precision
|
|
3889
|
-
const ONE_ALPHA_TOKEN = SCALE_FACTOR;
|
|
3890
|
-
const calculateAlphaPrice = ({
|
|
3891
|
-
dynamicInfo
|
|
3892
|
-
}) => {
|
|
3893
|
-
if (!dynamicInfo) return 0n;
|
|
3894
|
-
const {
|
|
3895
|
-
alpha_in,
|
|
3896
|
-
tao_in
|
|
3897
|
-
} = dynamicInfo;
|
|
3898
|
-
|
|
3899
|
-
// Scale taoIn before division to preserve precision
|
|
3900
|
-
const result = tao_in * SCALE_FACTOR / alpha_in;
|
|
3901
|
-
return result; // Scaled price as bigint
|
|
3902
|
-
};
|
|
3903
|
-
const calculateTaoAmountFromAlpha = ({
|
|
3904
|
-
alphaPrice,
|
|
3905
|
-
alphaStaked
|
|
3906
|
-
}) => {
|
|
3907
|
-
if (!alphaStaked || !alphaPrice) return 0n;
|
|
3908
|
-
const expectedAlpha = alphaStaked * alphaPrice;
|
|
3909
|
-
return expectedAlpha / SCALE_FACTOR;
|
|
3910
|
-
};
|
|
3911
|
-
const calculateTaoFromDynamicInfo = ({
|
|
3912
|
-
dynamicInfo,
|
|
3913
|
-
alphaStaked
|
|
3914
|
-
}) => {
|
|
3915
|
-
const alphaPrice = calculateAlphaPrice({
|
|
3916
|
-
dynamicInfo
|
|
3917
|
-
});
|
|
3918
|
-
return calculateTaoAmountFromAlpha({
|
|
3919
|
-
alphaPrice,
|
|
3920
|
-
alphaStaked
|
|
3921
|
-
});
|
|
3922
|
-
};
|
|
3923
|
-
|
|
3924
|
-
// per address, lists of values to add to the native balance
|
|
3925
|
-
|
|
3926
|
-
const getSubtensorStakingBalances$ = (connector, networkId, balanceDefs, miniMetadata) => {
|
|
3927
|
-
const addresses = balanceDefs.map(def => def.address);
|
|
3928
|
-
const token = balanceDefs[0].token;
|
|
3929
|
-
if (!addresses.length || !token || !miniMetadata.extra.hasSubtensorPallet || !miniMetadata.data) return of({});
|
|
3930
|
-
|
|
3931
|
-
// we are only doing runtime calls, there is no way to subscribe to changes, except polling
|
|
3932
|
-
// => start immediately, then repeat every 30 seconds
|
|
3933
|
-
return timer(0, 30000).pipe(switchMap(() => from(fetchStakeInfoByAddress(connector, networkId, miniMetadata, addresses)).pipe(switchMap(stakeInfoByAddress => fetchStakingBalanceValuesByAddress(connector, networkId, miniMetadata, stakeInfoByAddress)))));
|
|
3934
|
-
};
|
|
3935
|
-
const fetchStakingBalanceValuesByAddress = async (connector, networkId, miniMetadata, stakeInfoByAddress) => {
|
|
3936
|
-
const uniqueNetuids = uniq(values(stakeInfoByAddress).flatMap(infos => infos.map(info => info.netuid))).filter(netuid => netuid !== SUBTENSOR_ROOT_NETUID);
|
|
3937
|
-
const dynamicInfoByNetuid = await fetchDynamicInfoByNetuid(connector, networkId, miniMetadata, uniqueNetuids);
|
|
3938
|
-
return fromPairs(toPairs(stakeInfoByAddress).map(([address, stakeInfos]) => {
|
|
3939
|
-
const stakesBalances = stakeInfos.filter(({
|
|
3940
|
-
stake
|
|
3941
|
-
}) => stake >= SUBTENSOR_MIN_STAKE_AMOUNT_PLANK).map(({
|
|
3942
|
-
hotkey,
|
|
3943
|
-
netuid,
|
|
3944
|
-
stake
|
|
3945
|
-
}) => ({
|
|
3946
|
-
hotkey,
|
|
3947
|
-
netuid: Number(netuid),
|
|
3948
|
-
stake: BigInt(stake),
|
|
3949
|
-
dynamicInfo: dynamicInfoByNetuid[Number(netuid)]
|
|
3950
|
-
})).map(({
|
|
3951
|
-
hotkey,
|
|
3952
|
-
stake,
|
|
3953
|
-
netuid,
|
|
3954
|
-
dynamicInfo
|
|
3955
|
-
}) => {
|
|
3956
|
-
const {
|
|
3957
|
-
token_symbol,
|
|
3958
|
-
subnet_name,
|
|
3959
|
-
subnet_identity
|
|
3960
|
-
} = dynamicInfo ?? {};
|
|
3961
|
-
const tokenSymbol = new TextDecoder().decode(Uint8Array.from(token_symbol ?? []));
|
|
3962
|
-
const subnetName = new TextDecoder().decode(Uint8Array.from(subnet_name ?? []));
|
|
3963
|
-
const subnetIdentity = subnet_identity ? fromPairs(toPairs(subnet_identity).map(([key, binary]) => [key, binary.asText()])) : undefined;
|
|
3964
|
-
|
|
3965
|
-
// Add 1n balance if failed to fetch dynamic info, so the position is not ignored by Balance lib and is displayed in the UI.
|
|
3966
|
-
const alphaStakedInTao = dynamicInfo ? calculateTaoFromDynamicInfo({
|
|
3967
|
-
dynamicInfo,
|
|
3968
|
-
alphaStaked: stake
|
|
3969
|
-
}) : 1n;
|
|
3970
|
-
const alphaToTaoRate = calculateTaoFromDynamicInfo({
|
|
3971
|
-
dynamicInfo: dynamicInfo ?? null,
|
|
3972
|
-
alphaStaked: ONE_ALPHA_TOKEN
|
|
3973
|
-
}).toString();
|
|
3974
|
-
const stakeByNetuid = Number(netuid) === SUBTENSOR_ROOT_NETUID ? stake : alphaStakedInTao;
|
|
3975
|
-
const balanceValue = {
|
|
3976
|
-
source: "subtensor-staking",
|
|
3977
|
-
type: "subtensor",
|
|
3978
|
-
label: "subtensor-staking",
|
|
3979
|
-
amount: stakeByNetuid.toString(),
|
|
3980
|
-
meta: {
|
|
3981
|
-
type: "subtensor-staking",
|
|
3982
|
-
hotkey,
|
|
3983
|
-
netuid,
|
|
3984
|
-
amountStaked: stake.toString(),
|
|
3985
|
-
alphaToTaoRate,
|
|
3986
|
-
dynamicInfo: {
|
|
3987
|
-
tokenSymbol,
|
|
3988
|
-
subnetName,
|
|
3989
|
-
subnetIdentity: {
|
|
3990
|
-
...subnetIdentity,
|
|
3991
|
-
subnetName: subnetIdentity?.subnet_name || subnetName
|
|
3992
|
-
}
|
|
3993
|
-
}
|
|
3994
|
-
}
|
|
3995
|
-
};
|
|
3996
|
-
return balanceValue;
|
|
3997
|
-
});
|
|
3998
|
-
return [address, stakesBalances];
|
|
3999
|
-
}));
|
|
4000
|
-
};
|
|
4001
|
-
const fetchStakeInfoByAddress = async (connector, networkId, miniMetadata, addresses) => {
|
|
4002
|
-
const pairs = await Promise.all(addresses.map(async address => [address, await withRetry(() => fetchRuntimeCallResult(connector, networkId, miniMetadata.data, "StakeInfoRuntimeApi", "get_stake_info_for_coldkey", [address]), {
|
|
4003
|
-
delay: 500,
|
|
4004
|
-
retryCount: 3
|
|
4005
|
-
})]));
|
|
4006
|
-
return fromPairs(pairs);
|
|
4007
|
-
};
|
|
4008
|
-
|
|
4009
|
-
// assume dynamic info doesnt change over the course of a browser session
|
|
4010
|
-
const dynamicInfoCache = new Map();
|
|
4011
|
-
const getCacheKey$1 = (networkId, netuid) => `${networkId}:${netuid}`;
|
|
4012
|
-
const fetchDynamicInfoByNetuid = async (connector, networkId, miniMetadata, uniqueNetuids) => {
|
|
4013
|
-
const fetchInfo = async netuid => {
|
|
4014
|
-
if (netuid === SUBTENSOR_ROOT_NETUID) return null;
|
|
4015
|
-
const cacheKey = getCacheKey$1(networkId, netuid);
|
|
4016
|
-
if (!dynamicInfoCache.has(cacheKey)) {
|
|
4017
|
-
await withRetry(async () => {
|
|
4018
|
-
const result = await fetchRuntimeCallResult(connector, networkId, miniMetadata.data, "SubnetInfoRuntimeApi", "get_dynamic_info", [netuid]);
|
|
4019
|
-
dynamicInfoCache.set(cacheKey, result); // Cache successful response
|
|
4020
|
-
|
|
4021
|
-
return result;
|
|
4022
|
-
}, {
|
|
4023
|
-
delay: 500,
|
|
4024
|
-
retryCount: 3
|
|
4025
|
-
});
|
|
4026
|
-
}
|
|
4027
|
-
return dynamicInfoCache.get(cacheKey) ?? null;
|
|
4028
|
-
};
|
|
4029
|
-
const results = await Promise.all(uniqueNetuids.map(async netuid => [netuid, await fetchInfo(netuid)]));
|
|
4030
|
-
return fromPairs(results);
|
|
4031
|
-
};
|
|
4032
|
-
|
|
4033
4277
|
const getOtherType = input => `other-${input}`;
|
|
4034
4278
|
|
|
4035
4279
|
/**
|
|
@@ -4470,17 +4714,6 @@ const fetchBalances$2 = async ({
|
|
|
4470
4714
|
// now for each balance that includes nomPoolStaking, we need to fetch the metadata for the pool
|
|
4471
4715
|
const nomPoolQueries = buildNomPoolQueries(networkId, partialBalances, miniMetadata);
|
|
4472
4716
|
const balances = await fetchRpcQueryPack(connector, networkId, nomPoolQueries);
|
|
4473
|
-
|
|
4474
|
-
// TODO ⚠️ dedupe locks
|
|
4475
|
-
|
|
4476
|
-
const subtensorBalances$ = getSubtensorStakingBalances$(connector, networkId, balanceDefs, miniMetadata);
|
|
4477
|
-
const subtensorBalancesByAddress = await firstValueFrom(subtensorBalances$);
|
|
4478
|
-
for (const [address, subtensorBalances] of Object.entries(subtensorBalancesByAddress)) {
|
|
4479
|
-
const balance = balances.find(b => b.address === address);
|
|
4480
|
-
if (balance?.values) balance.values = [...balance.values.filter(({
|
|
4481
|
-
source
|
|
4482
|
-
}) => source !== "subtensor-staking"), ...subtensorBalances];
|
|
4483
|
-
}
|
|
4484
4717
|
return {
|
|
4485
4718
|
success: balances,
|
|
4486
4719
|
errors: []
|
|
@@ -4569,7 +4802,6 @@ const getMiniMetadata$2 = ({
|
|
|
4569
4802
|
};
|
|
4570
4803
|
const existentialDeposit = tryGetConstantValue(metadataRpc, "Balances", "ExistentialDeposit")?.toString();
|
|
4571
4804
|
const nominationPoolsPalletId = tryGetConstantValue(metadataRpc, "NominationPools", "PalletId")?.asText();
|
|
4572
|
-
const hasSubtensorPallet = !!tryGetConstantValue(metadataRpc, "SubtensorModule", "KeySwapCost");
|
|
4573
4805
|
const hasFreezesItem = Boolean(unifiedMetadata.pallets.find(({
|
|
4574
4806
|
name
|
|
4575
4807
|
}) => name === "Balances")?.storage?.items.find(({
|
|
@@ -4589,15 +4821,6 @@ const getMiniMetadata$2 = ({
|
|
|
4589
4821
|
}, {
|
|
4590
4822
|
pallet: "Staking",
|
|
4591
4823
|
items: ["Ledger"]
|
|
4592
|
-
}, {
|
|
4593
|
-
pallet: "SubtensorModule",
|
|
4594
|
-
items: ["StakingHotkeys", "Stake"]
|
|
4595
|
-
}], [{
|
|
4596
|
-
runtimeApi: "StakeInfoRuntimeApi",
|
|
4597
|
-
methods: ["get_stake_info_for_coldkey"]
|
|
4598
|
-
}, {
|
|
4599
|
-
runtimeApi: "SubnetInfoRuntimeApi",
|
|
4600
|
-
methods: ["get_dynamic_info"]
|
|
4601
4824
|
}]);
|
|
4602
4825
|
return {
|
|
4603
4826
|
id,
|
|
@@ -4609,8 +4832,7 @@ const getMiniMetadata$2 = ({
|
|
|
4609
4832
|
extra: {
|
|
4610
4833
|
useLegacyTransferableCalculation,
|
|
4611
4834
|
existentialDeposit,
|
|
4612
|
-
nominationPoolsPalletId
|
|
4613
|
-
hasSubtensorPallet
|
|
4835
|
+
nominationPoolsPalletId
|
|
4614
4836
|
}
|
|
4615
4837
|
};
|
|
4616
4838
|
};
|
|
@@ -4720,19 +4942,12 @@ const subscribeBalances$2 = ({
|
|
|
4720
4942
|
// could be use as shared observable key if we decide to cache the sub
|
|
4721
4943
|
const balanceDefs = getBalanceDefs(tokensWithAddresses);
|
|
4722
4944
|
const baseQueries = buildBaseQueries(networkId, balanceDefs, miniMetadata);
|
|
4723
|
-
|
|
4945
|
+
return getRpcQueryPack$(connector, networkId, baseQueries).pipe(switchMap(partialBalances => {
|
|
4724
4946
|
// now for each balance that includes nomPoolStaking, we need to fetch the metadata for the pool
|
|
4725
4947
|
const nomPoolQueries = buildNomPoolQueries(networkId, partialBalances, miniMetadata);
|
|
4726
4948
|
return getRpcQueryPack$(connector, networkId, nomPoolQueries);
|
|
4727
|
-
})
|
|
4728
|
-
|
|
4729
|
-
return combineLatest([baseBalances$, subtensorBalancesByAddress$]).pipe(map(([baseBalances, subtensorBalancesByAddress]) => ({
|
|
4730
|
-
success: [...baseBalances.map(b => ({
|
|
4731
|
-
...b,
|
|
4732
|
-
values: [...(b.values?.filter(({
|
|
4733
|
-
source
|
|
4734
|
-
}) => source !== "subtensor-staking") ?? []), ...(subtensorBalancesByAddress[b.address] ?? [])]
|
|
4735
|
-
}))],
|
|
4949
|
+
}), map(balances => ({
|
|
4950
|
+
success: balances,
|
|
4736
4951
|
errors: []
|
|
4737
4952
|
})));
|
|
4738
4953
|
};
|
|
@@ -4764,8 +4979,7 @@ const SubNativeMiniMetadataExtraSchema = z.strictObject({
|
|
|
4764
4979
|
disable: z.boolean().optional(),
|
|
4765
4980
|
useLegacyTransferableCalculation: z.boolean().optional(),
|
|
4766
4981
|
existentialDeposit: z.string().optional(),
|
|
4767
|
-
nominationPoolsPalletId: z.string().optional()
|
|
4768
|
-
hasSubtensorPallet: z.boolean().optional()
|
|
4982
|
+
nominationPoolsPalletId: z.string().optional()
|
|
4769
4983
|
});
|
|
4770
4984
|
|
|
4771
4985
|
// Do not use this type outside of this module
|
|
@@ -6568,7 +6782,7 @@ const SubTokensMiniMetadataExtraSchema = z.strictObject({
|
|
|
6568
6782
|
palletId: z.string()
|
|
6569
6783
|
});
|
|
6570
6784
|
|
|
6571
|
-
const BALANCE_MODULES = [SubNativeBalanceModule, SubAssetsBalanceModule, SubHydrationBalanceModule, SubForeignAssetsBalanceModule, SubPsp22BalanceModule, SubTokensBalanceModule, EvmErc20BalanceModule, EvmUniswapV2BalanceModule, EvmNativeBalanceModule, SolNativeBalanceModule, SolSplBalanceModule];
|
|
6785
|
+
const BALANCE_MODULES = [SubNativeBalanceModule, SubAssetsBalanceModule, SubDTaoBalanceModule, SubHydrationBalanceModule, SubForeignAssetsBalanceModule, SubPsp22BalanceModule, SubTokensBalanceModule, EvmErc20BalanceModule, EvmUniswapV2BalanceModule, EvmNativeBalanceModule, SolNativeBalanceModule, SolSplBalanceModule];
|
|
6572
6786
|
|
|
6573
6787
|
// share requests as all modules will call this at once
|
|
6574
6788
|
const CACHE$1 = new Map();
|
|
@@ -6810,7 +7024,12 @@ class BalancesProvider {
|
|
|
6810
7024
|
miniMetadata: miniMetadata
|
|
6811
7025
|
})), catchError(() => EMPTY),
|
|
6812
7026
|
// don't emit, let provider mark balances stale
|
|
6813
|
-
|
|
7027
|
+
tap(results => {
|
|
7028
|
+
if (results.dynamicTokens?.length) {
|
|
7029
|
+
// register missing tokens in the chaindata provider
|
|
7030
|
+
this.#chaindataProvider.registerDynamicTokens(results.dynamicTokens);
|
|
7031
|
+
}
|
|
7032
|
+
}), map(results => ({
|
|
6814
7033
|
status: "live",
|
|
6815
7034
|
// exclude zero balances
|
|
6816
7035
|
balances: results.success.filter(b => new Balance(b).total.planck > 0n)
|
|
@@ -7078,4 +7297,4 @@ const isAddressCompatibleWithNetwork = (network, address) => {
|
|
|
7078
7297
|
const sortByBalanceId = (a, b) => getBalanceId(a).localeCompare(getBalanceId(b));
|
|
7079
7298
|
const sortByMiniMetadataId = (a, b) => a.id.localeCompare(b.id);
|
|
7080
7299
|
|
|
7081
|
-
export { BALANCE_MODULES, Balance, BalanceFormatter, BalanceValueGetter, Balances, BalancesProvider, Change24hCurrencyFormatter, EvmErc20BalanceModule, EvmErc20TokenConfigSchema, EvmNativeBalanceModule, EvmNativeTokenConfigSchema, EvmUniswapV2BalanceModule, EvmUniswapV2TokenConfigSchema, FiatSumBalancesFormatter,
|
|
7300
|
+
export { ALPHA_PRICE_SCALE, BALANCE_MODULES, Balance, BalanceFormatter, BalanceValueGetter, Balances, BalancesProvider, Change24hCurrencyFormatter, EvmErc20BalanceModule, EvmErc20TokenConfigSchema, EvmNativeBalanceModule, EvmNativeTokenConfigSchema, EvmUniswapV2BalanceModule, EvmUniswapV2TokenConfigSchema, FiatSumBalancesFormatter, PlanckSumBalancesFormatter, SolNativeBalanceModule, SolNativeTokenConfigSchema, SolSplBalanceModule, SolSplTokenConfigSchema, SubAssetsBalanceModule, SubAssetsTokenConfigSchema, SubDTaoBalanceModule, SubDTaoTokenConfigSchema, SubForeignAssetsBalanceModule, SubForeignAssetsTokenConfigSchema, SubHydrationBalanceModule, SubHydrationTokenConfigSchema, SubNativeBalanceModule, SubNativeMiniMetadataExtraSchema, SubNativeModuleConfigSchema, SubNativeTokenConfigSchema, SubPsp22BalanceModule, SubPsp22TokenConfigSchema, SubTokensBalanceModule, SubTokensMiniMetadataExtraSchema, SubTokensModuleConfigSchema, SubTokensTokenConfigSchema, SumBalancesFormatter, TAO_DECIMALS, abiMulticall, alphaToTao, deriveMiniMetadataId, erc20BalancesAggregatorAbi, excludeFromFeePayableLocks, excludeFromTransferableAmount, filterBaseLocks, filterMirrorTokens, getBalanceId, getDTaoTokenRates, getLockTitle, getLockedType, getScaledAlphaPrice, getValueId, includeInTotalExtraAmount, taoToAlpha, uniswapV2PairAbi };
|