First thing's first, Clef needs to store some data itself. Since that data might be sensitive (passwords, signing rules, accounts), Clef's entire storage is encrypted. To support encrypting data, the first step is to initialize Clef with a random master seed, itself too encrypted with your chosen password:
First things first, Clef needs to store some data itself. Since that data might be sensitive (passwords, signing rules, accounts), Clef's entire storage is encrypted. To support encrypting data, the first step is to initialize Clef with a random master seed, itself too encrypted with your chosen password:
```text
```text
$ clef init
$ clef init
@ -27,8 +27,8 @@ Enter 'ok' to proceed:
The master seed of clef will be locked with a password.
The master seed of clef will be locked with a password.
Please specify a password. Do not forget this password!
Please specify a password. Do not forget this password!
Passphrase:
Password:
Repeat passphrase:
Repeat password:
A master seed has been generated into /home/martin/.clef/masterseed.json
A master seed has been generated into /home/martin/.clef/masterseed.json
The signer listens to HTTP requests on `rpcaddr`:`rpcport`, with the same JSONRPC standard as Geth. The messages are
Clef listens to HTTP requests on `rpcaddr`:`rpcport` (or to IPC on `ipcpath`), with the same JSON-RPC standard as Geth. The messages are expected to be [JSON-RPC 2.0 standard](https://www.jsonrpc.org/specification).
expected to be JSON [jsonrpc 2.0 standard](http://www.jsonrpc.org/specification).
Some of these call can require user interaction. Clients must be aware that responses
Some of these calls can require user interaction. Clients must be aware that responses may be delayed significantly or may never be received if a user decides to ignore the confirmation request.
may be delayed significantly or may never be received if a users decides to ignore the confirmation request.
The External API is **untrusted** : it does not accept credentials over this api, nor does it expect
The External API is **untrusted**: it does not accept credentials, nor does it expect that requests have any authority.
that requests have any authority.
### UI API
### Internal UI API
The signer has one native console-based UI, for operation without any standalone tools.
Clef has one native console-based UI, for operation without any standalone tools. However, there is also an API to communicate with an external UI. To enable that UI, the signer needs to be executed with the `--stdio-ui` option, which allocates `stdin` / `stdout` for the UI API.
However, there is also an API to communicate with an external UI. To enable that UI,
the signer needs to be executed with the `--stdio-ui` option, which allocates the
`stdin`/`stdout` for the UI-api.
An example (insecure) proof-of-concept of has been implemented in `pythonsigner.py`.
An example (insecure) proof-of-concept of has been implemented in `pythonsigner.py`.
The model is as follows:
The model is as follows:
* The user starts the UI app (`pythonsigner.py`).
* The user starts the UI app (`pythonsigner.py`).
* The UI app starts the `signer` with `--stdio-ui`, and listens to the
* The UI app starts `clef` with `--stdio-ui`, and listens to the
process output for confirmation-requests.
process output for confirmation-requests.
* The `signer` opens the external http api.
* `clef` opens the external HTTP API.
* When the `signer` receives requests, it sends a `jsonrpc` request via `stdout`.
* When the `signer` receives requests, it sends a JSON-RPC request via `stdout`.
* The UI app prompts the user accordingly, and responds to the `signer`
* The UI app prompts the user accordingly, and responds to `clef`.
* The `signer` signs (or not), and responds to the original request.
* `clef` signs (or not), and responds to the original request.
### More resoruces
### More resoruces
@ -43,7 +37,7 @@ process output for confirmation-requests.
## External API
## External API
See the [external api changelog](https://github.com/ethereum/go-ethereum/blob/master/cmd/clef/extapi_changelog.md) for information about changes to this API.
See the [external API changelog](https://github.com/ethereum/go-ethereum/blob/master/cmd/clef/extapi_changelog.md) for information about changes to this API.
### Encoding
### Encoding
@ -53,13 +47,11 @@ See the [external api changelog](https://github.com/ethereum/go-ethereum/blob/ma
All hex encoded values must be prefixed with `0x`.
All hex encoded values must be prefixed with `0x`.
## Methods
### account_new
### account_new
#### Create new password protected account
#### 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.
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
#### Arguments
@ -68,7 +60,6 @@ None
#### Result
#### Result
- address [string]: account address that is derived from the generated key
- address [string]: account address that is derived from the generated key
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
#### Arguments
2. transaction object:
1. transaction object:
- `from` [address]: account to send the transaction from
- `from` [address]: account to send the transaction from
- `to` [address]: receiver account. If omitted or `0x`, will cause contract creation.
- `to` [address]: receiver account. If omitted or `0x`, will cause contract creation.
- `gas` [number]: maximum amount of gas to burn
- `gas` [number]: maximum amount of gas to burn
@ -148,12 +126,13 @@ Response
- `value` [number:optional]: amount of Wei to send with the transaction
- `value` [number:optional]: amount of Wei to send with the transaction
- `data` [data:optional]: input data
- `data` [data:optional]: input data
- `nonce` [number]: account nonce
- `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.
- 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
#### Result
- signed transaction in RLP encoded form [data]
- raw [data]: signed transaction in RLP encoded form
Signs a chunk of structured data conformant to [EIP712](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-712.md) and returns the calculated signature.
Signs a chunk of structured data conformant to [EIP-712](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-712.md) and returns the calculated signature.
#### Arguments
#### Arguments
- account [address]: account to sign with
- account [address]: account to sign with
@ -377,7 +367,7 @@ Response
### account_ecRecover
### 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.
Derive the address from the account that was used to sign data with content type `text/plain` and the signature.
@ -395,7 +385,6 @@ Derive the address from the account that was used to sign data with content type
These methods needs to be implemented by a UI listener.
These methods needs to be implemented by a UI listener.
@ -535,9 +441,9 @@ 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.
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'.
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](https://github.com/ethereum/go-ethereum/blob/master/cmd/clef/intapi_changelog.md) for information about changes to this API.
See the [ui API changelog](https://github.com/ethereum/go-ethereum/blob/master/cmd/clef/intapi_changelog.md) for information about changes to this API.
OBS! A slight deviation from `json` standard is in place: every request and response should be confined to a single line.
OBS! A slight deviation from `json` standard is in place: every request and response should be confined to a single line.
Whereas the `json` specification allows for linebreaks, linebreaks __should not__ be used in this communication channel, to make
Whereas the `json` specification allows for linebreaks, linebreaks __should not__ be used in this communication channel, to make
@ -694,12 +600,10 @@ Invoked when a request for account listing has been made.
This method provide the UI with information about what API version the signer uses (both internal and external) aswell 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.
in k/v-form.
Example call:
Example call:
@ -815,3 +770,23 @@ 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",
These data types are defined in the channel between clef and the UI
These data types are defined in the channel between clef and the UI
### SignDataRequest
### SignDataRequest
SignDataRequest contains information about a pending request to sign some data. The data to be signed can be of various types, defined by content-type. Clef has done most of the work in canonicalizing and making sense of the data, and it's up to the UI to presentthe user with the contents of the `message`
SignDataRequest contains information about a pending request to sign some data. The data to be signed can be of various types, defined by content-type. Clef has done most of the work in canonicalizing and making sense of the data, and it's up to the UI to presentthe user with the contents of the `message`