Skip to content

Latest commit

 

History

History
486 lines (377 loc) · 18.1 KB

kip-0017.md

File metadata and controls

486 lines (377 loc) · 18.1 KB
KIP Title Author Status Type Category Created
0017
walletconnect-v2-sign implementation spec
Jacquin Mininger @jmininger, Doug Beardsley @mightybyte, Linda Ortega @lindaortega, Jermaine Jong @jermaine150, Albert Groothedde @alber70g
Final
Standard
Interface
2022-11-15

Motivation

This KIP proposes that the Kadena ecosystem implement the WalletConnect v2 Sign API. This API allows for establishing a secure channel for communicating between dApps and wallets in a platform-agnostic manner.

This is beneficial to Kadena for the following reasons:

  • The Kadena ecosystem doesn't have a standard protocol for wallets and dApps to communicate with each other.
  • The WalletConnect (WC) protocol is tried and tested across all devices and it removes the burden of having to maintain a Kadena-specific implementation.
  • Wallets and dApps that are already using the WC protocol will have an easier time integrating with the Kadena ecosystem.
  • Kadena's previous Signing API required the wallet to be able to run an http server. This is not feasible for some browser-based and mobile wallets.

Kadena's WalletConnect Specification

This specification is built on top of the WalletConnect Specification.

Pairing with WalletConnect

The dApp initiates a pairing with a wallet using WalletConnect as a tunnel. This is done by sending a so called Proposal. This proposal contains the chains, methods, and events the initiator wants to utilize. The wallet responds with the Settlement. This contains information on which of the requested items it supports.

Example Pairing Proposal Request and Settlement Response

// Proposal Request
{
  // ... other properties from the WalletConnect Proposal Request
  "requiredNamespaces": {
    "kadena": {
      "chains": ["kadena:mainnet01", "kadena:testnet04", "kadena:development"],
      "methods": [
        "kadena_getAccounts_v1",
        "kadena_sign_v1",
        "kadena_quicksign_v1"
      ],
      "events": []
    }
  }
}
// Settlement Response
{
  // ... other properties from the WalletConnect Settlement Response
  "namespaces": {
    "kadena": {
      "accounts": [
        "kadena:mainnet01:38298612cc2d5e841a232bd08413aa5304f9ef3251575ee182345abc3807dd89",
        "kadena:testnet04:38298612cc2d5e841a232bd08413aa5304f9ef3251575ee182345abc3807dd89",
        "kadena:development:22ddc64851718e9d41d98b0f33d5e328ae5bbbbd97aed9885adac0f2d070ff9c"
      ],
      "methods": [
        "kadena_getAccounts_v1",
        "kadena_sign_v1",
        "kadena_quicksign_v1"
      ],
      "events": []
    }
  }
}

There are also optionalNamespaces that may be included, but are not required in the settlement from the wallet.
The structure for these is the same as the structure for the requiredNamespaces.

The dApp uses the requiredNamespaces and optionalNamespaces fields to indicate to the wallet what chains, events, and methods it would like permission to.

The main difference being that the wallet must grant access to all the chains, methods, and events specified in the requiredNamespaces in order to establish an active session.

Also, the WalletConnect library enforces that a Session Response's accounts field must contain at least one account per chain specified in requiredNamespaces.

But it is up to the wallet to satisfy all, none, or some of the chains, methods, and events specified in the optionalNamespaces field.

WalletConnect Proposal Request

WalletConnect dictates a requiredNamespaces property that contains:

  1. requiredNamespaces: Object
    1.1. chains: Array<string> - an array of Chain IDs requested.
    1.2. methods: Array<string> - an array of Methods requested.
    1.3. events: Array<string> - an array of Events requested.

WalletConnect Settlement Response

The response for the Proposal contains a namespaces object with the following properties:

  1. namespaces: Object
    1.1. accounts: Array<string> - an array of Accounts availble for signing.
    1.2. methods: Array<string> - an array of Methods available.
    1.3. events: Array<string> - an array of Events available.

WalletConnect Chain IDs

Chain IDs are WalletConnect’s way of identifying specific blockchains within an ecosystem.

They are defined by the CAIP-2 standard and are formatted as:

<namespace> + ":" + <reference>
  • <namespace>: string - always defined as "kadena".
  • <reference>: string - a unique network ID within the blockchain ecosystem (e.g. testnet04, mainnet01).

These are valid Chain IDs:

  • kadena:mainnet01 - Kadena mainnet
  • kadena:testnet04 - Current Kadena testnet
  • kadena:development - Kadena devnet

