diff --git a/CAIPs/caip-282.md b/CAIPs/caip-282.md index 38e40383..804b0020 100644 --- a/CAIPs/caip-282.md +++ b/CAIPs/caip-282.md @@ -60,6 +60,7 @@ interface WalletAnnounceRequestParams { name: string; icon: string; rdns: string; + targets?: { type: string, value: any }[], scopes?: AuthorizationScopes; } ``` @@ -68,7 +69,7 @@ Whenever a new Wallet Provider is discovered the Blockchain Library would index The parameters `name` and `icon` are used to display to the user to be easily recognizable while the `rdns` and `uuid` are only used internally for de-duping while they must always be unique, the `rdns` will always be the same but `uuid` is ephemeral per browser session. -The only optional parameter is `scopes` which is defined by CAIP-217 authorization specs that enables early discoverability and filtering of wallets based on RPC methods, notifications, documents and endpoints but also optional discovery of supported chains and even accounts. +The optional parameters are `scopes`, which is defined by [CAIP-217] authorization specs that enables early discoverability and filtering of wallets based on RPC methods, notifications, documents and endpoints but also optional discovery of supported chains and even accounts, and `targets`, which accepts [CAIP-341] Extension ID as a valid target type for establishing connections with browser extension wallets via the [CAIP-294] `wallet_announce` wallet discovery event. ```typescript // Defined by CAIP-217 diff --git a/CAIPs/caip-294.md b/CAIPs/caip-294.md index ef959286..ba1f5748 100644 --- a/CAIPs/caip-294.md +++ b/CAIPs/caip-294.md @@ -138,7 +138,7 @@ The `walletData` object MUST include the following properties: Additionally, the `walletData` object MAY include the following optional properties: -- `extensionId`: The canonical extension ID of the wallet provider for the active browser. +- `targets`: An array of objects, with an object containing `type: "caip341"` and `value: ` used to connect to wallets using `externally_connectable`. Important to note here that other CAIPs can extend this, and [CAIP-341][caip-341] is an example of a valid target type for this use case. - `scopes`: An object defining the authorization scopes supported by the wallet, as specified in CAIP-217. ```typescript @@ -148,12 +148,8 @@ interface WalletData { name: string; icon: string; rdns: string; - // Optional properties - target?: { - origin?: string; - extensionId?: string; - } + targets?: { type: string, value: any }[], scopes?: Caip217AuthorizationScopes; } ``` @@ -166,7 +162,22 @@ const walletData = { name: "Example Wallet", icon: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==", rdns: "com.example.wallet", - extensionId: "abcdefghijklmnopqrstuvwxyz", + targets: [ + { + type: "caip341", + value: "abcdefghijklmnopqrstuvwxyz" + }, + { + type: "caip315", + value: true + }, + { + type: "caip316", + value: { + somethingElse: "hello" + } + }, + ] scopes: { "eip155:1": { methods: ["eth_signTransaction", "eth_sendTransaction"], @@ -176,20 +187,20 @@ const walletData = { } ``` -This `walletData` type is is a superset of `WalletAnnounceRequestParams` type described in the [CAIP-282][caip-282] standard, adding the optional `extensionId` property as it is only relevant for browser extension based wallets. +This `walletData` type is a superset of `WalletAnnounceRequestParams` type described in the [CAIP-282][caip-282] standard, adding the optional `targets` property with the object defining `extensionId`, as it is only relevant for browser extension based wallets. -### ExtensionId +### Targets -When the `extensionId` is included in the `walletData` object, it indicates that the wallet supports communication via the browser's `externally_connectable` API. In this case: +When a `targets` property with the array containing an object with [`type: 'caip341'`][caip-341] is included in the `walletData` object, it indicates that the wallet expects communication via the browser's [`externally_connectable` API][externally_connectable]. In this case: -1. The dapp MUST use the `extensionId` to establish a connection with the wallet using the `externally_connectable` browser API. +1. The dapp MUST use the `targets.find(({ type }) => type === "caip314").value` (an [`extensionId`][externally_connectable]) to establish a connection with the wallet using the `externally_connectable` browser API. 2. All subsequent communication with the wallet (the "session") SHOULD be conducted over the `externally_connectable` API using `runtime.connect()` and `runtime.sendMessage()`. -3. The dapp MUST NOT use the injected provider for communication when `extensionId` is present. +3. The dapp MUST NOT use the injected provider for communication when `targets` with [CAIP-341](https://github.com/ChainAgnostic/CAIPs/blob/656551f800843b92243fb08ca6c24e805ad149a3/CAIPs/caip-341.md) type is present. Example of establishing a connection and sending a message: ```javascript -const port = chrome.runtime.connect(walletData.extensionId); +const port = chrome.runtime.connect(walletData.targets.value); port.onMessage.addListener((message) => { // Handle incoming messages @@ -205,7 +216,7 @@ port.postMessage({ }); ``` -If the `extensionId` is not present in the `walletData` object, the dapp SHOULD assume that communication will occur through the traditional injected provider method. +If the `targets` object with [CAIP-341](https://github.com/ChainAgnostic/CAIPs/blob/656551f800843b92243fb08ca6c24e805ad149a3/CAIPs/caip-341.md) type is not present in the `walletData` object, the dapp SHOULD assume that communication will occur through the traditional injected provider method. #### Handshake @@ -500,11 +511,15 @@ TODO - [CAIP-27][caip-27] - Blockchain ID Specification - [CAIP-25][caip-25] - Blockchain ID Specification - [CAIP-282][caip-282] - Browser Wallet Discovery Interface +- [CAIP-341][caip-341] - Extension ID Target Type Specification +- [externally_connectable][externally_connectable] - Chrome's `externally_connectable` browser API documentation [eip-6963]: https://eips.ethereum.org/EIPS/eip-6963 [caip-27]: https://chainagnostic.org/CAIPs/caip-27 [caip-25]: https://chainagnostic.org/CAIPs/caip-25 [caip-282]: https://chainagnostic.org/CAIPs/caip-282 +[caip-341]: https://github.com/ChainAgnostic/CAIPs/blob/656551f800843b92243fb08ca6c24e805ad149a3/CAIPs/caip-341.md +[externally_connectable]: https://developer.chrome.com/docs/extensions/reference/manifest/externally-connectable ## Copyright diff --git a/CAIPs/caip-295.md b/CAIPs/caip-295.md index 05c30dcb..0fd6f3e4 100644 --- a/CAIPs/caip-295.md +++ b/CAIPs/caip-295.md @@ -47,6 +47,10 @@ This provides the foundation for any Wallet Provider to interface with a Decentr Different loading times can be affected by multiple factors, which makes it non-deterministic to publish and listen to messages from different sources within the browser. +#### Target Origin + +TODO Make Proposal For Target Origin As Valid Target Type For Wallet Data. + #### Discovery Both Wallet Providers and blockchain libraries must listen to incoming messages that might be published after their initialization. Additionally both Wallet Providers and blockchain libraries must publish a message to both announce themselves and their intent to connect, respectively. @@ -56,7 +60,10 @@ Here is the expected logic from the Blockchain Library: ```typescript interface WalletMapEntry { data: WalletAnnounceRequestParams; - targetOrigin: string; + targets: { + type: ; + value: + }[] } const wallets: Record = {} @@ -67,7 +74,7 @@ window.addEventListener("message", (event) => { // when an announce message was received then the library can index it by uuid wallets[event.data.params.uuid] = { params: event.data.params, - targetOrigin: event.targetOrigin + targetOrigin: event.target.value } } }); @@ -158,7 +165,10 @@ Logic from the Blockchain Library: // also by posting a prompt message interface WalletMapEntry { data: WalletAnnounceRequestParams; - targetOrigin: string; + targets: { + type: ; + value: + }[] } const wallets: Record = {} @@ -168,7 +178,7 @@ window.addEventListener("message", (event) => { // when an announce message was received then the library can index it by uuid wallets[event.data.params.uuid] = { params: event.data.params, - targetOrigin: event.targetOrigin + targetOrigin: event.targets.find(({ type }) => type === "caip295")?.value } } }); @@ -208,7 +218,7 @@ const sessionRequest = { let sessionResult = {} window.addEventListener("message", (event) => { - if (event.targetOrigin !== wallets[selected_uuid].targetOrigin) return; + if (event.targets.find(({ type }) => type === "caip295")?.value !== wallets[selected_uuid].targetOrigin) return; if (event.data.id === sessionRequest.id) { // Get JSON-RPC response if (event.data.error) { @@ -247,7 +257,7 @@ const signingRequest = { let signingResult = {} window.addEventListener("message", (event) => { - if (event.targetOrigin !== wallets[selected_uuid].targetOrigin) return; + if (event.targets.find(({ type }) => type === "caip295")?.value !== wallets[selected_uuid].targetOrigin) return; if (event.data.id === signingRequest.id) { // Get JSON-RPC response if (event.data.error) { @@ -309,7 +319,7 @@ window.addEventListener("message", (event) => { if (checkSupportedScopes(event.data.params)) { // prompt user to approve session // persist the targetOrigin for sessionRequest - sessionOrigin = event.targetOrigin + sessionOrigin = event.targets.find(({ type }) => type === "caip295")?.value } } }); @@ -344,7 +354,7 @@ window.postMessage(sessionResponse, sessionOrigin); let signingRequest = {} window.addEventListener("message", (event) => { - if (event.targetOrigin !== sessionOrigin) return; + if (event.targets.find(({ type }) => type === "caip295")?.value !== sessionOrigin) return; if (event.data.method === "wallet_createSession" && event.data.params.sessionId === walletData.uuid) { signingRequest = event.data.params }