@metamask/assets-controllers 73.1.0 → 73.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +43 -1
- package/dist/AccountTrackerController.cjs +51 -1
- package/dist/AccountTrackerController.cjs.map +1 -1
- package/dist/AccountTrackerController.d.cts +40 -1
- package/dist/AccountTrackerController.d.cts.map +1 -1
- package/dist/AccountTrackerController.d.mts +40 -1
- package/dist/AccountTrackerController.d.mts.map +1 -1
- package/dist/AccountTrackerController.mjs +51 -1
- package/dist/AccountTrackerController.mjs.map +1 -1
- package/dist/TokenBalancesController.cjs +278 -319
- package/dist/TokenBalancesController.cjs.map +1 -1
- package/dist/TokenBalancesController.d.cts +51 -93
- package/dist/TokenBalancesController.d.cts.map +1 -1
- package/dist/TokenBalancesController.d.mts +51 -93
- package/dist/TokenBalancesController.d.mts.map +1 -1
- package/dist/TokenBalancesController.mjs +277 -317
- package/dist/TokenBalancesController.mjs.map +1 -1
- package/dist/assetsUtil.cjs +13 -1
- package/dist/assetsUtil.cjs.map +1 -1
- package/dist/assetsUtil.d.cts +8 -0
- package/dist/assetsUtil.d.cts.map +1 -1
- package/dist/assetsUtil.d.mts +8 -0
- package/dist/assetsUtil.d.mts.map +1 -1
- package/dist/assetsUtil.mjs +12 -1
- package/dist/assetsUtil.mjs.map +1 -1
- package/dist/balances.cjs +447 -0
- package/dist/balances.cjs.map +1 -0
- package/dist/balances.d.cts +88 -0
- package/dist/balances.d.cts.map +1 -0
- package/dist/balances.d.mts +88 -0
- package/dist/balances.d.mts.map +1 -0
- package/dist/balances.mjs +441 -0
- package/dist/balances.mjs.map +1 -0
- package/dist/constants.cjs +13 -1
- package/dist/constants.cjs.map +1 -1
- package/dist/constants.d.cts +1 -0
- package/dist/constants.d.cts.map +1 -1
- package/dist/constants.d.mts +1 -0
- package/dist/constants.d.mts.map +1 -1
- package/dist/constants.mjs +12 -0
- package/dist/constants.mjs.map +1 -1
- package/dist/index.cjs +6 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +6 -4
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +6 -4
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +2 -1
- package/dist/index.mjs.map +1 -1
- package/dist/multi-chain-accounts-service/api-balance-fetcher.cjs +286 -0
- package/dist/multi-chain-accounts-service/api-balance-fetcher.cjs.map +1 -0
- package/dist/multi-chain-accounts-service/api-balance-fetcher.d.cts +30 -0
- package/dist/multi-chain-accounts-service/api-balance-fetcher.d.cts.map +1 -0
- package/dist/multi-chain-accounts-service/api-balance-fetcher.d.mts +30 -0
- package/dist/multi-chain-accounts-service/api-balance-fetcher.d.mts.map +1 -0
- package/dist/multi-chain-accounts-service/api-balance-fetcher.mjs +286 -0
- package/dist/multi-chain-accounts-service/api-balance-fetcher.mjs.map +1 -0
- package/dist/multi-chain-accounts-service/multi-chain-accounts.cjs +35 -1
- package/dist/multi-chain-accounts-service/multi-chain-accounts.cjs.map +1 -1
- package/dist/multi-chain-accounts-service/multi-chain-accounts.d.cts +16 -0
- package/dist/multi-chain-accounts-service/multi-chain-accounts.d.cts.map +1 -1
- package/dist/multi-chain-accounts-service/multi-chain-accounts.d.mts +16 -0
- package/dist/multi-chain-accounts-service/multi-chain-accounts.d.mts.map +1 -1
- package/dist/multi-chain-accounts-service/multi-chain-accounts.mjs +33 -0
- package/dist/multi-chain-accounts-service/multi-chain-accounts.mjs.map +1 -1
- package/dist/multi-chain-accounts-service/types.cjs.map +1 -1
- package/dist/multi-chain-accounts-service/types.d.cts +8 -0
- package/dist/multi-chain-accounts-service/types.d.cts.map +1 -1
- package/dist/multi-chain-accounts-service/types.d.mts +8 -0
- package/dist/multi-chain-accounts-service/types.d.mts.map +1 -1
- package/dist/multi-chain-accounts-service/types.mjs.map +1 -1
- package/dist/multicall.cjs +457 -1
- package/dist/multicall.cjs.map +1 -1
- package/dist/multicall.d.cts +51 -0
- package/dist/multicall.d.cts.map +1 -1
- package/dist/multicall.d.mts +51 -0
- package/dist/multicall.d.mts.map +1 -1
- package/dist/multicall.mjs +457 -0
- package/dist/multicall.mjs.map +1 -1
- package/dist/rpc-service/rpc-balance-fetcher.cjs +184 -0
- package/dist/rpc-service/rpc-balance-fetcher.cjs.map +1 -0
- package/dist/rpc-service/rpc-balance-fetcher.d.cts +34 -0
- package/dist/rpc-service/rpc-balance-fetcher.d.cts.map +1 -0
- package/dist/rpc-service/rpc-balance-fetcher.d.mts +34 -0
- package/dist/rpc-service/rpc-balance-fetcher.d.mts.map +1 -0
- package/dist/rpc-service/rpc-balance-fetcher.mjs +184 -0
- package/dist/rpc-service/rpc-balance-fetcher.mjs.map +1 -0
- package/package.json +11 -11
- package/dist/selectors/balanceSelectors.cjs +0 -328
- package/dist/selectors/balanceSelectors.cjs.map +0 -1
- package/dist/selectors/balanceSelectors.d.cts +0 -1676
- package/dist/selectors/balanceSelectors.d.cts.map +0 -1
- package/dist/selectors/balanceSelectors.d.mts +0 -1676
- package/dist/selectors/balanceSelectors.d.mts.map +0 -1
- package/dist/selectors/balanceSelectors.mjs +0 -321
- package/dist/selectors/balanceSelectors.mjs.map +0 -1
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { Web3Provider } from "@ethersproject/providers";
|
|
2
|
+
import type { InternalAccount } from "@metamask/keyring-internal-api";
|
|
3
|
+
import type { Hex } from "@metamask/utils";
|
|
4
|
+
import BN from "bn.js";
|
|
5
|
+
export type ChainIdHex = Hex;
|
|
6
|
+
export type ChecksumAddress = Hex;
|
|
7
|
+
export type ProcessedBalance = {
|
|
8
|
+
success: boolean;
|
|
9
|
+
value?: BN;
|
|
10
|
+
account: ChecksumAddress;
|
|
11
|
+
token: ChecksumAddress;
|
|
12
|
+
chainId: ChainIdHex;
|
|
13
|
+
};
|
|
14
|
+
export type BalanceFetcher = {
|
|
15
|
+
supports(chainId: ChainIdHex): boolean;
|
|
16
|
+
fetch(input: {
|
|
17
|
+
chainIds: ChainIdHex[];
|
|
18
|
+
queryAllAccounts: boolean;
|
|
19
|
+
selectedAccount: ChecksumAddress;
|
|
20
|
+
allAccounts: InternalAccount[];
|
|
21
|
+
}): Promise<ProcessedBalance[]>;
|
|
22
|
+
};
|
|
23
|
+
export type GetProviderFunction = (chainId: ChainIdHex) => Web3Provider;
|
|
24
|
+
export declare class AccountsApiBalanceFetcher implements BalanceFetcher {
|
|
25
|
+
#private;
|
|
26
|
+
constructor(platform?: 'extension' | 'mobile', getProvider?: GetProviderFunction);
|
|
27
|
+
supports(chainId: ChainIdHex): boolean;
|
|
28
|
+
fetch({ chainIds, queryAllAccounts, selectedAccount, allAccounts, }: Parameters<BalanceFetcher['fetch']>[0]): Promise<ProcessedBalance[]>;
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=api-balance-fetcher.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api-balance-fetcher.d.cts","sourceRoot":"","sources":["../../src/multi-chain-accounts-service/api-balance-fetcher.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,iCAAiC;AAM7D,OAAO,KAAK,EAAE,eAAe,EAAE,uCAAuC;AACtE,OAAO,KAAK,EAAsB,GAAG,EAAE,wBAAwB;AAC/D,OAAO,EAAE,cAAc;AAcvB,MAAM,MAAM,UAAU,GAAG,GAAG,CAAC;AAC7B,MAAM,MAAM,eAAe,GAAG,GAAG,CAAC;AAElC,MAAM,MAAM,gBAAgB,GAAG;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,EAAE,CAAC;IACX,OAAO,EAAE,eAAe,CAAC;IACzB,KAAK,EAAE,eAAe,CAAC;IACvB,OAAO,EAAE,UAAU,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC3B,QAAQ,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC;IACvC,KAAK,CAAC,KAAK,EAAE;QACX,QAAQ,EAAE,UAAU,EAAE,CAAC;QACvB,gBAAgB,EAAE,OAAO,CAAC;QAC1B,eAAe,EAAE,eAAe,CAAC;QACjC,WAAW,EAAE,eAAe,EAAE,CAAC;KAChC,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAAC;CACjC,CAAC;AAUF,MAAM,MAAM,mBAAmB,GAAG,CAAC,OAAO,EAAE,UAAU,KAAK,YAAY,CAAC;AAExE,qBAAa,yBAA0B,YAAW,cAAc;;gBAM5D,QAAQ,GAAE,WAAW,GAAG,QAAsB,EAC9C,WAAW,CAAC,EAAE,mBAAmB;IAMnC,QAAQ,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO;IA0KhC,KAAK,CAAC,EACV,QAAQ,EACR,gBAAgB,EAChB,eAAe,EACf,WAAW,GACZ,EAAE,UAAU,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC;CAgJxE"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { Web3Provider } from "@ethersproject/providers";
|
|
2
|
+
import type { InternalAccount } from "@metamask/keyring-internal-api";
|
|
3
|
+
import type { Hex } from "@metamask/utils";
|
|
4
|
+
import BN from "bn.js";
|
|
5
|
+
export type ChainIdHex = Hex;
|
|
6
|
+
export type ChecksumAddress = Hex;
|
|
7
|
+
export type ProcessedBalance = {
|
|
8
|
+
success: boolean;
|
|
9
|
+
value?: BN;
|
|
10
|
+
account: ChecksumAddress;
|
|
11
|
+
token: ChecksumAddress;
|
|
12
|
+
chainId: ChainIdHex;
|
|
13
|
+
};
|
|
14
|
+
export type BalanceFetcher = {
|
|
15
|
+
supports(chainId: ChainIdHex): boolean;
|
|
16
|
+
fetch(input: {
|
|
17
|
+
chainIds: ChainIdHex[];
|
|
18
|
+
queryAllAccounts: boolean;
|
|
19
|
+
selectedAccount: ChecksumAddress;
|
|
20
|
+
allAccounts: InternalAccount[];
|
|
21
|
+
}): Promise<ProcessedBalance[]>;
|
|
22
|
+
};
|
|
23
|
+
export type GetProviderFunction = (chainId: ChainIdHex) => Web3Provider;
|
|
24
|
+
export declare class AccountsApiBalanceFetcher implements BalanceFetcher {
|
|
25
|
+
#private;
|
|
26
|
+
constructor(platform?: 'extension' | 'mobile', getProvider?: GetProviderFunction);
|
|
27
|
+
supports(chainId: ChainIdHex): boolean;
|
|
28
|
+
fetch({ chainIds, queryAllAccounts, selectedAccount, allAccounts, }: Parameters<BalanceFetcher['fetch']>[0]): Promise<ProcessedBalance[]>;
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=api-balance-fetcher.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api-balance-fetcher.d.mts","sourceRoot":"","sources":["../../src/multi-chain-accounts-service/api-balance-fetcher.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,iCAAiC;AAM7D,OAAO,KAAK,EAAE,eAAe,EAAE,uCAAuC;AACtE,OAAO,KAAK,EAAsB,GAAG,EAAE,wBAAwB;AAC/D,OAAO,EAAE,cAAc;AAcvB,MAAM,MAAM,UAAU,GAAG,GAAG,CAAC;AAC7B,MAAM,MAAM,eAAe,GAAG,GAAG,CAAC;AAElC,MAAM,MAAM,gBAAgB,GAAG;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,EAAE,CAAC;IACX,OAAO,EAAE,eAAe,CAAC;IACzB,KAAK,EAAE,eAAe,CAAC;IACvB,OAAO,EAAE,UAAU,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC3B,QAAQ,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC;IACvC,KAAK,CAAC,KAAK,EAAE;QACX,QAAQ,EAAE,UAAU,EAAE,CAAC;QACvB,gBAAgB,EAAE,OAAO,CAAC;QAC1B,eAAe,EAAE,eAAe,CAAC;QACjC,WAAW,EAAE,eAAe,EAAE,CAAC;KAChC,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAAC;CACjC,CAAC;AAUF,MAAM,MAAM,mBAAmB,GAAG,CAAC,OAAO,EAAE,UAAU,KAAK,YAAY,CAAC;AAExE,qBAAa,yBAA0B,YAAW,cAAc;;gBAM5D,QAAQ,GAAE,WAAW,GAAG,QAAsB,EAC9C,WAAW,CAAC,EAAE,mBAAmB;IAMnC,QAAQ,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO;IA0KhC,KAAK,CAAC,EACV,QAAQ,EACR,gBAAgB,EAChB,eAAe,EACf,WAAW,GACZ,EAAE,UAAU,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC;CAgJxE"}
|
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
2
|
+
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
3
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
4
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
5
|
+
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
6
|
+
};
|
|
7
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
8
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
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
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
11
|
+
};
|
|
12
|
+
var _AccountsApiBalanceFetcher_instances, _AccountsApiBalanceFetcher_platform, _AccountsApiBalanceFetcher_getProvider, _AccountsApiBalanceFetcher_fetchStakedBalances, _AccountsApiBalanceFetcher_fetchBalances;
|
|
13
|
+
function $importDefault(module) {
|
|
14
|
+
if (module?.__esModule) {
|
|
15
|
+
return module.default;
|
|
16
|
+
}
|
|
17
|
+
return module;
|
|
18
|
+
}
|
|
19
|
+
import { Contract } from "@ethersproject/contracts";
|
|
20
|
+
import { safelyExecute, toHex, toChecksumHexAddress } from "@metamask/controller-utils";
|
|
21
|
+
import $BN from "bn.js";
|
|
22
|
+
const BN = $importDefault($BN);
|
|
23
|
+
import { fetchMultiChainBalancesV4 } from "./multi-chain-accounts.mjs";
|
|
24
|
+
import { STAKING_CONTRACT_ADDRESS_BY_CHAINID } from "../AssetsContractController.mjs";
|
|
25
|
+
import { accountAddressToCaipReference, reduceInBatchesSerially, SupportedStakedBalanceNetworks } from "../assetsUtil.mjs";
|
|
26
|
+
import { SUPPORTED_NETWORKS_ACCOUNTS_API_V4 } from "../constants.mjs";
|
|
27
|
+
// Maximum number of account addresses that can be sent to the accounts API in a single request
|
|
28
|
+
const ACCOUNTS_API_BATCH_SIZE = 50;
|
|
29
|
+
const checksum = (addr) => toChecksumHexAddress(addr);
|
|
30
|
+
const toCaipAccount = (chainId, account) => accountAddressToCaipReference(chainId, account);
|
|
31
|
+
export class AccountsApiBalanceFetcher {
|
|
32
|
+
constructor(platform = 'extension', getProvider) {
|
|
33
|
+
_AccountsApiBalanceFetcher_instances.add(this);
|
|
34
|
+
_AccountsApiBalanceFetcher_platform.set(this, 'extension');
|
|
35
|
+
_AccountsApiBalanceFetcher_getProvider.set(this, void 0);
|
|
36
|
+
__classPrivateFieldSet(this, _AccountsApiBalanceFetcher_platform, platform, "f");
|
|
37
|
+
__classPrivateFieldSet(this, _AccountsApiBalanceFetcher_getProvider, getProvider, "f");
|
|
38
|
+
}
|
|
39
|
+
supports(chainId) {
|
|
40
|
+
return SUPPORTED_NETWORKS_ACCOUNTS_API_V4.includes(chainId);
|
|
41
|
+
}
|
|
42
|
+
async fetch({ chainIds, queryAllAccounts, selectedAccount, allAccounts, }) {
|
|
43
|
+
const caipAddrs = [];
|
|
44
|
+
for (const chainId of chainIds.filter((c) => this.supports(c))) {
|
|
45
|
+
if (queryAllAccounts) {
|
|
46
|
+
allAccounts.forEach((a) => caipAddrs.push(toCaipAccount(chainId, a.address)));
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
caipAddrs.push(toCaipAccount(chainId, selectedAccount));
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
if (!caipAddrs.length) {
|
|
53
|
+
return [];
|
|
54
|
+
}
|
|
55
|
+
// Don't use safelyExecute here - let real errors propagate
|
|
56
|
+
let balances;
|
|
57
|
+
let apiError = false;
|
|
58
|
+
try {
|
|
59
|
+
balances = await __classPrivateFieldGet(this, _AccountsApiBalanceFetcher_instances, "m", _AccountsApiBalanceFetcher_fetchBalances).call(this, caipAddrs);
|
|
60
|
+
}
|
|
61
|
+
catch (error) {
|
|
62
|
+
// Mark that we had an API error so we don't add fake zero balances
|
|
63
|
+
apiError = true;
|
|
64
|
+
console.error('Failed to fetch balances from API:', error);
|
|
65
|
+
balances = undefined;
|
|
66
|
+
}
|
|
67
|
+
const stakedBalances = await __classPrivateFieldGet(this, _AccountsApiBalanceFetcher_instances, "m", _AccountsApiBalanceFetcher_fetchStakedBalances).call(this, caipAddrs);
|
|
68
|
+
const results = [];
|
|
69
|
+
// Collect all unique addresses and chains from the CAIP addresses
|
|
70
|
+
const addressChainMap = new Map();
|
|
71
|
+
caipAddrs.forEach((caipAddr) => {
|
|
72
|
+
const [, chainRef, address] = caipAddr.split(':');
|
|
73
|
+
const chainId = toHex(parseInt(chainRef, 10));
|
|
74
|
+
const checksumAddress = checksum(address);
|
|
75
|
+
if (!addressChainMap.has(checksumAddress)) {
|
|
76
|
+
addressChainMap.set(checksumAddress, new Set());
|
|
77
|
+
}
|
|
78
|
+
addressChainMap.get(checksumAddress)?.add(chainId);
|
|
79
|
+
});
|
|
80
|
+
// Ensure native token entries exist for all addresses on all requested chains
|
|
81
|
+
const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000';
|
|
82
|
+
const nativeBalancesFromAPI = new Map(); // key: `${address}-${chainId}`
|
|
83
|
+
// Process regular API balances
|
|
84
|
+
if (balances) {
|
|
85
|
+
const apiBalances = balances.flatMap((b) => {
|
|
86
|
+
const account = b.accountAddress?.split(':')[2];
|
|
87
|
+
if (!account) {
|
|
88
|
+
return [];
|
|
89
|
+
}
|
|
90
|
+
const token = checksum(b.address);
|
|
91
|
+
const chainId = toHex(b.chainId);
|
|
92
|
+
let value;
|
|
93
|
+
try {
|
|
94
|
+
// Convert string balance to BN avoiding floating point precision issues
|
|
95
|
+
const { balance: balanceStr, decimals } = b;
|
|
96
|
+
// Split the balance string into integer and decimal parts
|
|
97
|
+
const [integerPart = '0', decimalPart = ''] = balanceStr.split('.');
|
|
98
|
+
// Pad or truncate decimal part to match token decimals
|
|
99
|
+
const paddedDecimalPart = decimalPart
|
|
100
|
+
.padEnd(decimals, '0')
|
|
101
|
+
.slice(0, decimals);
|
|
102
|
+
// Combine and create BN
|
|
103
|
+
const fullIntegerStr = integerPart + paddedDecimalPart;
|
|
104
|
+
value = new BN(fullIntegerStr);
|
|
105
|
+
}
|
|
106
|
+
catch {
|
|
107
|
+
value = undefined;
|
|
108
|
+
}
|
|
109
|
+
// Track native balances for later
|
|
110
|
+
if (token === ZERO_ADDRESS && value !== undefined) {
|
|
111
|
+
nativeBalancesFromAPI.set(`${account}-${chainId}`, value);
|
|
112
|
+
}
|
|
113
|
+
return [
|
|
114
|
+
{
|
|
115
|
+
success: value !== undefined,
|
|
116
|
+
value,
|
|
117
|
+
account,
|
|
118
|
+
token,
|
|
119
|
+
chainId,
|
|
120
|
+
},
|
|
121
|
+
];
|
|
122
|
+
});
|
|
123
|
+
results.push(...apiBalances);
|
|
124
|
+
}
|
|
125
|
+
// Only add zero native balance entries if API succeeded but didn't return balances
|
|
126
|
+
// Don't add fake zero balances if the API failed entirely
|
|
127
|
+
if (!apiError) {
|
|
128
|
+
addressChainMap.forEach((chains, address) => {
|
|
129
|
+
chains.forEach((chainId) => {
|
|
130
|
+
const key = `${address}-${chainId}`;
|
|
131
|
+
const existingBalance = nativeBalancesFromAPI.get(key);
|
|
132
|
+
if (!existingBalance) {
|
|
133
|
+
// Add zero native balance entry if API succeeded but didn't return one
|
|
134
|
+
results.push({
|
|
135
|
+
success: true,
|
|
136
|
+
value: new BN('0'),
|
|
137
|
+
account: address,
|
|
138
|
+
token: ZERO_ADDRESS,
|
|
139
|
+
chainId,
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
else {
|
|
146
|
+
// If API failed, add error entries for all requested addresses/chains
|
|
147
|
+
addressChainMap.forEach((chains, address) => {
|
|
148
|
+
chains.forEach((chainId) => {
|
|
149
|
+
results.push({
|
|
150
|
+
success: false,
|
|
151
|
+
account: address,
|
|
152
|
+
token: ZERO_ADDRESS,
|
|
153
|
+
chainId,
|
|
154
|
+
});
|
|
155
|
+
});
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
// Add staked balances
|
|
159
|
+
results.push(...stakedBalances);
|
|
160
|
+
// If we had an API error and no successful results, throw the error
|
|
161
|
+
if (apiError && results.every((r) => !r.success)) {
|
|
162
|
+
throw new Error('Failed to fetch any balance data due to API error');
|
|
163
|
+
}
|
|
164
|
+
return results;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
_AccountsApiBalanceFetcher_platform = new WeakMap(), _AccountsApiBalanceFetcher_getProvider = new WeakMap(), _AccountsApiBalanceFetcher_instances = new WeakSet(), _AccountsApiBalanceFetcher_fetchStakedBalances = async function _AccountsApiBalanceFetcher_fetchStakedBalances(addrs) {
|
|
168
|
+
// Return empty array if no provider is available for blockchain calls
|
|
169
|
+
if (!__classPrivateFieldGet(this, _AccountsApiBalanceFetcher_getProvider, "f")) {
|
|
170
|
+
return [];
|
|
171
|
+
}
|
|
172
|
+
const results = [];
|
|
173
|
+
// Group addresses by chain ID
|
|
174
|
+
const addressesByChain = {};
|
|
175
|
+
for (const caipAddr of addrs) {
|
|
176
|
+
const [, chainRef, address] = caipAddr.split(':');
|
|
177
|
+
const chainId = toHex(parseInt(chainRef, 10));
|
|
178
|
+
const checksumAddress = checksum(address);
|
|
179
|
+
if (!addressesByChain[chainId]) {
|
|
180
|
+
addressesByChain[chainId] = [];
|
|
181
|
+
}
|
|
182
|
+
addressesByChain[chainId].push(checksumAddress);
|
|
183
|
+
}
|
|
184
|
+
// Process each supported chain
|
|
185
|
+
for (const [chainId, addresses] of Object.entries(addressesByChain)) {
|
|
186
|
+
const chainIdHex = chainId;
|
|
187
|
+
// Only fetch staked balance on supported networks (mainnet and hoodi)
|
|
188
|
+
if (![
|
|
189
|
+
SupportedStakedBalanceNetworks.mainnet,
|
|
190
|
+
SupportedStakedBalanceNetworks.hoodi,
|
|
191
|
+
].includes(chainIdHex)) {
|
|
192
|
+
continue;
|
|
193
|
+
}
|
|
194
|
+
// Only fetch staked balance if contract address exists
|
|
195
|
+
if (!(chainIdHex in STAKING_CONTRACT_ADDRESS_BY_CHAINID)) {
|
|
196
|
+
continue;
|
|
197
|
+
}
|
|
198
|
+
const contractAddress = STAKING_CONTRACT_ADDRESS_BY_CHAINID[chainIdHex];
|
|
199
|
+
const provider = __classPrivateFieldGet(this, _AccountsApiBalanceFetcher_getProvider, "f").call(this, chainIdHex);
|
|
200
|
+
const abi = [
|
|
201
|
+
{
|
|
202
|
+
inputs: [
|
|
203
|
+
{ internalType: 'address', name: 'account', type: 'address' },
|
|
204
|
+
],
|
|
205
|
+
name: 'getShares',
|
|
206
|
+
outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }],
|
|
207
|
+
stateMutability: 'view',
|
|
208
|
+
type: 'function',
|
|
209
|
+
},
|
|
210
|
+
{
|
|
211
|
+
inputs: [
|
|
212
|
+
{ internalType: 'uint256', name: 'shares', type: 'uint256' },
|
|
213
|
+
],
|
|
214
|
+
name: 'convertToAssets',
|
|
215
|
+
outputs: [
|
|
216
|
+
{ internalType: 'uint256', name: 'assets', type: 'uint256' },
|
|
217
|
+
],
|
|
218
|
+
stateMutability: 'view',
|
|
219
|
+
type: 'function',
|
|
220
|
+
},
|
|
221
|
+
];
|
|
222
|
+
try {
|
|
223
|
+
const contract = new Contract(contractAddress, abi, provider);
|
|
224
|
+
// Get shares for each address
|
|
225
|
+
for (const address of addresses) {
|
|
226
|
+
try {
|
|
227
|
+
const shares = await safelyExecute(() => contract.getShares(address));
|
|
228
|
+
if (shares && shares.gt(0)) {
|
|
229
|
+
// Convert shares to assets (actual staked ETH amount)
|
|
230
|
+
const assets = await safelyExecute(() => contract.convertToAssets(shares));
|
|
231
|
+
if (assets) {
|
|
232
|
+
results.push({
|
|
233
|
+
success: true,
|
|
234
|
+
value: new BN(assets.toString()),
|
|
235
|
+
account: address,
|
|
236
|
+
token: checksum(contractAddress),
|
|
237
|
+
chainId: chainIdHex,
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
else {
|
|
242
|
+
// Return zero balance for accounts with no staked assets
|
|
243
|
+
results.push({
|
|
244
|
+
success: true,
|
|
245
|
+
value: new BN('0'),
|
|
246
|
+
account: address,
|
|
247
|
+
token: checksum(contractAddress),
|
|
248
|
+
chainId: chainIdHex,
|
|
249
|
+
});
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
catch (error) {
|
|
253
|
+
// Log error and continue with next address
|
|
254
|
+
console.error(`Error fetching staked balance for ${address}:`, error);
|
|
255
|
+
results.push({
|
|
256
|
+
success: false,
|
|
257
|
+
account: address,
|
|
258
|
+
token: checksum(contractAddress),
|
|
259
|
+
chainId: chainIdHex,
|
|
260
|
+
});
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
catch (error) {
|
|
265
|
+
console.error(`Error setting up staking contract for chain ${chainId}:`, error);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
return results;
|
|
269
|
+
}, _AccountsApiBalanceFetcher_fetchBalances = async function _AccountsApiBalanceFetcher_fetchBalances(addrs) {
|
|
270
|
+
// If we have fewer than or equal to the batch size, make a single request
|
|
271
|
+
if (addrs.length <= ACCOUNTS_API_BATCH_SIZE) {
|
|
272
|
+
const { balances } = await fetchMultiChainBalancesV4({ accountAddresses: addrs }, __classPrivateFieldGet(this, _AccountsApiBalanceFetcher_platform, "f"));
|
|
273
|
+
return balances;
|
|
274
|
+
}
|
|
275
|
+
const allBalances = await reduceInBatchesSerially({
|
|
276
|
+
values: addrs,
|
|
277
|
+
batchSize: ACCOUNTS_API_BATCH_SIZE,
|
|
278
|
+
eachBatch: async (workingResult, batch) => {
|
|
279
|
+
const { balances } = await fetchMultiChainBalancesV4({ accountAddresses: batch }, __classPrivateFieldGet(this, _AccountsApiBalanceFetcher_platform, "f"));
|
|
280
|
+
return [...(workingResult || []), ...balances];
|
|
281
|
+
},
|
|
282
|
+
initialResult: [],
|
|
283
|
+
});
|
|
284
|
+
return allBalances;
|
|
285
|
+
};
|
|
286
|
+
//# sourceMappingURL=api-balance-fetcher.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api-balance-fetcher.mjs","sourceRoot":"","sources":["../../src/multi-chain-accounts-service/api-balance-fetcher.ts"],"names":[],"mappings":"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","sourcesContent":["import type { BigNumber } from '@ethersproject/bignumber';\nimport { Contract } from '@ethersproject/contracts';\nimport type { Web3Provider } from '@ethersproject/providers';\nimport {\n safelyExecute,\n toHex,\n toChecksumHexAddress,\n} from '@metamask/controller-utils';\nimport type { InternalAccount } from '@metamask/keyring-internal-api';\nimport type { CaipAccountAddress, Hex } from '@metamask/utils';\nimport BN from 'bn.js';\n\nimport { fetchMultiChainBalancesV4 } from './multi-chain-accounts';\nimport { STAKING_CONTRACT_ADDRESS_BY_CHAINID } from '../AssetsContractController';\nimport {\n accountAddressToCaipReference,\n reduceInBatchesSerially,\n SupportedStakedBalanceNetworks,\n} from '../assetsUtil';\nimport { SUPPORTED_NETWORKS_ACCOUNTS_API_V4 } from '../constants';\n\n// Maximum number of account addresses that can be sent to the accounts API in a single request\nconst ACCOUNTS_API_BATCH_SIZE = 50;\n\nexport type ChainIdHex = Hex;\nexport type ChecksumAddress = Hex;\n\nexport type ProcessedBalance = {\n success: boolean;\n value?: BN;\n account: ChecksumAddress;\n token: ChecksumAddress;\n chainId: ChainIdHex;\n};\n\nexport type BalanceFetcher = {\n supports(chainId: ChainIdHex): boolean;\n fetch(input: {\n chainIds: ChainIdHex[];\n queryAllAccounts: boolean;\n selectedAccount: ChecksumAddress;\n allAccounts: InternalAccount[];\n }): Promise<ProcessedBalance[]>;\n};\n\nconst checksum = (addr: string): ChecksumAddress =>\n toChecksumHexAddress(addr) as ChecksumAddress;\n\nconst toCaipAccount = (\n chainId: ChainIdHex,\n account: ChecksumAddress,\n): CaipAccountAddress => accountAddressToCaipReference(chainId, account);\n\nexport type GetProviderFunction = (chainId: ChainIdHex) => Web3Provider;\n\nexport class AccountsApiBalanceFetcher implements BalanceFetcher {\n readonly #platform: 'extension' | 'mobile' = 'extension';\n\n readonly #getProvider?: GetProviderFunction;\n\n constructor(\n platform: 'extension' | 'mobile' = 'extension',\n getProvider?: GetProviderFunction,\n ) {\n this.#platform = platform;\n this.#getProvider = getProvider;\n }\n\n supports(chainId: ChainIdHex): boolean {\n return SUPPORTED_NETWORKS_ACCOUNTS_API_V4.includes(chainId);\n }\n\n async #fetchStakedBalances(\n addrs: CaipAccountAddress[],\n ): Promise<ProcessedBalance[]> {\n // Return empty array if no provider is available for blockchain calls\n if (!this.#getProvider) {\n return [];\n }\n\n const results: ProcessedBalance[] = [];\n\n // Group addresses by chain ID\n const addressesByChain: Record<ChainIdHex, ChecksumAddress[]> = {};\n\n for (const caipAddr of addrs) {\n const [, chainRef, address] = caipAddr.split(':');\n const chainId = toHex(parseInt(chainRef, 10)) as ChainIdHex;\n const checksumAddress = checksum(address);\n\n if (!addressesByChain[chainId]) {\n addressesByChain[chainId] = [];\n }\n addressesByChain[chainId].push(checksumAddress);\n }\n\n // Process each supported chain\n for (const [chainId, addresses] of Object.entries(addressesByChain)) {\n const chainIdHex = chainId as ChainIdHex;\n\n // Only fetch staked balance on supported networks (mainnet and hoodi)\n if (\n ![\n SupportedStakedBalanceNetworks.mainnet,\n SupportedStakedBalanceNetworks.hoodi,\n ].includes(chainIdHex as SupportedStakedBalanceNetworks)\n ) {\n continue;\n }\n\n // Only fetch staked balance if contract address exists\n if (!(chainIdHex in STAKING_CONTRACT_ADDRESS_BY_CHAINID)) {\n continue;\n }\n\n const contractAddress =\n STAKING_CONTRACT_ADDRESS_BY_CHAINID[\n chainIdHex as keyof typeof STAKING_CONTRACT_ADDRESS_BY_CHAINID\n ];\n const provider = this.#getProvider(chainIdHex);\n\n const abi = [\n {\n inputs: [\n { internalType: 'address', name: 'account', type: 'address' },\n ],\n name: 'getShares',\n outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }],\n stateMutability: 'view',\n type: 'function',\n },\n {\n inputs: [\n { internalType: 'uint256', name: 'shares', type: 'uint256' },\n ],\n name: 'convertToAssets',\n outputs: [\n { internalType: 'uint256', name: 'assets', type: 'uint256' },\n ],\n stateMutability: 'view',\n type: 'function',\n },\n ];\n\n try {\n const contract = new Contract(contractAddress, abi, provider);\n\n // Get shares for each address\n for (const address of addresses) {\n try {\n const shares = await safelyExecute(() =>\n contract.getShares(address),\n );\n\n if (shares && (shares as BigNumber).gt(0)) {\n // Convert shares to assets (actual staked ETH amount)\n const assets = await safelyExecute(() =>\n contract.convertToAssets(shares),\n );\n\n if (assets) {\n results.push({\n success: true,\n value: new BN((assets as BigNumber).toString()),\n account: address,\n token: checksum(contractAddress) as ChecksumAddress,\n chainId: chainIdHex,\n });\n }\n } else {\n // Return zero balance for accounts with no staked assets\n results.push({\n success: true,\n value: new BN('0'),\n account: address,\n token: checksum(contractAddress) as ChecksumAddress,\n chainId: chainIdHex,\n });\n }\n } catch (error) {\n // Log error and continue with next address\n console.error(\n `Error fetching staked balance for ${address}:`,\n error,\n );\n results.push({\n success: false,\n account: address,\n token: checksum(contractAddress) as ChecksumAddress,\n chainId: chainIdHex,\n });\n }\n }\n } catch (error) {\n console.error(\n `Error setting up staking contract for chain ${chainId}:`,\n error,\n );\n }\n }\n\n return results;\n }\n\n async #fetchBalances(addrs: CaipAccountAddress[]) {\n // If we have fewer than or equal to the batch size, make a single request\n if (addrs.length <= ACCOUNTS_API_BATCH_SIZE) {\n const { balances } = await fetchMultiChainBalancesV4(\n { accountAddresses: addrs },\n this.#platform,\n );\n return balances;\n }\n\n // Otherwise, batch the requests to respect the 50-element limit\n type BalanceData = Awaited<\n ReturnType<typeof fetchMultiChainBalancesV4>\n >['balances'][number];\n\n const allBalances = await reduceInBatchesSerially<\n CaipAccountAddress,\n BalanceData[]\n >({\n values: addrs,\n batchSize: ACCOUNTS_API_BATCH_SIZE,\n eachBatch: async (workingResult, batch) => {\n const { balances } = await fetchMultiChainBalancesV4(\n { accountAddresses: batch },\n this.#platform,\n );\n return [...(workingResult || []), ...balances];\n },\n initialResult: [],\n });\n\n return allBalances;\n }\n\n async fetch({\n chainIds,\n queryAllAccounts,\n selectedAccount,\n allAccounts,\n }: Parameters<BalanceFetcher['fetch']>[0]): Promise<ProcessedBalance[]> {\n const caipAddrs: CaipAccountAddress[] = [];\n\n for (const chainId of chainIds.filter((c) => this.supports(c))) {\n if (queryAllAccounts) {\n allAccounts.forEach((a) =>\n caipAddrs.push(toCaipAccount(chainId, a.address as ChecksumAddress)),\n );\n } else {\n caipAddrs.push(toCaipAccount(chainId, selectedAccount));\n }\n }\n\n if (!caipAddrs.length) {\n return [];\n }\n\n // Don't use safelyExecute here - let real errors propagate\n let balances;\n let apiError = false;\n\n try {\n balances = await this.#fetchBalances(caipAddrs);\n } catch (error) {\n // Mark that we had an API error so we don't add fake zero balances\n apiError = true;\n console.error('Failed to fetch balances from API:', error);\n balances = undefined;\n }\n\n const stakedBalances = await this.#fetchStakedBalances(caipAddrs);\n\n const results: ProcessedBalance[] = [];\n\n // Collect all unique addresses and chains from the CAIP addresses\n const addressChainMap = new Map<string, Set<ChainIdHex>>();\n caipAddrs.forEach((caipAddr) => {\n const [, chainRef, address] = caipAddr.split(':');\n const chainId = toHex(parseInt(chainRef, 10)) as ChainIdHex;\n const checksumAddress = checksum(address);\n\n if (!addressChainMap.has(checksumAddress)) {\n addressChainMap.set(checksumAddress, new Set());\n }\n addressChainMap.get(checksumAddress)?.add(chainId);\n });\n\n // Ensure native token entries exist for all addresses on all requested chains\n const ZERO_ADDRESS =\n '0x0000000000000000000000000000000000000000' as ChecksumAddress;\n const nativeBalancesFromAPI = new Map<string, BN>(); // key: `${address}-${chainId}`\n\n // Process regular API balances\n if (balances) {\n const apiBalances = balances.flatMap((b) => {\n const account = b.accountAddress?.split(':')[2] as ChecksumAddress;\n if (!account) {\n return [];\n }\n const token = checksum(b.address);\n const chainId = toHex(b.chainId) as ChainIdHex;\n\n let value: BN | undefined;\n try {\n // Convert string balance to BN avoiding floating point precision issues\n const { balance: balanceStr, decimals } = b;\n\n // Split the balance string into integer and decimal parts\n const [integerPart = '0', decimalPart = ''] = balanceStr.split('.');\n\n // Pad or truncate decimal part to match token decimals\n const paddedDecimalPart = decimalPart\n .padEnd(decimals, '0')\n .slice(0, decimals);\n\n // Combine and create BN\n const fullIntegerStr = integerPart + paddedDecimalPart;\n value = new BN(fullIntegerStr);\n } catch {\n value = undefined;\n }\n\n // Track native balances for later\n if (token === ZERO_ADDRESS && value !== undefined) {\n nativeBalancesFromAPI.set(`${account}-${chainId}`, value);\n }\n\n return [\n {\n success: value !== undefined,\n value,\n account,\n token,\n chainId,\n },\n ];\n });\n results.push(...apiBalances);\n }\n\n // Only add zero native balance entries if API succeeded but didn't return balances\n // Don't add fake zero balances if the API failed entirely\n if (!apiError) {\n addressChainMap.forEach((chains, address) => {\n chains.forEach((chainId) => {\n const key = `${address}-${chainId}`;\n const existingBalance = nativeBalancesFromAPI.get(key);\n\n if (!existingBalance) {\n // Add zero native balance entry if API succeeded but didn't return one\n results.push({\n success: true,\n value: new BN('0'),\n account: address as ChecksumAddress,\n token: ZERO_ADDRESS,\n chainId,\n });\n }\n });\n });\n } else {\n // If API failed, add error entries for all requested addresses/chains\n addressChainMap.forEach((chains, address) => {\n chains.forEach((chainId) => {\n results.push({\n success: false,\n account: address as ChecksumAddress,\n token: ZERO_ADDRESS,\n chainId,\n });\n });\n });\n }\n\n // Add staked balances\n results.push(...stakedBalances);\n\n // If we had an API error and no successful results, throw the error\n if (apiError && results.every((r) => !r.success)) {\n throw new Error('Failed to fetch any balance data due to API error');\n }\n\n return results;\n }\n}\n"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.fetchMultiChainBalances = exports.fetchSupportedNetworks = exports.MULTICHAIN_ACCOUNTS_DOMAIN = void 0;
|
|
3
|
+
exports.fetchMultiChainBalancesV4 = exports.fetchMultiChainBalances = exports.fetchSupportedNetworks = exports.MULTICHAIN_ACCOUNTS_DOMAIN = void 0;
|
|
4
4
|
const controller_utils_1 = require("@metamask/controller-utils");
|
|
5
5
|
exports.MULTICHAIN_ACCOUNTS_DOMAIN = 'https://accounts.api.cx.metamask.io';
|
|
6
6
|
const getBalancesUrl = (address, queryParams) => {
|
|
@@ -10,8 +10,19 @@ const getBalancesUrl = (address, queryParams) => {
|
|
|
10
10
|
}
|
|
11
11
|
return url;
|
|
12
12
|
};
|
|
13
|
+
const getBalancesUrlV4 = (queryParams) => {
|
|
14
|
+
const url = new URL(`${exports.MULTICHAIN_ACCOUNTS_DOMAIN}/v4/multiaccount/balances`);
|
|
15
|
+
if (queryParams?.networks !== undefined) {
|
|
16
|
+
url.searchParams.append('networks', queryParams.networks);
|
|
17
|
+
}
|
|
18
|
+
if (queryParams?.accountAddresses !== undefined) {
|
|
19
|
+
url.searchParams.append('accountAddresses', queryParams.accountAddresses);
|
|
20
|
+
}
|
|
21
|
+
return url;
|
|
22
|
+
};
|
|
13
23
|
/**
|
|
14
24
|
* Fetches Supported Networks.
|
|
25
|
+
*
|
|
15
26
|
* @returns supported networks (decimal)
|
|
16
27
|
*/
|
|
17
28
|
async function fetchSupportedNetworks() {
|
|
@@ -22,6 +33,7 @@ async function fetchSupportedNetworks() {
|
|
|
22
33
|
exports.fetchSupportedNetworks = fetchSupportedNetworks;
|
|
23
34
|
/**
|
|
24
35
|
* Fetches Balances for multiple networks.
|
|
36
|
+
*
|
|
25
37
|
* @param address - address to fetch balances from
|
|
26
38
|
* @param options - params to pass down for a more refined search
|
|
27
39
|
* @param options.networks - the networks (in decimal) that you want to filter by
|
|
@@ -40,4 +52,26 @@ async function fetchMultiChainBalances(address, options, platform) {
|
|
|
40
52
|
return response;
|
|
41
53
|
}
|
|
42
54
|
exports.fetchMultiChainBalances = fetchMultiChainBalances;
|
|
55
|
+
/**
|
|
56
|
+
* Fetches Balances for multiple networks.
|
|
57
|
+
*
|
|
58
|
+
* @param options - params to pass down for a more refined search
|
|
59
|
+
* @param options.accountAddresses - the account addresses that you want to filter by
|
|
60
|
+
* @param options.networks - the networks (in decimal) that you want to filter by
|
|
61
|
+
* @param platform - indicates whether the platform is extension or mobile
|
|
62
|
+
* @returns a Balances Response
|
|
63
|
+
*/
|
|
64
|
+
async function fetchMultiChainBalancesV4(options, platform) {
|
|
65
|
+
const url = getBalancesUrlV4({
|
|
66
|
+
accountAddresses: options?.accountAddresses?.join(),
|
|
67
|
+
networks: options?.networks?.join(),
|
|
68
|
+
});
|
|
69
|
+
const response = await (0, controller_utils_1.handleFetch)(url, {
|
|
70
|
+
headers: {
|
|
71
|
+
'x-metamask-clientproduct': `metamask-${platform}`,
|
|
72
|
+
},
|
|
73
|
+
});
|
|
74
|
+
return response;
|
|
75
|
+
}
|
|
76
|
+
exports.fetchMultiChainBalancesV4 = fetchMultiChainBalancesV4;
|
|
43
77
|
//# sourceMappingURL=multi-chain-accounts.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"multi-chain-accounts.cjs","sourceRoot":"","sources":["../../src/multi-chain-accounts-service/multi-chain-accounts.ts"],"names":[],"mappings":";;;AAAA,iEAAyD;
|
|
1
|
+
{"version":3,"file":"multi-chain-accounts.cjs","sourceRoot":"","sources":["../../src/multi-chain-accounts-service/multi-chain-accounts.ts"],"names":[],"mappings":";;;AAAA,iEAAyD;AAU5C,QAAA,0BAA0B,GAAG,qCAAqC,CAAC;AAEhF,MAAM,cAAc,GAAG,CACrB,OAAe,EACf,WAAoC,EACpC,EAAE;IACF,MAAM,GAAG,GAAG,IAAI,GAAG,CACjB,GAAG,kCAA0B,gBAAgB,OAAO,WAAW,CAChE,CAAC;IAEF,IAAI,WAAW,EAAE,QAAQ,KAAK,SAAS,EAAE;QACvC,GAAG,CAAC,YAAY,CAAC,MAAM,CAAC,UAAU,EAAE,WAAW,CAAC,QAAQ,CAAC,CAAC;KAC3D;IAED,OAAO,GAAG,CAAC;AACb,CAAC,CAAC;AAEF,MAAM,gBAAgB,GAAG,CAAC,WAAsC,EAAE,EAAE;IAClE,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,kCAA0B,2BAA2B,CAAC,CAAC;IAE9E,IAAI,WAAW,EAAE,QAAQ,KAAK,SAAS,EAAE;QACvC,GAAG,CAAC,YAAY,CAAC,MAAM,CAAC,UAAU,EAAE,WAAW,CAAC,QAAQ,CAAC,CAAC;KAC3D;IAED,IAAI,WAAW,EAAE,gBAAgB,KAAK,SAAS,EAAE;QAC/C,GAAG,CAAC,YAAY,CAAC,MAAM,CAAC,kBAAkB,EAAE,WAAW,CAAC,gBAAgB,CAAC,CAAC;KAC3E;IAED,OAAO,GAAG,CAAC;AACb,CAAC,CAAC;AAEF;;;;GAIG;AACI,KAAK,UAAU,sBAAsB;IAC1C,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,kCAA0B,uBAAuB,CAAC,CAAC;IAC1E,MAAM,QAAQ,GAAiC,MAAM,IAAA,8BAAW,EAAC,GAAG,CAAC,CAAC;IACtE,OAAO,QAAQ,CAAC,WAAW,CAAC;AAC9B,CAAC;AAJD,wDAIC;AAED;;;;;;;;GAQG;AACI,KAAK,UAAU,uBAAuB,CAC3C,OAAe,EACf,OAAgC,EAChC,QAAgC;IAEhC,MAAM,GAAG,GAAG,cAAc,CAAC,OAAO,EAAE;QAClC,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE;KACpC,CAAC,CAAC;IACH,MAAM,QAAQ,GAAwB,MAAM,IAAA,8BAAW,EAAC,GAAG,EAAE;QAC3D,OAAO,EAAE;YACP,0BAA0B,EAAE,YAAY,QAAQ,EAAE;SACnD;KACF,CAAC,CAAC;IACH,OAAO,QAAQ,CAAC;AAClB,CAAC;AAdD,0DAcC;AAED;;;;;;;;GAQG;AACI,KAAK,UAAU,yBAAyB,CAC7C,OAAyE,EACzE,QAAgC;IAEhC,MAAM,GAAG,GAAG,gBAAgB,CAAC;QAC3B,gBAAgB,EAAE,OAAO,EAAE,gBAAgB,EAAE,IAAI,EAAE;QACnD,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE;KACpC,CAAC,CAAC;IAEH,MAAM,QAAQ,GAAwB,MAAM,IAAA,8BAAW,EAAC,GAAG,EAAE;QAC3D,OAAO,EAAE;YACP,0BAA0B,EAAE,YAAY,QAAQ,EAAE;SACnD;KACF,CAAC,CAAC;IACH,OAAO,QAAQ,CAAC;AAClB,CAAC;AAfD,8DAeC","sourcesContent":["import { handleFetch } from '@metamask/controller-utils';\nimport type { CaipAccountAddress } from '@metamask/utils';\n\nimport type {\n GetBalancesQueryParams,\n GetBalancesQueryParamsV4,\n GetBalancesResponse,\n GetSupportedNetworksResponse,\n} from './types';\n\nexport const MULTICHAIN_ACCOUNTS_DOMAIN = 'https://accounts.api.cx.metamask.io';\n\nconst getBalancesUrl = (\n address: string,\n queryParams?: GetBalancesQueryParams,\n) => {\n const url = new URL(\n `${MULTICHAIN_ACCOUNTS_DOMAIN}/v2/accounts/${address}/balances`,\n );\n\n if (queryParams?.networks !== undefined) {\n url.searchParams.append('networks', queryParams.networks);\n }\n\n return url;\n};\n\nconst getBalancesUrlV4 = (queryParams?: GetBalancesQueryParamsV4) => {\n const url = new URL(`${MULTICHAIN_ACCOUNTS_DOMAIN}/v4/multiaccount/balances`);\n\n if (queryParams?.networks !== undefined) {\n url.searchParams.append('networks', queryParams.networks);\n }\n\n if (queryParams?.accountAddresses !== undefined) {\n url.searchParams.append('accountAddresses', queryParams.accountAddresses);\n }\n\n return url;\n};\n\n/**\n * Fetches Supported Networks.\n *\n * @returns supported networks (decimal)\n */\nexport async function fetchSupportedNetworks(): Promise<number[]> {\n const url = new URL(`${MULTICHAIN_ACCOUNTS_DOMAIN}/v1/supportedNetworks`);\n const response: GetSupportedNetworksResponse = await handleFetch(url);\n return response.fullSupport;\n}\n\n/**\n * Fetches Balances for multiple networks.\n *\n * @param address - address to fetch balances from\n * @param options - params to pass down for a more refined search\n * @param options.networks - the networks (in decimal) that you want to filter by\n * @param platform - indicates whether the platform is extension or mobile\n * @returns a Balances Response\n */\nexport async function fetchMultiChainBalances(\n address: string,\n options: { networks?: number[] },\n platform: 'extension' | 'mobile',\n) {\n const url = getBalancesUrl(address, {\n networks: options?.networks?.join(),\n });\n const response: GetBalancesResponse = await handleFetch(url, {\n headers: {\n 'x-metamask-clientproduct': `metamask-${platform}`,\n },\n });\n return response;\n}\n\n/**\n * Fetches Balances for multiple networks.\n *\n * @param options - params to pass down for a more refined search\n * @param options.accountAddresses - the account addresses that you want to filter by\n * @param options.networks - the networks (in decimal) that you want to filter by\n * @param platform - indicates whether the platform is extension or mobile\n * @returns a Balances Response\n */\nexport async function fetchMultiChainBalancesV4(\n options: { accountAddresses?: CaipAccountAddress[]; networks?: number[] },\n platform: 'extension' | 'mobile',\n) {\n const url = getBalancesUrlV4({\n accountAddresses: options?.accountAddresses?.join(),\n networks: options?.networks?.join(),\n });\n\n const response: GetBalancesResponse = await handleFetch(url, {\n headers: {\n 'x-metamask-clientproduct': `metamask-${platform}`,\n },\n });\n return response;\n}\n"]}
|
|
@@ -1,12 +1,15 @@
|
|
|
1
|
+
import type { CaipAccountAddress } from "@metamask/utils";
|
|
1
2
|
import type { GetBalancesResponse } from "./types.cjs";
|
|
2
3
|
export declare const MULTICHAIN_ACCOUNTS_DOMAIN = "https://accounts.api.cx.metamask.io";
|
|
3
4
|
/**
|
|
4
5
|
* Fetches Supported Networks.
|
|
6
|
+
*
|
|
5
7
|
* @returns supported networks (decimal)
|
|
6
8
|
*/
|
|
7
9
|
export declare function fetchSupportedNetworks(): Promise<number[]>;
|
|
8
10
|
/**
|
|
9
11
|
* Fetches Balances for multiple networks.
|
|
12
|
+
*
|
|
10
13
|
* @param address - address to fetch balances from
|
|
11
14
|
* @param options - params to pass down for a more refined search
|
|
12
15
|
* @param options.networks - the networks (in decimal) that you want to filter by
|
|
@@ -16,4 +19,17 @@ export declare function fetchSupportedNetworks(): Promise<number[]>;
|
|
|
16
19
|
export declare function fetchMultiChainBalances(address: string, options: {
|
|
17
20
|
networks?: number[];
|
|
18
21
|
}, platform: 'extension' | 'mobile'): Promise<GetBalancesResponse>;
|
|
22
|
+
/**
|
|
23
|
+
* Fetches Balances for multiple networks.
|
|
24
|
+
*
|
|
25
|
+
* @param options - params to pass down for a more refined search
|
|
26
|
+
* @param options.accountAddresses - the account addresses that you want to filter by
|
|
27
|
+
* @param options.networks - the networks (in decimal) that you want to filter by
|
|
28
|
+
* @param platform - indicates whether the platform is extension or mobile
|
|
29
|
+
* @returns a Balances Response
|
|
30
|
+
*/
|
|
31
|
+
export declare function fetchMultiChainBalancesV4(options: {
|
|
32
|
+
accountAddresses?: CaipAccountAddress[];
|
|
33
|
+
networks?: number[];
|
|
34
|
+
}, platform: 'extension' | 'mobile'): Promise<GetBalancesResponse>;
|
|
19
35
|
//# sourceMappingURL=multi-chain-accounts.d.cts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"multi-chain-accounts.d.cts","sourceRoot":"","sources":["../../src/multi-chain-accounts-service/multi-chain-accounts.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"multi-chain-accounts.d.cts","sourceRoot":"","sources":["../../src/multi-chain-accounts-service/multi-chain-accounts.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,kBAAkB,EAAE,wBAAwB;AAE1D,OAAO,KAAK,EAGV,mBAAmB,EAEpB,oBAAgB;AAEjB,eAAO,MAAM,0BAA0B,wCAAwC,CAAC;AA+BhF;;;;GAIG;AACH,wBAAsB,sBAAsB,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CAIhE;AAED;;;;;;;;GAQG;AACH,wBAAsB,uBAAuB,CAC3C,OAAO,EAAE,MAAM,EACf,OAAO,EAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;CAAE,EAChC,QAAQ,EAAE,WAAW,GAAG,QAAQ,gCAWjC;AAED;;;;;;;;GAQG;AACH,wBAAsB,yBAAyB,CAC7C,OAAO,EAAE;IAAE,gBAAgB,CAAC,EAAE,kBAAkB,EAAE,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;CAAE,EACzE,QAAQ,EAAE,WAAW,GAAG,QAAQ,gCAajC"}
|
|
@@ -1,12 +1,15 @@
|
|
|
1
|
+
import type { CaipAccountAddress } from "@metamask/utils";
|
|
1
2
|
import type { GetBalancesResponse } from "./types.mjs";
|
|
2
3
|
export declare const MULTICHAIN_ACCOUNTS_DOMAIN = "https://accounts.api.cx.metamask.io";
|
|
3
4
|
/**
|
|
4
5
|
* Fetches Supported Networks.
|
|
6
|
+
*
|
|
5
7
|
* @returns supported networks (decimal)
|
|
6
8
|
*/
|
|
7
9
|
export declare function fetchSupportedNetworks(): Promise<number[]>;
|
|
8
10
|
/**
|
|
9
11
|
* Fetches Balances for multiple networks.
|
|
12
|
+
*
|
|
10
13
|
* @param address - address to fetch balances from
|
|
11
14
|
* @param options - params to pass down for a more refined search
|
|
12
15
|
* @param options.networks - the networks (in decimal) that you want to filter by
|
|
@@ -16,4 +19,17 @@ export declare function fetchSupportedNetworks(): Promise<number[]>;
|
|
|
16
19
|
export declare function fetchMultiChainBalances(address: string, options: {
|
|
17
20
|
networks?: number[];
|
|
18
21
|
}, platform: 'extension' | 'mobile'): Promise<GetBalancesResponse>;
|
|
22
|
+
/**
|
|
23
|
+
* Fetches Balances for multiple networks.
|
|
24
|
+
*
|
|
25
|
+
* @param options - params to pass down for a more refined search
|
|
26
|
+
* @param options.accountAddresses - the account addresses that you want to filter by
|
|
27
|
+
* @param options.networks - the networks (in decimal) that you want to filter by
|
|
28
|
+
* @param platform - indicates whether the platform is extension or mobile
|
|
29
|
+
* @returns a Balances Response
|
|
30
|
+
*/
|
|
31
|
+
export declare function fetchMultiChainBalancesV4(options: {
|
|
32
|
+
accountAddresses?: CaipAccountAddress[];
|
|
33
|
+
networks?: number[];
|
|
34
|
+
}, platform: 'extension' | 'mobile'): Promise<GetBalancesResponse>;
|
|
19
35
|
//# sourceMappingURL=multi-chain-accounts.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"multi-chain-accounts.d.mts","sourceRoot":"","sources":["../../src/multi-chain-accounts-service/multi-chain-accounts.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"multi-chain-accounts.d.mts","sourceRoot":"","sources":["../../src/multi-chain-accounts-service/multi-chain-accounts.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,kBAAkB,EAAE,wBAAwB;AAE1D,OAAO,KAAK,EAGV,mBAAmB,EAEpB,oBAAgB;AAEjB,eAAO,MAAM,0BAA0B,wCAAwC,CAAC;AA+BhF;;;;GAIG;AACH,wBAAsB,sBAAsB,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CAIhE;AAED;;;;;;;;GAQG;AACH,wBAAsB,uBAAuB,CAC3C,OAAO,EAAE,MAAM,EACf,OAAO,EAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;CAAE,EAChC,QAAQ,EAAE,WAAW,GAAG,QAAQ,gCAWjC;AAED;;;;;;;;GAQG;AACH,wBAAsB,yBAAyB,CAC7C,OAAO,EAAE;IAAE,gBAAgB,CAAC,EAAE,kBAAkB,EAAE,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;CAAE,EACzE,QAAQ,EAAE,WAAW,GAAG,QAAQ,gCAajC"}
|
|
@@ -7,8 +7,19 @@ const getBalancesUrl = (address, queryParams) => {
|
|
|
7
7
|
}
|
|
8
8
|
return url;
|
|
9
9
|
};
|
|
10
|
+
const getBalancesUrlV4 = (queryParams) => {
|
|
11
|
+
const url = new URL(`${MULTICHAIN_ACCOUNTS_DOMAIN}/v4/multiaccount/balances`);
|
|
12
|
+
if (queryParams?.networks !== undefined) {
|
|
13
|
+
url.searchParams.append('networks', queryParams.networks);
|
|
14
|
+
}
|
|
15
|
+
if (queryParams?.accountAddresses !== undefined) {
|
|
16
|
+
url.searchParams.append('accountAddresses', queryParams.accountAddresses);
|
|
17
|
+
}
|
|
18
|
+
return url;
|
|
19
|
+
};
|
|
10
20
|
/**
|
|
11
21
|
* Fetches Supported Networks.
|
|
22
|
+
*
|
|
12
23
|
* @returns supported networks (decimal)
|
|
13
24
|
*/
|
|
14
25
|
export async function fetchSupportedNetworks() {
|
|
@@ -18,6 +29,7 @@ export async function fetchSupportedNetworks() {
|
|
|
18
29
|
}
|
|
19
30
|
/**
|
|
20
31
|
* Fetches Balances for multiple networks.
|
|
32
|
+
*
|
|
21
33
|
* @param address - address to fetch balances from
|
|
22
34
|
* @param options - params to pass down for a more refined search
|
|
23
35
|
* @param options.networks - the networks (in decimal) that you want to filter by
|
|
@@ -35,4 +47,25 @@ export async function fetchMultiChainBalances(address, options, platform) {
|
|
|
35
47
|
});
|
|
36
48
|
return response;
|
|
37
49
|
}
|
|
50
|
+
/**
|
|
51
|
+
* Fetches Balances for multiple networks.
|
|
52
|
+
*
|
|
53
|
+
* @param options - params to pass down for a more refined search
|
|
54
|
+
* @param options.accountAddresses - the account addresses that you want to filter by
|
|
55
|
+
* @param options.networks - the networks (in decimal) that you want to filter by
|
|
56
|
+
* @param platform - indicates whether the platform is extension or mobile
|
|
57
|
+
* @returns a Balances Response
|
|
58
|
+
*/
|
|
59
|
+
export async function fetchMultiChainBalancesV4(options, platform) {
|
|
60
|
+
const url = getBalancesUrlV4({
|
|
61
|
+
accountAddresses: options?.accountAddresses?.join(),
|
|
62
|
+
networks: options?.networks?.join(),
|
|
63
|
+
});
|
|
64
|
+
const response = await handleFetch(url, {
|
|
65
|
+
headers: {
|
|
66
|
+
'x-metamask-clientproduct': `metamask-${platform}`,
|
|
67
|
+
},
|
|
68
|
+
});
|
|
69
|
+
return response;
|
|
70
|
+
}
|
|
38
71
|
//# sourceMappingURL=multi-chain-accounts.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"multi-chain-accounts.mjs","sourceRoot":"","sources":["../../src/multi-chain-accounts-service/multi-chain-accounts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,mCAAmC;
|
|
1
|
+
{"version":3,"file":"multi-chain-accounts.mjs","sourceRoot":"","sources":["../../src/multi-chain-accounts-service/multi-chain-accounts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,mCAAmC;AAUzD,MAAM,CAAC,MAAM,0BAA0B,GAAG,qCAAqC,CAAC;AAEhF,MAAM,cAAc,GAAG,CACrB,OAAe,EACf,WAAoC,EACpC,EAAE;IACF,MAAM,GAAG,GAAG,IAAI,GAAG,CACjB,GAAG,0BAA0B,gBAAgB,OAAO,WAAW,CAChE,CAAC;IAEF,IAAI,WAAW,EAAE,QAAQ,KAAK,SAAS,EAAE;QACvC,GAAG,CAAC,YAAY,CAAC,MAAM,CAAC,UAAU,EAAE,WAAW,CAAC,QAAQ,CAAC,CAAC;KAC3D;IAED,OAAO,GAAG,CAAC;AACb,CAAC,CAAC;AAEF,MAAM,gBAAgB,GAAG,CAAC,WAAsC,EAAE,EAAE;IAClE,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,0BAA0B,2BAA2B,CAAC,CAAC;IAE9E,IAAI,WAAW,EAAE,QAAQ,KAAK,SAAS,EAAE;QACvC,GAAG,CAAC,YAAY,CAAC,MAAM,CAAC,UAAU,EAAE,WAAW,CAAC,QAAQ,CAAC,CAAC;KAC3D;IAED,IAAI,WAAW,EAAE,gBAAgB,KAAK,SAAS,EAAE;QAC/C,GAAG,CAAC,YAAY,CAAC,MAAM,CAAC,kBAAkB,EAAE,WAAW,CAAC,gBAAgB,CAAC,CAAC;KAC3E;IAED,OAAO,GAAG,CAAC;AACb,CAAC,CAAC;AAEF;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,sBAAsB;IAC1C,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,0BAA0B,uBAAuB,CAAC,CAAC;IAC1E,MAAM,QAAQ,GAAiC,MAAM,WAAW,CAAC,GAAG,CAAC,CAAC;IACtE,OAAO,QAAQ,CAAC,WAAW,CAAC;AAC9B,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,OAAe,EACf,OAAgC,EAChC,QAAgC;IAEhC,MAAM,GAAG,GAAG,cAAc,CAAC,OAAO,EAAE;QAClC,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE;KACpC,CAAC,CAAC;IACH,MAAM,QAAQ,GAAwB,MAAM,WAAW,CAAC,GAAG,EAAE;QAC3D,OAAO,EAAE;YACP,0BAA0B,EAAE,YAAY,QAAQ,EAAE;SACnD;KACF,CAAC,CAAC;IACH,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,yBAAyB,CAC7C,OAAyE,EACzE,QAAgC;IAEhC,MAAM,GAAG,GAAG,gBAAgB,CAAC;QAC3B,gBAAgB,EAAE,OAAO,EAAE,gBAAgB,EAAE,IAAI,EAAE;QACnD,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE;KACpC,CAAC,CAAC;IAEH,MAAM,QAAQ,GAAwB,MAAM,WAAW,CAAC,GAAG,EAAE;QAC3D,OAAO,EAAE;YACP,0BAA0B,EAAE,YAAY,QAAQ,EAAE;SACnD;KACF,CAAC,CAAC;IACH,OAAO,QAAQ,CAAC;AAClB,CAAC","sourcesContent":["import { handleFetch } from '@metamask/controller-utils';\nimport type { CaipAccountAddress } from '@metamask/utils';\n\nimport type {\n GetBalancesQueryParams,\n GetBalancesQueryParamsV4,\n GetBalancesResponse,\n GetSupportedNetworksResponse,\n} from './types';\n\nexport const MULTICHAIN_ACCOUNTS_DOMAIN = 'https://accounts.api.cx.metamask.io';\n\nconst getBalancesUrl = (\n address: string,\n queryParams?: GetBalancesQueryParams,\n) => {\n const url = new URL(\n `${MULTICHAIN_ACCOUNTS_DOMAIN}/v2/accounts/${address}/balances`,\n );\n\n if (queryParams?.networks !== undefined) {\n url.searchParams.append('networks', queryParams.networks);\n }\n\n return url;\n};\n\nconst getBalancesUrlV4 = (queryParams?: GetBalancesQueryParamsV4) => {\n const url = new URL(`${MULTICHAIN_ACCOUNTS_DOMAIN}/v4/multiaccount/balances`);\n\n if (queryParams?.networks !== undefined) {\n url.searchParams.append('networks', queryParams.networks);\n }\n\n if (queryParams?.accountAddresses !== undefined) {\n url.searchParams.append('accountAddresses', queryParams.accountAddresses);\n }\n\n return url;\n};\n\n/**\n * Fetches Supported Networks.\n *\n * @returns supported networks (decimal)\n */\nexport async function fetchSupportedNetworks(): Promise<number[]> {\n const url = new URL(`${MULTICHAIN_ACCOUNTS_DOMAIN}/v1/supportedNetworks`);\n const response: GetSupportedNetworksResponse = await handleFetch(url);\n return response.fullSupport;\n}\n\n/**\n * Fetches Balances for multiple networks.\n *\n * @param address - address to fetch balances from\n * @param options - params to pass down for a more refined search\n * @param options.networks - the networks (in decimal) that you want to filter by\n * @param platform - indicates whether the platform is extension or mobile\n * @returns a Balances Response\n */\nexport async function fetchMultiChainBalances(\n address: string,\n options: { networks?: number[] },\n platform: 'extension' | 'mobile',\n) {\n const url = getBalancesUrl(address, {\n networks: options?.networks?.join(),\n });\n const response: GetBalancesResponse = await handleFetch(url, {\n headers: {\n 'x-metamask-clientproduct': `metamask-${platform}`,\n },\n });\n return response;\n}\n\n/**\n * Fetches Balances for multiple networks.\n *\n * @param options - params to pass down for a more refined search\n * @param options.accountAddresses - the account addresses that you want to filter by\n * @param options.networks - the networks (in decimal) that you want to filter by\n * @param platform - indicates whether the platform is extension or mobile\n * @returns a Balances Response\n */\nexport async function fetchMultiChainBalancesV4(\n options: { accountAddresses?: CaipAccountAddress[]; networks?: number[] },\n platform: 'extension' | 'mobile',\n) {\n const url = getBalancesUrlV4({\n accountAddresses: options?.accountAddresses?.join(),\n networks: options?.networks?.join(),\n });\n\n const response: GetBalancesResponse = await handleFetch(url, {\n headers: {\n 'x-metamask-clientproduct': `metamask-${platform}`,\n },\n });\n return response;\n}\n"]}
|