# Pairing API Source: https://docs.reown.com/advanced/api/core/pairing The Pairing API is a lightweight API for establishing an encrypted, protocol-agnostic communication layer between peers. Its purpose is to provide a secure channel for proposing protocols or sending requests between dapp and wallet. Head over to Reown Dashboard and create a new project. ## Installation WalletConnect currently offers Sign and Auth SDKs. To allow a reusable communication channel between peers, the Pairing API exposes a standard interface and allows for sending and receiving multi-protocol requests over a single pairing. Each SDK uses the same implementation of `core/pairing` (via `@walletconnect/core`) to manage pairings. To run multiple SDKs side-by-side (e.g. Sign and Auth), please refer to the \[Sharing a Core instance] guide. #### Add SDK for your project. You can add a WalletConnect Core SDKs to your project with Swift Package Manager. In order to do that: 1. Open XCode 2. Go to File -> Add Packages 3. Paste the repo GitHub URL: [https://github.com/reown-com/reown-swift](https://github.com/reown-com/reown-swift) 4. Tap Add Package 5. Select WalletConnectPairing check mark Kotlin implementation of Android CoreClient for all WalletConnect SDKs. This SDK is developed in Kotlin and usable in both Java and Kotlin files. ![Maven Central](https://img.shields.io/maven-central/v/com.walletconnect/android-core) #### Requirements * Android min SDK 23 * Java 11 #### Installation root/build.gradle.kts: ```gradle theme={null} allprojects { repositories { mavenCentral() maven { url "https://jitpack.io" } } } ``` app/build.gradle ```gradle theme={null} implementation("com.walletconnect:android-core:release_version") ``` #### Project set up To use initialize RelayClient properly you will need a projectId. Go to [https://dashboard.reown.com/app](https://dashboard.reown.com/app), register your project and get projectId. #### CoreClient initialization Before using any of the WalletConnect Kotlin SDKs, it is necessary to initialize the CoreClient. The initialization of CoreClient must always happen in the Android Application class. Provide the projectId generated in the Reown Dashboard, the WebSocket URL, choose the connection type, and pass the application class. You can also pass your own Relay instance using the `RelayConnectionInterface`. ```kotlin theme={null} val projectId = "" //Get Project ID at https://dashboard.reown.com/ val connectionType = ConnectionType.AUTOMATIC or ConnectionType.MANUAL val application = //Android Application level class [Optional] val optionalRelay: RelayConnectionInterface? = /*implement interface*/ CoreClient.initialize(projectId = projectId, connectionType = connectionType, application = application, relay = optionalRelay) ``` #### Using your own Relay instance The CoreClient offers the ability to use a custom Relay client. Just creating an instance of `RelayConnectionInterface` and passing it to `CoreClient.initialize`. ```kotlin theme={null} ... val optionalRelay: RelayConnectionInterface = /*implement interface*/ CoreClient.initialize(projectId = projectId, connectionType = connectionType, application = application, relay = optionalRelay) ``` WalletConnect currently offers Sign and Auth SDKs. To allow a reusable communication channel between peers, the Pairing API exposes a standard interface and allows for sending and receiving multi-protocol requests over a single pairing. Each SDK uses the same implementation of `core/pairing` (via `@walletconnect/core`) to manage pairings. To run multiple SDKs side-by-side (e.g. Sign and Auth), please refer to the \[Sharing a Core instance] guide. Install the `WalletConnect.Core` nuget package, which implements the Pairing API ```shell theme={null} dotnet add package WalletConnect.Core ``` Once the `WalletConnect.Core` library is installed, create a Metadata object. It will describe your application and define its appearance in a web browser. Then configure the Pair instance with a metadata object you have instantiated. ```csharp theme={null} var metadata = new Metadata() { Name = "my-app", Description = "My app description", Icons = new[] { "https://walletconnect.com/meta/favicon.ico" }, Url = "https://walletconnect.com", } var options = new CoreOptions() { ProjectId = "...", Name = "my-app", } var core = new WalletConnectCore(options); core.Pairing.Configure(metadata); ``` Since `WalletConnectUnity` is a wrapper around `WalletConnectSharp`, usage of the pairing API is identical to `.NET`. Please refer to .NET documentation on how to use Pairing inside `WalletConnectUnity`. #### Package Installation To install packages via OpenUPM, you need to have [Node.js](https://nodejs.org/en/) and [openupm-cli](https://openupm.com/docs/getting-started.html#installing-openupm-cli) installed. Once you have them installed, you can run the following commands: ```bash theme={null} openupm add com.walletconnect.core ``` 1. Open `Advanced Project Settings` from the gear ⚙ menu located at the top right of the Package Manager’s toolbar 2. Add a new scoped registry with the following details: * Name: `OpenUPM` * URL: `https://package.openupm.com` * Scope(s): `com.walletconnect` 3. Press plus ➕ and then `Save` buttons 4. In the Package Manager windows open the add ➕ menu from the toolbar 5. Select `Add package by name...` 6. Enter the package name: * `com.walletconnect.core` 7. Press `Add` button 1. Open the add ➕ menu in the Package Manager’s toolbar 2. Select `Add package from git URL...` 3. Enter the package URL: **WalletConnectUnity Core** ``` https://github.com/WalletConnect/WalletConnectUnity.git?path=Packages/com.walletconnect.core ``` 4. Press `Add` button It's possible to lock the version of the package by adding `#{version}` at the end of the git URL, where `#{version}` is the git tag of the version you want to use. For example, to install version `1.0.1` of WalletConnectUnity Modal, use the following URL: ``` https://github.com/WalletConnect/WalletConnectUnity.git?path=Packages/com.walletconnect.core#core/1.0.1 ``` #### WebGL Due to WebGL's single-threaded nature, certain asynchronous operations like `Task.Run`, `Task.ContinueWith`, `Task.Delay`, and `ConfigureAwait(false)` are not natively supported. To enable these operations in WebGL builds, an additional third-party package, [WebGLThreadingPatcher](https://github.com/VolodymyrBS/WebGLThreadingPatcher), is required. This package modifies the Unity WebGL build to delegate work to the `SynchronizationContext`, allowing these operations to be executed on the same thread without blocking the main application. Please note that all tasks are still executed on a single thread, and any blocking calls will freeze the entire application. The [WebGLThreadingPatcher](https://github.com/VolodymyrBS/WebGLThreadingPatcher) package can be added via git URL: ``` https://github.com/VolodymyrBS/WebGLThreadingPatcher.git ``` #### Initialization 1. Fill in the Project ID and Metadata fields in the `Assets/WalletConnectUnity/Resources/WalletConnectProjectConfig` asset. * If you don't have a Project ID, you can create one at [Reown Dashboard](https://dashboard.reown.com).). * The `Redirect` fields are optional. They are used to redirect the user back to your app after they approve or reject the session. 2. Initialize `WalletConnect` and get reference to the instance of `Core`: ```csharp theme={null} // Initialize singleton await WalletConnect.Instance.InitializeAsync(); // Or handle instancing manually var walletConnectUnity = new WalletConnect(); await walletConnectUnity.InitializeAsync(); var core = WalletConnect.Instance.SignClient.Core; ``` ## Usage The methods listed below are limited to only the public methods of the Pairing API that we recommend you interact with directly. For an exhaustive list, please refer to the spec and/or implementation linked under [Useful Links](https://specs.walletconnect.com/2.0/specs/clients/core/pairing/pairing-methods) above. The keyword `sdkClient` is used here as a placeholder for any WalletConnect SDK that implements the Pairing API (e.g. `signClient`, `authClient`, etc). ```ts theme={null} // Creates a new (inactive) pairing. Returns the URI for a peer to consume via `pair`, as well as the pairing topic. const {topic, uri} = await sdkClient.core.pairing.create() // Pair with a peer's proposed pairing, extracted from the provided `uri` parameter. await sdkClient.core.pairing.pair({ uri: "wc:1b3eda3f4..." }) // Activate a previously created pairing (e.g. after the peer has paired), by providing the pairing topic. await sdkClient.core.pairing.activate({ topic: "1b3eda3f4..." }) // Updates the expiry of an existing pairing, by providing the pairing topic and an `expiry` in seconds (e.g. `60` for one minute from now) await sdkClient.core.pairing.updateExpiry({ topic: "1b3eda3f4...", expiry: 60 }) // Updates a pairing's metadata, by providing the pairing topic and the desired metadata. await sdkClient.core.pairing.updateMetadata({ topic: "1b3eda3f4...", metadata: { name: "MyDapp", ... } }) // Returns an array of all existing pairings. const pairings = sdkClient.core.pairing.getPairings() // Pings a pairing's peer, by providing the pairing topic. await sdkClient.core.pairing.ping({ topic: "1b3eda3f4..." }) // Disconnects/Removes a pairing, by providing the pairing topic. await sdkClient.core.pairing.disconnect({ topic: "1b3eda3f4..." }) ``` #### Listeners for pairing-related events The Pairing API currently emits the following events: * `pairing_ping` * `pairing_delete` * `pairing_expire` Any of these events can be listened for via the standard Node [`EventEmitter` interface](https://nodejs.org/api/events.html#class-eventemitter): ```ts theme={null} sdkClient.core.pairing.events.on("pairing_delete", ({ id, topic }) => { // clean up after the pairing for `topic` was deleted. }); ``` Create an AppMetadata object. It will describe your application and define its appearance in a web browser. Starting from WalletConnect SDK version 1.9.5, the `redirect` field in the `AppMetadata` object is mandatory. Ensure that the provided value matches your app's URL scheme to prevent redirection-related issues. Then configure the Pair instance with a metadata object you have instantiated. ```swift theme={null} let metadata = AppMetadata(name: , description: , url: , icons: <[String]>, redirect: AppMetadata.Redirect(native: "example://", universal: nil)) Pair.configure(metadata: metadata) ``` #### Pairing Wallet Usage In pair wallet with dapp, the user needs to scan a QR code or open a deep link generated by dapp, then instantiate `WalletConnectURI` from the scanned QR code string and call the `pair()` function as follows. ```swift theme={null} let uri WalletConnectURI(string: ) try! await Pair.instance.pair(uri: uri) ``` Now wallet and a dapp have a secure communication channel that will be used by top level APIs. #### Pairing Dapp Usage In order to pair dapp and a wallet, dapp needs to generate and share a uri with wallet. To generate a uri call `create()` function on Pair instance as follows. ```swift theme={null} let uri = try await Pair.instance.create() ``` Now you can share the uri with the wallet. #### **Create Pairing** ```kotlin theme={null} val pairing: Pairing? = CoreClient.Pairing.create() { error -> } ``` When first establishing a pairing with a Peer, call `CoreClient.Pairing.create`. This will try and generate a new pairing with a URI parameter that can be used to establish a connection with the other Peer as well as other meta data related to the pairing. # #### **Pair Clients** ```kotlin theme={null} val pairingParams = Core.Params.Pair(pairingUri) CoreClient.Pairing.pair(pairingParams) { error -> } ``` To pair the wallet with the Dapp, call the CoreClient.Pairing's pair function which needs a `Core.Params.Pair` parameter. `Core.Params.Pair` is where the WC Uri will be passed. # #### **Get List of Active Pairings** ```kotlin theme={null} val listOfActivePairings: List = CoreClient.Pairing.getPairings() ``` To get a list of the most current active pairings, call `CoreClient.Pairing.getPairings()` which will return a list of type `Core.Model.Pairing`. # #### **Disconnect a Pairing** ```kotlin theme={null} CoreClient.Pairing.disconnect(topic = /*Pairing topic*/") { error -> } ``` To disconnect from a pairing, just pass the topic of the pairing to disconnect from (use `getPairings()` to get a list of all active pairings and their topics). The methods listed below are limited to only the public methods of the Pairing API that we recommend you interact with directly. For an exhaustive list, please refer to the spec and/or implementation linked under [Useful Links](https://specs.walletconnect.com/2.0/specs/clients/core/pairing/pairing-methods) above. The keyword `sdkClient` is used here as a placeholder for any WalletConnect SDK that implements the Pairing API (e.g. `signClient`, `authClient`, etc). ```ts theme={null} // Creates a new (inactive) pairing. Returns the URI for a peer to consume via `pair`, as well as the pairing topic. const {topic, uri} = await sdkClient.core.pairing.create() // Pair with a peer's proposed pairing, extracted from the provided `uri` parameter. await sdkClient.core.pairing.pair({ uri: "wc:1b3eda3f4..." }) // Activate a previously created pairing (e.g. after the peer has paired), by providing the pairing topic. await sdkClient.core.pairing.activate({ topic: "1b3eda3f4..." }) // Updates the expiry of an existing pairing, by providing the pairing topic and an `expiry` in seconds (e.g. `60` for one minute from now) await sdkClient.core.pairing.updateExpiry({ topic: "1b3eda3f4...", expiry: 60 }) // Updates a pairing's metadata, by providing the pairing topic and the desired metadata. await sdkClient.core.pairing.updateMetadata({ topic: "1b3eda3f4...", metadata: { name: "MyDapp", ... } }) // Returns an array of all existing pairings. const pairings = sdkClient.core.pairing.getPairings() // Pings a pairing's peer, by providing the pairing topic. await sdkClient.core.pairing.ping({ topic: "1b3eda3f4..." }) // Disconnects/Removes a pairing, by providing the pairing topic. await sdkClient.core.pairing.disconnect({ topic: "1b3eda3f4..." }) ``` #### Listeners for pairing-related events The Pairing API currently emits the following events: * `pairing_ping` * `pairing_delete` * `pairing_expire` Any of these events can be listened for via the standard Node [`EventEmitter` interface](https://nodejs.org/api/events.html#class-eventemitter): ```ts theme={null} sdkClient.core.pairing.events.on("pairing_delete", ({ id, topic }) => { // clean up after the pairing for `topic` was deleted. }); ``` #### Pairing Wallet Usage When paring a wallet with a dapp, the user needs to scan a QR code or open a deep link generated by the dapp. Grab the string from the scanned QR code string or from the deep link and call the `Pair()` function as follows. ```csharp theme={null} var uri = "..."; PairingStruct pairingData = await core.Pairing.Pair(uri); ``` Now the wallet and a dapp have a secure communication channel that will be used by top level APIs. #### Pairing Dapp Usage In order to pair dapp and a wallet, dapp needs to generate and share a uri with wallet. To generate a uri call `create()` function on Pair instance as follows. ```csharp theme={null} var pairData = await core.Pairing.Create(); string topic = pairData.Topic; string uri = pairData.Uri; ``` Now you can share the uri with the wallet either through a QR Code or by using a deep link. #### Message Sending / Handling Once a wallet and dapp has been paired, they can send messages securely to the pairing topic. Requests can be received from the dapp by handling the message callback in the `MessageHandler` module. ```csharp theme={null} core.MessageHandler.MessageEventHandler() .FilterRequests(r => r.Topic == pairingData.Topic) .OnRequest += async delegate(RequestEventArgs eventArgs) { Console.WriteLine(eventArgs.Request); eventArgs.Response = new MyResponse() { // ... }; }; ``` A response can be sent for any request by setting the `Response` field in the `eventArgs` parameter. Receiving responses is handled the same way, but instead of the `OnRequest` event you would use the `OnResponse` event. Request, Responses and Errors can be sent using the `SendRequest` , `SendResult` and `SendError` functions in the `MessageHandler` module. ```csharp theme={null} long id = await core.MessageHandler.SendRequest(pairingTopic, data); ``` # Relay Client Source: https://docs.reown.com/advanced/api/core/relay Relay client provides transport layer for Sign, Auth and Chat SDKs. You can configure it once and every SDK will transport protocol messages via the same instance of a relay client with only one opened WebSocket connection. The Relay API can be accessed through the Core Client Before using Sign or Auth SDK, it is necessary to configure a shared Networking Client instance. Set a project ID generated when starting a project on Reown Dashboard and SocketFactory instance. WalletConnect Swift SDK does not depend on any WebSocket library. SocketFactory parameter allows you to pass your own implementation of WebSocket connection. Here's an example of WebSocketFactory implementation using Starscream v3 ```swift theme={null} import Starscream extension WebSocket: WebSocketConnecting { } struct SocketFactory: WebSocketFactory { func create(with url: URL) -> WebSocketConnecting { return WebSocket(url: url) } } ``` Please note that if you have made changes to the list of **Allowed Domains** in the **Reown Dashboard**, then you may encounter an error with the connection if you use **Starscream** or any other socket client. For example, the native implementation of **Starscream** will use the `relay.walletconnect.com` as an `Origin` parameter if not provided, which will be missing from the list of **Allowed Domains**. The solution to this could be the inclusion of the `relay.walletconnect.com` in the **Allowed Domains**, corresponding changes in the socket client implementation, or following changes in the `WebSocketFactory`. Create and register App Group Identifier in [Apple Developer Center](https://developer.apple.com/account/resources/identifiers/list/applicationGroup) if needed and provide it during Networking client configuration. ```swift theme={null} import Starscream extension WebSocket: WebSocketConnecting { } struct DefaultSocketFactory: WebSocketFactory { func create(with url: URL) -> WebSocketConnecting { var urlRequest = URLRequest(url: url) urlRequest.addValue("allowed.domain.com", forHTTPHeaderField: "Origin") return WebSocket(request: urlRequest) } } ``` #### Networking client configuration ```swift theme={null} Networking.configure(groupIdentifier: , projectId: , socketFactory: SocketFactory()) ``` `groupIdentifier` - App group identifier, created on [Apple Developer Center](https://developer.apple.com/account/resources/identifiers/list/applicationGroup). Enables to share keychain items between the Notify SDK and a UNNotificationServiceExtension to receive and decrypt push notifications. #### WebSocket Connection By default WebSocket connection is handled internally by the SDK. That means that WebSocket will be safely disconnected when apps go to background and it will connect back when app reaches foreground. But if it is not expected for your app and you want to handle socket connection manually you can do it as follows: 1. set socketConnectionType for manual ```swift theme={null} Networking.configure(projectId: , socketFactory: SocketFactory(), socketConnectionType: .manual) ``` 2. control socket connection: ```swift theme={null} try Networking.instance.connect() ``` ```swift theme={null} try Networking.instance.disconnect() ``` #### WebSocket connection control There are two connection types, Automatic and Manual. Automatic connection type enables SDK to control WebSocket connection internally. Meaning, WebSocket connection is closed when app goes to the background and is opened when app goes to the foreground. Manual connection type enables developers to control WebSocket connection. ```kotlin theme={null} CoreClient.initialize(projectId = projectId, connectionType = ConnectionType.MANUAL, application = application) CoreClient.Relay.connect() { error -> /*Error when wrong connection type is in use*/ } CoreClient.Relay.disconnect() { error -> /*Error when wrong connection type is in use*/ } ``` # Shared Core Instance Source: https://docs.reown.com/advanced/api/core/shared-core The following content are only available for JavaScript. WalletConnect's SDKs are designed to share common logic and resources via the `@walletconnect/core` package. **If you intend to leverage multiple SDKs together (e.g. Sign + Auth), it is highly recommended to instantiate a single `Core` instance and pass it to the relevant SDKs.** This avoids each SDK creating its own `Core` instance, and thus duplicating computation, memory allocation, event listeners etc. In the following example, we first instantiate a `Core` instance, and then proceed to instantiate both the Sign and Auth SDK with this shared `Core`: ```ts theme={null} import { Core } from "@walletconnect/core"; import SignClient from "@walletconnect/sign-client"; import { AuthClient } from "@walletconnect/auth-client"; // First instantiate a separate `Core` instance. const core = new Core({ projectId: "", }); const metadata = { name: "Example Dapp", description: "Example Dapp", url: "#", icons: ["https://walletconnect.com/walletconnect-logo.png"], }; // Pass `core` to the SignClient on init. const signClient = await SignClient.init({ core, metadata }); // Pass `core` to the AuthClient on init. const authClient = await AuthClient.init({ core, metadata }); ``` # Dapp Usage Source: https://docs.reown.com/advanced/api/sign/dapp-usage ## Implementation This library is compatible with Node.js, browsers and React Native applications (Node.js modules require polyfills for React Native). `@walletconnect/modal` is now deprecated. Please use `@reown/appkit` instead. For migration guidance, see the [WalletConnect Modal to Reown AppKit Core migration guide](/appkit/upgrade/wcm). For an example implementation, please refer to our `react-dapp-v2` [example](https://github.com/WalletConnect/web-examples/tree/main/advanced/dapps/react-dapp-v2). #### Install Packages ```bash npm theme={null} npm install @walletconnect/sign-client ``` ```bash Yarn theme={null} yarn add @walletconnect/sign-client ``` ```bash Bun theme={null} bun add @walletconnect/sign-client ``` ```bash pnpm theme={null} pnpm add @walletconnect/sign-client ``` Dapps will also need to install Reown AppKit for the UI. ```bash npm theme={null} npm install @reown/appkit ``` ```bash Yarn theme={null} yarn add @reown/appkit ``` ```bash Bun theme={null} bun add @reown/appkit ``` ```bash pnpm theme={null} pnpm add @reown/appkit ``` #### Create a Session **1. Initiate your WalletConnect client with the relay server, using [your Project ID](/cloud/relay).** ```javascript theme={null} import SignClient from "@walletconnect/sign-client"; const signClient = await SignClient.init({ projectId: "", // optional parameters relayUrl: "", metadata: { name: "Example Dapp", description: "Example Dapp", url: "#", icons: ["https://walletconnect.com/walletconnect-logo.png"], }, }); ``` **2. Add listeners for desired `SignClient` events.** To listen to pairing-related events, please follow the guidance for [Pairing API event listeners](https://specs.walletconnect.com/2.0/specs/clients/core/pairing/pairing-api). ```javascript theme={null} signClient.on("session_event", ({ event }) => { // Handle session events, such as "chainChanged", "accountsChanged", etc. }); signClient.on("session_update", ({ topic, params }) => { const { namespaces } = params; const _session = signClient.session.get(topic); // Overwrite the `namespaces` of the existing session with the incoming one. const updatedSession = { ..._session, namespaces }; // Integrate the updated session state into your dapp state. onSessionUpdate(updatedSession); }); signClient.on("session_delete", () => { // Session was deleted -> reset the dapp state, clean up from user session, etc. }); ``` **3. Create a new AppKit instance.** ```javascript theme={null} import { createAppKit } from "@reown/appkit/core"; import { mainnet } from "@reown/appkit/networks"; const modal = createAppKit({ projectId: "", networks: [mainnet], manualWCControl: true }); ``` **4. Connect the application and specify session permissions.** ```javascript theme={null} try { const { uri, approval } = await signClient.connect({ // Optionally: pass a known prior pairing (e.g. from `signClient.core.pairing.getPairings()`) to skip the `uri` step. pairingTopic: pairing?.topic, // Provide the namespaces and chains (e.g. `eip155` for EVM-based chains) we want to use in this session. requiredNamespaces: { eip155: { methods: [ "eth_sendTransaction", "eth_signTransaction", "eth_sign", "personal_sign", "eth_signTypedData", ], chains: ["eip155:1"], events: ["chainChanged", "accountsChanged"], }, }, }); // Open QRCode modal if a URI was returned (i.e. we're not connecting an existing pairing). if (uri) { modal.open({ uri }); // Await session approval from the wallet. const session = await approval(); // Handle the returned session (e.g. update UI to "connected" state). // * You will need to create this function * onSessionConnect(session); // Close the QRCode modal in case it was open. modal.close(); } } catch (e) { console.error(e); } ``` #### Session Authenticate with ReCaps The authenticate() method enhances the WalletConnect protocol, offering EVM dApps a sophisticated mechanism to request wallet authentication and simultaneously establish a session. This innovative approach not only authenticates the user but also facilitates a seamless session creation, integrating the capabilities defined by ERC-5573, also known as ReCaps. ReCaps extend the SIWE protocol, enabling users to give informed consent for dApps to exercise scoped capabilities on their behalf. This consent mechanism is crucial for authorizing a dApp to perform actions or access resources, thus ensuring security and trust in dApp interactions. These scoped capabilities are specified through ReCap URIs in the resources field of the AuthRequestParams, which translate to human-readable consent in the SIWE message, detailing the actions a dApp is authorized to undertake. To initiate an authentication and authorization request, a dApp invokes the authenticate() method, passing in parameters that include desired capabilities as outlined in EIP-5573. The method generates a pairing URI for user interaction, facilitating a streamlined authentication and consent process. Example of initiating an authentication request with ReCaps: ```typescript theme={null} const { uri, response } = await signClient.authenticate({ chains: ['eip155:1', 'eip155:2'], // chains your dapp requests authentication for domain: 'localhost', // your domain uri: 'http://localhost/login', // uri nonce: '1239812982', // random nonce methods: ['personal_sign', 'eth_chainId', 'eth_signTypedData_v4'], // the methods you wish to use resources: ['https://example.com'] // any resources relevant to the connection }) // Present the URI to users as QR code to be able to connect with a wallet ... // wait for response const result = await response() // after a Wallet establishes a connection response will resolve with auths ( authentication objects ) & the established session const { auths, session } = result; // now you can send requests to that session ``` #### Making Requests Once the session has been established successfully, you can start making JSON-RPC requests to be approved and signed by the wallet: ```javascript theme={null} const result = await signClient.request({ topic: session.topic, chainId: "eip155:1", request: { method: "personal_sign", params: [ "0x7468697320697320612074657374206d65737361676520746f206265207369676e6564", "0x1d85568eEAbad713fBB5293B45ea066e552A90De", ], }, }); ``` > For more information on available JSON-RPC requests, see the [JSON-RPC reference](/advanced/multichain/rpc-reference/ethereum-rpc). ### Restoring a Session Sessions are saved to localstorage, meaning that even if the web page is reloaded, the session can still be retrieved, as demonstrated in the following code: ```ts theme={null} const lastKeyIndex = signClient.session.getAll().length - 1; const lastSession = signClient.session.getAll()[lastKeyIndex]; ``` #### Finding a Specific Session If you need to find a specific session, you can do so by passing in a known `requiredNamespace` and calling `find`. ```ts theme={null} const specificSession = _client.find({ requiredNamespaces: { eip155: { methods: [ "eth_sendTransaction", "eth_signTransaction", "eth_sign", "personal_sign", "eth_signTypedData", ], chains: ["eip155:5"], events: ["chainChanged", "accountsChanged"], }, }, }); ``` #### Configure Networking and Pair clients Make sure that you properly configure Networking and Pair Clients first. * [Networking](/advanced/api/core/relay) * [Pairing](/advanced/api/core/pairing) #### Configure Sign Client In order to initialize a client, call a `configure` method on the Sign instance ```swift theme={null} Sign.configure(crypto: CryptoProvider) ``` #### Subscribe for Sign publishers When your `Sign` instance receives requests from a peer it will publish related event. So you should set subscription to handle them. To track sessions subscribe to `sessionsPublisher` publisher ```swift theme={null} Sign.instance.sessionsPublisher .receive(on: DispatchQueue.main) .sink { [unowned self] (sessions: [Session]) in // reload UI }.store(in: &publishers) ``` Following publishers are available to subscribe: ```swift theme={null} public var sessionsPublisher: AnyPublisher<[Session], Never> public var sessionProposalPublisher: AnyPublisher public var sessionRequestPublisher: AnyPublisher public var socketConnectionStatusPublisher: AnyPublisher public var sessionSettlePublisher: AnyPublisher public var sessionDeletePublisher: AnyPublisher<(String, Reason), Never> public var sessionResponsePublisher: AnyPublisher public var sessionRejectionPublisher: AnyPublisher<(Session.Proposal, Reason), Never> public var sessionUpdatePublisher: AnyPublisher<(sessionTopic: String, namespaces: [String : SessionNamespace]), Never> public var sessionEventPublisher: AnyPublisher<(event: Session.Event, sessionTopic: String, chainId: Blockchain?), Never> public var sessionUpdateExpiryPublisher: AnyPublisher<(sessionTopic: String, expiry: Date), Never> ``` #### Connect Clients 1. Prepare namespaces that constraints minimal requirements for your dApp: ```Swift theme={null} let methods: Set = ["eth_sendTransaction", "personal_sign", "eth_signTypedData"] let blockchains: Set = [Blockchain("eip155:1")!, Blockchain("eip155:137")!] let namespaces: [String: ProposalNamespace] = ["eip155": ProposalNamespace(chains: blockchains, methods: methods, events: []] ``` To learn more on namespaces, check out our [specs](https://specs.walletconnect.com/2.0/specs/clients/sign/namespaces). 2. Your App should generate a pairing URI and share it with a wallet. Uri can be presented as a QR code or sent via a universal link. Wallet begins subscribing for session proposals after receiving URI. In order to create a pairing and send a session proposal, you need to call the following: ```Swift theme={null} let uri = try await Sign.instance.connect(requiredNamespaces: namespaces, topic: uri.topic) ``` #### Session Authenticate with ReCaps The authenticate() method enhances the WalletConnect protocol, offering EVM dApps a sophisticated mechanism to request wallet authentication and simultaneously establish a session. This innovative approach not only authenticates the user but also facilitates a seamless session creation, integrating the capabilities defined by ERC-5573, also known as ReCaps. ReCaps extend the SIWE protocol, enabling users to give informed consent for dApps to exercise scoped capabilities on their behalf. This consent mechanism is crucial for authorizing a dApp to perform actions or access resources, thus ensuring security and trust in dApp interactions. These scoped capabilities are specified through ReCap URIs in the resources field of the AuthRequestParams, which translate to human-readable consent in the SIWE message, detailing the actions a dApp is authorized to undertake. To initiate an authentication and authorization request, a dApp invokes the authenticate() method, passing in parameters that include desired capabilities as outlined in EIP-5573. The method generates a pairing URI for user interaction, facilitating a streamlined authentication and consent process. Example of initiating an authentication request with ReCaps: ```swift theme={null} func initiateAuthentication() { Task { do { let authParams = AuthRequestParams.stub() // Customize your AuthRequestParams as needed let uri = try await Sign.instance.authenticate(authParams) // Present the URI to the user, e.g., show a QR code or send a deep link presentAuthenticationURI(uri) } catch { print("Failed to initiate authentication request: \(error)") } } } ``` ##### Subscribe to Authentication Responses Once you have initiated an authentication request, you need to listen for responses from wallets. Responses will indicate whether the authentication request was approved or rejected. Use the authResponsePublisher to subscribe to these events. Example subscription to authentication responses: ```swift theme={null} Sign.instance.authResponsePublisher .receive(on: DispatchQueue.main) .sink { response in switch response.result { case .success(let (session, _)): if let session = session { // Authentication successful, session established handleSuccessfulAuthentication(session) } else { // Authentication successful, but no session created (SIWE-only flow) handleSuccessfulAuthenticationWithoutSession() } case .failure(let error): // Authentication request was rejected or failed handleAuthenticationFailure(error) } } .store(in: &subscriptions) ``` In this setup, the authResponsePublisher notifies your dApp of the outcome of the authentication request. Your dApp can then proceed based on whether the authentication was successful, rejected, or failed due to an error. Example of AuthRequestParams: ```swift theme={null} extension AuthRequestParams { static func stub( domain: String = "yourDappDomain.com", chains: [String] = ["eip155:1", "eip155:137"], nonce: String = "uniqueNonce", uri: String = "https://yourDappDomain.com/login", statement: String? = "I accept the Terms of Service: https://yourDappDomain.com/tos", resources: [String]? = nil, // here your dapp may request authorization with recaps methods: [String]? = ["personal_sign", "eth_sendTransaction"] ) -> AuthRequestParams { return try! AuthRequestParams( domain: domain, chains: chains, nonce: nonce, uri: uri, statement: statement, resources: resources, methods: methods ) } } ``` #### Send Request to the Wallet Once the session has been established `sessionSettlePublisher` will publish an event. Your dApp can start requesting wallet now. ```Swift theme={null} let method = "personal_sign" let walletAddress = "0x9b2055d370f73ec7d8a03e965129118dc8f5bf83" // This should match the connected address let requestParams = AnyCodable(["0x4d7920656d61696c206973206a6f686e40646f652e636f6d202d2031363533333933373535313531", walletAddress]) let request = Request(topic: session.topic, method: method, params: requestParams, chainId: Blockchain(chainId)!) try await Sign.instance.request(params: request) ``` When wallet respond `sessionResponsePublisher` will publish an event so you can verify the response. #### Extending a Session By default, session lifetime is set for 7 days and after that time user's session will expire. But if you consider that a session should be extended you can call: ```Swift theme={null} try await Sign.instance.extend(topic: session.topic) ``` Above method will extend a user's session to a week. #### Where to go from here * Try our [Example dApp](https://github.com/reown-com/reown-swift/tree/main/Example) that is part of [WalletConnectSwiftV2 repository](https://github.com/reown-com/reown-swift). * Build API documentation in XCode: go to Product -> Build Documentation #### **Initialization** ```kotlin theme={null} val projectId = "" // Get Project ID at https://dashboard.reown.com/ val connectionType = ConnectionType.AUTOMATIC or ConnectionType.MANUAL val appMetaData = Core.Model.AppMetaData( name = "Dapp Name", description = "Dapp Description", url = "Dapp URL", icons = /*list of icon url strings*/, redirect = "kotlin-dapp-wc:/request" // Custom Redirect URI ) CoreClient.initialize(projectId = projectId, connectionType = connectionType, application = this, metaData = appMetaData) val init = Sign.Params.Init(core = CoreClient) SignClient.initialize(init) { error -> // Error will be thrown if there's an issue during initialization } ``` The Dapp client is responsible for initiating the connection with wallets and defining the required namespaces (CAIP-2) from the Wallet and is also in charge of sending requests. To initialize the Sign client, create a `Sign.Params.Init` object in the Android Application class with the Core Client. The `Sign.Params.Init` object will then be passed to the `SignClient` initialize function. # # **Dapp** #### **SignClient.DappDelegate** ```kotlin theme={null} val dappDelegate = object : SignClient.DappDelegate { override fun onSessionApproved(approvedSession: Sign.Model.ApprovedSession) { // Triggered when Dapp receives the session approval from wallet } override fun onSessionRejected(rejectedSession: Sign.Model.RejectedSession) { // Triggered when Dapp receives the session rejection from wallet } fun onSessionAuthenticateResponse(sessionAuthenticateResponse: Sign.Model.SessionAuthenticateResponse) { // Triggered when Dapp receives the session authenticate response from wallet } override fun onSessionUpdate(updatedSession: Sign.Model.UpdatedSession) { // Triggered when Dapp receives the session update from wallet } override fun onSessionExtend(session: Sign.Model.Session) { // Triggered when Dapp receives the session extend from wallet } override fun onSessionEvent(sessionEvent: Sign.Model.SessionEvent) { // Triggered when the peer emits events that match the list of events agreed upon session settlement } override fun onSessionDelete(deletedSession: Sign.Model.DeletedSession) { // Triggered when Dapp receives the session delete from wallet } override fun onSessionRequestResponse(response: Sign.Model.SessionRequestResponse) { // Triggered when Dapp receives the session request response from wallet } override fun onProposalExpired(proposal: Modal.Model.ExpiredProposal) { // Triggered when a proposal becomes expired } override fun onRequestExpired(request: Modal.Model.ExpiredRequest) { // Triggered when a request becomes expired } override fun onConnectionStateChange(state: Sign.Model.ConnectionState) { //Triggered whenever the connection state is changed } override fun onError(error: Sign.Model.Error) { // Triggered whenever there is an issue inside the SDK } } SignClient.setDappDelegate(dappDelegate) ``` The SignClient needs a `SignClient.DappDelegate` passed to it for it to be able to expose asynchronously updates sent from the Wallet. # #### **Connect** ```kotlin theme={null} val namespace: String = /*Namespace identifier, see for reference: https://github.com/ChainAgnostic/CAIPs/blob/master/CAIPs/caip-2.md#syntax*/ val chains: List = /*List of chains that wallet will be requested for*/ val methods: List = /*List of methods that wallet will be requested for*/ val events: List = /*List of events that wallet will be requested for*/ val requiredNamespaces: Map = mapOf(namespace, Sign.Model.Namespaces.Proposal(accounts, methods, events)) /*Required namespaces to setup a session*/ val optionalNamespaces: Map = mapOf(namespace, Sign.Model.Namespaces.Proposal(accounts, methods, events)) /*Optional namespaces to setup a session*/ val pairing: Core.Model.Pairing = /*Either an active or inactive pairing*/ val connectParams = Sign.Params.Connect(requiredNamespaces, optionalNamespaces, pairing) fun SignClient.connect(connectParams, { onSuccess -> /*callback that returns letting you know that you have successfully initiated connecting*/ }, { error -> /*callback for error while trying to initiate a connection with a peer*/ } ) ``` More about optional and required namespaces can be found [here](https://github.com/ChainAgnostic/CAIPs/blob/master/CAIPs/caip-25.md) # #### **Authenticate** The authenticate() method enhances the WalletConnect protocol, offering EVM dApps a sophisticated mechanism to request wallet authentication and simultaneously establish a session. This innovative approach not only authenticates the user but also facilitates a seamless session creation, integrating the capabilities defined by ERC-5573, also known as ReCaps. Capabilities are specified through ReCap URIs in the resources field of the Sign.Params.Authenticate, which translate to human-readable consent in the SIWE message, detailing the actions a dApp is authorized to undertake. To initiate an authentication and authorization request, a dApp invokes the authenticate() method, passing in parameters that include desired capabilities as outlined in EIP-5573. The method generates a pairing URI for user interaction, facilitating a streamlined authentication and consent process. Example of initiating an authentication request with ReCaps: ```kotlin theme={null} val authenticateParams = Sign.Params.Authenticate( domain = "your.domain", chains = listof("eip155:1", "eip155:137"), methods = listOf("personal_sign", "eth_signTypedData"), uri = "https://yourDappDomain.com/login", nonce = randomNonce, statement = "Sign in with wallet.", resources = null, // here your dapp may request authorization with recaps ) SignClient.authenticate(authenticateParams, onSuccess = { url -> //Handle authentication URI. Show as a QR code a send via deeplink }, onError = { error -> //Handle error } ) ``` Once you have sent an authentication request, await for responses from wallets. Responses will indicate whether the authentication request was approved or rejected. Use the onSessionAuthenticateResponse callback to receive a response: ```kotlin theme={null} fun onSessionAuthenticateResponse(sessionAuthenticateResponse: Sign.Model.SessionAuthenticateResponse) { // Triggered when Dapp receives the session authenticate response from wallet if (sessionAuthenticateResponse is Sign.Model.SessionAuthenticateResponse.Result) { if (sessionAuthenticateResponse.session != null) { // Authentication successful, session established } else { // Authentication successful, but no session created (SIWE-only flow) } } else { // Authentication request was rejected or failed } } ``` # #### **Get List of Settled Sessions** ```kotlin theme={null} SignClient.getListOfSettledSessions() ``` To get a list of the most current settled sessions, call `SignClient.getListOfSettledSessions()` which will return a list of type `Session`. # #### **Get list of pending session requests for a topic** ```kotlin theme={null} SignClient.getPendingRequests(topic: String) ``` To get a list of pending session requests for a topic, call `SignClient.getPendingRequests()` and pass a topic which will return a `PendingRequest` object containing requestId, method, chainIs and params for pending request. #### Initialization To create an instance of `SignClient`, you need to pass in the core and metadata parameters. ```dart theme={null} SignClient signClient = await SignClient.createInstance( relayUrl: 'wss://relay.walletconnect.com', // The relay websocket URL, leave blank to use the default projectId: '123', metadata: PairingMetadata( name: 'dapp (Requester)', description: 'A dapp that can request that transactions be signed', url: 'https://walletconnect.com', icons: ['https://avatars.githubusercontent.com/u/37784886'], ), ); ``` #### Connection To connect with specific parameters and display the returned URI, use `connect` with the required namespaces. ```dart theme={null} ConnectResponse response = await signClient.connect( requiredNamespaces: { 'eip155': RequiredNamespace( chains: ['eip155:1'], // Ethereum chain methods: ['eth_signTransaction'], // Requestable Methods ), 'kadena': RequiredNamespace( chains: ['kadena:mainnet01'], // Kadena chain methods: ['kadena_quicksign_v1'], // Requestable Methods ), } ); Uri? uri = response.uri; ``` You will use that URI to display a QR code or handle a deep link. We recommend not handling deep linking yourself. If you want to deep link, then use the [walletconnect\_modal\_flutter](https://pub.dev/packages/walletconnect_modal_flutter) package. #### Session Data Once you've displayed the URI you can wait for the future and hide the QR code once you've received session data. ```dart theme={null} final SessionData session = await response.session.future; ``` #### Request Signatures Once the session had been created, you can request signatures. ```dart theme={null} final signature = await signClient.request( topic: session.topic, chainId: 'eip155:1', request: SessionRequestParams( method: 'eth_signTransaction', params: 'json serializable parameters', ), ); ``` #### Respond to Events You can also respond to events from the wallet, like chain changed, using `onSessionEvent` and `registerEventHandler`. ```dart theme={null} signClient.onSessionEvent.subscribe((SessionEvent? session) { // Do something with the event }); signClient.registerEventHandler( namespace: 'kadena', event: 'kadena_transaction_updated', ); ``` # To Test Run tests using `flutter test`. Expected flutter version is: >`3.3.10` # Useful Commands * `flutter pub run build_runner build --delete-conflicting-outputs` - Regenerates JSON Generators * `flutter doctor -v` - get paths of everything installed. * `flutter pub get` * `flutter upgrade` * `flutter clean` * `flutter pub cache clean` * `flutter pub deps` * `flutter pub run dependency_validator` - show unused dependencies and more * `dart format lib/* -l 120` * `flutter analyze` #### Setup First you must setup `SignClientOptions` which stores both the `ProjectId` and `Metadata`. You may also optionally specify the storage module to use. By default, the `FileSystemStorage` module is used if none is specified. ```csharp theme={null} var dappOptions = new SignClientOptions() { ProjectId = "39f3dc0a2c604ec9885799f9fc5feb7c", Metadata = new Metadata() { Description = "An example dapp to showcase WalletConnectSharpv2", Icons = new[] { "https://walletconnect.com/meta/favicon.ico" }, Name = "WalletConnectSharpv2 Dapp Example", Url = "https://walletconnect.com" }, // Uncomment to disable persistent storage // Storage = new InMemoryStorage() }; ``` Then, you must setup the `ConnectOptions` which define what blockchain, RPC methods and events your dapp will use. *C# Constructor* ```csharp theme={null} var dappConnectOptions = new ConnectOptions() { RequiredNamespaces = new RequiredNamespaces() { { "eip155", new RequiredNamespace() { Methods = new[] { "eth_sendTransaction", "eth_signTransaction", "eth_sign", "personal_sign", "eth_signTypedData", }, Chains = new[] { "eip155:1" }, Events = new[] { "chainChanged", "accountsChanged", } } } } }; ``` *Builder Functions Style* ```csharp theme={null} var dappConnectOptions1 = new ConnectOptions() .RequireNamespace("eip155", new RequiredNamespace() .WithMethod("eth_sendTransaction") .WithMethod("eth_signTransaction") .WithMethod("eth_sign") .WithMethod("personal_sign") .WithMethod("eth_signTypedData") .WithChain("eip155:1") .WithEvent("chainChanged") .WithEvent("accountsChanged") ); ``` With both options defined, you can initialize and connect the SDK. ```csharp theme={null} var dappClient = await WalletConnectSignClient.Init(dappOptions); var connectData = await dappClient.Connect(dappConnectOptions); ``` You can grab the `Uri` for the connection request from `connectData`. ```csharp theme={null} ExampleShowQRCode(connectData.Uri); ``` Then await connection approval using the `Approval` Task object. ```csharp theme={null} Task sessionConnectTask = connectData.Approval; SessionStruct sessionData = await sessionConnectTask; // or // SessionStruct sessionData = await connectData.Approval; ``` This `Task` will return the `SessionStruct` when the session was approved, or throw an exception when the session request has either * Timed out * Been Rejected #### Connected Address To get the currently connected address, use the following function ```csharp theme={null} public class Caip25Address { public string Address; public string ChainId; } public Caip25Address GetCurrentAddress(string chain) { if (string.IsNullOrWhiteSpace(chain)) return null; var defaultNamespace = currentSession.Namespaces[chain]; if (defaultNamespace.Accounts.Length == 0) return null; var fullAddress = defaultNamespace.Accounts[0]; var addressParts = fullAddress.Split(":"); var address = addressParts[2]; var chainId = string.Join(':', addressParts.Take(2)); return new Caip25Address() { Address = address, ChainId = chainId, }; } public Caip25Address GetCurrentAddress() { var currentSession = dappClient.Session.Get(dappClient.Session.Keys[0]); var defaultChain = currentSession.Namespaces.Keys.FirstOrDefault(); if (string.IsNullOrWhiteSpace(defaultChain)) return null; return GetCurrentAddress(defaultChain); } ``` #### WalletConnect Methods All sign methods require the `topic` of the session to be given. This can be found in the `SessionStruct` object given when a session has been given approval by the user. ```csharp theme={null} var sessionTopic = sessionData.Topic; ``` ##### Update Session Update a session, adding/removing additional namespaces in the given topic. ```csharp theme={null} var newNamespaces = new Namespaces(...); var request = await dappClient.UpdateSession(sessionTopic, newNamespaces); await request.Acknowledged(); ``` ##### Extend Session Extend a session's expiry time so the session remains open ```csharp theme={null} var request = await dappClient.Extend(sessionTopic); await request.Acknowledged(); ``` ##### Ping Send a ping to the session ```csharp theme={null} var request = await dappClient.Ping(sessionTopic); await request.Acknowledged(); ``` #### Session Requests Sending session requests as a dapp requires to build the request **and** response classes that the session request `params` will be structured. C# is a statically typed language, so these types must be given whenever you do a session request (or do any querying for session requests). Currently, **WalletConnectSharp does not automatically assume the object type for `params` is an array**. This is very important, since most EVM RPC requests have `params` as an array type. **Use `List` to workaround this**. For example, for `eth_sendTransaction`, use `List` instead of `Transaction`. Newtonsoft.Json is used for JSON serialization/deserialization, therefore you can use Newtonsoft.Json attributes when defining fields in your request/response classes. ##### Building a Request type Create a class for the request and populate it with the JSON properties the request object has. For this example, we will use `eth_sendTransaction` The `params` field for `eth_sendTransaction` has the object type ```csharp theme={null} using Newtonsoft.Json; public class Transaction { public string from; // Newtonsoft.Json attributes can be used [JsonProperty("to")] public string To; [JsonProperty("gas", NullValueHandling = NullValueHandling.Ignore)] public string Gas; // Properties have limited support [JsonProperty("gasPrice", NullValueHandling = NullValueHandling.Ignore)] public string GasPrice { get; set; } [JsonProperty("value")] public string Value { get; set; } [JsonProperty("data", NullValueHandling = NullValueHandling.Ignore)] public string Data { get; set; } = "0x"; } ``` [the `params` field is an array of this object](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_sendtransaction) ```json theme={null} params: [ { from: "0xb60e8dd61c5d32be8058bb8eb970870f07233155", to: "0xd46e8dd67c5d32be8058bb8eb970870f07244567", gas: "0x76c0", // 30400 gasPrice: "0x9184e72a000", // 10000000000000 value: "0x9184e72a", // 2441406250 data: "0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675", }, ] ``` Now, let's define the actual request class we'll use in `dappClient.Request` ```csharp theme={null} [RpcMethod("eth_sendTransaction"), RpcRequestOptions(Clock.ONE_MINUTE, 99997)] public class EthSendTransaction : List { public EthSendTransaction(params Transaction[] transactions) : base(transactions) { } } ``` The `RpcMethod` class attributes defines the rpc method this request uses. The `RpcRequestOptions` class attributes define the expiry time and tag attached to the request. **Both of these attributes are required** We use `List` since the `params` field for `eth_sendTransaction` is actually sent as an object array. If the `params` field was a normal object, then we could use `Transaction` or define the fields directly into this class. ##### Sending a request The response type for `eth_sendTransaction` is a `string`, so no response type is required to be made. You only need to create a response type if the response type is a custom object. ```csharp theme={null} var wallet = GetCurrentAddress(); var result = new EthSendTransaction(new Transaction() { From = wallet.Address, To = wallet.Address, Value = "0" }); // Returns the transaction hash or throws an error string result = await dappClient.Request(sessionTopic, request, wallet.ChainId); ``` #### Disconnecting To disconnect a session, use the `Disconnect` function. You may optional provide a reason for the disconnect ```csharp theme={null} await dappClient.Disconnect(sessionTopic); // or await dappClient.Disconnect(sessionTopic, Error.FromErrorType(ErrorType.USER_DISCONNECTED)); ``` #### Subscribe to session events ```csharp theme={null} dappClient.SubscribeToSessionEvent("chainChanged", OnChainChanged); ``` WalletConnectUnity is a wrapper for WalletConnectSharp. It simplifies managing a single active session, addressing a common challenge with the original library. #### Features of WalletConnectUnity 1. **Simplified Session Management**: WalletConnectSharp is designed to support multiple sessions, requiring developers to manually track and restore the active session. WalletConnectUnity simplifies this process by focusing on a single session, making it easier to manage session restoration. 2. **Session Restoration**: WalletConnectUnity includes methods to easily access and restore the active session from storage. 3. **Deep Linking Support**: WalletConnectUnity automatically handles deep linking for mobile and desktop wallets. 4. **QR Code Generation**: WalletConnectUnity provides a utility for generating QR codes. #### Usage To use WalletConnectUnity in your project: 1. Fill in the Project ID and Metadata fields in the `Assets/WalletConnectUnity/Resources/WalletConnectProjectConfig` asset. * If you don't have a Project ID, you can create one at [Reown Dashboard](https://dashboard.reown.com). * The `Redirect` fields are optional. They are used to redirect the user back to your app after they approve or reject the session. 2. Initialize `WalletConnect` and connect the wallet: ```csharp theme={null} // Initialize singleton await WalletConnect.Instance.InitializeAsync(); // Or handle instancing manually var walletConnectUnity = new WalletConnect(); await walletConnectUnity.InitializeAsync(); // Try to resume the last session var sessionResumed = await WalletConnect.Instance.TryResumeSessionAsync(); if (!sessionResumed) { var connectedData = await WalletConnect.Instance.ConnectAsync(connectOptions); // Create QR code texture var texture = WalletConnectUnity.Core.Utils.QRCode.EncodeTexture(connectedData.Uri); // ... Display QR code texture // Wait for wallet approval await connectedData.Approval; } ``` All features of WalletConnectSharp are accessible in WalletConnectUnity. For complex scenarios, the `SignClient` can be accessed directly through `WalletConnect.SignClient`. Refer to the `.NET` documentation for details on using the Sign API within WalletConnectUnity. The usage of the WalletConnectSharp.Sign API remains consistent with `.NET`. # Introduction Source: https://docs.reown.com/advanced/api/sign/overview WalletConnect Sign is a remote signer protocol to communicate securely between web3 wallets and dapps. The protocol establishes a remote pairing between two apps and/or devices using a Relay server to relay payloads. These payloads are symmetrically encrypted through a shared key between the two peers. The pairing is initiated by one peer displaying a QR Code or deep link with a standard WalletConnect URI and is established when the counter-party approves this pairing request. Head over to Reown Dashboard and create a new project. ## Installation ```bash npm theme={null} npm install @walletconnect/sign-client ``` ```bash yarn theme={null} yarn add @walletconnect/sign-client ``` ```bash bun theme={null} bun add @walletconnect/sign-client ``` ```bash pnpm theme={null} pnpm add @walletconnect/sign-client ``` For Node.js, the WalletConnect SignClient additionally requires `lokijs` to manage storage internally. ```bash npm theme={null} npm install --save @walletconnect/sign-client lokijs@1.x ``` ```bash yarn theme={null} yarn add @walletconnect/sign-client lokijs@1.x ``` ```bash bun theme={null} bun add --save @walletconnect/sign-client lokijs@1.x ``` ```bash pnpm theme={null} pnpm add @walletconnect/sign-client lokijs@1.x ``` You can add a WalletConnect SDK to your project with Swift Package Manager. In order to do that: 1. Open XCode 2. Go to File -> Add Packages 3. Paste the repo GitHub URL: [https://github.com/reown-com/reown-swift](https://github.com/reown-com/reown-swift) 4. Tap Add Package 5. Select WalletConnect check mark 1. Update Cocoapods spec repos. Type in terminal `pod repo update` 2. Initialize Podfile if needed with `pod init` 3. Add pod to your Podfile: ```ruby theme={null} pod 'WalletConnectSwiftV2' ``` 4. Install pods with `pod install` If you encounter any problems during package installation, you can specify the exact path to the repository ```ruby theme={null} pod 'WalletConnectSwiftV2', :git => 'https://github.com/reown-com/reown-swift.git', :tag => '1.0.5' ``` Kotlin implementation of WalletConnect v2 Sign protocol for Android applications. This SDK is developed in Kotlin and usable in both Java and Kotlin files. * Android Core ![Maven Central](https://img.shields.io/maven-central/v/com.walletconnect/android-core) * Sign ![Maven Central](https://img.shields.io/maven-central/v/com.walletconnect/sign) #### Requirements * Android min SDK 23 * Java 11 #### Installation root/build.gradle.kts: ```gradle theme={null} allprojects { repositories { mavenCentral() maven { url "https://jitpack.io" } } } ``` app/build.gradle.kts ```gradle theme={null} implementation("com.walletconnect:android-core:release_version") implementation("com.walletconnect:sign:release_version") ``` Install the WalletConnect client package. ```dart theme={null} flutter pub add walletconnect_flutter_v2 ``` #### Platform Specific Setup Depending on your platform, you will have to add different permissions to get the package to work. #### MacOS Add the following to your `DebugProfile.entitlements` and `Release.entitlements` files so that it can connect to the WebSocket server. ```xml theme={null} com.apple.security.network.client ``` #### Install via Packages Install the WalletConnect Sign Client package via Nuget. ```shell theme={null} dotnet add package WalletConnect.Sign ``` WalletConnectUnity.Core is a Unity package that provides a client implementation of the WalletConnect v2 protocol. It is built on top of the [WalletConnectSharp.Sign](https://github.com/WalletConnect/WalletConnectSharp) library, which provides the core functionality for the WalletConnect protocol. #### Prerequisites * Unity 2021.3 or above * IL2CPP code stripping level: Minimal (or lower) #### Package Installation To install packages via OpenUPM, you need to have [Node.js](https://nodejs.org/en/) and [openupm-cli](https://openupm.com/docs/getting-started.html#installing-openupm-cli) installed. Once you have them installed, you can run the following commands: ```bash theme={null} openupm add com.walletconnect.core ``` 1. Open `Advanced Project Settings` from the gear ⚙ menu located at the top right of the Package Manager's toolbar 2. Add a new scoped registry with the following details: * Name: `OpenUPM` * URL: `https://package.openupm.com` * Scope(s): `com.walletconnect` 3. Press plus ➕ and then `Save` buttons 4. In the Package Manager windows open the add ➕ menu from the toolbar 5. Select `Add package by name...` 6. Enter the package name: * `com.walletconnect.core` 7. Press `Add` button 1. Open the add ➕ menu in the Package Manager's toolbar 2. Select `Add package from git URL...` 3. Enter the package URL: **WalletConnectUnity Core** ``` https://github.com/WalletConnect/WalletConnectUnity.git?path=Packages/com.walletconnect.core ``` 4. Press `Add` button It's possible to lock the version of the package by adding `#{version}` at the end of the git URL, where `#{version}` is the git tag of the version you want to use. For example, to install version `1.0.1` of WalletConnectUnity Modal, use the following URL: ``` https://github.com/WalletConnect/WalletConnectUnity.git?path=Packages/com.walletconnect.core#core/1.0.1 ``` #### WebGL Due to WebGL's single-threaded nature, certain asynchronous operations like `Task.Run`, `Task.ContinueWith`, `Task.Delay`, and `ConfigureAwait(false)` are not natively supported. To enable these operations in WebGL builds, an additional third-party package, [WebGLThreadingPatcher](https://github.com/VolodymyrBS/WebGLThreadingPatcher), is required. This package modifies the Unity WebGL build to delegate work to the `SynchronizationContext`, allowing these operations to be executed on the same thread without blocking the main application. Please note that all tasks are still executed on a single thread, and any blocking calls will freeze the entire application. The [WebGLThreadingPatcher](https://github.com/VolodymyrBS/WebGLThreadingPatcher) package can be added via git URL: ``` https://github.com/VolodymyrBS/WebGLThreadingPatcher.git ``` # Smart Contract Wallet Usage Source: https://docs.reown.com/advanced/api/sign/smart-contract-wallet-usage This section is limited to just for Web/JavaScript at the present moment Smart Contract wallets like [Argent](https://argent.gitbook.io/argent/wallet-connect-and-argent) are fully supported by the WalletConnect protocol. However, there are some considerations to be taken when integrating WalletConnect in your dapp for Smart Contract wallets, regarding how the accounts are exposed in the session, message signatures are returned, and transactions are broadcasted. ### Accounts When you connect your dapp to a smart contract wallet, you will receive the **smart account address** for the wallet. This is not to be confused with the **delegate keys** that are used to sign messages and transactions. You can detect smart contract wallets by verifying on-chain if the exposed account address has any associated code deployed. ```javascript theme={null} import { providers, utils } from "ethers"; const provider = new providers.JsonRpcProvider(rpcUrl); const bytecode = await provider.getCode(address); const isSmartContract = bytecode && utils.hexStripZeros(bytecode) !== "0x"; ``` ```javascript theme={null} import Web3 from "web3"; const web3 = new Web3(rpcUrl); const bytecode = await web3.eth.getCode(address); const isSmartContract = bytecode && utils.hexStripZeros(bytecode) !== "0x"; ``` Smart contract wallets are essentially multi-signature wallets that use multiple keys to authorize operations on behalf of these smart contract accounts, so you will have to take into consideration how messages and transactions are handled by your dapp. ## Messages Normally, when verifying signatures from "normal" accounts, which are Externally Owned Accounts (EOAs), you would use an ECDSA method called `ecrecover()` to retrieve the corresponding public key, which will then map to an address. In the case of Smart Contract Wallets, you are not able to sign a message with the smart contract account. Therefore, the standard [EIP-1271](https://eips.ethereum.org/EIPS/eip-1271) was defined to outline a validation method which can be called on-chain, labeled `isValidSignature()`. ```text theme={null} contract ERC1271 { bytes4 constant internal MAGICVALUE = 0x1626ba7e; function isValidSignature( bytes32 _hash, bytes memory _signature ) public view returns (bytes4 magicValue); } ``` This method has a single parameter `_hash` which should be [EIP-191](https://eips.ethereum.org/EIPS/eip-191) compliant and can be computed using: ```javascript theme={null} import { utils } from "ethers"; const hash = utils.hashMessage(message); ``` ```javascript theme={null} import Web3 from "web3"; const web3 = new Web3(rpcUrl); const hash = web3.eth.accounts.hashMessage(message); ``` ## Transactions Smart Contract wallets, like [Argent](https://argent.gitbook.io/argent/wallet-connect-and-argent), commonly use the concept of meta transactions. These are a specific type of transaction that is signed by one or more key pairs but is submitted to the Ethereum network by a relayer. The relayer pays the gas fee (in ETH), and the wallet will refund the relayer (in ETH or ERC20 tokens) up to an amount signed by the wallet's owner. From your dapp's perspective, this is managed by the mobile wallet application. Your dapp will submit a regular `{ to, value, data }` transaction to the web3 provider. This transaction will be transmitted to the mobile wallet application through WalletConnect. The mobile wallet will transform the data into a meta transaction: * `to` will be the `RelayerManager` contract address * `data` will be the encoded data of the call to the `execute()` method with the relevant parameters Your dapp will receive the transaction hash in order to monitor the status of the transaction, and events will be emitted as usual. The relayer has the ability to replay a transaction with a higher gas price due to fluctuating network conditions. The transaction hash is modified, and the dapp will not be aware of the new transaction hash. One solution could be for your dapp to observe a specific event being emitted instead of the transaction status. There is currently work on standardizing events for transactions replies that has been recently proposed via [EIP-2831](https://eips.ethereum.org/EIPS/eip-2831). We hope to improve our SDKs in the future to take this standard into account. # FAQs Source: https://docs.reown.com/advanced/faq ## What chains does WalletConnect support? WalletConnect operates as a chain-agnostic protocol, adhering to the [CAIP-25](https://github.com/ChainAgnostic/CAIPs/blob/master/CAIPs/caip-25.md) standard. While the WalletConnect protocol supports various chains, you can refer to the [list](../cloud/chains/chain-list) for the known compatible blockchains. However, please note that our SDKs have certain limitations on the chains they support. If you intend to extend support for non-EVM chains in your wallet or dapp, it is recommended to review the cross-chain primitives supported by the WalletConnect protocol through the Chain Agnostic Standards Alliance's [Namespaces](https://namespaces.chainagnostic.org/) project. Additionally, feel free to reach out to our community team for further guidance. In the event that the desired chain lacks documentation in the Namespaces project, you can collaborate with an expert in the respective chain's tooling and submit a [namespaces PR](https://github.com/ChainAgnostic/namespaces/?tab=readme-ov-file#namespaces). ## Will the relay server `bridge.walletconnect.org` still work in v2? No, the bridge servers are v1 only. ## How can I reconnect to the same pairing if my browser was restarted? The `signClient` will restore & reconnect its pairings automatically after the page is reloaded. All pairings are stored on the page's `localStorage`. For more context, feel free to check our [web examples](https://github.com/WalletConnect/web-examples). ## The default relay endpoint is blocked. How can I get around this? When initializing `signClient`, you can set `relayUrl` to `wss://relay.walletconnect.org`. ```js theme={null} const signClient = await SignClient.init({ projectId: "", relayUrl: "wss://relay.walletconnect.org", metadata: {}, }); ``` ## How can we use a custom relay for our bridge without a WC URI parameter as the host? You are more than welcome to utilize a custom URI parameter during testing. However, it is currently not recommended for use in a production environment. ## Why is self-hosting not an option at this time? Are there plans to make this possible in the future? We understand the desire for developers to self-host their own relay. We share this vision, and have embarked on a decentralization roadmap in order to achieve this. By the end of this summer, we will launch a permissioned network and invite a select group of partners to participate in this crucial first phase. Our objective is to make self-hosting relay a reality with the creation of the decentralized WalletConnect Network, and we appreciate your patience as we progress in this enormous mission. ## How do I report a security issue? Please consult our [security.txt](https://reown.com/.well-known/security.txt) # Dapp Integration Guide Source: https://docs.reown.com/advanced/multichain/polkadot/dapp-integration-guide ## Dapp Guide Section Topics * WalletConnect Code/Component Setup * Constructing unsigned transactions * Sending unsigned transactions for signing using WalletConnect * Adding the signature to the ExtrinsicPayload * Signing and sending the transaction to the node *** # WalletConnect Code/Component Setup 1. **One time step**: Generate a unique `projectId` by visiting and creating your project’s profile on WalletConnect’s project dashboard at: [https://dashboard.reown.com/](https://dashboard.reown.com/). 2. Import `UniversalProvider` and `{ WalletConnectModal }` from `@walletconnect/universal-provider` and `@walletconnect/modal` respectively. ```js theme={null} import UniversalProvider from "@walletconnect/universal-provider"; import { WalletConnectModal } from "@walletconnect/modal"; ``` 3. Instantiate a universal provider using the `projectId` created for your app. ```js theme={null} const provider = await UniversalProvider.init({ projectId: "2ea3f3ghubh32b8ie2f2", relayUrl: "wss://relay.walletconnect.com", }); ``` 4. On user action (e.g. user clicks connect for WalletConnect), call the connect method on the providers sign client passing in preferred params. WalletConnect uses chain ids based on the CAIP standard (CAIP-13 for Polkadot Namespace): [Polkadot WalletConnect CAIP-13](https://github.com/ChainAgnostic/CAIPs/blob/master/CAIPs/caip-13.md) * polkadot CAIP id = `91b171bb158e2d3848fa23a9f1c25182` * kusama CAIP id = `b0a8d493285c2df73290dfb7e61f870f` * westend CAIP id = `e143f23803ac50e8f6f8e62695d1ce9e` * statemint CAIP id = `68d56f15f85d3136970ec16946040bc1` * hydradx CAIP id = `afdc188f45c71dacbaa0b62e16a91f72` * phala network CAIP id = `1bb969d85965e4bb5a651abbedf21a54` * astar network CAIP id = `9eb76c5184c4ab8679d2d5d819fdf90b` * crust shadow CAIP id = `d4c0c08ca49dc7c680c3dac71a7c0703` * mangata kusama mainnet CAIP id = `d611f22d291c5b7b69f1e105cca03352` * turing network CAIP id = `0f62b701fb12d02237a33b84818c11f6` * Chain ids correspond to the genesis hash for each respective chain ### Example Namespace and Sign Client connect call: **Note**: this serves as an example where a dapp requires 3 different chain namespaces (polkadot, hydradx and turing network). The supported methods, chains, and events can all be defined by the dapp team based on the requirements of the dapp. ```js theme={null} const params = { requiredNamespaces: { polkadot: { methods: ["polkadot_signTransaction", "polkadot_signMessage"], chains: [ "polkadot:91b171bb158e2d3848fa23a9f1c25182", // polkadot "polkadot:afdc188f45c71dacbaa0b62e16a91f72", // hydradx "polkadot:0f62b701fb12d02237a33b84818c11f6", // turing network ], events: ['chainChanged", "accountsChanged'], }, }, }; const { uri, approval } = await provider.client.connect(params); ``` 5. Create a standalone modal using your dapps WalletConnect projectId. ```js theme={null} const walletConnectModal = new WalletConnectModal({ projectId: "2ea3f3ghubh32b8ie2f2", }); ``` 6. Open the modal prompting the user to scan the QR code with their wallet app or copy the URI from the modal and paste into their wallet app to begin the session creation process. ```js theme={null} // if there is a URI from the client connect step open the modal if (uri) { walletConnectModal.openModal({ uri }); } // await session approval from the wallet app const walletConnectSession = await approval(); ``` 7. Get the accounts from the session for use in constructing transactions. ```js theme={null} const walletConnectAccount = Object.values(walletConnectSession.namespaces) .map((namespace) => namespace.accounts) .flat(); // grab account addresses from CAIP account formatted accounts const accounts = wcAccounts.map((wcAccount) => { const address = wcAccount.split(":")[2]; return address; }); ``` # Constructing Unsigned Transactions One thing the dapp must do is properly construct the unsigned transaction. This consists of constructing an object with the intended chain’s metadata including the `specVersion`, `transactionVersion`, etc. In addition to these, you must provide the transaction data (`method`, `address` etc). Below is an example of what this general structure looks like using polkadotjs but this can be done in any valid way: ```js theme={null} const unsignedTransaction = { specVersion: api.runtimeVersion.specVersion.toHex(), transactionVersion: api.runtimeVersion.transactionVersion.toHex(), address: selectedWalletConnectAccountAddress, blockHash: lastHeader.hash.toHex(), blockNumber: blockNumber.toHex(), era: era.toHex(), genesisHash: api.genesisHash.toHex(), method: method.toHex(), nonce: nonce.toHex(), signedExtensions: [ "CheckNonZeroSender", "CheckSpecVersion", "CheckTxVersion", "CheckGenesis", "CheckMortality", "CheckNonce", "CheckWeight", "ChargeTransactionPayment", ], tip: api.registry.createType("Compact", 0).toHex(), version: tx.version, }; ``` 8. A specific example of constructing an unsigned transaction using polkadotjs api to retrieve the chains metadata. ```js theme={null} // import api and wsprovider import { ApiPromise, WsProvider } from "@polkadot/api"; //instantiate wsProvider and api const wsProvider = new WsProvider("wss://rpc.polkadot.io"); const api = await ApiPromise.create({ provider: wsProvider }); const lastHeader = await api.rpc.chain.getHeader(); const blockNumber = api.registry.createType( "BlockNumber", lastHeader.number.toNumber() ); const tx = api.tx.balances.transfer(keyring.bob.publicKey, 100); const method = api.createType("Call", tx); const era = api.registry.createType("ExtrinsicEra", { current: lastHeader.number.toNumber(), period: 64, }); const accountNonce = getBalanceAccount(submitAddress)?.nonce || 0; const nonce = api.registry.createType("Compact", accountNonce); const unsignedTransaction = { specVersion: api.runtimeVersion.specVersion.toHex(), transactionVersion: api.runtimeVersion.transactionVersion.toHex(), address: selectedWalletConnectAccountAddress, blockHash: lastHeader.hash.toHex(), blockNumber: blockNumber.toHex(), era: era.toHex(), genesisHash: api.genesisHash.toHex(), method: method.toHex(), nonce: nonce.toHex(), signedExtensions: [ "CheckNonZeroSender", "CheckSpecVersion", "CheckTxVersion", "CheckGenesis", "CheckMortality", "CheckNonce", "CheckWeight", "ChargeTransactionPayment", ], tip: api.registry.createType("Compact", 0).toHex(), version: tx.version, }; ``` # Sending unsigned transactions to the wallet for signing using WalletConnect 9. Send the unsigned transaction to the paired wallet for signing using the providers sign client. This triggers a `session_request` event which must be handled by the paired wallet. ### Polkadot Example ```js theme={null} const result = await client.request({ chainId: "polkadot:91b171bb158e2d3848fa23a9f1c25182", topic: walletConnectSession.topic, request: { method: "polkadot_signTransaction", params: { address: selectedWalletConnectAddress, transactionPayload: unsignedTransaction, }, }, }); ``` ### Parachain Example (HydraDX) ```js theme={null} const result = await client.request({ chainId: "polkadot:afdc188f45c71dacbaa0b62e16a91f72", topic: walletConnectSession.topic, request: { method: "polkadot_signTransaction", params: { address: selectedWalletConnectAddress, transactionPayload: unsignedTransaction, }, }, }); ``` Once the request is resolved, the expected response should be a result object which contains a signature ```js theme={null} { signature: "0x09u03f0h3nf34f0m3mn0fn34fn3f"; // an example result } ``` ## Adding the signature to the ExtrinsicPayload Using this signature, we can now create an `ExtrinsicPayload` and add the signature. Below is an example of this general step: ```js theme={null} // create the extrinsic payload using the unsigned transaction const rawUnsignedTransaction = api.registry.createType( "ExtrinsicPayload", unsignedTransaction, { version: unsignedTransaction.version, } ); // add the signature to the extrinsic payload tx.addSignature( selectedWalletConnectAddress, result.signature, rawUnsignedTransaction ); ``` # Signing and sending the transaction to the node Now, it is just about attaching the returned signature to the transaction and submitting it as specified by the dApp. Below is a specific example showing this process: ```js theme={null} const rawUnsignedTransaction = api.registry.createType( "ExtrinsicPayload", unsignedTransaction, { version: unsignedTransaction.version, } ); tx.addSignature( selectedWalletConnectAddress, result.signature, rawUnsignedTransaction ); // send the signed transaction to the node const unsub = await tx.send(({ status, events }) => { // optionally handle ready status, notify user of submission if (status.isReady) { // ... } // optionally handle in block status, notify user of in block if (status.isInBlock) { // ... } // let user know outcome of transaction if (status.isFinalized) { events.forEach(({ event: { method } }) => { // if success optionally notify/update state if (method === "ExtrinsicSuccess") { // ... unsub(); // unsubscribe from extrinsic } else if (method === "ExtrinsicFailed") { // on failure optionally notify/update state // ... unsub(); // unsubscribe from extrinsic } }); } }); ``` # Namespaces Guide Source: https://docs.reown.com/advanced/multichain/polkadot/namespaces-guide ## Guide Section Topics * [Understanding Namespaces](#understanding-namespaces) * [Proposal Namespaces](#proposal-namespaces) * [Proposal Namespace Example](#proposal-namespace-example) * [Session Namespaces](#session-namespaces) * [Session Namespace Example](#session-namespace-example) * [Chains](#chains), [Methods](#methods) and [Events](#events) * [Using Namespaces with the Universal Provider](#dapps-universal-provider-and-namespaces) * [Using Namespaces with the WalletKit](#wallets-walletkit-and-namespaces) ### 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 if it is valid along with the approved accounts for each chain in the namespace. * If the requested proposal namespaces are not valid based on the wallets rules, the session cannot be established and the wallet rejects it with an error code that tells the dapp if the proposal namespaces have invalid chains, methods, events or if it was simply rejected by the user. ### Proposal Namespace Example An example Proposal Namespace for a dapp which supports connecting to Polkadot, Ethereum, Polygon and Cosmos: ```js theme={null} { "polkadot": { "chains": [ "polkadot:91b171bb158e2d3848fa23a9f1c25182", // Polkadot "polkadot:b0a8d493285c2df73290dfb7e61f870f", // Kusama ], "methods": ["polkadot_signMessage"], "events": ["accountsChanged"] }, "eip155": { "chains": [ "eip155:1", // Ethereum "eip155:137" // Polygon ], "methods": ["eth_sign"], "events": ["accountsChanged"] }, "cosmos": { "chains": ["cosmos:cosmoshub-4"], // Cosmos "methods": ["cosmos_signDirect"], "events": ["someCosmosEvent"] } } ``` ### Session Namespaces * The wallet validates if the received proposal namespaces match with the session namespaces it supports. If they match, a session is established successfully and pairing is completed. If not, the session is not established. * The wallet session can also choose to provide access to more chains, methods or events that were not a part of the proposal namespaces. This means a dapp could send a proposal namespace with only Polkadot `['polkadot:91b171bb158e2d3848fa23a9f1c25182']` in its requiredNamespaces `chains` field but a wallet could return a session namespace with both Polkadot and Kusama `['polkadot:91b171bb158e2d3848fa23a9f1c25182','polkadot:b0a8d493285c2df73290dfb7e61f870f']` as part of the sessions namespaces. ### Session Namespace Example ```js theme={null} { "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. `eip155`, `polkadot`, `cosmos` etc) followed by a colon and the genesis hash for the chain (e.g. `91b171bb158e2d3848fa23a9f1c25182` for Polkadot). * A dapp or wallet can make as many or as few chain ids a part of its namespace as desired. ### 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`. The idea for the functionality of these methods is to sign the relevant data (either a message or unsigned transaction) and return the signature. [An example for each method](https://github.com/WalletConnect/web-examples/blob/main/advanced/wallets/react-wallet-v2/src/lib/PolkadotLib.ts). * If a dapp required additional method support such as receiving the signed hex for a transaction in order to submit it rather than the signature, a wallet only needs to define and add support for the method so that any dapp that requires that functionality can use it when making requests. * An example would be adding a method named `polkadot_getSignedHex` and creating an implementation that signs, and returns the hash of the signed transaction. ```js theme={null} // Example Session Namespace { "polkadot": { "accounts": [ "polkadot:91b171bb158e2d3848fa23a9f1c25182:AZBEwbZhYeiofodZnM2iAoshP3pXRPNSJEKFqEPDmvv1mY7" ], "methods": [ "polkadot_signMessage", "polkadot_signTransaction" "polkadot_getSignedHex", ], "events": ["accountsChanged"], } } // In the wallets codebase, you'd add functionality to be called when this new method is called from a WalletConnect session // Specific Example Implementation: public async getSignedHex(payload: SignerPayloadJSON) { this.registry.setSignedExtensions(payload.signedExtensions) const txPayload = this.registry.createType('ExtrinsicPayload', payload, { version: payload.version }); const { signature } = txPayload.sign(this.keypair) const extrinsic = registry.createType( 'Extrinsic', { method: payload.method }, { version: payload.version } ); extrinsic.addSignature(unsigned.address, signature, unsigned); const hex = extrinsic.toHex(); return { hex }; } ``` * Wallets and dapps can define an agreed upon interface based on a particular chain or ecosystems needs. ### Events * `events` represent specific changes in a sessions state that a dapp or wallet may want to take some action on. * For example, a dapp or a wallet might want to perform some action if the user changes the selected session accounts. An example of emitting this event can be found below: ```js theme={null} await signClient.emit({ topic, event: { name: "accountsChanged", data: ["AZBEwbZhYeiofodZnM2iAoshP3pXRPNSJEKFqEPDmvv1mY7"], }, chainId: "polkadot:91b171bb158e2d3848fa23a9f1c25182", }); ``` This can be useful in a wallet if a user is adding additional accounts to a session so that the wallet or dapp can respond and update their respective states using events such as `session_update` to update the accounts, chains, methods or events for the session or `session_delete` to end a session. [(More on events)](https://docs.walletconnect.com/specs/clients/sign/session-events#session_request). ### Using Namespaces In order to create a session proposal, call the connect method on the universal provider's sign client. The sign clients `connect` method accepts an object based on the following interface: ```js theme={null} interface ConnectParams { requiredNamespaces?: ProposalTypes.RequiredNamespaces; optionalNamespaces?: ProposalTypes.OptionalNamespaces; sessionProperties?: ProposalTypes.SessionProperties; pairingTopic?: string; relays?: RelayerTypes.ProtocolOptions[]; } ``` ### Dapps: Universal Provider and Namespaces: The connect method on the universal provider expects an object that matches the above `ConnectParams` interface. All fields are optional and in the below example we use only the `requiredNamespaces` field in our proposal namespace: ```js theme={null} const proposalNamespace = { requiredNamespaces: { polkadot: { methods: ["polkadot_signTransaction", "polkadot_signMessage"], chains: ["polkadot:91b171bb158e2d3848fa23a9f1c25182"], events: ["chainChanged", "accountsChanged"], }, }, }; // call connect on the universal provider passing the proposal namespace const { uri, approval } = await provider.client.connect(proposalNamespace); ``` ### Wallets: WalletKit and Namespaces: When the WalletKit 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. An example of what this looks like is below. ```js theme={null} 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 [here](https://docs.walletconnect.com/specs/clients/sign/namespaces#controller-side-validation-of-incoming-proposal-namespaces-wallet). # Wallet Integration Guide Source: https://docs.reown.com/advanced/multichain/polkadot/wallet-integration-guide ## Wallet Guide Section Topics * WalletConnect Code/Component Setup * Approving a Session Proposal * Rejecting a Session Proposal * Handling Session Request Events * Session Persistence/Management *** 1. **Getting Started:** Generate a unique `projectId` by visiting and creating your project's profile on WalletConnect's project dashboard at: * `https://dashboard.reown.com/` # WalletConnect Code/Component Setup 2. Import Core and WalletKit from WalletConnect. ```js theme={null} import { Core } from "@walletconnect/core"; import { WalletKit } from "@walletconnect/wallekit"; ``` 3. Instantiate and add Core and WalletKit to the state of the wallet. ```js theme={null} const core = new Core({ projectId: "fgu234234njbhvhv23525bj" }); const walletKit = await WalletKit.init({ core: core, metadata: { name: "Example WalletConnect Wallet", description: "Example WalletConnect Integration", url: "myexamplewallet.com", icons: [], }, }); ``` 4. Create a function to accept a session `uri` which will be passed from a dapp when a user either scans the dapp's WalletConnect qrcode modal or manually copies and pastes the uri from the modal into the wallet's UI. ```js theme={null} const onConnect = async (uri: string) => { // call walletKit.core.pairing.pair( { uri: uri }) // with the uri received from the dapp in order to emit the // `session_proposal` event const result = await walletKit.core.pairing.pair({ uri }); }; ``` 5. 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 (Example) 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. Below is an example showing the format for wallet accounts and how to include them in a session proposal approval. ```js theme={null} // example account addresses in wallet state const substrateAccounts = [ "5CK8D1sKNwF473wbuBP6NuhQfPaWUetNsWUNAAzVwTfxqjfr", "5F3sa2TJAWMqDhXG6jhV4N8ko9SxwGy8TpaNS1repo5EYjQX", ]; // format the accounts to match the chain:chain_id:address format const walletConnectAccounts = accounts.map( (account) => `polkadot:91b171bb158e2d3848fa23a9f1c25182:${account.address}` ); walletKit.on("session_proposal", async (proposal) => { // optionally show user a modal or way to reject or approve session showWalletConnectModal(); // handle user approval case // create the approved session with selected accounts, supported methods, chains and events for your wallet const session = await walletKit.approveSession({ id: proposal.id, namespaces: { polkadot: { accounts: walletConnectAccounts, methods: ["polkadot_signTransaction", "polkadot_signMessage"], chains: ["polkadot:91b171bb158e2d3848fa23a9f1c25182"], events: ['chainChanged", "accountsChanged'], }, }, }); // create response object const response = { id: proposal.id, result: "session approved", jsonrpc: "2.0", }; // respond to the dapp request with the approved session's topic and response await walletKit.respondSessionRequest({ topic: session.topic, response }); }); ``` # Rejecting a Session Proposal (Example) 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. Below is an example of rejecting a session proposal. ```js theme={null} // Note: session_request is emitted when the client on the dapp end calls the request method // import getSdkError to create predefined ErrorResponse types import { getSdkError } from "@walletconnect/utils"; walletKit.on("session_proposal", async (proposal) => { // optionally show user a modal or way to reject or approve session showWalletConnectModal(); // handle user reject action await walletKit.rejectSession({ id: proposal.id, reason: getSdkError("USER_REJECTED"), }); }); ``` # Handling Session Request Event 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. As seen in the [WalletConnect Web Examples](https://github.com/WalletConnect/web-examples/blob/main/advanced/wallets/react-wallet-v2/src/lib/PolkadotLib.ts), two common use cases in polkadot are signing messages and signing transactions. These methods are represented here as `polkadot_signMessage` and `polkadot_signTransaction` respectively and each simply signs the respective payload and returns the signature to the dapp. An example of a `session_request` event handler containing both can be found below. ```js theme={null} walletKit.on("session_request", async (requestEvent) => { const { params, id } = requestEvent; const { request } = params; const address = request.params?.address; // check that the request address is in your users list of wallets // Example: const wallet = getPolkadotWallet(address); // if (!wallet) { throw new Error("Polkadot wallet does not exist"); } // handle supported methods (polkadot_signMessage, polkadot_signTransaction) switch (request.method) { case "polkadot_signMessage": // call function used by wallet to sign message and return the signature const signature = await yourwallet.signMessage(request.params.message); // create the response containing the signature in the result const response = { id, result: { signature: signature }, jsonrpc: "2.0" }; // respond to the dapp request with the response and topic await walletKit.respondSessionRequest({ topic, response }); case "polkadot_signTransaction": // call function used by wallet to sign transactions and return the signature const signature = await yourwallet.signTransaction( request.params.transactionPayload ); // create the response containing the signature in the result const response = { id, result: { signature: signature }, jsonrpc: "2.0" }; // respond to the dapp request with the response and topic await walletKit.respondSessionRequest({ topic, response }); // throw error for methods your wallet doesn't support default: throw new Error(getSdkError("INVALID_METHOD").message); } }); ``` # Sessions Persistence/Management * sessions can be saved/stored so users don't have to pair repeatedly * sessions can be disconnected from using `await walletKit.disconnectSession({ topic: topic });` passing the session topic. * sessions can be extended using `await walletKit.extendSession({ topic: topic });` passing the session topic. * Default session lifetime is 7 days for WalletConnect v2.0. # Further Documentation for WalletConnect 2.0 * [https://docs.walletconnect.com/](https://docs.walletconnect.com/) # Bitcoin Source: https://docs.reown.com/advanced/multichain/rpc-reference/bitcoin-rpc Bitcoin JSON-RPC Methods We define an account as the group of addresses derived using the same account value in their [derivation paths](https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki#user-content-Path_levels). We use the first address of the [external chain](https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki#examples) ("first external address"), as the identifier for an account. An account's total balance is defined as the sum of all unspent transaction outputs (UTXOs) belonging to its entire group of addresses. 1. Dapps **must** only display the first external address as a connected account. 2. Wallets **must** only offer to connect the first external address(es). #### Account Definition The derivation path levels in the [BIP44](https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki#path-levels), [BIP49](https://github.com/bitcoin/bips/blob/master/bip-0049.mediawiki#user-content-Public_key_derivation), [BIP84](https://github.com/bitcoin/bips/blob/master/bip-0084.mediawiki#public-key-derivation), [BIP86](https://github.com/bitcoin/bips/blob/master/bip-0086.mediawiki#user-content-Public_key_derivation) standards are: ``` m / purpose' / coin_type' / account' / change / address_index ``` Addresses with different `purpose`, `change` and `address_index` values are considered to belong to the same account. Valid `purpose` values are 44, 49, 84 and 86. We use the first external Native SegWit (purpose = 84) address as the default account identifier. For a specific seed phrase and path `m/84'/0'/0'/0/0` we get account 0 with identifier `bc1qcr8te4kr609gcawutmrza0j4xv80jy8z306fyu`. Its total balance is the sum of all UTXO balances on all addresses with derivation paths: * `m/44'/0'/0'/change/address_index` * `m/49'/0'/0'/change/address_index` * `m/84'/0'/0'/change/address_index` * `m/86'/0'/0'/change/address_index` If the wallet user changes to account 1 we get path `m/84'/0'/1'/0/0` with identifier `bc1qku0qh0mc00y8tk0n65x2tqw4trlspak0fnjmfz`. Its total balance is the sum of all UTXO balances on all addresses with derivation paths: * `m/44'/0'/1'/change/address_index` * `m/49'/0'/1'/change/address_index` * `m/84'/0'/1'/change/address_index` * `m/86'/0'/1'/change/address_index` ## sendTransfer This method is used to sign and submit a transfer of any `amount` of Bitcoin to a single `recipientAddress`, optionally including a `changeAddress` for the change amount and `memo` set as an OP\_RETURN output by supporting wallets. The transaction will be signed and broadcast upon user approval. ### Parameters * `Object` * `account` : `String` - *(Required)* The connected account's first external address. * `recipientAddress` : `String` - *(Required)* The recipient's public address. * `amount` : `String` - *(Required)* The amount of Bitcoin to send, denominated in satoshis (Bitcoin base unit). * `changeAddress` : `String` - *(Optional)* The sender's public address to receive change. * `memo` : `String` - *(Optional)* The OP\_RETURN value as a hex string without 0x prefix, maximum 80 bytes. ### Returns * `Object` * `txid` : `String` - *(Required)* The transaction id as a hex string without 0x prefix. ### Example The example below specifies a simple transfer of 1.23 BTC (123000000 Satoshi). ```javascript theme={null} // Request { "id": 1, "jsonrpc": "2.0", "method": "sendTransfer", "params": { "account": "bc1qcr8te4kr609gcawutmrza0j4xv80jy8z306fyu", "recipientAddress": "bc1pmzfrwwndsqmk5yh69yjr5lfgfg4ev8c0tsc06e", "amount": "123000000", "memo": "636861726c6579206c6f766573206865" } } // Result { "id": 1, "jsonrpc": "2.0", "result": { "txid": "f007551f169722ce74104d6673bd46ce193c624b8550889526d1b93820d725f7" } } ``` ## getAccountAddresses This method returns all current addresses needed for a dapp to fetch all UTXOs, calculate the total balance and prepare transactions. Dapps will typically use an indexing service to query for balances and UTXOs for all addresses returned by this method, such as: * [Blockbook API](https://github.com/trezor/blockbook/blob/master/docs/api.md#get-address) * [Bitcore API](https://github.com/bitpay/bitcore/blob/master/packages/bitcore-node/docs/api-documentation.md#address) We recognize that there are two broad classes of wallets in use today: 1. Wallets that generate a new change or receive address for every transaction ("dynamic wallet"). 2. Wallets that reuse the first external address for every transaction ("static wallet"). #### Implementation Details * All wallets **should** include the first external address and all addresses with one or more UTXOs, unless they're filtered by `intentions`. * Dynamic wallets **should** include minimum 2 unused change and receive addresses. Otherwise dapps may have to request [getAccountAddresses](#getAccountAddresses) after every transaction to discover the new addresses and keep track of the user's total balance. * All wallets **must** return fewer than 20 unused change and receive addresses to avoid breaking the [gap limit](https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki#address-gap-limit). ### Parameters * `Object` * `account` : `String` - *(Required)* The connected account's first external address. * `intentions` : `String[]` - *(Optional)* Filter what addresses to return, e.g. "payment" or "ordinal". ### Returns * `Array` * `Object` * `address` : `String` - *(Required)* Public address belonging to the account. * `publicKey` : `String` - *(Optional)* Public key for the derivation path in hex, without 0x prefix. * `path` : `String` - *(Optional)* Derivation path of the address e.g. "m/84'/0'/0'/0/0". * `intention` : `String` - *(Optional)* Intention of the address, e.g. "payment" or "ordinal". ### Session Properties In a connection request, it is recommended to serialize the response to `getAccountAddresses` in `session.sessionProperties.bip122_getAccountAddresses`. This allows dapps to consume an active session without requiring a context switch to re-request all addresses and associated public keys from the wallet. ### Example: Dynamic Wallet The example below specifies a result from a dynamic wallet. For the sake of this example, receive and change addresses with index 3-4 are considered unused and addresses with paths `m/49'/0'/0'/0/7` and `m/84'/0'/0'/0/2` are considered to have UTXOs. Assuming the dapp monitors all returned addresses for balance changes, a new request to `getAccountAddresses` is only needed when all UTXOs in provided addresses have been spent, or when all provided `receive` addresses or `change` addresses have been used. ```javascript theme={null} // Request { "id": 1, "jsonrpc": "2.0", "method": "getAccountAddresses", "params": { "account": "bc1qcr8te4kr609gcawutmrza0j4xv80jy8z306fyu" } } // Result { "id": 1, "jsonrpc": "2.0", "result": [ { "address": "bc1qcr8te4kr609gcawutmrza0j4xv80jy8z306fyu", "publicKey": "0330d54fd0dd420a6e5f8d3624f5f3482cae350f79d5f0753bf5beef9c2d91af3c", "path": "m/84'/0'/0'/0/0" }, { "address": "3KHhcgwPgYF9hE77zaKy2G36dpkcNtvQ33", "publicKey": "03b90230ca20150142bc2849a3df4517073978f32466214a0ebc00cac52f996989", "path": "m/49'/0'/0'/0/7" }, { "address": "bc1qp59yckz4ae5c4efgw2s5wfyvrz0ala7rgvuz8z", "publicKey": "038ffea936b2df76bf31220ebd56a34b30c6b86f40d3bd92664e2f5f98488dddfa", "path": "m/84'/0'/0'/0/2" }, { "address": "bc1qgl5vlg0zdl7yvprgxj9fevsc6q6x5dmcyk3cn3", "publicKey": "03de7490bcca92a2fb57d782c3fd60548ce3a842cad6f3a8d4e76d1f2ff7fcdb89", "path": "m/84'/0'/0'/0/3" }, { "address": "bc1qm97vqzgj934vnaq9s53ynkyf9dgr05rargr04n", "publicKey": "03995137c8eb3b223c904259e9b571a8939a0ec99b0717684c3936407ca8538c1b", "path": "m/84'/0'/0'/0/4" }, { "address": "bc1qv6vaedpeke2lxr3q0wek8dd7nzhut9w0eqkz9z", "publicKey": "03d0d243b6a3176fa20fa95cd7fb0e8e0829b83fc2b52053633d088c1a4ba91edf", "path": "m/84'/0'/0'/1/3" }, { "address": "bc1qetrkzfslk0d4kqjnu29fdh04tkav9vj3k36vuh", "publicKey": "02a8dee7573bcc7d3c1e9b9e267dbf0cd717343c31d322c5b074a3a97090a0d952", "path": "m/84'/0'/0'/1/4" } ] } ``` ### Example: Static Wallet The example below specifies a response from a static wallet. The returned address is used for both change and payments. It's the only address with UTXOs. Hardware wallets utilizing `bip32` are also supported. ```javascript theme={null} // Request { "id": 1, "jsonrpc": "2.0", "method": "getAccountAddresses", "params": { "account": "bc1qcr8te4kr609gcawutmrza0j4xv80jy8z306fyu" } } // Result { "id": 1, "jsonrpc": "2.0", "result": [ { "address": "bc1qcr8te4kr609gcawutmrza0j4xv80jy8z306fyu", "publicKey": "0330d54fd0dd420a6e5f8d3624f5f3482cae350f79d5f0753bf5beef9c2d91af3c", "path": "m/84'/0'/0'/0/0" } ] } ``` ## signPsbt This method can be used to request the signature of a Partially Signed Bitcoin Transaction (PSBT) and covers use-cases e.g. involving multiple-recipient transactions, requiring granular control over which UTXOs to spend or how to route change. ### Parameters * `Object` * `account` : `String` - *(Required)* The connected account's first external address. * `psbt` : `String` - *(Required)* Base64 encoded string of the PSBT to sign. * `signInputs` : `Array` * `Object` * `address` : `String` - *(Required)* The address whose private key to use for signing. * `index` : `Integer` - *(Required)* Specifies which input to sign. * `sighashTypes` : `Integer[]` - *(Optional)* Specifies which part(s) of the transaction the signature commits to. Default is `[1]`. * `broadcast` : `Boolean` - *(Optional)* Whether to finalize and broadcast the transaction after signing it. Default is `false`. ### Returns * `Object` * `psbt` : `String` - *(Required)* The base64 encoded signed PSBT. * `txid` : `String` - *(Optional)* The transaction ID as a hex-encoded string, without 0x prefix. This must be returned if the transaction was broadcasted. ## signMessage This method is used to sign a message with one of the connected account's addresses. ### Parameters * `Object` * `account` : `String` - *(Required)* The connected account's first external address. * `message` : `String` - *(Required)* The message to be signed by the wallet. * `address` : `String` - *(Optional)* The address whose private key to use for signing the message. * `protocol` : `"ecdsa" | "bip322"` - *(Optional)* Preferred signature type. Default is `"ecdsa"`. ### Returns * `Object` * `address` : `String` - *(Required)* The Bitcoin address used to sign the message. * `signature` : `String` - *(Required)* Hex encoded bytes of the signature, without 0x prefix. * `messageHash` : `String` - *(Optional)* Hex encoded bytes of the message hash, without 0x prefix. ## Events ### bip122\_addressesChanged This event is used by wallets to notify dapps about connected accounts' current addresses, for example all addresses with a UTXO and a few unused addresses. The event data has the same format as the [getAccountAddresses](#getaccountaddresses) result. #### Implementation Details * Wallets **should** emit a `bip122_addressesChanged` event immediately after connection approval of a BIP122 chain. * Wallets **should** emit a `bip122_addressesChanged` event whenever a UTXO is spent or created for a connected account's addresses. * Dapps **should** listen for `bip122_addressesChanged` events, collect and monitor all addresses for UTXO and balance changes. Example [session\_event](https://specs.walletconnect.com/2.0/specs/clients/sign/session-events#session_event) payload as received by a dapp: ``` { "id": 1675759795769537, "topic": "95d6aca451b8e3c6d9d176761bf786f1cc0a6d38dffd31ed896306bb37f6ae8d", "params": { "event": { "name": "bip122_addressesChanged", "data": [ { "address": "bc1qcr8te4kr609gcawutmrza0j4xv80jy8z306fyu", "publicKey": "0330d54fd0dd420a6e5f8d3624f5f3482cae350f79d5f0753bf5beef9c2d91af3c", "path": "m/84'/0'/0'/0/0" }, { "address": "3KHhcgwPgYF9hE77zaKy2G36dpkcNtvQ33", "publicKey": "03b90230ca20150142bc2849a3df4517073978f32466214a0ebc00cac52f996989", "path": "m/49'/0'/0'/0/7" }, { "address": "bc1qp59yckz4ae5c4efgw2s5wfyvrz0ala7rgvuz8z", "publicKey": "038ffea936b2df76bf31220ebd56a34b30c6b86f40d3bd92664e2f5f98488dddfa", "path": "m/84'/0'/0'/0/2" }, { "address": "bc1qgl5vlg0zdl7yvprgxj9fevsc6q6x5dmcyk3cn3", "publicKey": "03de7490bcca92a2fb57d782c3fd60548ce3a842cad6f3a8d4e76d1f2ff7fcdb89", "path": "m/84'/0'/0'/0/3" }, { "address": "bc1qm97vqzgj934vnaq9s53ynkyf9dgr05rargr04n", "publicKey": "03995137c8eb3b223c904259e9b571a8939a0ec99b0717684c3936407ca8538c1b", "path": "m/84'/0'/0'/0/4" }, { "address": "bc1qv6vaedpeke2lxr3q0wek8dd7nzhut9w0eqkz9z", "publicKey": "03d0d243b6a3176fa20fa95cd7fb0e8e0829b83fc2b52053633d088c1a4ba91edf", "path": "m/84'/0'/0'/1/3" }, { "address": "bc1qetrkzfslk0d4kqjnu29fdh04tkav9vj3k36vuh", "publicKey": "02a8dee7573bcc7d3c1e9b9e267dbf0cd717343c31d322c5b074a3a97090a0d952", "path": "m/84'/0'/0'/1/4" } ] }, "chainId": "bip122:000000000019d6689c085ae165831e93" } } ``` # Casper Source: https://docs.reown.com/advanced/multichain/rpc-reference/casper-rpc **Please note:** The Casper RPC standard is still under review and specifications may change. Implementation details and method signatures are subject to updates. ## Methods ### casper\_sign\_deploy Use the `casper_sign_deploy` method to request the user to approve or reject the signature of a transaction (aka deploy). The wallet should validate the received deploy object and present the details to the user for his review. #### Parameters * `address`. Type: `string`. The chain namespace and the public key corresponding to the key pair that signs the transaction are separated with a colon character. * `deploy`. Type: `object`. A Deploy object as per the Casper protocol specification. #### Returns * `deploy`. Type: `object`. The Deploy object including the newly generated approval item as per the Casper protocol specification. If the user rejects the signature, the wallet returns the WalletConnect SDK error `USER_REJECTED`. #### Example Request: ```json theme={null} { "id": 1, "jsonrpc": "2.0", "method": "casper_sign_deploy", "params": { "deploy": { "hash": "a3301c9da7f0183f1c8904bed7fc72cf563454509462cada378b3f42a92f7b4f", "header": { "account": "02032E126170e5f28443775330B5B5Fe29dCE1a1dD3269910349525935ccbaf352EA", "timestamp": "2024-02-01T08:41:59.207Z", "ttl": "30m", "gas_price": 1, "body_hash": "188d88eedd3dc64b4ac3f8ca9b74be2b2fa588e2d537875d22b7e1a68658d19e", "dependencies": [], "chain_name": "casper-test" }, "payment": { "ModuleBytes": { "module_bytes": "", "args": [["amount", { "bytes": "0400e1f505", "cl_type": "U512" }]] } }, "session": { "Transfer": { "args": [ ["amount", { "bytes": "0500f2052a01", "cl_type": "U512" }], [ "target", { "bytes": "0202e99759649fa63a72c685b72e696b30c90f1deabb02d0d9b1de45eb371a73e5bb", "cl_type": "PublicKey" } ], [ "id", { "bytes": "01d204000000000000", "cl_type": { "Option": "U64" } } ] ] } }, "approvals": [] }, "address": "casper:casper-test:02032E126170e5f28443775330B5B5Fe29dCE1a1dD3269910349525935ccbaf352EA" } } ``` Response: ```json theme={null} { "id": 1, "jsonrpc": "2.0", "result": { "deploy": { "hash": "a3301c9da7f0183f1c8904bed7fc72cf563454509462cada378b3f42a92f7b4f", "header": { "account": "02032E126170e5f28443775330B5B5Fe29dCE1a1dD3269910349525935ccbaf352EA", "timestamp": "2024-02-01T08:41:59.207Z", "ttl": "30m", "gas_price": 1, "body_hash": "188d88eedd3dc64b4ac3f8ca9b74be2b2fa588e2d537875d22b7e1a68658d19e", "dependencies": [], "chain_name": "casper-test" }, "payment": { "ModuleBytes": { "module_bytes": "", "args": [["amount", { "bytes": "0400e1f505", "cl_type": "U512" }]] } }, "session": { "Transfer": { "args": [ ["amount", { "bytes": "0500f2052a01", "cl_type": "U512" }], [ "target", { "bytes": "0202e99759649fa63a72c685b72e696b30c90f1deabb02d0d9b1de45eb371a73e5bb", "cl_type": "PublicKey" } ], [ "id", { "bytes": "01d204000000000000", "cl_type": { "Option": "U64" } } ] ] } }, "approvals": [ { "signer": "02032E126170e5f28443775330B5B5Fe29dCE1a1dD3269910349525935ccbaf352EA", "signature": "02ad07c25d7cef27598f67c7bafce3e07e4198de7884f0e48041965c0f0be2690956d25bae0510bec9463da4aa6a5e591fb3cb88c8f31df85bc0b6f857b80f64e2" } ] } } } ``` ### casper\_sign\_message Use `casper_sign_message` to request the user to sign a message. It's recommended to use this method with human-readable text messages. Upon user approval, the wallet must generate a signature for the prefixed message `"Casper Message:\n" + message`. The prefix protects the user against misuse of this method, preventing a malicious actor from trying to trick the user into signing arbitrary data, like a network transaction. #### Parameters * `address`. Type: `string`. The chain namespace and the public key corresponding to the key pair that signs the transaction separated with a colon character. * `message`. Type: `string`. The message to be signed. #### Returns * `signature`. Type: `string`. The signature of the message. If the user rejects the signature, the wallet returns the WalletConnect SDK error `USER_REJECTED`. #### Example Request: ```json theme={null} { "id": 1, "jsonrpc": "2.0", "method": "casper_sign_message", "params": { "message": "CSPR.studio wants you to sign in with your Casper account:\n0x01953...808f3 \n\nIssued At: 07/21/2023 10:07:25\nnonce: 428b62e4", "address": "casper:casper-test:0202a8e3e5E32800792F37F738d95BF2610d86E97922D13ab97945bb062824ed9E8A" } } ``` Response: ```json theme={null} { "id": 1, "jsonrpc": "2.0", "method": "casper_sign_message", "result": { "signature": "b52482afd2392b715cc43d9ad9f1f7067752a10ba5b49b89bc61b398e478841e6d8a4a224aeb944a34f23d98a232cdab6e5a60a5e886e8b0719d7b84277c405f" } } ``` ## Events Currently, this specification doesn't define any required events for wallets. # Cosmos Source: https://docs.reown.com/advanced/multichain/rpc-reference/cosmos-rpc Cosmos JSON-RPC Methods **Please note:** The Cosmos RPC standard is still under review and specifications may change. Implementation details and method signatures are subject to updates. ## cosmos\_getAccounts This method returns an array of key pairs available to sign from the wallet mapped with an associated algorithm and address on the blockchain. ### Parameters none ### Returns 1.`Array` - Array of accounts: 1.1. `Object` - Account Data object with parameters: 1.1.1. `algo` : `STRING` - algorithm used for signing 1.1.2. `address` : `STRING` - corresponding address for keypair 1.1.3. `pubkey` : `STRING` - base64 encoded public key for keypair ### Example ```javascript theme={null} // Request { "id": 1, "jsonrpc": "2.0", "method": "cosmos_getAccounts", "params": {} } // Result { "id": 1, "jsonrpc": "2.0", "result": [ { "algo": "secp256k1", "address": "cosmos1sguafvgmel6f880ryvq8efh9522p8zvmrzlcrq", "pubkey": "AgSEjOuOr991QlHCORRmdE5ahVKeyBrmtgoYepCpQGOW" } ] } ``` ## cosmos\_signDirect This method returns a signature for the provided document to be signed targeting the requested signer address corresponding to the keypair returned by the account data. ### Parameters 1. `Object` - Signing parameters: 1.1. `signerAddress` : `STRING` - corresponding address for keypair 1.2. `signDoc` : `Object` - Document to be signed: 1.2.2. `chainId` : `STRING` - identifier of blockchain 1.2.1. `accountNumber` : `STRING` - blockchain account number 1.2.3. `authInfoBytes` : `DATA` - encoded authentication information 1.2.4. `bodyBytes` : `DATA` - encoded body of message to sign ### Returns 1. `Object` - Signing parameters: 1.1. `signature` : `Object` - corresponding signature for signed documented 1.1.1. `pub_key` : `Object` - public key for keypair 1.1.1.1: `type` : `STRING` - type of public key 1.1.1.2: `value` : `STRING` - value of public key 1.1.2. `signature`: `STRING` - corresponding signature for signed documented 1.2. `signed` : `Object` - Signed document: 1.2.2. `chainId` : `STRING` - identifier of blockchain 1.2.1. `accountNumber` : `STRING` - blockchain account number 1.2.3. `authInfoBytes` : `DATA` - encoded authentication information 1.2.4. `bodyBytes` : `DATA` - encoded body of message to sign ### Example ```javascript theme={null} // Request { "id": 1, "jsonrpc": "2.0", "method": "cosmos_signDirect", "params": { "signerAddress": "cosmos1sguafvgmel6f880ryvq8efh9522p8zvmrzlcrq", "signDoc": { "chainId": "cosmoshub-4", "accountNumber": "1" "authInfoBytes": "CgoKABIECgIIARgBEhMKDQoFdWNvc20SBDIwMDAQwJoM", "bodyBytes": "CpABChwvY29zbW9zLmJhbmsudjFiZXRhMS5Nc2dTZW5kEnAKLWNvc21vczFwa3B0cmU3ZmRrbDZnZnJ6bGVzamp2aHhobGMzcjRnbW1rOHJzNhItY29zbW9zMXF5cHF4cHE5cWNyc3N6ZzJwdnhxNnJzMHpxZzN5eWM1bHp2N3h1GhAKBXVjb3NtEgcxMjM0NTY3" } } } // Result { "id": 1, "jsonrpc": "2.0", "result": { "signature": { "pub_key": { "type": "tendermint/PubKeySecp256k1", "value": "AgSEjOuOr991QlHCORRmdE5ahVKeyBrmtgoYepCpQGOW" }, "signature": "AnTrXtS2lr9CBwhTpRa8ZlKcVR9PeIXGaTpvodyJU05QvRKVjIkQfOZl5JhdkfxCY+a6rhwCOYVcbKQTJlMw4w==" }, "signed": { "chainId": "cosmoshub-4", "accountNumber": "1" "authInfoBytes": "CgoKABIECgIIARgBEhMKDQoFdWNvc20SBDIwMDAQwJoM", "bodyBytes": "CpABChwvY29zbW9zLmJhbmsudjFiZXRhMS5Nc2dTZW5kEnAKLWNvc21vczFwa3B0cmU3ZmRrbDZnZnJ6bGVzamp2aHhobGMzcjRnbW1rOHJzNhItY29zbW9zMXF5cHF4cHE5cWNyc3N6ZzJwdnhxNnJzMHpxZzN5eWM1bHp2N3h1GhAKBXVjb3NtEgcxMjM0NTY3" } } } ``` ## cosmos\_signAmino This method returns a signature for the provided document to be signed targeting the requested signer address corresponding to the keypair returned by the account data. ### Parameters 1. `Object` - Signing parameters: 1.1. `signerAddress` : `STRING` - corresponding address for keypair 1.2. `signDoc` : `Object` - Document to be signed: 1.2.2. `chain_id` : `STRING` - identifier of blockchain 1.2.1. `account_number` : `STRING` - blockchain account number 1.2.3. `sequence` : `STRING` - blockchain account sequence 1.2.4. `memo` : `STRING` - amino message memo 1.2.5. `msgs` : `Array` - array of amino messages to be signed: 1.2.5.1. `Object` - amino message object: 1.2.5.1.1. - `type` : `STRING` - amino message type 1.2.5.1.2. - `value` : `STRING` - amino message value 1.2.6. `fee` : `Object` - fee description object 1.2.6.1. `amount` : `Array` - array of currency fees: 1.2.6.1.1. `Object` - currency fee description object: 1.2.6.1.1.1. `denom` : `STRING` - currency denomination 1.2.6.1.1.2. `amount` : `STRING` - currency amount 1.2.6.2. `gas` : `STRING` - gas limit for execution ### Returns 1. `Object` - Signing parameters: 1.1. `signature` : `Object` - corresponding signature for signed documented 1.1.1. `pub_key` : `Object` - public key for keypair 1.1.1.1: `type` : `STRING` - type of public key 1.1.1.2: `value` : `STRING` - value of public key 1.1.2. `signature`: `STRING` - corresponding signature for signed documented 1.2. `signed` : `Object` - Signed document: 1.2.2. `chain_id` : `STRING` - identifier of blockchain 1.2.1. `account_number` : `STRING` - blockchain account number 1.2.3. `sequence` : `STRING` - blockchain account sequence 1.2.4. `memo` : `STRING` - amino message memo 1.2.5. `msgs` : `Array` - array of amino messages to be signed: 1.2.5.1. `Object` - amino message object: 1.2.5.1.1. - `type` : `STRING` - amino message type 1.2.5.1.2. - `value` : `STRING` - amino message value 1.2.6. `fee` : `Object` - fee description object 1.2.6.1. `amount` : `Array` - array of currency fees: 1.2.6.1.1. `Object` - currency fee description object: 1.2.6.1.1.1. `denom` : `STRING` - currency denomination 1.2.6.1.1.2. `amount` : `STRING` - currency amount 1.2.6.2. `gas` : `STRING` - gas limit for execution ### Example ```javascript theme={null} // Request { "id": 1, "jsonrpc": "2.0", "method": "cosmos_signAmino", "params": { "signerAddress": "cosmos1sguafvgmel6f880ryvq8efh9522p8zvmrzlcrq", "signDoc": { "chain_id": "foochain", "account_number": "7", "sequence": "54" "memo": "hello, world", "msgs": [], "fee": { "amount": [], "gas": "23" } } } } // Result { "id": 1, "jsonrpc": "2.0", "result": { "signature": { "pub_key": { "type": "tendermint/PubKeySecp256k1", "value": "AgSEjOuOr991QlHCORRmdE5ahVKeyBrmtgoYepCpQGOW" }, "signature": "AnTrXtS2lr9CBwhTpRa8ZlKcVR9PeIXGaTpvodyJU05QvRKVjIkQfOZl5JhdkfxCY+a6rhwCOYVcbKQTJlMw4w==" }, "signed": { "chain_id": "foochain", "account_number": "7", "sequence": "54" "memo": "hello, world", "msgs": [], "fee": { "amount": [{"denom": "ufoo", "amount": "10000"}], "gas": "23" } } } } ``` # Dogecoin Source: https://docs.reown.com/advanced/multichain/rpc-reference/dogecoin-rpc Dogecoin JSON-RPC Methods **Please note:** The Dogecoin RPC standard is still under review and specifications may change. Implementation details and method signatures are subject to updates. We define an account as the group of addresses derived using the same account value in their [derivation paths](https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki#user-content-Path_levels).We use the first address of the [external chain](https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki#examples) ("first external address"), as the identifier for an account. An account's total balance is defined as the sum of all unspent transaction outputs (UTXOs) belonging to its entire group of addresses. 1. Dapps **must** only display the first external address as a connected account. 2. Wallets **must** only offer to connect the first external address(es). #### Account Definition The derivation path levels in the [BIP44](https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki#path-levels) standard is: ``` m / purpose' / coin_type' / account' / change / address_index ``` Addresses with different `purpose`, `change` and `address_index` values are considered to belong to the same account. We use the first external P2PKH (purpose = 44) address as the default account identifier. For a specific seed phrase and path `m/44'/3'/0'/0/0` we get account 0 with identifier `DTyt9wHTgizR8CwK8HAsWDaoMMxcaRuLWJ`. Its total balance is the sum of all UTXO balances on all addresses with derivation paths: * `m/44'/3'/0'/change/address_index` If the wallet user changes to account 1 we get path `m/44'/3'/1'/0/0` with identifier `DBcZSePDaMMduBMLymWHXhkE5ArFEvkagU`. Its total balance is the sum of all UTXO balances on all addresses with derivation paths: * `m/44'/3'/1'/change/address_index` ## sendTransfer This method is used to sign and submit a transfer of any `amount` of Dogecoin to a single `recipientAddress`, optionally including a `changeAddress` for the change amount and `memo` set as the OP\_RETURN value by supporting wallets. The transaction will be signed and broadcast upon user approval. ### Parameters * `Object` * `account` : `String` - *(Required)* The connected account's first external address. * `recipientAddress` : `String` - *(Required)* The recipient's public address. * `amount` : `String` - *(Required)* The amount of Dogecoin to send, denominated in satoshis (Dogecoin base unit). * `changeAddress` : `String` - *(Optional)* The sender's public address to receive change. * `memo` : `String` - *(Optional)* The OP\_RETURN value as a hex string without 0x prefix, maximum 80 bytes. ### Returns * `Object` * `txid` : `String` - The transaction id as a hex string without 0x prefix. ### Example The example below specifies a simple transfer of 1.23 DOGE (123000000 Satoshi). ```javascript theme={null} // Request { "id": 1, "jsonrpc": "2.0", "method": "sendTransfer", "params": { "account": "DTyt9wHTgizR8CwK8HAsWDaoMMxcaRuLWJ", "recipient": "DBcZSePDaMMduBMLymWHXhkE5ArFEvkagU", "amount": "123000000", "memo": "636861726c6579206c6f766573206865" } } // Result { "id": 1, "jsonrpc": "2.0", "result": { "txid": "f007551f169722ce74104d6673bd46ce193c624b8550889526d1b93820d725f7" } } ``` ## getAccountAddresses This method returns all current addresses needed for a dapp to fetch all UTXOs, calculate the total balance and prepare transactions. Dapps will typically use an indexing service to query for balances and UTXOs for all addresses returned by this method, such as: * [Blockbook API](https://github.com/trezor/blockbook/blob/master/docs/api.md#get-address) * [Bitcore API](https://github.com/bitpay/bitcore/blob/master/packages/bitcore-node/docs/api-documentation.md#address) We recognize that there are two broad classes of wallets in use today: 1. Wallets that generate a new change or receive address for every transaction ("dynamic wallet"). 2. Wallets that reuse the first external address for every transaction ("static wallet"). #### Implementation Details * All wallets **should** include the first external address and all addresses with one or more UTXOs, unless they're filtered by `intentions`. * Dynamic wallets **should** include minimum 2 unused change and receive addresses. Otherwise dapps may have to request [getAccountAddresses](#getAccountAddresses) after every transaction to discover the new addresses and keep track of the user's total balance. * All wallets **must** return fewer than 20 unused change and receive addresses to avoid breaking the [gap limit](https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki#address-gap-limit). ### Parameters * `Object` * `account` : `String` - *(Required)* The connected account's first external address. * `intentions` : `String[]` - *(Optional)* Filter what addresses to return, e.g. "payment" or "ordinal". ### Returns * `Array` * `Object` * `address` : `String` - *(Required)* Public address belonging to the account. * `publicKey` : `String` - *(Optional)* Public key for the derivation path in hex, without 0x prefix. * `path` : `String` - *(Optional)* Derivation path of the address e.g. "m/44'/3'/0'/0/0". * `intention` : `String` - *(Optional)* Intention of the address, e.g. "payment" or "ordinal". ### Example: Dynamic Wallet The example below specifies a result from a dynamic wallet. For the sake of this example, receive and change addresses with index 3-4 are considered unused and address with path `m/44'/3'/0'/0/2` is considered to have UTXOs. Assuming the dapp monitors all returned addresses for balance changes, a new request to `getAccountAddresses` is only needed when all UTXOs in provided addresses have been spent, or when all provided `receive` addresses or `change` addresses have been used. ```javascript theme={null} // Request { "id": 1, "jsonrpc": "2.0", "method": "getAccountAddresses", "params": { "account": "DTyt9wHTgizR8CwK8HAsWDaoMMxcaRuLWJ" } } // Result { "id": 1, "jsonrpc": "2.0", "result": [ { "address": "DTyt9wHTgizR8CwK8HAsWDaoMMxcaRuLWJ", "path": "m/44'/3'/0'/0/0" }, { "address": "DA6rZ9aV3mkz9uxNvddzzbXEEcSPN8SCUS", "path": "m/44'/3'/0'/0/2" }, { "address": "DDtQfA541GQU2KDrY3ofF5F5hsKxkFiUuG", "path": "m/44'/3'/0'/0/3" }, { "address": "D5A6wPFhCNChUiQHGXftD8DiNgc2G7yT1L", "path": "m/44'/3'/0'/0/4" }, { "address": "DFG9R8ENG4mK5gUiU1VRr3FBT13LfWJ4Fb", "path": "m/44'/3'/0'/1/3" }, { "address": "D7rakaGgZvaBH1vGTxnsQ3ZdV7ejX57hRy", "path": "m/44'/3'/0'/1/4" } ] } ``` ### Example: Static Wallet The example below specifies a response from a static wallet. The returned address is used for both change and payments. It's the only address with UTXOs. ```javascript theme={null} // Request { "id": 1, "jsonrpc": "2.0", "method": "getAccountAddresses", "params": { "account": "DTyt9wHTgizR8CwK8HAsWDaoMMxcaRuLWJ" } } // Result { "id": 1, "jsonrpc": "2.0", "result": [ { "address": "DTyt9wHTgizR8CwK8HAsWDaoMMxcaRuLWJ", "path": "m/44'/3'/0'/0/0" } ] } ``` ## signPsbt This method can be used to request the signature of a Partially Signed Bitcoin Transaction (PSBT) and covers use-cases e.g. involving multiple-recipient transactions, requiring granular control over which UTXOs to spend or how to route change. ### Parameters * `Object` * `account` : `String` - *(Required)* The connected account's first external address. * `psbt` : `String` - *(Required)* Base64 encoded string of the PSBT to sign. * `signInputs` : `Array` * `Object` * `address` : `String` - *(Required)* The address whose private key to use for signing. * `index` : `Integer` - *(Required)* Specifies which input to sign. * `sighashTypes` : `Integer[]` - *(Optional)* Specifies which part(s) of the transaction the signature commits to. Default is `[1]`. * `broadcast` : `Boolean` - *(Optional)* Whether to finalize and broadcast the transaction after signing it. Default is `false`. ### Returns * `Object` * `psbt` : `String` - *(Required)* The base64 encoded signed PSBT. * `txid` : `String` - *(Optional)* The transaction ID as a hex-encoded string, without 0x prefix. This must be returned if the transaction was broadcasted. ## signMessage This method is used to sign a message with one of the connected account's addresses. ### Parameters * `Object` * `account` : `String` - *(Required)* The connected account's first external address. * `message` : `String` - *(Required)* The message to be signed by the wallet. * `address` : `String` - *(Optional)* The address whose private key to use for signing the message. * `protocol` : `"ecdsa" | "bip322"` - *(Optional)* Preferred signature type. Default is `"ecdsa"`. ### Returns * `Object` * `address` : `String` - *(Required)* The Dogecoin address used to sign the message. * `signature` : `String` - *(Required)* Hex encoded bytes of the signature, without 0x prefix. * `messageHash` : `String` - *(Optional)* Hex encoded bytes of the message hash, without 0x prefix. ## Events ### bip122\_addressesChanged This event is used by wallets to notify dapps about connected accounts' current addresses, for example all addresses with a UTXO and a few unused addresses. The event data has the same format as the [getAccountAddresses](#getaccountaddresses) result. #### Implementation Details * Wallets **should** emit a `bip122_addressesChanged` event immediately after connection approval of a BIP122 chain. * Wallets **should** emit a `bip122_addressesChanged` event whenever a UTXO is spent or created for a connected account's addresses. * Dapps **should** listen for `bip122_addressesChanged` events, collect and monitor all addresses for UTXO and balance changes. Example [session\_event](https://specs.walletconnect.com/2.0/specs/clients/sign/session-events#session_event) payload as received by a dapp: ``` { "id": 1675759795769537, "topic": "95d6aca451b8e3c6d9d176761bf786f1cc0a6d38dffd31ed896306bb37f6ae8d", "params": { "event": { "name": "bip122_addressesChanged", "data": [ { "address": "DTyt9wHTgizR8CwK8HAsWDaoMMxcaRuLWJ", "path": "m/44'/3'/0'/0/0" }, { "address": "DA6rZ9aV3mkz9uxNvddzzbXEEcSPN8SCUS", "path": "m/44'/3'/0'/0/2" }, { "address": "DDtQfA541GQU2KDrY3ofF5F5hsKxkFiUuG", "path": "m/44'/3'/0'/0/3" }, { "address": "D5A6wPFhCNChUiQHGXftD8DiNgc2G7yT1L", "path": "m/44'/3'/0'/0/4" }, { "address": "DFG9R8ENG4mK5gUiU1VRr3FBT13LfWJ4Fb", "path": "m/44'/3'/0'/1/3" }, { "address": "D7rakaGgZvaBH1vGTxnsQ3ZdV7ejX57hRy", "path": "m/44'/3'/0'/1/4" } ] }, "chainId": "bip122:1a91e3dace36e2be3bf030a65679fe821" } } ``` # Ethereum Source: https://docs.reown.com/advanced/multichain/rpc-reference/ethereum-rpc Ethereum JSON-RPC Methods ## personal\_sign The sign method calculates an Ethereum specific signature with:`sign(keccak256("\x19Ethereum Signed Message:\n" + len(message) + message)))`. By adding a prefix to the message makes the calculated signature recognizable as an Ethereum specific signature. This prevents misuse where a malicious DApp can sign arbitrary data (e.g. transaction) and use the signature to impersonate the victim. **Note** See ecRecover to verify the signature. ### Parameters message, account 1. `DATA`, N Bytes - message to sign. 2. `DATA`, 20 Bytes - address. ### Returns `DATA`: Signature ### Example ```javascript theme={null} // Request { "id": 1, "jsonrpc": "2.0", "method": "personal_sign", "params":["0xdeadbeaf","0x9b2055d370f73ec7d8a03e965129118dc8f5bf83"], } // Result { "id": 1, "jsonrpc": "2.0", "result": "0xa3f20717a250c2b0b729b7e5becbff67fdaef7e0699da4de7ca5895b02a170a12d887fd3b17bfdce3481f10bea41f45ba9f709d39ce8325427b57afcfc994cee1b" } ``` ## eth\_sign The sign method calculates an Ethereum specific signature with: `sign(keccak256("\x19Ethereum Signed Message:\n" + len(message) + message)))`. By adding a prefix to the message makes the calculated signature recognizable as an Ethereum specific signature. This prevents misuse where a malicious DApp can sign arbitrary data (e.g. transaction) and use the signature to impersonate the victim. **Note** the address to sign with must be unlocked. ### Parameters account, message 1. `DATA`, 20 Bytes - address. 2. `DATA`, N Bytes - message to sign. ### Returns `DATA`: Signature ### Example ```javascript theme={null} // Request { "id": 1, "jsonrpc": "2.0", "method": "eth_sign", "params": ["0x9b2055d370f73ec7d8a03e965129118dc8f5bf83", "0xdeadbeaf"], } // Result { "id": 1, "jsonrpc": "2.0", "result": "0xa3f20717a250c2b0b729b7e5becbff67fdaef7e0699da4de7ca5895b02a170a12d887fd3b17bfdce3481f10bea41f45ba9f709d39ce8325427b57afcfc994cee1b" } ``` An example how to use solidity ecrecover to verify the signature calculated with `eth_sign` can be found [here](https://gist.github.com/bas-vk/d46d83da2b2b4721efb0907aecdb7ebd). The contract is deployed on the testnet Ropsten and Rinkeby. ## eth\_signTypedData Calculates an Ethereum-specific signature in the form of `keccak256("\x19Ethereum Signed Message:\n" + len(message) + message))` By adding a prefix to the message makes the calculated signature recognizable as an Ethereum specific signature. This prevents misuse where a malicious DApp can sign arbitrary data (e.g. transaction) and use the signature to impersonate the victim. **Note** the address to sign with must be unlocked. ### Parameters account, message 1. `DATA`, 20 Bytes - address. 2. `DATA`, N Bytes - message to sign containing type information, a domain separator, and data ### Example Parameters ```javascript theme={null} [ "0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826", { types: { EIP712Domain: [ { name: "name", type: "string", }, { name: "version", type: "string", }, { name: "chainId", type: "uint256", }, { name: "verifyingContract", type: "address", }, ], Person: [ { name: "name", type: "string", }, { name: "wallet", type: "address", }, ], Mail: [ { name: "from", type: "Person", }, { name: "to", type: "Person", }, { name: "contents", type: "string", }, ], }, primaryType: "Mail", domain: { name: "Ether Mail", version: "1", chainId: 1, verifyingContract: "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC", }, message: { from: { name: "Cow", wallet: "0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826", }, to: { name: "Bob", wallet: "0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB", }, contents: "Hello, Bob!", }, }, ]; ``` ### Returns `DATA`: Signature ### Example ```javascript theme={null} // Request { "id": 1, "jsonrpc": "2.0", "method": "eth_signTypedData", "params": ["0x9b2055d370f73ec7d8a03e965129118dc8f5bf83", {see above}], } ' // Result { "id": 1, "jsonrpc": "2.0", "result": "0x4355c47d63924e8a72e509b65029052eb6c299d53a04e167c5775fd466751c9d07299936d304c153f6443dfa05f40ff007d72911b6f72307f996231605b915621c" } ``` ## eth\_sendTransaction Creates new message call transaction or a contract creation, if the data field contains code. ### Parameters 1. `Object` - The transaction object 2. `from`: `DATA`, 20 Bytes - The address the transaction is send from. 3. `to`: `DATA`, 20 Bytes - (optional when creating new contract) The address the transaction is directed to. 4. `data`: `DATA` - The compiled code of a contract OR the hash of the invoked method signature and encoded parameters. For details see [Ethereum Contract ABI](https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI) 5. `gas`: `QUANTITY` - (optional, default: 90000) Integer of the gas provided for the transaction execution. It will return unused gas. 6. `gasPrice`: `QUANTITY` - (optional, default: To-Be-Determined) Integer of the gasPrice used for each paid gas 7. `value`: `QUANTITY` - (optional) Integer of the value sent with this transaction 8. `nonce`: `QUANTITY` - (optional) Integer of a nonce. This allows to overwrite your own pending transactions that use the same nonce. ### Example Parameters ```javascript theme={null} [ { from: "0xb60e8dd61c5d32be8058bb8eb970870f07233155", to: "0xBDE1EAE59cE082505bB73fedBa56252b1b9C60Ce", data: "0x", gasPrice: "0x029104e28c", gas: "0x5208", value: "0x00", }, ]; ``` ### Returns `DATA`, 32 Bytes - the transaction hash, or the zero hash if the transaction is not yet available. Use [eth\_getTransactionReceipt](https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_gettransactionreceipt) to get the contract address, after the transaction was mined, when you created a contract. ### Example ```javascript theme={null} // Request { "id": 1, "jsonrpc": "2.0", "method": "eth_sendTransaction", "params":[{see above}], } // Result { "id": 1, "jsonrpc": "2.0", "result": "0xe670ec64341771606e55d6b4ca35a1a6b75ee3d5145a99d05921026d1527331" } ``` ## eth\_signTransaction Signs a transaction that can be submitted to the network at a later time using with `eth_sendRawTransaction` ### Parameters 1. `Object` - The transaction object 2. `from`: `DATA`, 20 Bytes - The address the transaction is send from. 3. `to`: `DATA`, 20 Bytes - (optional when creating new contract) The address the transaction is directed to. 4. `data`: `DATA` - The compiled code of a contract OR the hash of the invoked method signature and encoded parameters. For details see [Ethereum Contract ABI](https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI) 5. `gas`: `QUANTITY` - (optional, default: 90000) Integer of the gas provided for the transaction execution. It will return unused gas. 6. `gasPrice`: `QUANTITY` - (optional, default: To-Be-Determined) Integer of the gasPrice used for each paid gas 7. `value`: `QUANTITY` - (optional) Integer of the value sent with this transaction 8. `nonce`: `QUANTITY` - (optional) Integer of a nonce. This allows to overwrite your own pending transactions that use the same nonce. ### Example Parameters ```javascript theme={null} [ { from: "0xb60e8dd61c5d32be8058bb8eb970870f07233155", to: "0xd46e8dd67c5d32be8058bb8eb970870f07244567", data: "0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675", gas: "0x76c0", // 30400 gasPrice: "0x9184e72a000", // 10000000000000 value: "0x9184e72a", // 2441406250 nonce: "0x117", // 279 }, ]; ``` ### Returns `DATA` - the signed transaction data ### Example ```javascript theme={null} // Request { "id": 1, "jsonrpc": "2.0", "method": "eth_signTransaction", "params":[{see above}], } // Result { "id": 1, "jsonrpc": "2.0", "result": "0xe670ec64341771606e55d6b4ca35a1a6b75ee3d5145a99d05921026d1527331" } ``` ## eth\_sendRawTransaction Creates new message call transaction or a contract creation for signed transactions. ### Parameters 1. `DATA`, the signed transaction data. ### Returns `DATA`, 32 Bytes - the transaction hash, or the zero hash if the transaction is not yet available. Use [eth\_getTransactionReceipt](https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_gettransactionreceipt) to get the contract address, after the transaction was mined, when you created a contract. ### Example ```javascript theme={null} // Request { "id": 1, "jsonrpc": "2.0", "method": "eth_sendRawTransaction", "params":[ "0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f07244567" ], } // Result { "id": 1, "jsonrpc": "2.0", "result": "0xe670ec64341771606e55d6b4ca35a1a6b75ee3d5145a99d05921026d1527331" } ``` # WC JSON-RPC for Everscale Source: https://docs.reown.com/advanced/multichain/rpc-reference/everscale-rpc Everscale JSON-RPC Methods **Please note:** The Everscale RPC standard is still under review and specifications may change. Implementation details and method signatures are subject to updates. ### ever\_sign Signature of a random message for authentication. ##### Parameters: 1. message - some message in base64; 2. withSignatureId - bool or number 3. hashData - bool ##### Returns: 1. signature - string signature in base64; 2. pubkey - public key of the wallet's address; ##### Example: ``` // Request { "id": 1, "jsonrpc": "2.0", "method": "ever_sign", "params": { "message": "some message in base64", "withSignatureId": true, "hashData": true } } // Result { "id": 1, "jsonrpc": "2.0", "result": { "signature": "0xa3f207... in base64", "pubkey": "0x07bf94e...37e3" } } ``` ### ever\_sendMessage Creates message, sends it to the network, monitors its processing and returns transaction's id. ##### Parameters: 1. value - amount of coins attached to the message; 2. bounce - should the answer message be generated in case of an error; 3. destAddress - message destination address; 4. destPayload - message destination payload; 4.1. abi - destination contract ABI; 4.2. method - destination contract method; 4.3. params - destination contract method params ##### Returns: 1. txId - transaction's id in blockchain; ##### Example: ``` // Request { "id": 1, "jsonrpc": "2.0", "method": "ever_sendMessage", "params": { "source_address": "0:695e42...b8d", "value": 1000000000, "bounce": False, "destAddress": "0:b38d96...708", "destPayload": { "abi": "", "method": "", "params": {} }, } } // Result { "id": 1, "jsonrpc": "2.0", "result": { "txId": "743e1c0046b82a48a2cf8cbe9a2059ce6f3862cfae377c77d9f1b4efd88d7acb" } } ``` ### ever\_signMessage Message that can then be sent to the blockchain. ##### Parameters: 1. value - amount of coins attached to the message; 2. bounce - should the answer message be generated in case of an error; 3. destAddress - message destination address; 4. destPayload - message destination payload; 4.1. abi - destination contract ABI; 4.2. method - destination contract method; 4.3. params - destination contract method params ##### Returns: 1. signedExtMessage - signed external message; 2. expireAt - message expiration timestamp ##### Example: ``` // Request { "id": 1, "jsonrpc": "2.0", "method": "ever_processMessage", "params": { "source_address": "0:695e42...b8d", "value": 1000000000, "bounce": False, "destAddress": "0:b38d96...708", "destPayload": { "abi": "", "method": "", "params": {} }, } } // Result { "id": 1, "jsonrpc": "2.0", "result": { "signedExtMessage": "c0b0996a9f0ea8e472041857ff2da9cf8086a78603f823a7170891f43a217ff1", "expireAt": 1685594678 } } ``` ### ever\_sendExternalMessage Sends an external message to the contract. ##### Parameters: 1. destAddress - message destination address; 2. destPayload - message destination payload; 2.1. abi - destination contract ABI; 2.2. method - destination contract method; 2.3. params - destination contract method params ##### Returns: 1. txId - transaction's id in blockchain; ##### Example: ``` // Request { "id": 1, "jsonrpc": "2.0", "method": "ever_sendExternalMessage", "params": { "sourceAddress": "0:695e42...b8d", "destAddress": "0:b38d96...708", "destPayload": { "abi": "", "method": "", "params": {} }, } } // Result { "id": 1, "jsonrpc": "2.0", "result": { "txId": "743e1c0046b82a48a2cf8cbe9a2059ce6f3862cfae377c77d9f1b4efd88d7acb" } }; ``` ### ever\_broadcastMessage Sends an internal message from the user account without waiting for the transaction. ##### Parameters: 1. value - amount of coins attached to the message; 2. bounce - should the answer message be generated in case of an error; 3. destAddress - message destination address; 4. destPayload - message destination payload; 4.1. abi - destination contract ABI; 4.2. method - destination contract method; 4.3. params - destination contract method params ##### Returns: 1. hash: string - external message hash; 2. account: string - destination account address (equals to source\_address); 3. expireAt: number - message expiration timestamp ##### Example: ``` // Request { "id": 1, "jsonrpc": "2.0", "method": "ever_broadcastMessage", "params": { "sourceAddress": "0:695e42...b8d", "value": 1000000000, "bounce": False, "destAddress": "0:b38d96...708", "destPayload": { "abi": "", "method": "", "params": {} }, } } // Result { "id": 1, "jsonrpc": "2.0", "result": { "hash": "743e1c0046b82a48a2cf8cbe9a2059ce6f3862cfae377c77d9f1b4efd88d7acb", "account": "0:695e42...b8d", "expireAt": 1684327417543 } }; ``` ### ever\_broadcastExternalMessage Sends an external message to the contract without waiting for the transaction. ##### Parameters: 1. destAddress - message destination address; 2. destPayload - message destination payload; 2.1. abi - destination contract ABI; 2.2. method - destination contract method; 2.3. params - destination contract method params ##### Returns: 1. hash: string - external message hash; 2. account: string - destination account address (equals to source\_address); 3. expireAt: number - message expiration timestamp ##### Example: ``` // Request { "id": 1, "jsonrpc": "2.0", "method": "ever_broadcastExternalMessage", "params": { "sourceAddress": "0:695e42...b8d", "destAddress": "0:b38d96...708", "destPayload": { "abi": "", "method": "", "params": {} }, } } // Result { "id": 1, "jsonrpc": "2.0", "result": { "hash": "743e1c0046b82a48a2cf8cbe9a2059ce6f3862cfae377c77d9f1b4efd88d7acb", "account": "0:b38d96...708", "expireAt": 1684327417543 } } ``` ### ever\_addTokenAsset Adds asset (TIP-3 or native tokens) to the selected account. ##### Parameters: 1. rootContract - asset root address. Note: you can add native coin by leaving this field empty ##### Returns: 1. newAsset: bool - returns true if the account did not have this asset before ##### Example: ``` // Request { "id": 1, "jsonrpc": "2.0", "method": "ever_addTokenAsset", "params": { "sourceAddress": "0:695e42...b8d", "rootContract": "0:b38d96...708" } } // Result { "id": 1, "jsonrpc": "2.0", "result": { "newAsset": true } } ``` ### ever\_encryptData Encrypts arbitrary data with specified algorithm for each specified recipient. ##### Parameters: 1. recipientPublicKeys - public keys of recipients. Hex encoded; 2. algorithm - encryption algorithm. Currently supports only “ChaCha20Poly1305” 3. data - base64 encoded data; ##### Returns: 1. encryptedData - encrypted data for each recipient 1.1. algorithm - encryption algorithm 1.2. sourcePublicKey - hex encoded encryptor's public key 1.3. recipientPublicKey - hex encoded recipient public key 1.4. data - base64 encoded data 1.5. nonce - base64 encoded nonce ##### Example: ``` // Request { "id": 1, "jsonrpc": "2.0", "method": "ever_encryptData", "params": { "sourceAddress": "0:695e42...b8d", "recipientPublicKeys": ["0x6e74...4e95", "0x9532...403f"], "algorithm": "ChaCha20Poly1305", "data": "ZGF0YQ==" } } // Result { "id": 1, "jsonrpc": "2.0", "result": { "encryptedData": [ { "algorithm": "ChaCha20Poly1305", "sourcePublicKey": "0x209f...d08f", "recipientPublicKey": "0x6e74...4e95", "data": "ZW5jRGF0YTE=", "nonce": "bm9uY2Ux" }, { "algorithm": "ChaCha20Poly1305", "sourcePublicKey": "0x209f...d08f", "recipientPublicKey": "0x6e74...4e95", "data":"ZW5jRGF0YTI=", "nonce":"bm9uY2Uy" } ] } }; ``` ### ever\_decryptData Decrypts encrypted data. ##### Parameters: 1. algorithm - encryption algorithm. Currently supports only “ChaCha20Poly1305” 2. recipientPublicKey - hex encoded recipient public key 3. data - base64 encoded data 4. nonce - base64 encoded nonce ##### Returns: 1. data - base64 encoded decrypted data ##### Example: ``` // Request { "id": 1, "jsonrpc": "2.0", "method": "ever_decryptData", "params": { "sourceAddress": "0:695e42...b8d", "algorithm": "ChaCha20Poly1305", "recipientPublicKey": "0x6e74...4e95", "data": "ZW5jRGF0YTE=", "nonce": "bm9uY2Ux" } } // Result { "id": 1, "jsonrpc": "2.0", "result": { "data": "ZGF0YQ==" } }; ``` # Hedera Source: https://docs.reown.com/advanced/multichain/rpc-reference/hedera-rpc Hedera JSON-RPC Methods **Please note:** The Hedera RPC standard is still under review and specifications may change. Implementation details and method signatures are subject to updates. The following JSON-RPC methods offer native integration into Hedera utilizing the [Hedera APIs](https://hashgraph.github.io/hedera-protobufs/) and the [Hedera SDKs](https://docs.hedera.com/hedera/sdks-and-apis/sdks). Hedera documentation can be found at [docs.hedera.com](https://docs.hedera.com/hedera/). The following resources provide specific information referenced in the methods below. * The Hedera network structure is summarized by [Mainnet Nodes](https://docs.hedera.com/hedera/networks/mainnet/mainnet-nodes) * The full list of Hedera functionality is described by the protobuf definitions: [Hedera Functionality](https://hashgraph.github.io/hedera-protobufs/#proto.HederaFunctionality) * Further details about these methods can be found in the accompanying Hedera Improvement Proposal: [HIP-820](https://hips.hedera.com/hip/hip-820) * The `signerAccountId` utilized in the methods below is specified by [HIP-30](https://hips.hedera.com/hip/hip-30) * A Hedera Transaction ID is composed of the account id that pays for a transaction and the valid start timestamp in nanoseconds: [Hedera Transaction ID](https://docs.hedera.com/hedera/sdks-and-apis/sdks/transactions/transaction-id) * There are pre-processing validation response codes returned by the network: [ResponseCodeEnum](https://github.com/hashgraph/hedera-protobufs/blob/f36e05bd6bf3f572707ca9bb338f5ad6421a4241/services/response_code.proto#L32) *Hedera has a separate open-source project implementing parts of the [Ethereum JSON-RPC standard](https://docs.hedera.com/hedera/core-concepts/smart-contracts/json-rpc-relay) which is not covered in this documentation.* ## Methods * [`hedera_signAndExecuteTransaction`](#hedera_signandexecutetransaction) * [`hedera_signTransaction`](#hedera_signtransaction) * [`hedera_executeTransaction`](#hedera_executetransaction) * [`hedera_signAndExecuteQuery`](#hedera_signandexecutequery) * [`hedera_signMessage`](#hedera_signmessage) * [`hedera_getNodeAddresses`](#hedera_getnodeaddresses) ## hedera\_signAndExecuteTransaction The `hedera_signAndExecuteTransaction` method is a generic method for executing a transaction on the Hedera network. A dApp can begin by constructing a transaction with one of the Hedera SDKs or by constructing the raw protobuf messages and may select one or more consensus nodes that are authorized to execute the transaction. The dApp then constructs a list of valid transaction bytes that differ only in the node account id and serializes the list, for example by using the `toBytes()` method of an SDK. Finally, the dApp base64 encodes the resulting bytes. This final base64 encoded string of bytes is sent as a method param titled `transactionList` to the wallet. Wallets and SDKs must take special care to deserialize the list of transactions and validate that each transaction in the list differs only in the node authorized to receive the transaction and does NOT differ in intent before submitting to an end user for approval and ultimately signing. ### Parameters 1. `Object` - signAndExecuteTransaction parameters 1.1. `signerAccountId` : `String` - Hedera account id in the format `:..<-optional-checksum>` 1.2. `transactionList` : `String` - Base64 encoded string of TransactionList bytes ### Returns 1. `Object` - Result of transaction submission to Hedera network 1.1. `nodeId` : `String` - The Hedera node the transaction was submitted to 1.2. `transactionHash` : `String` - The hash of the transaction 1.3. `transactionId` : `String` - Transaction ID, which includes the payer account id and the valid start timestamp ### Error In certain conditions, the Hedera network will return a response that signifies a pre-processing validation error, for example, when the transaction has expired. In these cases, wallets will return an error with the following format: 1. `Object` - Result of transaction submission to Hedera network 1.1. `code` : 9000 - The reserved WalletConnect error code for unknown errors or errors not related to the WalletConnect protocol 1.2. `message` : `String` - A human readable string describing the nature of the failure 1.3. `data` : `Number` - An integer representing the ResponseCodeEnum value returned from the Hedera Node, which indicates the reason for the failure ### Example #### Request ```json theme={null} { "id": 1, "jsonrpc": "2.0", "method": "hedera_signAndExecuteTransaction", "params": { "signerAccountId": "hedera:testnet:0.0.12345", "transactionList": "Co8BKowBCocBChoKDAjchKWmBhDW..." } } ``` #### Result ```json theme={null} { "id": 1, "jsonrpc": "2.0", "result": { "nodeId": "0.0.3", "transactionHash": "252b8fd...", "transactionId": "0.0.12345678@1689281510.675369303" } } ``` #### Error ```json theme={null} { "id": 1, "jsonrpc": "2.0", "error": { "code": 9000, "message": "The transaction failed with precheck code...", "data": 6 } } ``` ## hedera\_signTransaction The `hedera_signTransaction` signs a `TransactionBody` and returns a `SignatureMap` to the caller. ### Parameters 1. `Object` - signTransaction parameters 1.1 `signerAccountId` : `String` - Hedera account id in the format `:..<-optional-checksum>` 1.2 `transactionBody` : `String` - Base64 encoded string representation of TransactionBody ### Returns 1. `Object` - SignatureMap of related signed TransactionBody 1.1 `signatureMap` : `String` - Base64 encoded string of SignatureMap ### Example #### Request ```json theme={null} { "id": 1, "jsonrpc": "2.0", "method": "hedera_signTransaction", "params": { "signerAccountId": "hedera:testnet:0.0.12345", "transactionBody": "Co8BKowBCocBChoKDAjchKWmBhDW..." } } ``` #### Result ```json theme={null} { "id": 1, "jsonrpc": "2.0", "result": { "signatureMap": "VGhpcyBpcyBqdXN0IHNvbWUgc3R1..." } } ``` ## hedera\_executeTransaction When a dApp only requires the services of the controller to act as a relay to the Hedera network for submitting an already signed transaction, it can use the `hedera_executeTransaction` method. ### Parameters 1. `Object` - executeTransaction parameters 1.1 `transactionList` : `String` Base64 encoded TransactionList ### Returns 1. `Object` - Result of transaction submission to the Hedera network 1.1. `nodeId` : `String` - The Hedera node the transaction was submitted to 1.1. `transactionHash` : `String` - The hash of the transaction 1.1. `transactionId` : `String` - Transaction ID, which includes the payer account id and the valid start timestamp ### Error In certain conditions, the Hedera network with return a response that signifies a pre-processing validation error, for example, when the transaction has expired. In these cases, wallets will return an error with the following format: 1. `Object` - Result of transaction submission to the Hedera network 1.1. `code` : 9000 - The reserved WalletConnect error code for unknown errors or errors not related to the WalletConnect protocol 1.1. `message` : `String` - A human readable string describing the nature of the failure 1.1. `data` : `Number` - An integer representing the ResponseCodeEnum value returned from the Hedera Node, which indicates the reason for the failure ### Example #### Request ```json theme={null} { "id": 1, "jsonrpc": "2.0", "method": "hedera_executeTransaction", "params": { "transactionList": "Co8BKowBCocBChoKDAjchKWmBhDW..." } } ``` #### Result ```json theme={null} { "id": 1, "jsonrpc": "2.0", "result": { "nodeId": "0.0.3", "transactionHash": "252b8fd...", "transactionId": "0.0.12345678@1689281510.675369303" } } ``` #### Error ```json theme={null} { "id": 1, "jsonrpc": "2.0", "error": { "code": 9000, "message": "The transaction failed with precheck code...", "data": 6 } } ``` ## hedera\_signAndExecuteQuery This method provides functionality to perform a query on a Hedera consensus node. Many Queries against consensus nodes have a transaction fee [Learn more about Queries](https://docs.hedera.com/hedera/sdks-and-apis/sdks/queries). Most requests that do not change network state can be performed against a [Mirror Node](https://docs.hedera.com/hedera/core-concepts/mirror-nodes) and for many use cases calling a mirror node endpoint is the recommended approach. ### Parameters 1. `Object` - signAndExecuteQuery parameters 1.1 `signerAccountId` : `String` - Hedera account id in the format `:..<-optional-checksum>` 1.2 `query` : `String` - base64 encoded Query ### Returns 1. `Object` - Result of the Query submitted to a Hedera consensus node 1.1. `response` : `String` - Base64 encoding of the Hedera API response ## hedera\_signMessage This method accepts a plain text string value as input. If approved by the user, the controller UTF-8 encodes this message prepended with "\x19Hedera Signed Message:\n" plus the length of the message and signs the resulting bytes in the same manner as HAPI transactions are signed. The resulting signature(s) are transmitted back to the user encoded in a SignatureMap structure. The pseudo code for computing the signature is as follows: ```javascript theme={null} .sign("\x19Hedera Signed Message:\n" + len(message) + message) ``` ### Parameters 1. `Object` - signMessage parameters 1.1 `signerAccountId` : `String` - Hedera account id in the format `:..<-optional-checksum>` 1.2 `message` : `String` ### Returns 1. `Object` - signMessage result 1.1 `signatureMap` : `String` - Base64 encoded SignatureMap ### Example #### Request ```json theme={null} { "id": 1, "jsonrpc": "2.0", "method": "hedera_signMessage", "params": { "signerAccountId": "hedera:testnet:0.0.12345" "message": "Co8BKowBCocBChoKDAjchKWmBhDW..." } } ``` #### Result ```json theme={null} { "id": 1, "jsonrpc": "2.0", "result": { "signatureMap": "CAAQABjMrxoYABIGCAAQABgHGIDIr..." } } ``` ## hedera\_getNodeAddresses While constructing a transaction for transmission to a controller, a dApp needs to choose which Hedera Network node shall receive the transaction prior to signing (this is a requirement of the Hedera API Protocol). While a dApp can easily obtain a list of potential Hedera Nodes, a controller may not have an all-inclusive list nor a path to the node’s gRPC endpoint. The `hedera_getNodeAddresses` method allows a dApp to request a list of node wallet addresses known to the controller. The controller should only include nodes in this list that it is willing and able to submit transactions to at the time of the request. ### Returns 1. `Object` - signMessage result 1.1 `nodes` : `Array` - an array of strings in `..<-optional-checksum>` format, each identifying a node by its Hedera Address ### Example #### Request ```json theme={null} { "id": 1, "jsonrpc": "2.0", "method": "hedera_getNodeAddresses" } ``` #### Result ```json theme={null} { "id": 1, "jsonrpc": "2.0", "result": { "nodes": ["0.0.3", "0.0.4"] } } ``` # Litecoin Source: https://docs.reown.com/advanced/multichain/rpc-reference/litecoin-rpc Litecoin JSON-RPC Methods **Please note:** The Litecoin RPC standard is still under review and specifications may change. Implementation details and method signatures are subject to updates. We define an account as the group of addresses derived using the same account value in their [derivation paths](https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki#user-content-Path_levels).We use the first address of the [external chain](https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki#examples) ("first external address"), as the identifier for an account. An account's total balance is defined as the sum of all unspent transaction outputs (UTXOs) belonging to its entire group of addresses. 1. Dapps **must** only display the first external address as a connected account. 2. Wallets **must** only offer to connect the first external address(es). #### Account Definition The derivation path levels in the [BIP44](https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki#path-levels), [BIP49](https://github.com/bitcoin/bips/blob/master/bip-0049.mediawiki#user-content-Public_key_derivation), [BIP84](https://github.com/bitcoin/bips/blob/master/bip-0084.mediawiki#public-key-derivation), [BIP86](https://github.com/bitcoin/bips/blob/master/bip-0086.mediawiki#user-content-Public_key_derivation) standards are: ``` m / purpose' / coin_type' / account' / change / address_index ``` Addresses with different `purpose`, `change` and `address_index` values are considered to belong to the same account. Valid `purpose` values are 44, 49, 84 and 86. We use the first external Native SegWit (purpose = 84) address as the default account identifier. For a specific seed phrase and path `m/84'/2'/0'/0/0` we get account 0 with identifier `ltc1q8c6fshw2dlwun7ekn9qwf37cu2rn755u9ym7p0`. Its total balance is the sum of all UTXO balances on all addresses with derivation paths: * `m/44'/2'/0'/change/address_index` * `m/49'/2'/0'/change/address_index` * `m/84'/2'/0'/change/address_index` * `m/86'/2'/0'/change/address_index` If the wallet user changes to account 1 we get path `m/84'/2'/1'/0/0` with identifier `ltc1qn9h77dt0s6ar78ptxq58t2ne7tyhvfnruc3e7d`. Its total balance is the sum of all UTXO balances on all addresses with derivation paths: * `m/44'/2'/1'/change/address_index` * `m/49'/2'/1'/change/address_index` * `m/84'/2'/1'/change/address_index` * `m/86'/2'/1'/change/address_index` ## sendTransfer This method is used to sign and submit a transfer of any `amount` of Litecoin to a single `recipientAddress`, optionally including a `changeAddress` for the change amount and `memo` set as the OP\_RETURN value by supporting wallets. The transaction will be signed and broadcast upon user approval. ### Parameters * `Object` * `account` : `String` - *(Required)* The connected account's first external address. * `recipientAddress` : `String` - *(Required)* The recipient's public address. * `amount` : `String` - *(Required)* The amount of Litecoin to send, denominated in litoshis (Litecoin base unit). * `changeAddress` : `String` - *(Optional)* The sender's public address to receive change. * `memo` : `String` - *(Optional)* The OP\_RETURN value as a hex string without 0x prefix, maximum 80 bytes. ### Returns * `Object` * `txid` : `String` - The transaction id as a hex string without 0x prefix. ### Example The example below specifies a simple transfer of 1.23 LTC (123000000 Litoshi). ```javascript theme={null} // Request { "id": 1, "jsonrpc": "2.0", "method": "sendTransfer", "params": { "account": "ltc1q8c6fshw2dlwun7ekn9qwf37cu2rn755u9ym7p0", "recipient": "ltc1qn9h77dt0s6ar78ptxq58t2ne7tyhvfnruc3e7d", "amount": "123000000", "memo": "636861726c6579206c6f766573206865" } } // Result { "id": 1, "jsonrpc": "2.0", "result": { "txid": "f007551f169722ce74104d6673bd46ce193c624b8550889526d1b93820d725f7" } } ``` ## getAccountAddresses This method returns all current addresses needed for a dapp to fetch all UTXOs, calculate the total balance and prepare transactions. Dapps will typically use an indexing service to query for balances and UTXOs for all addresses returned by this method, such as: * [Blockbook API](https://github.com/trezor/blockbook/blob/master/docs/api.md#get-address) * [Bitcore API](https://github.com/bitpay/bitcore/blob/master/packages/bitcore-node/docs/api-documentation.md#address) We recognize that there are two broad classes of wallets in use today: 1. Wallets that generate a new change or receive address for every transaction ("dynamic wallet"). 2. Wallets that reuse the first external address for every transaction ("static wallet"). #### Implementation Details * All wallets **should** include the first external address and all addresses with one or more UTXOs, unless they're filtered by `intentions`. * Dynamic wallets **should** include minimum 2 unused change and receive addresses. Otherwise dapps may have to request [getAccountAddresses](#getAccountAddresses) after every transaction to discover the new addresses and keep track of the user's total balance. * All wallets **must** return fewer than 20 unused change and receive addresses to avoid breaking the [gap limit](https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki#address-gap-limit). ### Parameters * `Object` * `account` : `String` - *(Required)* The connected account's first external address. * `intentions` : `String[]` - *(Optional)* Filter what addresses to return, e.g. "payment" or "ordinal". ### Returns * `Array` * `Object` * `address` : `String` - *(Required)* Public address belonging to the account. * `publicKey` : `String` - *(Optional)* Public key for the derivation path in hex, without 0x prefix. * `path` : `String` - *(Optional)* Derivation path of the address e.g. "m/84'/2'/0'/0/0". * `intention` : `String` - *(Optional)* Intention of the address, e.g. "payment" or "ordinal". ### Example: Dynamic Wallet The example below specifies a result from a dynamic wallet. For the sake of this example, receive and change addresses with index 3-4 are considered unused and addresses with paths `m/49'/2'/0'/0/7` and `m/84'/2'/0'/0/2` are considered to have UTXOs. Assuming the dapp monitors all returned addresses for balance changes, a new request to `getAccountAddresses` is only needed when all UTXOs in provided addresses have been spent, or when all provided `receive` addresses or `change` addresses have been used. ```javascript theme={null} // Request { "id": 1, "jsonrpc": "2.0", "method": "getAccountAddresses", "params": { "account": "ltc1q8c6fshw2dlwun7ekn9qwf37cu2rn755u9ym7p0" } } // Result { "id": 1, "jsonrpc": "2.0", "result": [ { "address": "ltc1q8c6fshw2dlwun7ekn9qwf37cu2rn755u9ym7p0", "path": "m/84'/2'/0'/0/0" }, { "address": "LXkGhTKmZpviAtYdDaxWbiJsdg4tA6EzrU", "path": "m/49'/2'/0'/0/7" }, { "address": "ltc1qj4plcuyhuzw0sycf99gcayzhhcddfj6xkcke5g", "path": "m/84'/2'/0'/0/2" }, { "address": "ltc1qsdxa6pseqekqg5d3uksaxnwrey2s2ujcx03alc", "path": "m/84'/2'/0'/0/3" }, { "address": "ltc1qhuvt3sq8xmx9ktzdfznkzvjl5zup7mg9zpwllw", "path": "m/84'/2'/0'/0/4" }, { "address": "ltc1qtjd3y5a2axpwzfjcj4y9zy50qfjuxwzm0vu5fq", "path": "m/84'/2'/0'/1/3" }, { "address": "ltc1qp7ujtprgl0quvcg0dj335p37r2mc2cxdc8xumq", "path": "m/84'/2'/0'/1/4" } ] } ``` ### Example: Static Wallet The example below specifies a response from a static wallet. The returned address is used for both change and payments. It's the only address with UTXOs. ```javascript theme={null} // Request { "id": 1, "jsonrpc": "2.0", "method": "getAccountAddresses", "params": { "account": "ltc1q8c6fshw2dlwun7ekn9qwf37cu2rn755u9ym7p0" } } // Result { "id": 1, "jsonrpc": "2.0", "result": [ { "address": "ltc1q8c6fshw2dlwun7ekn9qwf37cu2rn755u9ym7p0", "path": "m/84'/2'/0'/0/0" } ] } ``` ## signPsbt This method can be used to request the signature of a Partially Signed Bitcoin Transaction (PSBT) and covers use-cases e.g. involving multiple-recipient transactions, requiring granular control over which UTXOs to spend or how to route change. ### Parameters * `Object` * `account` : `String` - *(Required)* The connected account's first external address. * `psbt` : `String` - *(Required)* Base64 encoded string of the PSBT to sign. * `signInputs` : `Array` * `Object` * `address` : `String` - *(Required)* The address whose private key to use for signing. * `index` : `Integer` - *(Required)* Specifies which input to sign. * `sighashTypes` : `Integer[]` - *(Optional)* Specifies which part(s) of the transaction the signature commits to. Default is `[1]`. * `broadcast` : `Boolean` - *(Optional)* Whether to finalize and broadcast the transaction after signing it. Default is `false`. ### Returns * `Object` * `psbt` : `String` - *(Required)* The base64 encoded signed PSBT. * `txid` : `String` - *(Optional)* The transaction ID as a hex-encoded string, without 0x prefix. This must be returned if the transaction was broadcasted. ## signMessage This method is used to sign a message with one of the connected account's addresses. ### Parameters * `Object` * `account` : `String` - *(Required)* The connected account's first external address. * `message` : `String` - *(Required)* The message to be signed by the wallet. * `address` : `String` - *(Optional)* The address whose private key to use for signing the message. * `protocol` : `"ecdsa" | "bip322"` - *(Optional)* Preferred signature type. Default is `"ecdsa"`. ### Returns * `Object` * `address` : `String` - *(Required)* The Litecoin address used to sign the message. * `signature` : `String` - *(Required)* Hex encoded bytes of the signature, without 0x prefix. * `messageHash` : `String` - *(Optional)* Hex encoded bytes of the message hash, without 0x prefix. ## Events ### bip122\_addressesChanged This event is used by wallets to notify dapps about connected accounts' current addresses, for example all addresses with a UTXO and a few unused addresses. The event data has the same format as the [getAccountAddresses](#getaccountaddresses) result. #### Implementation Details * Wallets **should** emit a `bip122_addressesChanged` event immediately after connection approval of a BIP122 chain. * Wallets **should** emit a `bip122_addressesChanged` event whenever a UTXO is spent or created for a connected account's addresses. * Dapps **should** listen for `bip122_addressesChanged` events, collect and monitor all addresses for UTXO and balance changes. Example [session\_event](https://specs.walletconnect.com/2.0/specs/clients/sign/session-events#session_event) payload as received by a dapp: ``` { "id": 1675759795769537, "topic": "95d6aca451b8e3c6d9d176761bf786f1cc0a6d38dffd31ed896306bb37f6ae8d", "params": { "event": { "name": "bip122_addressesChanged", "data": [ { "address": "ltc1q8c6fshw2dlwun7ekn9qwf37cu2rn755u9ym7p0", "path": "m/84'/2'/0'/0/0" }, { "address": "LXkGhTKmZpviAtYdDaxWbiJsdg4tA6EzrU", "path": "m/49'/2'/0'/0/7" }, { "address": "ltc1qj4plcuyhuzw0sycf99gcayzhhcddfj6xkcke5g", "path": "m/84'/2'/0'/0/2" }, { "address": "ltc1qsdxa6pseqekqg5d3uksaxnwrey2s2ujcx03alc", "path": "m/84'/2'/0'/0/3" }, { "address": "ltc1qhuvt3sq8xmx9ktzdfznkzvjl5zup7mg9zpwllw", "path": "m/84'/2'/0'/0/4" }, { "address": "ltc1qtjd3y5a2axpwzfjcj4y9zy50qfjuxwzm0vu5fq", "path": "m/84'/2'/0'/1/3" }, { "address": "ltc1qp7ujtprgl0quvcg0dj335p37r2mc2cxdc8xumq", "path": "m/84'/2'/0'/1/4" } ] }, "chainId": "bip122:12a765e31ffd4059bada1e25190f6e98" } } ``` # NEAR Source: https://docs.reown.com/advanced/multichain/rpc-reference/near-rpc NEAR JSON-RPC Methods **Please note:** The NEAR RPC standard is still under review and specifications may change. Implementation details and method signatures are subject to updates. The method names below are based on the [Bridge Wallets](https://github.com/near/NEPs/blob/master/specs/Standards/Wallets/BridgeWallets.md#) Standard for NEAR. ## near\_getAccounts Retrieve all accounts visible to the session. `publicKey` references the underlying `FullAccess` key linked to each account. ### Parameters none ### Returns 1.`Array` - Array of accounts: 1.1. `Object` 1.1.1. `accountId` : `String` - The account name to which the publicKey corresponds as plain text 1.1.2. `publicKey` : `String` - The public counterpart of the key used to sign, expressed as a string with format `:` ### Example ```javascript theme={null} // Request { "id": 1, "jsonrpc": "2.0", "method": "near_getAccounts", "params": {} } // Result { "id": 1, "jsonrpc": "2.0", "result": [{ "accountId": "alice.near", "publicKey": "ed25519:DmnRVNb89cLKZY1cH1Zcr3rxMVD9r1cVfnDac7RFwM94" }] } ``` ## near\_signIn For dApps that often sign gas-only transactions, `FunctionCall` access keys can be created for one or more accounts to greatly improve the UX. While this could be achieved with `signTransactions`, it suggests a direct intention that a user wishes to sign in to a dApp's smart contract. ### Parameters 1. `Object` - Sign In parameters: 1.1. `permission` : `Object` - Function call key permission parameters 1.1.1. `receiverId` : `String` - smart contract for which the function call access key will be created 1.1.2. `methodNames` : `Array` - list of methods that can be called on the smart contract 1.2. `accounts` : `Array` - list of accounts for which a FunctionCall access key will be added: 1.2.1. `Object` - Account 1.2.1.1. `accountId` : `String` - The account name to which the publicKey corresponds as plain text 1.2.1.2. `publicKey` : `String` - The public counterpart of the key used to sign, expressed as a string with format `:` ### Returns void ### Example ```javascript theme={null} // Request { "id": 1, "jsonrpc": "2.0", "method": "near_signIn", "params": { "permission": { "receiverId": "guest-book.testnet", "methodNames": [] }, "accounts": [{ "accountId": "alice.near", "publicKey": "ed25519:DmnRVNb89cLKZY1cH1Zcr3rxMVD9r1cVfnDac7RFwM94" }] } } ``` ## near\_signOut Delete one or more `FunctionCall` access keys created with `signIn`. While this could be achieved with `signTransactions`, it suggests a direct intention that a user wishes to sign out from a dApp's smart contract. ### Parameters 1.`Array` - Array of accounts: 1.1. `Object` 1.1.1. `accountId` : `String` - The account name to which the publicKey corresponds as plain text 1.1.2. `publicKey` : `String` - The public counterpart of the key used to sign, expressed as a string with format `:` ### Returns void ### Example ```javascript theme={null} // Request { "id": 1, "jsonrpc": "2.0", "method": "near_signOut", "params": { "accounts": [{ "accountId": "alice.near", "publicKey": "ed25519:DmnRVNb89cLKZY1cH1Zcr3rxMVD9r1cVfnDac7RFwM94" }] } } ``` ## near\_signTransaction Sign a transaction. It makes use of [near-api-js](https://github.com/near/near-api-js) to enable interoperability with dApps that will already use it for constructing transactions and communicating with RPC endpoints. [Transaction](https://nomicon.io/RuntimeSpec/Transactions) passed to `signTransaction` must be encoded. ### Parameters 1. `Object` - Signing parameters: 1.1. `transaction` : `Uint8Array` - Encoded Transaction via transactions.Transaction.encode() ### Returns The result of `signTransaction` and is encoded [SignedTransaction](https://nomicon.io/RuntimeSpec/Transactions#signed-transaction) model. 1. `Uint8Array` - Encoded SignedTransaction via transactions.SignedTransaction.encode() ### Example ```javascript theme={null} // Request { "id": 1, "jsonrpc": "2.0", "method": "near_signTransaction", "params": { "transaction": { "type": "Buffer", "data": [32, 0, 0, 0, 100, 101, 118, 45, 49, 54, 55, 49, 51, 56, 55, 51, 57, 56 ...] } } } // Result { "id": 1, "jsonrpc": "2.0", "result": { "type": "Buffer", "data": [32, 0, 0, 0, 100, 101, 118, 45, 49, 54, 55, 49, 51, 56, 55, 51, 57, 56 ...] } } ``` ## near\_signTransactions Sign a list of transactions. It makes use of [near-api-js](https://github.com/near/near-api-js) to enable interoperability with dApps that will already use it for constructing transactions and communicating with RPC endpoints. [Transactions](https://nomicon.io/RuntimeSpec/Transactions) passed to `signTransactions` must be encoded. ### Parameters 1. `Array` - Signing parameters: 1.1. `transactions` : `Array` - Array of Encoded Transaction via transactions.Transaction.encode() ### Returns The result of `signTransactions` and are encoded [SignedTransaction](https://nomicon.io/RuntimeSpec/Transactions#signed-transaction) models. 1. `Array` - Array of Encoded SignedTransaction via transactions.SignedTransaction.encode() ### Example ```javascript theme={null} // Request { "id": 1, "jsonrpc": "2.0", "method": "near_signTransactions", "params": { "transactions": [ { "type": "Buffer", "data": [32, 0, 0, 0, 100, 101, 118, 45, 49, 54, 55, 49, 53, 52, 49, 55, 56, 57, 51, 50 ...] }, { "type": "Buffer", "data": [32, 0, 0, 0, 100, 101, 118, 45, 49, 54, 55, 49, 53, 52, 49, 55, 56, 57, 51, 50 ...] } ] } } // Result { "id": 1, "jsonrpc": "2.0", "result": [ { "type": "Buffer", "data": [32, 0, 0, 0, 100, 101, 118, 45, 49, 54, 55, 49, 53, 52, 49, 55, 56, 57, 51, 50 ...] }, { "type": "Buffer", "data": [32, 0, 0, 0, 100, 101, 118, 45, 49, 54, 55, 49, 53, 52, 49, 55, 56, 57, 51, 50 ...] } ] } ``` # Polkadot Source: https://docs.reown.com/advanced/multichain/rpc-reference/polkadot-rpc Polkadot SDK JSON-RPC Methods **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 { "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 } } } // Result { "id": 1, "jsonrpc": "2.0", "result": { "signature": "0x01234567..." } } ``` 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. ## polkadot\_signMessage This method returns a signature for the provided message payload. It will be signed by a keypair corresponding to the requested signer address. ### Parameters 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 `polkadot_signMessage` can potentially be used to sign arbitrary transactions blindly. To mitigate this security risk: 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 This convention helps prevent malicious applications from using `polkadot_signMessage` for blind transaction signing while maintaining compatibility with widely-used Polkadot signing implementations. ### Returns 1. `Object` - Signature result: * `signature`: `string` - Hex-encoded signature ### Example ```javascript theme={null} // Request { "id": 1, "jsonrpc": "2.0", "method": "polkadot_signMessage", "params": { "address": "15UyNqZ7NB1QQVpY9xv7VGwkxtvXePKihFHx8kH4VgEcS1gU", "data": "0x3c42797465733e68656c6c6f20776f726c643c2f42797465733e", // "hello world" hex encoded "type": "bytes" } } // Result { "id": 1, "jsonrpc": "2.0", "result": { "signature": "0x6a98517e159dcaef1855cda5f5e5a61387ac3b63212b0f82642f5599502fc9eb1ea134e2db5dfbe0ec4530c6e7e576b177ad0618f68eaec37a3ac6dce819a30a" } } ``` ## Additional Resources For more information about Polkadot RPC methods and integration details, please refer to: * [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) # Solana Source: https://docs.reown.com/advanced/multichain/rpc-reference/solana-rpc Solana JSON-RPC Methods ## solana\_getAccounts This method returns an Array of public keys available to sign from the wallet. ### Parameters none ### Returns `Array` - Array of accounts: * `Object` : * `pubkey` : `String` - public key for keypair ### Example ```typescript theme={null} // Request { "id": 1, "jsonrpc": "2.0", "method": "solana_getAccounts", "params": {} } // Result { "id": 1, "jsonrpc": "2.0", "result": [{ "pubkey": "722RdWmHC5TGXBjTejzNjbc8xEiduVDLqZvoUGz6Xzbp" }] } ``` ## solana\_requestAccounts This method returns an Array of public keys available to sign from the wallet. ### Parameters none ### Returns `Array` - Array of accounts: * `Object` : * `pubkey` : `String` - public key for keypair ### Example ```typescript theme={null} // Request { "id": 1, "jsonrpc": "2.0", "method": "solana_getAccounts", "params": {} } // Result { "id": 1, "jsonrpc": "2.0", "result": [{ "pubkey": "722RdWmHC5TGXBjTejzNjbc8xEiduVDLqZvoUGz6Xzbp" }] } ``` ## solana\_signMessage This method returns a signature for the provided message from the requested signer address. ### Parameters `Object` - Signing parameters: * `message` : `String` - the message to be signed (base58 encoded) * `pubkey` : `String` - public key of the signer ### Returns `Object`: * `signature` : `String` - corresponding signature for signed message ### Example ```javascript theme={null} // Request { "id": 1, "jsonrpc": "2.0", "method": "solana_signMessage", "params": { "message": "37u9WtQpcm6ULa3VtWDFAWoQc1hUvybPrA3dtx99tgHvvcE7pKRZjuGmn7VX2tC3JmYDYGG7", "pubkey": "AqP3MyNwDP4L1GJKYhzmaAUdrjzpqJUZjahM7kHpgavm" } } // Result { "id": 1, "jsonrpc": "2.0", "result": { signature: "2Lb1KQHWfbV3pWMqXZveFWqneSyhH95YsgCENRWnArSkLydjN1M42oB82zSd6BBdGkM9pE6sQLQf1gyBh8KWM2c4" } } ``` ## solana\_signTransaction This method returns a signature over the provided instructions by the targeted public key. **WARNING**: Refer always to `transaction` param. The deprecated parameters are not compatible with versioned transactions. ### Parameters `Object` - Signing parameters:
* `transaction` : `String` - base64-encoded serialized transaction
* **\[deprecated]** `feePayer` : `String | undefined` - public key of the transaction fee payer
* **\[deprecated]** `instructions` : `Array` of `Object` or `undefined` - instructions to be atomically executed:
 - `Object` - instruction
 - `programId` : `String` - public key of the on chain program
 - `data` : `String | undefined` - encoded calldata for instruction
 - `keys` : `Array` of `Object` - account metadata used to define instructions
  - `Object` - key
   - `isSigner` : `Boolean` - true if an instruction requires a transaction signature matching `pubkey`
   - `isWritable` : `Boolean` - true if the `pubkey` can be loaded as a read-write account
   - `pubkey` : `String` - public key of authorized program
