Skip to content

CAIP-345: Wallet service URL property #345

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

Draft
wants to merge 5 commits into
base: main
Choose a base branch
from
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
104 changes: 104 additions & 0 deletions CAIPs/caip-345.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
---
caip: CAIP-345
title: Wallet Service URL property
author: Chris Smith (@chris13524)
discussions-to: https://github.com/ChainAgnostic/CAIPs/discussions/345
status: Draft
type: Standard
created: 2025-02-17
updated: 2025-02-17
requires: 25
---

## Simple Summary
<!--"If you can't explain it simply, you don't understand it well enough." Provide a simplified and layman-accessible explanation of the CAIP.-->
This CAIP defines a mechanism for CAIP-25 wallets to advertize support for a "wallet service" which can handle requests for specific wallet RPC methods instead of apps sending these requests directly to the wallet app.

## Abstract
<!--A short (~200 word) description of the technical issue being addressed.-->
A short (~200 word) description of the technical issue being addressed.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO write this


## Motivation
<!--The motivation is critical for CAIP. It should clearly explain why the state of the art is inadequate to address the problem that the CAIP solves. CAIP submissions without sufficient motivation may be rejected outright.-->
In protocols such as WalletConnect it is bad UX to redirect the user to a wallet to handle requests that are non-actionable to them. Examples of this include:
- `wallet_getCapabilities` - Defined in [EIP-5792](https://eips.ethereum.org/EIPS/eip-5792#wallet_getcapabilities)
- `wallet_getCallsStatus` - Defined in [EIP-5792](https://eips.ethereum.org/EIPS/eip-5792#wallet_getcallsstatus-rpc-specification)
- `wallet_getAssets` - Defined in [EIP-7811](https://eip.tools/eip/7811)

By defining a way for wallets to send requests to an external URL, the requests can be satisfied without needing the wallet app to be open.

## Specification
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO specify wallet service endpoint design. E.g. use POST and be JSON-RPC compatible

Also are these responses cacheable or not? I guess not since POST.

<!--The technical specification should describe the standard in detail. The specification should be detailed enough to allow competing, interoperable implementations. -->

Apps SHOULD use the wallet service when available for a method, instead of calling the wallet directly.

Wallets SHOULD implement fallback handling for all wallet service methods.
Copy link
Contributor Author

@chris13524 chris13524 Feb 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the relationship between methods listed in walletService and methods available according to CAIP-25? If a method is listed in walletService must it also be part of the CAIP-25 session payload?

Not requiring them to be present in the session payload could allow wallets to indicate support for a method ONLY on the wallet service, avoiding the wallet potentially needing to forward methods to the wallet service (if apps don't implement the wallet service but do implement the method).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

However, it is possible that having methods only listed in walletService may cause problems for existing CAIP-25 implementations. For example if a provider pre-validates a method is valid before checking if it should be forwarded to the walletService.

Copy link

@jakubuid jakubuid Feb 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For example if a provider pre-validates a method is valid before checking if it should be forwarded to the walletService.

It's not only providers that validate the methods; it's also the dapp/wallet that does that. E.g. when the method is received and is not listed in CAIP-25, it would most likely be invalid. Hence, I think it would be good to make the CAIP-25 listing obligatory.


Wallets MUST NOT include the same method multiple times or with different (conflicting) wallet service URLs. Apps SHOULD NOT attempt to recover from multiple or conflicting wallet service URLs, but MAY use the first URL available for the method as a convenience for implementation.

```ts
type WalletService = {
url: string,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO mention the case where wallet wants authentication on this service and should include a token in this URL. What about an RPC to refresh the token?

Copy link
Contributor Author

@chris13524 chris13524 Feb 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be uri instead to account for other non-HTTP protocols? For example a wallet could indicate to use p2p or a light client of some kind in order to handle the method.

Furthermore, we could allow listing a wallet service with multiple URIs and the client could select the first one it is able to support/use.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sounds complicated but future-proof.
uri: [string] sounds highly decentralized and would save us having to ducktype it as an array five years from now, although you end up having to catch the case of strings not-in-an-array-of-1 because humans 😅

methods: string[],
}[];

type Properties = {
walletService: WalletService,
[key: string]: any, // other properties
};
```

An easy way for apps to find the wallet service URL for a given method would be:

```javascript
walletService.find(s => s.methods.includes(method)).url
```

The `walletService` key can be used in both `sessionProperties` and `scopedProperties`, depending on what namespaces the method(s) in question are supported on.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about conflicting scenarios here?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would think you'd want to scope it to individual chains, right, with a slightly different URL/token/query-params/etc per-chain?

Copy link

@jakubuid jakubuid Feb 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why sessionProperties? Can't we limit this to scopedProperties only? Where eip155 stands for the EVM chains. If there's a need to define support per chain, scopedProperties also allows that.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

well, the way CAIP-25 was written, sessionProperties were meant to be things about the app<>wallet connection that had nothing to do with specific VMs/L1s, like "expiry" (of the connection) for example. which this kinda feels like to me, actually, unless it's a different URL for each chain?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so yeah, kinda depends on the API design, all options seem justifiable (as does picking one and excluding the others for this specific CAIP)


Below is an example support for `wallet_getAssets` which is only supported on `eip155` namespaces:

```json
"scopedProperties": {
"eip155": {
Copy link

@jakubuid jakubuid Feb 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the example of wallet_getAssets, which is supported on eip155 and solana?

LIke that?

"scopedProperties": {
    "eip155": {
	  "walletService": [{
            	"url": "<wallet service URL>",
            	"methods": ["wallet_getAssets"]
        }],
    },
  "solana": {
	  "walletService": [{
            	"url": "<wallet service URL>",
            	"methods": ["wallet_getAssets"]
        }],
    }
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah that's how it should look. I'll add some examples

But nothing that wallet_getAssets is not supported on Solana anyway (at least currently)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assume you mean this one from an open PR? https://eip.tools/eip/7811

"walletService": [{
"url": "<wallet service URL>",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what about adding headers?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is an example use case?

Copy link
Contributor

@llbartekll llbartekll Mar 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Auth token?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Auth token can be added as query param IMO. Avoids pre-flight requests on web apps.

"methods": ["wallet_getAssets"]
}],
}
}
```

## Rationale
<!--The rationale fleshes out the specification by describing what motivated the design and why particular design decisions were made. It should describe alternate designs that were considered and related work, e.g. how the feature is supported in other languages. The rationale may also provide evidence of consensus within the community, and should discuss important objections or concerns raised during discussion.-->

Allowing multiple URLs to be provided for different methods (useful for different endpoints, params or auth tokens). While at the same time, not duplicating the Wallet Service URL.

There was consideration for being able to specify different wallet service URLs for different accounts. However this would not make sense in the context of CAIP-25 because there is no mechanism to scope the methods themselves to particular accounts. If we provided a mechanism to scope the methods to accounts in this CAIP, the app may still try to send the method requests for non-listed accounts directly to the wallet.

There was consideraiton for defining the standard to have a unique wallet service URL for every single method. However this would cause excessive bandwidth consumption if the same URL were to be used for multiple methods.

## Test Cases
<!--Please add diverse test cases here if applicable. Any normative definition of an interface requires test cases to be implementable. -->

## Security Considerations
<!--Please add an explicit list of intra-actor assumptions and known risk factors if applicable. Any normative definition of an interface requires these to be implementable; assumptions and risks should be at both individual interaction/use-case scale and systemically, should the interface specified gain ecosystem-namespace adoption. -->
The wallet service would bear the security resonsibility of responding to these wallet RPC requests. Wallets should make informed decisions about which providers they use for this.

## Privacy Considerations
<!--Please add an explicit list of intra-actor assumptions and known risk factors if applicable. Any normative definition of an interface requires these to be implementable; assumptions and risks should be at both individual interaction/use-case scale and systemically, should the interface specified gain ecosystem-namespace adoption. -->
Similarly, the wallet service would have visibility into the wallet RPC requests being sent to it.

## Backwards Compatibility
<!--All CAIPs that introduce backwards incompatibilities must include a section describing these incompatibilities and their severity. The CAIP must explain how the author proposes to deal with these incompatibilities. CAIP submissions without a sufficient backwards compatibility treatise may be rejected outright.-->
This new property is fully backwards-compatible with CAIP-25.

## References
<!--Links to external resources that help understanding the CAIP better. This can e.g. be links to existing implementations. See CONTRIBUTING.md#style-guide . -->

- [CAIP-25][CAIP-25] is where this property is used

[CAIP-25]: https://ChainAgnostic.org/CAIPs/caip-25

## Copyright
Copyright and related rights waived via [CC0](../LICENSE).