-
-
Notifications
You must be signed in to change notification settings - Fork 187
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
feat: add and use Accounts API for Account balance calls #4781
feat: add and use Accounts API for Account balance calls #4781
Conversation
we currently have added the `getBalances` call, we will extend this in the future
packages/assets-controllers/src/multi-chain-accounts-service/types.ts
Outdated
Show resolved
Hide resolved
packages/assets-controllers/src/multi-chain-accounts-service/multi-chain-accounts.ts
Outdated
Show resolved
Hide resolved
packages/assets-controllers/src/multi-chain-accounts-service/mocks/mock-get-balances.ts
Show resolved
Hide resolved
getting bearings straight
9bd1664
to
6e4171a
Compare
…account-api-to-token-detection-controller
and add jsdoc comments to balance response type
…troller. I'll add some tests and might refactor out pieces if it makes it easier for testing
*/ | ||
constructor({ | ||
interval = DEFAULT_INTERVAL, | ||
disabled = true, | ||
getBalancesInSingleCall, | ||
trackMetaMetricsEvent, | ||
messenger, | ||
useAccountsAPI = true, |
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.
Big proponent of feature switching (in case this PR gets too large, or we need to turn this feature off).
Happy to remove otherwise.
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.
This is enabled by default
12a4687
to
9adebed
Compare
/** | ||
* TODO - discuss if this is correct. | ||
* | ||
* If the Accounts API succeeds, but the tokens cannot be added (unable to create `Token` shape) | ||
* Then should we add no tokens & then finish? | ||
* | ||
* If we want to, we could then do a pass with the RPC flow? But would it be necessary? | ||
* - DEV - we can just add a simple check at the end of the API flow where if no tokens were added, then count it as a failure and perform the RPC flow? | ||
*/ |
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.
Yeah lets discuss this scenario.
This is because we are using the TokenCache
to create the correct token shape.
The Token
shape requires the aggregators
and image
fields which the API does not provide us.
If the new token from the API does not exist in this cache, then we need to skip it.
/** | ||
* TODO - discuss if this is correct. | ||
* | ||
* If the Accounts API succeeds, but the tokens cannot be added (token already added) | ||
* Then should we add no tokens (if they are all added) & then finish? | ||
* | ||
* If we want to, we could then do a pass with the RPC flow? But would it be necessary? | ||
* - DEV - we can just add a simple check at the end of the API flow where if no tokens were added, then count it as a failure and perform the RPC flow? | ||
*/ |
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.
Yep lets discuss.
This flow happens when we receive tokens from our API, but these tokens are already added into the wallet (as detected tokens, ignored tokens, etc).
So if the token is already added, we will skip it.
// NOTE: some of this data is also available from the `token` balance, | ||
// however it is missing the `aggregators` and `iconUrl` properties |
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.
These 2 fields that are missing from the Account API are technically optional. We could leave them out.
However I do not know the unintended effects if we were to do this.
packages/assets-controllers/src/TokenDetectionController.test.ts
Outdated
Show resolved
Hide resolved
…account-api-to-token-detection-controller
currently the supportedNetworks call has places that has unreachable errors, but could still be errors if used directly in the future
…account-api-to-token-detection-controller
@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.
|
…account-api-to-token-detection-controller
…er' of github.com:MetaMask/core into NOTIFY-1179/add-account-api-to-token-detection-controller
return; | ||
} | ||
|
||
// We need specific data from tokenList to correctly create a token |
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.
Are the fields we get from the token list the icon url and aggregators?
We'll eventually stop storing icon urls in state since its always calculable as "https://static.cx.metamask.io/api/v1/tokenIcons/${chainId}/${address}.png"
.
Aggregators are shown in the UI but we could just query them from the big token list rather than duplicating on each imported token. So I think we keep this for now but could remove the dependency later.
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.
Yep 100% agree. How expensive would it be for the accounts API to serve this additional information?
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.
Aha saw a relevant comment you've made before, great callout.
https://github.com/MetaMask/mobile-planning/issues/1935#issuecomment-2384061477
} | ||
|
||
const result = await fetchSupportedNetworks().catch(() => null); | ||
this.supportedNetworksCache = result; |
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 like the cache and dynamic lookup of support. Since its in memory rather than state, it'll re run when extension is reloaded or browser close/open. But not each time you open the popup. Which seems like a reasonable interval.
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.
Yep only on browser close/open. We can think of more sophisticating caches if need be... later though 😄
@@ -0,0 +1,52 @@ | |||
import { handleFetch } from '@metamask/controller-utils'; |
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.
Nice move with the separate client. Also good to attempt OpenAPI generation but we can live without it for now.
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.
This looks great to me, I couldn't find any bugs. I tested chains with and without account API support, hiding tokens, and manually adding them.
Explanation
This integrates the Accounts API (Multi-chain Balances Endpoint) to help alleviate expensive RPC calls made by Token Detection.
The aim is to attempt to use the Accounts API when making balance calls for expensive functionality (e.g. Token Detection)
Code Walkthrough
https://www.loom.com/share/e540cae3967746b0aca343d4c59d0af6?sid=69c2556c-96d3-451e-bd67-7d03f32fff03
References
#4743
https://consensyssoftware.atlassian.net/browse/NOTIFY-1179
Changelog
@metamask/assets-controllers
fetchSupportedNetworks()
function to dynamically fetch supported networks by the Accounts APIfetchMultiChainBalances()
function to get balances for a given addressuseAccountsAPI
to theTokenDetectionController
constructor to enable/disable the accounts API feature.#addDetectedTokensViaAPI()
private method inTokenDetectionController
to get detected tokens via the Accounts API.detectTokens()
method inTokenDetectionController
to try AccountsAPI first before using RPC flow to detect tokens.Checklist