{"id":"ERC-7811","name":"Unified Cross-Chain Balances","status":"Draft","chain":"both","category":{"id":"cross-chain","name":"Cross-Chain","description":"Moving assets and messages between chains"},"journeyStages":[{"id":"asset-display","name":"Asset Discovery & Display","description":"Seeing tokens, NFTs, and balances"}],"uxImpact":"ERC-7811 defines wallet_getAssets for a wallet to report an account's assets, grouped by EIP-155 chain ID with optional filters. An application may build a cross-chain portfolio or net-worth view from those reports, but valuation, aggregation, stale-data policy, and bridged-asset deduplication remain application responsibilities.","officialUrl":"https://ercs.ethereum.org/ERCS/erc-7811","lastReviewed":"2026-09-18","lastUpdated":"2026-09-18","kind":"proposal","hasDetailedContent":true,"content":{"id":"ERC-7811","specConstraints":[{"id":"asset-network-identity","constraint":"Asset responses are keyed by the EIP-155 chain ID.","appliesTo":"application","normativity":"normative","specQuote":"The key MUST be EIP-155 chainId","specSection":"Specification / Method: wallet_getAssets / Response schema","specUrl":"https://ercs.ethereum.org/ERCS/erc-7811#response-schema","designImplication":"Derive network labels and action destinations from each response group. Do not merge identical-looking addresses or asset symbols across chains without retaining their network identity."},{"id":"asset-metadata-fields","constraint":"Known asset types have required metadata fields, but the asset-type list is not exhaustive.","appliesTo":"wallet","normativity":"normative","specQuote":"Implementations that are compliant with this ERC and return these well-known asset types MUST return at least these fields in metadata. Implementations MAY return more fields than specified here.","specSection":"Specification / Well-known asset types","specUrl":"https://ercs.ethereum.org/ERCS/erc-7811#well-known-asset-types","designImplication":"Validate the known type's metadata before formatting amounts or artwork. Handle missing fields and unknown types explicitly rather than assuming every response is an ERC-20 or has usable decimals."},{"id":"asset-filter-precedence","constraint":"An explicit assetFilter takes precedence over type and chain filters.","appliesTo":"application","normativity":"normative","specQuote":"If the assetFilter field is provided, the wallet MUST only return the assets specified within it, even if assetTypeFilter or chainFilter could have further filtered the result. This effectively disregards the assetTypeFilter and chainFilter fields entirely.","specSection":"Specification / Method: wallet_getAssets / Request schema","specUrl":"https://ercs.ethereum.org/ERCS/erc-7811#request-schema","designImplication":"Do not show combined filter chips as intersecting criteria when the RPC ignores the type and chain filters. Construct one coherent request and label the actual result scope."},{"id":"asset-type-filter","constraint":"A requested asset-type filter restricts the response to those types.","appliesTo":"wallet","normativity":"normative","specQuote":"assetTypeFilter is an OPTIONAL field that specifies an array of asset types, as defined in this ERC. If assetTypeFilter field is provided, wallet MUST include only assets with those types in the response.","specSection":"Specification / Method: wallet_getAssets / Request schema","specUrl":"https://ercs.ethereum.org/ERCS/erc-7811#request-schema","designImplication":"Apply this when no explicit assetFilter overrides it. Keep a filtered empty result distinct from an account with no assets and do not label it a complete portfolio."},{"id":"asset-filter-optional","constraint":"assetFilter is OPTIONAL and, when present, accepts asset identifiers scoped by a valid chainId.","appliesTo":"application","normativity":"normative","specQuote":"`assetFilter` is **OPTIONAL** field that accepts a list of assets identifiers. Each asset identifier is an object that contains `address` and `type` fields and is scoped by `chainId`, where ChainId **MUST** be a valid [EIP-155](./eip-155.md) chainId.","specSection":"Specification > Method: walletgetAssets > Request schema","specUrl":"https://ercs.ethereum.org/ERCS/erc-7811#request-schema","designImplication":"Make asset discovery scope visible: show whether the caller requested all assets or narrowed the response by address, type, and chain."},{"id":"asset-sort-order","constraint":"When assetFilter is omitted, the wallet SHOULD return all available assets, and it is RECOMMENDED that returned assets be ordered by estimated value in descending order.","appliesTo":"application","normativity":"normative","specQuote":"If the `assetFilter` field is omitted, the wallet **SHOULD** return all available assets for the requested account. It is **RECOMMENDED** that the returned assets be ordered by estimated value in descending order, as determined by the wallet.","specSection":"Specification > Method: walletgetAssets > Request schema","specUrl":"https://ercs.ethereum.org/ERCS/erc-7811#request-schema","designImplication":"Treat value ordering as wallet-provided guidance rather than a universal ranking; disclose the selected ordering when it affects prioritization."},{"id":"asset-chain-filter","constraint":"chainFilter is OPTIONAL; each supplied chainId MUST be a valid EIP-155 chainId.","appliesTo":"wallet","normativity":"normative","specQuote":"`chainFilter` is an **OPTIONAL** field that specifies an array of chain ids, where each value in the array **MUST** be a valid [EIP-155](./eip-155.md) chainId","specSection":"Specification > Method: walletgetAssets > Request schema","specUrl":"https://ercs.ethereum.org/ERCS/erc-7811#request-schema","designImplication":"Show chain scope in the asset request and avoid presenting a filtered response as the account's complete portfolio."},{"id":"asset-filter-granularity","constraint":"Consumers SHOULD set assetFilter, assetTypeFilter, and chainFilter as granular as reasonably possible.","appliesTo":"application","normativity":"normative","specQuote":"Consumers of `wallet_getAssets` SHOULD set `assetFilter`, `assetTypeFilter` and `chainFilter` with as granular as reasonably possible values. For example, if an app is only interested in interacting with a single token on a single chain, it should provide filters for this. Doing this both ensures that wallets and the underlying infrastructure do not incur excessive cost, as well as significantly increased performance to client applications.","specSection":"Specification > Method: walletgetAssets > Request schema","specUrl":"https://ercs.ethereum.org/ERCS/erc-7811#request-schema","designImplication":"Use narrow filters when the product needs one asset or chain, reducing unnecessary wallet work and keeping the result set focused."}],"sources":[{"label":"Official specification","url":"https://ercs.ethereum.org/ERCS/erc-7811","type":"official-spec"}],"lastReviewed":"2026-09-18","lastUpdated":"2026-09-18","summary":"ERC-7811 defines wallet_getAssets for a wallet to report an account's assets, grouped by EIP-155 chain ID with optional filters. An application may build a cross-chain portfolio or net-worth view from those reports, but valuation, aggregation, stale-data policy, and bridged-asset deduplication remain application responsibilities.","partialDeployment":{"body":"ERC-7811 is Draft. Treat wallet_getAssets and portfolio aggregation as conditional on wallet, chain, and provider support; verify filters, stale-data handling, valuation, bridged-asset deduplication, and privacy behavior before showing a complete portfolio."},"designerTakeaways":["You can show an app-derived total header with expandable per-chain breakdown rows.","Your loading UI can skeleton each chain row independently as data arrives.","You can mark stale chain data with Last updated 5m ago when RPC lags."],"applicability":{"whenToUse":["Multi-chain users are primary audience.","Product positioning is omnichain portfolio.","Aggregator infrastructure exists for target chains."],"whenToAvoid":["Single-chain-only product.","Cannot solve double-count on bridged assets.","Draft spec with no reliable data pipeline."]},"prototypeFirst":[{"screen":"Unified portfolio header","why":"An application may derive a total after showing which wallet-reported chains and assets are included.","covers":["All chains loaded","Partial load","Fiat toggle"],"include":["App-derived USD/EUR total with included-chain coverage","Chain expand chevron","Partial data warning"]},{"screen":"Per-chain breakdown expand","why":"Power users verify which chain holds what.","covers":["Expand row","Zero balance chain hidden"],"include":["Chain icon","Chain subtotal","Asset list per chain"]},{"screen":"Stale chain indicator","why":"Wrong totals destroy trust.","covers":["Stale","Refreshing","Failed chain"],"include":["Timestamp","Refresh button","Exclude from total option"]},{"screen":"Cross-chain action hint","why":"User may need asset on specific chain to act.","covers":["Available on Ethereum only"],"include":["Chain availability chip","Bridge CTA if needed"]}],"mentalModel":[{"label":"App-derived total","description":"A product-calculated sum of the wallet's reported chain assets, with coverage shown."},{"label":"Chain slice","description":"Each network contributes a portion — expand to see."},{"label":"Same asset multi-chain","description":"The wallet reports chain-keyed assets; any merge or split is an application policy."},{"label":"Bridged representations","description":"Potentially related assets require application-specific provenance and deduplication rules."},{"label":"Stale slice","description":"Slow chain data old — total may be approximate."}],"statesToDesign":[{"state":"Full portfolio loaded","trigger":"All chains responded.","userNeed":"Trust total.","designResponse":"Complete header and breakdown."},{"state":"Partial load","trigger":"Some chains pending.","userNeed":"Not think money vanished.","designResponse":"Skeleton rows; partial total label."},{"state":"Stale chain data","trigger":"RPC lag.","userNeed":"Know total approximate.","designResponse":"Amber stale badge on chain row."},{"state":"Chain query failed","trigger":"RPC down.","userNeed":"Retry or exclude.","designResponse":"Failed to load Chain X with retry."},{"state":"Asset only on one chain","trigger":"User tries action needing other chain.","userNeed":"Bridge path.","designResponse":"Available on Polygon only chip."}],"designDecisions":[{"question":"Merge same symbol across chains?","recommendation":"Single ETH row with chain sub-badges in expand.","rationale":"Users think one ETH, multiple locations."},{"question":"Show zero-balance chains?","recommendation":"Hide in default; show in chain manager settings.","rationale":"Clutter without value."},{"question":"Include stale in total?","recommendation":"Yes with ~ approximate label or exclude with user toggle.","rationale":"Honesty over false precision."}],"problemsSolved":[{"problem":"Manual network switching to check balances","oldWay":"Switch MetaMask network 8 times","newWay":"wallet_getAssets reports chain-keyed assets; the application can derive a total with coverage and caveats","impact":"critical"},{"problem":"Misstated net worth from missing chains","oldWay":"Forgot assets on L2","newWay":"The wallet returns assets it chooses to report for the requested account and filters","impact":"high"},{"problem":"Slow chain hides behind fast total","oldWay":"Total looks complete while L2 stale","newWay":"The application can show per-chain freshness and partial coverage around the wallet response","impact":"medium"}],"uxPatterns":[{"name":"Wallet Asset Overview","description":"Wallet-reported assets grouped by chain, with an optional app-derived total.","components":["TotalBalance","ChainExpand","FiatToggle"],"userFlow":["Open portfolio","See an app-derived total with its coverage label","Expand chain","Per-chain assets"]},{"name":"Incremental Asset Load","description":"Skeleton rows as each chain resolves.","components":["ChainSkeleton","StaleBadge","RefreshButton"],"userFlow":["Load starts","Chains populate","Stale flagged","User refreshes"]}],"antiPatterns":[{"pattern":"Total without loading partial state","why":"Understated wealth while chains load","instead":"Partial total label until all chains resolve","severity":"high"},{"pattern":"Double-counting bridged same asset","why":"Inflated net worth","instead":"Apply an explicit, application-specific deduplication policy and show which assets were included","severity":"critical"},{"pattern":"Hiding which chain holds asset","why":"User cannot act on holding","instead":"Chain badge on expand and action hints","severity":"medium"}],"vocabulary":[{"use":"App-derived total across networks","avoid":"Aggregated multichain balance","why":"Plain wealth language."},{"use":"On [chain name]","avoid":"Chain ID 42161 slice","why":"Network names not ids."},{"use":"Updating…","avoid":"RPC query pending","why":"Loading copy not infra jargon."}],"technicalNotes":"ERC-7811 defines the wallet JSON-RPC method wallet_getAssets for one account, with optional asset/type/chain filters and a response grouped by EIP-155 chain ID. It does not define fiat valuation, net-worth arithmetic, bridged-asset deduplication, freshness guarantees, or a complete aggregator; label those as application-derived.","relatedStandards":[{"id":"ERC-7828","relationship":"Chain-aware addresses complement balance view"},{"id":"ERC-5164","relationship":"Cross-chain messaging for balance sync"}]},"sources":[{"label":"Official specification","url":"https://ercs.ethereum.org/ERCS/erc-7811","type":"official-spec"},{"label":"Discussion search","url":"https://ethereum-magicians.org/search?q=ERC-7811","type":"discussion"}],"urls":{"canonical":"https://www.eipsfordesigners.com/standards/ERC-7811","markdown":"https://www.eipsfordesigners.com/standards/ERC-7811/content.md","agent":"https://www.eipsfordesigners.com/standards/ERC-7811/agent.md","api":"https://www.eipsfordesigners.com/api/standards/ERC-7811","official":"https://ercs.ethereum.org/ERCS/erc-7811","discussion":"https://ethereum-magicians.org/search?q=ERC-7811"},"freshness":{"lastReviewed":"2026-09-18","lastUpdated":"2026-09-18"}}