Skip to content

Latest commit

 

History

History
304 lines (234 loc) · 11.2 KB

kip-0015.md

File metadata and controls

304 lines (234 loc) · 11.2 KB
KIP Title Author Status Type Category Created
0015
quicksign signing api v1
Jacquin Mininger @jmininger, Doug Beardsley @mightybyte
Draft
Standard
Interface
2022-09-15

Abstract

We propose an additional quicksign endpoint to the kadena-signing-api that allows a wallet to show the user multiple transactions at once for signature approval

Motivation

The current sign method used by signing-api-v1 contains a number of limitations:

  • Only a single txn can be signed at a time. This is painfully inefficient for workflows that require multi-step transactions or for transactions to occur across multiple chains
  • Only exec transactions can be sent and signed; cont transactions have no means of being signed in the current api
  • The response value returns a Command type which represents a fully-signed transaction. It does not allow for an intermediate state with a partially signed transaction. The latter is a useful workflow given that pact is multisig-native

In addition to the above, we propose an evolution of the SigData type used by the pact command line tool for representing partially-signed payloads (since pact’s Command type can only exist as a fully signed payload), that we call CommandSigData.

  • The SigData type includes a hash field https://github.com/kadena-io/pact/blob/957b8bd7644cebc60d043b33f0d7ffc53c65d783/src/Pact/Types/SigData.hs#L62-L66 . This data can also be derived from the cmd field of SigData. Imagine a scenario where a malicious dapp sends a SigData where the hash represents a malicious transaction, while the payload represents an unrelated transaction that the user is expecting. If the wallet does not explicitly check the hash, by recalculating, this becomes a security issue. To avoid this we force the wallet to compute the hash (by omitting it from the new CommandSigData structure)

Specification

Schema Sketch

Request

{
  "commandSigDatas": [ { "cmd": string, "sigs": [ { "pubKey":string, "sig": string|null }]}]
}

Response

{
  "responses": [{
    "commandSigData": { "cmd": string, "sigs": [ { "pubKey":string, "sig": string|null }]},
    "outcome": { "result": "success|failure|noSig", "hash|message"|null: string } }
  }]
}

or

{
  "error": {  "type": "reject|emptyList|other", "msg": string|null }
}

Quicksign Request

A quicksign request takes the form of a json-encoded payload matching the following schema:

{
  "commandSigDatas": [CommandSigData]
}

CommandSigData

    "{\"networkId\":\"testnet04\",\"payload\":{\"exec\":{\"data\":null,\"code\":\"(+ 1 2)\"}},\"signers\":[{\"pubKey\":\"ae18efd16cbd49e9a92552a2589ac01491b486fbcbb1e3f07980f945597e2033\",\"clist\":[{\"args\":[],\"name\":\"coin.GAS\"}]},{\"pubKey\":\"fa781bdd858cd2380b5e2b654e58035f7189a6e8158686a1bb7eabb585a56e7f\"}],\"meta\":{\"creationTime\":1663085494,\"ttl\":1800,\"gasLimit\":20,\"chainId\":\"0\",\"gasPrice\":1.0e-6,\"sender\":\"ae18efd16cbd49e9a92552a2589ac01491b486fbcbb1e3f07980f945597e2033\"},\"nonce\":\"2022-09-13 16:11:34.678231 UTC\"}"

The schema for a CommandSigData object is:

{
  "sigs": [Signer],
  "cmd": string
}

Note that this type is an evolved version of SigData which pact currently uses in its command-line tool: https://github.com/kadena-io/pact/blob/957b8bd7644cebc60d043b33f0d7ffc53c65d783/src/Pact/Types/SigData.hs#L62-L66

Signer

  • The pubKey field is a lowercase base-16 encoded public key
  • The sig element is either a lowercase base-16 encoded signature or a null value (representing a request for signature).
{
  "pubKey": string,
  "sig": string //optional; its omission represents a signature that has not yet been acquired
}

Quicksign Response

{
  "responses": [Response]
}

or

{
  "error": QuicksignError
}