NB: Chain IDs, as defined here, are semantically specific to WalletConnect and are not equivalent to a Kadena "Chain ID" (e.g. chain 1). They are more closely related to Kadena's networkId field. We are displaying Kadena chainId information in the kadena_getAccounts_v1 method.

WalletConnect Accounts

Accounts are WalletConnect's way of specifying control over signing privileges.

They are defined by the CAIP-10 standard, and are formatted as:

<chain_id> + ":" + <account_address>
  • <chain_id>: string - the WalletConnect Chain ID.
  • <account_address>: string - the public key available for signing by the wallet.
// WalletConnect Account Example

"kadena:mainnet01:38298612cc2d5e841a232bd08413aa5304f9ef3251575ee182345abc3807dd89"

NB: accounts is semantically specific to WalletConnect. This does not represent an account in a Kadena fungible contract (e.g. coin). Read the motivation for this in Accounts vs. Public Keys.

After the initial pairing with the wallet via WalletConnect, the Kadena accounts relevant for each public key can be requested by calling getAccounts.

The use of account names that can be derived from the public key (i.e. k:-accounts that are defined as k:<public_key>), is highly discouraged as implementing this will limit the end-users flexibility in which account to use, thus making dApps less generic.

WalletConnect Methods

WalletConnect methods are ways for dApps to interact with a wallet using predefined method identifiers and an optional payload.

The methods available for Kadena are:

Any additional Kadena method names will be formatted as:

kadena_<methodName>_v<methodVersionNumber>
  • <methodName>: string - name of the method in camelCase format.
  • <methodVersionNumber>: integer - the version number of the method. Methods are versioned to allow upgradeability

kadena_getAccounts_v1

This method returns the Kadena account names associated with a given WalletConnect account and contract(s) on the Kadena blockchain.

Example kadena_getAccounts_v1 Request and Response

// kadena_getAccounts_v1 Method Request
{
  "id": 1,
  "jsonrpc": "2.0",
  "method": "kadena_getAccounts_v1",
  "params": {
    "accounts": [
      {
        "account": "kadena:mainnet01:38298612cc2d5e841a232bd08413aa5304f9ef3251575ee182345abc3807dd89",
        "contracts": ["coin"] // optional, when omitted the wallet returns all known fungible accounts
      }
    ]
  }
}
// kadena_getAccounts_v1 Method Response
{
  "id": 1,
  "jsonrpc": "2.0",
  "result": {
    "accounts": [
      {
        "account": "kadena:mainnet01:38298612cc2d5e841a232bd08413aa5304f9ef3251575ee182345abc3807dd89",
        "publicKey": "38298612cc2d5e841a232bd08413aa5304f9ef3251575ee182345abc3807dd89",
        "kadenaAccounts": [
          {
            "name": "w:aoriestnaoirsetnaorisetn",
            "contract": "coin",
            "chains": ["0", "1"]
          },
          {
            "name": "bill",
            "contract": "coin",
            "chains": ["2", "4"]
          },
          {
            "name": "k:38298612cc2d5e841a232bd08413aa5304f9ef3251575ee182345abc3807dd89",
            "contract": "coin",
            "chains": [
              "0",
              "1",
              "2",
              "3",
              "4",
              "5",
              "6",
              "7",
              "8",
              "9",
              "10",
              "11",
              "12",
              "13",
              "14",
              "15",
              "16",
              "17",
              "18",
              "19"
            ]
          }
        ]
      }
    ]
  }
}

kadena_getAccounts_v1 Request

This method expects a method field that is set to "kadena_getAccounts_v1".

This method also expects a params object with the following properties:

  1. params: Object
    1.1. accounts: Array<Object>
    __ 1.1.1 account: string - a WalletConnect Account for which the Kadena account names are requested.
    __ 1.1.2 contracts: Array<string> (optional) - array of contracts for which the Kadena account name is requested. Returns all known Kadena accounts when omitted.

NB: We choose to not add chains to the getAccounts_v1 request since it would add complexity to the interface. The dApp can filter the necessary chains.

kadena_getAccounts_v1 Response

The method response expects a result object with the following properties:

  1. result: Object
    1.1. accounts: Array<Object>
    __ 1.1.1 account: string - the requested WalletConnect Account.
    __ 1.1.2 publicKey: string - the requested public key, which was extracted from the WalletConnect account.
    __ 1.1.3 kadenaAccounts: Array<Object>
    ____ 1.1.3.1 name: string - the account name, as stored in the blockchain, for the specified contract.
    ____ 1.1.3.2 contract: string - the contract on which this account name is present.
    ____ 1.1.3.3 chains: Array<string> - the chains on which this account name is present.

