feat(Stellar): asset enrichment through snap data source#9422
Conversation
| if (assetsBalance) { | ||
| const response: DataResponse = { assetsBalance, updateMode: 'merge' }; | ||
| for (const subscription of this.activeSubscriptions.values()) { | ||
| subscription.onAssetsUpdate(response)?.catch(console.error); | ||
| } | ||
| if (!assetsBalance) { | ||
| return; | ||
| } | ||
|
|
||
| const response: DataResponse = { assetsBalance, updateMode: 'merge' }; | ||
| for (const subscription of this.activeSubscriptions.values()) { | ||
| subscription.onAssetsUpdate(response)?.catch(console.error); |
There was a problem hiding this comment.
this should not change
| * Handle snap balance updates from the keyring. | ||
| * Transforms the payload and publishes to AssetsController. | ||
| * | ||
| * Push updates carry amounts only. Per-asset snap enrichment (e.g. Stellar |
There was a problem hiding this comment.
no need to add comment
| } | ||
| } | ||
|
|
||
| if ( |
There was a problem hiding this comment.
we should just add step 3 with Feature flag
| } | ||
| } | ||
| results.assetsBalance ??= {}; | ||
| const accountBalances = results.assetsBalance[accountId] ?? {}; |
There was a problem hiding this comment.
on step 3:
if stellar feature flag:
- fetch enrichment
- update the state (results.assetsBalance)
| * When false, SnapDataSource skips `getAccountAssetInfo` enrichment. | ||
| * Evaluated at call time. Defaults to () => false. | ||
| */ | ||
| assetEnrichmentEnabled?: () => boolean; |
There was a problem hiding this comment.
i think they prefer stellar focus, but up to them
and there are 2 way to get feature flag
- use messenger call directly from data source, so u dont need pass in , as we are temp solution, which i think is better (please check packages/network-controller/src/NetworkController.ts)
- pass in from client, like what u did
There was a problem hiding this comment.
Yep, if poss can we make this stellar specific? This is mostly generic, but let's keep it as a stellar flag
There was a problem hiding this comment.
@salimtb confirm we should pass feature flag from client side
change assetEnrichmentEnabled to isStellarEnabled
| }) | ||
| ) { | ||
| // TODO(STELLAR): Remove this Snap-side accountAssetInfo enrichment path once the Accounts API returns account-asset enrichment directly. | ||
| await enrichAccountAssetInfo({ |
There was a problem hiding this comment.
um..i feel just do:
- call snap
- modify data
that will be clear enough
putting into a function, may create complexity, but it also clean
i leave it to Asset team
| await enrichAccountAssetInfo({ | |
| for (acc in accounts) { | |
| const result = await callSNAP() | |
| mergeResultIntoExistingBalanceData() | |
| } |
| const next: Record<string, AssetBalance> = { ...previousBalances }; | ||
| for (const [assetId, balance] of Object.entries(accountBalances)) { | ||
| next[assetId] = { | ||
| ...(previousBalances[assetId] ?? { amount: '0' }), |
There was a problem hiding this comment.
still have amt 0?
|
|
||
| ### Added | ||
|
|
||
| - Add optional `snapDataSourceConfig.assetEnrichmentEnabled` getter to `AssetsControllerOptions` so clients can enable or disable snap `getAccountAssetInfo` enrichment at runtime (defaults to disabled) |
There was a problem hiding this comment.
Let's add the PR number and link.
| { | ||
| "name": "@metamask/assets-controller", | ||
| "version": "10.0.1", | ||
| "version": "10.0.1-dev.8", |
There was a problem hiding this comment.
Ah nice, didn't know you could do this for testing. Let's clean up
| * When false, SnapDataSource skips `getAccountAssetInfo` enrichment. | ||
| * Evaluated at call time. Defaults to () => false. | ||
| */ | ||
| assetEnrichmentEnabled?: () => boolean; |
There was a problem hiding this comment.
Yep, if poss can we make this stellar specific? This is mostly generic, but let's keep it as a stellar flag
| * Optional per-asset fields from snap account-asset enrichment. | ||
| * Stellar classic assets use trustline fields; native XLM may include baseReserve. | ||
| */ | ||
| export type AccountAssetInfo = { |
There was a problem hiding this comment.
To future proof this, thoughts on making this a discriminated typed union.
{
type: "StellarAccountAssetInfo",
...
}
That way we have protection as other future network specific shapes are needed.
Likewise let's also "parse, don't validate" by using @metamask/superstruct to create structs that can parse the right shape (use as type assertion functions).
| // standard (unenriched) balance shape. When the feature flag is enabled | ||
| // and there are eligible assets, apply accountAssetInfo enrichment once. | ||
| if ( | ||
| this.#assetEnrichmentEnabled() && |
There was a problem hiding this comment.
| this.#assetEnrichmentEnabled() && | |
| this.#isStellarEnabled() && |
| // Post-fetch enrichment stage: assetsBalance above already matches the | ||
| // standard (unenriched) balance shape. When the feature flag is enabled | ||
| // and there are eligible assets, apply accountAssetInfo enrichment once. |
There was a problem hiding this comment.
| // Post-fetch enrichment stage: assetsBalance above already matches the | |
| // standard (unenriched) balance shape. When the feature flag is enabled | |
| // and there are eligible assets, apply accountAssetInfo enrichment once. |
| /** Raw balance amount as string (e.g., "1000000000" for 1000 USDC) */ | ||
| amount: string; | ||
| /** Optional per-asset info from snap account-asset enrichment (e.g. Stellar trustlines). */ | ||
| accountAssetInfo?: AccountAssetInfo; |
There was a problem hiding this comment.
change accountAssetInfo => metadata
| /** Per-asset enrichment keyed by CAIP-19 asset id from snap getAccountAssetInfo. */ | ||
| export type GetAccountAssetInfoResponse = Record< | ||
| Caip19AssetId, | ||
| AccountAssetInfo |
There was a problem hiding this comment.
| AccountAssetInfo | |
| Record<string, unknown> |
client side using super struct to verify the data, when they use it
Explanation
References
Checklist