Response

  • The commandSigDatas field contains the list of requests; some of which contain new signatures attached. Even in the case of an error, it is still useful to have the ordered list of CommandSigDatas in the response, given that some of them will contain new signatures.
{
  "commandSigData": CommandSigData,
  "outcome": Outcome
}

Outcome

The following are the 3 possible forms of the Outcome type

  • At least one signature was added
    • hash is an unpadded Base64URL of Blake2s-256 hash of the cmd field value of the successfully signed CommandSigData
{ "result": "success", "hash": string }
  • An error occurred parsing this particular CommandSigData
{ "result": "failure", "msg": string }
  • Special case for when 0 signatures have been added to the CommandSigData
{ "result": "noSig" }

QuicksignError

reject

For when the user chooses to reject the entire request and not provide any signatures

{
	"type": "reject"
}

emptyList

For when the commandSigDatas field in the request is an empty list

{
  "type": "emptyList",
}

other

A catch-all value for other error cases

{
  "type": "other",
  "msg": string
}

Requests

The signing api has traditionally been exposed via localhost port 9467. The quicksign handler will handle requests to the /quicksign route.

Examples

Example Requests

A single commandSigData to unlock a 3-person multisig, with one signature already provided

{
  "commandSigDatas":
   [
     { //Note that "sig" can either be explicitly null or omitted entirely under this spec
       "sigs":
          [ {
              "pubKey": "ae18efd16cbd49e9a92552a2589ac01491b486fbcbb1e3f07980f945597e2033"
            },
            {
              "pubKey": "fa781bdd858cd2380b5e2b654e58035f7189a6e8158686a1bb7eabb585a56e7f",
              "sig": null
            },
            {
              "pubKey": "d61c2b4d8151cd0a7599790a6a905a96dc1028b5e61181e08104e60f28ad8997",
              "sig": "a41b1c481414b0a0bac27c1f95f03d058cf1dc7ace571cf7b7a74be34e90116096dac8744adc0b94ffc16241cc87f513ea7f999802b3b6e58a1139c56881f800"
            },
          ]
        "cmd":"{\"networkId\":\"testnet04\",\"payload\":{\"exec\":{\"data\":null,\"code\":\"(enforce-keyset (read-keyset 'ks))\"}},\"signers\":[{\"pubKey\":\"ae18efd16cbd49e9a92552a2589ac01491b486fbcbb1e3f07980f945597e2033\"},{\"pubKey\":\"fa781bdd858cd2380b5e2b654e58035f7189a6e8158686a1bb7eabb585a56e7f\"},{\"pubKey\":\"d61c2b4d8151cd0a7599790a6a905a96dc1028b5e61181e08104e60f28ad8997\"}],\"meta\":{\"creationTime\":1664393516,\"ttl\":1800,\"gasLimit\":100,\"chainId\":\"0\",\"gasPrice\":1.0e-6,\"sender\":\"k:ae18efd16cbd49e9a92552a2589ac01491b486fbcbb1e3f07980f945597e2033\"},\"nonce\":\"2022-09-28 19:31:56.965212 UTC\"}"
      }
   ]
}

Example Responses

A single signature has been added for “d61c2b4d8151cd0a7599790a6a905a96dc1028b5e61181e08104e60f28ad8997”

