@metamask-previews/assets-controller 2.0.0-preview-33dbba4f3 → 2.0.0-preview-a196307b6
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 +6 -0
- package/dist/data-sources/RpcDataSource.cjs +1 -2
- package/dist/data-sources/RpcDataSource.cjs.map +1 -1
- package/dist/data-sources/RpcDataSource.d.cts.map +1 -1
- package/dist/data-sources/RpcDataSource.d.mts.map +1 -1
- package/dist/data-sources/RpcDataSource.mjs +1 -2
- package/dist/data-sources/RpcDataSource.mjs.map +1 -1
- package/dist/data-sources/StakedBalanceDataSource.cjs +6 -18
- package/dist/data-sources/StakedBalanceDataSource.cjs.map +1 -1
- package/dist/data-sources/StakedBalanceDataSource.d.cts.map +1 -1
- package/dist/data-sources/StakedBalanceDataSource.d.mts.map +1 -1
- package/dist/data-sources/StakedBalanceDataSource.mjs +6 -18
- package/dist/data-sources/StakedBalanceDataSource.mjs.map +1 -1
- package/dist/data-sources/evm-rpc-services/services/StakedBalanceFetcher.cjs +6 -6
- package/dist/data-sources/evm-rpc-services/services/StakedBalanceFetcher.cjs.map +1 -1
- package/dist/data-sources/evm-rpc-services/services/StakedBalanceFetcher.d.cts +2 -0
- package/dist/data-sources/evm-rpc-services/services/StakedBalanceFetcher.d.cts.map +1 -1
- package/dist/data-sources/evm-rpc-services/services/StakedBalanceFetcher.d.mts +2 -0
- package/dist/data-sources/evm-rpc-services/services/StakedBalanceFetcher.d.mts.map +1 -1
- package/dist/data-sources/evm-rpc-services/services/StakedBalanceFetcher.mjs +1 -1
- package/dist/data-sources/evm-rpc-services/services/StakedBalanceFetcher.mjs.map +1 -1
- package/package.json +1 -1
|
@@ -12,7 +12,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
12
12
|
};
|
|
13
13
|
var _StakedBalanceFetcher_providerGetter, _StakedBalanceFetcher_onStakedBalanceUpdate;
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
-
exports.StakedBalanceFetcher = exports.isStakingContractAssetId = exports.getSupportedStakingChainIds = exports.getStakingContractAddress = void 0;
|
|
15
|
+
exports.StakedBalanceFetcher = exports.STAKING_INTERFACE = exports.isStakingContractAssetId = exports.getSupportedStakingChainIds = exports.getStakingContractAddress = void 0;
|
|
16
16
|
const abi_1 = require("@ethersproject/abi");
|
|
17
17
|
const providers_1 = require("@ethersproject/providers");
|
|
18
18
|
const polling_controller_1 = require("@metamask/polling-controller");
|
|
@@ -37,7 +37,7 @@ const STAKING_CONTRACT_ABI = [
|
|
|
37
37
|
type: 'function',
|
|
38
38
|
},
|
|
39
39
|
];
|
|
40
|
-
|
|
40
|
+
exports.STAKING_INTERFACE = new abi_1.Interface(STAKING_CONTRACT_ABI);
|
|
41
41
|
const STAKING_DECIMALS = 18;
|
|
42
42
|
const DEFAULT_STAKED_BALANCE_INTERVAL = 180000; // 3 minutes
|
|
43
43
|
class StakedBalanceFetcher extends (0, polling_controller_1.StaticIntervalPollingControllerOnly)() {
|
|
@@ -98,24 +98,24 @@ class StakedBalanceFetcher extends (0, polling_controller_1.StaticIntervalPollin
|
|
|
98
98
|
return { amount: '0' };
|
|
99
99
|
}
|
|
100
100
|
try {
|
|
101
|
-
const sharesCalldata = STAKING_INTERFACE.encodeFunctionData('getShares', [
|
|
101
|
+
const sharesCalldata = exports.STAKING_INTERFACE.encodeFunctionData('getShares', [
|
|
102
102
|
accountAddress,
|
|
103
103
|
]);
|
|
104
104
|
const sharesResult = await provider.call({
|
|
105
105
|
to: contractAddress,
|
|
106
106
|
data: sharesCalldata,
|
|
107
107
|
});
|
|
108
|
-
const sharesRaw = STAKING_INTERFACE.decodeFunctionResult('getShares', sharesResult)[0];
|
|
108
|
+
const sharesRaw = exports.STAKING_INTERFACE.decodeFunctionResult('getShares', sharesResult)[0];
|
|
109
109
|
const sharesBigNum = BigInt(sharesRaw.toString());
|
|
110
110
|
if (sharesBigNum === 0n) {
|
|
111
111
|
return { amount: '0' };
|
|
112
112
|
}
|
|
113
|
-
const assetsCalldata = STAKING_INTERFACE.encodeFunctionData('convertToAssets', [sharesBigNum]);
|
|
113
|
+
const assetsCalldata = exports.STAKING_INTERFACE.encodeFunctionData('convertToAssets', [sharesBigNum]);
|
|
114
114
|
const assetsResult = await provider.call({
|
|
115
115
|
to: contractAddress,
|
|
116
116
|
data: assetsCalldata,
|
|
117
117
|
});
|
|
118
|
-
const assetsRaw = STAKING_INTERFACE.decodeFunctionResult('convertToAssets', assetsResult)[0];
|
|
118
|
+
const assetsRaw = exports.STAKING_INTERFACE.decodeFunctionResult('convertToAssets', assetsResult)[0];
|
|
119
119
|
const assetsWei = BigInt(assetsRaw.toString());
|
|
120
120
|
const amount = (0, utils_1.weiToHumanReadable)(assetsWei, STAKING_DECIMALS);
|
|
121
121
|
return { amount };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StakedBalanceFetcher.cjs","sourceRoot":"","sources":["../../../../src/data-sources/evm-rpc-services/services/StakedBalanceFetcher.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,4CAA+C;AAC/C,wDAAwD;AACxD,qEAAmF;AAGnF,8CAKkB;AAGhB,0GAPA,iCAAyB,OAOA;AACzB,4GAPA,mCAA2B,OAOA;AAC3B,yGAPA,gCAAwB,OAOA;AAkC1B,4EAA4E;AAC5E,MAAM,oBAAoB,GAAG;IAC3B;QACE,MAAM,EAAE,CAAC,EAAE,YAAY,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;QACvE,IAAI,EAAE,WAAW;QACjB,OAAO,EAAE,CAAC,EAAE,YAAY,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;QACjE,eAAe,EAAE,MAAM;QACvB,IAAI,EAAE,UAAU;KACjB;IACD;QACE,MAAM,EAAE,CAAC,EAAE,YAAY,EAAE,SAAS,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;QACtE,IAAI,EAAE,iBAAiB;QACvB,OAAO,EAAE,CAAC,EAAE,YAAY,EAAE,SAAS,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;QACvE,eAAe,EAAE,MAAM;QACvB,IAAI,EAAE,UAAU;KACjB;CACF,CAAC;
|
|
1
|
+
{"version":3,"file":"StakedBalanceFetcher.cjs","sourceRoot":"","sources":["../../../../src/data-sources/evm-rpc-services/services/StakedBalanceFetcher.ts"],"names":[],"mappings":"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","sourcesContent":["import { Interface } from '@ethersproject/abi';\nimport { Web3Provider } from '@ethersproject/providers';\nimport { StaticIntervalPollingControllerOnly } from '@metamask/polling-controller';\n\nimport type { Address, AccountId, ChainId } from '../types';\nimport {\n getStakingContractAddress,\n getSupportedStakingChainIds,\n isStakingContractAssetId,\n weiToHumanReadable,\n} from '../utils';\n\nexport {\n getStakingContractAddress,\n getSupportedStakingChainIds,\n isStakingContractAssetId,\n};\n\nexport type StakedBalancePollingInput = {\n /** Chain ID (hex format, e.g. 0x1) */\n chainId: ChainId;\n /** Account ID */\n accountId: AccountId;\n /** Account address */\n accountAddress: Address;\n};\n\n/** Human-readable staked balance (e.g. \"1.5\" for 1.5 ETH). */\nexport type StakedBalance = {\n amount: string;\n};\n\n/** Result reported via the update callback. */\nexport type StakedBalanceFetchResult = {\n /** Account ID (UUID). */\n accountId: AccountId;\n /** Hex chain ID. */\n chainId: ChainId;\n /** Human-readable staked balance. */\n balance: StakedBalance;\n};\n\n/**\n * Callback type for staked balance updates.\n */\nexport type OnStakedBalanceUpdateCallback = (\n result: StakedBalanceFetchResult,\n) => void;\n\n/** Staking contract ABI: getShares(account) and convertToAssets(shares). */\nconst STAKING_CONTRACT_ABI = [\n {\n inputs: [{ internalType: 'address', name: 'account', type: 'address' }],\n name: 'getShares',\n outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }],\n stateMutability: 'view',\n type: 'function',\n },\n {\n inputs: [{ internalType: 'uint256', name: 'shares', type: 'uint256' }],\n name: 'convertToAssets',\n outputs: [{ internalType: 'uint256', name: 'assets', type: 'uint256' }],\n stateMutability: 'view',\n type: 'function',\n },\n];\n\nexport const STAKING_INTERFACE = new Interface(STAKING_CONTRACT_ABI);\n\nconst STAKING_DECIMALS = 18;\n\nexport type StakedBalanceFetcherConfig = {\n /** Polling interval in ms (default: 180s) */\n pollingInterval?: number;\n /** Returns the network provider for the given chain. Required for fetchStakedBalance. */\n getNetworkProvider?: (chainId: ChainId) => Web3Provider | undefined;\n};\n\nconst DEFAULT_STAKED_BALANCE_INTERVAL = 180_000; // 3 minutes\n\nexport class StakedBalanceFetcher extends StaticIntervalPollingControllerOnly<StakedBalancePollingInput>() {\n readonly #providerGetter?: (chainId: ChainId) => Web3Provider | undefined;\n\n #onStakedBalanceUpdate: OnStakedBalanceUpdateCallback | undefined;\n\n constructor(config?: StakedBalanceFetcherConfig) {\n super();\n this.#providerGetter = config?.getNetworkProvider;\n\n this.setIntervalLength(\n config?.pollingInterval ?? DEFAULT_STAKED_BALANCE_INTERVAL,\n );\n }\n\n /**\n * Register a callback that is invoked after every successful poll with\n * the staked balance (including zero). Zero is reported so that merged\n * updates can clear prior non-zero state.\n *\n * @param callback - The callback to invoke.\n */\n setOnStakedBalanceUpdate(callback: OnStakedBalanceUpdateCallback): void {\n this.#onStakedBalanceUpdate = callback;\n }\n\n async _executePoll(input: StakedBalancePollingInput): Promise<void> {\n let result: StakedBalance;\n try {\n result = await this.fetchStakedBalance(input);\n } catch {\n // Do not push an update on provider/RPC failure; otherwise we would\n // overwrite existing non-zero staked balances with zero in state.\n return;\n }\n\n if (this.#onStakedBalanceUpdate) {\n this.#onStakedBalanceUpdate({\n accountId: input.accountId,\n chainId: input.chainId,\n balance: result,\n });\n }\n }\n\n /**\n * Fetches the staked balance for an account on a chain using the same\n * staking contract as AccountTrackerController (getShares then convertToAssets).\n * Returns a human-readable amount string (e.g. \"1.5\" for 1.5 ETH).\n * Throws when no provider is available or when the RPC/contract call fails, so\n * callers do not persist a false zero and overwrite existing balances.\n *\n * @param input - Chain, account ID, and address to query.\n * @returns Human-readable staked balance (amount string).\n * @throws When provider is missing or when getShares/convertToAssets fails.\n */\n async fetchStakedBalance(\n input: StakedBalancePollingInput,\n ): Promise<StakedBalance> {\n const { chainId, accountAddress } = input;\n const provider = this.#providerGetter?.(chainId);\n if (!provider) {\n throw new Error('StakedBalanceFetcher: no provider available for chain');\n }\n const contractAddress = getStakingContractAddress(chainId);\n\n if (!contractAddress) {\n return { amount: '0' };\n }\n\n try {\n const sharesCalldata = STAKING_INTERFACE.encodeFunctionData('getShares', [\n accountAddress,\n ]);\n const sharesResult = await provider.call({\n to: contractAddress,\n data: sharesCalldata,\n });\n const sharesRaw = STAKING_INTERFACE.decodeFunctionResult(\n 'getShares',\n sharesResult,\n )[0];\n const sharesBigNum = BigInt(sharesRaw.toString());\n\n if (sharesBigNum === 0n) {\n return { amount: '0' };\n }\n\n const assetsCalldata = STAKING_INTERFACE.encodeFunctionData(\n 'convertToAssets',\n [sharesBigNum],\n );\n const assetsResult = await provider.call({\n to: contractAddress,\n data: assetsCalldata,\n });\n const assetsRaw = STAKING_INTERFACE.decodeFunctionResult(\n 'convertToAssets',\n assetsResult,\n )[0];\n const assetsWei = BigInt(assetsRaw.toString());\n\n const amount = weiToHumanReadable(assetsWei, STAKING_DECIMALS);\n return { amount };\n } catch (error) {\n throw error instanceof Error\n ? error\n : new Error('StakedBalanceFetcher: failed to fetch staked balance');\n }\n }\n}\n"]}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Interface } from "@ethersproject/abi";
|
|
1
2
|
import { Web3Provider } from "@ethersproject/providers";
|
|
2
3
|
import type { Address, AccountId, ChainId } from "../types/index.cjs";
|
|
3
4
|
import { getStakingContractAddress, getSupportedStakingChainIds, isStakingContractAssetId } from "../utils/index.cjs";
|
|
@@ -27,6 +28,7 @@ export type StakedBalanceFetchResult = {
|
|
|
27
28
|
* Callback type for staked balance updates.
|
|
28
29
|
*/
|
|
29
30
|
export type OnStakedBalanceUpdateCallback = (result: StakedBalanceFetchResult) => void;
|
|
31
|
+
export declare const STAKING_INTERFACE: Interface;
|
|
30
32
|
export type StakedBalanceFetcherConfig = {
|
|
31
33
|
/** Polling interval in ms (default: 180s) */
|
|
32
34
|
pollingInterval?: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StakedBalanceFetcher.d.cts","sourceRoot":"","sources":["../../../../src/data-sources/evm-rpc-services/services/StakedBalanceFetcher.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"StakedBalanceFetcher.d.cts","sourceRoot":"","sources":["../../../../src/data-sources/evm-rpc-services/services/StakedBalanceFetcher.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,2BAA2B;AAC/C,OAAO,EAAE,YAAY,EAAE,iCAAiC;AAGxD,OAAO,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,2BAAiB;AAC5D,OAAO,EACL,yBAAyB,EACzB,2BAA2B,EAC3B,wBAAwB,EAEzB,2BAAiB;AAElB,OAAO,EACL,yBAAyB,EACzB,2BAA2B,EAC3B,wBAAwB,GACzB,CAAC;AAEF,MAAM,MAAM,yBAAyB,GAAG;IACtC,sCAAsC;IACtC,OAAO,EAAE,OAAO,CAAC;IACjB,iBAAiB;IACjB,SAAS,EAAE,SAAS,CAAC;IACrB,sBAAsB;IACtB,cAAc,EAAE,OAAO,CAAC;CACzB,CAAC;AAEF,8DAA8D;AAC9D,MAAM,MAAM,aAAa,GAAG;IAC1B,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,+CAA+C;AAC/C,MAAM,MAAM,wBAAwB,GAAG;IACrC,yBAAyB;IACzB,SAAS,EAAE,SAAS,CAAC;IACrB,oBAAoB;IACpB,OAAO,EAAE,OAAO,CAAC;IACjB,qCAAqC;IACrC,OAAO,EAAE,aAAa,CAAC;CACxB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,6BAA6B,GAAG,CAC1C,MAAM,EAAE,wBAAwB,KAC7B,IAAI,CAAC;AAoBV,eAAO,MAAM,iBAAiB,WAAsC,CAAC;AAIrE,MAAM,MAAM,0BAA0B,GAAG;IACvC,6CAA6C;IAC7C,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,yFAAyF;IACzF,kBAAkB,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,YAAY,GAAG,SAAS,CAAC;CACrE,CAAC;;;;;6CAzDA,sCAAsC;;;;;;;;;;;;;AA6DxC,qBAAa,oBAAqB,SAAQ,yBAAgE;;gBAK5F,MAAM,CAAC,EAAE,0BAA0B;IAS/C;;;;;;OAMG;IACH,wBAAwB,CAAC,QAAQ,EAAE,6BAA6B,GAAG,IAAI;IAIjE,YAAY,CAAC,KAAK,EAAE,yBAAyB,GAAG,OAAO,CAAC,IAAI,CAAC;IAmBnE;;;;;;;;;;OAUG;IACG,kBAAkB,CACtB,KAAK,EAAE,yBAAyB,GAC/B,OAAO,CAAC,aAAa,CAAC;CAoD1B"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Interface } from "@ethersproject/abi";
|
|
1
2
|
import { Web3Provider } from "@ethersproject/providers";
|
|
2
3
|
import type { Address, AccountId, ChainId } from "../types/index.mjs";
|
|
3
4
|
import { getStakingContractAddress, getSupportedStakingChainIds, isStakingContractAssetId } from "../utils/index.mjs";
|
|
@@ -27,6 +28,7 @@ export type StakedBalanceFetchResult = {
|
|
|
27
28
|
* Callback type for staked balance updates.
|
|
28
29
|
*/
|
|
29
30
|
export type OnStakedBalanceUpdateCallback = (result: StakedBalanceFetchResult) => void;
|
|
31
|
+
export declare const STAKING_INTERFACE: Interface;
|
|
30
32
|
export type StakedBalanceFetcherConfig = {
|
|
31
33
|
/** Polling interval in ms (default: 180s) */
|
|
32
34
|
pollingInterval?: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StakedBalanceFetcher.d.mts","sourceRoot":"","sources":["../../../../src/data-sources/evm-rpc-services/services/StakedBalanceFetcher.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"StakedBalanceFetcher.d.mts","sourceRoot":"","sources":["../../../../src/data-sources/evm-rpc-services/services/StakedBalanceFetcher.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,2BAA2B;AAC/C,OAAO,EAAE,YAAY,EAAE,iCAAiC;AAGxD,OAAO,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,2BAAiB;AAC5D,OAAO,EACL,yBAAyB,EACzB,2BAA2B,EAC3B,wBAAwB,EAEzB,2BAAiB;AAElB,OAAO,EACL,yBAAyB,EACzB,2BAA2B,EAC3B,wBAAwB,GACzB,CAAC;AAEF,MAAM,MAAM,yBAAyB,GAAG;IACtC,sCAAsC;IACtC,OAAO,EAAE,OAAO,CAAC;IACjB,iBAAiB;IACjB,SAAS,EAAE,SAAS,CAAC;IACrB,sBAAsB;IACtB,cAAc,EAAE,OAAO,CAAC;CACzB,CAAC;AAEF,8DAA8D;AAC9D,MAAM,MAAM,aAAa,GAAG;IAC1B,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,+CAA+C;AAC/C,MAAM,MAAM,wBAAwB,GAAG;IACrC,yBAAyB;IACzB,SAAS,EAAE,SAAS,CAAC;IACrB,oBAAoB;IACpB,OAAO,EAAE,OAAO,CAAC;IACjB,qCAAqC;IACrC,OAAO,EAAE,aAAa,CAAC;CACxB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,6BAA6B,GAAG,CAC1C,MAAM,EAAE,wBAAwB,KAC7B,IAAI,CAAC;AAoBV,eAAO,MAAM,iBAAiB,WAAsC,CAAC;AAIrE,MAAM,MAAM,0BAA0B,GAAG;IACvC,6CAA6C;IAC7C,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,yFAAyF;IACzF,kBAAkB,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,YAAY,GAAG,SAAS,CAAC;CACrE,CAAC;;;;;6CAzDA,sCAAsC;;;;;;;;;;;;;AA6DxC,qBAAa,oBAAqB,SAAQ,yBAAgE;;gBAK5F,MAAM,CAAC,EAAE,0BAA0B;IAS/C;;;;;;OAMG;IACH,wBAAwB,CAAC,QAAQ,EAAE,6BAA6B,GAAG,IAAI;IAIjE,YAAY,CAAC,KAAK,EAAE,yBAAyB,GAAG,OAAO,CAAC,IAAI,CAAC;IAmBnE;;;;;;;;;;OAUG;IACG,kBAAkB,CACtB,KAAK,EAAE,yBAAyB,GAC/B,OAAO,CAAC,aAAa,CAAC;CAoD1B"}
|
|
@@ -32,7 +32,7 @@ const STAKING_CONTRACT_ABI = [
|
|
|
32
32
|
type: 'function',
|
|
33
33
|
},
|
|
34
34
|
];
|
|
35
|
-
const STAKING_INTERFACE = new Interface(STAKING_CONTRACT_ABI);
|
|
35
|
+
export const STAKING_INTERFACE = new Interface(STAKING_CONTRACT_ABI);
|
|
36
36
|
const STAKING_DECIMALS = 18;
|
|
37
37
|
const DEFAULT_STAKED_BALANCE_INTERVAL = 180000; // 3 minutes
|
|
38
38
|
export class StakedBalanceFetcher extends StaticIntervalPollingControllerOnly() {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StakedBalanceFetcher.mjs","sourceRoot":"","sources":["../../../../src/data-sources/evm-rpc-services/services/StakedBalanceFetcher.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,OAAO,EAAE,SAAS,EAAE,2BAA2B;AAC/C,OAAO,EAAE,YAAY,EAAE,iCAAiC;AACxD,OAAO,EAAE,mCAAmC,EAAE,qCAAqC;AAGnF,OAAO,EACL,yBAAyB,EACzB,2BAA2B,EAC3B,wBAAwB,EACxB,kBAAkB,EACnB,2BAAiB;AAElB,OAAO,EACL,yBAAyB,EACzB,2BAA2B,EAC3B,wBAAwB,EACzB,CAAC;AAiCF,4EAA4E;AAC5E,MAAM,oBAAoB,GAAG;IAC3B;QACE,MAAM,EAAE,CAAC,EAAE,YAAY,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;QACvE,IAAI,EAAE,WAAW;QACjB,OAAO,EAAE,CAAC,EAAE,YAAY,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;QACjE,eAAe,EAAE,MAAM;QACvB,IAAI,EAAE,UAAU;KACjB;IACD;QACE,MAAM,EAAE,CAAC,EAAE,YAAY,EAAE,SAAS,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;QACtE,IAAI,EAAE,iBAAiB;QACvB,OAAO,EAAE,CAAC,EAAE,YAAY,EAAE,SAAS,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;QACvE,eAAe,EAAE,MAAM;QACvB,IAAI,EAAE,UAAU;KACjB;CACF,CAAC;AAEF,MAAM,iBAAiB,GAAG,IAAI,SAAS,CAAC,oBAAoB,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"StakedBalanceFetcher.mjs","sourceRoot":"","sources":["../../../../src/data-sources/evm-rpc-services/services/StakedBalanceFetcher.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,OAAO,EAAE,SAAS,EAAE,2BAA2B;AAC/C,OAAO,EAAE,YAAY,EAAE,iCAAiC;AACxD,OAAO,EAAE,mCAAmC,EAAE,qCAAqC;AAGnF,OAAO,EACL,yBAAyB,EACzB,2BAA2B,EAC3B,wBAAwB,EACxB,kBAAkB,EACnB,2BAAiB;AAElB,OAAO,EACL,yBAAyB,EACzB,2BAA2B,EAC3B,wBAAwB,EACzB,CAAC;AAiCF,4EAA4E;AAC5E,MAAM,oBAAoB,GAAG;IAC3B;QACE,MAAM,EAAE,CAAC,EAAE,YAAY,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;QACvE,IAAI,EAAE,WAAW;QACjB,OAAO,EAAE,CAAC,EAAE,YAAY,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;QACjE,eAAe,EAAE,MAAM;QACvB,IAAI,EAAE,UAAU;KACjB;IACD;QACE,MAAM,EAAE,CAAC,EAAE,YAAY,EAAE,SAAS,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;QACtE,IAAI,EAAE,iBAAiB;QACvB,OAAO,EAAE,CAAC,EAAE,YAAY,EAAE,SAAS,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;QACvE,eAAe,EAAE,MAAM;QACvB,IAAI,EAAE,UAAU;KACjB;CACF,CAAC;AAEF,MAAM,CAAC,MAAM,iBAAiB,GAAG,IAAI,SAAS,CAAC,oBAAoB,CAAC,CAAC;AAErE,MAAM,gBAAgB,GAAG,EAAE,CAAC;AAS5B,MAAM,+BAA+B,GAAG,MAAO,CAAC,CAAC,YAAY;AAE7D,MAAM,OAAO,oBAAqB,SAAQ,mCAAmC,EAA6B;IAKxG,YAAY,MAAmC;QAC7C,KAAK,EAAE,CAAC;QALD,uDAAiE;QAE1E,8DAAkE;QAIhE,uBAAA,IAAI,wCAAmB,MAAM,EAAE,kBAAkB,MAAA,CAAC;QAElD,IAAI,CAAC,iBAAiB,CACpB,MAAM,EAAE,eAAe,IAAI,+BAA+B,CAC3D,CAAC;IACJ,CAAC;IAED;;;;;;OAMG;IACH,wBAAwB,CAAC,QAAuC;QAC9D,uBAAA,IAAI,+CAA0B,QAAQ,MAAA,CAAC;IACzC,CAAC;IAED,KAAK,CAAC,YAAY,CAAC,KAAgC;QACjD,IAAI,MAAqB,CAAC;QAC1B,IAAI,CAAC;YACH,MAAM,GAAG,MAAM,IAAI,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAC;QAChD,CAAC;QAAC,MAAM,CAAC;YACP,oEAAoE;YACpE,kEAAkE;YAClE,OAAO;QACT,CAAC;QAED,IAAI,uBAAA,IAAI,mDAAuB,EAAE,CAAC;YAChC,uBAAA,IAAI,mDAAuB,MAA3B,IAAI,EAAwB;gBAC1B,SAAS,EAAE,KAAK,CAAC,SAAS;gBAC1B,OAAO,EAAE,KAAK,CAAC,OAAO;gBACtB,OAAO,EAAE,MAAM;aAChB,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED;;;;;;;;;;OAUG;IACH,KAAK,CAAC,kBAAkB,CACtB,KAAgC;QAEhC,MAAM,EAAE,OAAO,EAAE,cAAc,EAAE,GAAG,KAAK,CAAC;QAC1C,MAAM,QAAQ,GAAG,uBAAA,IAAI,4CAAgB,EAAE,KAAtB,IAAI,EAAmB,OAAO,CAAC,CAAC;QACjD,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,MAAM,IAAI,KAAK,CAAC,uDAAuD,CAAC,CAAC;QAC3E,CAAC;QACD,MAAM,eAAe,GAAG,yBAAyB,CAAC,OAAO,CAAC,CAAC;QAE3D,IAAI,CAAC,eAAe,EAAE,CAAC;YACrB,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC;QACzB,CAAC;QAED,IAAI,CAAC;YACH,MAAM,cAAc,GAAG,iBAAiB,CAAC,kBAAkB,CAAC,WAAW,EAAE;gBACvE,cAAc;aACf,CAAC,CAAC;YACH,MAAM,YAAY,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC;gBACvC,EAAE,EAAE,eAAe;gBACnB,IAAI,EAAE,cAAc;aACrB,CAAC,CAAC;YACH,MAAM,SAAS,GAAG,iBAAiB,CAAC,oBAAoB,CACtD,WAAW,EACX,YAAY,CACb,CAAC,CAAC,CAAC,CAAC;YACL,MAAM,YAAY,GAAG,MAAM,CAAC,SAAS,CAAC,QAAQ,EAAE,CAAC,CAAC;YAElD,IAAI,YAAY,KAAK,EAAE,EAAE,CAAC;gBACxB,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC;YACzB,CAAC;YAED,MAAM,cAAc,GAAG,iBAAiB,CAAC,kBAAkB,CACzD,iBAAiB,EACjB,CAAC,YAAY,CAAC,CACf,CAAC;YACF,MAAM,YAAY,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC;gBACvC,EAAE,EAAE,eAAe;gBACnB,IAAI,EAAE,cAAc;aACrB,CAAC,CAAC;YACH,MAAM,SAAS,GAAG,iBAAiB,CAAC,oBAAoB,CACtD,iBAAiB,EACjB,YAAY,CACb,CAAC,CAAC,CAAC,CAAC;YACL,MAAM,SAAS,GAAG,MAAM,CAAC,SAAS,CAAC,QAAQ,EAAE,CAAC,CAAC;YAE/C,MAAM,MAAM,GAAG,kBAAkB,CAAC,SAAS,EAAE,gBAAgB,CAAC,CAAC;YAC/D,OAAO,EAAE,MAAM,EAAE,CAAC;QACpB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,KAAK,YAAY,KAAK;gBAC1B,CAAC,CAAC,KAAK;gBACP,CAAC,CAAC,IAAI,KAAK,CAAC,sDAAsD,CAAC,CAAC;QACxE,CAAC;IACH,CAAC;CACF","sourcesContent":["import { Interface } from '@ethersproject/abi';\nimport { Web3Provider } from '@ethersproject/providers';\nimport { StaticIntervalPollingControllerOnly } from '@metamask/polling-controller';\n\nimport type { Address, AccountId, ChainId } from '../types';\nimport {\n getStakingContractAddress,\n getSupportedStakingChainIds,\n isStakingContractAssetId,\n weiToHumanReadable,\n} from '../utils';\n\nexport {\n getStakingContractAddress,\n getSupportedStakingChainIds,\n isStakingContractAssetId,\n};\n\nexport type StakedBalancePollingInput = {\n /** Chain ID (hex format, e.g. 0x1) */\n chainId: ChainId;\n /** Account ID */\n accountId: AccountId;\n /** Account address */\n accountAddress: Address;\n};\n\n/** Human-readable staked balance (e.g. \"1.5\" for 1.5 ETH). */\nexport type StakedBalance = {\n amount: string;\n};\n\n/** Result reported via the update callback. */\nexport type StakedBalanceFetchResult = {\n /** Account ID (UUID). */\n accountId: AccountId;\n /** Hex chain ID. */\n chainId: ChainId;\n /** Human-readable staked balance. */\n balance: StakedBalance;\n};\n\n/**\n * Callback type for staked balance updates.\n */\nexport type OnStakedBalanceUpdateCallback = (\n result: StakedBalanceFetchResult,\n) => void;\n\n/** Staking contract ABI: getShares(account) and convertToAssets(shares). */\nconst STAKING_CONTRACT_ABI = [\n {\n inputs: [{ internalType: 'address', name: 'account', type: 'address' }],\n name: 'getShares',\n outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }],\n stateMutability: 'view',\n type: 'function',\n },\n {\n inputs: [{ internalType: 'uint256', name: 'shares', type: 'uint256' }],\n name: 'convertToAssets',\n outputs: [{ internalType: 'uint256', name: 'assets', type: 'uint256' }],\n stateMutability: 'view',\n type: 'function',\n },\n];\n\nexport const STAKING_INTERFACE = new Interface(STAKING_CONTRACT_ABI);\n\nconst STAKING_DECIMALS = 18;\n\nexport type StakedBalanceFetcherConfig = {\n /** Polling interval in ms (default: 180s) */\n pollingInterval?: number;\n /** Returns the network provider for the given chain. Required for fetchStakedBalance. */\n getNetworkProvider?: (chainId: ChainId) => Web3Provider | undefined;\n};\n\nconst DEFAULT_STAKED_BALANCE_INTERVAL = 180_000; // 3 minutes\n\nexport class StakedBalanceFetcher extends StaticIntervalPollingControllerOnly<StakedBalancePollingInput>() {\n readonly #providerGetter?: (chainId: ChainId) => Web3Provider | undefined;\n\n #onStakedBalanceUpdate: OnStakedBalanceUpdateCallback | undefined;\n\n constructor(config?: StakedBalanceFetcherConfig) {\n super();\n this.#providerGetter = config?.getNetworkProvider;\n\n this.setIntervalLength(\n config?.pollingInterval ?? DEFAULT_STAKED_BALANCE_INTERVAL,\n );\n }\n\n /**\n * Register a callback that is invoked after every successful poll with\n * the staked balance (including zero). Zero is reported so that merged\n * updates can clear prior non-zero state.\n *\n * @param callback - The callback to invoke.\n */\n setOnStakedBalanceUpdate(callback: OnStakedBalanceUpdateCallback): void {\n this.#onStakedBalanceUpdate = callback;\n }\n\n async _executePoll(input: StakedBalancePollingInput): Promise<void> {\n let result: StakedBalance;\n try {\n result = await this.fetchStakedBalance(input);\n } catch {\n // Do not push an update on provider/RPC failure; otherwise we would\n // overwrite existing non-zero staked balances with zero in state.\n return;\n }\n\n if (this.#onStakedBalanceUpdate) {\n this.#onStakedBalanceUpdate({\n accountId: input.accountId,\n chainId: input.chainId,\n balance: result,\n });\n }\n }\n\n /**\n * Fetches the staked balance for an account on a chain using the same\n * staking contract as AccountTrackerController (getShares then convertToAssets).\n * Returns a human-readable amount string (e.g. \"1.5\" for 1.5 ETH).\n * Throws when no provider is available or when the RPC/contract call fails, so\n * callers do not persist a false zero and overwrite existing balances.\n *\n * @param input - Chain, account ID, and address to query.\n * @returns Human-readable staked balance (amount string).\n * @throws When provider is missing or when getShares/convertToAssets fails.\n */\n async fetchStakedBalance(\n input: StakedBalancePollingInput,\n ): Promise<StakedBalance> {\n const { chainId, accountAddress } = input;\n const provider = this.#providerGetter?.(chainId);\n if (!provider) {\n throw new Error('StakedBalanceFetcher: no provider available for chain');\n }\n const contractAddress = getStakingContractAddress(chainId);\n\n if (!contractAddress) {\n return { amount: '0' };\n }\n\n try {\n const sharesCalldata = STAKING_INTERFACE.encodeFunctionData('getShares', [\n accountAddress,\n ]);\n const sharesResult = await provider.call({\n to: contractAddress,\n data: sharesCalldata,\n });\n const sharesRaw = STAKING_INTERFACE.decodeFunctionResult(\n 'getShares',\n sharesResult,\n )[0];\n const sharesBigNum = BigInt(sharesRaw.toString());\n\n if (sharesBigNum === 0n) {\n return { amount: '0' };\n }\n\n const assetsCalldata = STAKING_INTERFACE.encodeFunctionData(\n 'convertToAssets',\n [sharesBigNum],\n );\n const assetsResult = await provider.call({\n to: contractAddress,\n data: assetsCalldata,\n });\n const assetsRaw = STAKING_INTERFACE.decodeFunctionResult(\n 'convertToAssets',\n assetsResult,\n )[0];\n const assetsWei = BigInt(assetsRaw.toString());\n\n const amount = weiToHumanReadable(assetsWei, STAKING_DECIMALS);\n return { amount };\n } catch (error) {\n throw error instanceof Error\n ? error\n : new Error('StakedBalanceFetcher: failed to fetch staked balance');\n }\n }\n}\n"]}
|
package/package.json
CHANGED