Kepler Wallet JSON RPC API

Kepler Wallet API Guide

General Information

This doc is for the Kepler Wallet API practical usage guide, NOT for the wallet API doc. For detailed wallet APIs reference, please read the DOCS.RS, and be careful to read the docs of proper version.

Wallet Configuration

By default, the wallet configuration file ~/.Kepler/main/Kepler-wallet.toml will be automatically generated on the 1st run of Kepler-wallet. Floonet configuration is stored in a separate directory (~/.Kepler/floo).

Note: On all following introductions, I will only write floo for floonet (the Kepler Testnet). If you're running mainnet, please remember to remove --floo in command line, or replace floo as main in some URLs.

Some default configuration need to be modified according to your practical requirements:

1. Listen Interface:

#host IP for wallet listener, change to "0.0.0.0" to receive Keplersapi_listen_interface = "0.0.0.0"

And remember to double check the listening interface after you start wallet listening:

netstat -tlna | grep 7415

For example, my output is:

tcp        0      0 127.0.0.1:7415          0.0.0.0:*               LISTEN 

that means my wallet's listening on localhost only.

Note: For send-only wallet, it's OK to keep api_listen_interface = "127.0.0.1" as the default configuration for it.

2. API Secrets

On the 1st time running of Kepler, a random API secret will be generated into ~/.Kepler/floo/.api_secret file. You can use your own secret but please make sure using some kinds of password generator to ensure this secret has enough complexity.

#path of the secret token used by the API to authenticate the calls#comment it to disable basic authapi_secret_path = "/home/garyyu/.Kepler/floo/.api_secret"#location of the node api secret for basic auth on the Kepler APInode_api_secret_path = "/home/garyyu/.Kepler/floo/.api_secret"#where the wallet should find a running nodecheck_node_api_http_addr = "http://127.0.0.1:7413"

These are my configurations, and yours should be different on the home directory name.

Regarding the check_node_api_http_addr, in my case I have a Kepler server running on same server, so I can use "http://127.0.0.1:7413". If you're using an external Kepler server, you can modify this to point to your Kepler server. 3413 is the default node API port.

3. Owner API Port

#port for wallet owner apiowner_api_listen_port = 7420

You can change this owner API listening port as you want. On all the following examples, I will use 7420 as the port.

4. Owner API Include Foreign

#include the foreign API endpoints on the same port as the owner#API. Useful for networking environments like AWS ECS that make#it difficult to access multiple ports on a single service.owner_api_include_foreign = true

I propose to change this as true for the convenience, if you don't want to run another process to run a listening wallet.

5. HTTPS

For the wallet which is listening on external network interface, it's a MUST to enable the https, unless you know exactly what you're doing by HTTP!

To enable https, for example we can configure the following TLS certificate files:

#path of TLS certificate file, self-signed certificates are not supportedtls_certificate_file = "/your/tls/certificate/file/fullchain.pem"#private key for the TLS certificatetls_certificate_key =  "/your/tls/certificate/key/privkey.pem"

Please replace these files with your own TLS certificate files.

If you want to use letsencrypt, you can refer to the Wallet TLS Setup Guide.

6. Wallet Data File Directory

By default, Kepler wallet will create wallet data folder in ~/.Kepler/floo/wallet_data. And you can modify this folder as you want, to put wallet_data into any location.

#where to find wallet files (seed, data, etc)data_file_dir = "/home/garyyu/.Kepler/floo/wallet_data"

In this wallet_data, you will find 3 types of files:

  • wallet database files: lmdb database.
  • wallet.seed: the encrypted wallet seed file.
  • saved_txs: the folder to save those raw transaction data, in file format, with the Shared Transaction Id (i.e. an UUID) as the file name. Note: only those sending transactions have the corresponding saved_txs file, and the purpose of this saved raw transaction data is for reposting, in case any failure of previous post_tx.

7. Log Output