{
  "responses": [{
      "outcome":
        {
          "result": "success",
          "hash": "RKABKR6zLC44vunHHzycRE0JXqbwpvQXztRnzbUKKls"
        },
      "commandSigData":
        {
          "sigs":
            [
              {
                "pubKey": "ae18efd16cbd49e9a92552a2589ac01491b486fbcbb1e3f07980f945597e2033",
                "sig": "10d3189ee55a34d0f15509c889d1a313c292c1b419244ae2938dd745ab887a45e34183e577ed0ab61fd0c76e8e957922fc467a21ab6d074aa3aa3e742a10390d"
              },
              {
                "pubKey": "fa781bdd858cd2380b5e2b654e58035f7189a6e8158686a1bb7eabb585a56e7f",
              },
              {
                "pubKey": "d61c2b4d8151cd0a7599790a6a905a96dc1028b5e61181e08104e60f28ad8997",
                "sig": "a41b1c481414b0a0bac27c1f95f03d058cf1dc7ace571cf7b7a74be34e90116096dac8744adc0b94ffc16241cc87f513ea7f999802b3b6e58a1139c56881f800"
              },
            ]
          "cmd":"{\"networkId\":\"testnet04\",\"payload\":{\"exec\":{\"data\":null,\"code\":\"(enforce-keyset (read-keyset 'ks))\"}},\"signers\":[{\"pubKey\":\"ae18efd16cbd49e9a92552a2589ac01491b486fbcbb1e3f07980f945597e2033\"},{\"pubKey\":\"fa781bdd858cd2380b5e2b654e58035f7189a6e8158686a1bb7eabb585a56e7f\"},{\"pubKey\":\"d61c2b4d8151cd0a7599790a6a905a96dc1028b5e61181e08104e60f28ad8997\"}],\"meta\":{\"creationTime\":1664393516,\"ttl\":1800,\"gasLimit\":100,\"chainId\":\"0\",\"gasPrice\":1.0e-6,\"sender\":\"k:ae18efd16cbd49e9a92552a2589ac01491b486fbcbb1e3f07980f945597e2033\"},\"nonce\":\"2022-09-28 19:31:56.965212 UTC\"}"
        }
   }]
}

Alternatively, here is a response where no signature was added to the single commandSigData

{
  "responses": [{
      "outcome":
        {
          "result": "noSig",
        },
      "commandSigData":
        {
          "sigs":
            [ {
                "pubKey": "ae18efd16cbd49e9a92552a2589ac01491b486fbcbb1e3f07980f945597e2033"
              },
              {
                "pubKey": "fa781bdd858cd2380b5e2b654e58035f7189a6e8158686a1bb7eabb585a56e7f",
                "sig": null
              },
              {
                "pubKey": "d61c2b4d8151cd0a7599790a6a905a96dc1028b5e61181e08104e60f28ad8997",
                "sig": "a41b1c481414b0a0bac27c1f95f03d058cf1dc7ace571cf7b7a74be34e90116096dac8744adc0b94ffc16241cc87f513ea7f999802b3b6e58a1139c56881f800"
              },
            ]
          "cmd":"{\"networkId\":\"testnet04\",\"payload\":{\"exec\":{\"data\":null,\"code\":\"(enforce-keyset (read-keyset 'ks))\"}},\"signers\":[{\"pubKey\":\"ae18efd16cbd49e9a92552a2589ac01491b486fbcbb1e3f07980f945597e2033\"},{\"pubKey\":\"fa781bdd858cd2380b5e2b654e58035f7189a6e8158686a1bb7eabb585a56e7f\"},{\"pubKey\":\"d61c2b4d8151cd0a7599790a6a905a96dc1028b5e61181e08104e60f28ad8997\"}],\"meta\":{\"creationTime\":1664393516,\"ttl\":1800,\"gasLimit\":100,\"chainId\":\"0\",\"gasPrice\":1.0e-6,\"sender\":\"k:ae18efd16cbd49e9a92552a2589ac01491b486fbcbb1e3f07980f945597e2033\"},\"nonce\":\"2022-09-28 19:31:56.965212 UTC\"}"
        }
   }]
}

Alternatively, the user may indicate to the wallet that they do not approve of the signature:

{
  "error":
    {
      "type": "reject"
    }
}

Backwards Compatibility

  • This is an addition to the signing-api and as such, the sign method is still supported.

References

Potential next steps

  • Quicksign implementation on-top of the Wallet-Connect v2 sign protocol
  • Kadena.js implementation
  • A quicksign-ui specification for detailing exactly how a wallet should display the many requests in a digestible manner for the user
  • A “dynamic” version that allows a user to select gas prices for each transaction. Alternatively, it will be up to the dapp to do this, and we need to provide an easy/pluggable framework that makes it easy for dapps to control this interaction with the user.