From 2698089868052229613a66482969e957ac83863e Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Tue, 10 Feb 2026 14:51:12 +0000 Subject: [PATCH 1/2] docs: add security and polkadot chain support pages Co-Authored-By: Jem Conlon --- docs.json | 7 +- wallet-sdk/chain-support/polkadot.mdx | 311 ++++++++++++++++++++++++++ wallet-sdk/security.mdx | 42 ++++ 3 files changed, 359 insertions(+), 1 deletion(-) create mode 100644 wallet-sdk/chain-support/polkadot.mdx create mode 100644 wallet-sdk/security.mdx diff --git a/docs.json b/docs.json index 8bef0fa..d50fb78 100644 --- a/docs.json +++ b/docs.json @@ -60,7 +60,8 @@ "wallet-sdk/chain-support/stacks", "wallet-sdk/chain-support/ton", "wallet-sdk/chain-support/tron", - "wallet-sdk/chain-support/adi" + "wallet-sdk/chain-support/adi", + "wallet-sdk/chain-support/polkadot" ] }, { @@ -77,6 +78,10 @@ "walletguide/explorer" ] }, + { + "group": "Security", + "pages": ["wallet-sdk/security"] + }, { "group": "Production", "pages": ["wallet-sdk/best-practices"] diff --git a/wallet-sdk/chain-support/polkadot.mdx b/wallet-sdk/chain-support/polkadot.mdx new file mode 100644 index 0000000..ef31b0e --- /dev/null +++ b/wallet-sdk/chain-support/polkadot.mdx @@ -0,0 +1,311 @@ +--- +title: "Polkadot" +description: "Integrate WalletConnect into Polkadot wallets using the Wallet SDK, including session management, signing, and namespace configuration." +sidebarTitle: "Polkadot" +--- + +This guide covers integrating the WalletConnect Wallet SDK into Polkadot-based wallets, including session proposals, request handling, and namespace configuration. + +## Wallet Integration Guide + +### Getting Started + +Generate a unique `projectId` by visiting and creating your project's profile on the WalletConnect Dashboard at [dashboard.walletconnect.com](https://dashboard.walletconnect.com/). + +### Setup + +Import Core and Wallet SDK from WalletConnect. + +```js +import { Core } from "@walletconnect/core"; +import { WalletKit } from "@walletconnect/walletkit"; +``` + +Instantiate and add Core and Wallet SDK to the state of the wallet. + +```js +const core = new Core({ projectId: "YOUR_PROJECT_ID" }); +const walletKit = await WalletKit.init({ + core: core, + metadata: { + name: "Example WalletConnect Wallet", + description: "Example WalletConnect Integration", + url: "myexamplewallet.com", + icons: [], + }, +}); +``` + +Create a function to accept a session `uri` which will be passed from a dapp when a user either scans the dapp's WalletConnect QR code modal or manually copies and pastes the URI from the modal into the wallet's UI. + +```js +const onConnect = async (uri: string) => { + const result = await walletKit.core.pairing.pair({ uri }); +}; +``` + +Handle the `session_proposal` event on the `walletKit`. This event is triggered when the `pair` method is called on `walletKit.core.pairing` to create a pairing session. + +### Approving a Session Proposal + +When approving a session proposal, the wallet can perform any necessary checks such as ensuring that the proposal includes all required namespaces and any optional namespaces. The approval response also contains the approved accounts as part of the namespace. + +```js +const substrateAccounts = [ + "5CK8D1sKNwF473wbuBP6NuhQfPaWUetNsWUNAAzVwTfxqjfr", + "5F3sa2TJAWMqDhXG6jhV4N8ko9SxwGy8TpaNS1repo5EYjQX", +]; + +const walletConnectAccounts = accounts.map( + (account) => `polkadot:91b171bb158e2d3848fa23a9f1c25182:${account.address}` +); + +walletKit.on("session_proposal", async (proposal) => { + showWalletConnectModal(); + + const session = await walletKit.approveSession({ + id: proposal.id, + namespaces: { + polkadot: { + accounts: walletConnectAccounts, + methods: ["polkadot_signTransaction", "polkadot_signMessage"], + chains: ["polkadot:91b171bb158e2d3848fa23a9f1c25182"], + events: ["chainChanged", "accountsChanged"], + }, + }, + }); + + const response = { + id: proposal.id, + result: "session approved", + jsonrpc: "2.0", + }; + + await walletKit.respondSessionRequest({ topic: session.topic, response }); +}); +``` + +### Rejecting a Session Proposal + +If the user does not approve the requested chains, methods, or accounts, or if the wallet does not support the requested chains or methods, the response should not be considered a success. + +```js +import { getSdkError } from "@walletconnect/utils"; + +walletKit.on("session_proposal", async (proposal) => { + showWalletConnectModal(); + + await walletKit.rejectSession({ + id: proposal.id, + reason: getSdkError("USER_REJECTED"), + }); +}); +``` + +### Handling Session Request Events + +A dapp triggers an event when it requires the wallet to carry out a specific action, such as signing a transaction. The event includes a topic and a request object, which will differ based on the requested action. Two common use cases in Polkadot are signing messages and signing transactions, represented as `polkadot_signMessage` and `polkadot_signTransaction` respectively. + +```js +walletKit.on("session_request", async (requestEvent) => { + const { params, id } = requestEvent; + const { request } = params; + const address = request.params?.address; + + const wallet = getPolkadotWallet(address); + + if (!wallet) { + throw new Error("Polkadot wallet does not exist"); + } + + switch (request.method) { + case "polkadot_signMessage": + const msgSignature = await wallet.signMessage(request.params.message); + const msgResponse = { id, result: { signature: msgSignature }, jsonrpc: "2.0" }; + await walletKit.respondSessionRequest({ topic, response: msgResponse }); + break; + + case "polkadot_signTransaction": + const txSignature = await wallet.signTransaction( + request.params.transactionPayload + ); + const txResponse = { id, result: { signature: txSignature }, jsonrpc: "2.0" }; + await walletKit.respondSessionRequest({ topic, response: txResponse }); + break; + + default: + throw new Error(getSdkError("INVALID_METHOD").message); + } +}); +``` + +### Session Persistence and Management + +- Sessions can be saved/stored so users don't have to pair repeatedly. +- Sessions can be disconnected using `await walletKit.disconnectSession({ topic: topic });`. +- Sessions can be extended using `await walletKit.extendSession({ topic: topic });`. +- Default session lifetime is 7 days for WalletConnect v2.0. + +## Namespaces Guide + +### Understanding Namespaces + +Pairing sessions use specific methods, events, and chains during their lifetimes. These arguments constitute what is known as a `namespace`. Namespaces are used to specify the chains, methods, and events that are intended to be used in a particular session. They establish the minimal requirement for a wallet and a dapp to get paired. There are two types of namespaces: `proposal namespaces` and `session namespaces`. + +### Proposal Namespaces + +A dapp sends a proposal namespace to the wallet for pairing. The proposal namespace contains the list of `chains`, `methods`, and `events` that the dapp intends to make use of. The wallet validates if the received proposal namespaces are valid and returns a session with its approved namespaces as a response. + +Example Proposal Namespace for a dapp which supports connecting to Polkadot, Ethereum, Polygon, and Cosmos: + +```js +{ + "polkadot": { + "chains": [ + "polkadot:91b171bb158e2d3848fa23a9f1c25182", + "polkadot:b0a8d493285c2df73290dfb7e61f870f", + ], + "methods": ["polkadot_signMessage"], + "events": ["accountsChanged"] + }, + "eip155": { + "chains": [ + "eip155:1", + "eip155:137" + ], + "methods": ["eth_sign"], + "events": ["accountsChanged"] + }, + "cosmos": { + "chains": ["cosmos:cosmoshub-4"], + "methods": ["cosmos_signDirect"], + "events": ["someCosmosEvent"] + } +} +``` + +### Session Namespaces + +The wallet validates if the received proposal namespaces match with the session namespaces it supports. The wallet session can also choose to provide access to more chains, methods, or events that were not a part of the proposal namespaces. + +```js +{ + "polkadot": { + "accounts": [ + "polkadot:91b171bb158e2d3848fa23a9f1c25182:AZBEwbZhYeiofodZnM2iAoshP3pXRPNSJEKFqEPDmvv1mY7" + ], + "methods": ["polkadot_signMessage", "polkadot_signTransaction"], + "events": ["accountsChanged"] + }, + "eip155": { + "accounts": [ + "eip155:137:0xab16a96d359ec26a11e2c2b3d8f8b8942d5bfcdb", + "eip155:1:0xab16a96d359ec26a11e2c2b3d8f8b8942d5bfcdb" + ], + "methods": ["eth_sign"], + "events": ["accountsChanged"] + }, + "cosmos": { + "accounts": [ + "cosmos:cosmoshub-4:cosmos1t2uflqwqe0fsj0shcfkrvpukewcw40yjj6hdc0" + ], + "methods": ["cosmos_signDirect", "personal_sign"], + "events": ["someCosmosEvent", "proofFinalized"] + } +} +``` + +### Chains + +`chains` is an array of chain IDs which represent the chains the session will be using during its lifetime. For Polkadot, the format for each chain ID is the chain-agnostic namespace (e.g. `polkadot`, `eip155`, `cosmos`) followed by a colon and the genesis hash for the chain (e.g. `91b171bb158e2d3848fa23a9f1c25182` for Polkadot). + +### Methods + +`methods` is represented as an array of wallet-defined methods that a session supports. These are not pre-defined or centrally implemented and can be modified/extended as needed by a wallet. + +In the above Polkadot session namespace example there are two given methods: `polkadot_signMessage` and `polkadot_signTransaction`. [An example for each method](https://github.com/WalletConnect/web-examples/blob/main/advanced/wallets/react-wallet-v2/src/lib/PolkadotLib.ts). + +Wallets can also define additional methods. For example, adding a `polkadot_getSignedHex` method: + +```js +{ + "polkadot": { + "accounts": [ + "polkadot:91b171bb158e2d3848fa23a9f1c25182:AZBEwbZhYeiofodZnM2iAoshP3pXRPNSJEKFqEPDmvv1mY7" + ], + "methods": [ + "polkadot_signMessage", + "polkadot_signTransaction", + "polkadot_getSignedHex" + ], + "events": ["accountsChanged"] + } +} +``` + +### Events + +`events` represent specific changes in a session's state that a dapp or wallet may want to take action on. For example, emitting an `accountsChanged` event: + +```js +await signClient.emit({ + topic, + event: { + name: "accountsChanged", + data: ["AZBEwbZhYeiofodZnM2iAoshP3pXRPNSJEKFqEPDmvv1mY7"], + }, + chainId: "polkadot:91b171bb158e2d3848fa23a9f1c25182", +}); +``` + +### Dapps: Universal Provider and Namespaces + +The connect method on the universal provider expects an object that matches the `ConnectParams` interface: + +```js +interface ConnectParams { + requiredNamespaces?: ProposalTypes.RequiredNamespaces; + optionalNamespaces?: ProposalTypes.OptionalNamespaces; + sessionProperties?: ProposalTypes.SessionProperties; + pairingTopic?: string; + relays?: RelayerTypes.ProtocolOptions[]; +} +``` + +Example using only the `requiredNamespaces` field: + +```js +const proposalNamespace = { + requiredNamespaces: { + polkadot: { + methods: ["polkadot_signTransaction", "polkadot_signMessage"], + chains: ["polkadot:91b171bb158e2d3848fa23a9f1c25182"], + events: ["chainChanged", "accountsChanged"], + }, + }, +}; + +const { uri, approval } = await provider.client.connect(proposalNamespace); +``` + +### Wallets: Wallet SDK and Namespaces + +When the Wallet SDK approves and creates a session, it must provide the session proposal `id` as well as the session `namespaces` which are approved for use in the session: + +```js +const session = await walletKit.approveSession({ + id: proposal.id, + namespaces: { + polkadot: { + accounts: [ + "polkadot:91b171bb158e2d3848fa23a9f1c25182:AZBEwbZhYeiofodZnM2iAoshP3pXRPNSJEKFqEPDmvv1mY7", + ], + methods: ["polkadot_signTransaction", "polkadot_signMessage"], + chains: ["polkadot:91b171bb158e2d3848fa23a9f1c25182"], + events: ["chainChanged", "accountsChanged"], + }, + }, +}); +``` + +More information on namespaces can be found in the [WalletConnect specification](https://docs.walletconnect.com/specs/clients/sign/namespaces#controller-side-validation-of-incoming-proposal-namespaces-wallet). diff --git a/wallet-sdk/security.mdx b/wallet-sdk/security.mdx new file mode 100644 index 0000000..e4c0536 --- /dev/null +++ b/wallet-sdk/security.mdx @@ -0,0 +1,42 @@ +--- +title: "Security Information" +description: "Security architecture, audits, and encryption details for the WalletConnect Wallet SDK." +sidebarTitle: "Security" +--- + +Security is a fundamental aspect of the WalletConnect architecture. The infrastructure has undergone multiple rounds of third-party security reviews, audits, penetration testing, and threat modeling to ensure the highest standards of protection. Security is viewed as a continuously evolving discipline, with regular system audits to identify and address potential vulnerabilities. + +## Wallet SDK + +### Architecture + +The Wallet SDK provides an end-to-end encrypted solution for wallets to connect to applications and sign messages/transactions. As an open-source SDK, it supports multiple transport methods, from WebSockets to Universal Links. + +### Handshake & End-to-End Encryption + +For a detailed overview of the handshake and end-to-end encryption protocol, refer to the [technical specification](https://specs.walletconnect.com/2.0/specs/clients/sign/session-proposal). + +### Audits + +The Wallet SDK, including its encryption stack, was audited by Trail of Bits. The audit report is available [here](https://github.com/trailofbits/publications/blob/master/reviews/2023-03-walletconnectv2-securityreview.pdf). This comprehensive security review covered the source code and included a lightweight Threat Model covering upstream and downstream dependencies. The broader WalletConnect system underwent Threat Modeling by Spearbit. The threat model is available [here](https://drive.google.com/file/d/1QpPSLvCEMunaYHHBPN0g6kYd39uFxpPk/view). + +### Dependencies + +The Wallet SDK's design philosophy prioritizes minimizing third-party dependencies to reduce the attack surface area. + +## Third-Party Reviews + +The security infrastructure of WalletConnect has undergone multiple rounds of audits by independent security auditing firms, including Trail of Bits, Halborn, and Spearbit. + +| Audit Scope | Auditor | Report | +| --- | --- | --- | +| WalletConnect Comprehensive Threat Model | Spearbit | [View Report](https://drive.google.com/file/d/1QpPSLvCEMunaYHHBPN0g6kYd39uFxpPk/view) | +| Wallet SDK Security Review & Lightweight Threat Model | Trail of Bits | [View Report](https://github.com/trailofbits/publications/blob/master/reviews/2023-03-walletconnectv2-securityreview.pdf) | + +## Bug Bounty Program + +WalletConnect maintains an active bug bounty program to encourage security researchers to responsibly disclose vulnerabilities and help strengthen the systems. For more information, visit the [security page](https://walletconnect.network/security). + +## Get in Touch + +For security-related inquiries, please visit the [security contact page](https://walletconnect.network/security). From a35967d6a560ee27bdcc674927d9295e03327b63 Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Thu, 12 Feb 2026 07:58:38 +0000 Subject: [PATCH 2/2] docs: replace polkadot integration guide with RPC reference Co-Authored-By: Jem Conlon --- wallet-sdk/chain-support/polkadot.mdx | 409 ++++++++------------------ 1 file changed, 126 insertions(+), 283 deletions(-) diff --git a/wallet-sdk/chain-support/polkadot.mdx b/wallet-sdk/chain-support/polkadot.mdx index ef31b0e..608c858 100644 --- a/wallet-sdk/chain-support/polkadot.mdx +++ b/wallet-sdk/chain-support/polkadot.mdx @@ -1,311 +1,154 @@ --- -title: "Polkadot" -description: "Integrate WalletConnect into Polkadot wallets using the Wallet SDK, including session management, signing, and namespace configuration." -sidebarTitle: "Polkadot" +title: Polkadot +description: "Overview of the Polkadot JSON-RPC methods supported by Wallet SDK." --- -This guide covers integrating the WalletConnect Wallet SDK into Polkadot-based wallets, including session proposals, request handling, and namespace configuration. - -## Wallet Integration Guide - -### Getting Started - -Generate a unique `projectId` by visiting and creating your project's profile on the WalletConnect Dashboard at [dashboard.walletconnect.com](https://dashboard.walletconnect.com/). - -### Setup - -Import Core and Wallet SDK from WalletConnect. - -```js -import { Core } from "@walletconnect/core"; -import { WalletKit } from "@walletconnect/walletkit"; -``` - -Instantiate and add Core and Wallet SDK to the state of the wallet. - -```js -const core = new Core({ projectId: "YOUR_PROJECT_ID" }); -const walletKit = await WalletKit.init({ - core: core, - metadata: { - name: "Example WalletConnect Wallet", - description: "Example WalletConnect Integration", - url: "myexamplewallet.com", - icons: [], - }, -}); -``` - -Create a function to accept a session `uri` which will be passed from a dapp when a user either scans the dapp's WalletConnect QR code modal or manually copies and pastes the URI from the modal into the wallet's UI. - -```js -const onConnect = async (uri: string) => { - const result = await walletKit.core.pairing.pair({ uri }); -}; -``` - -Handle the `session_proposal` event on the `walletKit`. This event is triggered when the `pair` method is called on `walletKit.core.pairing` to create a pairing session. - -### Approving a Session Proposal - -When approving a session proposal, the wallet can perform any necessary checks such as ensuring that the proposal includes all required namespaces and any optional namespaces. The approval response also contains the approved accounts as part of the namespace. - -```js -const substrateAccounts = [ - "5CK8D1sKNwF473wbuBP6NuhQfPaWUetNsWUNAAzVwTfxqjfr", - "5F3sa2TJAWMqDhXG6jhV4N8ko9SxwGy8TpaNS1repo5EYjQX", -]; - -const walletConnectAccounts = accounts.map( - (account) => `polkadot:91b171bb158e2d3848fa23a9f1c25182:${account.address}` -); - -walletKit.on("session_proposal", async (proposal) => { - showWalletConnectModal(); - - const session = await walletKit.approveSession({ - id: proposal.id, - namespaces: { - polkadot: { - accounts: walletConnectAccounts, - methods: ["polkadot_signTransaction", "polkadot_signMessage"], - chains: ["polkadot:91b171bb158e2d3848fa23a9f1c25182"], - events: ["chainChanged", "accountsChanged"], - }, - }, - }); - - const response = { - id: proposal.id, - result: "session approved", - jsonrpc: "2.0", - }; - - await walletKit.respondSessionRequest({ topic: session.topic, response }); -}); -``` - -### Rejecting a Session Proposal - -If the user does not approve the requested chains, methods, or accounts, or if the wallet does not support the requested chains or methods, the response should not be considered a success. - -```js -import { getSdkError } from "@walletconnect/utils"; - -walletKit.on("session_proposal", async (proposal) => { - showWalletConnectModal(); - - await walletKit.rejectSession({ - id: proposal.id, - reason: getSdkError("USER_REJECTED"), - }); -}); -``` - -### Handling Session Request Events - -A dapp triggers an event when it requires the wallet to carry out a specific action, such as signing a transaction. The event includes a topic and a request object, which will differ based on the requested action. Two common use cases in Polkadot are signing messages and signing transactions, represented as `polkadot_signMessage` and `polkadot_signTransaction` respectively. - -```js -walletKit.on("session_request", async (requestEvent) => { - const { params, id } = requestEvent; - const { request } = params; - const address = request.params?.address; - - const wallet = getPolkadotWallet(address); - - if (!wallet) { - throw new Error("Polkadot wallet does not exist"); - } - - switch (request.method) { - case "polkadot_signMessage": - const msgSignature = await wallet.signMessage(request.params.message); - const msgResponse = { id, result: { signature: msgSignature }, jsonrpc: "2.0" }; - await walletKit.respondSessionRequest({ topic, response: msgResponse }); - break; - - case "polkadot_signTransaction": - const txSignature = await wallet.signTransaction( - request.params.transactionPayload - ); - const txResponse = { id, result: { signature: txSignature }, jsonrpc: "2.0" }; - await walletKit.respondSessionRequest({ topic, response: txResponse }); - break; - - default: - throw new Error(getSdkError("INVALID_METHOD").message); - } -}); -``` - -### Session Persistence and Management - -- Sessions can be saved/stored so users don't have to pair repeatedly. -- Sessions can be disconnected using `await walletKit.disconnectSession({ topic: topic });`. -- Sessions can be extended using `await walletKit.extendSession({ topic: topic });`. -- Default session lifetime is 7 days for WalletConnect v2.0. - -## Namespaces Guide - -### Understanding Namespaces - -Pairing sessions use specific methods, events, and chains during their lifetimes. These arguments constitute what is known as a `namespace`. Namespaces are used to specify the chains, methods, and events that are intended to be used in a particular session. They establish the minimal requirement for a wallet and a dapp to get paired. There are two types of namespaces: `proposal namespaces` and `session namespaces`. - -### Proposal Namespaces - -A dapp sends a proposal namespace to the wallet for pairing. The proposal namespace contains the list of `chains`, `methods`, and `events` that the dapp intends to make use of. The wallet validates if the received proposal namespaces are valid and returns a session with its approved namespaces as a response. - -Example Proposal Namespace for a dapp which supports connecting to Polkadot, Ethereum, Polygon, and Cosmos: - -```js + + **Please note:** The Polkadot RPC standard is still under review and specifications may change. + Implementation details and method signatures are subject to updates. + + +## polkadot_signTransaction + +This method returns a signature for the provided transaction payload. It will be signed by a keypair corresponding to the requested signer address. + +### Parameters + +1. `Object` - Request parameters: + - `address`: `string` - SS58 encoded address of the signer + - `transactionPayload`: `Object` - As per Polkadot type `SignerPayloadJSON` containing: + - `address`: `string` - The SS58 encoded address (must match outer address) + - `assetId`: `HexString | null` - (optional) The id of the asset used to pay fees + - `blockHash`: `HexString` - The checkpoint hash of the block, 32 bytes + - `blockNumber`: `HexString` - The checkpoint block number (hex encoded) + - `era`: `HexString` - The mortality period of this transaction + - `genesisHash`: `HexString` - The genesis hash of the chain, 32 bytes + - `metadataHash`: `HexString | null` - (optional) The hash of the metadata for verification + - `method`: `string` - The SCALE encoded method data (hex encoded) + - `mode`: `number` - (optional) The mode for metadata verification (0=none, 1=exact, 2=partial) + - `nonce`: `HexString` - The nonce for this transaction (hex encoded) + - `specVersion`: `HexString` - The current specification version (hex encoded) + - `tip`: `HexString` - The tip for this transaction (hex encoded amount) + - `transactionVersion`: `HexString` - The current transaction version (hex encoded) + - `signedExtensions`: `string[]` - The array of signed extension identifiers + - `version`: `number` - The extrinsic version number + - `withSignedTransaction`: `boolean` - (optional) Request signed transaction bytes + +### Returns + +1. `Object` - Signature result: + - `signature`: `string` - Hex-encoded signature + +### Example + +```javascript theme={null} +// Request { - "polkadot": { - "chains": [ - "polkadot:91b171bb158e2d3848fa23a9f1c25182", - "polkadot:b0a8d493285c2df73290dfb7e61f870f", - ], - "methods": ["polkadot_signMessage"], - "events": ["accountsChanged"] - }, - "eip155": { - "chains": [ - "eip155:1", - "eip155:137" - ], - "methods": ["eth_sign"], - "events": ["accountsChanged"] - }, - "cosmos": { - "chains": ["cosmos:cosmoshub-4"], - "methods": ["cosmos_signDirect"], - "events": ["someCosmosEvent"] - } + "id": 1, + "jsonrpc": "2.0", + "method": "polkadot_signTransaction", + "params": { + "address": "15UyNqZ7NB1QQVpY9xv7VGwkxtvXePKihFHx8kH4VgEcS1gU", + "transactionPayload": { + "address": "15UyNqZ7NB1QQVpY9xv7VGwkxtvXePKihFHx8kH4VgEcS1gU", + "assetId": null, + "blockHash": "0x1b1c32a33c3622044a3be1b7753ff9b24695c327fc9254f97c...", + "blockNumber": "0x00000393", + "era": "0x0500", + "genesisHash": "0x91b171bb158e2d3848fa23a9f1c25182fb8e20313b2c1eb49219da7a70ce90c3", + "metadataHash": null, + "method": "0x0400....", + "mode": 0, + "nonce": "0x00000000", + "specVersion": "0x00000000", + "tip": "0x00000000000000000000000000000000", + "transactionVersion": "0x00000004", + "signedExtensions": [ + "CheckNonZeroSender", + "CheckSpecVersion", + "CheckTxVersion", + "CheckGenesis", + "CheckMortality", + "CheckNonce", + "CheckWeight", + "ChargeTransactionPayment" + ], + "version": 4 + } + } } -``` - -### Session Namespaces -The wallet validates if the received proposal namespaces match with the session namespaces it supports. The wallet session can also choose to provide access to more chains, methods, or events that were not a part of the proposal namespaces. - -```js +// Result { - "polkadot": { - "accounts": [ - "polkadot:91b171bb158e2d3848fa23a9f1c25182:AZBEwbZhYeiofodZnM2iAoshP3pXRPNSJEKFqEPDmvv1mY7" - ], - "methods": ["polkadot_signMessage", "polkadot_signTransaction"], - "events": ["accountsChanged"] - }, - "eip155": { - "accounts": [ - "eip155:137:0xab16a96d359ec26a11e2c2b3d8f8b8942d5bfcdb", - "eip155:1:0xab16a96d359ec26a11e2c2b3d8f8b8942d5bfcdb" - ], - "methods": ["eth_sign"], - "events": ["accountsChanged"] - }, - "cosmos": { - "accounts": [ - "cosmos:cosmoshub-4:cosmos1t2uflqwqe0fsj0shcfkrvpukewcw40yjj6hdc0" - ], - "methods": ["cosmos_signDirect", "personal_sign"], - "events": ["someCosmosEvent", "proofFinalized"] - } + "id": 1, + "jsonrpc": "2.0", + "result": { + "signature": "0x01234567..." + } } ``` -### Chains + + The `method` field in the transaction payload contains the SCALE encoded call data specific to the + transaction being signed. This typically includes the pallet name, function name and any + parameters required for that specific transaction. + -`chains` is an array of chain IDs which represent the chains the session will be using during its lifetime. For Polkadot, the format for each chain ID is the chain-agnostic namespace (e.g. `polkadot`, `eip155`, `cosmos`) followed by a colon and the genesis hash for the chain (e.g. `91b171bb158e2d3848fa23a9f1c25182` for Polkadot). +## polkadot_signMessage -### Methods +This method returns a signature for the provided message payload. It will be signed by a keypair corresponding to the requested signer address. -`methods` is represented as an array of wallet-defined methods that a session supports. These are not pre-defined or centrally implemented and can be modified/extended as needed by a wallet. +### Parameters -In the above Polkadot session namespace example there are two given methods: `polkadot_signMessage` and `polkadot_signTransaction`. [An example for each method](https://github.com/WalletConnect/web-examples/blob/main/advanced/wallets/react-wallet-v2/src/lib/PolkadotLib.ts). +1. `Object` - As per Polkadot type `SignerPayloadRaw` containing: + - `address`: `string` - SS58 encoded address + - `data`: `string` - The hex-encoded data for this request + - `type`: `'bytes' | 'payload'` - (optional) Identifies if the message is arbitrary bytes or a transaction payload -Wallets can also define additional methods. For example, adding a `polkadot_getSignedHex` method: + +`polkadot_signMessage` can potentially be used to sign arbitrary transactions blindly. To mitigate this security risk: -```js -{ - "polkadot": { - "accounts": [ - "polkadot:91b171bb158e2d3848fa23a9f1c25182:AZBEwbZhYeiofodZnM2iAoshP3pXRPNSJEKFqEPDmvv1mY7" - ], - "methods": [ - "polkadot_signMessage", - "polkadot_signTransaction", - "polkadot_getSignedHex" - ], - "events": ["accountsChanged"] - } -} -``` +1. Always wrap messages in `message` tags before hex encoding when message `type` is `'bytes'` or not specified +2. If the type is not `'payload'`, signers MUST verify that messages are properly wrapped +3. Use `type: 'payload'` only when signing transaction-like data that should be possible to decrypt -### Events +This convention helps prevent malicious applications from using `polkadot_signMessage` for blind transaction signing while maintaining compatibility with widely-used Polkadot signing implementations. -`events` represent specific changes in a session's state that a dapp or wallet may want to take action on. For example, emitting an `accountsChanged` event: + -```js -await signClient.emit({ - topic, - event: { - name: "accountsChanged", - data: ["AZBEwbZhYeiofodZnM2iAoshP3pXRPNSJEKFqEPDmvv1mY7"], - }, - chainId: "polkadot:91b171bb158e2d3848fa23a9f1c25182", -}); -``` +### Returns -### Dapps: Universal Provider and Namespaces +1. `Object` - Signature result: + - `signature`: `string` - Hex-encoded signature -The connect method on the universal provider expects an object that matches the `ConnectParams` interface: +### Example -```js -interface ConnectParams { - requiredNamespaces?: ProposalTypes.RequiredNamespaces; - optionalNamespaces?: ProposalTypes.OptionalNamespaces; - sessionProperties?: ProposalTypes.SessionProperties; - pairingTopic?: string; - relays?: RelayerTypes.ProtocolOptions[]; +```javascript theme={null} +// Request +{ + "id": 1, + "jsonrpc": "2.0", + "method": "polkadot_signMessage", + "params": { + "address": "15UyNqZ7NB1QQVpY9xv7VGwkxtvXePKihFHx8kH4VgEcS1gU", + "data": "0x3c42797465733e68656c6c6f20776f726c643c2f42797465733e", + "type": "bytes" + } } -``` - -Example using only the `requiredNamespaces` field: -```js -const proposalNamespace = { - requiredNamespaces: { - polkadot: { - methods: ["polkadot_signTransaction", "polkadot_signMessage"], - chains: ["polkadot:91b171bb158e2d3848fa23a9f1c25182"], - events: ["chainChanged", "accountsChanged"], - }, - }, -}; - -const { uri, approval } = await provider.client.connect(proposalNamespace); +// Result +{ + "id": 1, + "jsonrpc": "2.0", + "result": { + "signature": "0x6a98517e159dcaef1855cda5f5e5a61387ac3b63212b0f82642f5599502fc9eb1ea134e2db5dfbe0ec4530c6e7e576b177ad0618f68eaec37a3ac6dce819a30a" + } +} ``` -### Wallets: Wallet SDK and Namespaces - -When the Wallet SDK approves and creates a session, it must provide the session proposal `id` as well as the session `namespaces` which are approved for use in the session: +## Additional Resources -```js -const session = await walletKit.approveSession({ - id: proposal.id, - namespaces: { - polkadot: { - accounts: [ - "polkadot:91b171bb158e2d3848fa23a9f1c25182:AZBEwbZhYeiofodZnM2iAoshP3pXRPNSJEKFqEPDmvv1mY7", - ], - methods: ["polkadot_signTransaction", "polkadot_signMessage"], - chains: ["polkadot:91b171bb158e2d3848fa23a9f1c25182"], - events: ["chainChanged", "accountsChanged"], - }, - }, -}); -``` +For more information about Polkadot RPC methods and integration details, please refer to: -More information on namespaces can be found in the [WalletConnect specification](https://docs.walletconnect.com/specs/clients/sign/namespaces#controller-side-validation-of-incoming-proposal-namespaces-wallet). +- [Polkadot Transaction Construction](https://docs.polkadot.com/develop/toolkit/integrations/transaction-construction/) +- [Polkadot.js Extrinsic Types](https://github.com/polkadot-js/api/blob/master/packages/types/src/types/extrinsic.ts#L32)