Lightwallet API

March 25, 2021 · View on GitHub

This document describes a reference standard specification for the Monero lightwallet server/client API. It’s implemented by OpenMonero, MyMonero, and the official Monero project, and is maintained with the purpose of organizing and recording the consensus of Monero lightwallet API projects, and to support alternate implementations.

Modifications to this specification should only be made with consensus of the projects which participate by implementing the specification.

Encoding Schemes

JSON

JSON is the original and required encoding scheme used for the API. Binary values (public keys, hashes, etc) are sent as an ascii-hex string. Some integers, that may exceed 2532^{53}, are sent as strings. This is to due to the limitation within Javascript where all integers are double floating point values.

Transport Layers

HTTP-REST

When calling an API method, the client must use HTTP POST to a path with the method name. As an example, to invoke the get_address_txs method, the client sends a POST message to /get_address_txs where the body contains the JSON request object associated with that method name. If the requested method does not exist, a HTTP 404 "Not Found" error must be returned. If the request type is not POST, the server shall return a HTTP 405 "Method Not Allowed" error. If the server is unable to complete a request temporarily due to load, then the server shall return a HTTP 503 "Service Unavailable" error to indicate to the client that the request may be serviceable later.

Servers must support the JSON encoding scheme. The client must send the HTTP field Content-Type: application/json; if the server is not provided that content type from the client then the server shall respond with a HTTP 415 "Unsupported Media Type" error.

This transport layer does not use HTTP authentication, and instead uses the view_key field for authorization. Documentation for a specific method will indicate whether view_key is required. When it is not necessary, anyone can invoke the method.

Schema

The ascii name of the field is used as a key in JSON encoding. If a field has a * indicator, that means the field is optional. If * is used next to the type, the value can be "null" or a value valid according to the type.

Types

binary

A hex-ascii string in JSON. This is generally some irreducible cryptographic concept - a public key or hash.

base58-address

A standard Monero public address encoded as a string in JSON.

output object

Information needed to spend an output.

FieldTypeDescription
tx_iduint64Index of tx in blockchain
amountuint64-stringXMR value of output
indexuint16Index within vout vector
global_indexuint64-stringIndex within amount
rctbinaryBytes of ringct data
tx_hashbinaryBytes of tx hash
tx_prefix_hashbinaryBytes of tx prefix hash
public_keybinaryBytes of output public key
tx_pub_keybinaryBytes of the tx public key
spend_key_imagesarray of binary objectsBytes of key images
timestamptimestampTimestamp of containing block
heightuint64Containing block height

tx_id is determined by the monero daemon. It is the offset that a transaction appears in the blockchain from the genesis block.

global_index is determined by the monero daemon. It is the offset from the first time the amount appeared in the blockchain. After ringct, this is the order of outputs as they appear in the blockchain.

tx_hash and tx_prefix_hash are determined by how monerod computes the hash.

rct is, for ringct outputs, a 96-byte blob containing the concatenation of the public commitment, then the ringct mask value, and finally the ringct amount value. For ringct coinbase outputs, the mask is always the identity mask and the amount is zero; for non-coinbase ringct outputs, the mask and amount are the respective raw encrypted values, which must be decrypted by the client using the view secret key. For non-ringct outputs, this field is nil.

rates object

FieldTypeDescription
AUD *float32AUD/XMR exchange rate
BRL *float32BRL/XMR exchange rate
BTC *float32BTC/XMR exchange rate
CAD *float32CAD/XMR exchange rate
CHF *float32CHF/XMR exchange rate
CNY *float32CNY/XMR exchange rate
EUR *float32EUR/XMR exchange rate
GBP *float32GBP/XMR exchange rate
HKD *float32HKD/XMR exchange rate
INR *float32INR/XMR exchange rate
JPY *float32JPY/XMR exchange rate
KRW *float32KRW/XMR exhcnage rate
MXN *float32MXN/XMR exchange rate
NOK *float32NOK/XMR exchange rate
NZD *float32NZD/XMR exchange rate
SEK *float32SEK/XMR exchange rate
SGD *float32SGD/XMR exchange rate
TRY *float32TRY/XMR exchange rate
USD *float32USD/XMR exchange rate
RUB *float32RUB/XMR exchange rate
ZAR *float32ZAR/XMR exchange rate

