@talismn/balances 0.0.0-pr2075-20250707160526 → 0.0.0-pr2075-20250708125508
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/BalancesProvider.d.ts +23 -0
- package/dist/declarations/src/getMiniMetadata/getMiniMetadatas.d.ts +1 -1
- package/dist/declarations/src/index.d.ts +1 -0
- package/dist/declarations/src/modules/IBalanceModule.d.ts +4 -4
- package/dist/declarations/src/modules/substrate-native/queries/buildBaseQueries.d.ts +1 -1
- package/dist/declarations/src/modules/substrate-native/queries/buildNomPoolQueries.d.ts +1 -1
- package/dist/declarations/src/modules/util/rpcQueryPack.d.ts +11 -0
- package/dist/declarations/src/types/balances.d.ts +4 -3
- package/dist/talismn-balances.cjs.dev.js +254 -246
- package/dist/talismn-balances.cjs.prod.js +254 -246
- package/dist/talismn-balances.esm.js +255 -248
- package/package.json +8 -8
- package/dist/declarations/src/modules/util/RpcStateQueriesHelper.d.ts +0 -12
@@ -1,6 +1,6 @@
|
|
1
1
|
import { Dexie } from 'dexie';
|
2
2
|
import anylogger from 'anylogger';
|
3
|
-
import { evmErc20TokenId, MINIMETADATA_VERSION, EvmErc20TokenSchema, parseTokenId, parseEvmErc20TokenId, isTokenOfType, TokenBaseSchema, EvmNativeTokenSchema, evmNativeTokenId, EvmUniswapV2TokenSchema, evmUniswapV2TokenId, networkIdFromTokenId, getGithubTokenLogoUrl, SubAssetsTokenSchema, subAssetTokenId, SubForeignAssetsTokenSchema, subForeignAssetTokenId, SubHydrationTokenSchema, subHydrationTokenId, SubNativeTokenSchema, subNativeTokenId, SubPsp22TokenSchema, subPsp22TokenId, SubTokensTokenSchema, subTokensTokenId,
|
3
|
+
import { evmErc20TokenId, MINIMETADATA_VERSION, EvmErc20TokenSchema, parseTokenId, parseEvmErc20TokenId, isTokenOfType, TokenBaseSchema, EvmNativeTokenSchema, evmNativeTokenId, EvmUniswapV2TokenSchema, evmUniswapV2TokenId, networkIdFromTokenId, getGithubTokenLogoUrl, SubAssetsTokenSchema, subAssetTokenId, SubForeignAssetsTokenSchema, subForeignAssetTokenId, SubHydrationTokenSchema, subHydrationTokenId, SubNativeTokenSchema, subNativeTokenId, SubPsp22TokenSchema, subPsp22TokenId, SubTokensTokenSchema, subTokensTokenId, parseSubAssetTokenId, parseSubForeignAssetTokenId, parseSubTokensTokenId, isNetworkDot } from '@talismn/chaindata-provider';
|
4
4
|
export { MINIMETADATA_VERSION } from '@talismn/chaindata-provider';
|
5
5
|
import { newTokenRates } from '@talismn/token-rates';
|
6
6
|
import { isBigInt, BigMath, planckToTokens, isArrayOf, isTruthy, isEthereumAddress, hasOwnProperty, isNotNil, isAbortError, decodeAnyAddress, blake2Concat, Deferred } from '@talismn/util';
|
@@ -11,7 +11,7 @@ import pako from 'pako';
|
|
11
11
|
import { parseAbi, erc20Abi, getContract, ContractFunctionExecutionError, hexToString, erc20Abi_bytes32, encodeFunctionData, isHex, hexToBigInt, withRetry } from 'viem';
|
12
12
|
import { assign, omit, isEqual, fromPairs, toPairs, keys, keyBy, uniq, values, groupBy as groupBy$1 } from 'lodash';
|
13
13
|
import z from 'zod/v4';
|
14
|
-
import { Observable, distinctUntilChanged, of, timer, switchMap, from, firstValueFrom,
|
14
|
+
import { Observable, distinctUntilChanged, of, timer, switchMap, from, firstValueFrom, combineLatest, map, scan, share, switchAll, mergeMap, toArray, interval, startWith, exhaustMap, BehaviorSubject, debounceTime, takeUntil, withLatestFrom, concatMap, tap } from 'rxjs';
|
15
15
|
import isEqual$1 from 'lodash/isEqual';
|
16
16
|
import { unifyMetadata, decAnyMetadata, getDynamicBuilder, getLookupFn, decodeScale, parseMetadataRpc, getStorageKeyPrefix, compactMetadata, encodeMetadata, papiParse, papiStringify, toHex, getMetadataVersion, encodeStateKey } from '@talismn/scale';
|
17
17
|
import { Metadata, TypeRegistry } from '@polkadot/types';
|
@@ -275,11 +275,10 @@ class Balances {
|
|
275
275
|
}
|
276
276
|
const getBalanceId = balance => {
|
277
277
|
const {
|
278
|
-
source,
|
279
278
|
address,
|
280
279
|
tokenId
|
281
280
|
} = balance;
|
282
|
-
return [
|
281
|
+
return [address, tokenId].join("::");
|
283
282
|
};
|
284
283
|
|
285
284
|
/**
|
@@ -1538,16 +1537,16 @@ const getBalanceDefs = addressesByToken => {
|
|
1538
1537
|
|
1539
1538
|
const fetchBalances$c = async ({
|
1540
1539
|
networkId,
|
1541
|
-
|
1540
|
+
tokensWithAddresses,
|
1542
1541
|
connector
|
1543
1542
|
}) => {
|
1544
1543
|
const client = await connector.getPublicClientForEvmNetwork(networkId);
|
1545
1544
|
if (!client) throw new Error(`Could not get rpc provider for evm network ${networkId}`);
|
1546
|
-
for (const [token, addresses] of
|
1545
|
+
for (const [token, addresses] of tokensWithAddresses) {
|
1547
1546
|
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}`);
|
1548
1547
|
for (const address of addresses) if (!isEthereumAddress(address)) throw new Error(`Invalid ethereum address for EVM ERC20 balance module: ${address} for token ${token.id}`);
|
1549
1548
|
}
|
1550
|
-
const balanceDefs = getBalanceDefs(
|
1549
|
+
const balanceDefs = getBalanceDefs(tokensWithAddresses);
|
1551
1550
|
if (client.chain?.contracts?.erc20Aggregator && balanceDefs.length > 1) {
|
1552
1551
|
const erc20Aggregator = client.chain.contracts.erc20Aggregator;
|
1553
1552
|
return fetchWithAggregator$1(client, balanceDefs, erc20Aggregator.address);
|
@@ -1767,10 +1766,10 @@ const getTransferCallData$8 = ({
|
|
1767
1766
|
};
|
1768
1767
|
};
|
1769
1768
|
|
1770
|
-
const SUBSCRIPTION_INTERVAL$
|
1769
|
+
const SUBSCRIPTION_INTERVAL$7 = 6_000;
|
1771
1770
|
const subscribeBalances$8 = ({
|
1772
1771
|
networkId,
|
1773
|
-
|
1772
|
+
tokensWithAddresses,
|
1774
1773
|
connector
|
1775
1774
|
}) => {
|
1776
1775
|
return new Observable(subscriber => {
|
@@ -1780,17 +1779,17 @@ const subscribeBalances$8 = ({
|
|
1780
1779
|
if (abortController.signal.aborted) return;
|
1781
1780
|
const balances = await fetchBalances$c({
|
1782
1781
|
networkId,
|
1783
|
-
|
1782
|
+
tokensWithAddresses: tokensWithAddresses,
|
1784
1783
|
connector
|
1785
1784
|
});
|
1786
1785
|
if (abortController.signal.aborted) return;
|
1787
1786
|
subscriber.next(balances);
|
1788
|
-
setTimeout(poll, SUBSCRIPTION_INTERVAL$
|
1787
|
+
setTimeout(poll, SUBSCRIPTION_INTERVAL$7);
|
1789
1788
|
} catch (error) {
|
1790
1789
|
log.error("Error", {
|
1791
1790
|
module: MODULE_TYPE$8,
|
1792
1791
|
networkId,
|
1793
|
-
addressesByToken,
|
1792
|
+
addressesByToken: tokensWithAddresses,
|
1794
1793
|
error
|
1795
1794
|
});
|
1796
1795
|
subscriber.error(error);
|
@@ -1828,16 +1827,16 @@ const PLATFORM$7 = EvmNativeTokenSchema.shape.platform.value;
|
|
1828
1827
|
|
1829
1828
|
const fetchBalances$b = async ({
|
1830
1829
|
networkId,
|
1831
|
-
|
1830
|
+
tokensWithAddresses,
|
1832
1831
|
connector
|
1833
1832
|
}) => {
|
1834
1833
|
const client = await connector.getPublicClientForEvmNetwork(networkId);
|
1835
1834
|
if (!client) throw new Error(`Could not get rpc provider for evm network ${networkId}`);
|
1836
|
-
for (const [token, addresses] of
|
1835
|
+
for (const [token, addresses] of tokensWithAddresses) {
|
1837
1836
|
if (token.type !== MODULE_TYPE$7 || token.networkId !== networkId) throw new Error(`Invalid token type or networkId for EVM ERC20 balance module: ${token.type} on ${token.networkId}`);
|
1838
1837
|
for (const address of addresses) if (!isEthereumAddress(address)) throw new Error(`Invalid ethereum address for EVM ERC20 balance module: ${address} for token ${token.id}`);
|
1839
1838
|
}
|
1840
|
-
const balanceDefs = getBalanceDefs(
|
1839
|
+
const balanceDefs = getBalanceDefs(tokensWithAddresses);
|
1841
1840
|
if (client.chain?.contracts?.multicall3 && balanceDefs.length > 1) {
|
1842
1841
|
const multicall3 = client.chain.contracts.multicall3;
|
1843
1842
|
return fetchWithMulticall(client, balanceDefs, multicall3.address);
|
@@ -1981,10 +1980,10 @@ const getTransferCallData$7 = ({
|
|
1981
1980
|
};
|
1982
1981
|
};
|
1983
1982
|
|
1984
|
-
const SUBSCRIPTION_INTERVAL$
|
1983
|
+
const SUBSCRIPTION_INTERVAL$6 = 6_000;
|
1985
1984
|
const subscribeBalances$7 = ({
|
1986
1985
|
networkId,
|
1987
|
-
|
1986
|
+
tokensWithAddresses,
|
1988
1987
|
connector
|
1989
1988
|
}) => {
|
1990
1989
|
return new Observable(subscriber => {
|
@@ -1994,17 +1993,17 @@ const subscribeBalances$7 = ({
|
|
1994
1993
|
if (abortController.signal.aborted) return;
|
1995
1994
|
const balances = await fetchBalances$b({
|
1996
1995
|
networkId,
|
1997
|
-
|
1996
|
+
tokensWithAddresses: tokensWithAddresses,
|
1998
1997
|
connector
|
1999
1998
|
});
|
2000
1999
|
if (abortController.signal.aborted) return;
|
2001
2000
|
subscriber.next(balances);
|
2002
|
-
setTimeout(poll, SUBSCRIPTION_INTERVAL$
|
2001
|
+
setTimeout(poll, SUBSCRIPTION_INTERVAL$6);
|
2003
2002
|
} catch (error) {
|
2004
2003
|
log.error("Error", {
|
2005
2004
|
module: MODULE_TYPE$7,
|
2006
2005
|
networkId,
|
2007
|
-
addressesByToken,
|
2006
|
+
addressesByToken: tokensWithAddresses,
|
2008
2007
|
error
|
2009
2008
|
});
|
2010
2009
|
subscriber.error(error);
|
@@ -2037,16 +2036,16 @@ const PLATFORM$6 = EvmUniswapV2TokenSchema.shape.platform.value;
|
|
2037
2036
|
|
2038
2037
|
const fetchBalances$a = async ({
|
2039
2038
|
networkId,
|
2040
|
-
|
2039
|
+
tokensWithAddresses,
|
2041
2040
|
connector
|
2042
2041
|
}) => {
|
2043
2042
|
const client = await connector.getPublicClientForEvmNetwork(networkId);
|
2044
2043
|
if (!client) throw new Error(`Could not get rpc provider for evm network ${networkId}`);
|
2045
|
-
for (const [token, addresses] of
|
2044
|
+
for (const [token, addresses] of tokensWithAddresses) {
|
2046
2045
|
if (token.type !== MODULE_TYPE$6 || token.networkId !== networkId) throw new Error(`Invalid token type or networkId for EVM ERC20 balance module: ${token.type} on ${token.networkId}`);
|
2047
2046
|
for (const address of addresses) if (!isEthereumAddress(address)) throw new Error(`Invalid ethereum address for EVM ERC20 balance module: ${address} for token ${token.id}`);
|
2048
2047
|
}
|
2049
|
-
const balanceDefs = getBalanceDefs(
|
2048
|
+
const balanceDefs = getBalanceDefs(tokensWithAddresses);
|
2050
2049
|
if (client.chain?.contracts?.erc20Aggregator && balanceDefs.length > 1) {
|
2051
2050
|
const erc20Aggregator = client.chain.contracts.erc20Aggregator;
|
2052
2051
|
return fetchWithAggregator(client, balanceDefs, erc20Aggregator.address);
|
@@ -2314,10 +2313,10 @@ const getTransferCallData$6 = ({
|
|
2314
2313
|
};
|
2315
2314
|
};
|
2316
2315
|
|
2317
|
-
const SUBSCRIPTION_INTERVAL$
|
2316
|
+
const SUBSCRIPTION_INTERVAL$5 = 6_000;
|
2318
2317
|
const subscribeBalances$6 = ({
|
2319
2318
|
networkId,
|
2320
|
-
|
2319
|
+
tokensWithAddresses,
|
2321
2320
|
connector
|
2322
2321
|
}) => {
|
2323
2322
|
return new Observable(subscriber => {
|
@@ -2327,17 +2326,17 @@ const subscribeBalances$6 = ({
|
|
2327
2326
|
if (abortController.signal.aborted) return;
|
2328
2327
|
const balances = await fetchBalances$a({
|
2329
2328
|
networkId,
|
2330
|
-
|
2329
|
+
tokensWithAddresses: tokensWithAddresses,
|
2331
2330
|
connector
|
2332
2331
|
});
|
2333
2332
|
if (abortController.signal.aborted) return;
|
2334
2333
|
subscriber.next(balances);
|
2335
|
-
setTimeout(poll, SUBSCRIPTION_INTERVAL$
|
2334
|
+
setTimeout(poll, SUBSCRIPTION_INTERVAL$5);
|
2336
2335
|
} catch (error) {
|
2337
2336
|
log.error("Error", {
|
2338
2337
|
module: MODULE_TYPE$6,
|
2339
2338
|
networkId,
|
2340
|
-
addressesByToken,
|
2339
|
+
addressesByToken: tokensWithAddresses,
|
2341
2340
|
error
|
2342
2341
|
});
|
2343
2342
|
subscriber.error(error);
|
@@ -3459,13 +3458,13 @@ const decompress = data => {
|
|
3459
3458
|
|
3460
3459
|
const fetchBalances$6 = async ({
|
3461
3460
|
networkId,
|
3462
|
-
|
3461
|
+
tokensWithAddresses,
|
3463
3462
|
connector,
|
3464
3463
|
miniMetadata
|
3465
3464
|
}) => {
|
3466
|
-
const balanceDefs = getBalanceDefs(
|
3465
|
+
const balanceDefs = getBalanceDefs(tokensWithAddresses);
|
3467
3466
|
if (!miniMetadata?.data) {
|
3468
|
-
log.warn(
|
3467
|
+
log.warn(`MiniMetadata is required for fetching ${MODULE_TYPE$5} balances on ${networkId}.`);
|
3469
3468
|
return {
|
3470
3469
|
success: [],
|
3471
3470
|
errors: balanceDefs.map(def => ({
|
@@ -3835,10 +3834,10 @@ const getTransferAllEncodedArgs$2 = (assetId, to, codec) => {
|
|
3835
3834
|
})]);
|
3836
3835
|
};
|
3837
3836
|
|
3838
|
-
const SUBSCRIPTION_INTERVAL$
|
3837
|
+
const SUBSCRIPTION_INTERVAL$4 = 6_000;
|
3839
3838
|
const subscribeBalances$5 = ({
|
3840
3839
|
networkId,
|
3841
|
-
|
3840
|
+
tokensWithAddresses,
|
3842
3841
|
connector,
|
3843
3842
|
miniMetadata
|
3844
3843
|
}) => {
|
@@ -3852,19 +3851,19 @@ const subscribeBalances$5 = ({
|
|
3852
3851
|
if (abortController.signal.aborted) return;
|
3853
3852
|
const balances = await fetchBalances$6({
|
3854
3853
|
networkId,
|
3855
|
-
|
3854
|
+
tokensWithAddresses: tokensWithAddresses,
|
3856
3855
|
connector,
|
3857
3856
|
miniMetadata
|
3858
3857
|
});
|
3859
3858
|
if (abortController.signal.aborted) return;
|
3860
3859
|
subscriber.next(balances);
|
3861
|
-
setTimeout(poll, SUBSCRIPTION_INTERVAL$
|
3860
|
+
setTimeout(poll, SUBSCRIPTION_INTERVAL$4);
|
3862
3861
|
} catch (error) {
|
3863
3862
|
log.error("Error", {
|
3864
3863
|
module: MODULE_TYPE$5,
|
3865
3864
|
networkId,
|
3866
3865
|
miniMetadata,
|
3867
|
-
addressesByToken,
|
3866
|
+
addressesByToken: tokensWithAddresses,
|
3868
3867
|
error
|
3869
3868
|
});
|
3870
3869
|
subscriber.error(error);
|
@@ -3898,13 +3897,13 @@ const PLATFORM$4 = SubForeignAssetsTokenSchema.shape.platform.value;
|
|
3898
3897
|
|
3899
3898
|
const fetchBalances$5 = async ({
|
3900
3899
|
networkId,
|
3901
|
-
|
3900
|
+
tokensWithAddresses,
|
3902
3901
|
connector,
|
3903
3902
|
miniMetadata
|
3904
3903
|
}) => {
|
3905
|
-
const balanceDefs = getBalanceDefs(
|
3904
|
+
const balanceDefs = getBalanceDefs(tokensWithAddresses);
|
3906
3905
|
if (!miniMetadata?.data) {
|
3907
|
-
log.warn(
|
3906
|
+
log.warn(`MiniMetadata is required for fetching ${MODULE_TYPE$4} balances on ${networkId}.`);
|
3908
3907
|
return {
|
3909
3908
|
success: [],
|
3910
3909
|
errors: balanceDefs.map(def => ({
|
@@ -4233,10 +4232,10 @@ const getTransferAllEncodedArgs$1 = (onChainId, to, codec) => {
|
|
4233
4232
|
})]);
|
4234
4233
|
};
|
4235
4234
|
|
4236
|
-
const SUBSCRIPTION_INTERVAL$
|
4235
|
+
const SUBSCRIPTION_INTERVAL$3 = 6_000;
|
4237
4236
|
const subscribeBalances$4 = ({
|
4238
4237
|
networkId,
|
4239
|
-
|
4238
|
+
tokensWithAddresses,
|
4240
4239
|
connector,
|
4241
4240
|
miniMetadata
|
4242
4241
|
}) => {
|
@@ -4250,19 +4249,19 @@ const subscribeBalances$4 = ({
|
|
4250
4249
|
if (abortController.signal.aborted) return;
|
4251
4250
|
const balances = await fetchBalances$5({
|
4252
4251
|
networkId,
|
4253
|
-
|
4252
|
+
tokensWithAddresses: tokensWithAddresses,
|
4254
4253
|
connector,
|
4255
4254
|
miniMetadata
|
4256
4255
|
});
|
4257
4256
|
if (abortController.signal.aborted) return;
|
4258
4257
|
subscriber.next(balances);
|
4259
|
-
setTimeout(poll, SUBSCRIPTION_INTERVAL$
|
4258
|
+
setTimeout(poll, SUBSCRIPTION_INTERVAL$3);
|
4260
4259
|
} catch (error) {
|
4261
4260
|
log.error("Error", {
|
4262
4261
|
module: MODULE_TYPE$4,
|
4263
4262
|
networkId,
|
4264
4263
|
miniMetadata,
|
4265
|
-
addressesByToken,
|
4264
|
+
addressesByToken: tokensWithAddresses,
|
4266
4265
|
error
|
4267
4266
|
});
|
4268
4267
|
subscriber.error(error);
|
@@ -4326,13 +4325,13 @@ const tryGetConstantValue = (metadataRpc, pallet, constant) => {
|
|
4326
4325
|
|
4327
4326
|
const fetchBalances$4 = async ({
|
4328
4327
|
networkId,
|
4329
|
-
|
4328
|
+
tokensWithAddresses,
|
4330
4329
|
connector,
|
4331
4330
|
miniMetadata
|
4332
4331
|
}) => {
|
4333
|
-
const balanceDefs = getBalanceDefs(
|
4332
|
+
const balanceDefs = getBalanceDefs(tokensWithAddresses);
|
4334
4333
|
if (!miniMetadata?.data) {
|
4335
|
-
log.warn(
|
4334
|
+
log.warn(`MiniMetadata is required for fetching ${MODULE_TYPE$3} balances on ${networkId}.`);
|
4336
4335
|
return {
|
4337
4336
|
success: [],
|
4338
4337
|
errors: balanceDefs.map(def => ({
|
@@ -4377,7 +4376,7 @@ const fetchBalances$4 = async ({
|
|
4377
4376
|
})).filter(b => b.onChainId !== undefined);
|
4378
4377
|
});
|
4379
4378
|
const balancesByKey = keyBy(fetchedBalances, b => `${b.address}:${b.onChainId}`);
|
4380
|
-
const success =
|
4379
|
+
const success = tokensWithAddresses.reduce((acc, [token, addresses]) => {
|
4381
4380
|
if (token.type === MODULE_TYPE$3) for (const address of addresses) {
|
4382
4381
|
const rawBalance = balancesByKey[`${address}:${token.onChainId}`];
|
4383
4382
|
|
@@ -4579,10 +4578,10 @@ const getTransferCallData$3 = ({
|
|
4579
4578
|
};
|
4580
4579
|
};
|
4581
4580
|
|
4582
|
-
const SUBSCRIPTION_INTERVAL$
|
4581
|
+
const SUBSCRIPTION_INTERVAL$2 = 6_000;
|
4583
4582
|
const subscribeBalances$3 = ({
|
4584
4583
|
networkId,
|
4585
|
-
|
4584
|
+
tokensWithAddresses,
|
4586
4585
|
connector,
|
4587
4586
|
miniMetadata
|
4588
4587
|
}) => {
|
@@ -4596,19 +4595,19 @@ const subscribeBalances$3 = ({
|
|
4596
4595
|
if (abortController.signal.aborted) return;
|
4597
4596
|
const balances = await fetchBalances$4({
|
4598
4597
|
networkId,
|
4599
|
-
|
4598
|
+
tokensWithAddresses: tokensWithAddresses,
|
4600
4599
|
connector,
|
4601
4600
|
miniMetadata
|
4602
4601
|
});
|
4603
4602
|
if (abortController.signal.aborted) return;
|
4604
4603
|
subscriber.next(balances);
|
4605
|
-
setTimeout(poll, SUBSCRIPTION_INTERVAL$
|
4604
|
+
setTimeout(poll, SUBSCRIPTION_INTERVAL$2);
|
4606
4605
|
} catch (error) {
|
4607
4606
|
log.error("Error", {
|
4608
4607
|
module: MODULE_TYPE$3,
|
4609
4608
|
networkId,
|
4610
4609
|
miniMetadata,
|
4611
|
-
addressesByToken,
|
4610
|
+
addressesByToken: tokensWithAddresses,
|
4612
4611
|
error
|
4613
4612
|
});
|
4614
4613
|
subscriber.error(error);
|
@@ -4634,140 +4633,54 @@ const SubHydrationBalanceModule = {
|
|
4634
4633
|
const MODULE_TYPE$2 = SubNativeTokenSchema.shape.type.value;
|
4635
4634
|
const PLATFORM$2 = SubNativeTokenSchema.shape.platform.value;
|
4636
4635
|
|
4637
|
-
|
4638
|
-
* Pass some these into an `RpcStateQueryHelper` in order to easily batch multiple state queries into the one rpc call.
|
4639
|
-
*/
|
4640
|
-
|
4641
|
-
const fetchQueriesPack = async (connector, networkId, queries) => {
|
4636
|
+
const fetchRpcQueryPack = async (connector, networkId, queries) => {
|
4642
4637
|
const allStateKeys = queries.flatMap(({
|
4643
4638
|
stateKeys
|
4644
4639
|
}) => stateKeys).filter(isNotNil);
|
4645
4640
|
|
4646
|
-
// doing a query
|
4641
|
+
// doing a query without keys would throw an error => return early
|
4647
4642
|
if (!allStateKeys.length) return queries.map(({
|
4648
4643
|
stateKeys,
|
4649
4644
|
decodeResult
|
4650
4645
|
}) => decodeResult(stateKeys.map(() => null)));
|
4651
|
-
const
|
4652
|
-
|
4646
|
+
const [result] = await connector.send(networkId, "state_queryStorageAt", [allStateKeys]);
|
4647
|
+
return decodeRpcQueryPack(queries, result);
|
4648
|
+
};
|
4649
|
+
const getRpcQueryPack$ = (connector, networkId, queries, timeout = false) => {
|
4650
|
+
const allStateKeys = queries.flatMap(({
|
4651
|
+
stateKeys
|
4652
|
+
}) => stateKeys).filter(isNotNil);
|
4653
|
+
|
4654
|
+
// doing a query without keys would throw an error => return early
|
4655
|
+
if (!allStateKeys.length) return of(queries.map(({
|
4656
|
+
stateKeys,
|
4657
|
+
decodeResult
|
4658
|
+
}) => decodeResult(stateKeys.map(() => null))));
|
4659
|
+
return new Observable(subscriber => {
|
4660
|
+
const promUnsub = connector.subscribe(networkId, "state_subscribeStorage", "state_storage", [allStateKeys], (error, result) => {
|
4661
|
+
if (error) subscriber.error(error);else subscriber.next(decodeRpcQueryPack(queries, result));
|
4662
|
+
}, timeout);
|
4663
|
+
return () => {
|
4664
|
+
promUnsub.then(unsub => unsub("state_unsubscribeStorage"));
|
4665
|
+
};
|
4666
|
+
});
|
4667
|
+
};
|
4668
|
+
const decodeRpcQueryPack = (queries, result) => {
|
4669
|
+
return queries.reduce((acc, {
|
4653
4670
|
stateKeys,
|
4654
4671
|
decodeResult
|
4655
4672
|
}) => {
|
4656
4673
|
const changes = stateKeys.map(stateKey => {
|
4657
4674
|
if (!stateKey) return null;
|
4658
|
-
const change =
|
4675
|
+
const change = result.changes.find(([key]) => key === stateKey);
|
4659
4676
|
if (!change) return null;
|
4660
4677
|
return change[1];
|
4661
4678
|
});
|
4662
4679
|
acc.push(decodeResult(changes));
|
4663
4680
|
return acc;
|
4664
4681
|
}, []);
|
4665
|
-
return results;
|
4666
4682
|
};
|
4667
4683
|
|
4668
|
-
/**
|
4669
|
-
* Used by a variety of balance modules to help batch multiple state queries into the one rpc call.
|
4670
|
-
*/
|
4671
|
-
// export class RpcStateQueriesHelper<T> {
|
4672
|
-
// #connector: ChainConnector
|
4673
|
-
// #queries: Array<RpcStateQueries<T>>
|
4674
|
-
|
4675
|
-
// constructor(connector: ChainConnector, queries: Array<RpcStateQueries<T>>) {
|
4676
|
-
// this.#connector = connector
|
4677
|
-
// this.#queries = queries
|
4678
|
-
// }
|
4679
|
-
|
4680
|
-
// async subscribe(
|
4681
|
-
// networkId: DotNetworkId,
|
4682
|
-
// callback: SubscriptionCallback<T[]>,
|
4683
|
-
// timeout: number | false = false,
|
4684
|
-
// subscribeMethod = "state_subscribeStorage",
|
4685
|
-
// responseMethod = "state_storage",
|
4686
|
-
// unsubscribeMethod = "state_unsubscribeStorage",
|
4687
|
-
// ): Promise<UnsubscribeFn> {
|
4688
|
-
// const params = [this.#queries.flatMap(({ stateKeys }) => stateKeys)]
|
4689
|
-
|
4690
|
-
// const unsub = this.#connector.subscribe(
|
4691
|
-
// networkId,
|
4692
|
-
// subscribeMethod,
|
4693
|
-
// responseMethod,
|
4694
|
-
// params,
|
4695
|
-
// (error, result) => {
|
4696
|
-
// error
|
4697
|
-
// ? callback(error)
|
4698
|
-
// : callback(null, this.#distributeChangesToQueryDecoders.call(this, chainId, result))
|
4699
|
-
// },
|
4700
|
-
// timeout,
|
4701
|
-
// )
|
4702
|
-
|
4703
|
-
// const subscriptions = queries.map(([chainId, queries]) => {
|
4704
|
-
// const params = [queries.map(({ stateKey }) => stateKey)]
|
4705
|
-
|
4706
|
-
// const unsub = this.#connector.subscribe(
|
4707
|
-
// networkId,
|
4708
|
-
// subscribeMethod,
|
4709
|
-
// responseMethod,
|
4710
|
-
// params,
|
4711
|
-
// (error, result) => {
|
4712
|
-
// error
|
4713
|
-
// ? callback(error)
|
4714
|
-
// : callback(null, this.#distributeChangesToQueryDecoders.call(this, chainId, result))
|
4715
|
-
// },
|
4716
|
-
// timeout,
|
4717
|
-
// )
|
4718
|
-
|
4719
|
-
// return () => unsub.then((unsubscribe) => unsubscribe(unsubscribeMethod))
|
4720
|
-
// })
|
4721
|
-
|
4722
|
-
// return () => subscriptions.forEach((unsubscribe) => unsubscribe())
|
4723
|
-
// }
|
4724
|
-
|
4725
|
-
// async fetch(method = "state_queryStorageAt"): Promise<T[]> {
|
4726
|
-
// const queriesByChain = groupBy(this.#queries, "chainId")
|
4727
|
-
|
4728
|
-
// const resultsByChain = await Promise.all(
|
4729
|
-
// Object.entries(queriesByChain).map(async ([chainId, queries]) => {
|
4730
|
-
// const params = [queries.map(({ stateKey }) => stateKey)]
|
4731
|
-
|
4732
|
-
// const result = (await this.#connector.send(chainId, method, params))[0]
|
4733
|
-
// return this.#distributeChangesToQueryDecoders.call(this, chainId, result)
|
4734
|
-
// }),
|
4735
|
-
// )
|
4736
|
-
|
4737
|
-
// return resultsByChain.flatMap((result) => result)
|
4738
|
-
// }
|
4739
|
-
|
4740
|
-
// #distributeChangesToQueryDecoders(chainId: DotNetworkId, result: unknown): T[] {
|
4741
|
-
// if (typeof result !== "object" || result === null) return []
|
4742
|
-
// if (!hasOwnProperty(result, "changes") || typeof result.changes !== "object") return []
|
4743
|
-
// if (!Array.isArray(result.changes)) return []
|
4744
|
-
|
4745
|
-
// return result.changes.flatMap(([reference, change]: [unknown, unknown]): [T] | [] => {
|
4746
|
-
// if (typeof reference !== "string") {
|
4747
|
-
// log.warn(`Received non-string reference in RPC result: ${reference}`)
|
4748
|
-
// return []
|
4749
|
-
// }
|
4750
|
-
|
4751
|
-
// if (typeof change !== "string" && change !== null) {
|
4752
|
-
// log.warn(`Received non-string and non-null change in RPC result: ${reference} | ${change}`)
|
4753
|
-
// return []
|
4754
|
-
// }
|
4755
|
-
|
4756
|
-
// const query = this.#queries.find(
|
4757
|
-
// ({ chainId: cId, stateKey }) => cId === chainId && stateKey === reference,
|
4758
|
-
// )
|
4759
|
-
// if (!query) {
|
4760
|
-
// log.warn(
|
4761
|
-
// `Failed to find query:\n${reference} in\n${this.#queries.map(({ stateKey }) => stateKey)}`,
|
4762
|
-
// )
|
4763
|
-
// return []
|
4764
|
-
// }
|
4765
|
-
|
4766
|
-
// return [query.decodeResult(change)]
|
4767
|
-
// })
|
4768
|
-
// }
|
4769
|
-
// }
|
4770
|
-
|
4771
4684
|
const SUBTENSOR_ROOT_NETUID$1 = 0;
|
4772
4685
|
const SUBTENSOR_MIN_STAKE_AMOUNT_PLANK$1 = 1000000n;
|
4773
4686
|
const TAO_DECIMALS$1 = 9n;
|
@@ -5481,13 +5394,13 @@ const getNomPoolStateKeys = (coders, nomPoolMemberInfo, extra) => {
|
|
5481
5394
|
|
5482
5395
|
const fetchBalances$3 = async ({
|
5483
5396
|
networkId,
|
5484
|
-
|
5397
|
+
tokensWithAddresses,
|
5485
5398
|
connector,
|
5486
5399
|
miniMetadata
|
5487
5400
|
}) => {
|
5488
|
-
const balanceDefs = getBalanceDefs(
|
5401
|
+
const balanceDefs = getBalanceDefs(tokensWithAddresses);
|
5489
5402
|
if (!miniMetadata?.data) {
|
5490
|
-
log.warn(
|
5403
|
+
log.warn(`MiniMetadata is required for fetching ${MODULE_TYPE$2} balances on ${networkId}.`);
|
5491
5404
|
return {
|
5492
5405
|
success: [],
|
5493
5406
|
errors: balanceDefs.map(def => ({
|
@@ -5519,12 +5432,12 @@ const fetchBalances$3 = async ({
|
|
5519
5432
|
}))
|
5520
5433
|
};
|
5521
5434
|
}
|
5522
|
-
const
|
5523
|
-
const partialBalances = await
|
5435
|
+
const baseQueries = buildBaseQueries(networkId, balanceDefs, miniMetadata);
|
5436
|
+
const partialBalances = await fetchRpcQueryPack(connector, networkId, baseQueries);
|
5524
5437
|
|
5525
5438
|
// now for each balance that includes nomPoolStaking, we need to fetch the metadata for the pool
|
5526
5439
|
const nomPoolQueries = buildNomPoolQueries(networkId, partialBalances, miniMetadata);
|
5527
|
-
const balances = await
|
5440
|
+
const balances = await fetchRpcQueryPack(connector, networkId, nomPoolQueries);
|
5528
5441
|
|
5529
5442
|
// TODO ⚠️ dedupe locks
|
5530
5443
|
|
@@ -5760,46 +5673,32 @@ const getTransferAllEncodedArgs = (to, codec) => {
|
|
5760
5673
|
})]);
|
5761
5674
|
};
|
5762
5675
|
|
5763
|
-
const SUBSCRIPTION_INTERVAL$2 = 6_000;
|
5764
5676
|
const subscribeBalances$2 = ({
|
5765
5677
|
networkId,
|
5766
|
-
|
5678
|
+
tokensWithAddresses,
|
5767
5679
|
connector,
|
5768
5680
|
miniMetadata
|
5769
5681
|
}) => {
|
5770
|
-
|
5771
|
-
|
5772
|
-
|
5773
|
-
|
5774
|
-
//
|
5775
|
-
const
|
5776
|
-
|
5777
|
-
|
5778
|
-
|
5779
|
-
|
5780
|
-
|
5781
|
-
|
5782
|
-
|
5783
|
-
|
5784
|
-
|
5785
|
-
|
5786
|
-
|
5787
|
-
|
5788
|
-
log.error("Error", {
|
5789
|
-
module: MODULE_TYPE$2,
|
5790
|
-
networkId,
|
5791
|
-
miniMetadata,
|
5792
|
-
addressesByToken,
|
5793
|
-
error
|
5794
|
-
});
|
5795
|
-
subscriber.error(error);
|
5796
|
-
}
|
5797
|
-
};
|
5798
|
-
poll();
|
5799
|
-
return () => {
|
5800
|
-
abortController.abort();
|
5682
|
+
// could be use as shared observable key if we decide to cache the sub
|
5683
|
+
const balanceDefs = getBalanceDefs(tokensWithAddresses);
|
5684
|
+
const baseQueries = buildBaseQueries(networkId, balanceDefs, miniMetadata);
|
5685
|
+
const baseBalances$ = getRpcQueryPack$(connector, networkId, baseQueries).pipe(switchMap(partialBalances => {
|
5686
|
+
// now for each balance that includes nomPoolStaking, we need to fetch the metadata for the pool
|
5687
|
+
const nomPoolQueries = buildNomPoolQueries(networkId, partialBalances, miniMetadata);
|
5688
|
+
return getRpcQueryPack$(connector, networkId, nomPoolQueries);
|
5689
|
+
}));
|
5690
|
+
const subtensorBalancesByAddress$ = getSubtensorStakingBalances$(connector, networkId, balanceDefs, miniMetadata);
|
5691
|
+
return combineLatest([baseBalances$, subtensorBalancesByAddress$]).pipe(map(([baseBalances, subtensorBalancesByAddress]) => {
|
5692
|
+
// add subtensor balances to base balances
|
5693
|
+
for (const [address, subtensorBalances] of toPairs(subtensorBalancesByAddress)) {
|
5694
|
+
const balance = baseBalances.find(b => b.address === address);
|
5695
|
+
if (balance?.values) balance.values.push(...subtensorBalances);
|
5696
|
+
}
|
5697
|
+
return {
|
5698
|
+
success: baseBalances,
|
5699
|
+
errors: []
|
5801
5700
|
};
|
5802
|
-
})
|
5701
|
+
}));
|
5803
5702
|
};
|
5804
5703
|
|
5805
5704
|
const SubNativeBalanceModule = {
|
@@ -6980,10 +6879,10 @@ var psp22Abi = {
|
|
6980
6879
|
|
6981
6880
|
const fetchBalances$2 = async ({
|
6982
6881
|
networkId,
|
6983
|
-
|
6882
|
+
tokensWithAddresses,
|
6984
6883
|
connector
|
6985
6884
|
}) => {
|
6986
|
-
const balanceDefs = getBalanceDefs(
|
6885
|
+
const balanceDefs = getBalanceDefs(tokensWithAddresses);
|
6987
6886
|
if (!balanceDefs.length) return {
|
6988
6887
|
success: [],
|
6989
6888
|
errors: []
|
@@ -7173,7 +7072,7 @@ const getTransferCallData$1 = async ({
|
|
7173
7072
|
const SUBSCRIPTION_INTERVAL$1 = 6_000;
|
7174
7073
|
const subscribeBalances$1 = ({
|
7175
7074
|
networkId,
|
7176
|
-
|
7075
|
+
tokensWithAddresses,
|
7177
7076
|
connector,
|
7178
7077
|
miniMetadata
|
7179
7078
|
}) => {
|
@@ -7187,7 +7086,7 @@ const subscribeBalances$1 = ({
|
|
7187
7086
|
if (abortController.signal.aborted) return;
|
7188
7087
|
const balances = await fetchBalances$2({
|
7189
7088
|
networkId,
|
7190
|
-
|
7089
|
+
tokensWithAddresses: tokensWithAddresses,
|
7191
7090
|
connector,
|
7192
7091
|
miniMetadata
|
7193
7092
|
});
|
@@ -7199,7 +7098,7 @@ const subscribeBalances$1 = ({
|
|
7199
7098
|
module: MODULE_TYPE$1,
|
7200
7099
|
networkId,
|
7201
7100
|
miniMetadata,
|
7202
|
-
addressesByToken,
|
7101
|
+
addressesByToken: tokensWithAddresses,
|
7203
7102
|
error
|
7204
7103
|
});
|
7205
7104
|
subscriber.error(error);
|
@@ -7233,13 +7132,13 @@ const PLATFORM = SubTokensTokenSchema.shape.platform.value;
|
|
7233
7132
|
|
7234
7133
|
const fetchBalances$1 = async ({
|
7235
7134
|
networkId,
|
7236
|
-
|
7135
|
+
tokensWithAddresses,
|
7237
7136
|
connector,
|
7238
7137
|
miniMetadata
|
7239
7138
|
}) => {
|
7240
|
-
const balanceDefs = getBalanceDefs(
|
7139
|
+
const balanceDefs = getBalanceDefs(tokensWithAddresses);
|
7241
7140
|
if (!miniMetadata?.data) {
|
7242
|
-
log.warn(
|
7141
|
+
log.warn(`MiniMetadata is required for fetching ${MODULE_TYPE} balances on ${networkId}.`);
|
7243
7142
|
return {
|
7244
7143
|
success: [],
|
7245
7144
|
errors: balanceDefs.map(def => ({
|
@@ -7563,7 +7462,7 @@ const getCallDataOptions = (to, token, value, type, config) => {
|
|
7563
7462
|
const SUBSCRIPTION_INTERVAL = 6_000;
|
7564
7463
|
const subscribeBalances = ({
|
7565
7464
|
networkId,
|
7566
|
-
|
7465
|
+
tokensWithAddresses,
|
7567
7466
|
connector,
|
7568
7467
|
miniMetadata
|
7569
7468
|
}) => {
|
@@ -7577,7 +7476,7 @@ const subscribeBalances = ({
|
|
7577
7476
|
if (abortController.signal.aborted) return;
|
7578
7477
|
const balances = await fetchBalances$1({
|
7579
7478
|
networkId,
|
7580
|
-
|
7479
|
+
tokensWithAddresses: tokensWithAddresses,
|
7581
7480
|
connector,
|
7582
7481
|
miniMetadata
|
7583
7482
|
});
|
@@ -7589,7 +7488,7 @@ const subscribeBalances = ({
|
|
7589
7488
|
module: MODULE_TYPE,
|
7590
7489
|
networkId,
|
7591
7490
|
miniMetadata,
|
7592
|
-
addressesByToken,
|
7491
|
+
addressesByToken: tokensWithAddresses,
|
7593
7492
|
error
|
7594
7493
|
});
|
7595
7494
|
subscriber.error(error);
|
@@ -7693,6 +7592,7 @@ const getMiniMetadatas = async (chainConnector, chaindataProvider, networkId, sp
|
|
7693
7592
|
if (CACHE.has(networkId)) return CACHE.get(networkId);
|
7694
7593
|
if (!signal) log.warn("[miniMetadata] getMiniMetadatas called without signal, this may hang the updates", new Error("No signal provided") // this will show the stack trace
|
7695
7594
|
);
|
7595
|
+
if (specVersion === undefined) specVersion = await getSpecVersion(chainConnector, networkId);
|
7696
7596
|
const pResult = POOL.add(() => fetchMiniMetadatas(chainConnector, chaindataProvider, networkId, specVersion), {
|
7697
7597
|
signal
|
7698
7598
|
});
|
@@ -7708,42 +7608,21 @@ const getMiniMetadatas = async (chainConnector, chaindataProvider, networkId, sp
|
|
7708
7608
|
CACHE.delete(networkId);
|
7709
7609
|
}
|
7710
7610
|
};
|
7711
|
-
const DotBalanceModuleTypeSchema = z.keyof(DotNetworkBalancesConfigSchema);
|
7712
7611
|
const fetchMiniMetadatas = async (chainConnector, chaindataProvider, chainId, specVersion, signal) => {
|
7713
7612
|
const start = performance.now();
|
7714
7613
|
log.info("[miniMetadata] fetching minimetadatas for %s", chainId);
|
7715
7614
|
try {
|
7615
|
+
const network = await chaindataProvider.getNetworkById(chainId, "polkadot");
|
7616
|
+
if (!network) throw new Error(`Network ${chainId} not found in chaindataProvider`);
|
7617
|
+
signal?.throwIfAborted();
|
7716
7618
|
const metadataRpc = await getMetadataRpc(chainConnector, chainId);
|
7717
7619
|
signal?.throwIfAborted();
|
7718
|
-
|
7719
|
-
|
7720
|
-
|
7721
|
-
|
7722
|
-
|
7723
|
-
|
7724
|
-
chaindataProvider
|
7725
|
-
})).filter(mod => DotBalanceModuleTypeSchema.safeParse(mod.type).success);
|
7726
|
-
return Promise.all(modules.map(async mod => {
|
7727
|
-
const source = mod.type;
|
7728
|
-
const chain = await chaindataProvider.getNetworkById(chainId, "polkadot");
|
7729
|
-
const balancesConfig = chain?.balancesConfig?.[mod.type];
|
7730
|
-
const chainMeta = await mod.fetchSubstrateChainMeta(chainId, balancesConfig,
|
7731
|
-
// TODO better typing
|
7732
|
-
metadataRpc);
|
7733
|
-
return {
|
7734
|
-
id: deriveMiniMetadataId({
|
7735
|
-
source,
|
7736
|
-
chainId,
|
7737
|
-
specVersion
|
7738
|
-
}),
|
7739
|
-
source,
|
7740
|
-
chainId,
|
7741
|
-
specVersion,
|
7742
|
-
version: MINIMETADATA_VERSION,
|
7743
|
-
data: chainMeta?.miniMetadata ?? null,
|
7744
|
-
extra: chainMeta?.extra ?? null
|
7745
|
-
};
|
7746
|
-
}));
|
7620
|
+
return Promise.all(BALANCE_MODULES.filter(m => m.platform === "polkadot").map(mod => mod.getMiniMetadata({
|
7621
|
+
networkId: chainId,
|
7622
|
+
metadataRpc,
|
7623
|
+
specVersion,
|
7624
|
+
config: network.balancesConfig?.[mod.type]
|
7625
|
+
})));
|
7747
7626
|
} finally {
|
7748
7627
|
log.debug("[miniMetadata] updated miniMetadatas for %s in %sms", chainId, (performance.now() - start).toFixed(2));
|
7749
7628
|
}
|
@@ -10454,4 +10333,132 @@ async function buildQueries(chainConnector, chaindataProvider, addressesByToken,
|
|
10454
10333
|
const defaultBalanceModules = [EvmErc20Module, EvmNativeModule, EvmUniswapV2Module, SubAssetsModule, SubForeignAssetsModule, SubNativeModule, SubPsp22Module, SubTokensModule];
|
10455
10334
|
const BALANCE_MODULES = [SubNativeBalanceModule, SubAssetsBalanceModule, SubHydrationBalanceModule, SubForeignAssetsBalanceModule, SubPsp22BalanceModule, SubTokensBalanceModule, EvmErc20BalanceModule, EvmUniswapV2BalanceModule, EvmNativeBalanceModule];
|
10456
10335
|
|
10457
|
-
|
10336
|
+
const DEFAULT_STORAGE = {
|
10337
|
+
balances: [],
|
10338
|
+
miniMetadatas: []
|
10339
|
+
};
|
10340
|
+
class BalancesProvider {
|
10341
|
+
#chaindataProvider;
|
10342
|
+
#chainConnectors;
|
10343
|
+
#storage;
|
10344
|
+
constructor(chaindataProvider, chainConnectors, storage = DEFAULT_STORAGE) {
|
10345
|
+
this.#chaindataProvider = chaindataProvider;
|
10346
|
+
this.#chainConnectors = chainConnectors;
|
10347
|
+
this.#storage = new BehaviorSubject({
|
10348
|
+
balances: keyBy(storage.balances.filter(isNotNil), b => getBalanceId(b)),
|
10349
|
+
miniMetadatas: keyBy(storage.miniMetadatas.filter(isNotNil), m => m.id)
|
10350
|
+
});
|
10351
|
+
}
|
10352
|
+
get storage$() {
|
10353
|
+
return this.#storage.pipe(map(({
|
10354
|
+
balances,
|
10355
|
+
miniMetadatas
|
10356
|
+
}) => ({
|
10357
|
+
balances: values(balances).filter(isNotNil),
|
10358
|
+
miniMetadatas: values(miniMetadatas).filter(isNotNil)
|
10359
|
+
})));
|
10360
|
+
}
|
10361
|
+
getBalances$(addressesByToken) {
|
10362
|
+
const networkIds = uniq(keys(addressesByToken).map(tokenId => parseTokenId(tokenId).networkId));
|
10363
|
+
return combineLatest(networkIds.map(networkId => this.getNetworkBalances$(networkId, addressesByToken))).pipe(map(results => {
|
10364
|
+
return {
|
10365
|
+
status: results.some(({
|
10366
|
+
status
|
10367
|
+
}) => status === "initialising") ? "initialising" : "live",
|
10368
|
+
balances: results.flatMap(result => result.balances)
|
10369
|
+
};
|
10370
|
+
}), startWith({
|
10371
|
+
status: "initialising",
|
10372
|
+
balances: this.getStoredBalances(addressesByToken)
|
10373
|
+
}), distinctUntilChanged(isEqual));
|
10374
|
+
}
|
10375
|
+
getNetworkBalances$(networkId, addressesByTokenId) {
|
10376
|
+
const network$ = this.#chaindataProvider.getNetworkById$(networkId);
|
10377
|
+
const tokensMapById$ = this.#chaindataProvider.getTokensMapById$();
|
10378
|
+
const miniMetadatas$ = this.getNetworkMiniMetadatas$(networkId);
|
10379
|
+
return combineLatest([network$, miniMetadatas$, tokensMapById$]).pipe(switchMap(([network, miniMetadatas, tokensMapById]) => {
|
10380
|
+
const tokensAndAddresses = toPairs(addressesByTokenId).map(([tokenId, addresses]) => [tokensMapById[tokenId], addresses]);
|
10381
|
+
return combineLatest(BALANCE_MODULES.filter(mod => mod.platform === network?.platform).map(mod => {
|
10382
|
+
const tokensWithAddresses = tokensAndAddresses.filter(([token]) => token.type === mod.type);
|
10383
|
+
const moduleAddressesByTokenId = fromPairs(tokensWithAddresses.map(([token, addresses]) => [token.id, addresses]));
|
10384
|
+
const miniMetadata = miniMetadatas.find(m => m.source === mod.type);
|
10385
|
+
|
10386
|
+
// all balance ids expected in result set
|
10387
|
+
const balanceIds = toPairs(moduleAddressesByTokenId).flatMap(([tokenId, addresses]) => addresses.map(address => getBalanceId({
|
10388
|
+
tokenId,
|
10389
|
+
address
|
10390
|
+
})));
|
10391
|
+
const initValue = {
|
10392
|
+
status: "initialising",
|
10393
|
+
balances: this.getStoredBalances(moduleAddressesByTokenId)
|
10394
|
+
};
|
10395
|
+
const updateStorage = results => {
|
10396
|
+
if (results.status !== "live") return;
|
10397
|
+
const storage = this.#storage.getValue();
|
10398
|
+
const balances = assign({}, storage.balances,
|
10399
|
+
// delete all balances expected in the result set. because if they are not present it means they are empty.
|
10400
|
+
fromPairs(balanceIds.map(balanceId => [balanceId, undefined])), keyBy(results.balances, b => getBalanceId(b)));
|
10401
|
+
this.#storage.next(assign({}, storage, {
|
10402
|
+
balances
|
10403
|
+
}));
|
10404
|
+
};
|
10405
|
+
switch (mod.platform) {
|
10406
|
+
case "ethereum":
|
10407
|
+
{
|
10408
|
+
if (!this.#chainConnectors.evm) return of(initValue);
|
10409
|
+
return mod.subscribeBalances({
|
10410
|
+
networkId,
|
10411
|
+
tokensWithAddresses,
|
10412
|
+
connector: this.#chainConnectors.evm
|
10413
|
+
}).pipe(map(results => ({
|
10414
|
+
status: "live",
|
10415
|
+
// exclude zero balances
|
10416
|
+
balances: results.success.filter(b => new Balance(b).total.planck > 0n)
|
10417
|
+
})), tap(updateStorage), startWith(initValue));
|
10418
|
+
}
|
10419
|
+
case "polkadot":
|
10420
|
+
if (!this.#chainConnectors.substrate || !miniMetadata) {
|
10421
|
+
log.debug("[balances] no substrate connector or miniMetadata for polkadot", mod.type);
|
10422
|
+
return of(initValue);
|
10423
|
+
}
|
10424
|
+
return mod.subscribeBalances({
|
10425
|
+
networkId,
|
10426
|
+
tokensWithAddresses,
|
10427
|
+
connector: this.#chainConnectors.substrate,
|
10428
|
+
miniMetadata: miniMetadata
|
10429
|
+
}).pipe(map(results => ({
|
10430
|
+
status: "live",
|
10431
|
+
// exclude zero balances
|
10432
|
+
balances: results.success.filter(b => new Balance(b).total.planck > 0n)
|
10433
|
+
})), tap(updateStorage), startWith(initValue));
|
10434
|
+
}
|
10435
|
+
}));
|
10436
|
+
}), map(results => {
|
10437
|
+
return {
|
10438
|
+
status: results.some(({
|
10439
|
+
status
|
10440
|
+
}) => status === "initialising") ? "initialising" : "live",
|
10441
|
+
balances: results.flatMap(result => result.balances)
|
10442
|
+
};
|
10443
|
+
}));
|
10444
|
+
}
|
10445
|
+
getNetworkMiniMetadatas$(networkId) {
|
10446
|
+
return this.#chaindataProvider.getNetworkById$(networkId).pipe(switchMap(network => isNetworkDot(network) && this.#chainConnectors.substrate ? from(getMiniMetadatas(this.#chainConnectors.substrate, this.#chaindataProvider, networkId)) : of([])));
|
10447
|
+
}
|
10448
|
+
getStoredBalances(addressesByToken) {
|
10449
|
+
const balanceDefs = toPairs(addressesByToken).flatMap(([tokenId, addresses]) => addresses.map(address => [tokenId, address]));
|
10450
|
+
return balanceDefs.map(([tokenId, address]) => this.#storage.value.balances[getBalanceId({
|
10451
|
+
address,
|
10452
|
+
tokenId
|
10453
|
+
})]).filter(isNotNil);
|
10454
|
+
}
|
10455
|
+
}
|
10456
|
+
|
10457
|
+
// const getStoredBalances = (
|
10458
|
+
// storedBalances: Record<string, IBalance>,
|
10459
|
+
// addressesByToken: Record<TokenId, Address[]>,
|
10460
|
+
// ): IBalance[] => {
|
10461
|
+
|
10462
|
+
// }
|
10463
|
+
|
10464
|
+
export { BALANCE_MODULES, Balance, BalanceFormatter, BalanceValueGetter, Balances, BalancesProvider, Change24hCurrencyFormatter, DefaultBalanceModule, EvmErc20BalanceModule, EvmErc20TokenConfigSchema, EvmNativeBalanceModule, EvmNativeTokenConfigSchema, EvmUniswapV2BalanceModule, EvmUniswapV2TokenConfigSchema, FiatSumBalancesFormatter, ONE_ALPHA_TOKEN$1 as ONE_ALPHA_TOKEN, PlanckSumBalancesFormatter, RpcStateQueryHelper, SCALE_FACTOR$1 as SCALE_FACTOR, SUBTENSOR_MIN_STAKE_AMOUNT_PLANK$1 as SUBTENSOR_MIN_STAKE_AMOUNT_PLANK, SUBTENSOR_ROOT_NETUID$1 as SUBTENSOR_ROOT_NETUID, SubAssetsBalanceModule, SubAssetsTokenConfigSchema, SubForeignAssetsBalanceModule, SubForeignAssetsTokenConfigSchema, SubHydrationBalanceModule, SubHydrationTokenConfigSchema, SubNativeBalanceModule, SubNativeMiniMetadataExtraSchema, SubNativeModuleConfigSchema, SubNativeTokenConfigSchema, SubPsp22BalanceModule, SubPsp22TokenConfigSchema, SubTokensBalanceModule, SubTokensMiniMetadataExtraSchema, SubTokensModuleConfigSchema, SubTokensTokenConfigSchema, SumBalancesFormatter, TalismanBalancesDatabase, abiMulticall, balances, buildNetworkStorageCoders, buildStorageCoders, calculateAlphaPrice$1 as calculateAlphaPrice, calculateTaoAmountFromAlpha$1 as calculateTaoAmountFromAlpha, calculateTaoFromDynamicInfo$1 as calculateTaoFromDynamicInfo, compress, configureStore, db, decodeOutput, decompress, defaultBalanceModules, deriveMiniMetadataId, detectTransferMethod, erc20BalancesAggregatorAbi, excludeFromFeePayableLocks, excludeFromTransferableAmount, filterBaseLocks, filterMirrorTokens, getBalanceId, getLockTitle, getLockedType$1 as getLockedType, getUniqueChainIds, getValueId, includeInTotalExtraAmount, makeContractCaller, uniswapV2PairAbi };
|