CAIP-25 proposes a standardized way to describe and interact with blockchain assets across different blockchain networks. It mainly focuses on token identifiers, which are used to uniquely identify tokens (like cryptocurrencies and digital assets) across multiple blockchains.
CAIP-25 defines an authorization procedure for a chain agnostic provider to interface with a wallet as part of their initialization and/or "handshake" protocol.
This proposal defines a standard procedure for decentralized applications to interface with chain agnostic cryptocurrency wallets and other user agents that govern identities (including accounts) across multiple cryptographic systems. It specifies a lightweight protocol for negotiating and persisting authorizations during a session managed either by an in-DOM provider construct, by a securely-addressed browser extensions, or by a distinct user-agent.
The absence of standardized interfaces and abstractions for reading from and writing to blockchains such as consistent account models and JSON-RPC method specifications has fragmented application and wallet interactions. CAIP-25 resolves this by defining a unified, session-based interface that standardizes communication between applications and wallets.
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" are interpreted as described in RFC-2119.
The session is proposed by a caller and accepted by the respondent. The respondent may return a sessionId which both parties then persist along with session properties and authorization scopes. See CAIP-316 for guidance on session lifecycles with and without sessionIds.
If a wallet does not return a sessionId, it MUST track session data internally. The caller is not required to persist any session state but may query or revoke sessions via wallet_getSession, wallet_revokeSession, or receive updates via wallet_sessionChanged.
Subsequent wallet_createSession calls may:
sessionIdsessionId is provided (discouraged)Session updates initiated by the wallet must notify the caller using wallet_sessionChanged.
Callers may revoke sessions using wallet_revokeSession, passing the sessionId parameter if it was returned by the initial response.
Authorization requests are expressed as a top-level object scopes containing keyed scopeObjects.
Each scopeObject is keyed by a CAIP-2 or CAIP-104 identifiers. A null reference can be used to refer to a scope that applies to ANY chain within that namespace (eg. eip155:0)
Wallets MAY authorize a subset of scopes or scope properties as requested, and MAY also authorize additional scopes or scope properties. This enables granular control and flexibility on the part of the respondent.
Upon successful negotiation, the response includes a unified scopes object containing all granted scopes. Identically-keyed scopeObjects from multiple requests MUST be merged. No duplicate scopes with identical keys are allowed.
Respondents MUST NOT restructure scope formats (e.g., converting chain-specific keys into namespace-wide keys).
If a connection is rejected, the wallet MAY respond with a generic error or silently ignore the request to minimize fingerprinting risk (see Privacy Considerations).
The scopes object MUST contain one or more scopeObjects.
The properties object MAY be included for global session metadata.
Each entry within scopes object MAY contain accounts and capabilities as part of its object for success response.
The wallet MAY return generic or specific error messages depending on trust. Trusted responses may include codes like:
5000: Unknown error5001: User disapproved requested methods5002: User disapproved requested notifications5100-5102: Unsupported chains, methods, or notifications5201-5302: Malformed requestsExample 1
For request, we define a very simple scope for 10 EVM chains with the exact same scope.
For response, we also keep it quite simple with no wallet capabilities or special scopes.
Example 2
For the request, we define the expectation of 5 EVM chains with similar scope and additonally we have 2 Solana chains with similar scope
For the response, we match the same scopes as the request but separate 2 out of 5 EVM chains into individual scopes because of non-overlapping accounts, capabilities or methods.
Additionaly we have the two Solana chains returning the same scopes but returning two different account addresses for each chain including a unique capability for one of the chains
Finally the wallet has provided within properties with its walletInfo per CAIP-372.
To avoid ambiguity in authorizations, scopes MUST retain their original keyed structure using CAIP-2 or CAIP-104 identifiers. This ensures clarity in what is authorized and prevents accidental scope merging or misinterpretation.
To mitigate fingerprinting risks, wallets should prefer uniform or silent failure responses. Avoid leaking timing or error detail that may help malicious actors identify users or wallets. Progressive, minimal scope requests and updates are encouraged.
capababilities from request AND remove CAIP-2 prefix from accountscapabilities (fka scopedProperties) into scopeObjectsscopeObjects and retained only Chain-scoped scopeObjectsrequiredScopes and retained only scopes (fka optionalScopes).optionalScopes to scopes, scopedProperties to capabilities and sessionProperties to propertiesscopeObject syntax to CAIP-217sessionId usage (CAIP-171)sessionIdsscopeObjectswallet_revokeSession Specificationwallet_getSession Specificationwallet_sessionChanged SpecificationCopyright and related rights waived via CC0.