From e5871b928fb0a4caf65153b552187c5c103e24d7 Mon Sep 17 00:00:00 2001 From: chris-j-h <39617426+chris-j-h@users.noreply.github.com> Date: Tue, 7 Jul 2020 10:12:38 +0100 Subject: [PATCH] cmd/clef: Update README with external v6.0.0 & internal v7.0.1 APIs (#21298) Changes include: * Updates response docs for `account_new`, `account_list`, `account_signTransaction` * Removes `account_import`, `account_export` docs * Adds `account_version` docs * Updates request docs for `ui_approveListing`, `ui_approveSignData`, `ui_showInfo`, `ui_showError`, `ui_onApprovedTx` * Adds `ui_approveNewAccount`, `ui_onInputRequired` docs --- cmd/clef/README.md | 274 +++++++++++++++++++++------------------------ 1 file changed, 129 insertions(+), 145 deletions(-) diff --git a/cmd/clef/README.md b/cmd/clef/README.md index afa996c8d..9758b9436 100644 --- a/cmd/clef/README.md +++ b/cmd/clef/README.md @@ -146,13 +146,11 @@ See the [external API changelog](extapi_changelog.md) for information about chan All hex encoded values must be prefixed with `0x`. -## Methods - ### account_new #### Create new password protected account -The signer will generate a new private key, encrypts it according to [web3 keystore spec](https://github.com/ethereum/wiki/wiki/Web3-Secret-Storage-Definition) and stores it in the keystore directory. +The signer will generate a new private key, encrypt it according to [web3 keystore spec](https://github.com/ethereum/wiki/wiki/Web3-Secret-Storage-Definition) and store it in the keystore directory. The client is responsible for creating a backup of the keystore. If the keystore is lost there is no method of retrieving lost accounts. #### Arguments @@ -161,7 +159,6 @@ None #### Result - address [string]: account address that is derived from the generated key - - url [string]: location of the keyfile #### Sample call ```json @@ -173,14 +170,11 @@ None } ``` Response -``` +```json { - "id": 0, - "jsonrpc": "2.0", - "result": { - "address": "0xbea9183f8f4f03d427f6bcea17388bdff1cab133", - "url": "keystore:///my/keystore/UTC--2017-08-24T08-40-15.419655028Z--bea9183f8f4f03d427f6bcea17388bdff1cab133" - } + "id": 0, + "jsonrpc": "2.0", + "result": "0xbea9183f8f4f03d427f6bcea17388bdff1cab133" } ``` @@ -196,8 +190,6 @@ None #### Result - array with account records: - account.address [string]: account address that is derived from the generated key - - account.type [string]: type of the - - account.url [string]: location of the account #### Sample call ```json @@ -208,21 +200,13 @@ None } ``` Response -``` +```json { "id": 1, "jsonrpc": "2.0", "result": [ - { - "address": "0xafb2f771f58513609765698f65d3f2f0224a956f", - "type": "account", - "url": "keystore:///tmp/keystore/UTC--2017-08-24T07-26-47.162109726Z--afb2f771f58513609765698f65d3f2f0224a956f" - }, - { - "address": "0xbea9183f8f4f03d427f6bcea17388bdff1cab133", - "type": "account", - "url": "keystore:///tmp/keystore/UTC--2017-08-24T08-40-15.419655028Z--bea9183f8f4f03d427f6bcea17388bdff1cab133" - } + "0xafb2f771f58513609765698f65d3f2f0224a956f", + "0xbea9183f8f4f03d427f6bcea17388bdff1cab133" ] } ``` @@ -230,10 +214,10 @@ Response ### account_signTransaction #### Sign transactions - Signs a transactions and responds with the signed transaction in RLP encoded form. + Signs a transaction and responds with the signed transaction in RLP-encoded and JSON forms. #### Arguments - 2. transaction object: + 1. transaction object: - `from` [address]: account to send the transaction from - `to` [address]: receiver account. If omitted or `0x`, will cause contract creation. - `gas` [number]: maximum amount of gas to burn @@ -241,12 +225,13 @@ Response - `value` [number:optional]: amount of Wei to send with the transaction - `data` [data:optional]: input data - `nonce` [number]: account nonce - 3. method signature [string:optional] + 1. method signature [string:optional] - The method signature, if present, is to aid decoding the calldata. Should consist of `methodname(paramtype,...)`, e.g. `transfer(uint256,address)`. The signer may use this data to parse the supplied calldata, and show the user. The data, however, is considered totally untrusted, and reliability is not expected. #### Result - - signed transaction in RLP encoded form [data] + - raw [data]: signed transaction in RLP encoded form + - tx [json]: signed transaction in JSON form #### Sample call ```json @@ -271,11 +256,22 @@ Response ```json { - "id": 2, "jsonrpc": "2.0", - "error": { - "code": -32000, - "message": "Request denied" + "id": 2, + "result": { + "raw": "0xf88380018203339407a565b7ed7d7a678680a4c162885bedbb695fe080a44401a6e4000000000000000000000000000000000000000000000000000000000000001226a0223a7c9bcf5531c99be5ea7082183816eb20cfe0bbc322e97cc5c7f71ab8b20ea02aadee6b34b45bb15bc42d9c09de4a6754e7000908da72d48cc7704971491663", + "tx": { + "nonce": "0x0", + "gasPrice": "0x1234", + "gas": "0x55555", + "to": "0x07a565b7ed7d7a678680a4c162885bedbb695fe0", + "value": "0x1234", + "input": "0xabcd", + "v": "0x26", + "r": "0x223a7c9bcf5531c99be5ea7082183816eb20cfe0bbc322e97cc5c7f71ab8b20e", + "s": "0x2aadee6b34b45bb15bc42d9c09de4a6754e7000908da72d48cc7704971491663", + "hash": "0xeba2df809e7a612a0a0d444ccfa5c839624bdc00dd29e3340d46df3870f8a30e" + } } } ``` @@ -327,7 +323,7 @@ Response Bash example: ```bash -#curl -H "Content-Type: application/json" -X POST --data '{"jsonrpc":"2.0","method":"account_signTransaction","params":[{"from":"0x694267f14675d7e1b9494fd8d72fefe1755710fa","gas":"0x333","gasPrice":"0x1","nonce":"0x0","to":"0x07a565b7ed7d7a678680a4c162885bedbb695fe0", "value":"0x0", "data":"0x4401a6e40000000000000000000000000000000000000000000000000000000000000012"},"safeSend(address)"],"id":67}' http://localhost:8550/ +> curl -H "Content-Type: application/json" -X POST --data '{"jsonrpc":"2.0","method":"account_signTransaction","params":[{"from":"0x694267f14675d7e1b9494fd8d72fefe1755710fa","gas":"0x333","gasPrice":"0x1","nonce":"0x0","to":"0x07a565b7ed7d7a678680a4c162885bedbb695fe0", "value":"0x0", "data":"0x4401a6e40000000000000000000000000000000000000000000000000000000000000012"},"safeSend(address)"],"id":67}' http://localhost:8550/ {"jsonrpc":"2.0","id":67,"result":{"raw":"0xf88380018203339407a565b7ed7d7a678680a4c162885bedbb695fe080a44401a6e4000000000000000000000000000000000000000000000000000000000000001226a0223a7c9bcf5531c99be5ea7082183816eb20cfe0bbc322e97cc5c7f71ab8b20ea02aadee6b34b45bb15bc42d9c09de4a6754e7000908da72d48cc7704971491663","tx":{"nonce":"0x0","gasPrice":"0x1","gas":"0x333","to":"0x07a565b7ed7d7a678680a4c162885bedbb695fe0","value":"0x0","input":"0x4401a6e40000000000000000000000000000000000000000000000000000000000000012","v":"0x26","r":"0x223a7c9bcf5531c99be5ea7082183816eb20cfe0bbc322e97cc5c7f71ab8b20e","s":"0x2aadee6b34b45bb15bc42d9c09de4a6754e7000908da72d48cc7704971491663","hash":"0xeba2df809e7a612a0a0d444ccfa5c839624bdc00dd29e3340d46df3870f8a30e"}}} ``` @@ -470,7 +466,7 @@ Response ### account_ecRecover -#### Sign data +#### Recover the signing address Derive the address from the account that was used to sign data with content type `text/plain` and the signature. @@ -488,7 +484,6 @@ Derive the address from the account that was used to sign data with content type "jsonrpc": "2.0", "method": "account_ecRecover", "params": [ - "data/plain", "0xaabbccdd", "0x5b6693f153b48ec1c706ba4169960386dbaa6903e249cc79a8e6ddc434451d417e1e57327872c7f538beeb323c300afa9999a3d4a5de6caf3be0d5ef832b67ef1c" ] @@ -504,117 +499,36 @@ Response } ``` -### account_import +### account_version -#### Import account - Import a private key into the keystore. The imported key is expected to be encrypted according to the web3 keystore - format. +#### Get external API version + +Get the version of the external API used by Clef. #### Arguments - - account [object]: key in [web3 keystore format](https://github.com/ethereum/wiki/wiki/Web3-Secret-Storage-Definition) (retrieved with account_export) + +None #### Result - - imported key [object]: - - key.address [address]: address of the imported key - - key.type [string]: type of the account - - key.url [string]: key URL + +* external API version [string] #### Sample call ```json { - "id": 6, + "id": 0, "jsonrpc": "2.0", - "method": "account_import", - "params": [ - { - "address": "c7412fc59930fd90099c917a50e5f11d0934b2f5", - "crypto": { - "cipher": "aes-128-ctr", - "cipherparams": { - "iv": "401c39a7c7af0388491c3d3ecb39f532" - }, - "ciphertext": "eb045260b18dd35cd0e6d99ead52f8fa1e63a6b0af2d52a8de198e59ad783204", - "kdf": "scrypt", - "kdfparams": { - "dklen": 32, - "n": 262144, - "p": 1, - "r": 8, - "salt": "9a657e3618527c9b5580ded60c12092e5038922667b7b76b906496f021bb841a" - }, - "mac": "880dc10bc06e9cec78eb9830aeb1e7a4a26b4c2c19615c94acb632992b952806" - }, - "id": "09bccb61-b8d3-4e93-bf4f-205a8194f0b9", - "version": 3 - } - ] + "method": "account_version", + "params": [] } ``` + Response - ```json { - "id": 6, - "jsonrpc": "2.0", - "result": { - "address": "0xc7412fc59930fd90099c917a50e5f11d0934b2f5", - "type": "account", - "url": "keystore:///tmp/keystore/UTC--2017-08-24T11-00-42.032024108Z--c7412fc59930fd90099c917a50e5f11d0934b2f5" - } -} -``` - -### account_export - -#### Export account from keystore - Export a private key from the keystore. The exported private key is encrypted with the original password. When the - key is imported later this password is required. - -#### Arguments - - account [address]: export private key that is associated with this account - -#### Result - - exported key, see [web3 keystore format](https://github.com/ethereum/wiki/wiki/Web3-Secret-Storage-Definition) for - more information - -#### Sample call -```json -{ - "id": 5, - "jsonrpc": "2.0", - "method": "account_export", - "params": [ - "0xc7412fc59930fd90099c917a50e5f11d0934b2f5" - ] -} -``` -Response - -```json -{ - "id": 5, - "jsonrpc": "2.0", - "result": { - "address": "c7412fc59930fd90099c917a50e5f11d0934b2f5", - "crypto": { - "cipher": "aes-128-ctr", - "cipherparams": { - "iv": "401c39a7c7af0388491c3d3ecb39f532" - }, - "ciphertext": "eb045260b18dd35cd0e6d99ead52f8fa1e63a6b0af2d52a8de198e59ad783204", - "kdf": "scrypt", - "kdfparams": { - "dklen": 32, - "n": 262144, - "p": 1, - "r": 8, - "salt": "9a657e3618527c9b5580ded60c12092e5038922667b7b76b906496f021bb841a" - }, - "mac": "880dc10bc06e9cec78eb9830aeb1e7a4a26b4c2c19615c94acb632992b952806" - }, - "id": "09bccb61-b8d3-4e93-bf4f-205a8194f0b9", - "version": 3 - } + "id": 0, + "jsonrpc": "2.0", + "result": "6.0.0" } ``` @@ -626,7 +540,7 @@ By starting the signer with the switch `--stdio-ui-test`, the signer will invoke denials. This can be used during development to ensure that the API is (at least somewhat) correctly implemented. See `pythonsigner`, which can be invoked via `python3 pythonsigner.py test` to perform the 'denial-handshake-test'. -All methods in this API uses object-based parameters, so that there can be no mixups of parameters: each piece of data is accessed by key. +All methods in this API use object-based parameters, so that there can be no mixup of parameters: each piece of data is accessed by key. See the [ui API changelog](intapi_changelog.md) for information about changes to this API. @@ -785,12 +699,10 @@ Invoked when a request for account listing has been made. { "accounts": [ { - "type": "Account", "url": "keystore:///home/bazonk/.ethereum/keystore/UTC--2017-11-20T14-44-54.089682944Z--123409812340981234098123409812deadbeef42", "address": "0x123409812340981234098123409812deadbeef42" }, { - "type": "Account", "url": "keystore:///home/bazonk/.ethereum/keystore/UTC--2017-11-23T21-59-03.199240693Z--cafebabedeadbeef34098123409812deadbeef42", "address": "0xcafebabedeadbeef34098123409812deadbeef42" } @@ -820,7 +732,13 @@ Invoked when a request for account listing has been made. { "address": "0x123409812340981234098123409812deadbeef42", "raw_data": "0x01020304", - "message": "\u0019Ethereum Signed Message:\n4\u0001\u0002\u0003\u0004", + "messages": [ + { + "name": "message", + "value": "\u0019Ethereum Signed Message:\n4\u0001\u0002\u0003\u0004", + "type": "text/plain" + } + ], "hash": "0x7e3a4e7a9d1744bc5c675c25e1234ca8ed9162bd17f78b9085e48047c15ac310", "meta": { "remote": "signer binary", @@ -830,12 +748,34 @@ Invoked when a request for account listing has been made. } ] } +``` +### ApproveNewAccount / `ui_approveNewAccount` + +Invoked when a request for creating a new account has been made. + +#### Sample call + +```json +{ + "jsonrpc": "2.0", + "id": 4, + "method": "ui_approveNewAccount", + "params": [ + { + "meta": { + "remote": "signer binary", + "local": "main", + "scheme": "in-proc" + } + } + ] +} ``` ### ShowInfo / `ui_showInfo` -The UI should show the info to the user. Does not expect response. +The UI should show the info (a single message) to the user. Does not expect response. #### Sample call @@ -845,9 +785,7 @@ The UI should show the info to the user. Does not expect response. "id": 9, "method": "ui_showInfo", "params": [ - { - "text": "Tests completed" - } + "Tests completed" ] } @@ -855,18 +793,16 @@ The UI should show the info to the user. Does not expect response. ### ShowError / `ui_showError` -The UI should show the info to the user. Does not expect response. +The UI should show the error (a single message) to the user. Does not expect response. ```json { "jsonrpc": "2.0", "id": 2, - "method": "ShowError", + "method": "ui_showError", "params": [ - { - "text": "Testing 'ShowError'" - } + "Something bad happened!" ] } @@ -880,9 +816,36 @@ When implementing rate-limited rules, this callback should be used. TLDR; Use this method to keep track of signed transactions, instead of using the data in `ApproveTx`. +Example call: +```json + +{ + "jsonrpc": "2.0", + "id": 1, + "method": "ui_onApprovedTx", + "params": [ + { + "raw": "0xf88380018203339407a565b7ed7d7a678680a4c162885bedbb695fe080a44401a6e4000000000000000000000000000000000000000000000000000000000000001226a0223a7c9bcf5531c99be5ea7082183816eb20cfe0bbc322e97cc5c7f71ab8b20ea02aadee6b34b45bb15bc42d9c09de4a6754e7000908da72d48cc7704971491663", + "tx": { + "nonce": "0x0", + "gasPrice": "0x1", + "gas": "0x333", + "to": "0x07a565b7ed7d7a678680a4c162885bedbb695fe0", + "value": "0x0", + "input": "0x4401a6e40000000000000000000000000000000000000000000000000000000000000012", + "v": "0x26", + "r": "0x223a7c9bcf5531c99be5ea7082183816eb20cfe0bbc322e97cc5c7f71ab8b20e", + "s": "0x2aadee6b34b45bb15bc42d9c09de4a6754e7000908da72d48cc7704971491663", + "hash": "0xeba2df809e7a612a0a0d444ccfa5c839624bdc00dd29e3340d46df3870f8a30e" + } + } + ] +} +``` + ### OnSignerStartup / `ui_onSignerStartup` -This method provide the UI with information about what API version the signer uses (both internal and external) as well as build-info and external API, +This method provides the UI with information about what API version the signer uses (both internal and external) as well as build-info and external API, in k/v-form. Example call: @@ -906,6 +869,27 @@ Example call: ``` +### OnInputRequired / `ui_onInputRequired` + +Invoked when Clef requires user input (e.g. a password). + +Example call: +```json + +{ + "jsonrpc": "2.0", + "id": 1, + "method": "ui_onInputRequired", + "params": [ + { + "title": "Account password", + "prompt": "Please enter the password for account 0x694267f14675d7e1b9494fd8d72fefe1755710fa", + "isPassword": true + } + ] +} +``` + ### Rules for UI apis