If an exchange rate is unavailable, the server field shall omit the field from the JSON object.

spend object

FieldTypeDescription
amountuint64-stringXMR possibly being spent
key_imagebinaryBytes of the key image
tx_pub_keybinaryBytes of the tx public key
out_indexuint16Index of source output
mixinuint32Mixin of the spend

out_index is a zero-based offset from the original received output. The variable within the monero codebase is the vout array, this is the index within that. It is needed for correct computation of the key_image.

mixin does not include the real spend - this is the number of dummy inputs.

timestamp

A string in JSON. The string format is "YYYY-HH-MM-SS.0-00:00". Monero blockchain timestamps do not have sub-seconds.

transaction object

FieldTypeDescription
iduint64Index of tx in blockchain
hashbinaryBytes of tx hash
timestamp *timestampTimestamp of block
total_receiveduint64-stringTotal XMR received
total_sentuint64-stringXMR possibly being spent
unlock_timeuint64Tx unlock time field
height *uint64Block height
spent_outputsarray of spend objectsList of possible spends
payment_id *binaryBytes of tx payment id
coinbasebooleanTrue if tx is coinbase
mempoolbooleanTrue if tx is in mempool
mixinuint32Mixin of the receive

id is determined by the monero daemon. It is the offset that a transaction appears in the blockchain from the genesis block.

timestamp and height are not sent when mempool is true.

hash is determined by how the monero core computes the hash.

spent_outputs is the list of possible spends in this transaction only.

payment_id is omitted if the transaction had none. It is decrypted when the encrypted form is used. The decryption may be incorrect - if the transaction was TO another address, then this will be random bytes. This happens frequently with outgoing payment ids; the received XMR in the transaction is change and the payment id is for the real recipient.

mixin does not include the real spend - this is the number of dummy inputs.

uint16 / uint32 / uint64

Sent as a standard decimal encoded number in JSON. The JSON decoder must reject number values that exceed the specified bit-width.

uint64-string

A uint64 encoded as a decimal string value in JSON. Used when a value may exceed 2532^{53} - all numbers are 64-bit floats in JavaScript.

random_output object

FieldTypeDescription
global_indexuint64-stringIndex within amount
public_keybytesBytes of output public key
rctbytesBytes containing ringct commitment

global_index is determined by the monero daemon. It is the offset from the first time the amount appeared in the blockchain. After ringct, this is the order of outputs as they appear in the blockchain.

random_outputs object

Randomly selected outputs for use in a ring signature.

FieldTypeDescription
amountuint64-stringXMR amount, 0 if ringct
outputs *array of random_output objectsSelected outputs

outputs is omitted by the server if the amount does not have enough mixable outputs.

Methods

get_address_info

Returns the minimal set of information needed to calculate a wallet balance. The server cannot calculate when a spend occurs without the spend key, so a list of candidate spends is returned.

Request object

FieldTypeDescription
addressbase58-addressAddress to retrieve
view_keybinaryView key bytes for authorization

If address is not authorized, the server must return a HTTP 403 "Forbidden" error.

Response object

FieldTypeDescription
locked_fundsuint64-stringSum of unspendable XMR
total_receiveduint64-stringSum of received XMR
total_sentuint64-stringSum of possibly spent XMR
scanned_heightuint64Current tx scan progress
scanned_block_heightuint64Current scan progress
start_heightuint64Start height of response
transaction_heightuint64Total txes sent in Monero
blockchain_heightuint64Current blockchain height
spent_outputsarray of spend objectsPossible spend info
rates *ratesCurrent exchange rates

rates is omitted if unavailable.

get_address_txs