NB: The accounts that are returned are the ones that are available in the scope of the wallet (i.e. only the accounts the wallet knows about).

NB: The same Kadena account name can be used in different contracts (e.g. coin, my-fungible). They require different entries since the chains on which the accounts are present can differ.

kadena_quicksign_v1

QuickSign is part of the Kadena Signing API and was defined in kip-0015 (QuickSign Signing API v1). This method allows the wallet to show the user multiple transactions that need signature approval.

Example kadena_quicksign_v1 Request and Response

// kadena_quicksign_v1 Method Request
{
  "id": 1,
  "jsonrpc": "2.0",
  "method": "kadena_quicksign_v1",
  "params": {
    "commandSigDatas": [CommandSigData] // type defined in KIP-15
  }
}
// Successful kadena_quicksign_v1 Response
{
    "id": 1,
    "jsonrpc": "2.0",
    "result":  {
      "responses": [Response] // type defined in KIP-15
    }
}

or

// Failed kadena_quicksign_v1 Response
{
    "id": 1,
    "jsonrpc": "2.0",
    "result":  {
      "error": QuicksignError // type defined in KIP-15
    }
}

kadena_quicksign_v1 Request

This method expects a method field that is set to "kadena_quicksign_v1".

This method also expects a params object with the following properties:

  1. params: Object
    1.1. commandSigDatas: Array<Object> - A list of CommandSigData to sign.

kadena_quicksign_v1 Response

If signing was successful, then the method response expects a result object with the following properties:

  1. result: Object
    1.1. responses: Array<Object> - A list of Response containing the signed transactions.

If signing was NOT successful, then the result object will contain the following properties:

  1. result: Object
    1.1. error: Object - A list of QuicksignError.

kadena_sign_v1

Sign is part of the Kadena Signing API. This method allows the wallet to show the user a single transaction that needs signature approval.

Example kadena_sign_v1 Request and Response

// kadena_sign_v1 Method Request
{
  "id": 1,
  "jsonrpc": "2.0",
  "method": "kadena_sign_v1",
  "params": {
    SigningRequest
  }
}
// kadena_sign_v1 Response
{
    "id": 1,
    "jsonrpc": "2.0",
    "result":  {
      SigningResponse
    }
}

kadena_sign_v1 Request

This method expects a method field that is set to "kadena_sign_v1".

This method also expects a params object with the following properties:

  1. params: Object - A SigningRequest containing information the wallet needs to create and sign the transaction.

kadena_sign_v1 Response

The method response expects a result object with the following properties:

  1. result: Object - A SigningResponse that contains a signed command ready to be submitted to the blockchain.

WalletConnect Events

At the moment we see no need to standardize any events and believe that most use cases can be handled at the Kadena protocol level that sits atop Wallet Connect.

This is subject to change in the future as we understand the workflows more through extended use of the protocol.

However, any future Kadena event names will be formatted as:

kadena_<eventName>_v<eventVersionNumber>
  • <eventName>: string - name of the event in camelCase format.
  • <eventVersionNumber>: integer - the version number of the event to allow for future upgradeability

Rationale for the spec

Accounts vs Public Keys

Several options were considered when discussing what information to include in the accounts section of the initial pairing response.

However, the following reasons forced us to only include the public keys (prefixed with Kadena's WalletConnect Chain ID):

  1. Kadena fungible contracts (specifically the coin contract) have a maximum account name length of 256, but the CAIP-10 standard limits WalletConnect account names to a maximum of 128 characters.
  2. We considered only supporting k: accounts, as they're built from k:publicKey, but we want this response to be generic for all accounts that could exist on the Kadena blockchain.

Therefore, we strongly advise builders to integrate the kadena_getAccounts_v1 method into the pairing process with the wallet.

This will allow them to support multi-sig accounts (e.g. w:-accounts) and other means of signing transactions.

We do NOT recommend extracting the publicKey from the WalletConnect account and just adding a k: in front of it.

SLIP-0044

While not required in the namespace proposal process, a network's SLIP-0044 value is used throughout the WalletConnect demo code.

Kadena's coin type is 626 as documented in (SLIP-0044)[https://github.com/satoshilabs/slips/blob/master/slip-0044.md].

Backwards Compatibility

  • The localhost:9467 web-server will be phased out.
  • The /sign and /quicksign endpoints will have their counterparts in the WalletConnect Methods kadena_sign_v1 and kadena_quicksign_v1.
  • For wallets that have the local web-server integrated, we suggest they keep this available behind a toggle while they transition to WalletConnect.