mirror of
https://github.com/monero-project/meta.git
synced 2024-12-22 11:39:22 +00:00
Merge pull request #287 from ndorf/lightwallet_api
Specification for standard lightwallet client/server API
This commit is contained in:
commit
d0aba77120
1 changed files with 402 additions and 0 deletions
402
api/lightwallet_rest.md
Normal file
402
api/lightwallet_rest.md
Normal file
|
@ -0,0 +1,402 @@
|
||||||
|
# Lightwallet API
|
||||||
|
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 2^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.
|
||||||
|
|
||||||
|
| Field | Type | Description |
|
||||||
|
|------------------|-------------------|-------------------------------|
|
||||||
|
| tx_id | uint64 | Index of tx in blockchain |
|
||||||
|
| amount | uint64-string | XMR value of output |
|
||||||
|
| index | uint16 | Index within vout vector |
|
||||||
|
| global_index | uint64-string | Index within amount |
|
||||||
|
| rct | binary | Bytes of ringct data |
|
||||||
|
| tx_hash | binary | Bytes of tx hash |
|
||||||
|
| tx_prefix_hash | binary | Bytes of tx prefix hash |
|
||||||
|
| public_key | binary | Bytes of output public key |
|
||||||
|
| tx_pub_key | binary | Bytes of the tx public key |
|
||||||
|
| spend_key_images | array of binary's | Bytes of key images |
|
||||||
|
| timestamp | timestamp | Timestamp of containing block |
|
||||||
|
| height | uint64 | Containing 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
|
||||||
|
|
||||||
|
| Field | Type | Description |
|
||||||
|
|-------|---------|-----------------------|
|
||||||
|
| AUD * | float32 | AUD/XMR exchange rate |
|
||||||
|
| BRL * | float32 | BRL/XMR exchange rate |
|
||||||
|
| BTC * | float32 | BTC/XMR exchange rate |
|
||||||
|
| CAD * | float32 | CAD/XMR exchange rate |
|
||||||
|
| CHF * | float32 | CHF/XMR exchange rate |
|
||||||
|
| CNY * | float32 | CNY/XMR exchange rate |
|
||||||
|
| EUR * | float32 | EUR/XMR exchange rate |
|
||||||
|
| GBP * | float32 | GBP/XMR exchange rate |
|
||||||
|
| HKD * | float32 | HKD/XMR exchange rate |
|
||||||
|
| INR * | float32 | INR/XMR exchange rate |
|
||||||
|
| JPY * | float32 | JPY/XMR exchange rate |
|
||||||
|
| KRW * | float32 | KRW/XMR exhcnage rate |
|
||||||
|
| MXN * | float32 | MXN/XMR exchange rate |
|
||||||
|
| NOK * | float32 | NOK/XMR exchange rate |
|
||||||
|
| NZD * | float32 | NZD/XMR exchange rate |
|
||||||
|
| SEK * | float32 | SEK/XMR exchange rate |
|
||||||
|
| SGD * | float32 | SGD/XMR exchange rate |
|
||||||
|
| TRY * | float32 | TRY/XMR exchange rate |
|
||||||
|
| USD * | float32 | USD/XMR exchange rate |
|
||||||
|
| RUB * | float32 | RUB/XMR exchange rate |
|
||||||
|
| ZAR * | float32 | ZAR/XMR exchange rate |
|
||||||
|
|
||||||
|
> If an exchange rate is unavailable, the server field shall omit the field
|
||||||
|
> from the JSON object.
|
||||||
|
|
||||||
|
**spend** object
|
||||||
|
|
||||||
|
| Field | Type | Description |
|
||||||
|
|------------|---------------|----------------------------|
|
||||||
|
| amount | uint64-string | XMR possibly being spent |
|
||||||
|
| key_image | binary | Bytes of the key image |
|
||||||
|
| tx_pub_key | binary | Bytes of the tx public key |
|
||||||
|
| out_index | uint16 | Index of source output |
|
||||||
|
| mixin | uint32 | Mixin 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
|
||||||
|
|
||||||
|
| Field | Type | Description |
|
||||||
|
|----------------|------------------|---------------------------|
|
||||||
|
| id | uint64 | Index of tx in blockchain |
|
||||||
|
| hash | binary | Bytes of tx hash |
|
||||||
|
| timestamp * | timestamp | Timestamp of block |
|
||||||
|
| total_received | uint64-string | Total XMR received |
|
||||||
|
| total_sent | uint64-string | XMR possibly being spent |
|
||||||
|
| unlock_time | uint64 | Tx unlock time field |
|
||||||
|
| height * | uint64 | Block height |
|
||||||
|
| spent_outputs | array of spend's | List of possible spends |
|
||||||
|
| payment_id * | binary | Bytes of tx payment id |
|
||||||
|
| coinbase | boolean | True if tx is coinbase |
|
||||||
|
| mempool | boolean | True if tx is in mempool |
|
||||||
|
| mixin | uint32 | Mixin 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 2^53 - all numbers are 64-bit floats in JavaScript.
|
||||||
|
|
||||||
|
**random_output** object
|
||||||
|
|
||||||
|
| Field | Type | Description |
|
||||||
|
|--------------|---------------|------------------------------------|
|
||||||
|
| global_index | uint64-string | Index within amount |
|
||||||
|
| public_key | bytes | Bytes of output public key |
|
||||||
|
| rct | bytes | Bytes 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.
|
||||||
|
|
||||||
|
| Field | Type | Description |
|
||||||
|
|-----------|--------------------------|-------------------------|
|
||||||
|
| amount | uint64-string | XMR amount, 0 if ringct |
|
||||||
|
| outputs * | array of random_output's | Selected 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
|
||||||
|
|
||||||
|
| Field | Type | Description |
|
||||||
|
|-----------|----------------|---------------------------------------|
|
||||||
|
| address | base58-address | Address to retrieve |
|
||||||
|
| view_key | binary | View key bytes for authorization |
|
||||||
|
|
||||||
|
> If `address` is not authorized, the server must return a HTTP 403
|
||||||
|
> "Forbidden" error.
|
||||||
|
|
||||||
|
**Response** object
|
||||||
|
|
||||||
|
| Field | Type | Description |
|
||||||
|
|----------------------|------------------|---------------------------|
|
||||||
|
| locked_funds | uint64-string | Sum of unspendable XMR |
|
||||||
|
| total_received | uint64-string | Sum of received XMR |
|
||||||
|
| total_sent | uint64-string | Sum of possibly spent XMR |
|
||||||
|
| scanned_height | uint64 | Current tx scan progress |
|
||||||
|
| scanned_block_height | uint64 | Current scan progress |
|
||||||
|
| start_height | uint64 | Start height of response |
|
||||||
|
| transaction_height | uint64 | Total txes sent in Monero |
|
||||||
|
| blockchain_height | uint64 | Current blockchain height |
|
||||||
|
| spent_outputs | array of spend's | Possible spend info |
|
||||||
|
| rates * | rates | Current 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
|
||||||
|
|
||||||
|
| Field | Type | Description |
|
||||||
|
|----------|----------------|---------------------------------------|
|
||||||
|
| address | base58-address | Address to retrieve |
|
||||||
|
| view_key | binary | View key bytes for authorization |
|
||||||
|
|
||||||
|
> If `address` is not authorized, the server must return a HTTP 403
|
||||||
|
> "Forbidden" error.
|
||||||
|
|
||||||
|
**Response** object
|
||||||
|
|
||||||
|
| Field | Type | Description |
|
||||||
|
|----------------------|------------------------|---------------------------|
|
||||||
|
| total_received | uint64-string | Sum of received outputs |
|
||||||
|
| scanned_height | uint64 | Current tx scan progress |
|
||||||
|
| scanned_block_height | uint64 | Current scan progress |
|
||||||
|
| start_height | uint64 | Start height of response |
|
||||||
|
| blockchain_height | uint64 | Current blockchain height |
|
||||||
|
| transactions | array of transaction's | Possible 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
|
||||||
|
|
||||||
|
| Field | Type | Description |
|
||||||
|
|------------|---------------------------|----------------------------------|
|
||||||
|
| count | uint32 | Mixin (name is historical) |
|
||||||
|
| amounts | array of uint64-strings's | XMR 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
|
||||||
|
|
||||||
|
| Field | Type | Description |
|
||||||
|
|-------------|--------------------------|----------------------------------|
|
||||||
|
| amount_outs | array of random_outputs' | Dummy 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
|
||||||
|
|
||||||
|
| Field | Type | Description |
|
||||||
|
|------------------|----------------|----------------------------------|
|
||||||
|
| address | base58-address | Address to create/probe |
|
||||||
|
| view_key | binary | View key bytes |
|
||||||
|
| amount | uint64-string | XMR send amount |
|
||||||
|
| mixin | uint32 | Minimum mixin for source output |
|
||||||
|
| use_dust | boolean | Return all available outputs |
|
||||||
|
| dust_threshold * | uint64-string | Ignore 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
|
||||||
|
|
||||||
|
| Field | Type | Description |
|
||||||
|
|--------------|-------------------|-----------------------------------------|
|
||||||
|
| per_byte_fee | uint64-string | Estimated network fee |
|
||||||
|
| fee_mask | uint64-string | Fee quantization mask |
|
||||||
|
| amount | uint64-string | The total value in outputs |
|
||||||
|
| outputs | array of output's | Outputs possibly available for spending |
|
||||||
|
|
||||||
|
#### `import_request`
|
||||||
|
Request an account scan from the genesis block.
|
||||||
|
|
||||||
|
**Request** object
|
||||||
|
|
||||||
|
| Field | Type | Description |
|
||||||
|
|----------|----------------|-------------------------|
|
||||||
|
| address | base58-address | Address to create/probe |
|
||||||
|
| view_key | binary | View key bytes |
|
||||||
|
|
||||||
|
**Response** object
|
||||||
|
|
||||||
|
| Field | Type | Description |
|
||||||
|
|--------------------|----------------|----------------------------------|
|
||||||
|
| payment_address * | base58-address | Payment location |
|
||||||
|
| payment_id * | binary | Bytes for payment_id tx field |
|
||||||
|
| import_fee * | uint64-string | Fee required to complete request |
|
||||||
|
| new_request | boolean | New or existing request |
|
||||||
|
| request_fulfilled | boolean | Indicates success |
|
||||||
|
| status | string | Custom 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
|
||||||
|
|
||||||
|
| Field | Type | Description |
|
||||||
|
|-------------------|----------------|----------------------------------|
|
||||||
|
| address | base58-address | Address to create/probe |
|
||||||
|
| view_key | binary | View key bytes |
|
||||||
|
| create_account | boolean | Try to create new account |
|
||||||
|
| generated_locally | boolean | Indicate 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
|
||||||
|
|
||||||
|
| Field | Type | Description |
|
||||||
|
|---------------------|---------|------------------------------------|
|
||||||
|
| new_address | boolean | Whether account was just created |
|
||||||
|
| generated_locally * | boolean | Flag from initial account creation |
|
||||||
|
| start_height * | uint64 | Account scanning start block |
|
||||||
|
|
||||||
|
#### `submit_raw_tx`
|
||||||
|
Submit raw transaction to be relayed to monero network.
|
||||||
|
|
||||||
|
**Request** object
|
||||||
|
|
||||||
|
| Field | Type | Description |
|
||||||
|
|------------|----------------|-----------------------------------------------------------|
|
||||||
|
| tx | binary | Raw 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
|
||||||
|
|
||||||
|
| Field | Type | Description |
|
||||||
|
|--------|--------|-----------------|
|
||||||
|
| status | string | Status of relay |
|
||||||
|
|
||||||
|
> `status` is typically the response by the monero daemon attempting to relay
|
||||||
|
> the transaction.
|
Loading…
Reference in a new issue