Returns information needed to show transaction history. The server cannot calculate when a spend occurs without the spend key, so a list of candidate spends is returned.

Request object

FieldTypeDescription
addressbase58-addressAddress to retrieve
view_keybinaryView key bytes for authorization

If address is not authorized, the server must return a HTTP 403 "Forbidden" error.

Response object

FieldTypeDescription
total_receiveduint64-stringSum of received outputs
scanned_heightuint64Current tx scan progress
scanned_block_heightuint64Current scan progress
start_heightuint64Start height of response
blockchain_heightuint64Current blockchain height
transactionsarray of transaction objectsPossible spend info

get_random_outs

Selects random outputs to use in a ring signature of a new transaction. If the amount is 0 then the monerod RPC get_output_distribution should be used to locally select outputs using a gamma distribution as described in "An Empirical Analysis of Traceability in the Monero Blockchain". If the amount is not 0, then the monerod RPC get_output_histogram should be used to locally select outputs using a triangular distribution (uint64_t dummy_out = histogram.total * sqrt(float64(random_uint53) / float64($2^{53}$))).

Request object

FieldTypeDescription
countuint32Mixin (name is historical)
amountsarray of uint64-string objectsXMR amounts that need mixing

Clients must use amount 0 when computing a ringct output.

If clients are creating multiple rings with the same amount, they must set count to the mixin level and add the value to amounts multiple times. Server must respond to each value in amounts, even if the value appears multiple times.

Response object

FieldTypeDescription
amount_outsarray of random_output objectsDummy outputs for each amounts

If there are not enough outputs to mix for a specific amount, the server shall omit the outputs field in amount_outs.

get_unspent_outs

Returns a list of received outputs. The client must determine when the output was actually spent.

Request object

FieldTypeDescription
addressbase58-addressAddress to create/probe
view_keybinaryView key bytes
amountuint64-stringXMR send amount
mixinuint32Minimum mixin for source output
use_dustbooleanReturn all available outputs
dust_threshold *uint64-stringIgnore outputs below this amount

If the total received outputs for the address is less than amount, the server shall return a HTTP 400 "Bad Request" error code.

Response object

FieldTypeDescription
per_byte_feeuint64-stringEstimated network fee
fee_maskuint64-stringFee quantization mask
amountuint64-stringThe total value in outputs
outputsarray of output objectsOutputs possibly available for spending

import_request

Request an account scan from the genesis block.

Request object

FieldTypeDescription
addressbase58-addressAddress to create/probe
view_keybinaryView key bytes

Response object

FieldTypeDescription
payment_address *base58-addressPayment location
payment_id *binaryBytes for payment_id tx field
import_fee *uint64-stringFee required to complete request
new_requestbooleanNew or existing request
request_fulfilledbooleanIndicates success
statusstringCustom message

payment_id, import_fee, and payment_address may be omitted if the client does not need to send XMR to complete the request.

login

Check for the existence of an account or create a new one.

Request object

FieldTypeDescription
addressbase58-addressAddress to create/probe
view_keybinaryView key bytes
create_accountbooleanTry to create new account
generated_locallybooleanIndicate that the address is new

The view key bytes are required even if an account is not being created, to prevent metadata leakage.

If the server does not allow account creations, HTTP 501 "Not Implemented" error must be returned.

If approval process is manual, a successful HTTP 200 OK and response object must be returned. Subsequent requests shall be HTTP 403 "Forbidden" until account is approved.

Response object

FieldTypeDescription
new_addressbooleanWhether account was just created
generated_locally *booleanFlag from initial account creation
start_height *uint64Account scanning start block

submit_raw_tx

Submit raw transaction to be relayed to monero network.

Request object

FieldTypeDescription
txbinaryRaw transaction bytes, in format used by daemon p2p comms

This format is tricky unfortunately, it is custom to the monero daemon. The internal code of monerod must be read to determine this format currently.

Response object

FieldTypeDescription
statusstringStatus of relay

status is typically the response by the monero daemon attempting to relay the transaction.