* **\[deprecated]** `recentBlockhash` : `String | undefined` - a recent blockhash
* **\[deprecated]** `signatures` : `Array` of `Object` or `undefined` - (optional) previous partial signatures for this instruction set
 - `Object` - partial signature
 - `pubkey` : `String` - pubkey of the signer
 - `signature` : `String` - signature matching `pubkey`
### Returns `Object`: * `signature`: `String` - corresponding signature for signed instructions * `transaction`?: `String | undefined` - optional: base64-encoded serialized transaction ### Example ```typescript theme={null} // Request { "id": 1, "jsonrpc": "2.0", "method": "solana_signTransaction", "params": { "feePayer": "AqP3MyNwDP4L1GJKYhzmaAUdrjzpqJUZjahM7kHpgavm", "instructions": [{ "programId": "Vote111111111111111111111111111111111111111", "data": "37u9WtQpcm6ULa3VtWDFAWoQc1hUvybPrA3dtx99tgHvvcE7pKRZjuGmn7VX2tC3JmYDYGG7", "keys": [{ "isSigner": true, "isWritable": true, "pubkey": "AqP3MyNwDP4L1GJKYhzmaAUdrjzpqJUZjahM7kHpgavm" }] }], "recentBlockhash": "2bUz6wu3axM8cDDncLB5chWuZaoscSjnoMD2nVvC1swe", "signatures": [{ "pubkey": "AqP3MyNwDP4L1GJKYhzmaAUdrjzpqJUZjahM7kHpgavm", "signature": "2Lb1KQHWfbV3pWMqXZveFWqneSyhH95YsgCENRWnArSkLydjN1M42oB82zSd6BBdGkM9pE6sQLQf1gyBh8KWM2c4" }], "transaction": "r32f2..FD33r" } } // Result { "id": 1, "jsonrpc": "2.0", "result": { signature: "2Lb1KQHWfbV3pWMqXZveFWqneSyhH95YsgCENRWnArSkLydjN1M42oB82zSd6BBdGkM9pE6sQLQf1gyBh8KWM2c4" } } ``` ## solana\_signAllTransactions This method is responsible for signing a list of transactions. The wallet must sign all transactions and return the signed transactions in the same order as received. Wallets must sign all transactions or return an error if it is not possible to sign any of them. ### Parameters `Object` - Signing parameters: * `transactions` : `String[]` - base64-encoded serialized list of transactions
### Returns `Object`: * `transactions` : `String[]` - base64-encoded serialized list of signed transactions in the same order as received
### Example ```typescript theme={null} // Request { "id": 1, "jsonrpc": "2.0", "method": "solana_signAllTransactions", "params": { "transactions": string[] } } // Response { "id": 1, "jsonrpc": "2.0", "result": { "transactions": string[] } } ``` ## solana\_signAndSendTransaction This method is responsible for signing and sending a transaction to the Solana network. The wallet must sent the transaction and return the signature that can be used as a transaction id. ### Parameters `Object` - transaction and options:
* `transaction` : `String` - the whole transaction serialized and encoded with base64
* `sendOptions` : `Object` - options for sending the transaction
* `skipPreflight` : `Boolean` - skip preflight checks
* `preflightCommitment` : `'processed' | 'confirmed' | 'finalized' | 'recent' | 'single' | 'singleGossip' | 'root' | 'max'` - preflight commitment level
* `maxRetries` : `Number` - maximum number of retries
* `minContextSlot` : `Number` - minimum context slot
### Returns `Object`: * `signature` : `String`, - the signature of the transaction encoded with base58 used as transaction id
### Example ```typescript theme={null} // Request { "id": 1, "jsonrpc": "2.0", "method": "solana_signAndSendTransaction", "params": { "transaction": string, "sendOptions": { "skipPreflight"?: boolean, "preflightCommitment"?: 'processed' | 'confirmed' | 'finalized' | 'recent' | 'single' | 'singleGossip' | 'root' | 'max', "maxRetries"?: number, "minContextSlot"?: number, } } } // Response { "id": 1, "jsonrpc": "2.0", "result": { "signature": string } } ``` # Stacks Source: https://docs.reown.com/advanced/multichain/rpc-reference/stacks-rpc Stacks JSON-RPC Methods These are the methods that wallets should implement to handle Stacks transfers and messages via WalletConnect. ## Core Methods (common) ### stx\_getAddresses Retrieve active account addresses; primarily Stacks-focused. #### Request ```json theme={null} { "id": 1, "jsonrpc": "2.0", "method": "stx_getAddresses", "params": {} } ``` #### Response ```json theme={null} { "jsonrpc": "2.0", "id": 1, "result": { "addresses": [ { "symbol": "STX", "address": "SP…" } ] } } ``` **Notes:** * Use this first to select the wallet's active address. * Filter on `symbol: "STX"` or by address prefix (SP for mainnet, ST for testnet). ## Stacks Methods ### stx\_transferStx Transfer STX. #### Request ```json theme={null} { "id": 1, "jsonrpc": "2.0", "method": "stx_transferStx", "params": { "sender": "SP3F7GQ48JY59521DZEE6KABHBF4Q33PEYJ823ZXQ", "recipient": "SP3F7GQ48JY59521DZEE6KABHBF4Q33PEYJ823ZXQ", "amount": "100000000000", "memo": "", "network": "mainnet" } } ``` #### Parameters | Parameter | Required? | Data Type | Description | | ----------- | --------- | --------- | ------------------------------------------------------------------- | | `sender` | Required | `string` | The stacks address of sender (required for multi-account scenarios) | | `recipient` | Required | `string` | Stacks address | | `amount` | Required | `string` | micro-STX (uSTX) | | `memo` | Optional | `string` | Memo string to be included with the transfer transaction | | `network` | Optional | `string` | "mainnet" \| "testnet" \| "devnet" | #### Response ```json theme={null} { "jsonrpc": "2.0", "id": 1, "result": { "txid": "1234567890abcdef1234567890abcdef12345678", "transaction": "0x…" } } ``` ### stx\_signTransaction Sign a Stacks transaction. Optional broadcast. #### Request ```json theme={null} { "id": 1, "jsonrpc": "2.0", "method": "stx_signTransaction", "params": { "transaction": "0x…", "broadcast": false, "network": "mainnet" } } ``` #### Parameters | Parameter | Required? | Data Type | Description | | ------------- | --------- | --------- | ---------------------------------- | | `transaction` | Required | `string` | hex transaction | | `broadcast` | Optional | `boolean` | default false | | `network` | Optional | `string` | "mainnet" \| "testnet" \| "devnet" | #### Response ```json theme={null} { "jsonrpc": "2.0", "id": 1, "result": { "signature": "0x…", "transaction": "0x…", "txid": "1234567890abcdef1234567890abcdef12345678" } } ``` **Note:** `txid` is present if broadcast=true ### stx\_signMessage Sign arbitrary message; supports structured (SIP-018). #### Request ```json theme={null} { "id": 1, "jsonrpc": "2.0", "method": "stx_signMessage", "params": { "address": "SP3F7GQ48JY59521DZEE6KABHBF4Q33PEYJ823ZXQ", "message": "message", "messageType": "utf8", "network": "mainnet", "domain": "example.com" } } ``` #### Parameters | Parameter | Required? | Data Type | Description | | ------------- | --------- | --------- | --------------------------------------------------------------------------------------------------------- | | `address` | Required | `string` | The stacks address of sender | | `message` | Required | `string` | Utf-8 string representing the message to be signed by the wallet | | `messageType` | Optional | `string` | Type of message for signing: `utf8` for basic string or `structured` for structured data | | `network` | Optional | `string` | Network for signing: `mainnet`, `testnet`, `signet`, `devnet` (note: redundant since chainId is provided) | | `domain` | Optional | `string` | Domain tuple per SIP-018 (for structured messages only) | #### Response ```json theme={null} { "jsonrpc": "2.0", "id": 1, "result": { "signature": "0x…" } } ``` ### stx\_signStructuredMessage Domain-bound structured signing (SIP-018). #### Request ```json theme={null} { "id": 1, "jsonrpc": "2.0", "method": "stx_signStructuredMessage", "params": { "message": "message", "domain": "domain" } } ``` #### Parameters | Parameter | Required? | Data Type | Description | | --------- | --------- | ------------------ | ----------------------------- | | `message` | Required | `string \| object` | message to be signed | | `domain` | Required | `string \| object` | domain for structured signing | #### Response ```json theme={null} { "jsonrpc": "2.0", "id": 1, "result": { "signature": "0x…", "publicKey": "0x04…" } } ``` **Note:** `publicKey` is optional ### stx\_callContract Wrapper method for `stx_signTransaction` that calls a Stacks contract. #### Request ```json theme={null} { "id": 1, "jsonrpc": "2.0", "method": "stx_callContract", "params": { "contract": "SP3F7GQ48JY59521DZEE6KABHBF4Q33PEYJ823ZXQ.my-contract", "functionName": "get-balance", "functionArgs": [] } } ``` #### Parameters | Parameter | Required? | Data Type | Description | | -------------- | --------- | ---------- | ------------------------------------------------------------------------------- | | `contract` | Required | `string` | Fully qualified contract identifier, including Stacks address and contract name | | `functionName` | Required | `string` | Name of the function to call | | `functionArgs` | Required | `string[]` | Arguments to pass to the contract function, encoded as strings | #### Response ```json theme={null} { "jsonrpc": "2.0", "id": 1, "result": { "txid": "stack_tx_id", "transaction": "raw_tx_hex" } } ``` * `txid` - is used to identify the transaction on the explorer * `transaction` - hex-encoded raw transaction ## Session Properties In a connection request, it is recommended to serialize the response to `stx_getAddresses` in `session.sessionProperties.stacks_getAddresses`. This allows dapps to consume an active session without requiring a context switch to re-request all addresses and associated public keys from the wallet. # Starknet Source: https://docs.reown.com/advanced/multichain/rpc-reference/starknet-rpc Starknet JSON-RPC Methods **Please note:** The Starknet RPC standard is still under review and specifications may change. Implementation details and method signatures are subject to updates. We define new types for starknet: * `FELT`, a number represented by a hex string. Prefixed with 0x. It can be left padded with zeroes or not. It follows the [Cairo Field Element spec](https://www.cairo-lang.org/docs/how_cairo_works/cairo_intro.html#field-elements) * `ABI`, a representation of a Starknet contract’s interface. As [Starknet ABI Spec](https://docs.starknet.io/documentation/architecture_and_concepts/Contracts/contract-abi/) ## starknet\_requestAddInvokeTransaction Requests the wallet to sign and submit a [INVOKE transaction](https://docs.starknet.io/documentation/architecture_and_concepts/Blocks/transactions/#invoke_transaction) This request might be processed before the account is deployed. In that scenario the wallet will ask the user to do the deployment and the requested transaction. ### Parameters ``` 1. `FELT`, `accountAddress` : Account that is being requested to send a transaction 2. `Object`, `executionRequest` : Transaction requested 2.1. `calls` : `Object[]` array of calls to perform 2.1.1. `contractAddress` : `Felt` 2.1.2. `entrypoint` : `Felt` 2.1.3. `calldata` : `Felt[]` (Optional) 2.2. `abis` : `ABI[]` (Optional) one or more contract abis which can be used to display the calls ``` ### Example Parameters ```javascript theme={null} { "accountAddress": "0x003a8278a26f32452f156260d81b93efb0eca126b44df7b005a5b27e2bbc4a64", "executionRequest" : { "calls" : [ { "contractAddress": "0x003a8278a26f32452f156260d81b93efb0eca126b44df7b005a5b27e2bbc4a64", "entrypoint": "0x555278a26f32452f156260d81b93efb0eca126b44df7b005a5b27e2bbc4a64", "calldata": ["0x003", "0xa82705a5b27e2bbc4a64"] }, { "contractAddress": "0x00111178a26f32452f156260d81b93efb0eca126b44df7b005a5b27e2bbc4a64", "entrypoint": "0x0022228a26f32452f156260d81b93efb0eca126b44df7b005a5b27e2bbc4a64" } ], "abis" : [{ "inputs": [{ "name": "amount", "type": "felt" }], "name": "set_balance", "outputs": [], "type": "function" }] } } ``` ### Returns 1. `FELT`, `transaction_hash` : The hash of the transaction submitted by the wallet ### Example ```javascript theme={null} // Request { "id": 1, "jsonrpc": "2.0", "method": "starknet_requestAddInvokeTransaction", "params":{see above} } // Result { "id": 1, "jsonrpc": "2.0", "result": { "transaction_hash" : "0x01d666de4dc4d7e888190475ea6381a862e7d77cc3cb425e72ebf85e1d5144fa" } } ``` ## starknet\_signTypedData Request the wallet to sign an *Off-chain message* as defined here [Starknet Off-chain message spec](https://community.starknet.io/t/signing-transactions-and-off-chain-messages/66). This is similar to Ethereum's EIP-712 This request might be processed before the account is deployed. In that scenario the wallet will ask the user to do the deployment and sign the data ### Parameters account, message ``` 1. `FELT`, `accountAddress` : account address used for signing. 2. `Object`, `typedData` : typed data to sign containing type information, a domain separator, and data. It follows the Starknet Off-chain message spec ``` ### Example Parameters ```javascript theme={null} { "accountAddress" : "0x003a8278a26f32452f156260d81b93efb0eca126b44df7b005a5b27e2bbc4a64", "typedData" : { "types" : { "StarkNetDomain ": [ { "name" : "name", "type" : "felt" }, { "name" : "version", "type" : "felt" }, { "name" : "chainId", "type" : "felt" } ], "Person" : [ { "name": "name", "type" : "felt" }, { "name": "wallet", "type" : "felt" } ], "Mail": [ { "name": "from", "type": "Person" }, { "name": "to", "type": "Person" }, { "name": "contents", "type": "felt" } ] }, "primaryType" : "Mail", "domain" : { "name" : "StarkNet Mail", "version" : "1", "chainId" : 1 }, "message" : { "from" : { "name" : "Cow", "wallet" : "0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826" }, "to": { "name" : "Bob", "wallet" : "0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB" }, "contents" : "Hello, Bob!" } } } ``` ### Returns 1. `FELT[]`, `signature` : Signature as an array of Felts ### Example ```javascript theme={null} // Request { "id": 1, "jsonrpc": "2.0", "method": "starknet_signTypedData", "params": ["0x003a8278a26f32452f156260d81b93efb0eca126b44df7b005a5b27e2bbc4a64", {see above}] } // Result { "id": 1, "jsonrpc": "2.0", "result": { "signature" : ["0x3a8278a26f32452f156260d81b93efb0eca126b44df7b005a5b27e2bbc4a64", "0x072e509b6502e2bbc4a649052eb6c299d53a04e16605b915621c", "0x07897a1b93efb0eca126b44df4646", "0x072e509b6502e2bbc4a649052eb6c299d53a04e16605b915621c"] } } ``` # Stellar Source: https://docs.reown.com/advanced/multichain/rpc-reference/stellar-rpc Stellar JSON-RPC Methods **Please note:** The Stellar RPC standard is still under review and specifications may change. Implementation details and method signatures are subject to updates. ## stellar\_signAndSubmitXDR This method sends the Stellar transaction encoded as [XDR](https://developers.stellar.org/api/introduction/xdr/) to the wallet. The wallet is expected to sign the transaction and submit it to the Stellar network. For accounts protected with [multisig](https://developers.stellar.org/docs/glossary/multisig/), the wallet should also handle the collection of signatures and submission of the transaction at a later time. The method returns the transaction status: `success` - if the transaction was successfully confirmed in the Stellar network, `pending` - if the transaction requires additional signatures ### Parameters 1. `Object` - Signing parameters: 1.1. `xdr` : `STRING` - stellar transaction encoded as XDR ### Returns 1. `Object` - Signing parameters: 1.1. `status` : `success` or `pending` ### Example ```javascript theme={null} // Request { "id": 1, "jsonrpc": "2.0", "method": "stellar_signAndSubmitXDR", "params": { "xdr": "AAAAAPewD+/6X8o0bx3bp49Wf+mUhG3o+TUrcjcst717DWJVAAAAyAFvzscADTkNAAAAAAAAAAAAAAACAAAAAAAAAAYAAAACWE1BVEsAAAAAAAAAAAAAAAPvNOuztX4IjvV8pztsEc1/ZnTz0G3p5Cx4vcf04+xUAAONfqTGgAAAAAAAAAAABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAD2NyeXB0b21hcmluZS5ldQAAAAAAAAAAAAAAAAF7DWJVAAAAQK3vfUCZ8mbjW3ssMd0n1tJTF9Fv6EbuJ6cWKkYXBqG5itqanPbFzIQoZEHbPS8nr2vo4dROvKI0uQzNcfExKwM=" } } // Result { "id": 1, "jsonrpc": "2.0", "result": { "status": "success" } } ``` ## stellar\_signXDR This method sends the Stellar transaction encoded as [XDR](https://developers.stellar.org/api/introduction/xdr/) to the wallet. The wallet is expected to sign the transaction and return the signed transaction. ### Parameters 1. `Object` - Signing parameters: 1.1. `xdr` : `STRING` - stellar transaction encoded as XDR ### Returns 1. `Object` - Signing parameters: 1.1. `signedXDR` : `STRING` - stellar transaction encoded as XDR ### Example ```javascript theme={null} // Request { "id": 1, "jsonrpc": "2.0", "method": "stellar_signXDR", "params": { "xdr": "AAAAAPewD+/6X8o0bx3bp49Wf+mUhG3o+TUrcjcst717DWJVAAAAyAFvzscADTkNAAAAAAAAAAAAAAACAAAAAAAAAAYAAAACWE1BVEsAAAAAAAAAAAAAAAPvNOuztX4IjvV8pztsEc1/ZnTz0G3p5Cx4vcf04+xUAAONfqTGgAAAAAAAAAAABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAD2NyeXB0b21hcmluZS5ldQAAAAAAAAAAAAAAAAF7DWJVAAAAQK3vfUCZ8mbjW3ssMd0n1tJTF9Fv6EbuJ6cWKkYXBqG5itqanPbFzIQoZEHbPS8nr2vo4dROvKI0uQzNcfExKwM=" } } // Result { "id": 1, "jsonrpc": "2.0", "result": { "signedXDR": "AAAAAPewD+/6X8o0bx3bp49Wf+mUhG3o+TUrcjcst717DWJVAAAAyAFvzscADTkNAAAAAAAAAAAAAAACAAAAAAAAAAYAAAACWE1BVEsAAAAAAAAAAAAAAAPvNOuztX4IjvV8pztsEc1/ZnTz0G3p5Cx4vcf04+xUAAONfqTGgAAAAAAAAAAABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAD2NyeXB0b21hcmluZS5ldQAAAAAAAAAAAAAAAAF7DWJVAAAAQK3vfUCZ8mbjW3ssMd0n1tJTF9Fv6EbuJ6cWKkYXBqG5itqanPbFzIQoZEHbPS8nr2vo4dROvKI0uQzNcfExKwM=" } } ``` # Sui Source: https://docs.reown.com/advanced/multichain/rpc-reference/sui-rpc Sui JSON-RPC Methods These are the methods that wallets should implement to handle Sui transactions and messages via WalletConnect. ## sui\_getAccounts This method returns an Array of public keys and addresses available to sign from the wallet. ### Parameters none ### Returns `Array` - Array of accounts: * `Object` : * `pubkey` : `String` - public key for keypair * `address` : `String` - the Sui address ### Example ```typescript theme={null} // Request { "id": 1, "jsonrpc": "2.0", "method": "sui_getAccounts", "params": {} } // Result { "id": 1, "jsonrpc": "2.0", "result": [{ "pubkey": "AC68P56WCCTF0nUEX31/V5b1wqiD1pvfc8Fql8dPIPDA", "address":"0x3cd077f41680eebca0176baad3915b2ea26dbbdfd10161865234732bb1f2ac50" }] } ``` ### Session Properties In a connection request, it is recommended to serialize the response to `getAccounts` in `session.sessionProperties.sui_getAccounts`. This allows dapps to consume an active session without requiring a context switch to re-request all addresses and associated public keys from the wallet. :::warning This method is **required** for all wallets to implement in order to connect to applications using Sui Dappkit. Wallets that do not implement `sui_getAccounts` will not be able to establish connections with dapps using the Sui Dappkit SDK. ::: ## sui\_signTransaction Sign a Sui transaction without executing it. #### Parameters 1. `transaction` (object) - The transaction to sign: * `transaction` (string) - The base64 encoded, BCS encoded, transaction data * `address` (string) - The sender's Sui address #### Returns `object` - The signed transaction: * `signature` (string) - The base64 encoded signature * `transactionBytes` (string) - The base64 encoded signed transaction bytes #### Example ```javascript theme={null} // Request { "jsonrpc": "2.0", "id": 1, "method": "sui_signTransaction", "params": { "transaction": "AAACAAhkAAAAAAAAAAAgcfGPMPqXhXLvgkjSYSgtJoBBfJN4xPm3bwZGapDhVIICAgABAQAAAQEDAAAAAAEBAHHxjzD6l4Vy74JI0mEoLSaAQXyTeMT5t28GRmqQ4VSCAq3fqx8mNL6p13BcS9bG74Gbh1dowEtQ", "address": "0xd5f647edb77d4fda31d0304506447fb3c92e55aaf77bc5ed4b77c332dd4605fa" } } // Response { "jsonrpc": "2.0", "result": { "signature": "ACRvdr3yI2mdpeOK+NsJIimdNGcE9R//jjT3HALZ17fFyu818op4jZi/64lPBjpKMDX6ZtxnCFZExTOFdpi3MwEZXLv/ORduxMYX0fw8dbHlnWC8WG0ymrlAmARpEibbhw==", "transactionBytes": "AAACAAhkAAAAAAAAAAAg1fZH7bd9T9ox0DBFBkR/s8kuVar3e8XtS3fDMt1GBfoCAgABAQAAAQEDAAAAAAEBANX2R+23fU/aMdAwRQZEf7PJLlWq93vF7Ut3wzLdRgX6At/pRJzj2VpZgqXpSvEtd3GzPvt99hR8e/yOCGz/8nbRmA7QFAAAAAAgBy5vStJizn76LmJTBlDiONdR/2rSuzzS4L+Tp/Zs4hZ8cBxYkcSlxBD6QXvgS11E6d+DNek8LiA/beba6iH3l5gO0BQAAAAAIMpdmZjiqJ5GG9di1MAgD4S3uRr2gaMC7S1WsaeBwNIx1fZH7bd9T9ox0DBFBkR/s8kuVar3e8XtS3fDMt1GBfroAwAAAAAAAECrPAAAAAAAAA==" }, "id": 1 } ``` ### sui\_signAndExecuteTransaction Sign and execute a Sui transaction. #### Parameters 1. `transaction` (object) - The transaction to sign and execute: * `transaction` (string) - The base64 encoded, BCS encoded, transaction data * `address` (string) - The sender's Sui address #### Returns `object` - The transaction result: * `digest` (string) - The transaction digest that can be used to look up the transaction in the explorer #### Example ```javascript theme={null} // Request { "jsonrpc": "2.0", "id": 1, "method": "sui_signAndExecuteTransaction", "params": { "transaction": "AAACAAhkAAAAAAAAAAAgcfGPMPqXhXLvgkjSYSgtJoBBfJN4xPm3bwZGapDhVIICAgABAQAAAQEDAAAAAAEBAHHxjzD6l4Vy74JI0mEoLSaAQXyTeMT5t28GRmqQ4VSCAq3fqx8mNL6p13BcS9bG74Gbh1dowEtQ", "address": "0xd5f647edb77d4fda31d0304506447fb3c92e55aaf77bc5ed4b77c332dd4605fa" } } // Response { "jsonrpc": "2.0", "result": { "digest": "GBqPRFR9sYfWA8rt2wCkcgZrctyYMj8Ufunxkjg5G8zt" }, "id": 1 } ``` ### sui\_signPersonalMessage Sign a personal message. #### Parameters 1. `message` (object) - The message to sign: * `message` (string) - The message to sign (plain text) * `address` (string) - The account address to sign with #### Returns `object` - The signed message: * `signature` (string) - The base64 encoded signature #### Example ```javascript theme={null} // Request { "jsonrpc": "2.0", "id": 1, "method": "sui_signPersonalMessage", "params": { "message": "This is a message to be signed for SUI", "address": "0xd5f647edb77d4fda31d0304506447fb3c92e55aaf77bc5ed4b77c332dd4605fa" } } // Response { "jsonrpc": "2.0", "result": { "signature": "APsZ7PvuAynXYxxfeo0Py4DWOnrUpwqHhJJ1F8aGB2nmS5Wv9dvVo8Gr7DKaXwPMqFaFNKsHb0Hej07R0L0NpQsZXLv/ORduxMYX0fw8dbHlnWC8WG0ymrlAmARpEibbhw==" }, "id": 1 } ``` ## Additional Resources For more information about Sui RPC methods and implementation details, please refer to the [official Sui documentation](https://docs.sui.io/sui-api-ref). # Tezos Source: https://docs.reown.com/advanced/multichain/rpc-reference/tezos-rpc Tezos JSON-RPC Methods **Please note:** The Tezos RPC standard is still under review and specifications may change. Implementation details and method signatures are subject to updates. ## tezos\_getAccounts This method returns an array of public keys, which correspond to keypairs available in the wallet for signing. ### Parameters none ### Returns 1.`Array` - Array of accounts: 1.1. `Object` - Account Data object with parameters: 1.1.1. `algo` : `STRING` - algorithm used for signing 1.1.2. `address` : `STRING` - corresponding address for keypair 1.1.3. `pubkey` : `STRING` - public key for keypair ### Example ```javascript theme={null} // Request { "id": 1, "jsonrpc": "2.0", "method": "tezos_getAccounts", "params": {} } // Result { "id": 1, "jsonrpc": "2.0", "result": [ { "algo": "ed25519", "address": "tz1VQA4RP4fLjEEMW2FR4pE9kAg5abb5h5GL", "pubkey": "edpku4US3ZykcZifjzSGFCmFr3zRgCKndE82estE4irj4d5oqDNDvf" } ] } ``` ## tezos\_send This method returns a hash for the provided operations. They will be signed by the keypair corresponding to the requested signer address and sent to the blockchain. ### Parameters 1. `Object` - Signing parameters: 1.1. `account` : `STRING` - corresponding address for keypair 1.2. `operations` : `Array` - operations to be signed: 1.2.1. `Object` - identifier of blockchain 1.2.1.1. `kind` : `STRING` - type of the operation 1.2.1.2. `destination` : `STRING` - recipient of the operation 1.2.1.3. `amount` : `STRING` - mutez amount 1.2.1.4. `fee` : `STRING` - (optional) operation fee - NOTE: Not all wallets will respect this value because it's usually set by the wallet depending on network usage 1.2.1.5. `gas_limit` : `STRING` - (optional) integer of the gas\_limit 1.2.1.6. `storage_limit` : `STRING` - (optional) integer of the storage\_limit 1.2.1.7. `parameters` : `Object` - (optional) contract call data Note: All [RPC Operations](https://github.com/ecadlabs/taquito/blob/4dc6c391047b977b11eb92c7f5a5bc508ca32f01/packages/taquito/src/operations/types.ts#L553C13-L567) are valid. The above definition describes only the most common operation type. ### Returns 1. `Object` - Signing parameters: 1.1. `operationHash` : `STRING` - hash of the operation ### Example ```javascript theme={null} // Request { "id": 1, "jsonrpc": "2.0", "method": "tezos_send", "params": { "account": "tz1VQA4RP4fLjEEMW2FR4pE9kAg5abb5h5GL", "operations": [ { "kind": "transaction"; "amount": "1"; "destination": "tz1VQA4RP4fLjEEMW2FR4pE9kAg5abb5h5GL"; } ] } } // Result { "id": 1, "jsonrpc": "2.0", "result": { "operationHash": "op..." } } ``` ## tezos\_sign This method returns a signature for the provided payload. It will be signed by the keypair corresponding to the requested signer address. ### Parameters 1. `Object` - Signing parameters: 1.1. `account` : `STRING` - corresponding address for keypair 1.2. `payload` : `STRING` - payload to be signed ### Returns 1. `Object` - Signing parameters: 1.1. `signature` : `STRING` - signature for signed payload ### Example ```javascript theme={null} // Request { "id": 1, "jsonrpc": "2.0", "method": "tezos_sign", "params": { "account": "tz1VQA4RP4fLjEEMW2FR4pE9kAg5abb5h5GL", "payload": "05010000004254", } } // Result { "id": 1, "jsonrpc": "2.0", "result": { "signature": "edsig..." } } ``` # TON Source: https://docs.reown.com/advanced/multichain/rpc-reference/ton-rpc TON JSON-RPC Methods ## Network / Chain Information | CAIP-2 | Chain ID | Name | RPC Endpoint | Namespace | | ---------- | -------- | ----------- | ---------------------------------------------- | --------- | | `ton:-239` | `-239` | TON Mainnet | `https://toncenter.com/api/v2/jsonRPC` | `ton` | | `ton:-3` | `-3` | TON Testnet | `https://testnet.toncenter.com/api/v2/jsonRPC` | `ton` | ## RPC Methods Wallets must support the following JSON-RPC methods over WalletConnect sessions. No events are required. ## ton\_sendMessage Submit one or more transaction messages to the TON network. ### Request ```typescript theme={null} interface TonSendMessageRequest { method: 'ton_sendMessage'; params: TonSendTransactionParams[]; } interface TonSendTransactionParams { valid_until?: number; // optional UNIX timestamp from?: string; // optional sender address (TEP-123 format) messages: TonTransactionMessage[]; } interface TonTransactionMessage { address: string; // recipient in TEP-123 format amount: number | string; // value in nanotons payload?: string; // optional base64 BoC stateInit?: string; // optional base64 BoC } ``` ### Example Request ```json theme={null} { "id": 123, "jsonrpc": "2.0", "params": { "chainId": "ton:-239", "request": { "method": "ton_sendMessage", "params": [ { "valid_until": 1658253458, "from": "EQDmnxDMhId6v1Ofg_h5KR5coWlFG6e86Ro3pc7Tq4CA0-Jn", "messages": [ { "address": "EQBBJBB3HagsujBqVfqeDUPJ0kXjgTPLWPFFffuNXNiJL0aA", "amount": "20000000", "stateInit": "base64boc..." }, { "address": "EQDmnxDMhId6v1Ofg_h5KR5coWlFG6e86Ro3pc7Tq4CA0-Jn", "amount": "60000000", "payload": "base64boc..." } ] } ] } } } ``` ### Success Response ```json theme={null} { "jsonrpc": "2.0", "id": 123, "result": "base64bocEncodedTransaction" } ``` The `base64bocEncodedTransaction` in the result is a base64 encoded BOC (Bag of Cells) of an external message. #### Example: Building an External-In Message ```typescript theme={null} // Build external-in message for the result const message: Message = { info: { type: 'external-in', src: null, dest: Address.parse(""), importFee: BigInt(0) }, init: null, body: transfer } const externalMessageCell = beginCell() .store(storeMessage(message, { forceRef: true })) .endCell() return externalMessageCell.toBoc().toString('base64') ``` ### Error Response ```json theme={null} { "jsonrpc": "2.0", "id": 123, "error": { "code": , "message": "" } } ``` ## ton\_signData Sign an off-chain payload (text, binary, or cell) for authentication or verification by dApps. ### Request ```typescript theme={null} interface TonSignDataRequest { method: 'ton_signData'; params: TonSignDataParams[]; } type TonSignDataParams = | { type: 'text'; text: string; from?: string } | { type: 'binary'; bytes: string; from?: string } | { type: 'cell'; schema: string; cell: string; from?: string }; ``` ### Example Request ```json theme={null} { "id": 123, "jsonrpc": "2.0", "params": { "chainId": "ton:-239", "request": { "method": "ton_signData", "params": [ { "type": "text", "text": "Confirm new 2FA number:\\n+1 234 567 8901", "from": "EQDmnxDMhId6v1Ofg_h5KR5coWlFG6e86Ro3pc7Tq4CA0-Jn" } ] } } } ``` ### Success Response ```json theme={null} { "jsonrpc": "2.0", "id": 123, "result": { "signature": "base64_signature", "publicKey": "base64_encoded_publicKey", "timestamp": 1658253458, "domain": "yourapp.com", "payload": { "type": "text", "text": "Confirm new 2FA number:\\n+1 234 567 8901" } } } ``` ### Error Response ```json theme={null} { "jsonrpc": "2.0", "id": 123, "error": { "code": , "message": "" } } ``` ## Notes & Considerations * If `from` is omitted, the wallet should prompt the user to select an address. * All requests and responses must comply with JSON-RPC structure (`id`, `jsonrpc`, etc.). * Signature verification can be done using `ed25519.verify` on the original bytes. * `stateInit` support is needed when your wallet supports contract deployment flows. * The `domain` field in responses indicates the originating application (dApp) domain. # Tron Source: https://docs.reown.com/advanced/multichain/rpc-reference/tron-rpc Tron JSON-RPC Methods These are the methods that wallets should implement to handle Tron transactions and messages via WalletConnect. ## Session Properties To enable the new simplified transaction structure, wallets should include `tron_method_version: "v1"` in their `sessionProperties` during the connection handshake: ```json theme={null} { "sessionProperties": { "tron_method_version": "v1" } } ``` When `tron_method_version` is set to `"v1"`, the transaction structure is simplified to remove the nested `transaction.transaction` format. If not set, the legacy nested format is used for backward compatibility. ### tron\_signTransaction Sign a Tron transaction without executing it. #### Parameters * The transaction to sign: * `address` (string) - The sender's Tron address * `transaction` (object) - The transaction object to sign #### Returns * The signed transaction: * `txID` (string) - The transaction ID (deterministically derived from raw transaction) * `signature` (array) - Array of signature strings * `raw_data` (object) - The raw transaction data * `raw_data_hex` (string) - The hex-encoded raw transaction data * `visible` (boolean) - Whether addresses are in visible format #### Example (Legacy Format) * Request with the nested `transaction.transaction` format ```javascript theme={null} { "jsonrpc": "2.0", "id": 1, "method": "tron_signTransaction", "params": { "address": "TLyqzVGLV1srkB7dToTAEqgDSfPtXRJZYH", "transaction": { "transaction": { "raw_data": { "contract": [ { "parameter": { "value": { "data": "095ea7b30000000000000000000000001cb0b7348eded93b8d0816bbeb819fc1d7a51f310000000000000000000000000000000000000000000000000000000000000000", "owner_address": "411cb0b7348eded93b8d0816bbeb819fc1d7a51f31", "contract_address": "41a614f803b6fd780986a42c78ec9c7f77e6ded13c" }, "type_url": "type.googleapis.com/protocol.TriggerSmartContract" }, "type": "TriggerSmartContract" } ], "ref_block_bytes": "885b", "ref_block_hash": "baa1c278fd0a309f", "expiration": 1745849082000, "fee_limit": 200000000, "timestamp": 1745849022978 } } } } } ``` * Response: ```javascript theme={null} { "jsonrpc": "2.0", "result": { "txID": "66e79c6993f29b02725da54ab146ffb0453ee6a43b4083568ad9585da305374a", "signature": [ "7e760cef94bc82a7533bc1e8d4ab88508c6e13224cd50cc8da62d3f4d4e19b99514f..." ], "raw_data": { "expiration": 1745849082000, "contract": [ { "parameter": { "type_url": "type.googleapis.com/protocol.TriggerSmartContract", "value": { "data": "095ea7b30000000000000000000000001cb0b7348eded93b8d0816bbeb819fc1d7a51f310000000000000000000000000000000000000000000000000000000000000000", "contract_address": "41a614f803b6fd780986a42c78ec9c7f77e6ded13c", "owner_address": "411cb0b7348eded93b8d0816bbeb819fc1d7a51f31" } }, "type": "TriggerSmartContract" } ], "ref_block_hash": "baa1c278fd0a309f", "fee_limit": 200000000, "timestamp": 1745849022978, "ref_block_bytes": "885b" }, "visible": false, "raw_data_hex": "0a02885b2208baa1c278fd0a309f4090c1dbe5e7325aae01081f12a9010a31747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e54726967676572536d617274436f6e747261637412740a15411cb0b7348eded93b8d0816bbeb819fc1d7a51f31121541a614f803b6fd780986a42c78ec9c7f77e6ded13c2244095ea7b30000000000000000000000001cb0b7348eded93b8d0816bbeb819fc1d7a51f3100000000000000000000000000000000000000000000000000000000000000007082f4d7e5e73290018084af5f" }, "id": 1 } ``` #### Example (New Format with tron\_method\_version: "v1") Request with the simplified format: ```javascript theme={null} { "request": { "method": "tron_signTransaction", "params": { "address": "TKZRPqoV7WLFvjhT4cEyBLv27Rvv1RNWGj", "transaction": { "visible": false, "txID": "539f218871fdd87e94eb03a0dd617107ba722005f37a5ddb82cb65aa4f3b73b0", "raw_data": { "contract": [ { "parameter": { "value": { "data": "095ea7b300000000000000000000000069319ea845b1c35a1f7b0e1429f4f303e8f791330000000000000000000000000000000000000000000000000000000000000000", "owner_address": "4169319ea845b1c35a1f7b0e1429f4f303e8f79133", "contract_address": "41eca9bc828a3005b9a3b909f2cc5c2a54794de05f" }, "type_url": "type.googleapis.com/protocol.TriggerSmartContract" }, "type": "TriggerSmartContract" } ], "ref_block_bytes": "7803", "ref_block_hash": "16138f9255a1db91", "expiration": 1756201572000, "fee_limit": 200000000, "timestamp": 1756201512720 }, "raw_data_hex": "0a027803220816138f9255a1db9140a0ad95ae8e335aae01081f12a9010a31747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e54726967676572536d617274436f6e747261637412740a154169319ea845b1c35a1f7b0e1429f4f303e8f79133121541eca9bc828a3005b9a3b909f2cc5c2a54794de05f2244095ea7b300000000000000000000000069319ea845b1c35a1f7b0e1429f4f303e8f79133000000000000000000000000000000000000000000000000000000000000000007090de91ae8e3390018084af5f" } }, "expiryTimestamp": 1756201811 }, "chainId": "tron:0xcd8690dc" } ``` * Response: ```javascript theme={null} { "visible": false, "txID": "539f218871fdd87e94eb03a0dd617107ba722005f37a5ddb82cb65aa4f3b73b0", "raw_data": { "contract": [ { "parameter": { "value": { "data": "095ea7b300000000000000000000000069319ea845b1c35a1f7b0e1429f4f303e8f791330000000000000000000000000000000000000000000000000000000000000000", "owner_address": "4169319ea845b1c35a1f7b0e1429f4f303e8f79133", "contract_address": "41eca9bc828a3005b9a3b909f2cc5c2a54794de05f" }, "type_url": "type.googleapis.com/protocol.TriggerSmartContract" }, "type": "TriggerSmartContract" } ], "ref_block_bytes": "7803", "ref_block_hash": "16138f9255a1db91", "expiration": 1756201572000, "fee_limit": 200000000, "timestamp": 1756201512720 }, "raw_data_hex": "0a027803220816138f9255a1db9140a0ad95ae8e335aae01081f12a9010a31747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e54726967676572536d617274436f6e747261637412740a154169319ea845b1c35a1f7b0e1429f4f303e8f79133121541eca9bc828a3005b9a3b909f2cc5c2a54794de05f2244095ea7b300000000000000000000000069319ea845b1c35a1f7b0e1429f4f303e8f79133000000000000000000000000000000000000000000000000000000000000000007090de91ae8e3390018084af5f", "signature": [ "1c2dd921c15fd83ca1dec4fd999b801f08c8bb073702f4bfafa4132a6e129421ed6267ec81c7dd2e4ef04ce077b101186ec2cda86d69f9f44255c216398cc9c601" ] } ``` ### tron\_signMessage Sign a personal message. #### Parameters The message to sign: * `message` (string) - The message to sign (plain text) * `address` (string) - The account address to sign with #### Returns The signed message: * `signature` (string) - The signature string #### Example * Request: ```javascript theme={null} { "request": { "method": "tron_signMessage", "params": { "address": "TXUEmLr...", "message": "This is a message to be signed for Tron" }, "expiryTimestamp": 1758269816 }, "chainId": "tron:0xcd8690dc" } ``` * dApp result (what client.request(...) resolves to): ```javascript theme={null} { "signature": "0x1ec623ee6e4716f5a116d0a2755b158ac05dfbc3e9118cca..." } ``` The methods below are not part of the required wallet surface in the Reown official Tron Wallet example. dApps may perform these directly against a Tron node or gateway. Wallets may implement them for convenience, but they’re not required. ### tron\_sendTransaction (optional) Broadcast a signed transaction to the Tron network. #### Parameters The signed transaction object: * `txID` (string) - The transaction ID * `signature` (array) - Array of signature strings * `raw_data` (object) - The raw transaction data * `raw_data_hex` (string) - The hex-encoded raw transaction data #### Returns The transaction result: * `result` (boolean) - Whether the transaction was successfully broadcast * `txid` (string) - The transaction ID that can be used to look up the transaction #### Example * Request: ```javascript theme={null} { "jsonrpc": "2.0", "id": 1, "method": "tron_sendTransaction", "params": { "signedTransaction": { "txID": "66e79c6993f29b02725da54ab146ffb0453ee6a43b4083568ad9585da305374a", "signature": [ "7e760cef94bc82a7533bc1e8d4ab88508c6e13224cd50cc8da62d3f4d4e19b99514f..." ], "raw_data_hex": "0a02885b2208baa1c278fd0a309f4090c1dbe5e7325aae01081f12a9010a31747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e54726967676572536d617274436f6e747261637412740a15411cb0b7348eded93b8d0816bbeb819fc1d7a51f31121541a614f803b6fd780986a42c78ec9c7f77e6ded13c2244095ea7b30000000000000000000000001cb0b7348eded93b8d0816bbeb819fc1d7a51f3100000000000000000000000000000000000000000000000000000000000000007082f4d7e5e73290018084af5f" } } } ``` * Response: ```javascript theme={null} { "jsonrpc": "2.0", "result": { "result": true, "txid": "66e79c6993f29b02725da54ab146ffb0453ee6a43b4083568ad9585da305374a" }, "id": 1 } ``` ### tron\_getBalance (optional) Get the TRX balance of a Tron address. #### Parameters 1. `address` (string) - The Tron address to query #### Returns `number` - The balance in SUN (1 TRX = 1,000,000 SUN) #### Example ```javascript theme={null} - Request: { "jsonrpc": "2.0", "id": 1, "method": "tron_getBalance", "params": { "address": "TLyqzVGLV1srkB7dToTAEqgDSfPtXRJZYH" } } ``` * Response: ```javascript theme={null} { "jsonrpc": "2.0", "result": 1000000000, "id": 1 } ``` ## Additional Resources For more information about Tron RPC methods and implementation details, please refer to the [official Tron documentation](https://developers.tron.network/). # XRPL Source: https://docs.reown.com/advanced/multichain/rpc-reference/xrpl-rpc XRPL JSON-RPC Methods **Please note:** The XRPL RPC standard is still under review and specifications may change. Implementation details and method signatures are subject to updates. ## xrpl\_signTransaction This method is used to sign and submit a transaction to the XRP Ledger (XRPL). Every transaction has the same set of [common fields][XRPL Transaction Common Fields], plus additional fields based on the [transaction type][XRPL Transaction Types]. It is expected that the dapp provides all transaction fields defined as `required`, but not necessarily the `auto-fillable`. ### Parameters * `Object` * `tx_json` : `Object` - *(Required)* JSON specification of the transaction. * `autofill` : `Boolean` - *(Optional)* Defaults to `true`. Set to `false` to skip auto-filling parameters. * `submit` : `Boolean` - *(Optional)* Defaults to `true`. Set to `false` to skip submitting the transaction. Please note that if you set `submit` to `false`, your dapp will need to encode the signed `tx_json` to the required [binary format][XRPL Serialization], before you can send it as `tx_blob` to an XRPL node using the [submit][XRPL Signed Transaction] command. ### Returns * `Object` * `tx_json` : `Object` - JSON specification of the complete transaction as signed, including any fields that were auto-filled. ### Example The example below specifies a simple DEX order for selling 15,000 XRP in exchange for 7,072.8 USD. ```javascript theme={null} // Request { "id": 1, "jsonrpc": "2.0", "method": "xrpl_signTransaction", "params": { "tx_json": { "TransactionType": "OfferCreate", "Account": "rMBzp8CgpE441cp5PVyA9rpVV7oT8hP3ys", "Flags": 524288, "LastLedgerSequence": 7108682, "Expiration": 595640108, "TakerGets": "15000000000", "TakerPays": { "currency": "USD", "issuer": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B", "value": "7072.8" } } } } // Result { "id": 1, "jsonrpc": "2.0", "result": { "tx_json": { "Account": "rMBzp8CgpE441cp5PVyA9rpVV7oT8hP3ys", "Expiration": 595640108, "Fee": "10", "Flags": 524288, "OfferSequence": 1752791, "Sequence": 1752792, "LastLedgerSequence": 7108682, "SigningPubKey": "03EE83BB432547885C219634A1BC407A9DB0474145D69737D09CCDC63E1DEE7FE3", "TakerGets": "15000000000", "TakerPays": { "currency": "USD", "issuer": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B", "value": "7072.8" }, "TransactionType": "OfferCreate", "TxnSignature": "30440220143759437C04F7B61F012563AFE90D8DAFC46E86035E1D965A9CED282C97D4CE02204CFD241E86F17E011298FC1A39B63386C74306A5DE047E213B0F29EFA4571C2C", "hash": "73734B611DDA23D3F5F62E20A173B78AB8406AC5015094DA53F53D39B9EDB06C" } } } ``` ## xrpl\_signTransactionFor This method is used to add a signature to a [multi-signed][XRPL Multisign] transaction. The same common fields and transaction types as single-signed transactions are supported. ### Parameters * `Object` * `tx_signer` : `String` - *(Required)* The XRPL address of the signer. * `tx_json` : `Object` - *(Required)* JSON specification of the transaction. * `autofill` : `Boolean` - *(Optional)* Defaults to `false`. Set to `true` to auto-fill parameters. * `submit` : `Boolean` - *(Optional)* Defaults to `false`. Set to `true` to submit the transaction. Please note that `autofill` and `submit` both defaults to `false`, since explicit transaction specification and controlled submission is typically needed for multi-signed transactions. ### Returns * `Object` * `tx_json` : `Object` - JSON specification of the complete transaction as signed, including any fields that were auto-filled. ### Example The example below specifies a multi-signed payment transaction, already signed ([in serial][XRPL Multisign Methods]) by 3 of 4 required signers. Since only one more signature is required, the optional `submit` parameter has been set to `true`. ```javascript theme={null} // Request { "id": 1, "jsonrpc": "2.0", "method": "xrpl_signTransactionFor", "params": { "submit": true, "tx_signer": "rJ4wmkgK8n93UjtaqQTaj1vxBwQWdLrBjP", "tx_json": { "Account": "rh2EsAe2xVE71ZBjx7oEL2zpD4zmSs3sY9", "TransactionType": "Payment", "Amount": "400000000000000", "Destination": "r9NpyVfLfUG8hatuCCHKzosyDtKnBdsEN3", "Fee": "5000", "Flags": 2147483648, "LastLedgerSequence": 73541531, "Sequence": 38, "Signers": [ { "Signer": { "Account": "re3LGjhrCvthtWWwrfKbVJjXN9PYDeQDJ", "SigningPubKey": "0320ECD5569CAFA4E23147BE238DBFB268DB3B5A502ED339387AC7DCA0ADC6FB90", "TxnSignature": "3045022100EC2BF025E748A028187EDB3C350D518F91F05BC201EAFC9C92566DE9E48AA1B7022018847D172386E93679630E3905BD30481359E5766931944F79F1BA6D910F5C01" } }, { "Signer": { "Account": "rpcL6T32dYb6FDgdm4CnC1DZQSoMvvkLRd", "SigningPubKey": "030BF97DA9A563A9A0679DD527F615CF8EA6B2DB55543075B72822B8D39910B5E1", "TxnSignature": "304402201A891AF3945C81E2D6B95213B79E9A31635209AF0FB94DA8C0983D15F454179B0220388679E02CE6DE2AAC904A9C2F42208418BEF60743A7F9F76FC36D519902DA8C" } }, { "Signer": { "Account": "r3vw3FnkXn2L7St45tzpySZsXVgG75seNk", "SigningPubKey": "030BE281F6DFF9AFD260003375B64235DDBCD5B7A54511BE3DA1FEF1ADE4A85D87", "TxnSignature": "3044022049D36ACE39F1208B4C78A1550F458E54E21161FA4B52B3763C8FA9C4FE45B52C022003BE3579B5B5558A27BB7DC6A8ED163999A451665974138298469C1FDACA615F" } } ], "SigningPubKey": "" } } } // Result { "id": 1, "jsonrpc": "2.0", "result": { "tx_json": { "Account": "rh2EsAe2xVE71ZBjx7oEL2zpD4zmSs3sY9", "TransactionType": "Payment", "Amount": "400000000000000", "Destination": "r9NpyVfLfUG8hatuCCHKzosyDtKnBdsEN3", "Fee": "5000", "Flags": 2147483648, "LastLedgerSequence": 73541531, "Sequence": 38, "Signers": [ { "Signer": { "Account": "re3LGjhrCvthtWWwrfKbVJjXN9PYDeQDJ", "SigningPubKey": "0320ECD5569CAFA4E23147BE238DBFB268DB3B5A502ED339387AC7DCA0ADC6FB90", "TxnSignature": "3045022100EC2BF025E748A028187EDB3C350D518F91F05BC201EAFC9C92566DE9E48AA1B7022018847D172386E93679630E3905BD30481359E5766931944F79F1BA6D910F5C01" } }, { "Signer": { "Account": "rpcL6T32dYb6FDgdm4CnC1DZQSoMvvkLRd", "SigningPubKey": "030BF97DA9A563A9A0679DD527F615CF8EA6B2DB55543075B72822B8D39910B5E1", "TxnSignature": "304402201A891AF3945C81E2D6B95213B79E9A31635209AF0FB94DA8C0983D15F454179B0220388679E02CE6DE2AAC904A9C2F42208418BEF60743A7F9F76FC36D519902DA8C" } }, { "Signer": { "Account": "r3vw3FnkXn2L7St45tzpySZsXVgG75seNk", "SigningPubKey": "030BE281F6DFF9AFD260003375B64235DDBCD5B7A54511BE3DA1FEF1ADE4A85D87", "TxnSignature": "3044022049D36ACE39F1208B4C78A1550F458E54E21161FA4B52B3763C8FA9C4FE45B52C022003BE3579B5B5558A27BB7DC6A8ED163999A451665974138298469C1FDACA615F" } }, { "Signer": { "Account": "rJ4wmkgK8n93UjtaqQTaj1vxBwQWdLrBjP", "SigningPubKey": "02D5D616D4005B91DE02BF6E29157B514C667810860F389CF36DC9E4D5E73BFE79", "TxnSignature": "304402207589FA73E72F85A2C8F82BBCB3C7C67C455D4C14A946BA427A4735F4ED106123022069845499A9DE50F26765F097BA0EA3C96E56A1304B380E0533514AEEF29363D7" } } ], "SigningPubKey": "", "hash": "BA2AF0C652F46C97B85C1D17080EEC7422C092B0BD906DCA344B42EF30FA8285", } } } ``` [XRPL Transaction Common Fields]: https://xrpl.org/transaction-common-fields.html [XRPL Transaction Types]: https://xrpl.org/transaction-types.html [XRPL Signed Transaction]: https://xrpl.org/transaction-basics.html#example-signed-transaction-blob [XRPL Serialization]: https://xrpl.org/serialization.html#examples [XRPL Algorithms]: https://xrpl.org/cryptographic-keys.html#signing-algorithms [XRPL Multisign]: https://xrpl.org/multi-signing.html#multi-signing [XRPL Multisign Methods]: https://xrpl.org/send-a-multi-signed-transaction.html#3-get-additional-signatures # Ethereum Provider Source: https://docs.reown.com/advanced/providers/ethereum [EIP-1193](https://eips.ethereum.org/EIPS/eip-1193) compliant Provider for the WalletConnect v2 protocol. Built on top of [Universal Provider](./universal) and [WalletConnectModal](../walletconnectmodal/about). You can use this on it's own or pass it down to libraries like ethers, viem or web3js. `showQrModal` has been deprecated as WalletConnect's Web3Modal is now rebranded as Reown's AppKit. If you are looking to use this, please refer to the ["**Use with AppKit**"](#use-with-appkit) section below. ## Installation ```bash npm theme={null} npm install @walletconnect/ethereum-provider ``` ```bash Yarn theme={null} yarn add @walletconnect/ethereum-provider ``` ```bash Bun theme={null} bun add @walletconnect/ethereum-provider ``` ```bash pnpm theme={null} pnpm add @walletconnect/ethereum-provider ``` ## Initialization Initialize Ethereum Provider by calling its `init` method and passing down the required arguments: ```ts theme={null} import { EthereumProvider } from "@walletconnect/ethereum-provider"; const provider = await EthereumProvider.init({ projectId: "YOUR_PROJECT_ID", metadata: { name: "My Website", description: "My Website Description", url: "https://mywebsite.com", // origin must match your domain & subdomain icons: ["https://avatars.githubusercontent.com/u/37784886"], }, showQrModal: true, optionalChains: [1, 137, 2020], /*Optional - Add custom RPCs for each supported chain*/ rpcMap: { 1: "mainnet.rpc...", 137: "polygon.rpc...", }, }); ``` * Make sure that `url` from `metadata` matches your domain and subdomain. This will later be used by **Verify API** to confirm if your application has been verified or not. * We recommend using `optionalChains` (optional namespaces) over `chains` (required namespaces).\ *Required namespaces* will block wallets from connecting to your application if any of the chains are not supported by the wallet. Smart Contract Wallets can only support one chain, the one that they had been deployed to, this might cause issues when using required namespaces. * Using `chains`, `methods` or `events` will create a *Required Namespaces* object internally. * `optionalMethods` and `optionalChains` default to the following methods and events: [Read source code](https://github.com/WalletConnect/walletconnect-monorepo/blob/v2.0/providers/ethereum-provider/src/constants/rpc.ts). * If `rpcMap` is not defined it will fallback to [Blockchain API](../../cloud/blockchain-api) RPCs. Keep in mind that Blockchain API supports a limited [list of chains](https://github.com/WalletConnect/rpc-proxy/blob/master/SUPPORTED_CHAINS.md). ### Init Params The Ethereum Provider's `init` method takes the following parameters: | Value | Description | Type | Required | | ------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------ | -------- | | **projectId** | Your project ID obtained from Reown Dashboard: [https://dashboard.reown.com/](https://dashboard.reown.com/) | `string` | true | | **optionalChains** | An array of the chain IDs you want to support. It is highly recommended to use "optionalChains" over "chains" for multi-chain dapps, ensuring compatibility with Smart Contract Wallets. | `number[]` | false | | **optionalMethods** | The Ethereum methods you want to support and send in the session proposal under the "optionalNamespaces" scope. If undefined, it defaults to all EIP-1193 compatible methods. | `string[]` | false | | **optionalEvents** | The Ethereum events you want to support and send in the session proposal under the "optionalNamespaces" scope. If undefined, it defaults to all EIP-1193 compatible events. | `string[]` | false | | **rpcMap** | An object whose keys are chain IDs and values are their RPC endpoints. | `Record` | false | | **metadata** | Your application's metadata. It is important to set the correct URL, as this will later be used by the Verify API to check if your domain has been verified. | `Metadata` | false | | **qrModalOptions** | An array of WalletConnectModal options. See WalletConnectModal options. | `QrModalOptions` | false | | **chains** | An array of required chain IDs you want to support. If the wallet does not support these chains, it will not be able to connect. Not recommended for multi-chain applications. | `number[]` | false | | **methods** | The required methods you want to support. Not recommended for multi-chain applications. | `string[]` | false | | **events** | The required events you want to support. Not recommended for multi-chain applications. | `string[]` | false | ## Use with AppKit The QRModal is enabled by default on reown's AppKit. In order to use it, all you need to do is to create an AppKit instance. ### Installation ```bash npm theme={null} npm install @reown/appkit ``` ```bash Yarn theme={null} yarn add @reown/appkit ``` ```bash Bun theme={null} bun add @reown/appkit ``` ```bash pnpm theme={null} pnpm add @reown/appkit ``` ### Setup Upon integrating the below code, you will be able to see the QRModal on your Web3 App. ```tsx theme={null} import { createAppKit } from "@reown/appkit"; import { mainnet, arbitrum, sepolia } from "@reown/appkit/networks"; // 1. Get projectId from https://dashboard.reown.com const projectId = "YOUR_PROJECT_ID"; // 2. Create the AppKit instance const modal = createAppKit({ networks: [mainnet, arbitrum, sepolia], projectId, }); ``` ## Use without AppKit You can subscribe to the `display_uri` event and handle the URI yourself. ```ts theme={null} function handleURI(uri: string) { //code... } provider.on("display_uri", handleURI); await provider.connect(); // or const accounts = await provider.enable(); ``` You can then use the URI to generate a QR Code or redirect the user from the mobile browser to the wallet and request to connect. The later one will require you to use the wallet's deep link and the URI. You can get the deep link of wallets that support the WalletConnect v2 protocol from the [Explorer API](../../cloud/explorer.md). ## Sending Requests ```typescript theme={null} const result = await provider.request({ method: "eth_requestAccounts" }); // OR provider.sendAsync({ method: "eth_requestAccounts" }, CallBackFunction); ``` ## Events ```typescript theme={null} // chain changed provider.on("chainChanged", handler); // accounts changed provider.on("accountsChanged", handler); // session established provider.on("connect", handler); // session event - chainChanged/accountsChanged/custom events provider.on("session_event", handler); // connection uri provider.on("display_uri", handler); // session disconnected from the wallet - this won't be called when the disconnect function is called from the dapp. provider.on("disconnect", handler); ``` ## Session data Once a wallet is connected you can find the session data in the `provider.session` object. The session object includes the following properties, *among others*: * **namespaces**: `session.namespaces` is an object that contains the approved session data. Note that the `chains` object is an optional parameter and may be undefined. Therefore, we encourage apps to obtain the approved chains from the `session.accounts` object instead. ```ts theme={null} interface Namespaces { chains?: string[]; accounts: string[]; methods: string[]; events: string[]; } ``` * **requiredNamespaces, optionalNamespaces & sessionProperties**: These objects contain the namespaces and properties proposed for the session. * **peer**: The `session.peer.metadata` object contains the metadata of the connected wallet. ```ts theme={null} interface Metadata { name: string; description: string; url: string; icons: string[]; verifyUrl?: string; redirect?: { native?: string; universal?: string; }; } ``` Find the complete type definition of the `session` object [here](https://github.com/WalletConnect/walletconnect-monorepo/blob/022e4d492c9862ab9b17c1a7b12884bdcd992ae4/packages/types/src/sign-client/session.ts#L25). # Solana Adapter Source: https://docs.reown.com/advanced/providers/solana-adapter The WalletConnect Solana Adapter allows you to integrate the WalletConnect protocol into the Wallet Adapter library. This adapter is compatible with **Solana and SVM-based chains**, including [Solayer Chain](https://solayer.org). Applications built on SVM-compatible networks can use the same Solana adapter for wallet authentication and transaction signing. If you are not familiar with the Wallet Adapter library it is recommended to use [AppKit instead](../../appkit//overview). AppKit now supports multichain, which means you can choose and configure multiple blockchain networks within your instance of AppKit, extending beyond just Ethereum-based (EVM) networks. ## Installation `bash npm npm install @walletconnect/solana-adapter ` `bash Yarn yarn add @walletconnect/solana-adapter ` `bash Bun bun add @walletconnect/solana-adapter ` `bash pnpm pnpm add @walletconnect/solana-adapter ` ## Cloud Configuration Create a new project on [Reown Dashboard](https://dashboard.reown.com) and obtain a new project ID. Head over to Reown Dashboard and create a new project. ## Implementation Add the `WalletConnectAdapter` to your wallets list. ```tsx {12, 22-27} theme={null} import { ReactNode, useMemo, useState } from 'react' import { ConnectionProvider, WalletProvider } from '@solana/wallet-adapter-react' import { WalletAdapterNetwork } from '@solana/wallet-adapter-base' import { WalletModalProvider } from '@solana/wallet-adapter-react-ui' import { clusterApiUrl } from '@solana/web3.js' import '@solana/wallet-adapter-react-ui/styles.css' import { WalletConnectWalletAdapter } from '@walletconnect/solana-adapter' export const SolanaContext = ({ children }: { children: ReactNode }) => { const endpoint = useMemo(() => clusterApiUrl(WalletAdapterNetwork.Mainnet), []) const wallets = useMemo( () => [ new WalletConnectWalletAdapter({ network: WalletAdapterNetwork.Mainnet, options: { projectId: 'YOUR_PROJECT_ID' } }) ], // eslint-disable-next-line react-hooks/exhaustive-deps [] ) return ( {children} ) } ``` # Universal Provider Source: https://docs.reown.com/advanced/providers/universal Universal Provider is a multi-chain provider for WalletConnect v2 protocol. Find more about different supported chains [here](../../cloud/chains/overview.md). ## Installation ```bash npm theme={null} npm install @walletconnect/universal-provider ``` ```bash Yarn theme={null} yarn add @walletconnect/universal-provider ``` ```bash Bun theme={null} bun add @walletconnect/universal-provider ``` ```bash pnpm theme={null} pnpm add @walletconnect/universal-provider ``` ## Usage ```typescript theme={null} import UniversalProvider from "@walletconnect/universal-provider"; // Initialize the provider const provider = await UniversalProvider.init({ projectId: "YOUR_PROJECT_ID", metadata: { name: "React App", description: "React App for WalletConnect", url: "https://walletconnect.com/", icons: ["https://avatars.githubusercontent.com/u/37784886"], }, client: undefined, // optional instance of @walletconnect/sign-client }); // create sub providers for each namespace/chain await provider.connect({ optionalNamespaces: { eip155: { methods: [ "eth_sendTransaction", "eth_signTransaction", "eth_sign", "personal_sign", "eth_signTypedData", ], chains: ["eip155:80001"], events: ["chainChanged", "accountsChanged"], rpcMap: { 80001: "https://rpc.walletconnect.com?chainId=eip155:80001&projectId=", }, }, }, pairingTopic: "<123...topic>", // optional topic to connect to skipPairing: false, // optional to skip pairing ( later it can be resumed by invoking .pair()) }); ``` ## Events ```typescript theme={null} // Subscribe for pairing URI provider.on("display_uri", (uri) => { console.log("display_uri", uri); }); // Subscribe to session ping provider.on("session_ping", ({ id, topic }) => { console.log("session_ping", id, topic); }); // Subscribe to session event provider.on("session_event", ({ event, chainId }) => { console.log("session_event", event, chainId); }); // Subscribe to session update provider.on("session_update", ({ topic, params }) => { console.log("session_update", topic, params); }); // Subscribe to session delete provider.on("session_delete", ({ id, topic }) => { console.log("session_delete", id, topic); }); ``` ## Provider Methods ```typescript theme={null} interface RequestArguments { method: string; params?: any[] | undefined; } // Send JSON RPC requests /** * @param payload * @param chain - optionally specify which chain should handle this request * in the format `:` e.g. `eip155:1` */ const result = await provider.request(payload: RequestArguments, chain: string | undefined); ``` ## Chain switching `DefaultChain` is the current chain that the provider will target for the next requested transaction. ```typescript theme={null} // set the default chain to 56 provider.setDefaultChain(`eip155:56`, rpcUrl?: string | undefined); ``` ## Session data Once a wallet is connected you can find the session data in the `provider.session` object. The session object includes the following properties, *among others*: * **namespaces**: `session.namespaces` is an object that contains the approved session data. Note that the `chains` object is an optional parameter and may be undefined. Therefore, we encourage apps to obtain the approved chains from the `session.accounts` object instead. ```ts theme={null} interface Namespaces { chains?: string[]; accounts: string[]; methods: string[]; events: string[]; } ``` * **requiredNamespaces, optionalNamespaces & sessionProperties**: These objects contain the namespaces and properties proposed for the session. * **peer**: The `session.peer.metadata` object contains the metadata of the connected wallet. ```ts theme={null} interface Metadata { name: string; description: string; url: string; icons: string[]; verifyUrl?: string; redirect?: { native?: string; universal?: string; }; } ``` Find the complete type definition of the `session` object [here](https://github.com/WalletConnect/walletconnect-monorepo/blob/022e4d492c9862ab9b17c1a7b12884bdcd992ae4/packages/types/src/sign-client/session.ts#L25). # Report an Issue Source: https://docs.reown.com/advanced/report-an-issue Report bugs, share feedback, and get help through the Reown Dashboard The [Reown Dashboard](https://dashboard.reown.com/) is your single place to report bugs, share feedback, send us a message, and get help resolving issues with our AI-powered support. ## How to Report an Issue Follow these steps to get in touch with our support team: ### Step 1 - Log in to the Reown Dashboard Go to [dashboard.reown.com](https://dashboard.reown.com/) and log in with your account. ### Step 2 - Open the Help Center Once logged in, click the **chat bubble** in the bottom-right corner of the page, or choose **Report a bug** from the **Help Center** sidebar. Help Center bubble in the bottom-right corner of the Reown Dashboard ### Step 3 - Choose an Option From the help desk modal, select the option that best fits your needs: * **Send us a message** - Reach out directly to our support team. * **Create a ticket / Report an issue** - File a bug report or request assistance with a technical problem. * **Check our docs** - Browse through our documentation for answers. Help desk modal with support options Our team will review your submission and get back to you as soon as possible. ## Support Response Times Depending on your plan, you can expect different levels of support: **Response time & expert issue resolution:** Up to 7 days. In-dashboard support with the ability to create support tickets. **Guaranteed 24-hour response time** and expert issue resolution. Prioritized support across multiple channels (email, Slack, Telegram, ticketing system). ### Upgrade Your Plan Want faster response times and dedicated support? You can upgrade your plan directly from the [Reown Dashboard](https://dashboard.reown.com/): 1. Log in to [dashboard.reown.com](https://dashboard.reown.com/) 2. Click the **"Upgrade Now"** button in the top right-hand corner 3. Choose **[Pro](/appkit/paid-plans/pro)** or **[Enterprise](/appkit/paid-plans/enterprise)** depending on your needs For a full comparison of all plans and pricing, visit reown.com/pricing. # Content Security Policy (CSP) Source: https://docs.reown.com/advanced/security/content-security-policy ## Overview A Content Security Policy (CSP) is a security feature that helps protect web applications from various attacks like Cross-Site Scripting (XSS), clickjacking, and data injection. By specifying allowed content sources, CSPs minimize the risk of executing malicious content on your site. ## CSP Guidance ### AppKit The following is a **partial CSP** that covers WalletConnect's libraries and services for [AppKit](https://docs.walletconnect.com/appkit/overview). Note that **you may need to define additional sources based on your application's requirements**. ``` default-src 'self'; script-src 'self'; style-src https://fonts.googleapis.com; img-src * 'self' data: blob: https://walletconnect.org https://walletconnect.com https://secure.walletconnect.com https://secure.walletconnect.org https://tokens-data.1inch.io https://tokens.1inch.io https://ipfs.io https://cdn.zerion.io; font-src 'self' https://fonts.gstatic.com https://fonts.reown.com; connect-src 'self' https://rpc.walletconnect.com https://rpc.walletconnect.org https://relay.walletconnect.com https://relay.walletconnect.org wss://relay.walletconnect.com wss://relay.walletconnect.org https://pulse.walletconnect.com https://pulse.walletconnect.org https://api.web3modal.com https://api.web3modal.org https://keys.walletconnect.com https://keys.walletconnect.org https://notify.walletconnect.com https://notify.walletconnect.org https://echo.walletconnect.com https://echo.walletconnect.org https://push.walletconnect.com https://push.walletconnect.org wss://www.walletlink.org https://cca-lite.coinbase.com; frame-src 'self' https://verify.walletconnect.com https://verify.walletconnect.org https://secure.walletconnect.com https://secure.walletconnect.org; Cross-Origin-Opener-Policy: same-origin-allow-popups; ``` You may need to list the RPC endpoints used by blockchain networks you have enabled (e.g. via the [`@wagmi/chains` package](https://wagmi.sh/core/api/chains)) as part of your `connect-src` definition. For a full of list of RPC sources used by `wagmi/viem`, please refer to [Viem's chain definitions](https://github.com/wevm/viem/tree/main/src/chains/definitions). **Cross-Origin-Opener-Policy for Social Login Security**: The `Cross-Origin-Opener-Policy: same-origin-allow-popups` header is essential when using AppKit's social login features (Google, X, GitHub, Discord, Apple, Facebook, Farcaster). This header helps prevent tabnabbing attacks during OAuth flows by controlling how popup windows can interact with your application. Without this header, malicious sites could potentially hijack the authentication flow and redirect users to phishing pages. ## Testing and Deploying Your CSP ### Test Your CSP in a Staging Environment Run through your standard user flows in a staging environment with CSP enforcement. This may include connecting to browser extension wallets, transacting, logging out, etc. Directives may need updates after SDK upgrades. Always test your CSP again before deploying updates to production. ### Using Report-Only Mode Use the `Content-Security-Policy-Report-Only` header, which sends violation reports without enforcing policies. This helps assess the impact of CSP changes without affecting functionality. ### Deployment First deploy your CSP in `report-only` mode. After validation, migrate to `Content-Security-Policy` for enforcement. ### Monitoring Configure `report-uri` or `report-to` to receive violation reports and set up a monitoring dashboard for review. # Security Information Source: https://docs.reown.com/advanced/security/security-information Security is not just a feature but a fundamental aspect of Reown's 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. ## AppKit - Embedded Wallet Key Management ### Architecture and Custody AppKit Embedded wallets enable applications to provide end-users with a quick onboarding experience by provisioning a non-custodial wallet through social login or email wallets. While the implementation varies per network, Reown relies on a SOC 2 Type 2 compliant third-party vendor for key management. The vendor's [security overview](https://magic.link/docs/home/security/product-security) and [list of audits](https://magic.link/docs/home/security/security-compliance) are available in their documentation. For a subset of EVM Networks, gas abstraction functionality requires deploying a Smart Account on behalf of the end-user. In this case, the key management provider acts as a signer for this Smart Account. Reown relies on a third-party vendor for the Smart Account implementation. The [Smart Account implementation audits](https://docs.safe.global/smart-account-audits) are available in their documentation. ### Key Export Reown enables end-users to export their keys when needed. ### Audits Both the key management vendors and Smart Account vendors have undergone multiple audits (see links above). The integration of the key management provider into AppKit has been audited by Halborn. The complete audit report is available [here](https://drive.google.com/file/d/1LQ6BkcI4PHs_FKAzpCRMqwD--rq6uOy6/view). ## WalletKit ### Architecture WalletKit 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 WalletKit, 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 WalletKit's design philosophy prioritizes minimizing third-party dependencies to reduce the attack surface area. ## Third-Party Reviews The security infrastructure of Reown has undergone multiple rounds of audits by independent security auditing firms, including Trail of Bits, Halborn, and Spearbit. These audits cover both AppKit and WalletKit, along with a comprehensive company-wide Threat Model. | Audit Scope | Auditor | Report | | ---------------------------------------------------- | ------------- | ------------------------------------------------------------------------------------------------------------------------- | | WalletConnect Comprehensive Threat Model | Spearbit | [View Report](https://drive.google.com/file/d/1QpPSLvCEMunaYHHBPN0g6kYd39uFxpPk/view) | | AppKit Embedded Wallet Integration Pentest | Halborn | [View Report](https://drive.google.com/file/d/1LQ6BkcI4PHs_FKAzpCRMqwD--rq6uOy6/view) | | WalletKit 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 Reown 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 text file](https://reown.com/.well-known/security.txt) or the [security page](https://reown.com/security). ## Get in Touch For security-related inquiries, please visit the [security contact page](https://reown.com/security). # WalletKit Migration Source: https://docs.reown.com/advanced/walletkit-migration WalletKit documentation has moved to the WalletConnect Docs. Find links to the new locations for all migrated pages, and answers to common questions about the new WalletConnect Dashboard. The following WalletKit-related pages have been migrated from Reown Docs to the [WalletConnect Docs](https://docs.walletconnect.network). Use the links below to find the updated content. ## Migrated Pages | Former Reown Docs Page | New WalletConnect Docs Location | | ----------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | WalletGuide Submission | [WalletGuide Submission](https://docs.walletconnect.network/walletguide/explorer-submission) | | Deprecated WalletConnect SDKs | [Upgrade from Web3Wallet to Wallet SDK](https://docs.walletconnect.network/wallet-sdk/upgrade/from-web3wallet-to-reown) | | Sign API - Wallet Usage | [Wallet SDK Web - One-click Auth](https://docs.walletconnect.network/wallet-sdk/web/one-click-auth) and platform-specific Usage pages ([Web](https://docs.walletconnect.network/wallet-sdk/web/usage), [iOS](https://docs.walletconnect.network/wallet-sdk/ios/usage), [React Native](https://docs.walletconnect.network/wallet-sdk/react-native/usage)) | | WalletConnectModal Usage | [App SDK Overview](https://docs.walletconnect.network/app-sdk/overview) | | WalletConnectModal Resources | [Wallet SDK Web - Resources](https://docs.walletconnect.network/wallet-sdk/web/resources) and [Wallet SDK React Native - Resources](https://docs.walletconnect.network/wallet-sdk/react-native/resources) | ## WalletConnect Dashboard FAQ If you are a legacy WalletKit team previously using the Reown Cloud dashboard, the new [WalletConnect Dashboard](https://dashboard.walletconnect.com) is now the place to manage all your wallet projects, integrations, and WalletGuide submissions. Below are answers to common questions about the transition. All WalletKit teams should use the new [WalletConnect Dashboard](https://dashboard.walletconnect.com) to manage their projects. This dashboard replaces the Reown Cloud dashboard as the unified hub for wallet and app developers to create projects, submit wallets to WalletGuide, and manage WalletConnect Certification. Yes. Your existing Project ID will remain the same and will continue to work as expected. There is no need to create a new Project ID or update your integration. Simply log in to [dashboard.walletconnect.com](https://dashboard.walletconnect.com) and you will find your existing projects and Project IDs ready to use. Yes. Your team setup, including team members and project configurations, will remain the same on the new WalletConnect Dashboard. No action is required to migrate your team — everything carries over automatically. You can log in to [dashboard.walletconnect.com](https://dashboard.walletconnect.com) using the same credentials you used for the Reown Cloud dashboard. Your login method (email, social, or wallet-based authentication) remains unchanged. The [WalletConnect Dashboard](https://dashboard.walletconnect.com) is the unified home for wallet and app developers. From the dashboard you can: * **Create and manage projects** — Set up new projects and obtain Project IDs for your wallet or app. * **Submit your wallet to WalletGuide** — Get your wallet listed in the WalletConnect modal so users can discover and connect with it. * **Manage WalletConnect Certification** — Submit, track, and manage your certification process all in one place. * **View analytics** — Monitor usage and performance of your integrations. No code changes are required. Your existing Project IDs and SDK integrations will continue to work without modification. The dashboard change only affects where you manage your projects and settings — it does not impact your application's runtime behavior. Read the official announcement blog post: [Meet the New WalletConnect Dashboard](https://walletconnect.com/blog/meet-the-new-walletconnect-dashboard). For additional help, join the [WalletConnect Discord](https://discord.gg/walletconnect) and post in the developers forum. # Analytics Source: https://docs.reown.com/appkit/android/cloud/analytics ## What is the Reown Analytics feature? Reown offers in-depth analytics so you can track your project's progress. Explore your users' behavior, including their origin countries, wallet providers, hours most active and more. Or dive into the details about the total number and volume of swaps and onramps you've enabled. With Reown Analytics, you have the power to make data-driven decisions to take your app to the next level. ## How to find Reown Analytics ### See your project's analytics To access Reown Analytics for your project, follow these simple steps: 1. Log in to the [Reown Dashboard](https://dashboard.reown.com/sign-in). 2. Click on your Project. 3. Click the **Analytics** tab. 4. Pick the Analytics page you would like to view: either **User Activity**, **Swaps** or **Onramps**. The Analytics pages show in-depth insights into your app's performance. ### See your team's Usage To track your RPC usage or total MAUs, follow these steps: 1. Log in to the [Reown Dashboard](https://dashboard.reown.com/sign-in). 2. Select the team you want to check in the top left hand corner. 3. Click on the **Usage** tab. The Usage tab shows your team's total RPC calls and MAUs in the past 30 days, including any overage. ## Understanding Reown Project Analytics ### User Activity Under the **User Activity** tab, you'll find in-depth data about your users and how they are interacting with your app. #### Total Users The total users chart shows you how many users you've served during a specific period. On Starter and Pro, you have access to the 7 day history. On Enterprise, you have the full history of total users, filterable by Week, Month, Quarter, Year or All time. #### Sessions vs Wallet Connection The sessions vs wallet connection chart shows you how many times a session was started and how many of those sessions resulted in a wallet connection. On Starter and Pro, you have access to the 7 day history. On Enterprise, you have the full history, filterable by Week, Month, Quarter, Year or All time. #### Total Signatures The total signatures chart shows you the number of transaction signatures your users have made in a given period. On Pro, you have access to the 7 day history. On Enterprise, you have the full history, filterable by Week, Month, Quarter, Year or All time. (Not available on Starter plans) #### Active Hours The active hours chart shows you which hours of the day your users are most active. Available on Pro and Enterprise plans. (Not available on Starter plans) #### Operating Systems The operating systems chart breaks down which operating systems your users access your app from. Available on Pro and Enterprise plans. (Not available on Starter plans) #### Networks The Networks chart shows you the top networks your users access your app through. On Pro, you have access to the 7 day history. On Enterprise, you have the full history, filterable by Week, Month, Quarter, Year or All time. (Not available on Starter plans) #### Connection Methods The Connection methods chart shows you how users log in to your app, either via browser, mobile or QR code. Available on Pro and Enterprise plans. (Not available on Starter plans) #### Social Login Providers The social logins chart shows you your users' top social or email login methods. Available on Pro and Enterprise plans. (Not available on Starter plans) #### Wallet Providers The Wallets chart shows you which wallet providers your users are connecting to your app with. Available on Pro and Enterprise plans. (Not available on Starter plans) #### Top Countries The countries chart shows you where in the world your users are connecting to your app from. On Pro, you have access to the 7 day history. On Enterprise, you have the full history, filterable by Week, Month, Quarter, Year or All time. (Not available on Starter plans) #### User Net Worth The user net worth chart shows valuable insights into your high value users, categorizing them by their onchain wealth. The data can be filtered by token holdings and network to surface which assets your highest value users hold and where. Available on Enterprise plans. (Not available on Starter or Pro plans) #### Wallet Intelligence Wallet Intelligence gives you valuable insights into each of your individual users' behavior, activity, authentication status, holdings and more. Filter connected users by: * **Country** – to gain deeper geographical insights * **Net worth segment** – to identify and research your whales and high-value users * **Authentication status** – to understand which method of authentication specific users choose Plus, gain insights on each connected user including: * Their token holdings * The networks they hold tokens on * The wallets they use to connect * A blockchain explorer link for further insights Available on Enterprise plans only. (Not available on Starter or Pro plans) #### App Co-usage The App co-usage chart gives valuable insights into the other apps your audience uses. Available on Enterprise plans. (Not available on Starter or Pro plans) **COMING SOON!** ### Swaps Under the **Swaps** tab, you'll find information about how your users are swapping crypto in your app. #### Total Swaps The total swaps chart shows you the total number of swaps your app has facilitated in a given period. On Starter and Pro, you have access to the 7 day history. On Enterprise, you have the full history, filterable by Week, Month, Quarter, Year or All time. #### Swap Volume The swap volume chart shows you the volume generated in your app via swaps for a given period. On Starter and Pro, you have access to the 7 day history. On Enterprise, you have the full history, filterable by Week, Month, Quarter, Year or All time. #### Swap Pairs The swap pairs chart shows you the top cryptocurrencies users are swapping to and from in a given period. On Starter and Pro, you have access to the 7 day history. On Enterprise, you have the full history, filterable by Week, Month, Quarter, Year or All time. #### Swap Countries The swap countries chart shows you the top countries your users are swapping from in a given period. On Starter and Pro, you have access to the 7 day history. On Enterprise, you have the full history, filterable by Week, Month, Quarter, Year or All time. ### Onramp Under the **Onramp** tab, you'll find information about how your users are buying crypto in your app. #### Total Onramps The total onramps chart shows you the total number of onramps your app has facilitated in a given period. On Starter and Pro, you have access to the 7 day history. On Enterprise, you have the full history, filterable by Week, Month, Quarter, Year or All time. #### Onramp Volume The onramp volume chart shows you the volume generated in your app via onramps for a given period. On Starter and Pro, you have access to the 7 day history. On Enterprise, you have the full history, filterable by Week, Month, Quarter, Year or All time. #### Onramp Currencies The onramp currencies chart shows you the top currencies your users are buying in a given period. On Starter and Pro, you have access to the 7 day history. On Enterprise, you have the full history, filterable by Week, Month, Quarter, Year or All time. #### Onramp Countries The onramp countries chart shows you the top countries your users are buying crypto from in a given period. On Starter and Pro, you have access to the 7 day history. On Enterprise, you have the full history, filterable by Week, Month, Quarter, Year or All time. # Blockchain API Source: https://docs.reown.com/appkit/android/cloud/blockchain-api The Blockchain API is the RPC service that powers AppKit's blockchain functions such as account balances, ENS resolution, transaction history, and more. Blockchain API is not the same as the WalletConnect protocol. WalletConnect protocol supports wallets on all chains using the [CAIP-25](https://chainagnostic.org/CAIPs/caip-25) standard. We do not accept requests for new chains to be added to our Blockchain API. Please see your SDK's relevant documentation on how to add RPC URLs for chains you want to use that Blockchain API does not. ## Features * AppKit built-in integration * Multi-chain mainnet and testnets * HTTP RPC support * Cloud metrics and reporting * The Identity API with near-instant ENS resolution * Transaction history ## Supported Chains Chain name with associated `chainId` query param to use. ### HTTP RPC #### Ethereum | Network | Chain ID | | ------------------------------------------------------ | ----------------- | | Ethereum Mainnet | eip155:1 | | Optimism Mainnet | eip155:10 | | Cronos Mainnet [1](#footnote1) | eip155:25 | | Rootstock Mainnet [1](#footnote1) | eip155:30 | | Rootstock Testnet [1](#footnote1) | eip155:31 | | Binance Smart Chain Mainnet | eip155:56 | | Binance Smart Chain Testnet [1](#footnote1) | eip155:97 | | Gnosis Chain Mainnet | eip155:100 | | Unichain Mainnet [1](#footnote1) | eip155:130 | | Polygon Mainnet | eip155:137 | | Sonic Mainnet | eip155:146 | | zkSync Era Sepolia Testnet [1](#footnote1) | eip155:300 | | zkSync Era Mainnet | eip155:324 | | Polygon zkEVM Mainnet | eip155:1101 | | Wemix Mainnet [1](#footnote1) | eip155:1111 | | Wemix Testnet [1](#footnote1) | eip155:1112 | | Moonbeam GLMR [1](#footnote1) | eip155:1284 | | Unichain Sepolia [1](#footnote1) | eip155:1301 | | Sei Network [1](#footnote1) | eip155:1329 | | Morph Mainnet [1](#footnote1) | eip155:2818 | | Morph Hoodi [1](#footnote1) | eip155:2910 | | Mantle Mainnet [1](#footnote1) | eip155:5000 | | Mantle Testnet [1](#footnote1) | eip155:5003 | | Kaia Mainnet | eip155:8217 | | Base Mainnet | eip155:8453 | | Monad Testnet | eip155:10143 | | Ethereum Holesky | eip155:17000 | | Arbitrum Mainnet | eip155:42161 | | Celo Mainnet | eip155:42220 | | Avalanche Fuji Testnet [1](#footnote1) | eip155:43113 | | Avalanche C-Chain | eip155:43114 | | DataHaven Testnet [1](#footnote1) | eip155:55931 | | Sonic Testnet [1](#footnote1) | eip155:57054 | | Linea Mainnet [1](#footnote1) | eip155:59144 | | Polygon Amoy [1](#footnote1) | eip155:80002 | | Berachain Bepolia [1](#footnote1) | eip155:80069 | | Berachain Mainnet [1](#footnote1) | eip155:80094 | | Base Sepolia | eip155:84532 | | Arbitrum Sepolia | eip155:421614 | | Scroll Mainnet [1](#footnote1) | eip155:534352 | | Scroll Sepolia Testnet [1](#footnote1) | eip155:534351 | | Ethereum Hoodi [1](#footnote1) | eip155:560048 | | XRPL EVM Mainnet [1](#footnote1) | eip155:1440000 | | XRPL EVM Testnet [1](#footnote1) | eip155:1449000 | | Zora [1](#footnote1) | eip155:7777777 | | Ethereum Sepolia | eip155:11155111 | | Optimism Sepolia | eip155:11155420 | | Zora Sepolia [1](#footnote1) | eip155:999999999 | | Aurora Mainnet [1](#footnote1) | eip155:1313161554 | | Aurora Testnet [1](#footnote1) | eip155:1313161555 | | Near Mainnet | near:mainnet | #### Solana | Network | Chain ID | | -------------- | --------------------------------------- | | Solana Mainnet | solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp | | Solana Devnet | solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1 | | Solana Testnet | solana:4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z | #### Bitcoin | Network | Chain ID | | --------------- | --------------------------------------- | | Bitcoin Mainnet | bip122:000000000019d6689c085ae165831e93 | | Bitcoin Testnet | bip122:000000000933ea01ad0ee984209779ba | #### Sui | Network | Chain ID | | ----------- | ----------- | | Sui Mainnet | sui:mainnet | | Sui Devnet | sui:devnet | | Sui Testnet | sui:testnet | #### Tron | Network | Chain ID | | -------------------------------------------- | --------------- | | Tron Mainnet | tron:0x2b6653dc | | Tron Nile Testnet [1](#footnote1) | tron:0xcd8690dc | #### Ton | Network | Chain ID | | ----------- | -------- | | Ton Mainnet | ton:-239 | | Ton Testnet | ton:-3 | #### Stacks The Stacks support is currently in Beta. Endpoints and schema can be changed in the near future. | Network | Chain ID | | ----------------------------------------- | ----------------- | | Stacks Mainnet [1](#footnote1) | stacks:1 | | Stacks Testnet [1](#footnote1) | stacks:2147483648 | 1 The availability of this chain in our RPC is not guaranteed. ### WebSocket RPC WebSocket RPC is not recommended for production use, and may be removed in the future. #### Ethereum | Network | Chain ID | | ------------------- | -------------- | | Ethereum Mainnet | eip155:1 | | Binance Smart Chain | eip155:56 | | Polygon Mainnet | eip155:137 | | Base Mainnet | eip155:8453 | | Zora | eip155:7777777 | #### Solana | Network | Chain ID | | -------------- | --------------------------------------- | | Solana Mainnet | solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp | | Solana Devnet | solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1 | ## Using the Blockchain API No config or setup is needed for AppKit integrations. For other usage, see the [Usage](https://github.com/walletconnect/blockchain-api#usage) section. ## Limits The Blockchain API is free for 2.5 million requests per 30 days. If you wish to increase your limits, contact us [via our form here](https://share.hsforms.com/1_oWa8QkwRXi6oR0nZ_SIxQnxw6s). # Relay Source: https://docs.reown.com/appkit/android/cloud/relay ## Project ID The Project ID is consumed through URL parameters. URL parameters used: * `projectId`: Your Project ID can be obtained from [dashboard.reown.com](https://dashboard.reown.com) Example URL: `https://relay.walletconnect.com/?projectId=c4f79cc821944d9680842e34466bfbd` This can be instantiated from the client with the `projectId` in the `SignClient` constructor. ```javascript theme={null} import SignClient from '@walletconnect/sign-client' const signClient = await SignClient.init({ projectId: 'c4f79cc821944d9680842e34466bfb' }) ``` ## Allowlist To help prevent malicious use of your project ID you are strongly encouraged to set an allowlist of [origins](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Origin) or application/bundle ids for mobile applications where the project ID is used. Requests from other origins will be denied. * Allowlist supports a list of origins in the format `[scheme://] /* callback for error while trying to disconnection with a peer */ } ) ``` ### Request ```kotlin theme={null} val requestParams = Modal.Params.Request( method = /* Selected method */, params = /* Method params */, ) AppKit.request( request = requestParams, onSuccess = { /* callback that letting you know that you have successful request */ }, onError = { error -> /* callback for error */ } ) ``` ### Get Active Account Returns the current active account connected via AppKit ```kotlin theme={null} AppKit.getAccount() ``` ### Get Connection type Return information about the type of our connection ```kotlin theme={null} AppKit.getConnectorType() ``` # Components Source: https://docs.reown.com/appkit/android/core/components You can use predefined AppKitComponent and add it in your application. As a view, dialog or modal. ```kotlin theme={null} import androidx.compose.material.ExperimentalMaterialApi import androidx.compose.material.ModalBottomSheetState import androidx.navigation.compose.NavHost import androidx.navigation.compose.composable import androidx.navigation.compose.rememberNavController import androidx.compose.material.ModalBottomSheetLayout setContent { val modalSheetState = rememberModalBottomSheetState(initialValue = ModalBottomSheetValue.Hidden, skipHalfExpanded = true) val coroutineScope = rememberCoroutineScope() val navController = rememberNavController() ModalBottomSheetLayout( sheetContent = { AppKitComponent( shouldOpenChooseNetwork = true | false, closeModal = { coroutineScope.launch { modalSheetState.hide() } ) } ) { // content } } ``` ## Buttons You can add ready made button components to your application ### Web3Button ```kotlin theme={null} import com.reown.appkit.ui.components.button.Web3Button import com.reown.appkit.ui.components.button.ConnectButtonSize import com.reown.appkit.ui.components.button.AccountButtonType import com.reown.appkit.ui.components.button.rememberAppKitState YourAppScreen(navController: NavController) { val appKitState = rememberAppKitState(navController = navController) Web3Button( state = appKitState, accountButtonType = AccountButtonType.NORMAL || AccountButtonType.MIXED, connectButtonSize = ConnectButtonSize.NORMAL || ConnectButtonSize.SMALL ) } ``` ```xml theme={null} ``` ### Network Button ```kotlin theme={null} import com.reown.appkit.ui.components.button.NetworkButton import com.reown.appkit.ui.components.button.rememberAppKitState YourAppScreen(navController: NavController) { val appKitState = rememberAppKitState(navController = navController) NetworkButton(state = appKitState) } ``` ```xml theme={null} ``` ### Connect Button ```kotlin theme={null} import com.reown.appkit.ui.components.button.ConnectButton import com.reown.appkit.ui.components.button.ConnectButtonSize import com.reown.appkit.ui.components.button.rememberAppKitState YourAppScreen(navController: NavController) { val appKitState = rememberAppKitState(navController = navController) ConnectButton( state = appKitState, buttonSize = ConnectButtonSize.NORMAL || ConnectButtonSize.SMALL ) } ``` ```xml theme={null} ``` ### Account Button ```kotlin theme={null} import com.reown.appkit.ui.components.button.AccountButton import com.reown.appkit.ui.components.button.AccountButtonType import com.reown.appkit.ui.components.button.rememberAppKitState YourAppScreen(navController: NavController) { val appKitState = rememberAppKitState(navController = navController) AccountButton( state = appKitState, buttonSize = AccountButtonType.NORMAL || AccountButtonType.MIXED ) } ``` ```xml theme={null} ``` ### AppKit State AppKitState is an object that ensures communication between your application and the state of the AppKit. #### Create appKitState: NavController is required to create appKitState ```kotlin theme={null} val appKitState = rememberAppKitState(navController) ``` #### AppKitState methods ```kotlin theme={null} appKitState.isOpen ``` returns `StateFlow` whose value is updated depending on whether the appkit component is open ```kotlin theme={null} appKitState.isConnected ``` returns `StateFlow` whose value depends on the active session in AppKit # Kotlin Source: https://docs.reown.com/appkit/android/core/installation Kotlin implementation of AppKit for Android applications. Android Core \ Appkit ### Requirements * Android min SDK 23 * Java 11 ## Installation root/build.gradle.kts: ```gradle theme={null} allprojects { repositories { mavenCentral() maven { url "https://jitpack.io" } } } ``` app/build.gradle.kts ```gradle theme={null} implementation(platform("com.reown:android-bom:$BOM_VERSION")) implementation("com.reown:android-core") implementation("com.reown:appkit") ``` ## ProGuard rules If you encounter issues with minification, add the below rules to your application: ``` -keepattributes *Annotation* -keep class com.sun.jna.** { *; } -keepclassmembers class com.sun.jna.** { native ; *; } -keep class uniffi.** { *; } # Preserve all public and protected fields and methods -keepclassmembers class ** { public *; protected *; } -dontwarn uniffi.** -dontwarn com.sun.jna.** ``` ## Example Check the Kotlin example ## Test Apps Want to see AppKit in action? Download our sample AppKit apps below and explore what it can do. Enjoy! 😊 * [Android Build (Firebase)](https://appdistribution.firebase.google.com/pub/i/4cf60e7b49f9265e) # Sign In With Ethereum Source: https://docs.reown.com/appkit/android/core/one-click-auth AppKit provides a simple solution for integrating with "Sign In With Ethereum" (SIWE), a form of authentication that enables users to control their digital identity with their Ethereum account. SIWE is a standard also known as [EIP-4361](https://docs.login.xyz/general-information/siwe-overview/eip-4361). ## One-Click Auth One-Click Auth represents a key advancement within WalletConnect v2, streamlining the user authentication process in AppKit by enabling them to seamlessly connect with a wallet and sign a SIWE message with just one click. Connecting a wallet, proving control of an address with an off-chain signature, authorizing specific actions. These are the kinds of authorizations that can be encoded as "ReCaps". ReCaps are permissions for a specific website or dapp that can be compactly encoded as a long string in the message you sign and translated by any wallet into a straight-forward one-sentence summary. WalletConnect uses permissions expressed as ReCaps to enable a One-Click Authentication. ## Configure your AppKit Client To integrate SIWE with AppKit, you need to configure your AppKit client using `Modal.Model.AuthPayloadParams`, which are required to create a SIWE message for the user to sign: ```kotlin theme={null} AppKit.setAuthRequestParams(authPayloadParams) ``` #### Example of AuthRequestParams ```kotlin theme={null} val authParams = Modal.Model.AuthPayloadParams( chains = ["eip155:1", "eip155:137"], domain = "yourDappDomain.com", uri = "https://yourDappDomain.com/login", nonce = //uniqueNonce, statement = "I accept the Terms of Service: https://yourDappDomain.com/", methods = ["personal_sign", "eth_sendTransaction"], resources = null //// Here your dapp may request authorization with ReCaps ) ``` Configuring your AppKit client with Modal.Model.AuthPayloadParams will prioritize authentication requests over regular session proposals. If the wallet supports One-Click Auth, the session will be created and the user will automatically authenticate without needing to send another SIWE request over personal\_sign. If the wallet does not support One-Click Auth, it will fall back to the session proposal. In this case, to authenticate the user, AppKit will send another session request to prove address ownership. To check whether the user has signed a SIWE message, check `onSessionAuthenticateResponse` callback from `AppKit.ModalDelegate`: ```kotlin theme={null} fun onSessionAuthenticateResponse(response: Modal.Model.SessionAuthenticateResponse) { // Triggered when Dapp receives the session authenticate response from wallet if (response is Modal.Model.SessionAuthenticateResponse.Result) { if (response.session != null) { // Authentication successful, session established } else { // Authentication successful, but no session created (SIWE-only flow) } } else { // Authentication request was rejected or failed } } ``` ### Fallback to SIWE Over Session Request If the wallet connecting to your dapp does not support One-Click Auth, the SDK will fallback to the `wc_sessionPropose` method and create a session with the wallet. AppKit will then inform the user that they need to sign a message to prove address ownership. AppKit will send a SIWE request to the wallet, and once the wallet responds with a signed message, use `onSIWEAuthenticationResponse` callback to check the result: ```kotlin theme={null} override fun onSIWEAuthenticationResponse(response: Modal.Model.SIWEAuthenticateResponse) { if (response is Modal.Model.SIWEAuthenticateResponse.Result) { // message and signature } else { //error } } ``` ### Link Mode The latest release of AppKit supports link mode, a low latency mechanism for transporting One-Click Auth requests and session requests over universal links, reducing the need for a WebSocket connection with the Relay. This significantly enhances the user experience when connecting native dApps to native wallets by reducing the latency associated with networking connections, especially when the user has an unstable internet connection.