-
-
Notifications
You must be signed in to change notification settings - Fork 242
chore: remove usages of NetworkController:getState in EarnController #6153
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
chore: remove usages of NetworkController:getState in EarnController #6153
Conversation
@metamaskbot publish-preview |
Preview builds have been published. See these instructions for more information about preview builds. Expand for full list of packages and versions.
|
243e64f
to
8886aa1
Compare
// refresh pooled staking data | ||
this.refreshPooledStakingVaultMetadata().catch(console.error); | ||
this.refreshPooledStakingVaultDailyApys().catch(console.error); | ||
this.refreshPooledStakingVaultApyAverages().catch(console.error); | ||
this.refreshPooledStakes().catch(console.error); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've left these calls the same here but I don't know if it brings much value to refresh PS data on each network change given PS isn't multi-chain? For the Lending calls below it seems to make more sense.
8886aa1
to
6a9a827
Compare
@metamaskbot publish-preview |
Preview builds have been published. See these instructions for more information about preview builds. Expand for full list of packages and versions.
|
7853624
to
d05158e
Compare
@metamaskbot publish-preview |
Preview builds have been published. See these instructions for more information about preview builds. Expand for full list of packages and versions.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bug: Chain ID Typing Mismatch Causes Hex Conversion Errors
Type inconsistency in executeLendingDeposit
, executeLendingWithdraw
, and executeLendingTokenApprove
methods. The chainId
parameter is typed as string
but is passed to toHex()
, which expects a number
. This can lead to incorrect behavior if chainId
is already a hex string (e.g., '0x1'
). The chainId
parameter should either be typed as number
, or the toHex()
call should be removed.
packages/earn-controller/src/EarnController.ts#L872-L928
core/packages/earn-controller/src/EarnController.ts
Lines 872 to 928 in d05158e
*/ | |
async executeLendingDeposit({ | |
amount, | |
chainId, | |
protocol, | |
underlyingTokenAddress, | |
gasOptions, | |
txOptions, | |
}: { | |
amount: string; | |
chainId: string; | |
protocol: LendingMarket['protocol']; | |
underlyingTokenAddress: string; | |
gasOptions: { | |
gasLimit?: GasLimitParams; | |
gasBufferPct?: number; | |
}; | |
txOptions: Parameters< | |
typeof TransactionController.prototype.addTransaction | |
>[1]; | |
}) { | |
const address = this.#getCurrentAccount()?.address; | |
const transactionData = await this.#earnSDK?.contracts?.lending?.[ | |
protocol | |
]?.[underlyingTokenAddress]?.encodeDepositTransactionData( | |
amount, | |
address, | |
gasOptions, | |
); | |
if (!transactionData) { | |
throw new Error('Transaction data not found'); | |
} | |
if (!this.#selectedNetworkClientId) { | |
throw new Error('Selected network client id not found'); | |
} | |
const gasLimit = !transactionData.gasLimit | |
? undefined | |
: toHex(transactionData.gasLimit); | |
const txHash = await this.#addTransactionFn( | |
{ | |
...transactionData, | |
value: transactionData.value.toString(), | |
chainId: toHex(chainId), | |
gasLimit, | |
}, | |
{ | |
...txOptions, | |
networkClientId: this.#selectedNetworkClientId, | |
}, | |
); | |
return txHash; | |
} |
packages/earn-controller/src/EarnController.ts#L943-L999
core/packages/earn-controller/src/EarnController.ts
Lines 943 to 999 in d05158e
*/ | |
async executeLendingWithdraw({ | |
amount, | |
chainId, | |
protocol, | |
underlyingTokenAddress, | |
gasOptions, | |
txOptions, | |
}: { | |
amount: string; | |
chainId: string; | |
protocol: LendingMarket['protocol']; | |
underlyingTokenAddress: string; | |
gasOptions: { | |
gasLimit?: GasLimitParams; | |
gasBufferPct?: number; | |
}; | |
txOptions: Parameters< | |
typeof TransactionController.prototype.addTransaction | |
>[1]; | |
}) { | |
const address = this.#getCurrentAccount()?.address; | |
const transactionData = await this.#earnSDK?.contracts?.lending?.[ | |
protocol | |
]?.[underlyingTokenAddress]?.encodeWithdrawTransactionData( | |
amount, | |
address, | |
gasOptions, | |
); | |
if (!transactionData) { | |
throw new Error('Transaction data not found'); | |
} | |
if (!this.#selectedNetworkClientId) { | |
throw new Error('Selected network client id not found'); | |
} | |
const gasLimit = !transactionData.gasLimit | |
? undefined | |
: toHex(transactionData.gasLimit); | |
const txHash = await this.#addTransactionFn( | |
{ | |
...transactionData, | |
value: transactionData.value.toString(), | |
chainId: toHex(chainId), | |
gasLimit, | |
}, | |
{ | |
...txOptions, | |
networkClientId: this.#selectedNetworkClientId, | |
}, | |
); | |
return txHash; |
packages/earn-controller/src/EarnController.ts#L1015-L1071
core/packages/earn-controller/src/EarnController.ts
Lines 1015 to 1071 in d05158e
*/ | |
async executeLendingTokenApprove({ | |
protocol, | |
amount, | |
chainId, | |
underlyingTokenAddress, | |
gasOptions, | |
txOptions, | |
}: { | |
protocol: LendingMarket['protocol']; | |
amount: string; | |
chainId: string; | |
underlyingTokenAddress: string; | |
gasOptions: { | |
gasLimit?: GasLimitParams; | |
gasBufferPct?: number; | |
}; | |
txOptions: Parameters< | |
typeof TransactionController.prototype.addTransaction | |
>[1]; | |
}) { | |
const address = this.#getCurrentAccount()?.address; | |
const transactionData = await this.#earnSDK?.contracts?.lending?.[ | |
protocol | |
]?.[underlyingTokenAddress]?.encodeUnderlyingTokenApproveTransactionData( | |
amount, | |
address, | |
gasOptions, | |
); | |
if (!transactionData) { | |
throw new Error('Transaction data not found'); | |
} | |
if (!this.#selectedNetworkClientId) { | |
throw new Error('Selected network client id not found'); | |
} | |
const gasLimit = !transactionData.gasLimit | |
? undefined | |
: toHex(transactionData.gasLimit); | |
const txHash = await this.#addTransactionFn( | |
{ | |
...transactionData, | |
value: transactionData.value.toString(), | |
chainId: toHex(chainId), | |
gasLimit, | |
}, | |
{ | |
...txOptions, | |
networkClientId: this.#selectedNetworkClientId, | |
}, | |
); | |
return txHash; |
Bug: Redundant API Calls in Loop
The refreshEarnEligibility()
method is redundantly called inside the refreshPooledStakingData()
loop for each supported chain. As this method performs a global, address-based eligibility check independent of chain ID, these multiple calls cause unnecessary API requests, performance overhead, and potential race conditions. It should be called once outside the loop.
packages/earn-controller/src/EarnController.ts#L636-L657
core/packages/earn-controller/src/EarnController.ts
Lines 636 to 657 in d05158e
for (const chainId of this.#supportedPooledStakingChains) { | |
await Promise.all([ | |
this.refreshPooledStakes({ resetCache, address, chainId }).catch( | |
(error) => { | |
errors.push(error); | |
}, | |
), | |
this.refreshEarnEligibility({ address }).catch((error) => { | |
errors.push(error); | |
}), | |
this.refreshPooledStakingVaultMetadata(chainId).catch((error) => { | |
errors.push(error); | |
}), | |
this.refreshPooledStakingVaultDailyApys(chainId).catch((error) => { | |
errors.push(error); | |
}), | |
this.refreshPooledStakingVaultApyAverages(chainId).catch((error) => { | |
errors.push(error); | |
}), | |
]); | |
} |
Was this report helpful? Give feedback by reacting with 👍 or 👎
Explanation
The Global Network Selector is being removed and these changes for the EarnController ensure that we are not relying on global state via
NetworkController:getState
. Instead, information required such as the selected network client ID or chain ID is passed in contextually.NetworkController:getState
. Instead:selectedNetworkClientId
to be passed in when constructed and it is used ininitializeSDK
.chainId
parameter with fallback to Ethereum Mainnet used in Pooled Staking data calls:refreshPooledStakingVaultApyAverages
,refreshPooledStakingVaultDailyApys
,refreshPooledStakingVaultMetadata
andrefreshPooledStakes
chainId
parameter required in all Lending transaction calls:executeLendingTokenApprove
,executeLendingWithdraw
andexecuteLendingDeposit
chainId
parameter required in Lending data calls:getLendingMarketDailyApysAndAverages
andgetLendingPositionHistory
. The other Lending data fetches do not require a chainId.NetworkController:networkDidChange
rather thanNetworkController:stateChange
as this is a more granular and less frequent event to listen to.References
Checklist