Skip to content

Commit 7f43ba2

Browse files
authored
feat: Add new metadata to EarnController (#6555)
## Explanation The new metadata properties `includeInStateLogs` and `usedInUi` have been added to the `EarnController`. ## References Fixes #6517 ## Checklist - [x] I've updated the test suite for new or updated code as appropriate - [x] I've updated documentation (JSDoc, Markdown, etc.) for new or updated code as appropriate - [x] I've communicated my changes to consumers by [updating changelogs for packages I've changed](https://github.com/MetaMask/core/tree/main/docs/contributing.md#updating-changelogs), highlighting breaking changes as necessary - [x] I've prepared draft pull requests for clients and consumer packages to resolve any breaking changes
1 parent b32613a commit 7f43ba2

File tree

3 files changed

+300
-1
lines changed

3 files changed

+300
-1
lines changed

packages/earn-controller/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
### Added
11+
12+
- Add two new controller state metadata properties: `includeInStateLogs` and `usedInUi` ([#6555](https://github.com/MetaMask/core/pull/6555))
13+
1014
### Changed
1115

1216
- Bump `@metamask/controller-utils` from `^11.12.0` to `^11.14.0` ([#6620](https://github.com/MetaMask/core/pull/6620), [#6629](https://github.com/MetaMask/core/pull/6629))

packages/earn-controller/src/EarnController.test.ts

Lines changed: 290 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/* eslint-disable jest/no-conditional-in-test */
2-
import { Messenger } from '@metamask/base-controller';
2+
import { Messenger, deriveStateFromMetadata } from '@metamask/base-controller';
33
import { toHex } from '@metamask/controller-utils';
44
import type { InternalAccount } from '@metamask/keyring-internal-api';
55
import { getDefaultNetworkControllerState } from '@metamask/network-controller';
@@ -2566,4 +2566,293 @@ describe('EarnController', () => {
25662566
});
25672567
});
25682568
});
2569+
2570+
describe('metadata', () => {
2571+
it('includes expected state in debug snapshots', async () => {
2572+
const { controller } = await setupController();
2573+
2574+
expect(
2575+
deriveStateFromMetadata(
2576+
controller.state,
2577+
controller.metadata,
2578+
'anonymous',
2579+
),
2580+
).toMatchInlineSnapshot(`
2581+
Object {
2582+
"lastUpdated": 0,
2583+
}
2584+
`);
2585+
});
2586+
2587+
it('includes expected state in state logs', async () => {
2588+
const { controller } = await setupController();
2589+
2590+
const derivedState = deriveStateFromMetadata(
2591+
controller.state,
2592+
controller.metadata,
2593+
'includeInStateLogs',
2594+
);
2595+
2596+
// Compare `pooled_staking` separately to minimize size of snapshot
2597+
const {
2598+
pooled_staking: derivedPooledStaking,
2599+
...derivedStateWithoutPooledStaking
2600+
} = derivedState;
2601+
expect(derivedPooledStaking).toStrictEqual({
2602+
'1': {
2603+
pooledStakes: mockPooledStakes,
2604+
exchangeRate: '1.5',
2605+
vaultMetadata: mockVaultMetadata,
2606+
vaultDailyApys: mockPooledStakingVaultDailyApys,
2607+
vaultApyAverages: mockPooledStakingVaultApyAverages,
2608+
},
2609+
'560048': {
2610+
pooledStakes: mockPooledStakes,
2611+
exchangeRate: '1.5',
2612+
vaultMetadata: mockVaultMetadata,
2613+
vaultDailyApys: mockPooledStakingVaultDailyApys,
2614+
vaultApyAverages: mockPooledStakingVaultApyAverages,
2615+
},
2616+
isEligible: true,
2617+
});
2618+
expect(derivedStateWithoutPooledStaking).toMatchInlineSnapshot(`
2619+
Object {
2620+
"lastUpdated": 0,
2621+
"lending": Object {
2622+
"isEligible": true,
2623+
"markets": Array [
2624+
Object {
2625+
"address": "0xe50fa9b3c56ffb159cb0fca61f5c9d750e8128c8",
2626+
"chainId": 42161,
2627+
"id": "0xe50fa9b3c56ffb159cb0fca61f5c9d750e8128c8",
2628+
"name": "0xe50fa9b3c56ffb159cb0fca61f5c9d750e8128c8",
2629+
"netSupplyRate": 1.52269127978874,
2630+
"outputToken": Object {
2631+
"address": "0xe50fa9b3c56ffb159cb0fca61f5c9d750e8128c8",
2632+
"chainId": 42161,
2633+
},
2634+
"protocol": "aave",
2635+
"rewards": Array [],
2636+
"totalSupplyRate": 1.52269127978874,
2637+
"tvlUnderlying": "132942564710249273623333",
2638+
"underlying": Object {
2639+
"address": "0x82af49447d8a07e3bd95bd0d56f35241523fbab1",
2640+
"chainId": 42161,
2641+
},
2642+
},
2643+
],
2644+
"positions": Array [
2645+
Object {
2646+
"assets": "112",
2647+
"chainId": 42161,
2648+
"id": "0xe6a7d2b7de29167ae4c3864ac0873e6dcd9cb47b-0x078f358208685046a11c85e8ad32895ded33a249-COLLATERAL-0",
2649+
"market": Object {
2650+
"address": "0x078f358208685046a11c85e8ad32895ded33a249",
2651+
"chainId": 42161,
2652+
"id": "0x078f358208685046a11c85e8ad32895ded33a249",
2653+
"name": "0x078f358208685046a11c85e8ad32895ded33a249",
2654+
"netSupplyRate": 0.0062858302613958,
2655+
"outputToken": Object {
2656+
"address": "0x078f358208685046a11c85e8ad32895ded33a249",
2657+
"chainId": 42161,
2658+
},
2659+
"protocol": "aave",
2660+
"rewards": Array [],
2661+
"totalSupplyRate": 0.0062858302613958,
2662+
"tvlUnderlying": "315871357755",
2663+
"underlying": Object {
2664+
"address": "0x2f2a2543b76a4166549f7aab2e75bef0aefc5b0f",
2665+
"chainId": 42161,
2666+
},
2667+
},
2668+
"marketAddress": "0x078f358208685046a11c85e8ad32895ded33a249",
2669+
"marketId": "0x078f358208685046a11c85e8ad32895ded33a249",
2670+
"protocol": "aave",
2671+
},
2672+
],
2673+
},
2674+
}
2675+
`);
2676+
});
2677+
2678+
it('persists expected state', async () => {
2679+
const { controller } = await setupController();
2680+
2681+
const derivedState = deriveStateFromMetadata(
2682+
controller.state,
2683+
controller.metadata,
2684+
'persist',
2685+
);
2686+
2687+
// Compare `pooled_staking` separately to minimize size of snapshot
2688+
const {
2689+
pooled_staking: derivedPooledStaking,
2690+
...derivedStateWithoutPooledStaking
2691+
} = derivedState;
2692+
expect(derivedPooledStaking).toStrictEqual({
2693+
'1': {
2694+
pooledStakes: mockPooledStakes,
2695+
exchangeRate: '1.5',
2696+
vaultMetadata: mockVaultMetadata,
2697+
vaultDailyApys: mockPooledStakingVaultDailyApys,
2698+
vaultApyAverages: mockPooledStakingVaultApyAverages,
2699+
},
2700+
'560048': {
2701+
pooledStakes: mockPooledStakes,
2702+
exchangeRate: '1.5',
2703+
vaultMetadata: mockVaultMetadata,
2704+
vaultDailyApys: mockPooledStakingVaultDailyApys,
2705+
vaultApyAverages: mockPooledStakingVaultApyAverages,
2706+
},
2707+
isEligible: true,
2708+
});
2709+
expect(derivedStateWithoutPooledStaking).toMatchInlineSnapshot(`
2710+
Object {
2711+
"lending": Object {
2712+
"isEligible": true,
2713+
"markets": Array [
2714+
Object {
2715+
"address": "0xe50fa9b3c56ffb159cb0fca61f5c9d750e8128c8",
2716+
"chainId": 42161,
2717+
"id": "0xe50fa9b3c56ffb159cb0fca61f5c9d750e8128c8",
2718+
"name": "0xe50fa9b3c56ffb159cb0fca61f5c9d750e8128c8",
2719+
"netSupplyRate": 1.52269127978874,
2720+
"outputToken": Object {
2721+
"address": "0xe50fa9b3c56ffb159cb0fca61f5c9d750e8128c8",
2722+
"chainId": 42161,
2723+
},
2724+
"protocol": "aave",
2725+
"rewards": Array [],
2726+
"totalSupplyRate": 1.52269127978874,
2727+
"tvlUnderlying": "132942564710249273623333",
2728+
"underlying": Object {
2729+
"address": "0x82af49447d8a07e3bd95bd0d56f35241523fbab1",
2730+
"chainId": 42161,
2731+
},
2732+
},
2733+
],
2734+
"positions": Array [
2735+
Object {
2736+
"assets": "112",
2737+
"chainId": 42161,
2738+
"id": "0xe6a7d2b7de29167ae4c3864ac0873e6dcd9cb47b-0x078f358208685046a11c85e8ad32895ded33a249-COLLATERAL-0",
2739+
"market": Object {
2740+
"address": "0x078f358208685046a11c85e8ad32895ded33a249",
2741+
"chainId": 42161,
2742+
"id": "0x078f358208685046a11c85e8ad32895ded33a249",
2743+
"name": "0x078f358208685046a11c85e8ad32895ded33a249",
2744+
"netSupplyRate": 0.0062858302613958,
2745+
"outputToken": Object {
2746+
"address": "0x078f358208685046a11c85e8ad32895ded33a249",
2747+
"chainId": 42161,
2748+
},
2749+
"protocol": "aave",
2750+
"rewards": Array [],
2751+
"totalSupplyRate": 0.0062858302613958,
2752+
"tvlUnderlying": "315871357755",
2753+
"underlying": Object {
2754+
"address": "0x2f2a2543b76a4166549f7aab2e75bef0aefc5b0f",
2755+
"chainId": 42161,
2756+
},
2757+
},
2758+
"marketAddress": "0x078f358208685046a11c85e8ad32895ded33a249",
2759+
"marketId": "0x078f358208685046a11c85e8ad32895ded33a249",
2760+
"protocol": "aave",
2761+
},
2762+
],
2763+
},
2764+
}
2765+
`);
2766+
});
2767+
2768+
it('exposes expected state to UI', async () => {
2769+
const { controller } = await setupController();
2770+
2771+
const derivedState = deriveStateFromMetadata(
2772+
controller.state,
2773+
controller.metadata,
2774+
'usedInUi',
2775+
);
2776+
2777+
// Compare `pooled_staking` separately to minimize size of snapshot
2778+
const {
2779+
pooled_staking: derivedPooledStaking,
2780+
...derivedStateWithoutPooledStaking
2781+
} = derivedState;
2782+
expect(derivedPooledStaking).toStrictEqual({
2783+
'1': {
2784+
pooledStakes: mockPooledStakes,
2785+
exchangeRate: '1.5',
2786+
vaultMetadata: mockVaultMetadata,
2787+
vaultDailyApys: mockPooledStakingVaultDailyApys,
2788+
vaultApyAverages: mockPooledStakingVaultApyAverages,
2789+
},
2790+
'560048': {
2791+
pooledStakes: mockPooledStakes,
2792+
exchangeRate: '1.5',
2793+
vaultMetadata: mockVaultMetadata,
2794+
vaultDailyApys: mockPooledStakingVaultDailyApys,
2795+
vaultApyAverages: mockPooledStakingVaultApyAverages,
2796+
},
2797+
isEligible: true,
2798+
});
2799+
expect(derivedStateWithoutPooledStaking).toMatchInlineSnapshot(`
2800+
Object {
2801+
"lending": Object {
2802+
"isEligible": true,
2803+
"markets": Array [
2804+
Object {
2805+
"address": "0xe50fa9b3c56ffb159cb0fca61f5c9d750e8128c8",
2806+
"chainId": 42161,
2807+
"id": "0xe50fa9b3c56ffb159cb0fca61f5c9d750e8128c8",
2808+
"name": "0xe50fa9b3c56ffb159cb0fca61f5c9d750e8128c8",
2809+
"netSupplyRate": 1.52269127978874,
2810+
"outputToken": Object {
2811+
"address": "0xe50fa9b3c56ffb159cb0fca61f5c9d750e8128c8",
2812+
"chainId": 42161,
2813+
},
2814+
"protocol": "aave",
2815+
"rewards": Array [],
2816+
"totalSupplyRate": 1.52269127978874,
2817+
"tvlUnderlying": "132942564710249273623333",
2818+
"underlying": Object {
2819+
"address": "0x82af49447d8a07e3bd95bd0d56f35241523fbab1",
2820+
"chainId": 42161,
2821+
},
2822+
},
2823+
],
2824+
"positions": Array [
2825+
Object {
2826+
"assets": "112",
2827+
"chainId": 42161,
2828+
"id": "0xe6a7d2b7de29167ae4c3864ac0873e6dcd9cb47b-0x078f358208685046a11c85e8ad32895ded33a249-COLLATERAL-0",
2829+
"market": Object {
2830+
"address": "0x078f358208685046a11c85e8ad32895ded33a249",
2831+
"chainId": 42161,
2832+
"id": "0x078f358208685046a11c85e8ad32895ded33a249",
2833+
"name": "0x078f358208685046a11c85e8ad32895ded33a249",
2834+
"netSupplyRate": 0.0062858302613958,
2835+
"outputToken": Object {
2836+
"address": "0x078f358208685046a11c85e8ad32895ded33a249",
2837+
"chainId": 42161,
2838+
},
2839+
"protocol": "aave",
2840+
"rewards": Array [],
2841+
"totalSupplyRate": 0.0062858302613958,
2842+
"tvlUnderlying": "315871357755",
2843+
"underlying": Object {
2844+
"address": "0x2f2a2543b76a4166549f7aab2e75bef0aefc5b0f",
2845+
"chainId": 42161,
2846+
},
2847+
},
2848+
"marketAddress": "0x078f358208685046a11c85e8ad32895ded33a249",
2849+
"marketId": "0x078f358208685046a11c85e8ad32895ded33a249",
2850+
"protocol": "aave",
2851+
},
2852+
],
2853+
},
2854+
}
2855+
`);
2856+
});
2857+
});
25692858
});

packages/earn-controller/src/EarnController.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,16 +115,22 @@ const lendingTransactionTypes = new Set<LendingTransactionTypes>([
115115
*/
116116
const earnControllerMetadata: StateMetadata<EarnControllerState> = {
117117
pooled_staking: {
118+
includeInStateLogs: true,
118119
persist: true,
119120
anonymous: false,
121+
usedInUi: true,
120122
},
121123
lending: {
124+
includeInStateLogs: true,
122125
persist: true,
123126
anonymous: false,
127+
usedInUi: true,
124128
},
125129
lastUpdated: {
130+
includeInStateLogs: true,
126131
persist: false,
127132
anonymous: true,
133+
usedInUi: false,
128134
},
129135
};
130136

0 commit comments

Comments
 (0)