@metamask-previews/assets-controller 0.0.0-preview-3ec2a74 → 0.0.0-preview-6ae8a59c
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/CHANGELOG.md +5 -0
- package/dist/data-sources/RpcDataSource.cjs +415 -186
- package/dist/data-sources/RpcDataSource.cjs.map +1 -1
- package/dist/data-sources/RpcDataSource.d.cts +115 -30
- package/dist/data-sources/RpcDataSource.d.cts.map +1 -1
- package/dist/data-sources/RpcDataSource.d.mts +115 -30
- package/dist/data-sources/RpcDataSource.d.mts.map +1 -1
- package/dist/data-sources/RpcDataSource.mjs +413 -185
- package/dist/data-sources/RpcDataSource.mjs.map +1 -1
- package/dist/data-sources/evm-rpc-services/clients/MulticallClient.cjs.map +1 -0
- package/dist/data-sources/evm-rpc-services/clients/MulticallClient.d.cts.map +1 -0
- package/dist/data-sources/evm-rpc-services/clients/MulticallClient.d.mts.map +1 -0
- package/dist/data-sources/evm-rpc-services/clients/MulticallClient.mjs.map +1 -0
- package/dist/data-sources/evm-rpc-services/clients/index.cjs.map +1 -0
- package/dist/data-sources/evm-rpc-services/clients/index.d.cts.map +1 -0
- package/dist/data-sources/evm-rpc-services/clients/index.d.mts.map +1 -0
- package/dist/data-sources/evm-rpc-services/clients/index.mjs.map +1 -0
- package/dist/data-sources/{rpc-datasource → evm-rpc-services}/index.cjs +4 -1
- package/dist/data-sources/evm-rpc-services/index.cjs.map +1 -0
- package/dist/data-sources/evm-rpc-services/index.d.cts +5 -0
- package/dist/data-sources/evm-rpc-services/index.d.cts.map +1 -0
- package/dist/data-sources/evm-rpc-services/index.d.mts +5 -0
- package/dist/data-sources/evm-rpc-services/index.d.mts.map +1 -0
- package/dist/data-sources/{rpc-datasource → evm-rpc-services}/index.mjs +1 -0
- package/dist/data-sources/evm-rpc-services/index.mjs.map +1 -0
- package/dist/data-sources/{rpc-datasource → evm-rpc-services}/services/BalanceFetcher.cjs +33 -3
- package/dist/data-sources/evm-rpc-services/services/BalanceFetcher.cjs.map +1 -0
- package/dist/data-sources/evm-rpc-services/services/BalanceFetcher.d.cts +68 -0
- package/dist/data-sources/evm-rpc-services/services/BalanceFetcher.d.cts.map +1 -0
- package/dist/data-sources/evm-rpc-services/services/BalanceFetcher.d.mts +68 -0
- package/dist/data-sources/evm-rpc-services/services/BalanceFetcher.d.mts.map +1 -0
- package/dist/data-sources/{rpc-datasource → evm-rpc-services}/services/BalanceFetcher.mjs +33 -3
- package/dist/data-sources/evm-rpc-services/services/BalanceFetcher.mjs.map +1 -0
- package/dist/data-sources/{rpc-datasource → evm-rpc-services}/services/TokenDetector.cjs +33 -3
- package/dist/data-sources/evm-rpc-services/services/TokenDetector.cjs.map +1 -0
- package/dist/data-sources/evm-rpc-services/services/TokenDetector.d.cts +66 -0
- package/dist/data-sources/evm-rpc-services/services/TokenDetector.d.cts.map +1 -0
- package/dist/data-sources/evm-rpc-services/services/TokenDetector.d.mts +66 -0
- package/dist/data-sources/evm-rpc-services/services/TokenDetector.d.mts.map +1 -0
- package/dist/data-sources/{rpc-datasource → evm-rpc-services}/services/TokenDetector.mjs +33 -3
- package/dist/data-sources/evm-rpc-services/services/TokenDetector.mjs.map +1 -0
- package/dist/data-sources/evm-rpc-services/services/index.cjs.map +1 -0
- package/dist/data-sources/evm-rpc-services/services/index.d.cts +3 -0
- package/dist/data-sources/evm-rpc-services/services/index.d.cts.map +1 -0
- package/dist/data-sources/evm-rpc-services/services/index.d.mts +3 -0
- package/dist/data-sources/evm-rpc-services/services/index.d.mts.map +1 -0
- package/dist/data-sources/evm-rpc-services/services/index.mjs.map +1 -0
- package/dist/data-sources/evm-rpc-services/types/assets.cjs.map +1 -0
- package/dist/data-sources/evm-rpc-services/types/assets.d.cts.map +1 -0
- package/dist/data-sources/evm-rpc-services/types/assets.d.mts.map +1 -0
- package/dist/data-sources/evm-rpc-services/types/assets.mjs.map +1 -0
- package/dist/data-sources/evm-rpc-services/types/config.cjs.map +1 -0
- package/dist/data-sources/evm-rpc-services/types/config.d.cts.map +1 -0
- package/dist/data-sources/evm-rpc-services/types/config.d.mts.map +1 -0
- package/dist/data-sources/evm-rpc-services/types/config.mjs.map +1 -0
- package/dist/data-sources/evm-rpc-services/types/core.cjs.map +1 -0
- package/dist/data-sources/evm-rpc-services/types/core.d.cts.map +1 -0
- package/dist/data-sources/evm-rpc-services/types/core.d.mts.map +1 -0
- package/dist/data-sources/evm-rpc-services/types/core.mjs.map +1 -0
- package/dist/data-sources/evm-rpc-services/types/index.cjs.map +1 -0
- package/dist/data-sources/evm-rpc-services/types/index.d.cts.map +1 -0
- package/dist/data-sources/evm-rpc-services/types/index.d.mts.map +1 -0
- package/dist/data-sources/evm-rpc-services/types/index.mjs.map +1 -0
- package/dist/data-sources/evm-rpc-services/types/multicall.cjs.map +1 -0
- package/dist/data-sources/evm-rpc-services/types/multicall.d.cts.map +1 -0
- package/dist/data-sources/evm-rpc-services/types/multicall.d.mts.map +1 -0
- package/dist/data-sources/evm-rpc-services/types/multicall.mjs.map +1 -0
- package/dist/data-sources/evm-rpc-services/types/services.cjs.map +1 -0
- package/dist/data-sources/evm-rpc-services/types/services.d.cts.map +1 -0
- package/dist/data-sources/evm-rpc-services/types/services.d.mts.map +1 -0
- package/dist/data-sources/evm-rpc-services/types/services.mjs.map +1 -0
- package/dist/data-sources/evm-rpc-services/types/state.cjs.map +1 -0
- package/dist/data-sources/evm-rpc-services/types/state.d.cts.map +1 -0
- package/dist/data-sources/evm-rpc-services/types/state.d.mts.map +1 -0
- package/dist/data-sources/evm-rpc-services/types/state.mjs.map +1 -0
- package/dist/data-sources/evm-rpc-services/utils/batch.cjs.map +1 -0
- package/dist/data-sources/evm-rpc-services/utils/batch.d.cts.map +1 -0
- package/dist/data-sources/evm-rpc-services/utils/batch.d.mts.map +1 -0
- package/dist/data-sources/evm-rpc-services/utils/batch.mjs.map +1 -0
- package/dist/data-sources/evm-rpc-services/utils/index.cjs.map +1 -0
- package/dist/data-sources/evm-rpc-services/utils/index.d.cts.map +1 -0
- package/dist/data-sources/evm-rpc-services/utils/index.d.mts.map +1 -0
- package/dist/data-sources/evm-rpc-services/utils/index.mjs.map +1 -0
- package/dist/data-sources/initDataSources.cjs +5 -1
- package/dist/data-sources/initDataSources.cjs.map +1 -1
- package/dist/data-sources/initDataSources.d.cts +15 -0
- package/dist/data-sources/initDataSources.d.cts.map +1 -1
- package/dist/data-sources/initDataSources.d.mts +15 -0
- package/dist/data-sources/initDataSources.d.mts.map +1 -1
- package/dist/data-sources/initDataSources.mjs +5 -1
- package/dist/data-sources/initDataSources.mjs.map +1 -1
- package/package.json +5 -2
- package/dist/data-sources/rpc-datasource/clients/MulticallClient.cjs.map +0 -1
- package/dist/data-sources/rpc-datasource/clients/MulticallClient.d.cts.map +0 -1
- package/dist/data-sources/rpc-datasource/clients/MulticallClient.d.mts.map +0 -1
- package/dist/data-sources/rpc-datasource/clients/MulticallClient.mjs.map +0 -1
- package/dist/data-sources/rpc-datasource/clients/index.cjs.map +0 -1
- package/dist/data-sources/rpc-datasource/clients/index.d.cts.map +0 -1
- package/dist/data-sources/rpc-datasource/clients/index.d.mts.map +0 -1
- package/dist/data-sources/rpc-datasource/clients/index.mjs.map +0 -1
- package/dist/data-sources/rpc-datasource/index.cjs.map +0 -1
- package/dist/data-sources/rpc-datasource/index.d.cts +0 -4
- package/dist/data-sources/rpc-datasource/index.d.cts.map +0 -1
- package/dist/data-sources/rpc-datasource/index.d.mts +0 -4
- package/dist/data-sources/rpc-datasource/index.d.mts.map +0 -1
- package/dist/data-sources/rpc-datasource/index.mjs.map +0 -1
- package/dist/data-sources/rpc-datasource/services/BalanceFetcher.cjs.map +0 -1
- package/dist/data-sources/rpc-datasource/services/BalanceFetcher.d.cts +0 -16
- package/dist/data-sources/rpc-datasource/services/BalanceFetcher.d.cts.map +0 -1
- package/dist/data-sources/rpc-datasource/services/BalanceFetcher.d.mts +0 -16
- package/dist/data-sources/rpc-datasource/services/BalanceFetcher.d.mts.map +0 -1
- package/dist/data-sources/rpc-datasource/services/BalanceFetcher.mjs.map +0 -1
- package/dist/data-sources/rpc-datasource/services/TokenDetector.cjs.map +0 -1
- package/dist/data-sources/rpc-datasource/services/TokenDetector.d.cts +0 -14
- package/dist/data-sources/rpc-datasource/services/TokenDetector.d.cts.map +0 -1
- package/dist/data-sources/rpc-datasource/services/TokenDetector.d.mts +0 -14
- package/dist/data-sources/rpc-datasource/services/TokenDetector.d.mts.map +0 -1
- package/dist/data-sources/rpc-datasource/services/TokenDetector.mjs.map +0 -1
- package/dist/data-sources/rpc-datasource/services/index.cjs.map +0 -1
- package/dist/data-sources/rpc-datasource/services/index.d.cts +0 -3
- package/dist/data-sources/rpc-datasource/services/index.d.cts.map +0 -1
- package/dist/data-sources/rpc-datasource/services/index.d.mts +0 -3
- package/dist/data-sources/rpc-datasource/services/index.d.mts.map +0 -1
- package/dist/data-sources/rpc-datasource/services/index.mjs.map +0 -1
- package/dist/data-sources/rpc-datasource/types/assets.cjs.map +0 -1
- package/dist/data-sources/rpc-datasource/types/assets.d.cts.map +0 -1
- package/dist/data-sources/rpc-datasource/types/assets.d.mts.map +0 -1
- package/dist/data-sources/rpc-datasource/types/assets.mjs.map +0 -1
- package/dist/data-sources/rpc-datasource/types/config.cjs.map +0 -1
- package/dist/data-sources/rpc-datasource/types/config.d.cts.map +0 -1
- package/dist/data-sources/rpc-datasource/types/config.d.mts.map +0 -1
- package/dist/data-sources/rpc-datasource/types/config.mjs.map +0 -1
- package/dist/data-sources/rpc-datasource/types/core.cjs.map +0 -1
- package/dist/data-sources/rpc-datasource/types/core.d.cts.map +0 -1
- package/dist/data-sources/rpc-datasource/types/core.d.mts.map +0 -1
- package/dist/data-sources/rpc-datasource/types/core.mjs.map +0 -1
- package/dist/data-sources/rpc-datasource/types/index.cjs.map +0 -1
- package/dist/data-sources/rpc-datasource/types/index.d.cts.map +0 -1
- package/dist/data-sources/rpc-datasource/types/index.d.mts.map +0 -1
- package/dist/data-sources/rpc-datasource/types/index.mjs.map +0 -1
- package/dist/data-sources/rpc-datasource/types/multicall.cjs.map +0 -1
- package/dist/data-sources/rpc-datasource/types/multicall.d.cts.map +0 -1
- package/dist/data-sources/rpc-datasource/types/multicall.d.mts.map +0 -1
- package/dist/data-sources/rpc-datasource/types/multicall.mjs.map +0 -1
- package/dist/data-sources/rpc-datasource/types/services.cjs.map +0 -1
- package/dist/data-sources/rpc-datasource/types/services.d.cts.map +0 -1
- package/dist/data-sources/rpc-datasource/types/services.d.mts.map +0 -1
- package/dist/data-sources/rpc-datasource/types/services.mjs.map +0 -1
- package/dist/data-sources/rpc-datasource/types/state.cjs.map +0 -1
- package/dist/data-sources/rpc-datasource/types/state.d.cts.map +0 -1
- package/dist/data-sources/rpc-datasource/types/state.d.mts.map +0 -1
- package/dist/data-sources/rpc-datasource/types/state.mjs.map +0 -1
- package/dist/data-sources/rpc-datasource/utils/batch.cjs.map +0 -1
- package/dist/data-sources/rpc-datasource/utils/batch.d.cts.map +0 -1
- package/dist/data-sources/rpc-datasource/utils/batch.d.mts.map +0 -1
- package/dist/data-sources/rpc-datasource/utils/batch.mjs.map +0 -1
- package/dist/data-sources/rpc-datasource/utils/index.cjs.map +0 -1
- package/dist/data-sources/rpc-datasource/utils/index.d.cts.map +0 -1
- package/dist/data-sources/rpc-datasource/utils/index.d.mts.map +0 -1
- package/dist/data-sources/rpc-datasource/utils/index.mjs.map +0 -1
- /package/dist/data-sources/{rpc-datasource → evm-rpc-services}/clients/MulticallClient.cjs +0 -0
- /package/dist/data-sources/{rpc-datasource → evm-rpc-services}/clients/MulticallClient.d.cts +0 -0
- /package/dist/data-sources/{rpc-datasource → evm-rpc-services}/clients/MulticallClient.d.mts +0 -0
- /package/dist/data-sources/{rpc-datasource → evm-rpc-services}/clients/MulticallClient.mjs +0 -0
- /package/dist/data-sources/{rpc-datasource → evm-rpc-services}/clients/index.cjs +0 -0
- /package/dist/data-sources/{rpc-datasource → evm-rpc-services}/clients/index.d.cts +0 -0
- /package/dist/data-sources/{rpc-datasource → evm-rpc-services}/clients/index.d.mts +0 -0
- /package/dist/data-sources/{rpc-datasource → evm-rpc-services}/clients/index.mjs +0 -0
- /package/dist/data-sources/{rpc-datasource → evm-rpc-services}/services/index.cjs +0 -0
- /package/dist/data-sources/{rpc-datasource → evm-rpc-services}/services/index.mjs +0 -0
- /package/dist/data-sources/{rpc-datasource → evm-rpc-services}/types/assets.cjs +0 -0
- /package/dist/data-sources/{rpc-datasource → evm-rpc-services}/types/assets.d.cts +0 -0
- /package/dist/data-sources/{rpc-datasource → evm-rpc-services}/types/assets.d.mts +0 -0
- /package/dist/data-sources/{rpc-datasource → evm-rpc-services}/types/assets.mjs +0 -0
- /package/dist/data-sources/{rpc-datasource → evm-rpc-services}/types/config.cjs +0 -0
- /package/dist/data-sources/{rpc-datasource → evm-rpc-services}/types/config.d.cts +0 -0
- /package/dist/data-sources/{rpc-datasource → evm-rpc-services}/types/config.d.mts +0 -0
- /package/dist/data-sources/{rpc-datasource → evm-rpc-services}/types/config.mjs +0 -0
- /package/dist/data-sources/{rpc-datasource → evm-rpc-services}/types/core.cjs +0 -0
- /package/dist/data-sources/{rpc-datasource → evm-rpc-services}/types/core.d.cts +0 -0
- /package/dist/data-sources/{rpc-datasource → evm-rpc-services}/types/core.d.mts +0 -0
- /package/dist/data-sources/{rpc-datasource → evm-rpc-services}/types/core.mjs +0 -0
- /package/dist/data-sources/{rpc-datasource → evm-rpc-services}/types/index.cjs +0 -0
- /package/dist/data-sources/{rpc-datasource → evm-rpc-services}/types/index.d.cts +0 -0
- /package/dist/data-sources/{rpc-datasource → evm-rpc-services}/types/index.d.mts +0 -0
- /package/dist/data-sources/{rpc-datasource → evm-rpc-services}/types/index.mjs +0 -0
- /package/dist/data-sources/{rpc-datasource → evm-rpc-services}/types/multicall.cjs +0 -0
- /package/dist/data-sources/{rpc-datasource → evm-rpc-services}/types/multicall.d.cts +0 -0
- /package/dist/data-sources/{rpc-datasource → evm-rpc-services}/types/multicall.d.mts +0 -0
- /package/dist/data-sources/{rpc-datasource → evm-rpc-services}/types/multicall.mjs +0 -0
- /package/dist/data-sources/{rpc-datasource → evm-rpc-services}/types/services.cjs +0 -0
- /package/dist/data-sources/{rpc-datasource → evm-rpc-services}/types/services.d.cts +0 -0
- /package/dist/data-sources/{rpc-datasource → evm-rpc-services}/types/services.d.mts +0 -0
- /package/dist/data-sources/{rpc-datasource → evm-rpc-services}/types/services.mjs +0 -0
- /package/dist/data-sources/{rpc-datasource → evm-rpc-services}/types/state.cjs +0 -0
- /package/dist/data-sources/{rpc-datasource → evm-rpc-services}/types/state.d.cts +0 -0
- /package/dist/data-sources/{rpc-datasource → evm-rpc-services}/types/state.d.mts +0 -0
- /package/dist/data-sources/{rpc-datasource → evm-rpc-services}/types/state.mjs +0 -0
- /package/dist/data-sources/{rpc-datasource → evm-rpc-services}/utils/batch.cjs +0 -0
- /package/dist/data-sources/{rpc-datasource → evm-rpc-services}/utils/batch.d.cts +0 -0
- /package/dist/data-sources/{rpc-datasource → evm-rpc-services}/utils/batch.d.mts +0 -0
- /package/dist/data-sources/{rpc-datasource → evm-rpc-services}/utils/batch.mjs +0 -0
- /package/dist/data-sources/{rpc-datasource → evm-rpc-services}/utils/index.cjs +0 -0
- /package/dist/data-sources/{rpc-datasource → evm-rpc-services}/utils/index.d.cts +0 -0
- /package/dist/data-sources/{rpc-datasource → evm-rpc-services}/utils/index.d.mts +0 -0
- /package/dist/data-sources/{rpc-datasource → evm-rpc-services}/utils/index.mjs +0 -0
|
@@ -9,33 +9,37 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
9
9
|
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
10
10
|
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
11
11
|
};
|
|
12
|
-
var _RpcDataSource_instances,
|
|
12
|
+
var _RpcDataSource_instances, _RpcDataSource_timeout, _RpcDataSource_tokenDetectionEnabled, _RpcDataSource_activeChains, _RpcDataSource_chainStatuses, _RpcDataSource_providerCache, _RpcDataSource_activeSubscriptions, _RpcDataSource_multicallClient, _RpcDataSource_balanceFetcher, _RpcDataSource_tokenDetector, _RpcDataSource_handleBalanceUpdate, _RpcDataSource_handleDetectionUpdate, _RpcDataSource_registerActionHandlers, _RpcDataSource_subscribeToNetworkController, _RpcDataSource_initializeFromNetworkController, _RpcDataSource_updateFromNetworkState, _RpcDataSource_getProvider, _RpcDataSource_getMulticallProvider, _RpcDataSource_clearProviderCache, _RpcDataSource_accountSupportsChain, _RpcDataSource_buildNativeAssetId;
|
|
13
13
|
import { Web3Provider } from "@ethersproject/providers";
|
|
14
|
-
import {
|
|
14
|
+
import { BaseController } from "@metamask/base-controller";
|
|
15
|
+
import { toHex } from "@metamask/controller-utils";
|
|
16
|
+
import { isStrictHexString, isCaipChainId, parseCaipChainId } from "@metamask/utils";
|
|
17
|
+
import { BalanceFetcher, MulticallClient, TokenDetector } from "./evm-rpc-services/index.mjs";
|
|
15
18
|
import { projectLogger, createModuleLogger } from "../logger.mjs";
|
|
16
|
-
// ============================================================================
|
|
17
|
-
// CONSTANTS
|
|
18
|
-
// ============================================================================
|
|
19
19
|
const CONTROLLER_NAME = 'RpcDataSource';
|
|
20
|
-
const
|
|
20
|
+
const DEFAULT_BALANCE_INTERVAL = 30000; // 30 seconds
|
|
21
|
+
const DEFAULT_DETECTION_INTERVAL = 180000; // 3 minutes
|
|
21
22
|
const log = createModuleLogger(projectLogger, CONTROLLER_NAME);
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
23
|
+
/**
|
|
24
|
+
* Convert CAIP chain ID or hex chain ID to hex chain ID.
|
|
25
|
+
*
|
|
26
|
+
* @param chainId - CAIP chain ID or hex chain ID.
|
|
27
|
+
* @returns Hex chain ID.
|
|
28
|
+
*/
|
|
29
|
+
export const caipChainIdToHex = (chainId) => {
|
|
30
|
+
if (isStrictHexString(chainId)) {
|
|
31
|
+
return chainId;
|
|
32
|
+
}
|
|
33
|
+
if (isCaipChainId(chainId)) {
|
|
34
|
+
return toHex(parseCaipChainId(chainId).reference);
|
|
35
|
+
}
|
|
36
|
+
throw new Error('caipChainIdToHex - Failed to provide CAIP-2 or Hex chainId');
|
|
25
37
|
};
|
|
26
|
-
// ============================================================================
|
|
27
|
-
// HELPER FUNCTIONS
|
|
28
|
-
// ============================================================================
|
|
29
|
-
function buildNativeAssetId(chainId) {
|
|
30
|
-
return `${chainId}/slip44:60`;
|
|
31
|
-
}
|
|
32
|
-
// ============================================================================
|
|
33
|
-
// RPC DATA SOURCE
|
|
34
|
-
// ============================================================================
|
|
35
38
|
/**
|
|
36
39
|
* Data source for fetching balances via RPC calls.
|
|
37
40
|
*
|
|
38
|
-
*
|
|
41
|
+
* Orchestrates polling through BalanceFetcher and TokenDetector,
|
|
42
|
+
* each of which handle their own polling intervals.
|
|
39
43
|
*
|
|
40
44
|
* Communicates with AssetsController via Messenger:
|
|
41
45
|
*
|
|
@@ -49,88 +53,176 @@ function buildNativeAssetId(chainId) {
|
|
|
49
53
|
* - RpcDataSource:activeChainsUpdated
|
|
50
54
|
* - RpcDataSource:assetsUpdated
|
|
51
55
|
*/
|
|
52
|
-
export class RpcDataSource extends
|
|
56
|
+
export class RpcDataSource extends BaseController {
|
|
53
57
|
constructor(options) {
|
|
54
|
-
super(
|
|
55
|
-
|
|
56
|
-
|
|
58
|
+
super({
|
|
59
|
+
name: CONTROLLER_NAME,
|
|
60
|
+
metadata: {},
|
|
61
|
+
state: {},
|
|
62
|
+
messenger: options.messenger,
|
|
57
63
|
});
|
|
58
64
|
_RpcDataSource_instances.add(this);
|
|
59
|
-
_RpcDataSource_messenger.set(this, void 0);
|
|
60
65
|
_RpcDataSource_timeout.set(this, void 0);
|
|
61
|
-
|
|
66
|
+
_RpcDataSource_tokenDetectionEnabled.set(this, void 0);
|
|
67
|
+
/** Currently active chains */
|
|
68
|
+
_RpcDataSource_activeChains.set(this, []);
|
|
69
|
+
/** Network status for each active chain */
|
|
70
|
+
_RpcDataSource_chainStatuses.set(this, {});
|
|
62
71
|
/** Cache of Web3Provider instances by chainId */
|
|
63
72
|
_RpcDataSource_providerCache.set(this, new Map());
|
|
64
|
-
|
|
73
|
+
/** Active subscriptions by ID */
|
|
74
|
+
_RpcDataSource_activeSubscriptions.set(this, new Map());
|
|
75
|
+
// Rpc-datasource components
|
|
76
|
+
_RpcDataSource_multicallClient.set(this, void 0);
|
|
77
|
+
_RpcDataSource_balanceFetcher.set(this, void 0);
|
|
78
|
+
_RpcDataSource_tokenDetector.set(this, void 0);
|
|
65
79
|
__classPrivateFieldSet(this, _RpcDataSource_timeout, options.timeout ?? 10000, "f");
|
|
66
|
-
__classPrivateFieldSet(this,
|
|
80
|
+
__classPrivateFieldSet(this, _RpcDataSource_tokenDetectionEnabled, options.tokenDetectionEnabled ?? false, "f");
|
|
81
|
+
const balanceInterval = options.balanceInterval ?? DEFAULT_BALANCE_INTERVAL;
|
|
82
|
+
const detectionInterval = options.detectionInterval ?? DEFAULT_DETECTION_INTERVAL;
|
|
83
|
+
log('Initializing RpcDataSource', {
|
|
84
|
+
timeout: __classPrivateFieldGet(this, _RpcDataSource_timeout, "f"),
|
|
85
|
+
balanceInterval,
|
|
86
|
+
detectionInterval,
|
|
87
|
+
tokenDetectionEnabled: __classPrivateFieldGet(this, _RpcDataSource_tokenDetectionEnabled, "f"),
|
|
88
|
+
});
|
|
89
|
+
// Initialize MulticallClient with a provider getter
|
|
90
|
+
__classPrivateFieldSet(this, _RpcDataSource_multicallClient, new MulticallClient((hexChainId) => {
|
|
91
|
+
return __classPrivateFieldGet(this, _RpcDataSource_instances, "m", _RpcDataSource_getMulticallProvider).call(this, hexChainId);
|
|
92
|
+
}), "f");
|
|
93
|
+
// Create state getters using messenger
|
|
94
|
+
const getTokenListState = () => {
|
|
95
|
+
return this.messenger.call('TokenListController:getState');
|
|
96
|
+
};
|
|
97
|
+
const getUserTokensState = () => {
|
|
98
|
+
return this.messenger.call('AssetsController:getState');
|
|
99
|
+
};
|
|
100
|
+
// Initialize BalanceFetcher with polling interval
|
|
101
|
+
__classPrivateFieldSet(this, _RpcDataSource_balanceFetcher, new BalanceFetcher(__classPrivateFieldGet(this, _RpcDataSource_multicallClient, "f"), {
|
|
102
|
+
pollingInterval: balanceInterval,
|
|
103
|
+
}), "f");
|
|
104
|
+
__classPrivateFieldGet(this, _RpcDataSource_balanceFetcher, "f").setUserTokensStateGetter(getUserTokensState);
|
|
105
|
+
__classPrivateFieldGet(this, _RpcDataSource_balanceFetcher, "f").setOnBalanceUpdate(__classPrivateFieldGet(this, _RpcDataSource_instances, "m", _RpcDataSource_handleBalanceUpdate).bind(this));
|
|
106
|
+
// Initialize TokenDetector with polling interval
|
|
107
|
+
__classPrivateFieldSet(this, _RpcDataSource_tokenDetector, new TokenDetector(__classPrivateFieldGet(this, _RpcDataSource_multicallClient, "f"), {
|
|
108
|
+
pollingInterval: detectionInterval,
|
|
109
|
+
}), "f");
|
|
110
|
+
__classPrivateFieldGet(this, _RpcDataSource_tokenDetector, "f").setTokenListStateGetter(getTokenListState);
|
|
111
|
+
__classPrivateFieldGet(this, _RpcDataSource_tokenDetector, "f").setOnDetectionUpdate(__classPrivateFieldGet(this, _RpcDataSource_instances, "m", _RpcDataSource_handleDetectionUpdate).bind(this));
|
|
67
112
|
__classPrivateFieldGet(this, _RpcDataSource_instances, "m", _RpcDataSource_registerActionHandlers).call(this);
|
|
68
113
|
__classPrivateFieldGet(this, _RpcDataSource_instances, "m", _RpcDataSource_subscribeToNetworkController).call(this);
|
|
69
114
|
__classPrivateFieldGet(this, _RpcDataSource_instances, "m", _RpcDataSource_initializeFromNetworkController).call(this);
|
|
70
115
|
}
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
116
|
+
/**
|
|
117
|
+
* Get the data source name.
|
|
118
|
+
*
|
|
119
|
+
* @returns The name of this data source.
|
|
120
|
+
*/
|
|
121
|
+
getName() {
|
|
122
|
+
return this.name;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Get currently active chains.
|
|
126
|
+
*
|
|
127
|
+
* @returns Promise resolving to array of active chain IDs.
|
|
128
|
+
*/
|
|
129
|
+
async getActiveChains() {
|
|
130
|
+
return __classPrivateFieldGet(this, _RpcDataSource_activeChains, "f");
|
|
131
|
+
}
|
|
74
132
|
/**
|
|
75
133
|
* Get the status of all configured chains.
|
|
76
134
|
*
|
|
77
135
|
* @returns Record of chain statuses keyed by chain ID.
|
|
78
136
|
*/
|
|
79
137
|
getChainStatuses() {
|
|
80
|
-
return { ...this
|
|
138
|
+
return { ...__classPrivateFieldGet(this, _RpcDataSource_chainStatuses, "f") };
|
|
81
139
|
}
|
|
82
140
|
/**
|
|
83
141
|
* Get the status of a specific chain.
|
|
84
142
|
*
|
|
85
|
-
* @param chainId - The
|
|
86
|
-
* @returns The chain status
|
|
143
|
+
* @param chainId - The chain ID to get status for.
|
|
144
|
+
* @returns The chain status or undefined if not found.
|
|
87
145
|
*/
|
|
88
146
|
getChainStatus(chainId) {
|
|
89
|
-
return this
|
|
147
|
+
return __classPrivateFieldGet(this, _RpcDataSource_chainStatuses, "f")[chainId];
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Set the balance polling interval.
|
|
151
|
+
*
|
|
152
|
+
* @param interval - The polling interval in milliseconds.
|
|
153
|
+
*/
|
|
154
|
+
setBalancePollingInterval(interval) {
|
|
155
|
+
log('Setting balance polling interval', { interval });
|
|
156
|
+
__classPrivateFieldGet(this, _RpcDataSource_balanceFetcher, "f").setIntervalLength(interval);
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Get the current balance polling interval.
|
|
160
|
+
*
|
|
161
|
+
* @returns The polling interval in milliseconds, or undefined if not set.
|
|
162
|
+
*/
|
|
163
|
+
getBalancePollingInterval() {
|
|
164
|
+
return __classPrivateFieldGet(this, _RpcDataSource_balanceFetcher, "f").getIntervalLength();
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Set the token detection polling interval.
|
|
168
|
+
*
|
|
169
|
+
* @param interval - The polling interval in milliseconds.
|
|
170
|
+
*/
|
|
171
|
+
setDetectionPollingInterval(interval) {
|
|
172
|
+
log('Setting detection polling interval', { interval });
|
|
173
|
+
__classPrivateFieldGet(this, _RpcDataSource_tokenDetector, "f").setIntervalLength(interval);
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Get the current token detection polling interval.
|
|
177
|
+
*
|
|
178
|
+
* @returns The polling interval in milliseconds, or undefined if not set.
|
|
179
|
+
*/
|
|
180
|
+
getDetectionPollingInterval() {
|
|
181
|
+
return __classPrivateFieldGet(this, _RpcDataSource_tokenDetector, "f").getIntervalLength();
|
|
90
182
|
}
|
|
91
|
-
// ============================================================================
|
|
92
|
-
// FETCH
|
|
93
|
-
// ============================================================================
|
|
94
183
|
async fetch(request) {
|
|
95
184
|
const response = {};
|
|
96
|
-
|
|
97
|
-
|
|
185
|
+
const chainsToFetch = request.chainIds.filter((chainId) => __classPrivateFieldGet(this, _RpcDataSource_activeChains, "f").includes(chainId));
|
|
186
|
+
log('Fetch requested', {
|
|
187
|
+
accounts: request.accounts.map((a) => a.id),
|
|
188
|
+
requestedChains: request.chainIds,
|
|
189
|
+
chainsToFetch,
|
|
190
|
+
});
|
|
98
191
|
if (chainsToFetch.length === 0) {
|
|
192
|
+
log('No active chains to fetch');
|
|
99
193
|
return response;
|
|
100
194
|
}
|
|
101
195
|
const assetsBalance = {};
|
|
102
196
|
const failedChains = [];
|
|
103
|
-
// Fetch
|
|
197
|
+
// Fetch balances for each chain using BalanceFetcher
|
|
104
198
|
for (const chainId of chainsToFetch) {
|
|
105
|
-
const
|
|
106
|
-
if (!provider) {
|
|
107
|
-
continue;
|
|
108
|
-
}
|
|
109
|
-
const assetId = buildNativeAssetId(chainId);
|
|
110
|
-
// Fetch balance for each account that supports this chain
|
|
199
|
+
const hexChainId = caipChainIdToHex(chainId);
|
|
111
200
|
for (const account of request.accounts) {
|
|
112
|
-
// Check if account supports this chain based on its scopes
|
|
113
201
|
if (!__classPrivateFieldGet(this, _RpcDataSource_instances, "m", _RpcDataSource_accountSupportsChain).call(this, account, chainId)) {
|
|
114
202
|
continue;
|
|
115
203
|
}
|
|
116
204
|
const { address, id: accountId } = account;
|
|
117
205
|
try {
|
|
118
|
-
|
|
119
|
-
const
|
|
120
|
-
|
|
206
|
+
// Use BalanceFetcher for batched balance fetching
|
|
207
|
+
const result = await __classPrivateFieldGet(this, _RpcDataSource_balanceFetcher, "f").fetchBalancesForTokens(hexChainId, accountId, address, [], // Empty array means just native token
|
|
208
|
+
{ includeNative: true });
|
|
121
209
|
if (!assetsBalance[accountId]) {
|
|
122
210
|
assetsBalance[accountId] = {};
|
|
123
211
|
}
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
212
|
+
// Convert balances to response format
|
|
213
|
+
for (const balance of result.balances) {
|
|
214
|
+
assetsBalance[accountId][balance.assetId] = {
|
|
215
|
+
amount: balance.balance,
|
|
216
|
+
};
|
|
217
|
+
}
|
|
127
218
|
}
|
|
128
219
|
catch (error) {
|
|
129
220
|
log('Failed to fetch balance', { address, chainId, error });
|
|
130
221
|
if (!assetsBalance[accountId]) {
|
|
131
222
|
assetsBalance[accountId] = {};
|
|
132
223
|
}
|
|
133
|
-
|
|
224
|
+
const nativeAssetId = __classPrivateFieldGet(this, _RpcDataSource_instances, "m", _RpcDataSource_buildNativeAssetId).call(this, chainId);
|
|
225
|
+
assetsBalance[accountId][nativeAssetId] = { amount: '0' };
|
|
134
226
|
if (!failedChains.includes(chainId)) {
|
|
135
227
|
failedChains.push(chainId);
|
|
136
228
|
}
|
|
@@ -138,68 +230,101 @@ export class RpcDataSource extends AbstractDataSource {
|
|
|
138
230
|
}
|
|
139
231
|
}
|
|
140
232
|
if (failedChains.length > 0) {
|
|
141
|
-
|
|
233
|
+
log('Fetch PARTIAL - some chains failed', {
|
|
234
|
+
successChains: chainsToFetch.filter((chain) => !failedChains.includes(chain)),
|
|
235
|
+
failedChains,
|
|
236
|
+
});
|
|
142
237
|
response.errors = {};
|
|
143
238
|
for (const chainId of failedChains) {
|
|
144
239
|
response.errors[chainId] = 'RPC fetch failed';
|
|
145
240
|
}
|
|
146
241
|
}
|
|
242
|
+
else {
|
|
243
|
+
log('Fetch SUCCESS', {
|
|
244
|
+
chains: chainsToFetch,
|
|
245
|
+
accountCount: Object.keys(assetsBalance).length,
|
|
246
|
+
});
|
|
247
|
+
}
|
|
147
248
|
response.assetsBalance = assetsBalance;
|
|
148
249
|
return response;
|
|
149
250
|
}
|
|
150
|
-
// ============================================================================
|
|
151
|
-
// MIDDLEWARE
|
|
152
|
-
// ============================================================================
|
|
153
251
|
/**
|
|
154
|
-
*
|
|
155
|
-
* This middleware:
|
|
156
|
-
* - Supports multiple accounts in a single request
|
|
157
|
-
* - Filters request to only chains this data source supports
|
|
158
|
-
* - Fetches balances for those chains for all accounts
|
|
159
|
-
* - Merges response into context
|
|
160
|
-
* - Removes handled chains from request for next middleware
|
|
252
|
+
* Run token detection for an account on a chain.
|
|
161
253
|
*
|
|
162
|
-
* @
|
|
254
|
+
* @param chainId - The chain ID to detect tokens on.
|
|
255
|
+
* @param account - The account to detect tokens for.
|
|
256
|
+
* @returns Promise resolving to a DataResponse with detected assets.
|
|
163
257
|
*/
|
|
258
|
+
async detectTokens(chainId, account) {
|
|
259
|
+
if (!__classPrivateFieldGet(this, _RpcDataSource_tokenDetectionEnabled, "f")) {
|
|
260
|
+
return {};
|
|
261
|
+
}
|
|
262
|
+
const hexChainId = caipChainIdToHex(chainId);
|
|
263
|
+
const { address, id: accountId } = account;
|
|
264
|
+
log('Running token detection', { chainId, accountId });
|
|
265
|
+
try {
|
|
266
|
+
const result = await __classPrivateFieldGet(this, _RpcDataSource_tokenDetector, "f").detectTokens(hexChainId, accountId, address);
|
|
267
|
+
if (result.detectedAssets.length === 0) {
|
|
268
|
+
log('No new tokens detected');
|
|
269
|
+
return {};
|
|
270
|
+
}
|
|
271
|
+
log('Detected new tokens', {
|
|
272
|
+
count: result.detectedAssets.length,
|
|
273
|
+
chainId,
|
|
274
|
+
accountId,
|
|
275
|
+
});
|
|
276
|
+
// Convert detected assets to DataResponse format
|
|
277
|
+
const balances = {};
|
|
278
|
+
// Add balances for detected tokens
|
|
279
|
+
for (const balance of result.detectedBalances) {
|
|
280
|
+
balances[balance.assetId] = {
|
|
281
|
+
amount: balance.balance,
|
|
282
|
+
};
|
|
283
|
+
}
|
|
284
|
+
const response = {
|
|
285
|
+
detectedAssets: {
|
|
286
|
+
[accountId]: result.detectedAssets.map((asset) => asset.assetId),
|
|
287
|
+
},
|
|
288
|
+
assetsBalance: {
|
|
289
|
+
[accountId]: balances,
|
|
290
|
+
},
|
|
291
|
+
};
|
|
292
|
+
return response;
|
|
293
|
+
}
|
|
294
|
+
catch (error) {
|
|
295
|
+
log('Token detection failed', { chainId, accountId, error });
|
|
296
|
+
return {};
|
|
297
|
+
}
|
|
298
|
+
}
|
|
164
299
|
get assetsMiddleware() {
|
|
165
300
|
return async (context, next) => {
|
|
166
|
-
var _a;
|
|
301
|
+
var _a, _b;
|
|
167
302
|
const { request } = context;
|
|
168
|
-
|
|
169
|
-
const supportedChains = request.chainIds.filter((chainId) => this.state.activeChains.includes(chainId));
|
|
170
|
-
// If no supported chains, skip and pass to next middleware
|
|
303
|
+
const supportedChains = request.chainIds.filter((chainId) => __classPrivateFieldGet(this, _RpcDataSource_activeChains, "f").includes(chainId));
|
|
171
304
|
if (supportedChains.length === 0) {
|
|
172
305
|
return next(context);
|
|
173
306
|
}
|
|
174
307
|
let successfullyHandledChains = [];
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
context.response.assetsBalance[accountId]
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
};
|
|
192
|
-
}
|
|
308
|
+
log('Middleware fetching', {
|
|
309
|
+
chains: supportedChains,
|
|
310
|
+
accounts: request.accounts.map((a) => a.id),
|
|
311
|
+
});
|
|
312
|
+
const response = await this.fetch({
|
|
313
|
+
...request,
|
|
314
|
+
chainIds: supportedChains,
|
|
315
|
+
});
|
|
316
|
+
if (response.assetsBalance) {
|
|
317
|
+
(_a = context.response).assetsBalance ?? (_a.assetsBalance = {});
|
|
318
|
+
for (const [accountId, accountBalances] of Object.entries(response.assetsBalance)) {
|
|
319
|
+
(_b = context.response.assetsBalance)[accountId] ?? (_b[accountId] = {});
|
|
320
|
+
context.response.assetsBalance[accountId] = {
|
|
321
|
+
...context.response.assetsBalance[accountId],
|
|
322
|
+
...accountBalances,
|
|
323
|
+
};
|
|
193
324
|
}
|
|
194
|
-
// Determine successfully handled chains (exclude errors)
|
|
195
|
-
const failedChains = new Set(Object.keys(response.errors ?? {}));
|
|
196
|
-
successfullyHandledChains = supportedChains.filter((chainId) => !failedChains.has(chainId));
|
|
197
325
|
}
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
successfullyHandledChains = [];
|
|
201
|
-
}
|
|
202
|
-
// Remove successfully handled chains from request for next middleware
|
|
326
|
+
const failedChains = new Set(Object.keys(response.errors ?? {}));
|
|
327
|
+
successfullyHandledChains = supportedChains.filter((chainId) => !failedChains.has(chainId));
|
|
203
328
|
if (successfullyHandledChains.length > 0) {
|
|
204
329
|
const remainingChains = request.chainIds.filter((chainId) => !successfullyHandledChains.includes(chainId));
|
|
205
330
|
return next({
|
|
@@ -210,87 +335,184 @@ export class RpcDataSource extends AbstractDataSource {
|
|
|
210
335
|
},
|
|
211
336
|
});
|
|
212
337
|
}
|
|
213
|
-
// No chains handled - pass context unchanged
|
|
214
338
|
return next(context);
|
|
215
339
|
};
|
|
216
340
|
}
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
341
|
+
/**
|
|
342
|
+
* Subscribe to updates for the given request.
|
|
343
|
+
* Starts polling through BalanceFetcher and TokenDetector.
|
|
344
|
+
*
|
|
345
|
+
* @param subscriptionRequest - The subscription request details.
|
|
346
|
+
*/
|
|
220
347
|
async subscribe(subscriptionRequest) {
|
|
221
348
|
const { request, subscriptionId, isUpdate } = subscriptionRequest;
|
|
222
|
-
|
|
223
|
-
|
|
349
|
+
const chainsToSubscribe = request.chainIds.filter((chainId) => __classPrivateFieldGet(this, _RpcDataSource_activeChains, "f").includes(chainId));
|
|
350
|
+
log('Subscribe requested', {
|
|
351
|
+
subscriptionId,
|
|
352
|
+
isUpdate,
|
|
353
|
+
accounts: request.accounts.map((a) => a.id),
|
|
354
|
+
chainsToSubscribe,
|
|
355
|
+
});
|
|
224
356
|
if (chainsToSubscribe.length === 0) {
|
|
357
|
+
log('No active chains to subscribe');
|
|
225
358
|
return;
|
|
226
359
|
}
|
|
227
|
-
// Handle subscription update
|
|
360
|
+
// Handle subscription update
|
|
228
361
|
if (isUpdate) {
|
|
229
|
-
const existing = this.
|
|
362
|
+
const existing = __classPrivateFieldGet(this, _RpcDataSource_activeSubscriptions, "f").get(subscriptionId);
|
|
230
363
|
if (existing) {
|
|
364
|
+
log('Updating existing subscription', {
|
|
365
|
+
subscriptionId,
|
|
366
|
+
chainsToSubscribe,
|
|
367
|
+
});
|
|
231
368
|
existing.chains = chainsToSubscribe;
|
|
232
|
-
existing.
|
|
369
|
+
existing.accounts = request.accounts;
|
|
233
370
|
return;
|
|
234
371
|
}
|
|
235
372
|
}
|
|
236
373
|
// Clean up existing subscription
|
|
237
374
|
await this.unsubscribe(subscriptionId);
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
const
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
375
|
+
// Start polling through BalanceFetcher and TokenDetector
|
|
376
|
+
const balancePollingTokens = [];
|
|
377
|
+
const detectionPollingTokens = [];
|
|
378
|
+
for (const chainId of chainsToSubscribe) {
|
|
379
|
+
const hexChainId = caipChainIdToHex(chainId);
|
|
380
|
+
for (const account of request.accounts) {
|
|
381
|
+
if (!__classPrivateFieldGet(this, _RpcDataSource_instances, "m", _RpcDataSource_accountSupportsChain).call(this, account, chainId)) {
|
|
382
|
+
continue;
|
|
383
|
+
}
|
|
384
|
+
const { address, id: accountId } = account;
|
|
385
|
+
// Start balance polling
|
|
386
|
+
const balanceInput = {
|
|
387
|
+
chainId: hexChainId,
|
|
388
|
+
accountId,
|
|
389
|
+
accountAddress: address,
|
|
390
|
+
};
|
|
391
|
+
const balanceToken = __classPrivateFieldGet(this, _RpcDataSource_balanceFetcher, "f").startPolling(balanceInput);
|
|
392
|
+
balancePollingTokens.push(balanceToken);
|
|
393
|
+
// Start detection polling if enabled
|
|
394
|
+
if (__classPrivateFieldGet(this, _RpcDataSource_tokenDetectionEnabled, "f")) {
|
|
395
|
+
const detectionInput = {
|
|
396
|
+
chainId: hexChainId,
|
|
397
|
+
accountId,
|
|
398
|
+
accountAddress: address,
|
|
399
|
+
};
|
|
400
|
+
const detectionToken = __classPrivateFieldGet(this, _RpcDataSource_tokenDetector, "f").startPolling(detectionInput);
|
|
401
|
+
detectionPollingTokens.push(detectionToken);
|
|
245
402
|
}
|
|
246
|
-
// Use stored request (which gets updated on account changes)
|
|
247
|
-
const fetchResponse = await this.fetch({
|
|
248
|
-
...subscription.request,
|
|
249
|
-
chainIds: subscription.chains,
|
|
250
|
-
});
|
|
251
|
-
// Report update to AssetsController
|
|
252
|
-
await __classPrivateFieldGet(this, _RpcDataSource_messenger, "f").call('AssetsController:assetsUpdate', fetchResponse, CONTROLLER_NAME);
|
|
253
|
-
}
|
|
254
|
-
catch (error) {
|
|
255
|
-
log('Subscription poll failed', { subscriptionId, error });
|
|
256
403
|
}
|
|
257
|
-
}
|
|
258
|
-
//
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
404
|
+
}
|
|
405
|
+
// Store subscription data
|
|
406
|
+
__classPrivateFieldGet(this, _RpcDataSource_activeSubscriptions, "f").set(subscriptionId, {
|
|
407
|
+
balancePollingTokens,
|
|
408
|
+
detectionPollingTokens,
|
|
409
|
+
chains: chainsToSubscribe,
|
|
410
|
+
accounts: request.accounts,
|
|
411
|
+
});
|
|
412
|
+
log('Subscription SUCCESS', {
|
|
413
|
+
subscriptionId,
|
|
267
414
|
chains: chainsToSubscribe,
|
|
268
|
-
|
|
415
|
+
balancePollingCount: balancePollingTokens.length,
|
|
416
|
+
detectionPollingCount: detectionPollingTokens.length,
|
|
269
417
|
});
|
|
270
|
-
|
|
271
|
-
|
|
418
|
+
}
|
|
419
|
+
/**
|
|
420
|
+
* Unsubscribe from updates and stop polling.
|
|
421
|
+
*
|
|
422
|
+
* @param subscriptionId - The subscription ID to unsubscribe.
|
|
423
|
+
*/
|
|
424
|
+
async unsubscribe(subscriptionId) {
|
|
425
|
+
const subscription = __classPrivateFieldGet(this, _RpcDataSource_activeSubscriptions, "f").get(subscriptionId);
|
|
426
|
+
if (subscription) {
|
|
427
|
+
// Stop balance polling
|
|
428
|
+
for (const token of subscription.balancePollingTokens) {
|
|
429
|
+
__classPrivateFieldGet(this, _RpcDataSource_balanceFetcher, "f").stopPollingByPollingToken(token);
|
|
430
|
+
}
|
|
431
|
+
// Stop detection polling
|
|
432
|
+
for (const token of subscription.detectionPollingTokens) {
|
|
433
|
+
__classPrivateFieldGet(this, _RpcDataSource_tokenDetector, "f").stopPollingByPollingToken(token);
|
|
434
|
+
}
|
|
435
|
+
__classPrivateFieldGet(this, _RpcDataSource_activeSubscriptions, "f").delete(subscriptionId);
|
|
436
|
+
log('Unsubscribed and stopped polling', { subscriptionId });
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
/**
|
|
440
|
+
* Destroy the data source and clean up resources.
|
|
441
|
+
*/
|
|
442
|
+
destroy() {
|
|
443
|
+
log('Destroying RpcDataSource');
|
|
444
|
+
// Stop all polling
|
|
445
|
+
__classPrivateFieldGet(this, _RpcDataSource_balanceFetcher, "f").stopAllPolling();
|
|
446
|
+
__classPrivateFieldGet(this, _RpcDataSource_tokenDetector, "f").stopAllPolling();
|
|
447
|
+
// Clear subscriptions
|
|
448
|
+
__classPrivateFieldGet(this, _RpcDataSource_activeSubscriptions, "f").clear();
|
|
449
|
+
// Clear caches
|
|
450
|
+
__classPrivateFieldGet(this, _RpcDataSource_providerCache, "f").clear();
|
|
272
451
|
}
|
|
273
452
|
}
|
|
274
|
-
|
|
453
|
+
_RpcDataSource_timeout = new WeakMap(), _RpcDataSource_tokenDetectionEnabled = new WeakMap(), _RpcDataSource_activeChains = new WeakMap(), _RpcDataSource_chainStatuses = new WeakMap(), _RpcDataSource_providerCache = new WeakMap(), _RpcDataSource_activeSubscriptions = new WeakMap(), _RpcDataSource_multicallClient = new WeakMap(), _RpcDataSource_balanceFetcher = new WeakMap(), _RpcDataSource_tokenDetector = new WeakMap(), _RpcDataSource_instances = new WeakSet(), _RpcDataSource_handleBalanceUpdate = function _RpcDataSource_handleBalanceUpdate(result) {
|
|
454
|
+
const accountBalances = {};
|
|
455
|
+
for (const balance of result.balances) {
|
|
456
|
+
accountBalances[balance.assetId] = {
|
|
457
|
+
amount: balance.balance,
|
|
458
|
+
};
|
|
459
|
+
}
|
|
460
|
+
const response = {
|
|
461
|
+
assetsBalance: {
|
|
462
|
+
[result.accountId]: accountBalances,
|
|
463
|
+
},
|
|
464
|
+
};
|
|
465
|
+
this.messenger
|
|
466
|
+
.call('AssetsController:assetsUpdate', response, CONTROLLER_NAME)
|
|
467
|
+
.catch((error) => {
|
|
468
|
+
log('Failed to update assets', { error });
|
|
469
|
+
});
|
|
470
|
+
}, _RpcDataSource_handleDetectionUpdate = function _RpcDataSource_handleDetectionUpdate(result) {
|
|
471
|
+
log('Detected new tokens', {
|
|
472
|
+
count: result.detectedAssets.length,
|
|
473
|
+
});
|
|
474
|
+
const response = {
|
|
475
|
+
detectedAssets: {
|
|
476
|
+
[result.accountId]: result.detectedAssets.map((asset) => asset.assetId),
|
|
477
|
+
},
|
|
478
|
+
};
|
|
479
|
+
// Add balances for detected tokens
|
|
480
|
+
if (result.detectedBalances.length > 0) {
|
|
481
|
+
response.assetsBalance = {
|
|
482
|
+
[result.accountId]: {},
|
|
483
|
+
};
|
|
484
|
+
for (const balance of result.detectedBalances) {
|
|
485
|
+
response.assetsBalance[result.accountId][balance.assetId] = {
|
|
486
|
+
amount: balance.balance,
|
|
487
|
+
};
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
this.messenger
|
|
491
|
+
.call('AssetsController:assetsUpdate', response, CONTROLLER_NAME)
|
|
492
|
+
.catch((error) => {
|
|
493
|
+
log('Failed to update detected assets', { error });
|
|
494
|
+
});
|
|
495
|
+
}, _RpcDataSource_registerActionHandlers = function _RpcDataSource_registerActionHandlers() {
|
|
275
496
|
const getAssetsMiddlewareHandler = () => this.assetsMiddleware;
|
|
276
497
|
const getActiveChainsHandler = async () => this.getActiveChains();
|
|
277
498
|
const fetchHandler = async (request) => this.fetch(request);
|
|
278
499
|
const subscribeHandler = async (request) => this.subscribe(request);
|
|
279
500
|
const unsubscribeHandler = async (subscriptionId) => this.unsubscribe(subscriptionId);
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
501
|
+
this.messenger.registerActionHandler('RpcDataSource:getAssetsMiddleware', getAssetsMiddlewareHandler);
|
|
502
|
+
this.messenger.registerActionHandler('RpcDataSource:getActiveChains', getActiveChainsHandler);
|
|
503
|
+
this.messenger.registerActionHandler('RpcDataSource:fetch', fetchHandler);
|
|
504
|
+
this.messenger.registerActionHandler('RpcDataSource:subscribe', subscribeHandler);
|
|
505
|
+
this.messenger.registerActionHandler('RpcDataSource:unsubscribe', unsubscribeHandler);
|
|
285
506
|
}, _RpcDataSource_subscribeToNetworkController = function _RpcDataSource_subscribeToNetworkController() {
|
|
286
|
-
|
|
287
|
-
|
|
507
|
+
this.messenger.subscribe('NetworkController:stateChange', (networkState) => {
|
|
508
|
+
log('NetworkController state changed');
|
|
288
509
|
__classPrivateFieldGet(this, _RpcDataSource_instances, "m", _RpcDataSource_clearProviderCache).call(this);
|
|
289
510
|
__classPrivateFieldGet(this, _RpcDataSource_instances, "m", _RpcDataSource_updateFromNetworkState).call(this, networkState);
|
|
290
511
|
});
|
|
291
512
|
}, _RpcDataSource_initializeFromNetworkController = function _RpcDataSource_initializeFromNetworkController() {
|
|
513
|
+
log('Initializing from NetworkController');
|
|
292
514
|
try {
|
|
293
|
-
const networkState =
|
|
515
|
+
const networkState = this.messenger.call('NetworkController:getState');
|
|
294
516
|
__classPrivateFieldGet(this, _RpcDataSource_instances, "m", _RpcDataSource_updateFromNetworkState).call(this, networkState);
|
|
295
517
|
}
|
|
296
518
|
catch (error) {
|
|
@@ -300,19 +522,15 @@ _RpcDataSource_messenger = new WeakMap(), _RpcDataSource_timeout = new WeakMap()
|
|
|
300
522
|
const { networkConfigurationsByChainId, networksMetadata } = networkState;
|
|
301
523
|
const chainStatuses = {};
|
|
302
524
|
const activeChains = [];
|
|
303
|
-
// Iterate through all configured networks
|
|
304
525
|
for (const [hexChainId, config] of Object.entries(networkConfigurationsByChainId)) {
|
|
305
|
-
// Convert hex chainId to CAIP-2 format (eip155:decimal)
|
|
306
526
|
const decimalChainId = parseInt(hexChainId, 16);
|
|
307
527
|
const caip2ChainId = `eip155:${decimalChainId}`;
|
|
308
|
-
// Get the default RPC endpoint's network client ID
|
|
309
528
|
const defaultRpcEndpoint = config.rpcEndpoints[config.defaultRpcEndpointIndex];
|
|
310
529
|
if (!defaultRpcEndpoint) {
|
|
311
530
|
continue;
|
|
312
531
|
}
|
|
313
532
|
const { networkClientId } = defaultRpcEndpoint;
|
|
314
533
|
const metadata = networksMetadata[networkClientId];
|
|
315
|
-
// Determine status - default to 'unknown' if not in metadata
|
|
316
534
|
const status = metadata?.status ?? 'unknown';
|
|
317
535
|
chainStatuses[caip2ChainId] = {
|
|
318
536
|
chainId: caip2ChainId,
|
|
@@ -321,84 +539,94 @@ _RpcDataSource_messenger = new WeakMap(), _RpcDataSource_timeout = new WeakMap()
|
|
|
321
539
|
nativeCurrency: config.nativeCurrency,
|
|
322
540
|
networkClientId,
|
|
323
541
|
};
|
|
324
|
-
// Only include chains that have an available status
|
|
325
|
-
// (not degraded/unavailable/blocked)
|
|
326
542
|
if (status === 'available' || status === 'unknown') {
|
|
327
543
|
activeChains.push(caip2ChainId);
|
|
328
544
|
}
|
|
329
545
|
}
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
546
|
+
log('Network state updated', {
|
|
547
|
+
configuredChains: Object.keys(chainStatuses),
|
|
548
|
+
activeChains,
|
|
549
|
+
});
|
|
550
|
+
// Check if chains changed
|
|
551
|
+
const previousChains = new Set(__classPrivateFieldGet(this, _RpcDataSource_activeChains, "f"));
|
|
552
|
+
const hasChanges = previousChains.size !== activeChains.length ||
|
|
553
|
+
activeChains.some((chain) => !previousChains.has(chain));
|
|
554
|
+
// Update internal state
|
|
555
|
+
__classPrivateFieldSet(this, _RpcDataSource_chainStatuses, chainStatuses, "f");
|
|
556
|
+
__classPrivateFieldSet(this, _RpcDataSource_activeChains, activeChains, "f");
|
|
557
|
+
if (hasChanges) {
|
|
558
|
+
this.messenger.call('AssetsController:activeChainsUpdate', CONTROLLER_NAME, activeChains);
|
|
559
|
+
}
|
|
334
560
|
}, _RpcDataSource_getProvider = function _RpcDataSource_getProvider(chainId) {
|
|
335
|
-
// Check cache first
|
|
336
561
|
const cached = __classPrivateFieldGet(this, _RpcDataSource_providerCache, "f").get(chainId);
|
|
337
562
|
if (cached) {
|
|
338
563
|
return cached;
|
|
339
564
|
}
|
|
340
|
-
|
|
341
|
-
const chainStatus = this.state.chainStatuses[chainId];
|
|
565
|
+
const chainStatus = __classPrivateFieldGet(this, _RpcDataSource_chainStatuses, "f")[chainId];
|
|
342
566
|
if (!chainStatus) {
|
|
343
567
|
return undefined;
|
|
344
568
|
}
|
|
345
569
|
try {
|
|
346
|
-
|
|
347
|
-
const networkClient = __classPrivateFieldGet(this, _RpcDataSource_messenger, "f").call('NetworkController:getNetworkClientById', chainStatus.networkClientId);
|
|
348
|
-
// Create Web3Provider directly
|
|
570
|
+
const networkClient = this.messenger.call('NetworkController:getNetworkClientById', chainStatus.networkClientId);
|
|
349
571
|
const web3Provider = new Web3Provider(networkClient.provider);
|
|
350
|
-
// Cache for reuse
|
|
351
572
|
__classPrivateFieldGet(this, _RpcDataSource_providerCache, "f").set(chainId, web3Provider);
|
|
352
573
|
return web3Provider;
|
|
353
574
|
}
|
|
354
575
|
catch (error) {
|
|
355
|
-
|
|
576
|
+
log('Failed to get provider for chain', { chainId, error });
|
|
356
577
|
return undefined;
|
|
357
578
|
}
|
|
579
|
+
}, _RpcDataSource_getMulticallProvider = function _RpcDataSource_getMulticallProvider(hexChainId) {
|
|
580
|
+
const decimalChainId = parseInt(hexChainId, 16);
|
|
581
|
+
const caip2ChainId = `eip155:${decimalChainId}`;
|
|
582
|
+
const web3Provider = __classPrivateFieldGet(this, _RpcDataSource_instances, "m", _RpcDataSource_getProvider).call(this, caip2ChainId);
|
|
583
|
+
if (!web3Provider) {
|
|
584
|
+
throw new Error(`No provider available for chain ${hexChainId}`);
|
|
585
|
+
}
|
|
586
|
+
return {
|
|
587
|
+
call: async (params) => {
|
|
588
|
+
return web3Provider.call({
|
|
589
|
+
to: params.to,
|
|
590
|
+
data: params.data,
|
|
591
|
+
});
|
|
592
|
+
},
|
|
593
|
+
getBalance: async (address) => {
|
|
594
|
+
const balance = await web3Provider.getBalance(address);
|
|
595
|
+
return balance;
|
|
596
|
+
},
|
|
597
|
+
};
|
|
358
598
|
}, _RpcDataSource_clearProviderCache = function _RpcDataSource_clearProviderCache() {
|
|
359
599
|
__classPrivateFieldGet(this, _RpcDataSource_providerCache, "f").clear();
|
|
360
600
|
}, _RpcDataSource_accountSupportsChain = function _RpcDataSource_accountSupportsChain(account, chainId) {
|
|
361
601
|
const scopes = account.scopes ?? [];
|
|
362
|
-
// If no scopes defined, assume it supports the chain (backward compatibility)
|
|
363
602
|
if (scopes.length === 0) {
|
|
364
603
|
return true;
|
|
365
604
|
}
|
|
366
|
-
// Extract namespace and reference from chainId (e.g., "eip155:1" -> ["eip155", "1"])
|
|
367
605
|
const [chainNamespace, chainReference] = chainId.split(':');
|
|
368
606
|
for (const scope of scopes) {
|
|
369
607
|
const [scopeNamespace, scopeReference] = scope.split(':');
|
|
370
|
-
// Check if namespaces match
|
|
371
608
|
if (scopeNamespace !== chainNamespace) {
|
|
372
609
|
continue;
|
|
373
610
|
}
|
|
374
|
-
// Wildcard scope (e.g.,
|
|
611
|
+
// Wildcard scope (e.g., eip155:0) matches all chains in the namespace
|
|
375
612
|
if (scopeReference === '0') {
|
|
376
613
|
return true;
|
|
377
614
|
}
|
|
378
|
-
//
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
return true;
|
|
385
|
-
}
|
|
386
|
-
}
|
|
387
|
-
else if (scopeReference === chainReference) {
|
|
615
|
+
// RpcDataSource only handles eip155 (EVM) chains
|
|
616
|
+
// Normalize hex chain references (e.g., 0x1 -> 1) for comparison
|
|
617
|
+
const normalizedScopeRef = scopeReference?.startsWith('0x')
|
|
618
|
+
? parseInt(scopeReference, 16).toString()
|
|
619
|
+
: scopeReference;
|
|
620
|
+
if (normalizedScopeRef === chainReference) {
|
|
388
621
|
return true;
|
|
389
622
|
}
|
|
390
623
|
}
|
|
391
624
|
return false;
|
|
625
|
+
}, _RpcDataSource_buildNativeAssetId = function _RpcDataSource_buildNativeAssetId(chainId) {
|
|
626
|
+
const { nativeAssetIdentifiers } = this.messenger.call('NetworkEnablementController:getState');
|
|
627
|
+
return (nativeAssetIdentifiers[chainId] ??
|
|
628
|
+
`${chainId}/slip44:60`);
|
|
392
629
|
};
|
|
393
|
-
// ============================================================================
|
|
394
|
-
// FACTORY FUNCTION
|
|
395
|
-
// ============================================================================
|
|
396
|
-
/**
|
|
397
|
-
* Creates an RpcDataSource instance.
|
|
398
|
-
*
|
|
399
|
-
* @param options - Configuration options for the data source.
|
|
400
|
-
* @returns A new RpcDataSource instance.
|
|
401
|
-
*/
|
|
402
630
|
export function createRpcDataSource(options) {
|
|
403
631
|
return new RpcDataSource(options);
|
|
404
632
|
}
|