@metamask-previews/earn-controller 0.3.0-preview-ea165590 → 0.4.0-preview-52c28555

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 CHANGED
@@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.4.0]
11
+
12
+ ### Added
13
+
14
+ - Add resetCache arg to `refreshPooledStakingData` and `refreshPooledStakes` in EarnController ([#5334](https://github.com/MetaMask/core/pull/5334))
15
+
10
16
  ## [0.3.0]
11
17
 
12
18
  ### Changed
@@ -32,7 +38,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
32
38
 
33
39
  - Initial release ([#5271](https://github.com/MetaMask/core/pull/5271))
34
40
 
35
- [Unreleased]: https://github.com/MetaMask/core/compare/@metamask/earn-controller@0.3.0...HEAD
41
+ [Unreleased]: https://github.com/MetaMask/core/compare/@metamask/earn-controller@0.4.0...HEAD
42
+ [0.4.0]: https://github.com/MetaMask/core/compare/@metamask/earn-controller@0.3.0...@metamask/earn-controller@0.4.0
36
43
  [0.3.0]: https://github.com/MetaMask/core/compare/@metamask/earn-controller@0.2.1...@metamask/earn-controller@0.3.0
37
44
  [0.2.1]: https://github.com/MetaMask/core/compare/@metamask/earn-controller@0.2.0...@metamask/earn-controller@0.2.1
38
45
  [0.2.0]: https://github.com/MetaMask/core/compare/@metamask/earn-controller@0.1.0...@metamask/earn-controller@0.2.0
@@ -118,15 +118,16 @@ class EarnController extends base_controller_1.BaseController {
118
118
  * Fetches updated stake information including lifetime rewards, assets, and exit requests
119
119
  * from the staking API service and updates the state.
120
120
  *
121
+ * @param resetCache - Control whether the BE cache should be invalidated.
121
122
  * @returns A promise that resolves when the stakes data has been updated
122
123
  */
123
- async refreshPooledStakes() {
124
+ async refreshPooledStakes(resetCache = false) {
124
125
  const currentAccount = __classPrivateFieldGet(this, _EarnController_instances, "m", _EarnController_getCurrentAccount).call(this);
125
126
  if (!currentAccount?.address) {
126
127
  return;
127
128
  }
128
129
  const chainId = __classPrivateFieldGet(this, _EarnController_instances, "m", _EarnController_getCurrentChainId).call(this);
129
- const { accounts, exchangeRate } = await __classPrivateFieldGet(this, _EarnController_stakingApiService, "f").getPooledStakes([currentAccount.address], chainId);
130
+ const { accounts, exchangeRate } = await __classPrivateFieldGet(this, _EarnController_stakingApiService, "f").getPooledStakes([currentAccount.address], chainId, resetCache);
130
131
  this.update((state) => {
131
132
  state.pooled_staking.pooledStakes = accounts[0];
132
133
  state.pooled_staking.exchangeRate = exchangeRate;
@@ -169,13 +170,14 @@ class EarnController extends base_controller_1.BaseController {
169
170
  * This method allows partial success, meaning some data may update while other requests fail.
170
171
  * All errors are collected and thrown as a single error message.
171
172
  *
173
+ * @param resetCache - Control whether the BE cache should be invalidated.
172
174
  * @returns A promise that resolves when all possible data has been updated
173
175
  * @throws {Error} If any of the refresh operations fail, with concatenated error messages
174
176
  */
175
- async refreshPooledStakingData() {
177
+ async refreshPooledStakingData(resetCache = false) {
176
178
  const errors = [];
177
179
  await Promise.all([
178
- this.refreshPooledStakes().catch((error) => {
180
+ this.refreshPooledStakes(resetCache).catch((error) => {
179
181
  errors.push(error);
180
182
  }),
181
183
  this.refreshStakingEligibility().catch((error) => {
@@ -1 +1 @@
1
- {"version":3,"file":"EarnController.cjs","sourceRoot":"","sources":["../src/EarnController.ts"],"names":[],"mappings":"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","sourcesContent":["import { Web3Provider } from '@ethersproject/providers';\nimport type {\n AccountsControllerGetSelectedAccountAction,\n AccountsControllerSelectedAccountChangeEvent,\n} from '@metamask/accounts-controller';\nimport type {\n ControllerGetStateAction,\n ControllerStateChangeEvent,\n RestrictedMessenger,\n StateMetadata,\n} from '@metamask/base-controller';\nimport { BaseController } from '@metamask/base-controller';\nimport { convertHexToDecimal } from '@metamask/controller-utils';\nimport type { NetworkControllerStateChangeEvent } from '@metamask/network-controller';\nimport type {\n NetworkControllerGetNetworkClientByIdAction,\n NetworkControllerGetStateAction,\n} from '@metamask/network-controller';\nimport {\n StakeSdk,\n StakingApiService,\n type PooledStake,\n type StakeSdkConfig,\n type VaultData,\n} from '@metamask/stake-sdk';\n\nexport const controllerName = 'EarnController';\n\nexport type PooledStakingState = {\n pooledStakes: PooledStake;\n exchangeRate: string;\n vaultData: VaultData;\n isEligible: boolean;\n};\n\nexport type StablecoinLendingState = {\n vaults: StablecoinVault[];\n};\n\nexport type StablecoinVault = {\n symbol: string;\n name: string;\n chainId: number;\n tokenAddress: string;\n vaultAddress: string;\n currentAPY: string;\n supply: string;\n liquidity: string;\n};\n\n/**\n * Metadata for the EarnController.\n */\nconst earnControllerMetadata: StateMetadata<EarnControllerState> = {\n pooled_staking: {\n persist: true,\n anonymous: false,\n },\n stablecoin_lending: {\n persist: true,\n anonymous: false,\n },\n lastUpdated: {\n persist: false,\n anonymous: true,\n },\n};\n\n// === State Types ===\nexport type EarnControllerState = {\n pooled_staking: PooledStakingState;\n stablecoin_lending?: StablecoinLendingState;\n lastUpdated: number;\n};\n\n// === Default State ===\nconst DEFAULT_STABLECOIN_VAULT: StablecoinVault = {\n symbol: '',\n name: '',\n chainId: 0,\n tokenAddress: '',\n vaultAddress: '',\n currentAPY: '0',\n supply: '0',\n liquidity: '0',\n};\n\n/**\n * Gets the default state for the EarnController.\n *\n * @returns The default EarnController state.\n */\nexport function getDefaultEarnControllerState(): EarnControllerState {\n return {\n pooled_staking: {\n pooledStakes: {\n account: '',\n lifetimeRewards: '0',\n assets: '0',\n exitRequests: [],\n },\n exchangeRate: '1',\n vaultData: {\n apy: '0',\n capacity: '0',\n feePercent: 0,\n totalAssets: '0',\n vaultAddress: '0x0000000000000000000000000000000000000000',\n },\n isEligible: false,\n },\n stablecoin_lending: {\n vaults: [DEFAULT_STABLECOIN_VAULT],\n },\n lastUpdated: 0,\n };\n}\n\n// === MESSENGER ===\n\n/**\n * The action which can be used to retrieve the state of the EarnController.\n */\nexport type EarnControllerGetStateAction = ControllerGetStateAction<\n typeof controllerName,\n EarnControllerState\n>;\n\n/**\n * All actions that EarnController registers, to be called externally.\n */\nexport type EarnControllerActions = EarnControllerGetStateAction;\n\n/**\n * All actions that EarnController calls internally.\n */\nexport type AllowedActions =\n | NetworkControllerGetNetworkClientByIdAction\n | NetworkControllerGetStateAction\n | AccountsControllerGetSelectedAccountAction;\n\n/**\n * The event that EarnController publishes when updating state.\n */\nexport type EarnControllerStateChangeEvent = ControllerStateChangeEvent<\n typeof controllerName,\n EarnControllerState\n>;\n\n/**\n * All events that EarnController publishes, to be subscribed to externally.\n */\nexport type EarnControllerEvents = EarnControllerStateChangeEvent;\n\n/**\n * All events that EarnController subscribes to internally.\n */\nexport type AllowedEvents =\n | AccountsControllerSelectedAccountChangeEvent\n | NetworkControllerStateChangeEvent;\n\n/**\n * The messenger which is restricted to actions and events accessed by\n * EarnController.\n */\nexport type EarnControllerMessenger = RestrictedMessenger<\n typeof controllerName,\n EarnControllerActions | AllowedActions,\n EarnControllerEvents | AllowedEvents,\n AllowedActions['type'],\n AllowedEvents['type']\n>;\n\n// === CONTROLLER DEFINITION ===\n\n/**\n * EarnController manages DeFi earning opportunities across different protocols and chains.\n */\nexport class EarnController extends BaseController<\n typeof controllerName,\n EarnControllerState,\n EarnControllerMessenger\n> {\n #stakeSDK: StakeSdk | null = null;\n\n #selectedNetworkClientId?: string;\n\n readonly #stakingApiService: StakingApiService = new StakingApiService();\n\n constructor({\n messenger,\n state = {},\n }: {\n messenger: EarnControllerMessenger;\n state?: Partial<EarnControllerState>;\n }) {\n super({\n name: controllerName,\n metadata: earnControllerMetadata,\n messenger,\n state: {\n ...getDefaultEarnControllerState(),\n ...state,\n },\n });\n\n this.#initializeSDK();\n this.refreshPooledStakingData().catch(console.error);\n\n const { selectedNetworkClientId } = this.messagingSystem.call(\n 'NetworkController:getState',\n );\n this.#selectedNetworkClientId = selectedNetworkClientId;\n\n this.messagingSystem.subscribe(\n 'NetworkController:stateChange',\n (networkControllerState) => {\n if (\n networkControllerState.selectedNetworkClientId !==\n this.#selectedNetworkClientId\n ) {\n this.#initializeSDK(networkControllerState.selectedNetworkClientId);\n this.refreshPooledStakingData().catch(console.error);\n }\n this.#selectedNetworkClientId =\n networkControllerState.selectedNetworkClientId;\n },\n );\n\n // Listen for account changes\n this.messagingSystem.subscribe(\n 'AccountsController:selectedAccountChange',\n () => {\n this.refreshPooledStakingData().catch(console.error);\n },\n );\n }\n\n #initializeSDK(networkClientId?: string) {\n const { selectedNetworkClientId } = networkClientId\n ? { selectedNetworkClientId: networkClientId }\n : this.messagingSystem.call('NetworkController:getState');\n\n const networkClient = this.messagingSystem.call(\n 'NetworkController:getNetworkClientById',\n selectedNetworkClientId,\n );\n\n if (!networkClient?.provider) {\n this.#stakeSDK = null;\n return;\n }\n\n const provider = new Web3Provider(networkClient.provider);\n const { chainId } = networkClient.configuration;\n\n // Initialize appropriate contracts based on chainId\n const config: StakeSdkConfig = {\n chainId: convertHexToDecimal(chainId),\n };\n\n try {\n this.#stakeSDK = StakeSdk.create(config);\n this.#stakeSDK.pooledStakingContract.connectSignerOrProvider(provider);\n } catch (error) {\n this.#stakeSDK = null;\n // Only log unexpected errors, not unsupported chain errors\n if (\n !(\n error instanceof Error &&\n error.message.includes('Unsupported chainId')\n )\n ) {\n console.error('Stake SDK initialization failed:', error);\n }\n }\n }\n\n #getCurrentAccount() {\n return this.messagingSystem.call('AccountsController:getSelectedAccount');\n }\n\n #getCurrentChainId(): number {\n const { selectedNetworkClientId } = this.messagingSystem.call(\n 'NetworkController:getState',\n );\n const {\n configuration: { chainId },\n } = this.messagingSystem.call(\n 'NetworkController:getNetworkClientById',\n selectedNetworkClientId,\n );\n return convertHexToDecimal(chainId);\n }\n\n /**\n * Refreshes the pooled stakes data for the current account.\n * Fetches updated stake information including lifetime rewards, assets, and exit requests\n * from the staking API service and updates the state.\n *\n * @returns A promise that resolves when the stakes data has been updated\n */\n async refreshPooledStakes(): Promise<void> {\n const currentAccount = this.#getCurrentAccount();\n if (!currentAccount?.address) {\n return;\n }\n\n const chainId = this.#getCurrentChainId();\n\n const { accounts, exchangeRate } =\n await this.#stakingApiService.getPooledStakes(\n [currentAccount.address],\n chainId,\n );\n\n this.update((state) => {\n state.pooled_staking.pooledStakes = accounts[0];\n state.pooled_staking.exchangeRate = exchangeRate;\n });\n }\n\n /**\n * Refreshes the staking eligibility status for the current account.\n * Updates the eligibility status in the controller state based on the location and address blocklist for compliance.\n *\n * @returns A promise that resolves when the eligibility status has been updated\n */\n async refreshStakingEligibility(): Promise<void> {\n const currentAccount = this.#getCurrentAccount();\n if (!currentAccount?.address) {\n return;\n }\n\n const { eligible: isEligible } =\n await this.#stakingApiService.getPooledStakingEligibility([\n currentAccount.address,\n ]);\n\n this.update((state) => {\n state.pooled_staking.isEligible = isEligible;\n });\n }\n\n /**\n * Refreshes vault data for the current chain.\n * Updates the vault data in the controller state including APY, capacity,\n * fee percentage, total assets, and vault address.\n *\n * @returns A promise that resolves when the vault data has been updated\n */\n async refreshVaultData(): Promise<void> {\n const chainId = this.#getCurrentChainId();\n const vaultData = await this.#stakingApiService.getVaultData(chainId);\n\n this.update((state) => {\n state.pooled_staking.vaultData = vaultData;\n });\n }\n\n /**\n * Refreshes all pooled staking related data including stakes, eligibility, and vault data.\n * This method allows partial success, meaning some data may update while other requests fail.\n * All errors are collected and thrown as a single error message.\n *\n * @returns A promise that resolves when all possible data has been updated\n * @throws {Error} If any of the refresh operations fail, with concatenated error messages\n */\n async refreshPooledStakingData(): Promise<void> {\n const errors: Error[] = [];\n\n await Promise.all([\n this.refreshPooledStakes().catch((error) => {\n errors.push(error);\n }),\n this.refreshStakingEligibility().catch((error) => {\n errors.push(error);\n }),\n this.refreshVaultData().catch((error) => {\n errors.push(error);\n }),\n ]);\n\n if (errors.length > 0) {\n throw new Error(\n `Failed to refresh some staking data: ${errors\n .map((e) => e.message)\n .join(', ')}`,\n );\n }\n }\n}\n"]}
1
+ {"version":3,"file":"EarnController.cjs","sourceRoot":"","sources":["../src/EarnController.ts"],"names":[],"mappings":"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","sourcesContent":["import { Web3Provider } from '@ethersproject/providers';\nimport type {\n AccountsControllerGetSelectedAccountAction,\n AccountsControllerSelectedAccountChangeEvent,\n} from '@metamask/accounts-controller';\nimport type {\n ControllerGetStateAction,\n ControllerStateChangeEvent,\n RestrictedMessenger,\n StateMetadata,\n} from '@metamask/base-controller';\nimport { BaseController } from '@metamask/base-controller';\nimport { convertHexToDecimal } from '@metamask/controller-utils';\nimport type {\n NetworkControllerGetNetworkClientByIdAction,\n NetworkControllerGetStateAction,\n NetworkControllerStateChangeEvent,\n} from '@metamask/network-controller';\nimport {\n StakeSdk,\n StakingApiService,\n type PooledStake,\n type StakeSdkConfig,\n type VaultData,\n} from '@metamask/stake-sdk';\n\nexport const controllerName = 'EarnController';\n\nexport type PooledStakingState = {\n pooledStakes: PooledStake;\n exchangeRate: string;\n vaultData: VaultData;\n isEligible: boolean;\n};\n\nexport type StablecoinLendingState = {\n vaults: StablecoinVault[];\n};\n\nexport type StablecoinVault = {\n symbol: string;\n name: string;\n chainId: number;\n tokenAddress: string;\n vaultAddress: string;\n currentAPY: string;\n supply: string;\n liquidity: string;\n};\n\n/**\n * Metadata for the EarnController.\n */\nconst earnControllerMetadata: StateMetadata<EarnControllerState> = {\n pooled_staking: {\n persist: true,\n anonymous: false,\n },\n stablecoin_lending: {\n persist: true,\n anonymous: false,\n },\n lastUpdated: {\n persist: false,\n anonymous: true,\n },\n};\n\n// === State Types ===\nexport type EarnControllerState = {\n pooled_staking: PooledStakingState;\n stablecoin_lending?: StablecoinLendingState;\n lastUpdated: number;\n};\n\n// === Default State ===\nconst DEFAULT_STABLECOIN_VAULT: StablecoinVault = {\n symbol: '',\n name: '',\n chainId: 0,\n tokenAddress: '',\n vaultAddress: '',\n currentAPY: '0',\n supply: '0',\n liquidity: '0',\n};\n\n/**\n * Gets the default state for the EarnController.\n *\n * @returns The default EarnController state.\n */\nexport function getDefaultEarnControllerState(): EarnControllerState {\n return {\n pooled_staking: {\n pooledStakes: {\n account: '',\n lifetimeRewards: '0',\n assets: '0',\n exitRequests: [],\n },\n exchangeRate: '1',\n vaultData: {\n apy: '0',\n capacity: '0',\n feePercent: 0,\n totalAssets: '0',\n vaultAddress: '0x0000000000000000000000000000000000000000',\n },\n isEligible: false,\n },\n stablecoin_lending: {\n vaults: [DEFAULT_STABLECOIN_VAULT],\n },\n lastUpdated: 0,\n };\n}\n\n// === MESSENGER ===\n\n/**\n * The action which can be used to retrieve the state of the EarnController.\n */\nexport type EarnControllerGetStateAction = ControllerGetStateAction<\n typeof controllerName,\n EarnControllerState\n>;\n\n/**\n * All actions that EarnController registers, to be called externally.\n */\nexport type EarnControllerActions = EarnControllerGetStateAction;\n\n/**\n * All actions that EarnController calls internally.\n */\nexport type AllowedActions =\n | NetworkControllerGetNetworkClientByIdAction\n | NetworkControllerGetStateAction\n | AccountsControllerGetSelectedAccountAction;\n\n/**\n * The event that EarnController publishes when updating state.\n */\nexport type EarnControllerStateChangeEvent = ControllerStateChangeEvent<\n typeof controllerName,\n EarnControllerState\n>;\n\n/**\n * All events that EarnController publishes, to be subscribed to externally.\n */\nexport type EarnControllerEvents = EarnControllerStateChangeEvent;\n\n/**\n * All events that EarnController subscribes to internally.\n */\nexport type AllowedEvents =\n | AccountsControllerSelectedAccountChangeEvent\n | NetworkControllerStateChangeEvent;\n\n/**\n * The messenger which is restricted to actions and events accessed by\n * EarnController.\n */\nexport type EarnControllerMessenger = RestrictedMessenger<\n typeof controllerName,\n EarnControllerActions | AllowedActions,\n EarnControllerEvents | AllowedEvents,\n AllowedActions['type'],\n AllowedEvents['type']\n>;\n\n// === CONTROLLER DEFINITION ===\n\n/**\n * EarnController manages DeFi earning opportunities across different protocols and chains.\n */\nexport class EarnController extends BaseController<\n typeof controllerName,\n EarnControllerState,\n EarnControllerMessenger\n> {\n #stakeSDK: StakeSdk | null = null;\n\n #selectedNetworkClientId?: string;\n\n readonly #stakingApiService: StakingApiService = new StakingApiService();\n\n constructor({\n messenger,\n state = {},\n }: {\n messenger: EarnControllerMessenger;\n state?: Partial<EarnControllerState>;\n }) {\n super({\n name: controllerName,\n metadata: earnControllerMetadata,\n messenger,\n state: {\n ...getDefaultEarnControllerState(),\n ...state,\n },\n });\n\n this.#initializeSDK();\n this.refreshPooledStakingData().catch(console.error);\n\n const { selectedNetworkClientId } = this.messagingSystem.call(\n 'NetworkController:getState',\n );\n this.#selectedNetworkClientId = selectedNetworkClientId;\n\n this.messagingSystem.subscribe(\n 'NetworkController:stateChange',\n (networkControllerState) => {\n if (\n networkControllerState.selectedNetworkClientId !==\n this.#selectedNetworkClientId\n ) {\n this.#initializeSDK(networkControllerState.selectedNetworkClientId);\n this.refreshPooledStakingData().catch(console.error);\n }\n this.#selectedNetworkClientId =\n networkControllerState.selectedNetworkClientId;\n },\n );\n\n // Listen for account changes\n this.messagingSystem.subscribe(\n 'AccountsController:selectedAccountChange',\n () => {\n this.refreshPooledStakingData().catch(console.error);\n },\n );\n }\n\n #initializeSDK(networkClientId?: string) {\n const { selectedNetworkClientId } = networkClientId\n ? { selectedNetworkClientId: networkClientId }\n : this.messagingSystem.call('NetworkController:getState');\n\n const networkClient = this.messagingSystem.call(\n 'NetworkController:getNetworkClientById',\n selectedNetworkClientId,\n );\n\n if (!networkClient?.provider) {\n this.#stakeSDK = null;\n return;\n }\n\n const provider = new Web3Provider(networkClient.provider);\n const { chainId } = networkClient.configuration;\n\n // Initialize appropriate contracts based on chainId\n const config: StakeSdkConfig = {\n chainId: convertHexToDecimal(chainId),\n };\n\n try {\n this.#stakeSDK = StakeSdk.create(config);\n this.#stakeSDK.pooledStakingContract.connectSignerOrProvider(provider);\n } catch (error) {\n this.#stakeSDK = null;\n // Only log unexpected errors, not unsupported chain errors\n if (\n !(\n error instanceof Error &&\n error.message.includes('Unsupported chainId')\n )\n ) {\n console.error('Stake SDK initialization failed:', error);\n }\n }\n }\n\n #getCurrentAccount() {\n return this.messagingSystem.call('AccountsController:getSelectedAccount');\n }\n\n #getCurrentChainId(): number {\n const { selectedNetworkClientId } = this.messagingSystem.call(\n 'NetworkController:getState',\n );\n const {\n configuration: { chainId },\n } = this.messagingSystem.call(\n 'NetworkController:getNetworkClientById',\n selectedNetworkClientId,\n );\n return convertHexToDecimal(chainId);\n }\n\n /**\n * Refreshes the pooled stakes data for the current account.\n * Fetches updated stake information including lifetime rewards, assets, and exit requests\n * from the staking API service and updates the state.\n *\n * @param resetCache - Control whether the BE cache should be invalidated.\n * @returns A promise that resolves when the stakes data has been updated\n */\n async refreshPooledStakes(resetCache = false): Promise<void> {\n const currentAccount = this.#getCurrentAccount();\n if (!currentAccount?.address) {\n return;\n }\n\n const chainId = this.#getCurrentChainId();\n\n const { accounts, exchangeRate } =\n await this.#stakingApiService.getPooledStakes(\n [currentAccount.address],\n chainId,\n resetCache,\n );\n\n this.update((state) => {\n state.pooled_staking.pooledStakes = accounts[0];\n state.pooled_staking.exchangeRate = exchangeRate;\n });\n }\n\n /**\n * Refreshes the staking eligibility status for the current account.\n * Updates the eligibility status in the controller state based on the location and address blocklist for compliance.\n *\n * @returns A promise that resolves when the eligibility status has been updated\n */\n async refreshStakingEligibility(): Promise<void> {\n const currentAccount = this.#getCurrentAccount();\n if (!currentAccount?.address) {\n return;\n }\n\n const { eligible: isEligible } =\n await this.#stakingApiService.getPooledStakingEligibility([\n currentAccount.address,\n ]);\n\n this.update((state) => {\n state.pooled_staking.isEligible = isEligible;\n });\n }\n\n /**\n * Refreshes vault data for the current chain.\n * Updates the vault data in the controller state including APY, capacity,\n * fee percentage, total assets, and vault address.\n *\n * @returns A promise that resolves when the vault data has been updated\n */\n async refreshVaultData(): Promise<void> {\n const chainId = this.#getCurrentChainId();\n const vaultData = await this.#stakingApiService.getVaultData(chainId);\n\n this.update((state) => {\n state.pooled_staking.vaultData = vaultData;\n });\n }\n\n /**\n * Refreshes all pooled staking related data including stakes, eligibility, and vault data.\n * This method allows partial success, meaning some data may update while other requests fail.\n * All errors are collected and thrown as a single error message.\n *\n * @param resetCache - Control whether the BE cache should be invalidated.\n * @returns A promise that resolves when all possible data has been updated\n * @throws {Error} If any of the refresh operations fail, with concatenated error messages\n */\n async refreshPooledStakingData(resetCache = false): Promise<void> {\n const errors: Error[] = [];\n\n await Promise.all([\n this.refreshPooledStakes(resetCache).catch((error) => {\n errors.push(error);\n }),\n this.refreshStakingEligibility().catch((error) => {\n errors.push(error);\n }),\n this.refreshVaultData().catch((error) => {\n errors.push(error);\n }),\n ]);\n\n if (errors.length > 0) {\n throw new Error(\n `Failed to refresh some staking data: ${errors\n .map((e) => e.message)\n .join(', ')}`,\n );\n }\n }\n}\n"]}
@@ -1,8 +1,7 @@
1
1
  import type { AccountsControllerGetSelectedAccountAction, AccountsControllerSelectedAccountChangeEvent } from "@metamask/accounts-controller";
2
2
  import type { ControllerGetStateAction, ControllerStateChangeEvent, RestrictedMessenger } from "@metamask/base-controller";
3
3
  import { BaseController } from "@metamask/base-controller";
4
- import type { NetworkControllerStateChangeEvent } from "@metamask/network-controller";
5
- import type { NetworkControllerGetNetworkClientByIdAction, NetworkControllerGetStateAction } from "@metamask/network-controller";
4
+ import type { NetworkControllerGetNetworkClientByIdAction, NetworkControllerGetStateAction, NetworkControllerStateChangeEvent } from "@metamask/network-controller";
6
5
  import { type PooledStake, type VaultData } from "@metamask/stake-sdk";
7
6
  export declare const controllerName = "EarnController";
8
7
  export type PooledStakingState = {
@@ -78,9 +77,10 @@ export declare class EarnController extends BaseController<typeof controllerName
78
77
  * Fetches updated stake information including lifetime rewards, assets, and exit requests
79
78
  * from the staking API service and updates the state.
80
79
  *
80
+ * @param resetCache - Control whether the BE cache should be invalidated.
81
81
  * @returns A promise that resolves when the stakes data has been updated
82
82
  */
83
- refreshPooledStakes(): Promise<void>;
83
+ refreshPooledStakes(resetCache?: boolean): Promise<void>;
84
84
  /**
85
85
  * Refreshes the staking eligibility status for the current account.
86
86
  * Updates the eligibility status in the controller state based on the location and address blocklist for compliance.
@@ -101,9 +101,10 @@ export declare class EarnController extends BaseController<typeof controllerName
101
101
  * This method allows partial success, meaning some data may update while other requests fail.
102
102
  * All errors are collected and thrown as a single error message.
103
103
  *
104
+ * @param resetCache - Control whether the BE cache should be invalidated.
104
105
  * @returns A promise that resolves when all possible data has been updated
105
106
  * @throws {Error} If any of the refresh operations fail, with concatenated error messages
106
107
  */
107
- refreshPooledStakingData(): Promise<void>;
108
+ refreshPooledStakingData(resetCache?: boolean): Promise<void>;
108
109
  }
109
110
  //# sourceMappingURL=EarnController.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"EarnController.d.cts","sourceRoot":"","sources":["../src/EarnController.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,0CAA0C,EAC1C,4CAA4C,EAC7C,sCAAsC;AACvC,OAAO,KAAK,EACV,wBAAwB,EACxB,0BAA0B,EAC1B,mBAAmB,EAEpB,kCAAkC;AACnC,OAAO,EAAE,cAAc,EAAE,kCAAkC;AAE3D,OAAO,KAAK,EAAE,iCAAiC,EAAE,qCAAqC;AACtF,OAAO,KAAK,EACV,2CAA2C,EAC3C,+BAA+B,EAChC,qCAAqC;AACtC,OAAO,EAGL,KAAK,WAAW,EAEhB,KAAK,SAAS,EACf,4BAA4B;AAE7B,eAAO,MAAM,cAAc,mBAAmB,CAAC;AAE/C,MAAM,MAAM,kBAAkB,GAAG;IAC/B,YAAY,EAAE,WAAW,CAAC;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,SAAS,CAAC;IACrB,UAAU,EAAE,OAAO,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG;IACnC,MAAM,EAAE,eAAe,EAAE,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAqBF,MAAM,MAAM,mBAAmB,GAAG;IAChC,cAAc,EAAE,kBAAkB,CAAC;IACnC,kBAAkB,CAAC,EAAE,sBAAsB,CAAC;IAC5C,WAAW,EAAE,MAAM,CAAC;CACrB,CAAC;AAcF;;;;GAIG;AACH,wBAAgB,6BAA6B,IAAI,mBAAmB,CAwBnE;AAID;;GAEG;AACH,MAAM,MAAM,4BAA4B,GAAG,wBAAwB,CACjE,OAAO,cAAc,EACrB,mBAAmB,CACpB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,qBAAqB,GAAG,4BAA4B,CAAC;AAEjE;;GAEG;AACH,MAAM,MAAM,cAAc,GACtB,2CAA2C,GAC3C,+BAA+B,GAC/B,0CAA0C,CAAC;AAE/C;;GAEG;AACH,MAAM,MAAM,8BAA8B,GAAG,0BAA0B,CACrE,OAAO,cAAc,EACrB,mBAAmB,CACpB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,oBAAoB,GAAG,8BAA8B,CAAC;AAElE;;GAEG;AACH,MAAM,MAAM,aAAa,GACrB,4CAA4C,GAC5C,iCAAiC,CAAC;AAEtC;;;GAGG;AACH,MAAM,MAAM,uBAAuB,GAAG,mBAAmB,CACvD,OAAO,cAAc,EACrB,qBAAqB,GAAG,cAAc,EACtC,oBAAoB,GAAG,aAAa,EACpC,cAAc,CAAC,MAAM,CAAC,EACtB,aAAa,CAAC,MAAM,CAAC,CACtB,CAAC;AAIF;;GAEG;AACH,qBAAa,cAAe,SAAQ,cAAc,CAChD,OAAO,cAAc,EACrB,mBAAmB,EACnB,uBAAuB,CACxB;;gBAOa,EACV,SAAS,EACT,KAAU,GACX,EAAE;QACD,SAAS,EAAE,uBAAuB,CAAC;QACnC,KAAK,CAAC,EAAE,OAAO,CAAC,mBAAmB,CAAC,CAAC;KACtC;IAoGD;;;;;;OAMG;IACG,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC;IAoB1C;;;;;OAKG;IACG,yBAAyB,IAAI,OAAO,CAAC,IAAI,CAAC;IAgBhD;;;;;;OAMG;IACG,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC;IASvC;;;;;;;OAOG;IACG,wBAAwB,IAAI,OAAO,CAAC,IAAI,CAAC;CAuBhD"}
1
+ {"version":3,"file":"EarnController.d.cts","sourceRoot":"","sources":["../src/EarnController.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,0CAA0C,EAC1C,4CAA4C,EAC7C,sCAAsC;AACvC,OAAO,KAAK,EACV,wBAAwB,EACxB,0BAA0B,EAC1B,mBAAmB,EAEpB,kCAAkC;AACnC,OAAO,EAAE,cAAc,EAAE,kCAAkC;AAE3D,OAAO,KAAK,EACV,2CAA2C,EAC3C,+BAA+B,EAC/B,iCAAiC,EAClC,qCAAqC;AACtC,OAAO,EAGL,KAAK,WAAW,EAEhB,KAAK,SAAS,EACf,4BAA4B;AAE7B,eAAO,MAAM,cAAc,mBAAmB,CAAC;AAE/C,MAAM,MAAM,kBAAkB,GAAG;IAC/B,YAAY,EAAE,WAAW,CAAC;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,SAAS,CAAC;IACrB,UAAU,EAAE,OAAO,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG;IACnC,MAAM,EAAE,eAAe,EAAE,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAqBF,MAAM,MAAM,mBAAmB,GAAG;IAChC,cAAc,EAAE,kBAAkB,CAAC;IACnC,kBAAkB,CAAC,EAAE,sBAAsB,CAAC;IAC5C,WAAW,EAAE,MAAM,CAAC;CACrB,CAAC;AAcF;;;;GAIG;AACH,wBAAgB,6BAA6B,IAAI,mBAAmB,CAwBnE;AAID;;GAEG;AACH,MAAM,MAAM,4BAA4B,GAAG,wBAAwB,CACjE,OAAO,cAAc,EACrB,mBAAmB,CACpB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,qBAAqB,GAAG,4BAA4B,CAAC;AAEjE;;GAEG;AACH,MAAM,MAAM,cAAc,GACtB,2CAA2C,GAC3C,+BAA+B,GAC/B,0CAA0C,CAAC;AAE/C;;GAEG;AACH,MAAM,MAAM,8BAA8B,GAAG,0BAA0B,CACrE,OAAO,cAAc,EACrB,mBAAmB,CACpB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,oBAAoB,GAAG,8BAA8B,CAAC;AAElE;;GAEG;AACH,MAAM,MAAM,aAAa,GACrB,4CAA4C,GAC5C,iCAAiC,CAAC;AAEtC;;;GAGG;AACH,MAAM,MAAM,uBAAuB,GAAG,mBAAmB,CACvD,OAAO,cAAc,EACrB,qBAAqB,GAAG,cAAc,EACtC,oBAAoB,GAAG,aAAa,EACpC,cAAc,CAAC,MAAM,CAAC,EACtB,aAAa,CAAC,MAAM,CAAC,CACtB,CAAC;AAIF;;GAEG;AACH,qBAAa,cAAe,SAAQ,cAAc,CAChD,OAAO,cAAc,EACrB,mBAAmB,EACnB,uBAAuB,CACxB;;gBAOa,EACV,SAAS,EACT,KAAU,GACX,EAAE;QACD,SAAS,EAAE,uBAAuB,CAAC;QACnC,KAAK,CAAC,EAAE,OAAO,CAAC,mBAAmB,CAAC,CAAC;KACtC;IAoGD;;;;;;;OAOG;IACG,mBAAmB,CAAC,UAAU,UAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAqB5D;;;;;OAKG;IACG,yBAAyB,IAAI,OAAO,CAAC,IAAI,CAAC;IAgBhD;;;;;;OAMG;IACG,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC;IASvC;;;;;;;;OAQG;IACG,wBAAwB,CAAC,UAAU,UAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;CAuBlE"}
@@ -1,8 +1,7 @@
1
1
  import type { AccountsControllerGetSelectedAccountAction, AccountsControllerSelectedAccountChangeEvent } from "@metamask/accounts-controller";
2
2
  import type { ControllerGetStateAction, ControllerStateChangeEvent, RestrictedMessenger } from "@metamask/base-controller";
3
3
  import { BaseController } from "@metamask/base-controller";
4
- import type { NetworkControllerStateChangeEvent } from "@metamask/network-controller";
5
- import type { NetworkControllerGetNetworkClientByIdAction, NetworkControllerGetStateAction } from "@metamask/network-controller";
4
+ import type { NetworkControllerGetNetworkClientByIdAction, NetworkControllerGetStateAction, NetworkControllerStateChangeEvent } from "@metamask/network-controller";
6
5
  import { type PooledStake, type VaultData } from "@metamask/stake-sdk";
7
6
  export declare const controllerName = "EarnController";
8
7
  export type PooledStakingState = {
@@ -78,9 +77,10 @@ export declare class EarnController extends BaseController<typeof controllerName
78
77
  * Fetches updated stake information including lifetime rewards, assets, and exit requests
79
78
  * from the staking API service and updates the state.
80
79
  *
80
+ * @param resetCache - Control whether the BE cache should be invalidated.
81
81
  * @returns A promise that resolves when the stakes data has been updated
82
82
  */
83
- refreshPooledStakes(): Promise<void>;
83
+ refreshPooledStakes(resetCache?: boolean): Promise<void>;
84
84
  /**
85
85
  * Refreshes the staking eligibility status for the current account.
86
86
  * Updates the eligibility status in the controller state based on the location and address blocklist for compliance.
@@ -101,9 +101,10 @@ export declare class EarnController extends BaseController<typeof controllerName
101
101
  * This method allows partial success, meaning some data may update while other requests fail.
102
102
  * All errors are collected and thrown as a single error message.
103
103
  *
104
+ * @param resetCache - Control whether the BE cache should be invalidated.
104
105
  * @returns A promise that resolves when all possible data has been updated
105
106
  * @throws {Error} If any of the refresh operations fail, with concatenated error messages
106
107
  */
107
- refreshPooledStakingData(): Promise<void>;
108
+ refreshPooledStakingData(resetCache?: boolean): Promise<void>;
108
109
  }
109
110
  //# sourceMappingURL=EarnController.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"EarnController.d.mts","sourceRoot":"","sources":["../src/EarnController.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,0CAA0C,EAC1C,4CAA4C,EAC7C,sCAAsC;AACvC,OAAO,KAAK,EACV,wBAAwB,EACxB,0BAA0B,EAC1B,mBAAmB,EAEpB,kCAAkC;AACnC,OAAO,EAAE,cAAc,EAAE,kCAAkC;AAE3D,OAAO,KAAK,EAAE,iCAAiC,EAAE,qCAAqC;AACtF,OAAO,KAAK,EACV,2CAA2C,EAC3C,+BAA+B,EAChC,qCAAqC;AACtC,OAAO,EAGL,KAAK,WAAW,EAEhB,KAAK,SAAS,EACf,4BAA4B;AAE7B,eAAO,MAAM,cAAc,mBAAmB,CAAC;AAE/C,MAAM,MAAM,kBAAkB,GAAG;IAC/B,YAAY,EAAE,WAAW,CAAC;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,SAAS,CAAC;IACrB,UAAU,EAAE,OAAO,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG;IACnC,MAAM,EAAE,eAAe,EAAE,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAqBF,MAAM,MAAM,mBAAmB,GAAG;IAChC,cAAc,EAAE,kBAAkB,CAAC;IACnC,kBAAkB,CAAC,EAAE,sBAAsB,CAAC;IAC5C,WAAW,EAAE,MAAM,CAAC;CACrB,CAAC;AAcF;;;;GAIG;AACH,wBAAgB,6BAA6B,IAAI,mBAAmB,CAwBnE;AAID;;GAEG;AACH,MAAM,MAAM,4BAA4B,GAAG,wBAAwB,CACjE,OAAO,cAAc,EACrB,mBAAmB,CACpB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,qBAAqB,GAAG,4BAA4B,CAAC;AAEjE;;GAEG;AACH,MAAM,MAAM,cAAc,GACtB,2CAA2C,GAC3C,+BAA+B,GAC/B,0CAA0C,CAAC;AAE/C;;GAEG;AACH,MAAM,MAAM,8BAA8B,GAAG,0BAA0B,CACrE,OAAO,cAAc,EACrB,mBAAmB,CACpB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,oBAAoB,GAAG,8BAA8B,CAAC;AAElE;;GAEG;AACH,MAAM,MAAM,aAAa,GACrB,4CAA4C,GAC5C,iCAAiC,CAAC;AAEtC;;;GAGG;AACH,MAAM,MAAM,uBAAuB,GAAG,mBAAmB,CACvD,OAAO,cAAc,EACrB,qBAAqB,GAAG,cAAc,EACtC,oBAAoB,GAAG,aAAa,EACpC,cAAc,CAAC,MAAM,CAAC,EACtB,aAAa,CAAC,MAAM,CAAC,CACtB,CAAC;AAIF;;GAEG;AACH,qBAAa,cAAe,SAAQ,cAAc,CAChD,OAAO,cAAc,EACrB,mBAAmB,EACnB,uBAAuB,CACxB;;gBAOa,EACV,SAAS,EACT,KAAU,GACX,EAAE;QACD,SAAS,EAAE,uBAAuB,CAAC;QACnC,KAAK,CAAC,EAAE,OAAO,CAAC,mBAAmB,CAAC,CAAC;KACtC;IAoGD;;;;;;OAMG;IACG,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC;IAoB1C;;;;;OAKG;IACG,yBAAyB,IAAI,OAAO,CAAC,IAAI,CAAC;IAgBhD;;;;;;OAMG;IACG,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC;IASvC;;;;;;;OAOG;IACG,wBAAwB,IAAI,OAAO,CAAC,IAAI,CAAC;CAuBhD"}
1
+ {"version":3,"file":"EarnController.d.mts","sourceRoot":"","sources":["../src/EarnController.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,0CAA0C,EAC1C,4CAA4C,EAC7C,sCAAsC;AACvC,OAAO,KAAK,EACV,wBAAwB,EACxB,0BAA0B,EAC1B,mBAAmB,EAEpB,kCAAkC;AACnC,OAAO,EAAE,cAAc,EAAE,kCAAkC;AAE3D,OAAO,KAAK,EACV,2CAA2C,EAC3C,+BAA+B,EAC/B,iCAAiC,EAClC,qCAAqC;AACtC,OAAO,EAGL,KAAK,WAAW,EAEhB,KAAK,SAAS,EACf,4BAA4B;AAE7B,eAAO,MAAM,cAAc,mBAAmB,CAAC;AAE/C,MAAM,MAAM,kBAAkB,GAAG;IAC/B,YAAY,EAAE,WAAW,CAAC;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,SAAS,CAAC;IACrB,UAAU,EAAE,OAAO,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG;IACnC,MAAM,EAAE,eAAe,EAAE,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAqBF,MAAM,MAAM,mBAAmB,GAAG;IAChC,cAAc,EAAE,kBAAkB,CAAC;IACnC,kBAAkB,CAAC,EAAE,sBAAsB,CAAC;IAC5C,WAAW,EAAE,MAAM,CAAC;CACrB,CAAC;AAcF;;;;GAIG;AACH,wBAAgB,6BAA6B,IAAI,mBAAmB,CAwBnE;AAID;;GAEG;AACH,MAAM,MAAM,4BAA4B,GAAG,wBAAwB,CACjE,OAAO,cAAc,EACrB,mBAAmB,CACpB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,qBAAqB,GAAG,4BAA4B,CAAC;AAEjE;;GAEG;AACH,MAAM,MAAM,cAAc,GACtB,2CAA2C,GAC3C,+BAA+B,GAC/B,0CAA0C,CAAC;AAE/C;;GAEG;AACH,MAAM,MAAM,8BAA8B,GAAG,0BAA0B,CACrE,OAAO,cAAc,EACrB,mBAAmB,CACpB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,oBAAoB,GAAG,8BAA8B,CAAC;AAElE;;GAEG;AACH,MAAM,MAAM,aAAa,GACrB,4CAA4C,GAC5C,iCAAiC,CAAC;AAEtC;;;GAGG;AACH,MAAM,MAAM,uBAAuB,GAAG,mBAAmB,CACvD,OAAO,cAAc,EACrB,qBAAqB,GAAG,cAAc,EACtC,oBAAoB,GAAG,aAAa,EACpC,cAAc,CAAC,MAAM,CAAC,EACtB,aAAa,CAAC,MAAM,CAAC,CACtB,CAAC;AAIF;;GAEG;AACH,qBAAa,cAAe,SAAQ,cAAc,CAChD,OAAO,cAAc,EACrB,mBAAmB,EACnB,uBAAuB,CACxB;;gBAOa,EACV,SAAS,EACT,KAAU,GACX,EAAE;QACD,SAAS,EAAE,uBAAuB,CAAC;QACnC,KAAK,CAAC,EAAE,OAAO,CAAC,mBAAmB,CAAC,CAAC;KACtC;IAoGD;;;;;;;OAOG;IACG,mBAAmB,CAAC,UAAU,UAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAqB5D;;;;;OAKG;IACG,yBAAyB,IAAI,OAAO,CAAC,IAAI,CAAC;IAgBhD;;;;;;OAMG;IACG,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC;IASvC;;;;;;;;OAQG;IACG,wBAAwB,CAAC,UAAU,UAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;CAuBlE"}
@@ -114,15 +114,16 @@ export class EarnController extends BaseController {
114
114
  * Fetches updated stake information including lifetime rewards, assets, and exit requests
115
115
  * from the staking API service and updates the state.
116
116
  *
117
+ * @param resetCache - Control whether the BE cache should be invalidated.
117
118
  * @returns A promise that resolves when the stakes data has been updated
118
119
  */
119
- async refreshPooledStakes() {
120
+ async refreshPooledStakes(resetCache = false) {
120
121
  const currentAccount = __classPrivateFieldGet(this, _EarnController_instances, "m", _EarnController_getCurrentAccount).call(this);
121
122
  if (!currentAccount?.address) {
122
123
  return;
123
124
  }
124
125
  const chainId = __classPrivateFieldGet(this, _EarnController_instances, "m", _EarnController_getCurrentChainId).call(this);
125
- const { accounts, exchangeRate } = await __classPrivateFieldGet(this, _EarnController_stakingApiService, "f").getPooledStakes([currentAccount.address], chainId);
126
+ const { accounts, exchangeRate } = await __classPrivateFieldGet(this, _EarnController_stakingApiService, "f").getPooledStakes([currentAccount.address], chainId, resetCache);
126
127
  this.update((state) => {
127
128
  state.pooled_staking.pooledStakes = accounts[0];
128
129
  state.pooled_staking.exchangeRate = exchangeRate;
@@ -165,13 +166,14 @@ export class EarnController extends BaseController {
165
166
  * This method allows partial success, meaning some data may update while other requests fail.
166
167
  * All errors are collected and thrown as a single error message.
167
168
  *
169
+ * @param resetCache - Control whether the BE cache should be invalidated.
168
170
  * @returns A promise that resolves when all possible data has been updated
169
171
  * @throws {Error} If any of the refresh operations fail, with concatenated error messages
170
172
  */
171
- async refreshPooledStakingData() {
173
+ async refreshPooledStakingData(resetCache = false) {
172
174
  const errors = [];
173
175
  await Promise.all([
174
- this.refreshPooledStakes().catch((error) => {
176
+ this.refreshPooledStakes(resetCache).catch((error) => {
175
177
  errors.push(error);
176
178
  }),
177
179
  this.refreshStakingEligibility().catch((error) => {
@@ -1 +1 @@
1
- {"version":3,"file":"EarnController.mjs","sourceRoot":"","sources":["../src/EarnController.ts"],"names":[],"mappings":"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","sourcesContent":["import { Web3Provider } from '@ethersproject/providers';\nimport type {\n AccountsControllerGetSelectedAccountAction,\n AccountsControllerSelectedAccountChangeEvent,\n} from '@metamask/accounts-controller';\nimport type {\n ControllerGetStateAction,\n ControllerStateChangeEvent,\n RestrictedMessenger,\n StateMetadata,\n} from '@metamask/base-controller';\nimport { BaseController } from '@metamask/base-controller';\nimport { convertHexToDecimal } from '@metamask/controller-utils';\nimport type { NetworkControllerStateChangeEvent } from '@metamask/network-controller';\nimport type {\n NetworkControllerGetNetworkClientByIdAction,\n NetworkControllerGetStateAction,\n} from '@metamask/network-controller';\nimport {\n StakeSdk,\n StakingApiService,\n type PooledStake,\n type StakeSdkConfig,\n type VaultData,\n} from '@metamask/stake-sdk';\n\nexport const controllerName = 'EarnController';\n\nexport type PooledStakingState = {\n pooledStakes: PooledStake;\n exchangeRate: string;\n vaultData: VaultData;\n isEligible: boolean;\n};\n\nexport type StablecoinLendingState = {\n vaults: StablecoinVault[];\n};\n\nexport type StablecoinVault = {\n symbol: string;\n name: string;\n chainId: number;\n tokenAddress: string;\n vaultAddress: string;\n currentAPY: string;\n supply: string;\n liquidity: string;\n};\n\n/**\n * Metadata for the EarnController.\n */\nconst earnControllerMetadata: StateMetadata<EarnControllerState> = {\n pooled_staking: {\n persist: true,\n anonymous: false,\n },\n stablecoin_lending: {\n persist: true,\n anonymous: false,\n },\n lastUpdated: {\n persist: false,\n anonymous: true,\n },\n};\n\n// === State Types ===\nexport type EarnControllerState = {\n pooled_staking: PooledStakingState;\n stablecoin_lending?: StablecoinLendingState;\n lastUpdated: number;\n};\n\n// === Default State ===\nconst DEFAULT_STABLECOIN_VAULT: StablecoinVault = {\n symbol: '',\n name: '',\n chainId: 0,\n tokenAddress: '',\n vaultAddress: '',\n currentAPY: '0',\n supply: '0',\n liquidity: '0',\n};\n\n/**\n * Gets the default state for the EarnController.\n *\n * @returns The default EarnController state.\n */\nexport function getDefaultEarnControllerState(): EarnControllerState {\n return {\n pooled_staking: {\n pooledStakes: {\n account: '',\n lifetimeRewards: '0',\n assets: '0',\n exitRequests: [],\n },\n exchangeRate: '1',\n vaultData: {\n apy: '0',\n capacity: '0',\n feePercent: 0,\n totalAssets: '0',\n vaultAddress: '0x0000000000000000000000000000000000000000',\n },\n isEligible: false,\n },\n stablecoin_lending: {\n vaults: [DEFAULT_STABLECOIN_VAULT],\n },\n lastUpdated: 0,\n };\n}\n\n// === MESSENGER ===\n\n/**\n * The action which can be used to retrieve the state of the EarnController.\n */\nexport type EarnControllerGetStateAction = ControllerGetStateAction<\n typeof controllerName,\n EarnControllerState\n>;\n\n/**\n * All actions that EarnController registers, to be called externally.\n */\nexport type EarnControllerActions = EarnControllerGetStateAction;\n\n/**\n * All actions that EarnController calls internally.\n */\nexport type AllowedActions =\n | NetworkControllerGetNetworkClientByIdAction\n | NetworkControllerGetStateAction\n | AccountsControllerGetSelectedAccountAction;\n\n/**\n * The event that EarnController publishes when updating state.\n */\nexport type EarnControllerStateChangeEvent = ControllerStateChangeEvent<\n typeof controllerName,\n EarnControllerState\n>;\n\n/**\n * All events that EarnController publishes, to be subscribed to externally.\n */\nexport type EarnControllerEvents = EarnControllerStateChangeEvent;\n\n/**\n * All events that EarnController subscribes to internally.\n */\nexport type AllowedEvents =\n | AccountsControllerSelectedAccountChangeEvent\n | NetworkControllerStateChangeEvent;\n\n/**\n * The messenger which is restricted to actions and events accessed by\n * EarnController.\n */\nexport type EarnControllerMessenger = RestrictedMessenger<\n typeof controllerName,\n EarnControllerActions | AllowedActions,\n EarnControllerEvents | AllowedEvents,\n AllowedActions['type'],\n AllowedEvents['type']\n>;\n\n// === CONTROLLER DEFINITION ===\n\n/**\n * EarnController manages DeFi earning opportunities across different protocols and chains.\n */\nexport class EarnController extends BaseController<\n typeof controllerName,\n EarnControllerState,\n EarnControllerMessenger\n> {\n #stakeSDK: StakeSdk | null = null;\n\n #selectedNetworkClientId?: string;\n\n readonly #stakingApiService: StakingApiService = new StakingApiService();\n\n constructor({\n messenger,\n state = {},\n }: {\n messenger: EarnControllerMessenger;\n state?: Partial<EarnControllerState>;\n }) {\n super({\n name: controllerName,\n metadata: earnControllerMetadata,\n messenger,\n state: {\n ...getDefaultEarnControllerState(),\n ...state,\n },\n });\n\n this.#initializeSDK();\n this.refreshPooledStakingData().catch(console.error);\n\n const { selectedNetworkClientId } = this.messagingSystem.call(\n 'NetworkController:getState',\n );\n this.#selectedNetworkClientId = selectedNetworkClientId;\n\n this.messagingSystem.subscribe(\n 'NetworkController:stateChange',\n (networkControllerState) => {\n if (\n networkControllerState.selectedNetworkClientId !==\n this.#selectedNetworkClientId\n ) {\n this.#initializeSDK(networkControllerState.selectedNetworkClientId);\n this.refreshPooledStakingData().catch(console.error);\n }\n this.#selectedNetworkClientId =\n networkControllerState.selectedNetworkClientId;\n },\n );\n\n // Listen for account changes\n this.messagingSystem.subscribe(\n 'AccountsController:selectedAccountChange',\n () => {\n this.refreshPooledStakingData().catch(console.error);\n },\n );\n }\n\n #initializeSDK(networkClientId?: string) {\n const { selectedNetworkClientId } = networkClientId\n ? { selectedNetworkClientId: networkClientId }\n : this.messagingSystem.call('NetworkController:getState');\n\n const networkClient = this.messagingSystem.call(\n 'NetworkController:getNetworkClientById',\n selectedNetworkClientId,\n );\n\n if (!networkClient?.provider) {\n this.#stakeSDK = null;\n return;\n }\n\n const provider = new Web3Provider(networkClient.provider);\n const { chainId } = networkClient.configuration;\n\n // Initialize appropriate contracts based on chainId\n const config: StakeSdkConfig = {\n chainId: convertHexToDecimal(chainId),\n };\n\n try {\n this.#stakeSDK = StakeSdk.create(config);\n this.#stakeSDK.pooledStakingContract.connectSignerOrProvider(provider);\n } catch (error) {\n this.#stakeSDK = null;\n // Only log unexpected errors, not unsupported chain errors\n if (\n !(\n error instanceof Error &&\n error.message.includes('Unsupported chainId')\n )\n ) {\n console.error('Stake SDK initialization failed:', error);\n }\n }\n }\n\n #getCurrentAccount() {\n return this.messagingSystem.call('AccountsController:getSelectedAccount');\n }\n\n #getCurrentChainId(): number {\n const { selectedNetworkClientId } = this.messagingSystem.call(\n 'NetworkController:getState',\n );\n const {\n configuration: { chainId },\n } = this.messagingSystem.call(\n 'NetworkController:getNetworkClientById',\n selectedNetworkClientId,\n );\n return convertHexToDecimal(chainId);\n }\n\n /**\n * Refreshes the pooled stakes data for the current account.\n * Fetches updated stake information including lifetime rewards, assets, and exit requests\n * from the staking API service and updates the state.\n *\n * @returns A promise that resolves when the stakes data has been updated\n */\n async refreshPooledStakes(): Promise<void> {\n const currentAccount = this.#getCurrentAccount();\n if (!currentAccount?.address) {\n return;\n }\n\n const chainId = this.#getCurrentChainId();\n\n const { accounts, exchangeRate } =\n await this.#stakingApiService.getPooledStakes(\n [currentAccount.address],\n chainId,\n );\n\n this.update((state) => {\n state.pooled_staking.pooledStakes = accounts[0];\n state.pooled_staking.exchangeRate = exchangeRate;\n });\n }\n\n /**\n * Refreshes the staking eligibility status for the current account.\n * Updates the eligibility status in the controller state based on the location and address blocklist for compliance.\n *\n * @returns A promise that resolves when the eligibility status has been updated\n */\n async refreshStakingEligibility(): Promise<void> {\n const currentAccount = this.#getCurrentAccount();\n if (!currentAccount?.address) {\n return;\n }\n\n const { eligible: isEligible } =\n await this.#stakingApiService.getPooledStakingEligibility([\n currentAccount.address,\n ]);\n\n this.update((state) => {\n state.pooled_staking.isEligible = isEligible;\n });\n }\n\n /**\n * Refreshes vault data for the current chain.\n * Updates the vault data in the controller state including APY, capacity,\n * fee percentage, total assets, and vault address.\n *\n * @returns A promise that resolves when the vault data has been updated\n */\n async refreshVaultData(): Promise<void> {\n const chainId = this.#getCurrentChainId();\n const vaultData = await this.#stakingApiService.getVaultData(chainId);\n\n this.update((state) => {\n state.pooled_staking.vaultData = vaultData;\n });\n }\n\n /**\n * Refreshes all pooled staking related data including stakes, eligibility, and vault data.\n * This method allows partial success, meaning some data may update while other requests fail.\n * All errors are collected and thrown as a single error message.\n *\n * @returns A promise that resolves when all possible data has been updated\n * @throws {Error} If any of the refresh operations fail, with concatenated error messages\n */\n async refreshPooledStakingData(): Promise<void> {\n const errors: Error[] = [];\n\n await Promise.all([\n this.refreshPooledStakes().catch((error) => {\n errors.push(error);\n }),\n this.refreshStakingEligibility().catch((error) => {\n errors.push(error);\n }),\n this.refreshVaultData().catch((error) => {\n errors.push(error);\n }),\n ]);\n\n if (errors.length > 0) {\n throw new Error(\n `Failed to refresh some staking data: ${errors\n .map((e) => e.message)\n .join(', ')}`,\n );\n }\n }\n}\n"]}
1
+ {"version":3,"file":"EarnController.mjs","sourceRoot":"","sources":["../src/EarnController.ts"],"names":[],"mappings":"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","sourcesContent":["import { Web3Provider } from '@ethersproject/providers';\nimport type {\n AccountsControllerGetSelectedAccountAction,\n AccountsControllerSelectedAccountChangeEvent,\n} from '@metamask/accounts-controller';\nimport type {\n ControllerGetStateAction,\n ControllerStateChangeEvent,\n RestrictedMessenger,\n StateMetadata,\n} from '@metamask/base-controller';\nimport { BaseController } from '@metamask/base-controller';\nimport { convertHexToDecimal } from '@metamask/controller-utils';\nimport type {\n NetworkControllerGetNetworkClientByIdAction,\n NetworkControllerGetStateAction,\n NetworkControllerStateChangeEvent,\n} from '@metamask/network-controller';\nimport {\n StakeSdk,\n StakingApiService,\n type PooledStake,\n type StakeSdkConfig,\n type VaultData,\n} from '@metamask/stake-sdk';\n\nexport const controllerName = 'EarnController';\n\nexport type PooledStakingState = {\n pooledStakes: PooledStake;\n exchangeRate: string;\n vaultData: VaultData;\n isEligible: boolean;\n};\n\nexport type StablecoinLendingState = {\n vaults: StablecoinVault[];\n};\n\nexport type StablecoinVault = {\n symbol: string;\n name: string;\n chainId: number;\n tokenAddress: string;\n vaultAddress: string;\n currentAPY: string;\n supply: string;\n liquidity: string;\n};\n\n/**\n * Metadata for the EarnController.\n */\nconst earnControllerMetadata: StateMetadata<EarnControllerState> = {\n pooled_staking: {\n persist: true,\n anonymous: false,\n },\n stablecoin_lending: {\n persist: true,\n anonymous: false,\n },\n lastUpdated: {\n persist: false,\n anonymous: true,\n },\n};\n\n// === State Types ===\nexport type EarnControllerState = {\n pooled_staking: PooledStakingState;\n stablecoin_lending?: StablecoinLendingState;\n lastUpdated: number;\n};\n\n// === Default State ===\nconst DEFAULT_STABLECOIN_VAULT: StablecoinVault = {\n symbol: '',\n name: '',\n chainId: 0,\n tokenAddress: '',\n vaultAddress: '',\n currentAPY: '0',\n supply: '0',\n liquidity: '0',\n};\n\n/**\n * Gets the default state for the EarnController.\n *\n * @returns The default EarnController state.\n */\nexport function getDefaultEarnControllerState(): EarnControllerState {\n return {\n pooled_staking: {\n pooledStakes: {\n account: '',\n lifetimeRewards: '0',\n assets: '0',\n exitRequests: [],\n },\n exchangeRate: '1',\n vaultData: {\n apy: '0',\n capacity: '0',\n feePercent: 0,\n totalAssets: '0',\n vaultAddress: '0x0000000000000000000000000000000000000000',\n },\n isEligible: false,\n },\n stablecoin_lending: {\n vaults: [DEFAULT_STABLECOIN_VAULT],\n },\n lastUpdated: 0,\n };\n}\n\n// === MESSENGER ===\n\n/**\n * The action which can be used to retrieve the state of the EarnController.\n */\nexport type EarnControllerGetStateAction = ControllerGetStateAction<\n typeof controllerName,\n EarnControllerState\n>;\n\n/**\n * All actions that EarnController registers, to be called externally.\n */\nexport type EarnControllerActions = EarnControllerGetStateAction;\n\n/**\n * All actions that EarnController calls internally.\n */\nexport type AllowedActions =\n | NetworkControllerGetNetworkClientByIdAction\n | NetworkControllerGetStateAction\n | AccountsControllerGetSelectedAccountAction;\n\n/**\n * The event that EarnController publishes when updating state.\n */\nexport type EarnControllerStateChangeEvent = ControllerStateChangeEvent<\n typeof controllerName,\n EarnControllerState\n>;\n\n/**\n * All events that EarnController publishes, to be subscribed to externally.\n */\nexport type EarnControllerEvents = EarnControllerStateChangeEvent;\n\n/**\n * All events that EarnController subscribes to internally.\n */\nexport type AllowedEvents =\n | AccountsControllerSelectedAccountChangeEvent\n | NetworkControllerStateChangeEvent;\n\n/**\n * The messenger which is restricted to actions and events accessed by\n * EarnController.\n */\nexport type EarnControllerMessenger = RestrictedMessenger<\n typeof controllerName,\n EarnControllerActions | AllowedActions,\n EarnControllerEvents | AllowedEvents,\n AllowedActions['type'],\n AllowedEvents['type']\n>;\n\n// === CONTROLLER DEFINITION ===\n\n/**\n * EarnController manages DeFi earning opportunities across different protocols and chains.\n */\nexport class EarnController extends BaseController<\n typeof controllerName,\n EarnControllerState,\n EarnControllerMessenger\n> {\n #stakeSDK: StakeSdk | null = null;\n\n #selectedNetworkClientId?: string;\n\n readonly #stakingApiService: StakingApiService = new StakingApiService();\n\n constructor({\n messenger,\n state = {},\n }: {\n messenger: EarnControllerMessenger;\n state?: Partial<EarnControllerState>;\n }) {\n super({\n name: controllerName,\n metadata: earnControllerMetadata,\n messenger,\n state: {\n ...getDefaultEarnControllerState(),\n ...state,\n },\n });\n\n this.#initializeSDK();\n this.refreshPooledStakingData().catch(console.error);\n\n const { selectedNetworkClientId } = this.messagingSystem.call(\n 'NetworkController:getState',\n );\n this.#selectedNetworkClientId = selectedNetworkClientId;\n\n this.messagingSystem.subscribe(\n 'NetworkController:stateChange',\n (networkControllerState) => {\n if (\n networkControllerState.selectedNetworkClientId !==\n this.#selectedNetworkClientId\n ) {\n this.#initializeSDK(networkControllerState.selectedNetworkClientId);\n this.refreshPooledStakingData().catch(console.error);\n }\n this.#selectedNetworkClientId =\n networkControllerState.selectedNetworkClientId;\n },\n );\n\n // Listen for account changes\n this.messagingSystem.subscribe(\n 'AccountsController:selectedAccountChange',\n () => {\n this.refreshPooledStakingData().catch(console.error);\n },\n );\n }\n\n #initializeSDK(networkClientId?: string) {\n const { selectedNetworkClientId } = networkClientId\n ? { selectedNetworkClientId: networkClientId }\n : this.messagingSystem.call('NetworkController:getState');\n\n const networkClient = this.messagingSystem.call(\n 'NetworkController:getNetworkClientById',\n selectedNetworkClientId,\n );\n\n if (!networkClient?.provider) {\n this.#stakeSDK = null;\n return;\n }\n\n const provider = new Web3Provider(networkClient.provider);\n const { chainId } = networkClient.configuration;\n\n // Initialize appropriate contracts based on chainId\n const config: StakeSdkConfig = {\n chainId: convertHexToDecimal(chainId),\n };\n\n try {\n this.#stakeSDK = StakeSdk.create(config);\n this.#stakeSDK.pooledStakingContract.connectSignerOrProvider(provider);\n } catch (error) {\n this.#stakeSDK = null;\n // Only log unexpected errors, not unsupported chain errors\n if (\n !(\n error instanceof Error &&\n error.message.includes('Unsupported chainId')\n )\n ) {\n console.error('Stake SDK initialization failed:', error);\n }\n }\n }\n\n #getCurrentAccount() {\n return this.messagingSystem.call('AccountsController:getSelectedAccount');\n }\n\n #getCurrentChainId(): number {\n const { selectedNetworkClientId } = this.messagingSystem.call(\n 'NetworkController:getState',\n );\n const {\n configuration: { chainId },\n } = this.messagingSystem.call(\n 'NetworkController:getNetworkClientById',\n selectedNetworkClientId,\n );\n return convertHexToDecimal(chainId);\n }\n\n /**\n * Refreshes the pooled stakes data for the current account.\n * Fetches updated stake information including lifetime rewards, assets, and exit requests\n * from the staking API service and updates the state.\n *\n * @param resetCache - Control whether the BE cache should be invalidated.\n * @returns A promise that resolves when the stakes data has been updated\n */\n async refreshPooledStakes(resetCache = false): Promise<void> {\n const currentAccount = this.#getCurrentAccount();\n if (!currentAccount?.address) {\n return;\n }\n\n const chainId = this.#getCurrentChainId();\n\n const { accounts, exchangeRate } =\n await this.#stakingApiService.getPooledStakes(\n [currentAccount.address],\n chainId,\n resetCache,\n );\n\n this.update((state) => {\n state.pooled_staking.pooledStakes = accounts[0];\n state.pooled_staking.exchangeRate = exchangeRate;\n });\n }\n\n /**\n * Refreshes the staking eligibility status for the current account.\n * Updates the eligibility status in the controller state based on the location and address blocklist for compliance.\n *\n * @returns A promise that resolves when the eligibility status has been updated\n */\n async refreshStakingEligibility(): Promise<void> {\n const currentAccount = this.#getCurrentAccount();\n if (!currentAccount?.address) {\n return;\n }\n\n const { eligible: isEligible } =\n await this.#stakingApiService.getPooledStakingEligibility([\n currentAccount.address,\n ]);\n\n this.update((state) => {\n state.pooled_staking.isEligible = isEligible;\n });\n }\n\n /**\n * Refreshes vault data for the current chain.\n * Updates the vault data in the controller state including APY, capacity,\n * fee percentage, total assets, and vault address.\n *\n * @returns A promise that resolves when the vault data has been updated\n */\n async refreshVaultData(): Promise<void> {\n const chainId = this.#getCurrentChainId();\n const vaultData = await this.#stakingApiService.getVaultData(chainId);\n\n this.update((state) => {\n state.pooled_staking.vaultData = vaultData;\n });\n }\n\n /**\n * Refreshes all pooled staking related data including stakes, eligibility, and vault data.\n * This method allows partial success, meaning some data may update while other requests fail.\n * All errors are collected and thrown as a single error message.\n *\n * @param resetCache - Control whether the BE cache should be invalidated.\n * @returns A promise that resolves when all possible data has been updated\n * @throws {Error} If any of the refresh operations fail, with concatenated error messages\n */\n async refreshPooledStakingData(resetCache = false): Promise<void> {\n const errors: Error[] = [];\n\n await Promise.all([\n this.refreshPooledStakes(resetCache).catch((error) => {\n errors.push(error);\n }),\n this.refreshStakingEligibility().catch((error) => {\n errors.push(error);\n }),\n this.refreshVaultData().catch((error) => {\n errors.push(error);\n }),\n ]);\n\n if (errors.length > 0) {\n throw new Error(\n `Failed to refresh some staking data: ${errors\n .map((e) => e.message)\n .join(', ')}`,\n );\n }\n }\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@metamask-previews/earn-controller",
3
- "version": "0.3.0-preview-ea165590",
3
+ "version": "0.4.0-preview-52c28555",
4
4
  "description": "Manages state for earning features and coordinates interactions between staking services, SDK integrations, and other controllers to enable users to participate in various earning opportunities",
5
5
  "keywords": [
6
6
  "MetaMask",