I suggest to enable both stdout and file log, as follows. And stdout_log_level = "Info", the "Info" level is better than "Warning" level for stdout, because with this you will get some immediate useful feedbacks when using some Kepler wallet command.

#whether to log to stdoutlog_to_stdout = true#log level for stdout: Error, Warning, Info, Debug, Tracestdout_log_level = "Info"#whether to log to a filelog_to_file = true#log level for file: Error, Warning, Info, Debug, Tracefile_log_level = "Info"

Wallet Query APIs

Note: For easiness of demo these APIs usage, I use curl to simulate JSON-RPC API calls, for all the following demo examples.

Wallet Summary Query

To get the same info as the Kepler-wallet --floonet info command, we can use retrieve_summary_info API.

$ curl -0 -XPOST -u Kepler:`cat ~/.Kepler/floo/.api_secret` --data '{"jsonrpc":"2.0","method":"retrieve_summary_info","params":[true, 10],"id":1}' http://127.0.0.1:7420/v2/owner

An example output:

{  "id": 1,  "jsonrpc": "2.0",  "result": {    "Ok": [      true,      {        "amount_awaiting_confirmation": "0",        "amount_awaiting_finalization": "40000000",        "amount_currently_spendable": "7065600700000",        "amount_immature": "0",        "amount_locked": "0",        "last_confirmed_height": "193352",        "minimum_confirmations": "10",        "total": "7065600700000"      }    ]  }}

Transaction Query

Transactions Query

We can use retrieve_txs API for transactions query.

Let's simulate this API call with curl:

$ curl -0 -XPOST -u Kepler:`cat ~/.Kepler/floo/.api_secret` --data '{ "jsonrpc": "2.0", "method": "retrieve_txs", "params": [true,null,null], "id": 1}' http://127.0.0.1:7420/v2/owner

Note:

  1. The tx_slate_id here is the Shared Transaction Id for wallet, it's a local generated random UUID, and this UUID is not stored in the blockchain (please don't mix it with Bitcoin/Ethereum TxId concept).
  2. When using wallet API for payment, it's important to cache this UUID, so as to query the transaction status with this UUID, for example using it here.

Single Transaction Query

Let's take another example here for a single transaction query, with its tx_slate_id:

$ curl -0 -XPOST -u Kepler:`cat ~/.Kepler/floo/.api_secret` --data '{ "jsonrpc": "2.0", "method": "retrieve_txs", "params": [true,null,"8ca6ffeb-3210-41db-86d8-ea206acf3263"], "id": 1}' http://127.0.0.1:7420/v2/owner

Outputs Query

UTXOs Query

We can use retrieve_outputs API for outputs query.

To simulate this API call with curl:

$ curl -0 -XPOST -u Kepler:`cat ~/.Kepler/floo/.api_secret` --data '{ "jsonrpc": "2.0", "method": "retrieve_outputs", "params": [false,true,null], "id": 1}' http://127.0.0.1:7420/v2/owner

In this example, we query the all UTXOs.

Query All Outputs

We can query all outputs (spent included) with same API, but remember, only those spent outputs stored in THIS wallet instance included. MimbleWimble / Kepler doesn't always keep the spent outputs on chain (thanks to the cut-through feature).

For example:

$ curl -0 -XPOST -u Kepler:`cat ~/.Kepler/floo/.api_secret` --data '{ "jsonrpc": "2.0", "method": "retrieve_outputs", "params": [true,true,null], "id": 1}' http://127.0.0.1:7420/v2/owner

part of the query result:

Query Outputs of a Single Transaction

We can query all outputs in a one single transaction, but only transaction Input/s and Change Output/s.

For example, here is a query for transaction with tx_log_entry as 556:

$ curl -0 -XPOST -u Kepler:`cat ~/.Kepler/floo/.api_secret` --data '{ "jsonrpc": "2.0", "method": "retrieve_outputs", "params": [true,true,556], "id": 1}' http://127.0.0.1:7420/v2/owner

part of the query result:

Wallet Sending via API

Http/s Method

For example:

