ARCs:specs:arc-0025.md•11.4 kB
---
arc: 25
title: Algorand WalletConnect v1 API
description: API for communication between Dapps and wallets using WalletConnect
author: JasonPaulos (@jasonpaulos)
discussions-to: https://github.com/algorandfoundation/ARCs/issues/104
status: Final
type: Standards Track
category: Interface
sub-category: Wallet
created: 2022-05-12
---
# Algorand WalletConnect v1 API
This document specifies a standard API for communication between Algorand decentralized applications and wallets using the WalletConnect v1 protocol.
## Abstract
WalletConnect https://walletconnect.com/ is an open protocol to communicate securely between mobile wallets and decentralized applications (dApps) using QR code scanning (desktop) or deep linking (mobile). It’s main use case allows users to sign transactions on web apps using a mobile wallet.
This document aims to establish a standard API for using the WalletConnect v1 protocol on Algorand, leveraging the existing transaction signing APIs defined in [ARC-1](./arc-0001.md).
## Specification
The key words "**MUST**", "**MUST NOT**", "**REQUIRED**", "**SHALL**", "**SHALL NOT**", "**SHOULD**", "**SHOULD NOT**", "**RECOMMENDED**", "**MAY**", and "**OPTIONAL**" in this document are to be interpreted as described in <a href="https://www.ietf.org/rfc/rfc2119.txt">RFC-2119</a>.
> Comments like this are non-normative.
It is strongly recommended to read and understand the entirety of [ARC-1](./arc-0001.md) before reading this ARC.
### Overview
This overview section is non-normative. It offers a brief overview of the WalletConnect v1 lifecycle. A more in-depth description can be found in the WalletConnect v1 documentation https://docs.walletconnect.com/tech-spec .
In order for a dApp and wallet to communicate using WalletConnect, a WalletConnect session must be established between them. The dApp is responsible for initiating this session and producing a session URI, which it will communicate to the wallet, typically in the form of a QR code or a deep link. This processed is described in the [Session Creation](#session-creation) section.
Once a session is established between a dApp and a wallet, the dApp is able to send requests to the wallet. The wallet is responsible for listening for requests, performing the appropriate actions to fulfill requests, and sending responses back to the dApp with the results of requests. This process is described in the [Message Schema](#message-schema) section.
### Session Creation
The dApp is responsible for initializing a WalletConnect session and producing a WalletConnect URI that communicates the necessary session information to the wallet. This process is as described in the WalletConnect documentation https://docs.walletconnect.com/tech-spec#requesting-connection, with one addition. In order for wallets to be able to easily and immediately recognize an Algorand WalletConnect session, dApps **SHOULD** add an additional URI query parameter to the WalletConnect URI. If present, the name of this parameter **MUST** be `algorand` and its value **MUST** be `true`. This query parameter can appear in any order relative to the other query parameters in the URI.
> For example, here is a standard WalletConnect URI:
> ```
> wc:4015f93f-b88d-48fc-8bfe-8b063cc325b6@1?bridge=https%3A%2F%2F9.bridge.walletconnect.org&key=b0576e0880e17f8400bfff92d4caaf2158cccc0f493dcf455ba76d448c9b5655
> ```
> And here is that same URI with the Algorand-specific query parameter:
> ```
> wc:4015f93f-b88d-48fc-8bfe-8b063cc325b6@1?bridge=https%3A%2F%2F9.bridge.walletconnect.org&key=b0576e0880e17f8400bfff92d4caaf2158cccc0f493dcf455ba76d448c9b5655&algorand=true
> ```
It is **RECOMMENDED** that dApps include this query parameter, but it is not **REQUIRED**. Wallets **MAY** reject sessions if the session URI does not contain this query parameter.
#### Chain IDs
WalletConnect v1 sessions are associated with a numeric chain ID. Since Algorand chains do not have numeric identifiers (instead, the genesis hash or ID is used for this purpose), this document defines the following chain IDs for the Algorand ecosystem:
* MainNet (genesis hash `wGHE2Pwdvd7S12BL5FaOP20EGYesN73ktiC1qzkkit8=`): 416001
* TestNet (genesis hash `SGO1GKSzyE7IEPItTxCByw9x8FmnrCDexi9/cOUJOiI=`): 416002
* BetaNet (genesis hash `mFgazF+2uRS1tMiL9dsj01hJGySEmPN28B/TjjvpVW0=`): 416003
At the time of writing, these chain IDs do not conflict with any known chain that also uses WalletConnect. In the unfortunate event that this were to happen, the `algorand` query parameter discussed above would be used to differentiate Algorand chains from others.
Future Algorand chains, if introduced, **MUST** be assigned new chain IDs.
Wallets and dApps **MAY** support all of the above chain IDs or only a subset of them. If a chain ID is presented to a wallet or dApp that does not support that chain ID, they **MUST** terminate the session.
For compatibility with WalletConnect usage prior to this ARC, the following catch-all chain ID is also defined:
* All Algorand Chains (legacy value): 4160
Wallets and dApps **SHOULD** support this chain ID as well for backwards compatibility. Unfortunately this ID alone is not enough to identify which Algorand chain is being used, so extra fields in message requests (i.e. the genesis hash field in a transaction to sign) **SHOULD** be consulted as well to determine this.
### Message Schema
Note: interfaces are defined in TypeScript. These interfaces are designed to be serializable to and from valid JSON objects.
The WalletConnect message schema is a set of JSON-RPC 2.0 https://www.jsonrpc.org/specification requests and responses. Decentralized applications will send requests to the wallets and will receive responses as JSON-RPC messages. All requests **MUST** adhere to the following structure:
```typescript
interface JsonRpcRequest {
/**
* An identifier established by the Client. Numbers SHOULD NOT contain fractional parts.
*/
id: number;
/**
* A String specifying the version of the JSON-RPC protocol. MUST be exactly "2.0".
*/
jsonrpc: "2.0";
/**
* A String containing the name of the RPC method to be invoked.
*/
method: string;
/**
* A Structured value that holds the parameter values to be used during the invocation of the method.
*/
params: any[];
}
```
The Algorand WalletConnect schema consists of a single RPC method, `algo_signTxn`, as described in the following section.
All responses, whether successful or unsuccessful, **MUST** adhere to the following structure:
```typescript
interface JsonRpcResponse {
/**
* This member is REQUIRED.
* It MUST be the same as the value of the id member in the Request Object.
* If there was an error in detecting the id in the Request object (e.g. Parse error/Invalid Request), it MUST be Null.
*/
id: number;
/**
* A String specifying the version of the JSON-RPC protocol. MUST be exactly "2.0".
*/
jsonrpc: "2.0";
/**
* This member is REQUIRED on success.
* This member MUST NOT exist if there was an error invoking the method.
* The value of this member is determined by the method invoked on the Server.
*/
result?: any;
/**
* This member is REQUIRED on error.
* This member MUST NOT exist if the requested method was invoked successfully.
*/
error?: JsonRpcError;
}
interface JsonRpcError {
/**
* A Number that indicates the error type that occurred.
* This MUST be an integer.
*/
code: number;
/**
* A String providing a short description of the error.
* The message SHOULD be limited to a concise single sentence.
*/
message: string;
/**
* A Primitive or Structured value that contains additional information about the error.
* This may be omitted.
* The value of this member is defined by the Server (e.g. detailed error information, nested errors etc.).
*/
data?: any;
}
```
#### `algo_signTxn`
This request is used to ask a wallet to sign one or more transactions in one or more atomic groups.
##### Request
This request **MUST** adhere to the following structure:
```typescript
interface AlgoSignTxnRequest {
/**
* As described in JsonRpcRequest.
*/
id: number;
/**
* As described in JsonRpcRequest.
*/
jsonrpc: "2.0";
/**
* The method to invoke, MUST be "algo_signTxn".
*/
method: "algo_signTxn";
/**
* Parameters for the transaction signing request.
*/
params: SignTxnParams;
}
/**
* The first element is an array of `WalletTransaction` objects which contain the transaction(s) to be signed.
* If transactions from an atomic transaction group are being signed, then all transactions in the group (even the ones not being signed by the wallet) MUST appear in this array.
*
* The second element, if present, contains addition options specified with the `SignTxnOpts` structure.
*/
type SignTxnParams = [WalletTransaction[], SignTxnOpts?];
```
> `SignTxnParams` is a tuple with an optional element https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-0.html#optional-elements-in-tuple-types, meaning its length can be 1 or 2.
The [`WalletTransaction`](./arc-0001.md#interface-wallettransaction) and [`SignTxnOpts`](./arc-0001.md#interface-signtxnsopts) types are defined in [ARC-1](./arc-0001.md).
All specifications, restrictions, and guidelines declared in ARC-1 for these types apply to their usage here as well. Additionally, all security requirements and restrictions for processing transaction signing requests from ARC-1 apply to this request as well.
> For more information, see [ARC-1 - Syntax and Interfaces](./arc-0001.md#syntax-and-interfaces) and [ARC-1 - Semantic and Security Requirements](./arc-0001.md#semantic-and-security-requirements).
##### Response
To respond to a request, the wallet **MUST** send back the following response object:
```typescript
interface AlgoSignTxnResponse {
/**
* As described in JsonRpcResponse.
*/
id: number;
/**
* As described in JsonRpcResponse.
*/
jsonrpc: "2.0";
/**
* An array containing signed transactions at specific indexes.
*/
result?: Array<SignedTxnStr | null>;
/**
* As described in JsonRpcResponse.
*/
error?: JsonRpcError;
}
```
[`SignedTxnStr`](./arc-0001.md#interface-signedtxnstr) type is defined in [ARC-1](./arc-0001.md).
In this response, `result` **MUST** be an array with the same length as the number of `WalletTransaction`s in the request (i.e. `<AlgoSignTxnRequest instance>.params[0].length`). For every integer `i` such that `0 <= i < result.length`:
* If the transaction at index `i` in the group should be signed by the wallet (i.e. `<AlgoSignTxnRequest instance>.params[0][i].signers` is not an empty array): `result[i]` **MUST** be a base64-encoded string containing the msgpack-encoded signed transaction `params[0][i].txn`.
* Otherwise: `result[i]` **MUST** be `null`, since the wallet was not requested to sign this transaction.
If the wallet does not approve signing every transaction whose signature is being requested, the request **MUST** fail.
All request failures **MUST** use the error codes defined in [ARC-1 - Error Standards](./arc-0001.md#error-standards).
## Rationale
## Security Considerations
None.
## Copyright
Copyright and related rights waived via <a href="https://creativecommons.org/publicdomain/zero/1.0/">CCO</a>.