$ curl -0 -XPOST -u Kepler:`cat ~/.Kepler/floo/.api_secret` --data '{ "jsonrpc": "2.0", "method": "init_send_tx", "params": {"args":{"src_acct_name":null, "amount":10000000, "minimum_confirmations":10, "max_outputs":500, "num_change_outputs":1, "selection_strategy_is_use_all":true, "message":null, "target_slate_version":null, "estimate_only":null, "send_args": {"method":"http", "dest":"https://demo.Kepler.icu:7415", "finalize":true, "post_tx":true, "fluff":false}}}, "id": 1}' http://127.0.0.1:7420/v2/owner

Some additional notes on above parameters:

  1. amount is using Nano Kepler as unit, i.e. 10^-9 Kepler. For example, the amount 10000000 here means 0.01 Kepler coins.
  2. both https and https share the same method name: http.
  3. "dest": "https://demo.Kepler.icu:7415" here is using https. If you need use http, just modify the url as http://....
  4. For a simple case, normally we have one change output for self and another output for payee, that's why in this example I set "num_change_outputs": 1.
  5. "selection_strategy_is_use_all": true is the proposed setting (to make the chain has the minimum UTXO sets).
  6. "max_outputs" here means the maximum UTXOs can be used for this transaction. And it's a soft limit, when this is not enough to cover the whole output amount, the wallet will include more outputs. The proposed value here is 500.

The return result example for above call:

File Method

For some use cases, the file method is useful. For example, payment by email, or by file download/upload plus a finalize step, in which case the user will login to the website and request a payout, and then download a raw transaction file, then execute a receive on his/her local Kepler wallet, and then upload the output file, and the website will call the finalize once the uploading is completed, and call the last step post. Payment by email is similar.

1st Step

The payer create a slate with init_send_tx API:

For example:

$ curl -0 -XPOST -u Kepler:`cat ~/.Kepler/floo/.api_secret` --data '{ "jsonrpc": "2.0", "method": "init_send_tx", "params": {"args":{"src_acct_name":null, "amount":1000000000, "minimum_confirmations":10, "max_outputs":100, "num_change_outputs":1, "selection_strategy_is_use_all":true, "message":"I love Kepler, and you?", "target_slate_version":null, "estimate_only":null, "send_args": null}}, "id": 1}' http://127.0.0.1:7420/v2/owner  > init.result.json 2>/dev/null && cat init.result.json | jq '.result .Ok' > slate.init.json && cat init.result.json

2nd Step

The payer need call a tx_lock_outputs API to lock the transaction Input/s.

For example:

$ slate=$(cat slate.init.json | jq --compact-output .) ; curl -0 -XPOST -u Kepler:`cat ~/.Kepler/floo/.api_secret` --data '{ "jsonrpc": "2.0", "method": "tx_lock_outputs", "params": ['"$slate"', 0], "id": 1}' http://127.0.0.1:7420/v2/owner

And the result of above call:

{  "id": 1,  "jsonrpc": "2.0",  "result": {    "Ok": null  }}

As optional, you can query this transaction at this time. The call looks like this for above example:

$ curl -0 -XPOST -u Kepler:`cat ~/.Kepler/floo/.api_secret` --data '{ "jsonrpc": "2.0", "method": "retrieve_txs", "params": [true,null,"1c2e8455-44a6-445e-a36d-d90c7b9b0825"], "id": 1}' http://127.0.0.1:7420/v2/owner

3rd Step

This should be executed by the payment receiver! Remember that the Kepler transaction is an interactive procedure.

Suppose the payee already downloaded the file slate.init.json, and ask him/her to run following command on his local wallet:

$ Kepler-wallet --floonet receive -i slate.init.json

and this command will generate file slate.init.json.response, in the same folder as slate.init.json.

Then the payee need upload this slate.init.json.response file to the payer.

In case the receiver (payee) is also using the owner API, the following will introduce the API usage to do the same thing.

Verify Slate Messages

Firstly, as an optional step, the receiver can call a verify_slate_messages API to verify the slate message signature (if have):

$ slate=$(cat slate.init.json | jq --compact-output .); curl -0 -XPOST -u Kepler:`cat ~/.Kepler/floo/.api_secret` --data '{ "jsonrpc": "2.0", "method": "verify_slate_messages", "params": ['"$slate"'], "id": 1}' http://127.0.0.1:7420/v2/foreign

The wallet log and the returned result of above call looks like:

20190630 17:33:43.235 INFO Kepler_wallet_libwallet::slate - verify_messages - signature verified ok. Participant message: "I love Kepler, and you?"{  "id": 1,  "jsonrpc": "2.0",  "result": {    "Ok": null  }}

Receive Tx

And then, the receiver can call the receive_tx API:

For example:

$ slate=$(cat slate.init.json | jq --compact-output .); curl -0 -XPOST -u Kepler:`cat ~/.Kepler/floo/.api_secret` --data '{ "jsonrpc": "2.0", "method": "receive_tx", "params": ['"$slate"',"default","Me too! Thanks for sending me these Kepler/s."], "id": 1}' http://127.0.0.1:7420/v2/foreign > recv.result.json 2>/dev/null && cat recv.result.json | jq '.result .Ok' > slate.rx.json && cat recv.result.json

4th Step

Once the payer received above uploaded file slate.rx.json, call the finalize_tx API with the file.

But before that, we can still use an optional step to verify the slate message signature. For example:

$ slate=$(cat slate.rx.json | jq --compact-output .); curl -0 -XPOST -u Kepler:`cat ~/.Kepler/floo/.api_secret` --data '{ "jsonrpc": "2.0", "method": "verify_slate_messages", "params": ['"$slate"'], "id": 1}' http://127.0.0.1:7420/v2/owner

The wallet log and returned result of above call will look like this:

20190630 09:41:08.263 INFO Kepler_wallet_libwallet::slate - verify_messages - signature verified ok. Participant message: "I love Kepler, and you?"20190630 09:41:08.264 INFO Kepler_wallet_libwallet::slate - verify_messages - signature verified ok. Participant message: "Me too! Thanks for sending me these Kepler/s."{  "id": 1,  "jsonrpc": "2.0",  "result": {    "Ok": null  }}

But we can also skip above verification and directly call finalize_tx. For example:

$ slate=$(cat slate.rx.json | jq --compact-output .) ; curl -0 -XPOST -u Kepler:`cat ~/.Kepler/floo/.api_secret` --data '{ "jsonrpc": "2.0", "method": "finalize_tx", "params": ['"$slate"'], "id": 1}' http://127.0.0.1:7420/v2/owner > finalize.result.json 2>/dev/null && cat finalize.result.json | jq '.result .Ok .tx' > slate.final.json && cat finalize.result.json

The last Step

The sender need call the post_tx API with the finalize_tx API outputs from above step.

Suppose we save the final slate as a file slate.final.json, then, let's still use curl to simulate this API call:

$ slate=$(cat slate.final.json | jq --compact-output .) ; curl -0 -XPOST -u Kepler:`cat ~/.Kepler/floo/.api_secret` --data '{ "jsonrpc": "2.0", "method": "post_tx", "params": ['"$slate"', false], "id": 1}' http://127.0.0.1:7420/v2/owner

The example output of above call:

{  "id": 1,  "jsonrpc": "2.0",  "result": {    "Ok": null  }}

Cancel a Transaction

When a transaction is not posted yet, we can cancel it via cancel_tx API.

For example, with the known transaction slate id, we can call it with:

$ curl -0 -XPOST -u Kepler:`cat ~/.Kepler/floo/.api_secret` --data '{ "jsonrpc": "2.0", "method": "cancel_tx", "params": [null, "8ca6ffeb-3210-41db-86d8-ea206acf3263"], "id": 1}' http://127.0.0.1:7420/v2/owner{  "id": 1,  "jsonrpc": "2.0",  "result": {    "Ok": null  }}