From b3ac47705b266d39eb28224efefc494b25fab343 Mon Sep 17 00:00:00 2001 From: Lee *!* Clagett Date: Mon, 16 Mar 2026 22:36:21 -0400 Subject: [PATCH] Pushing initial attempt at a docs site --- .github/workflows/deploy-pages.yml | 29 + docs/api/admin.md | 1 + docs/api/admin.yaml | 941 ++++++++++++++++ docs/{ => api}/rmq.md | 4 +- docs/api/wallet.md | 1 + docs/api/wallet.yaml | 1210 +++++++++++++++++++++ docs/api/zmq.md | 154 +++ docs/{administration.md => apps/admin.md} | 19 +- docs/apps/client.md | 0 docs/apps/daemon.md | 81 ++ docs/index.md | 53 + docs/installation/docker.md | 15 + docs/installation/source.md | 80 ++ docs/{ => scan}/balance_new_addresses.md | 0 docs/{ => scan}/block_depth_threading.md | 0 docs/scan/round_robin.md | 5 + docs/{ => scan}/split_synced_threads.md | 0 docs/zmq.md | 178 --- mkdocs.yml | 27 + 19 files changed, 2609 insertions(+), 189 deletions(-) create mode 100644 .github/workflows/deploy-pages.yml create mode 100644 docs/api/admin.md create mode 100644 docs/api/admin.yaml rename docs/{ => api}/rmq.md (95%) create mode 100644 docs/api/wallet.md create mode 100644 docs/api/wallet.yaml create mode 100644 docs/api/zmq.md rename docs/{administration.md => apps/admin.md} (97%) create mode 100644 docs/apps/client.md create mode 100644 docs/apps/daemon.md create mode 100644 docs/index.md create mode 100644 docs/installation/docker.md create mode 100644 docs/installation/source.md rename docs/{ => scan}/balance_new_addresses.md (100%) rename docs/{ => scan}/block_depth_threading.md (100%) create mode 100644 docs/scan/round_robin.md rename docs/{ => scan}/split_synced_threads.md (100%) delete mode 100644 docs/zmq.md create mode 100644 mkdocs.yml diff --git a/.github/workflows/deploy-pages.yml b/.github/workflows/deploy-pages.yml new file mode 100644 index 0000000..640d0b5 --- /dev/null +++ b/.github/workflows/deploy-pages.yml @@ -0,0 +1,29 @@ +name: docs + +on: + push: + branches: [ "master" ] + paths: [ "docs/**" ] + pull_request: + branches: [ "develop" ] + paths: [ "docs/**" ] + +jobs: + deploy: + steps: + - name: Checkout LWS Source + uses: actions/checkout@v4 + - name: Setup Python + uses: actions/setup-python@v6 + - name: Install dependencies + run: | + python3 -m pip install --upgrade pip + python3 -m pip install mkdocs + python3 -m pip install mkdocs-swagger-ui-tag + python3 -m pip install mkdocs-schema-reader + python3 mkdocs build + - name: Deploy + uses: peaceiris/actions-gh-pages@v4 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: ./site diff --git a/docs/api/admin.md b/docs/api/admin.md new file mode 100644 index 0000000..00f8dee --- /dev/null +++ b/docs/api/admin.md @@ -0,0 +1 @@ + diff --git a/docs/api/admin.yaml b/docs/api/admin.yaml new file mode 100644 index 0000000..1f3ad32 --- /dev/null +++ b/docs/api/admin.yaml @@ -0,0 +1,941 @@ +openapi: 3.0.4 +info: + title: monero-lws Admin API + description: |- + This document describes the admin API for the [monero-lws](https://github.com/vtnerd/monero-lws) project. + + An admin account can be created running the executable `monero-lws-admin create_admin` only (this command is not available via REST for security purposes). The key value returned in the create_admin JSON object becomes the `auth` parameter in the admin REST API. A new admin account is put into the hidden state - the account is not scanned for transactions and is not available to the normal REST API, but is available to the admin REST API. + version: 1.0.0 +tags: + - name: account + description: Account administration + - name: webhook + description: Webhook administration +paths: + /accept_requests: + post: + tags: + - account + summary: Accept import+create account requests + description: | + This endpoint can perform two account actions: + * Accept new wallets requests created with the `/login` endpoint of the LWS client API. + * Accept "import" (from earlier block height) wallet requests created with the `/import_wallet_request` endpoint of the LWS client API. + operationId: accept_requests + requestBody: + content: + application/json: + schema: + type: object + properties: + params: + type: object + properties: + type: + type: string + enum: + - import + - create + addresses: + type: array + items: + $ref: '#/components/schemas/base58-address' + required: + - type + - addresses + allOf: + - $ref: '#/components/schemas/auth' + required: + - params + required: true + responses: + '200': + description: Success + content: + application/json: + schema: + $ref: '#/components/schemas/updated' + '400': + description: Invalid JSON. + '403': + description: Invalid `auth` parameter + '405': + description: Not `POST` method. + '500': + description: Invalid JSON schema, and all other general errors. + '503': + description: Unable to read or write from database. + /add_account: + post: + tags: + - account + summary: Add a new (client) account + description: Add a new account to be used by the client API. + operationId: add_account + requestBody: + content: + application/json: + schema: + type: object + properties: + params: + type: object + properties: + address: + $ref: '#/components/schemas/base58-address' + key: + description: The view-key corresponding to `address` + allOf: + - $ref: '#/components/schemas/binary32' + required: + - address + - key + allOf: + - $ref: '#/components/schemas/auth' + required: + - params + required: true + responses: + '200': + description: Success + content: + application/json: + schema: + $ref: '#/components/schemas/updated' + '400': + description: Invalid JSON. + '403': + description: Invalid `auth` parameter + '405': + description: Not `POST` method. + '500': + description: Invalid JSON schema, invalid key/address pair, and all other general errors. + '503': + description: Unable to read or write from database. + /list_accounts: + post: + tags: + - account + summary: List all accounts + operationId: list_accounts + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/auth' + required: true + responses: + '200': + description: Success + content: + application/json: + schema: + type: object + properties: + active: + description: Accounts that are being scanned and viewable in the client API + allOf: + - $ref: '#/components/schemas/account' + inactive: + description: Accounts that are _not_ being scanned, but are viewable in the client API + allOf: + - $ref: '#/components/schemas/account' + hidden: + description: Accounts that are neither being scanned nor viewable in the client API. This includes `auth` accounts that access the admin API. + allOf: + - $ref: '#/components/schemas/account' + '400': + description: Invalid JSON. + '403': + description: Invalid `auth` parameter + '405': + description: Not `POST` method. + '500': + description: Invalid JSON schema, and all other general errors. + '503': + description: Unable to read from database. + /list_requests: + post: + tags: + - account + summary: List all pending create+import requests + operationId: list_requests + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/auth' + required: true + responses: + '200': + description: Success + content: + application/json: + schema: + type: object + properties: + create: + $ref: '#/components/schemas/account-request' + import: + $ref: '#/components/schemas/account-request' + '400': + description: Invalid JSON. + '403': + description: Invalid `auth` parameter + '405': + description: Not `POST` method. + '500': + description: Invalid JSON schema, and all other general errors. + '503': + description: Unable to read from database. + /modify_account_status: + post: + tags: + - account + summary: Move account(s) to another state. + description: | + An account can have 3 states: + * `active`: Accounts that are being scanned and viewable in the client API + * `inactive`: Accounts that are _not_ being scanned, but are viewable in the client API + * `hidden`: Accounts that are neither being scanned nor viewable in the client API. + operationId: modify_account_status + requestBody: + content: + application/json: + schema: + type: object + properties: + params: + type: object + properties: + status: + type: string + enum: + - active + - inactive + - hidden + addresses: + type: array + items: + $ref: '#/components/schemas/base58-address' + required: + - status + - addresses + allOf: + - $ref: '#/components/schemas/auth' + required: + - params + required: true + responses: + '200': + description: Success + content: + application/json: + schema: + $ref: '#/components/schemas/updated' + '400': + description: Invalid JSON. + '403': + description: Invalid `auth` parameter + '405': + description: Not `POST` method. + '500': + description: Invalid JSON schema, and all other general errors. + '503': + description: Unable to read or write from database. + /reject_requests: + post: + tags: + - account + summary: Reject import+create account requests + description: | + This endpoint can perform two account actions: + * Reject new wallets requests created with the `/login` endpoint of the LWS client API. + * Reject "import" (from earlier block height) wallet requests created with the `/import_wallet_request` endpoint of the LWS client API. + operationId: reject_requests + requestBody: + content: + application/json: + schema: + type: object + properties: + params: + type: object + properties: + type: + type: string + enum: + - import + - create + addresses: + type: array + items: + $ref: '#/components/schemas/base58-address' + required: + - type + - addresses + allOf: + - $ref: '#/components/schemas/auth' + required: + - params + required: true + responses: + '200': + description: Success + content: + application/json: + schema: + $ref: '#/components/schemas/updated' + '400': + description: Invalid JSON. + '403': + description: Invalid `auth` parameter + '405': + description: Not `POST` method. + '500': + description: Invalid JSON schema, and all other general errors. + '503': + description: Unable to read or write from database. + /rescan: + post: + tags: + - account + summary: Force account(s) rescan from specific block height + operationId: rescan + requestBody: + content: + application/json: + schema: + type: object + properties: + params: + type: object + properties: + height: + $ref: '#/components/schemas/uint64' + addresses: + type: array + items: + $ref: '#/components/schemas/base58-address' + required: + - height + - addresses + allOf: + - $ref: '#/components/schemas/auth' + required: + - params + required: true + responses: + '200': + description: Success + content: + application/json: + schema: + $ref: '#/components/schemas/updated' + '400': + description: Invalid JSON. + '403': + description: Invalid `auth` parameter + '405': + description: Not `POST` method. + '500': + description: Invalid JSON schema, and all other general errors. + '503': + description: Unable to read or write from database. + /validate: + post: + summary: Validate components of a Monero wallet + operationId: validate + requestBody: + content: + application/json: + schema: + type: object + properties: + params: + type: object + properties: + spend_public_hex: + $ref: '#/components/schemas/binary32' + view_public_hex: + $ref: '#/components/schemas/binary32' + view_key_hex: + $ref: '#/components/schemas/binary32' + required: + - spend_public_hex + - view_public_hex + - view_key_hex + allOf: + - $ref: '#/components/schemas/auth' + required: + - params + required: true + responses: + '200': + description: Success + content: + application/json: + schema: + oneOf: + - type: object + properties: + address: + $ref: '#/components/schemas/base58-address' + required: + - address + - type: object + properties: + error: + type: object + properties: + field: + type: string + enum: + - spend_public_hex + - view_public_hex + - view_key_hex + details: + type: string + required: + - field + - details + required: + - error + '400': + description: Invalid JSON. + '403': + description: Invalid `auth` parameter + '405': + description: Not `POST` method. + '500': + description: Invalid JSON schema, and all other general errors. + /webhook_add: + post: + tags: + - webhook + summary: List all pending create+import requests + operationId: webhook_add + requestBody: + content: + application/json: + schema: + type: object + properties: + params: + oneOf: + - type: object + properties: + type: + type: string + enum: + - tx-confirmation + - tx-spend + url: + $ref: '#/components/schemas/webhook-url' + address: + $ref: '#/components/schemas/base58-address' + payment_id: + $ref: '#/components/schemas/payment-id' + token: + type: string + minLength: 1 + confirmations: + $ref: '#/components/schemas/uint32' + required: + - type + - url + - address + - type: object + properties: + type: + type: string + enum: + - new-account + url: + $ref: '#/components/schemas/webhook-url' + token: + type: string + minLength: 1 + required: + - type + - url + allOf: + - $ref: '#/components/schemas/auth' + required: + - params + required: true + responses: + '200': + description: Success + content: + application/json: + schema: + $ref: '#/components/schemas/webhook-value' + '400': + description: Invalid JSON. + '403': + description: Invalid `auth` parameter + '405': + description: Not `POST` method. + '500': + description: Invalid JSON schema, invalid URL, and all other general errors. + '503': + description: Unable to read or write from database. + callbacks: + onEvent: + '{$requestBody.params.url}': + post: + requestBody: + content: + application/json: + schema: + oneOf: + - type: object + description: Sent on tx-confirmation events + properties: + payment_id: + $ref: '#/components/schemas/payment-id' + token: + description: "The same token passed in the initial request" + type: string + confirmations: + $ref: '#/components/schemas/uint32' + event_id: + $ref: '#/components/schemas/uuid' + tx_info: + $ref: '#/components/schemas/tx-output' + required: + - payment_id + - token + - confirmations + - event_id + - tx_info + - type: object + description: Sent on tx-spend events + properties: + token: + description: "The same token passed in the initial request" + type: string + event_id: + $ref: '#/components/schemas/uuid' + tx_info: + $ref: '#/components/schemas/tx-spend' + required: + - token + - event_id + - tx_info + - type: object + description: Sent on new-account events + properties: + token: + description: "The same token passed in the initial request" + type: string + event_id: + $ref: '#/components/schemas/uuid' + address: + $ref: '#/components/schemas/base58-address' + required: + - token + - event_id + - address + + responses: + 201: + description: On success + /webhook_delete: + post: + tags: + - webhook + summary: Delete webhooks associated with Monero address(es) + operationId: webhook_delete + requestBody: + content: + application/json: + schema: + type: object + properties: + params: + type: object + properties: + addresses: + type: array + items: + $ref: '#/components/schemas/base58-address' + required: + - addresses + allOf: + - $ref: '#/components/schemas/auth' + required: + - params + required: true + responses: + '200': + description: Success + content: + application/json: + schema: + type: object + '400': + description: Invalid JSON. + '403': + description: Invalid `auth` parameter + '405': + description: Not `POST` method. + '500': + description: Invalid JSON schema, and all other general errors. + '503': + description: Unable to read or write from database. + /webhook_delete_uuid: + post: + tags: + - webhook + summary: Delete webhooks associated with UUID(s) + operationId: webhook_delete_uuid + requestBody: + content: + application/json: + schema: + type: object + properties: + params: + type: object + properties: + event_ids: + type: array + items: + $ref: '#/components/schemas/uuid' + required: + - event_ids + allOf: + - $ref: '#/components/schemas/auth' + required: + - params + required: true + responses: + '200': + description: Success + content: + application/json: + schema: + type: object + '400': + description: Invalid JSON. + '403': + description: Invalid `auth` parameter + '405': + description: Not `POST` method. + '500': + description: Invalid JSON schema, and all other general errors. + '503': + description: Unable to read or write from database. + /webhook_list: + post: + tags: + - webhook + summary: List all registered webhooks + operationId: webhook_list + requestBody: + content: + application/json: + schema: + type: object + allOf: + - $ref: '#/components/schemas/auth' + required: + - params + required: true + responses: + '200': + description: Success + content: + application/json: + schema: + type: object + properties: + webhooks: + type: object + properties: + key: + type: object + properties: + user: + $ref: '#/components/schemas/uint32' + type: + type: string + enum: + - tx-confirmation + - tx-send + - new-account + value: + $ref: '#/components/schemas/webhook-value' + required: + - key + - value + required: + - webhooks + '400': + description: Invalid JSON. + '403': + description: Invalid `auth` parameter + '405': + description: Not `POST` method. + '500': + description: Invalid JSON schema, and all other general errors. + '503': + description: Unable to read from database. +components: + schemas: + uint16: + type: integer + minimum: 0 + maximum: 65535 + uint32: + type: integer + minimum: 0 + maximum: 4294967295 + int64: + type: integer + minimum: -9223372036854775808 + maximum: 9223372036854775807 + uint64: + type: integer + minimum: 0 + maximum: 18446744073709551615 + timestamp: + description: Seconds since Unix epoch (1970-01-01 00:00:00) + allOf: + - $ref: '#/components/schemas/int64' + base58-address: + type: string + description: "Standard Monero address in base58" + minLength: 95 + maxLength: 95 + pattern: "^[0-9A-Za-z]{95}$" + example: "47nPhxp2cJeKN2NjamupNUNA13XgzcYPzQBCzzsKcj717s8M2UpFVmmdwSuYwgyy8kPDwU7hpEqTTDvfe5LAb9Aj6nwmEzf" + binary: + type: string + description: "binary data as hex (arbitrary length)" + pattern: "^([0-9A-Fa-f]{2})+$" + example: "0abcd9dcf0bca63310bb4d7e120918d1" + binary8: + type: string + description: "8-bytes binary data as hex" + minLength: 16 + maxLength: 16 + pattern: "^[0-9A-Fa-f]{16}$" + example: "6d26cac5c9d74f4e" + binary16: + type: string + description: "16-bytes binary data as hex" + minLength: 32 + maxLength: 32 + pattern: "^[0-9A-Fa-f]{32}$" + example: "67adfa30c9504e12955b9ae3ad3cd53b" + binary32: + type: string + description: "32-bytes binary data as hex" + minLength: 64 + maxLength: 64 + pattern: "^[0-9A-Fa-f]{64}$" + example: "ee171270296bbc26d5be4455b6313e1a2086a92080e205f77d6f861f8e5fd205" + payment-id: + $ref: '#/components/schemas/binary8' + uuid: + description: "A randomly generated, _unique_, UUID" + allOf: + - $ref: '#/components/schemas/binary16' + webhook-url: + description: A HTTP address OR `zmq` to indicate the notification happens over ZMQ PUB/SUB only. + type: string + pattern: "^(zmq|http://.+|https://.+)$" + auth: + type: object + properties: + auth: + description: | + A key generated via `./monero-lws-admin create_admin`. Not needed if server is started with `--disable-admin-auth`. + allOf: + - $ref: '#/components/schemas/binary32' + address-meta: + description: Subaddress index + type: object + properties: + maj_i: + $ref: '#/components/schemas/uint32' + min_i: + $ref: '#/components/schemas/uint32' + required: + - maj_i + - min_i + updated: + description: List of updated addresses + type: object + properties: + updated: + type: array + items: + $ref: '#/components/schemas/base58-address' + required: + - updated + account: + type: object + properties: + address: + $ref: '#/components/schemas/base58-address' + scan_height: + $ref: '#/components/schemas/uint64' + access_time: + $ref: '#/components/schemas/timestamp' + required: + - address + - scan_height + - access_time + account-request: + type: object + properties: + address: + $ref: '#/components/schemas/base58-address' + start_height: + $ref: '#/components/schemas/uint64' + required: + - address + - start_height + tx-output-id: + description: Blockchain unique identifier for the output. Changes on reorg. + type: object + properties: + high: + $ref: '#/components/schemas/uint32' + low: + $ref: '#/components/schemas/uint32' + required: + - high + - low + tx-spend-meta: + type: object + properties: + id: + $ref: '#/components/schemas/tx-output-id' + amount: + $ref: '#/components/schemas/uint64' + mixin: + $ref: '#/components/schemas/uint32' + index: + description: Index within vout, required for calculating spend key + allOf: + - $ref: '#/components/schemas/uint32' + tx_public: + description: The ephermal key used for the ECDH portion of transaction scanning + allOf: + - $ref: '#/components/schemas/binary32' + required: + - id + - amount + - mixin + - index + - tx_public + tx-output: + type: object + allOf: + - $ref: '#/components/schemas/tx-spend-meta' + properties: + block: + $ref: '#/components/schemas/uint64' + timestamp: + $ref: '#/components/schemas/timestamp' + tx_hash: + $ref: '#/components/schemas/binary32' + tx_prefix_hash: + $ref: '#/components/schemas/binary32' + rct_mask: + description: The encrypted ringct mask associated with output + allOf: + - $ref: '#/components/schemas/binary32' + payment_id: + $ref: '#/components/schemas/payment-id' + unlock_time: + $ref: '#/components/schemas/uint64' + mixin_count: + $ref: '#/components/schemas/uint32' + coinbase: + type: boolean + pub: + description: The unique public key for the output (which must be used in signature for spending) + allOf: + - $ref: '#/components/schemas/binary32' + recipient: + $ref: '#/components/schemas/address-meta' + required: + - block + - timestamp + - tx_hash + - tx_prefix_hash + - unlock_time + - mixin_count + - coinbase + - pub + - recipient + tx-spend: + type: object + properties: + input: + type: object + properties: + height: + $ref: '#/components/schemas/uint64' + tx_hash: + $ref: '#/components/schemas/binary32' + image: + $ref: '#/components/schemas/binary32' + source: + $ref: '#/components/schemas/tx-output-id' + timestamp: + $ref: '#/components/schemas/timestamp' + unlock_time: + $ref: '#/components/schemas/uint64' + mixin_count: + $ref: '#/components/schemas/uint32' + payment_id: + $ref: '#/components/schemas/payment-id' + sender: + $ref: '#/components/schemas/address-meta' + required: + - height + - tx_hash + - image + - source + - timestamp + - unlock_time + - mixin_count + - sender + output: + $ref: '#/components/schemas/tx-spend-meta' + required: + - input + - source + webhook-value: + type: object + properties: + event_id: + $ref: '#/components/schemas/uuid' + payment_id: + description: The `payment_id` sent in the request or all zeroes. + allOf: + - $ref: '#/components/schemas/payment-id' + token: + description: The token sent in the request or empty string. + type: string + confirmations: + description: The confirmations value sent in the request or `1`. + allOf: + - $ref: '#/components/schemas/uint32' + url: + description: The URL sent in the request. + allOf: + - $ref: '#/components/schemas/webhook-url' + required: + - event_id + - payment_id + - token + - confirmations + - url diff --git a/docs/rmq.md b/docs/api/rmq.md similarity index 95% rename from docs/rmq.md rename to docs/api/rmq.md index 66bbd14..470e7c8 100644 --- a/docs/rmq.md +++ b/docs/api/rmq.md @@ -1,5 +1,5 @@ -# monero-lws RabbitMQ Usage -Monero-lws uses RabbitMQ to provide JSON notifications of payment_id +# RabbitMQ +`monero-lws-daemon` uses RabbitMQ to provide JSON notifications of payment_id (web)hooks. The feature is optional - by default LWS is _not_ compiled with RabbitMQ support. The cmake option -DWITH_RMQ=ON must be specified during the configuration stage to enable the feature. diff --git a/docs/api/wallet.md b/docs/api/wallet.md new file mode 100644 index 0000000..52ede48 --- /dev/null +++ b/docs/api/wallet.md @@ -0,0 +1 @@ + diff --git a/docs/api/wallet.yaml b/docs/api/wallet.yaml new file mode 100644 index 0000000..564fba5 --- /dev/null +++ b/docs/api/wallet.yaml @@ -0,0 +1,1210 @@ +openapi: 3.0.4 +info: + title: Monero Light-Wallet-Server (LWS) API + description: |- + This document describes the wallet API provided by the [monero-lws](https://github.com/vtnerd/monero-lws) 1.0 alpha release. This API is fully compatible with the [community API](https://github.com/monero-project/meta/blob/master/api/lightwallet_rest.md), but adds some additional functionality: + * The [subaddress provisioning draft](https://github.com/monero-project/meta/pull/647) is implemented + * The [subaddress lookahead draft](https://github.com/monero-project/meta/pull/1228) is implemented + * A not proposed convenience endpoint `/daemon_status` is provided + + The additional functionality adds features, but does not interfere with the community API. + + version: 2.0.0 +externalDocs: + description: A markdown file, if more readable + url: https://github.com/monero-project/meta/blob/master/api/lightwallet_rest.md +tags: + - name: account + - name: subaddress + - name: transaction +paths: + /get_address_info: + post: + tags: + - transaction + summary: Calculate account balance + description: | + Returns the minimal set of information needed to calculate a wallet balance, including the balance of subaddresses. The server cannot calculate when a spend occurs without the spend key, so a list of candidate spends is returned. + operationId: get_address_info + requestBody: + description: Provide `view_key`/`address` pair + content: + application/json: + schema: + $ref: '#/components/schemas/login' + required: true + responses: + '200': + description: Success + content: + application/json: + schema: + type: object + properties: + locked_funds: + #description: Sum of unspendable XMR + $ref: '#/components/schemas/uint64-string' + total_received: + #description: Sum of received XMR + $ref: '#/components/schemas/uint64-string' + total_sent: + description: Sum of possibly spent XMR + allOf: + - $ref: '#/components/schemas/uint64-string' + scanned_height: + description: Current tx (tx_id) scan progress + allOf: + - $ref: '#/components/schemas/uint64' + scanned_block_height: + description: Current block scan progress + allOf: + - $ref: '#/components/schemas/uint64' + start_height: + #description: Start height of response + $ref: '#/components/schemas/uint64' + transaction_height: + description: Total transactions sent in Monero + allOf: + - $ref: '#/components/schemas/uint64' + blockchain_height: + #description: Current blockchain height + $ref: '#/components/schemas/uint64' + spent_outputs: + description: Possible spend info + type: array + items: + $ref: '#/components/schemas/spend' + lookahead: + description: The lookahead state, or {0, 0} if not provided + allOf: + - $ref: '#/components/schemas/address_meta' + lookahead_failure: + description: If provided, the block number subaddress lookahead failed + allOf: + - $ref: '#/components/schemas/uint64' + rates: + $ref: '#/components/schemas/rates' + required: + - locked_funds + - total_received + - total_sent + - scanned_height + - scanned_block_height + - start_height + - transaction_height + - blockchain_height + - spent_outputs + '400': + description: Invalid JSON, or invalid base58 address. + '403': + description: Account is disabled, or does not exist. + '405': + description: Not `POST` method. + '500': + description: Invalid JSON schema, and all other general errors. + '503': + description: Unable to read from database. + /get_address_txs: + post: + tags: + - transaction + summary: Get transaction history + description: | + 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. + operationId: get_address_txs + requestBody: + description: | + Provide `view_key`/`address` pair, with optional filtering of already seen transactions. + + `since_tx_id` and `since_tx_block_hash` may be omitted, in which case all transactions are returned. If `since_tx_id` is present, `since_tx_block_hash` must be, too. The latter is used to handle the case when a blockchain reorg has rendered the requested `since_tx_id` invalid. Clients must take care to honor the `since_tx_id` returned in the response, which may be different than the value that was in the request. + content: + application/json: + schema: + type: object + allOf: + - $ref: '#/components/schemas/login' + properties: + since_tx_id: + description: Most recent tx already known to client + allOf: + - $ref: '#/components/schemas/uint64' + since_tx_block_hash: + description: Block hash of most recent tx + allOf: + - $ref: '#/components/schemas/binary32' + required: true + responses: + '200': + description: | + Success + + `since_tx_id` may be omitted, and shall be omitted if omitted in the request. If present, it indicates that this response includes only transactions with an `id` greater than this one. It may be different than the value in the `request`: if a blockchain reorg has rendered the requested id/block_hash pair invalid, then some or all of the prior transaction history must be present. Clients must remove all newer transactions from their local history before appending the ones from this response. If null or omitted, the response contains every transaction. + content: + application/json: + schema: + type: object + properties: + total_received: + #description: Sum of received outputs + $ref: '#/components/schemas/uint64-string' + scanned_height: + description: Current tx (txid) scan progress + allOf: + - $ref: '#/components/schemas/uint64' + scanned_block_height: + description: Current scan progress + allOf: + - $ref: '#/components/schemas/uint64' + start_height: + #description: Start height of response + $ref: '#/components/schemas/uint64' + blockchain_height: + #description: Current blockchain height + $ref: '#/components/schemas/uint64' + transactions: + description: Possible spend info + type: array + items: + $ref: '#/components/schemas/transaction' + lookahead: + description: The lookahead state, or {0, 0} if not provided + allOf: + - $ref: '#/components/schemas/address_meta' + lookahead_failure: + description: If provided, the block number subaddress lookahead failed + allOf: + - $ref: '#/components/schemas/uint64' + since_tx_id: + description: Most recent omitted tx + allOf: + - $ref: '#/components/schemas/uint64' + required: + - total_received + - scanned_height + - scanned_block_height + - start_height + - transaction_height + - blockchain_height + - transactions + '400': + description: Invalid JSON, or invalid base58 address. + '403': + description: Account is disabled or does not exist. + '405': + description: Not `POST` method. + '500': + description: Invalid JSON schema, and general errors. + '503': + description: Unable to read from database. + /get_random_outs: + post: + tags: + - transaction + summary: Get server constructed rings + description: | + 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))`). + operationId: get_random_outs + requestBody: + content: + application/json: + schema: + type: object + properties: + count: + description: Mixin (name is historical) + allOf: + - $ref: '#/components/schemas/uint32' + amounts: + description: XMR amounts that need mixing + type: array + items: + $ref: '#/components/schemas/uint64-string' + required: + - count + - amounts + required: true + responses: + '200': + description: Success + content: + application/json: + schema: + type: object + properties: + amount_outs: + description: Decoy outputs for each amounts + type: array + items: + $ref: '#/components/schemas/random_outputs' + required: + - amount_outs + '400': + description: Invalid JSON. + '405': + description: Not `POST` method. + '500': + description: Invalid JSON schema, and general errors. + '503': + description: Unable to contact monero daemon. + /get_subaddrs: + post: + tags: + - subaddress + summary: Returns all subaddresses provisioned for a wallet + operationId: get_subaddrs + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/login' + required: true + responses: + '200': + description: Success + content: + application/json: + schema: + type: object + properties: + all_subaddrs: + $ref: '#/components/schemas/subaddrs' + max_subaddrs: + description: Maximum number of subaddresses permitted by server + allOf: + - $ref: '#/components/schemas/uint64' + required: + - all_subaddrs + '400': + description: Invalid JSON, or invalid base58 address. + '403': + description: Account is disabled or does not exist. + '405': + description: Not `POST` method + '409': + description: Unable to provision subaddresses due to server limits. + '500': + description: Invalid JSON schema, and general errors. + '503': + description: Unable to read from database. + /get_tree_path: + post: + tags: + - transaction + summary: Get all information needed to build a tree cache for fmcp++ signing + operationId: get_tree_path + requestBody: + content: + application/json: + schema: + type: object + properties: + output_ids: + type: array + items: + $ref: '#/components/schemas/composite_id' + required: [output_ids] + required: true + responses: + '200': + description: Success + content: + application/json: + schema: + type: object + properties: + paths: + type: array + items: + $ref: '#/components/schemas/path_spend' + last_path: + $ref: '#/components/schemas/path' + top_block_height: + $ref: '#/components/schemas/uint64' + n_leaf_tuples: + $ref: '#/components/schemas/uint64' + top_block_hash: + $ref: '#/components/schemas/binary32' + required: + - paths + - last_path + - top_block_height + - n_leaf_tuples + - top_block_hash + '400': + description: Invalid JSON, invalid base58 address, or invalid composite_id + '405': + description: Not `POST` method + '500': + description: Invalid JSON schema, and general errors. + '503': + description: Unable to read from database. + /get_unspent_outs: + post: + tags: + - transaction + summary: Get data for needed for sending transaction. + description: Returns a list of received outputs. The client must determine when the output was actually spent. + operationId: get_unspent_outs + requestBody: + content: + application/json: + schema: + type: object + allOf: + - $ref: '#/components/schemas/login' + properties: + amount: + description: XMR send amount + allOf: + - $ref: '#/components/schemas/uint64' + mixin: + description: Minimum mixin for source output + allOf: + - $ref: '#/components/schemas/uint32' + use_dust: + description: Return all available outputs + type: boolean + dust_threshold: + description: Ignore outputs below this amount + allOf: + - $ref: '#/components/schemas/uint64-string' + lookahead_failure: + description: If provided, the block number subaddress lookahead failed + allOf: + - $ref: '#/components/schemas/uint64' + required: + - height + - mixin + - use_dust + required: true + responses: + '200': + description: Success + content: + application/json: + schema: + type: object + properties: + per_byte_fee: + description: Estimated network fee (deprecated) + allOf: + - $ref: '#/components/schemas/uint64-string' + fee_mask: + description: Fee quantization mask + allOf: + - $ref: '#/components/schemas/uint64-string' + amount: + description: The total value in outputs + allOf: + - $ref: '#/components/schemas/uint64-string' + outputs: + description: Outputs possibly available for spending + type: array + items: + $ref: '#/components/schemas/output' + fees: + description: Priority based fee levels, starting with lowest + type: array + minItems: 1 + items: + $ref: '#/components/schemas/uint64' + required: + - per_byte_fee + - fee_mask + - amount + - outputs + '400': + description: Invalid JSON, or invalid base58 address. + '403': + description: Account is disabled or does not exist. + '405': + description: Not `POST` method. + '500': + description: Invalid JSON schema, and general errors. + '503': + description: Unable to read from database or unable to get monero daemon fee. + /get_version: + get: + summary: Get basic information about Server + operationId: get_version + responses: + '200': + description: Succeeded + content: + application/json: + schema: + type: object + properties: + server_type: + type: string + description: Name of server implementation + last_git_commit_hash: + description: A hash (of server determined length) corresponding to commit hash + allOf: + - $ref: '#/components/schemas/binary' + last_commit_date: + type: string + description: Implementation defined commit date + monero_version_full: + description: Implementation defined version string + type: string + blockchain_height: + description: Current blockchain height (as processed by LWS server) + allOf: + - $ref: '#/components/schemas/uint64' + api: + description: Unique number per schema Implementation + type: integer + max_subaddresses: + description: Max subaddresses allowed by server + type: integer + network: + description: Name of network type + type: string + testnet: + type: boolean + /import_wallet_request: + post: + tags: + - account + summary: Restore from height with optional subaddress lookahead + operationId: import_wallet_request + requestBody: + description: Provide `view_key`/`address` pair + content: + application/json: + schema: + description: | + If `height` is omitted, then it assumed to be `0`. If lookahead is omitted, it assumed to be `{0, 0}`. + type: object + allOf: + - $ref: '#/components/schemas/login' + properties: + from_height: + $ref: '#/components/schemas/uint64' + lookahead: + description: "Desired lookahead for (re)scan" + allOf: + - $ref: '#/components/schemas/address_meta' + required: true + responses: + '200': + description: "`payment_id`, `import_fee`, and `payment_address` may be omitted if the client does not need to send XMR to complete the request." + content: + application/json: + schema: + type: object + properties: + payment_address: + description: Payment location to enable rescan + allOf: + - $ref: '#/components/schemas/base58-address' + payment_id: + description: Bytes for payment_id field to track rescan + allOf: + - $ref: '#/components/schemas/binary8' + import_fee: + description: Fee required to complete request + allOf: + - $ref: '#/components/schemas/uint64-string' + new_request: + description: "New or existing request" + type: boolean + request_fulfilled: + description: Indicates success + type: boolean + status: + description: Custom message + type: string + example: "OK" + lookahead: + description: The lookahead state, or {0, 0} if not provided + allOf: + - $ref: '#/components/schemas/address_meta' + required: + - new_request + - request_fulfilled + - status + '400': + description: Invalid JSON, or invalid base58 address. + '403': + description: Account is disabled or does not exist + '405': + description: Not `POST` method + '500': + description: Invalid JSON schema, and general errors + '503': + description: Unable to read from database + /login: + post: + tags: + - account + summary: Create and check account status + description: | + The `view_key` bytes are required even if an account is not being created, to prevent metadata leakage. + operationId: login + requestBody: + description: Provide `view_key`/`address` pair + content: + application/json: + schema: + allOf: + - $ref: '#/components/schemas/login' + properties: + create_account: + type: boolean + description: True when account creation should be attempted + generated_locally: + type: boolean + description: True if the account is new (not restored/imported) + lookahead: + description: "Desired lookahead for new accounts" + allOf: + - $ref: '#/components/schemas/address_meta' + required: + - create_account + - generated_locally + required: true + responses: + '200': + description: Success + content: + application/json: + schema: + type: object + properties: + new_address: + description: Whether account was just created + type: boolean + generated_locally: + description: Flag from initial account creation + type: boolean + start_height: + description: Account scanning start block + allOf: + - $ref: '#/components/schemas/uint64' + lookahead: + description: The lookahead state, or {0, 0} if not provided + allOf: + - $ref: '#/components/schemas/address_meta' + required: + - new_address + '400': + description: Invalid JSON, or invalid base58 address. + '403': + description: "`view_key`/`address` pair is invalid" + '405': + description: Not `POST` method. + '500': + description: Invalid JSON schema, and general errors. + '501': + description: Account creation is not allowed. + '503': + description: Unable to read or write from database. + /provision_subaddrs: + post: + tags: + - subaddress + summary: Request new sub address ranges + description: | + Provision subaddresses at specified indexes. No two clients should ever receive the same newly provisioned subaddresses when calling this endpoint; the server should guarantee that newly provisioned subaddresses are fresh. + operationId: provision_subaddrs + requestBody: + content: + application/json: + schema: + description: | + The various combinations of `maj_i`, `min_i`, `n_maj`, and `n_min` behave differently, but generally the server provisions subaddresses where it has not already provisioned them, with the indexes specified as lower bounds. If, for example, only `maj_i` is included, then the server should provision a default number of minor subaddresses (e.g. 500) within that `maj_i`, wherever minor subaddresses have not already been provisioned, starting with `min_i` set to 0 as the lower bound. + + If, for example, `maj_i`, `min_i`, `n_maj` and `n_min` are included, then the server should provision `n_maj` majors wherever major subaddresses have not already been provisioned starting with `maj_i` as the lower bound, and for each major, provision `n_min` subaddresses starting with `min_i` as the lower bound. + + If, for example, `maj_i`, `min_i`, `n_maj` and `n_min` are included, then the server should provision `n_maj` majors wherever major subaddresses have not already been provisioned starting with `maj_i` as the lower bound, and for each major, provision `n_min` subaddresses starting with `min_i` as the lower bound. + + All combinations follow the above framework. The server can choose to "pad" counts and provision *more* than a client requests. + + If the server cannot provision a specified number of subaddresses because the server would provision more than the maximum number of subaddresses, HTTP 409 should be returned. Ack that the status code is not perfect here. In this case, the client should make a new request either with a smaller requested number of subaddresses to provision, or at a different major or minor index. If none of `maj_i`, `min_i`, `n_maj`, and `n_min` are included in the request, the server must return a HTTP 400 "Bad Request" error. `get_all` defaults to true if not included in the request. + type: object + allOf: + - $ref: '#/components/schemas/login' + properties: + maj_i: + description: Subaddress major index (defaults to 0) + allOf: + - $ref: '#/components/schemas/uint32' + min_i: + description: Subaddress minor index (defaults to 0) + allOf: + - $ref: '#/components/schemas/uint32' + n_maj: + description: Number of major subaddresses to provision + allOf: + - $ref: '#/components/schemas/uint32' + n_min: + description: Number of minor subaddresses to provision + allOf: + - $ref: '#/components/schemas/uint32' + get_all: + description: Whether to include all subaddresses in response. Defaults to true. + type: boolean + required: true + responses: + '200': + description: Success + content: + application/json: + schema: + $ref: '#/components/schemas/new_subaddrs' + '400': + description: Invalid JSON, or invalid base58 address. + '403': + description: Account is disabled or does not exist. + '405': + description: Not `POST` method. + '409': + description: Unable to provision subaddresses due to server limits. + '500': + description: Invalid JSON schema, and general errors. + '503': + description: Unable to read or write from database + /submit_raw_tx: + post: + tags: + - transaction + summary: Send a transaction to the Monero network + description: | + 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. + operationId: submit_raw_tx + requestBody: + description: Provide `view_key`/`address` pair + content: + application/json: + schema: + type: object + properties: + tx: + $ref: '#/components/schemas/binary' + required: + - tx + required: true + responses: + '200': + description: Success + content: + application/json: + schema: + type: object + properties: + status: + description: Typically the response by the monero daemon attempting to relay the transaction. + type: string + example: "OK" + required: + - status + '400': + description: Invalid JSON. + '405': + description: Not `POST` method. + '500': + description: Invalid JSON schema, and general errors. + '503': + description: Unable to communicate with monero daemon. + /upsert_subaddrs: + post: + tags: + - subaddress + summary: Upsert new subaddresses + description: | + Upsert subaddresses at the specified major and minor indexes. This endpoint is idempotent. + operationId: upsert_subaddrs + requestBody: + content: + application/json: + schema: + type: object + allOf: + - $ref: '#/components/schemas/login' + properties: + subaddrs: + description: Subaddresses to upsert + type: array + minItems: 1 + items: + $ref: '#/components/schemas/subaddrs' + get_all: + description: Whether to include all subaddresses in response. Defaults to true + type: boolean + required: + - subaddrs + required: true + responses: + '200': + description: Success + content: + application/json: + schema: + $ref: '#/components/schemas/new_subaddrs' + '400': + description: Invalid JSON. + '403': + description: Account is disabled or does not exist + '405': + description: Not `POST` method + '409': + description: Unable to provision subaddresses due to server limits + '500': + description: Invalid JSON schema, and general errors + '503': + description: Unable to read from database +components: + schemas: + base58-address: + type: string + description: "Standard Monero address in base58" + minLength: 95 + maxLength: 95 + pattern: "^[0-9A-Za-z]{95}$" + example: "47nPhxp2cJeKN2NjamupNUNA13XgzcYPzQBCzzsKcj717s8M2UpFVmmdwSuYwgyy8kPDwU7hpEqTTDvfe5LAb9Aj6nwmEzf" + binary: + type: string + description: "binary data as hex (arbitrary length)" + pattern: "^([0-9A-Fa-f]{2})+$" + example: "0abcd9dcf0bca63310bb4d7e120918d1" + binary8: + type: string + description: "8-bytes binary data as hex" + minLength: 16 + maxLength: 16 + pattern: "^[0-9A-Fa-f]{16}$" + example: "6d26cac5c9d74f4e" + binary32: + type: string + description: "32-bytes binary data as hex" + minLength: 64 + maxLength: 64 + pattern: "^[0-9A-Fa-f]{64}$" + example: "ee171270296bbc26d5be4455b6313e1a2086a92080e205f77d6f861f8e5fd205" + ringct-packed: + type: string + description: | + A "packed" hex struct containing: commitment|mask|amount. Only the 'mask' is needed, as the amount is already sent, and the commitment can be re-computed from the mask and amount. This format is used for legacy purposes. + pattern: "^[0-9A-Fa-f]{192}$" + example: "09e732db4d2154dcd79eff818d105184dcf8223ecbfeb64d4673334756ca9433a28dcc2511cb636dc836722f4f54f97e7a84d7aed012798a8f65229004e6dc299500de68879730a32933bd4df0a3a5927149ea8f678e42cbd863c166c73c920d" + ringct-random: + type: string + description: | + The first 64-bytes are the hex of the ringct commitment. The next 64-bytes are optionally sent (for legacy purposes), but still required to be hex. + pattern: "^[0-9A-Fa-f]{64}([0-9A-Fa-f]{128}){0,1}$" + example: "09e732db4d2154dcd79eff818d105184dcf8223ecbfeb64d4673334756ca9433" + payment-id: + description: 8-Byte encrypted payment-id or 32-byte unencrypted payment-id (deprecated) + oneOf: + - $ref: '#/components/schemas/binary8' + - $ref: '#/components/schemas/binary32' + uint64-string: + type: string + description: An unsigned 64-bit value encoded as a string + pattern: "^[1-9][0-9]{0,19}$" + minLength: 1 + maxLength: 20 + example: "10" + uint16: + type: integer + minimum: 0 + maximum: 65535 + uint32: + type: integer + minimum: 0 + maximum: 4294967295 + uint64: + type: integer + minimum: 0 + maximum: 18446744073709551615 + timestamp: + description: "'YYYY-MM-DDTHH:MM:SSZ' in UTC/Zulu timezone. No sub-subseconds" + type: string + pattern: "^[0-9]{4}-[0-9]{2}-[0-9]{2}:[0-9]{2}:[0-9]{2}:[0-9]{2}Z$" + example: "2025-06-29T20:44:32Z" + login: + type: object + properties: + address: + $ref: '#/components/schemas/base58-address' + view_key: + $ref: '#/components/schemas/binary32' + required: + - address + - view_key + address_meta: + type: object + description: A subaddress meta block (major, minor) index + properties: + maj_i: + $ref: '#/components/schemas/uint32' + min_i: + $ref: '#/components/schemas/uint32' + required: + - maj_i + - min_i + index_range: + description: | + The first element is the inclusive lower bound of the range. The second element is the inclusive upper bound of the range. The second element is greater than or equal to the first element. + type: array + minItems: 2 + maxItems: 2 + items: + $ref: '#/components/schemas/uint32' + legacy_id: + type: object + description: Specify an output using pre-fcmp++ indexing + properties: + amount: + $ref: '#/components/schemas/uint64' + index: + $ref: '#/components/schemas/uint64' + composite_id: + type: object + description: Specify an output using pre or post fcmp++ indexing + oneOf: + - + type: object + properties: + legacy: + $ref: '#/components/schemas/legacy_id' + - + type: object + properties: + unified: + $ref: '#/components/schemas/uint64' + output_pair: + type: object + description: The public-keys related to an output + properties: + output_pubkey: + $ref: '#/components/schemas/binary32' + commitment: + $ref: '#/components/schemas/binary32' + leaf: + type: object + description: Called `OutputContext` in Monero codebase + properties: + output_id: + description: Unified (post fcmp++) output identifier + allOf: + - $ref: '#/components/schemas/uint64' + torsion_checked: + type: boolean + description: True if checked for (lack of) Torsion point + output_pair: + $ref: '#/components/schemas/output_pair' + chunk: + type: object + properties: + chunk_bytes: + description: Curve points in the tree path + type: array + items: + $ref: '#/components/schemas/binary32' + path: + type: object + properties: + leaves: + type: array + items: + $ref: '#/components/schemas/leaf' + layer_chunks: + type: array + items: + $ref: '#/components/schemas/chunk' + path_spend: + type: object + properties: + path: + $ref: '#/components/schemas/path' + output_id: + $ref: '#/components/schemas/composite_id' + leaf_idx: + $ref: '#/components/schemas/uint64' + subaddrs: + description: | + Key is the major index of Monero subaddresses, values are the minor indexes of subaddresses within that major index. + type: object + properties: + key: + $ref: '#/components/schemas/uint32' + value: + type: array + minItems: 1 + items: + $ref: '#/components/schemas/index_range' + required: + - key + - value + new_subaddrs: + type: object + properties: + new_subaddrs: + #description: All new subaddresses provisioned in the request + $ref: '#/components/schemas/subaddrs' + all_subaddrs: + #descriptiopn: All subaddresses provisioned for the wallet (including new) + $ref: '#/components/schemas/subaddrs' + required: + - new_subaddrs + output: + type: object + properties: + tx_id: + #description: "Index of tx in blockchain" + $ref: '#/components/schemas/uint64' + amount: + #description: "XMR value of output" + $ref: '#/components/schemas/uint64-string' + index: + description: Index within vout vector + allOf: + - $ref: '#/components/schemas/uint16' + global_index: + description: Index within amount (determined by blockchain order) + allOf: + - $ref: '#/components/schemas/uint64-string' + rct: + $ref: '#/components/schemas/ringct-packed' + tx_hash: + #description: "Bytes of tx hash" + $ref: '#/components/schemas/binary32' + tx_prefix_hash: + #description: "Bytes of tx prefix hash" + $ref: '#/components/schemas/binary32' + public_key: + #description: "Bytes of output public key" + $ref: '#/components/schemas/binary32' + tx_pub_key: + description: Bytes of the ephermal tx public key + allOf: + - $ref: '#/components/schemas/binary32' + spend_key_images: + description: "Bytes of key images" + type: array + items: + $ref: '#/components/schemas/binary32' + timestamp: + $ref: '#/components/schemas/timestamp' + height: + description: Block height + allOf: + - $ref: '#/components/schemas/uint64' + recipient: + $ref: '#/components/schemas/address_meta' + required: + - tx_id + - amount + - index + - global_index + - tx_hash + - tx_prefix_hash + - public_key + - tx_pub_key + - spend_key_images + - timestamp + - height + rates: + description: "Conversion rates into common/popular currencies" + type: object + properties: + AUD: + description: "AUD/XMR exchange rate" + type: number + BRL: + description: "BRL/XMR exchange rate" + type: number + BTC: + description: "BTC/XMR exchange rate" + type: number + CAD: + description: "CAD/XMR exchange rate" + type: number + CHF: + description: "CHF/XMR exchange rate" + type: number + CNY: + description: "CNY/XMR exchange rate" + type: number + EUR: + description: "EUR/XMR exchange rate" + type: number + GBP: + description: "GBP/XMR exchange rate" + type: number + HKD: + description: "HKD/XMR exchange rate" + type: number + INR: + description: "INR/XMR exchange rate" + type: number + JPY: + description: "JPY/XMR exchange rate" + type: number + KRW: + description: "KRW/XMR exhcnage rate" + type: number + MXN: + description: "MXN/XMR exchange rate" + type: number + NOK: + description: "NOK/XMR exchange rate" + type: number + NZD: + description: "NZD/XMR exchange rate" + type: number + SEK: + description: "SEK/XMR exchange rate" + type: number + SGD: + description: "SGD/XMR exchange rate" + type: number + TRY: + description: "TRY/XMR exchange rate" + type: number + USD: + description: "USD/XMR exchange rate" + type: number + RUB: + description: "RUB/XMR exchange rate" + type: number + ZAR: + description: "ZAR/XMR exchange rate" + type: number + spend: + description: | + This object represents a single _possible_ 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. + type: object + properties: + amount: + #description: "XMR possibly being spent" + $ref: '#/components/schemas/uint64-string' + key_image: + #description: "Bytes of the key image" + $ref: '#/components/schemas/binary32' + tx_pub_key: + description: Bytes of the ephermal tx public key + allOf: + - $ref: '#/components/schemas/binary32' + out_index: + description: Index (within vout vector) of source output + allOf: + - $ref: '#/components/schemas/uint16' + mixin: + #description: "Mixin of the spend" + $ref: '#/components/schemas/uint32' + sender: + $ref: '#/components/schemas/address_meta' + required: + - amount + - key_image + - tx_pub_key + - out_index + - mixin + transaction: + description: | + This object represents a single Transaction on the blockchain + + `id` is determined by the monero daemon. It is the offset that a transaction appears in the blockchain from the genesis block. + + `timestamp`, `height` and `block_hash` 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 decoy inputs. + properties: + id: + description: "Index of tx in blockchain" + allOf: + - $ref: '#/components/schemas/uint64' + hash: + #description: "Bytes of tx hash" + $ref: '#/components/schemas/binary32' + timestamp: + $ref: '#/components/schemas/timestamp' + total_received: + #description: "Total XMR received" + $ref: '#/components/schemas/uint64-string' + total_sent: + #description: "XMR possibly being spent" + $ref: '#/components/schemas/uint64-string' + unlock_time: + #description: "Tx unlock time field" + $ref: '#/components/schemas/uint64' + block_hash: + $ref: '#/components/schemas/binary32' + height: + description: Block height + allOf: + - $ref: '#/components/schemas/uint64' + spent_outputs: + description: List of possible spends + type: array + items: + $ref: '#/components/schemas/spend' + payment_id: + $ref: '#/components/schemas/payment-id' + coinbase: + type: boolean + mempool: + type: boolean + mixin: + #description: "Mixin of the receive" + $ref: '#/components/schemas/uint32' + required: + - id + - hash + - total_received + - total_sent + - unlock_time + - spent_outputs + - coinbase + - mempool + - mixin + random_output: + description: | + A single random output, used for generating ring signatures. + + `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. + type: object + properties: + global_index: + description: Index within amount + allOf: + - $ref: '#/components/schemas/uint64-string' + public_key: + #description: "Bytes of output public key" + $ref: '#/components/schemas/binary32' + rct: + #description: "Bytes containing ringct commitment" + $ref: '#/components/schemas/ringct-random' + required: + - global_index + - public_key + random_outputs: + description: | + `outputs` is omitted by the server if the amount does not have enough mixable outputs. + type: object + properties: + amount: + $ref: '#/components/schemas/uint64-string' + outputs: + description: Server selected ring + type: array + items: + $ref: '#/components/schemas/random_output' + required: + - amount + - outputs + diff --git a/docs/api/zmq.md b/docs/api/zmq.md new file mode 100644 index 0000000..4d717a2 --- /dev/null +++ b/docs/api/zmq.md @@ -0,0 +1,154 @@ +# Webhooks / ZeroMQ +monero-lws can report scanner events via HTTP/1.1 webhooks or ZeroMQ PUB/SUB. +The ZeroMQ PUB is distinct from the `monerod` PUB socket; +`monero-lws-daemon --zmq-pub` creates a socket just for `monero-lws-daemon` +scanner updates. Webhooks can be "http" or "https" - the latter performing +standard system certificate authority checks (self-signed certificates NOT +allowed). + +Events are ALWAYS published over ZMQ-PUB, whereas webhooks are only used when +a specific URL is given to `/webhook_add`. If the provided URL is `zmq` then +only ZMQ-PUB is used to push the event. All other URLs must start with +`http://` or `https://` as per [admin api spec](/api/admin). + +## Registration +Registering for events requires `/webhook_add` from the +[admin api](/api/admin). Examples and full schema are provided on that page. + +## Events +Every callback for an event has this structure: +```json +{ + "index": 0, + "event": {...} +} +``` +The `index` field is per event type, and tracks the number of events in that +type. This is useful only for ZeroMQ, where events can be dropped. + +### Payments +A payment event occurs from 0-confirmations up to the user requested number of +confirmations. A payment event, even when using ZeroMQ, only occurs when one is +registered via `/webhook_add`. Payment registerations can only be done on +primary addresses and optionally a payment id. Registering a primary address +automatically registers all subaddresses; specifying a payment id only +registers that payment id. Leaving the payment id field blank during +registeration enables hooks from all payment ids. + +The relevant topics for ZeroMQ-PUB are: `json-full-payment_hook`, and +`msgpack-full-payment_hook`. + +Example payload of a webhook callback: +```json +{ + "index": 2, + "event": { + "event": "tx-confirmation", + "payment_id": "4f695d197f2a3c54", + "token": "single zmq wallet", + "confirmations": 1, + "event_id": "3894f98f5dd54af5857e4f8a961a4e57", + "tx_info": { + "id": { + "high": 0, + "low": 5666768 + }, + "block": 2265961, + "index": 1, + "amount": 3117324236131, + "timestamp": 1687301600, + "tx_hash": "ef3187775584351cc5109de124b877bcc530fb3fdbf77895329dd447902cc566", + "tx_prefix_hash": "064884b8a8f903edcfebab830707ed44b633438b47c95a83320f4438b1b28626", + "tx_public": "54dce1a6eebafa2fdedcea5e373ef9de1c3d2737ae9f809e80958d1ba4590d74", + "rct_mask": "4cdc4c4e340aacb4741ba20f9b0b859242ecdad2fcc251f71d81123a47db3400", + "payment_id": "4f695d197f2a3c54", + "unlock_time": 0, + "mixin_count": 15, + "coinbase": false + } + } +} + +``` + +### Spends +All of the information in the [payments](#payments) section is relevant to +here, except instead of payment confirmations, spend confirmations are +published. The relevant ZeroMQ-PUB topics are: `json-full-spend_hook` and +`msgpack-full_spend_hook`. Example payload of a webhook callback: + +```json +{ + "index": 0, + "event": { + "event": "tx-spend", + "token": "spend-xmr", + "event_id": "7ff047aa74e14f4aa978469bc0eec8ec", + "tx_info": { + "input": { + "height": 2464207, + "tx_hash": "97d4e66c4968b16fec7662adc9f8562c49108d3c5e7030c4d6dd32d97fb62540", + "image": "b0fe7acd9e17bb8b9ac2daae36d4cb607ac60ed8a101cc9b2e1f74016cf80b24", + "source": { + "high": 0, + "low": 6246316 + }, + "timestamp": 1711902214, + "unlock_time": 0, + "mixin_count": 15, + "sender": { + "maj_i": 0, + "min_i": 0 + } + }, + "source": { + "id": { + "high": 0, + "low": 6246316 + }, + "amount": 10000000000, + "mixin": 15, + "index": 0, + "tx_public": "426ccd6d39535a1ee8636d14978581e580fcea35c8d3843ceb32eb688a0197f7" + } + } + } +} +``` + +### New Accounts +When a new account is registered, regardless of the `--auto-accept-creation` +flag for `monero-lws-daemon`, the system will publish events. Registration +occurs in the [admin api](/api/admin). The ZeroMQ-PUB topics are +`json_full-new_account` and `msgpack-full-new_account`. Example of callback: + +```json +{ + "index": 2, + "event": { + "event": "new-account", + "event_id": "c5a735e71b1e4f0a8bfaeff661d0b38a", + "token": "", + "address": "9zGwnfWRMTF9nFVW9DNKp46aJ43CRtQBWNFvPqFVSN3RUKHuc37u2RDi2GXGp1wRdSRo5juS828FqgyxkumDaE4s9qyyi9B" + } +} +``` + +### Updated Accounts +You can register to be notified when the scanner has updated _any_ account, +and the event will batch the notifications per-thread. The ZeroMQ-PUB topics +are `json-minimal-scanned` and `msgpack-minimal-scanned`. Example of +callback: + +```json +{ + "index": 13, + "event": { + "height": 2438536, + "id": "9197e1c6f3de28a98dfc579325903e5416ef1ba2681043c54b5fff0d39645a7f", + "addresses": [ + "9xkhhJSa7ZhS5sAcTix6ozL14RwdgxbV7JZVFW4rCghN7GidutaykfxDHfgW45UPiCTXncuvZ91GNSGgxs3b2Cin9TU8nP3" + ] + } +} +``` diff --git a/docs/administration.md b/docs/apps/admin.md similarity index 97% rename from docs/administration.md rename to docs/apps/admin.md index c99b28e..60252b5 100644 --- a/docs/administration.md +++ b/docs/apps/admin.md @@ -1,11 +1,11 @@ -# monero-lws Administration +# Admin The `monero-lws-admin` executable or `--admin-rest-server` option in the `monero-lws-daemon` executable can be used to administer the database used by `monero-lws-daemon`. Any number of `monero-lws-admin` instances can run concurrently with a single `monero-lws-daemon` instance on the same database. Administration is necessary to authorize new accounts and rescan requests -submitted from the REST API. The admin executable can also be used to list -the contents of the LMDB file for debugging purposes. +submitted from the [wallet API](/api/wallet). The admin executable can also be +used to list the contents of the LMDB file for debugging purposes. # monero-lws-admin @@ -21,14 +21,14 @@ search+filter the JSON output from the command. # Admin REST API The `monero-lws-daemon` can be started with 1+ `--admin-rest-server` parameters -that specify a listening location for admin REST clients. By default, there is -no admin REST server and no available admin accounts. +that specify a listening location for [admin API](/api/admin) clients. By +default, there is no admin REST server and no available admin accounts. An admin REST server can be merged with a regular REST server if path prefixes are specified, such as `--rest-server https://0.0.0.0:8443/basic --admin-rest-server https://0.0.0.0:8443/admin`. This will start a server listening on one port, 8443, and requires clients to -specify `/basic/command` or `/admin/admin_command` when making a +specify `/basic/command` or `/admin/admin/command` when making a request. An admin account account can be created via `monero-lws-admin create_admin` @@ -58,9 +58,10 @@ if `--disable-admin-auth` is specified in the CLI arguments for the REST server. ## Commands (of Admin REST API) -A subset of admin commands are available via admin REST API - the remainder -are initially omitted for security purposes. The commands available via REST -are: +A subset of admin commands are available via [admin REST API](/api/admin) - the +remainder are initially omitted for security purposes. The commands available +via REST are: + * [**accept_requests**](#accept_requests): `{"type": "import"|"create", "addresses":[...]}` * [**add_account**](#add_account): `{"address": ..., "key": ...}` * [**list_accounts**](#list_accounts): `{}` diff --git a/docs/apps/client.md b/docs/apps/client.md new file mode 100644 index 0000000..e69de29 diff --git a/docs/apps/daemon.md b/docs/apps/daemon.md new file mode 100644 index 0000000..2d59d38 --- /dev/null +++ b/docs/apps/daemon.md @@ -0,0 +1,81 @@ +# monero-lws-daemon + +`monero-lws-daemon` hosts the HTTP/1.1 server components of the +[wallet](/api/wallet) and [admin](/api/admin) API. +The wallet API is enabled by default on `http://127.0.0.1:8443`, and the admin +API is disabled by default. The daemon will listen for wallet API requests on +every `--rest-server` argument (multiple can be supplied). The same properties +apply to `--admin-rest-server` with the admin API. + +The wallet API and admin API can be merged into one server instance through a +shared prefix: `--rest-server http://127.0.0.1:8443/wallet` combined with +` --admin-rest-server http://127.0.0.1:8443/admin` will listen on one port for +both APIs, and the client software must use `/wallet` or `/admin` to access +the correct API. + +## SSL/TLS + +Every REST endpoint that starts with `https://` will only communicate via +SSL/TLS. By default, a new certificate is created each time the lws daemon +starts. The commands `--rest-ssl-key` and `--rest-ssl-certificate` allow for +explicit server keys to be used, and they are applied to _every_ `https://` +REST argument (both wallet API and admin API). + +## Subaddresses + +Subaddresses are disabled by default in the lws daemon - all relevant endpoints +will fail. The option `--max-subaddresses`, when specified with a non-zero +value, will enable subaddress endpoints and impose restrictions on their +creation. If the value is lowered in the future, existing subaddresses are not +retroactively removed, so the limit is enforced purely at creation time. + +If `--max-subaddresses` is zero or left unspecified, it will always disable +subaddresses, even if a user previously created some. So it is generally +recommended that once enabled, they always be enabled, even if the value +is lowered to `1` to discourage their use. + +## ZeroMQ Sub + +The daemon supports ZeroMQ SUB from `monerod` for instant mempool and block +notification. The `monerod` instance must use the option `--zmq-pub` and +`monero-lws-daemon` must use the `--sub` option. Both executables support +`tcp://` and `ipc://` for the rendevous location. + +When a new block is processed by `monerod`, the lws daemon will immediately +begin processing as a result of the notification. Without proper `--sub` +usage, the lws daemon will poll the `monerod` instance at 20 second intervals. + +The wallet API will **NOT** report mempool transactions due to a limitation +of the design. Webhooks **will** report mempool ("0-conf") transactions. + +## Webhooks + +The [admin API](/api/admin) has an endpoint, `/webhook_add`, with an `url` +field that must start with `http://`, `https://`, or `zmq`. See the link to +the API for specs/schema. + +Every webhook is "simulcast" over an optional ZeroZQ PUB socket specified with +`--zmq-pub` (which is different from `monerod --zmq-pub`). If the webhook was +created with `params.url == zmq` then the notification occurs only over ZeroMQ. + +The `params.address` field of `/webhook_add`, when needed as per spec, must +be a primary address. Subaddresses registered with the wallet API are +automatically reported to any primary address webhook. Omit `payment_id` to +report on _every_ transaction to that account. + +See [webhooks documentation](/usage/webhooks) for more information. + +## Remote Scanning + +The view-key scanning process can be spread to multiple machines with the +`--lws-server-addr` option. The remote side should use the +[`monero-lws-client`](#monero-lws-client) executable, and connect back to the +`monero-lws-daemon` location. Usage of `--lws-server-pass` is highly +recommended when doing remote scanning, as it will prevent rogue processes +from hijacking the scan process. Also consider specifying the password in a + `--config-file`, otherwise the process list will leak the password. + +The protocol is a custom unencrypted binary format, so `ssh -L ...` should be +used on the `monero-lws-client` side to provide proper encryption, and +additional authentication). + diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 0000000..8fec412 --- /dev/null +++ b/docs/index.md @@ -0,0 +1,53 @@ +# monero-lws Overview + +[monero-lws](https://github.com/vtnerd/monero-lws) is a Monero light-wallet +server that adheres to the community ratified +[LWS spec](https://github.com/monero-project/meta/blob/master/api/lightwallet_rest.md). +The server does all "cryptographic scanning" that is required of a Monero +wallet, and is non-custodial (the "spend" keys are never sent to server). It is +compatible with [Skylight wallet](https://skylight.magicgrants.org), and +[lwcli](https://github.com/cifro-codes/lwcli). + +## Background + +Monero wallets require complex scanning/decryption against _every_ transaction +to determine if funds were sent to that wallet. This process can be offloaded +to an outside process **without** giving up the "spend" keys of the wallet. The +LWS API provides a standard mechanism for splitting the "scanning" process from +the "spend" process. + +The only negative of splitting this process is privacy - the "LWS server" knows +all incoming funds and can typically infer outgoing funds as well. This privacy +issue can be mitigated by self-hosting a LWS server. `monero-lws` and +[OpenMonero](https://github.com/moneroexamples/openmonero) +are the two options for self-hosting. + +## Clients + +The two available wallets are [lwcli](/lwcli/) and +[Skylight wallet](https://skylight.magicgrants.org). `lwcli` is a TUI wallet +aimed at advanced users, whereas `Skylight` is a beginner wallet. + +Programmers wishing to create a new LWS wallet should investigate the +[lwsf](https://github.com/vtnerd/lwsf) project which provides a simple C++ +interface of typical wallet functions while performing all of the heavy lifting +of communicating to the server and creating transactions. + +## Versions + +The `develop` branch is considered "nightly", and the `master` branch is +considered the "alpha" branch. Only developers should use `develop` because +DB changes could be incompatible from commit to commit. + +After changes are well tested, they are moved to the `master` branch which +should rarely see incompatible DB changes. Users of this branch should +check the `src/lws_version.h.in` file - a major (first) number change indicates +that a incompatible DB change has been made. You will be unable to "roll-back" +to a prior `master` commit unless you save your DB and re-use it with that +older commited. + +The `release-v` branches indicate beta/stable versions of the software. The +major (first) number indicates the DB version. Upgrades from lower numbers +to higher numbers is possible, but the reverse is never true. The minor +(second) number refers to stability: new features are never imported into a +release branch, instead a new release with higher major/minor number are used. diff --git a/docs/installation/docker.md b/docs/installation/docker.md new file mode 100644 index 0000000..d4bad7c --- /dev/null +++ b/docs/installation/docker.md @@ -0,0 +1,15 @@ +# Docker +Docker is the easiest way to get a recent copy of `monero-lws`. The paths are: +```bash +docker pull vtnerd/monero-lws +docker pull ghcr.io/vtnerd/monero-lws +``` +which will download the latest stable release. A bleeding edge version can be +retrieved with: +```bash +docker pull vtnerd/monero-lws:master +docker pull ghcr.io/vtnerd/monero-lws:master +``` +which is considered "alpha" software. The docker build comes with +`monero-lws-daemon` and `monero-lws-admin`. + diff --git a/docs/installation/source.md b/docs/installation/source.md new file mode 100644 index 0000000..2e694b5 --- /dev/null +++ b/docs/installation/source.md @@ -0,0 +1,80 @@ +# From Source + +## Branches +Building from source requires deciding on a branch to compile: + + * `develop` is where all merges go first. So this the "nightly" branch, and + is generally only recommended for developers. This should compile against + the `master` branch of `monerod`. + * `master` is where tested merges go - making this the "alpha" branch. + Recommended only if some new feature(s) are needed. This should compile + against the `master` branch of `monerod`. + * `release-v...` - The first number specifies the `monero-lws` version and + the second number specifies the `monerod` version. Example: + `release-v0.3_0.18` is the v0.3 version of `monero-lws` to be compiled + against the v0.18 version of `monerod`. The most recent release branch is + recommended for the bulk of users. The supported release branches are: + * release-v0.3_0.18 + +## Dependencies +After deciding on a branch, the next step is dependency installation. The only +dependencies are those required by `monerod` - go to +the [`monerod` dependency section](https://github.com/monero-project/monero/?tab=readme-ov-file#dependencies) +and follow those instructions for installing dependencies. Then come back to +this guide. + +## Building +### Beginner + +The "beginner" method for compilation lets the git submodules do all of the +hard work, but is only available on `develop` and `master` branches. The +process is simply: + +```bash +git clone https://github.com/vtnerd/monero-lws.git +git checkout master +git submodule update --init --recursive +mkdir monero-lws/build && cd monero-lws/build +cmake -DCMAKE_BUILD_TYPE=Release .. +make -j$(nproc) +``` + +If on macOS, replace `-j$(nproc)` with `-j8` (or the number of cores on your +system). This should produce three binaries in the `monero/build/src` folder: +`monero-lws-daemon`, `monero-lws-admin`, and `monero-lws-client`. You can now +move onto [usage](/monero-lws/usage/). + +### Advanced + +If you already have the `monerod` source tree on your system, you can save some +space by re-using that copy. You need to manually ensure that the `monerod` +branch is the one needed by `monero-lws`. The +[first instruction](#building-from-source) specifies the expected `monerod` +branch foreach `monero-lws` branch. + +The process skips the submodule init and specifies the monero tree manually: + +```bash +git clone https://github.com/vtnerd/monero-lws.git +git checkout origin/release-v0.3_0.18 +mkdir monero-lws/build && cd monero-lws/build +cmake -DMONERO_SOURCE_DIR=/path/to/monero_0.18/source -DCMAKE_BUILD_TYPE=Release .. +make -j$(nproc) +``` + +Again, replace `-j$(nproc)` on macOS with appropriate core count. This should +produce three executables in the `monero-lws/build/src` directory. Move onto +[usage](/monero-lws/usage/) portion. + +### Other Build Options + +Advanced users/developers may wish to specify additional build-time options +supported by the project. The easiest is specifying `-DSTATIC=ON` at the +cmake stage, which tries to use static libraries where possible. + +The other available option is `-DBUILD_TESTS=ON` which can also be specified at +the cmake stage. This creates an executable `tests/unit/monero-lws-unit`. + +The last option is `-DSANITIZER=address` which can be specified at the cmake +stage. This builds both monero source tree and lws source tree with the address +sanitizer. diff --git a/docs/balance_new_addresses.md b/docs/scan/balance_new_addresses.md similarity index 100% rename from docs/balance_new_addresses.md rename to docs/scan/balance_new_addresses.md diff --git a/docs/block_depth_threading.md b/docs/scan/block_depth_threading.md similarity index 100% rename from docs/block_depth_threading.md rename to docs/scan/block_depth_threading.md diff --git a/docs/scan/round_robin.md b/docs/scan/round_robin.md new file mode 100644 index 0000000..bdf4750 --- /dev/null +++ b/docs/scan/round_robin.md @@ -0,0 +1,5 @@ +# Round-Robin +This is the default scan algorithm used by `monero-lws-daemon`. Each account +is sorted by height, and then distributed evenly across threads. Older accounts +will typically end up on the first thread, however, some accounts are stuck +"waiting" for the old accounts to "catch-up". diff --git a/docs/split_synced_threads.md b/docs/scan/split_synced_threads.md similarity index 100% rename from docs/split_synced_threads.md rename to docs/scan/split_synced_threads.md diff --git a/docs/zmq.md b/docs/zmq.md deleted file mode 100644 index 4c22a7c..0000000 --- a/docs/zmq.md +++ /dev/null @@ -1,178 +0,0 @@ -# monero-lws ZeroMQ Usage -Monero-lws uses ZeroMQ-RPC to retrieve information from a Monero daemon, -ZeroMQ-SUB to get immediate notifications of blocks and transactions from a -Monero daemon, and ZeroMQ-PUB to notify external applications of payment_id -and new account (web)hooks. - -## External "pub" socket -The bind location of the ZMQ-PUB socket is specified with the `--zmq-pub` -option. Users are still required to "subscribe" to topics: - * `json-full-payment_hook`: A JSON object of a single webhook payment event - that has recently triggered (identical output as webhook). - * `msgpack-full-payment_hook`: A msgpack object of a webhook payment events - that have recently triggered (identical output as webhook). - * `json-full-new_account_hook`: A JSON object of a single new account - creation that has recently triggered (identical output as webhook). - * `msgpack-full-new_account_hook`: A msgpack object of a single new account - creation that has recently triggered (identical output as webhook). - * `json-minimal-scanned`: A JSON object of a list of user primary addresses, - with their new height and block hash. - * `msgpack-minimal-scanned:` A msgpack object of a list of user primary - addresses with their new height and block hash. - * `json-full-spend_hook': A JSON object of a webhook spend event that has - recently triggerd (identical output as webhook). - * `msgpack-full-spend_hook`: A msgpack object of a single new account - creation that has recently triggered (identical output as webhook). - - -### `json-full-payment_hook`/`msgpack-full-payment_hook` -These topics receive PUB messages when a webhook ([`webhook_add`](administration.md)), -event is triggered for a payment (`tx-confirmation`). If the specified URL is -`zmq`, then notifications are only done over the ZMQ-PUB socket, otherwise the -notification is sent over ZMQ-PUB socket AND the specified URL. Invoking -`webhook_add` with a `payment_id` of zeroes (the field is optional in -`webhook_add`), will match on all transactions that lack a `payment_id`. - -Example of the "raw" output from ZMQ-SUB side: - -```json -json-full-payment_hook:{ - "index": 2, - "event": { - "event": "tx-confirmation", - "payment_id": "4f695d197f2a3c54", - "token": "single zmq wallet", - "confirmations": 1, - "event_id": "3894f98f5dd54af5857e4f8a961a4e57", - "tx_info": { - "id": { - "high": 0, - "low": 5666768 - }, - "block": 2265961, - "index": 1, - "amount": 3117324236131, - "timestamp": 1687301600, - "tx_hash": "ef3187775584351cc5109de124b877bcc530fb3fdbf77895329dd447902cc566", - "tx_prefix_hash": "064884b8a8f903edcfebab830707ed44b633438b47c95a83320f4438b1b28626", - "tx_public": "54dce1a6eebafa2fdedcea5e373ef9de1c3d2737ae9f809e80958d1ba4590d74", - "rct_mask": "4cdc4c4e340aacb4741ba20f9b0b859242ecdad2fcc251f71d81123a47db3400", - "payment_id": "4f695d197f2a3c54", - "unlock_time": 0, - "mixin_count": 15, - "coinbase": false - } - } -} - -``` - -Notice the `json-full-payment_hook:` prefix - this is required for the ZMQ PUB/SUB -subscription model. The subscriber requests data from a certain "topic" where -matching is done by string prefixes. - -> `index` is a counter used to detect dropped messages. - -> The `block` and `id` fields in the above example are NOT present when -`confirmations == 0`. - -### `json-full-new_account_hook`/`msgpack-full-new_account_hook` -These topics receive PUB messages when a webhook ([`webhook_add`](administration.md)), -event is triggered for a new account (`new-account`). If the specified URL is -`zmq`, then notifications are only done over the ZMQ-PUB socket, otherwise the -notification is sent over ZMQ-PUB socket AND the specified URL. Invoking -`webhook_add` with a `payment_id` of zeroes (the field is optional in -`webhook_add`), will match on all transactions that lack a `payment_id`. - -Example of the "raw" output from ZMQ-SUB side: - -```json -json-full-new_account_hook:{ - "index": 2, - "event": { - "event": "new-account", - "event_id": "c5a735e71b1e4f0a8bfaeff661d0b38a", - "token": "", - "address": "9zGwnfWRMTF9nFVW9DNKp46aJ43CRtQBWNFvPqFVSN3RUKHuc37u2RDi2GXGp1wRdSRo5juS828FqgyxkumDaE4s9qyyi9B" - } -} -``` - -Notice the `json-full-new_account_hook:` prefix - this is required for the ZMQ -PUB/SUB subscription model. The subscriber requests data from a certain "topic" -where matching is done by string prefixes. - -> `index` is a counter used to detect dropped messages. - -### `json-minimal-scanned`/`msgpack-minimal-scanned` -These topics receive PUB messages when a thread has finished scanning 1+ -accounts. The last block height and hash is sent. - -Example of the "raw" output from ZMQ-SUB side: -```json -json-minimal-scanned:{ - "index": 13, - "event": { - "height": 2438536, - "id": "9197e1c6f3de28a98dfc579325903e5416ef1ba2681043c54b5fff0d39645a7f", - "addresses": [ - "9xkhhJSa7ZhS5sAcTix6ozL14RwdgxbV7JZVFW4rCghN7GidutaykfxDHfgW45UPiCTXncuvZ91GNSGgxs3b2Cin9TU8nP3" - ] - -> `index` is a counter used to detect dropped messages. - -### `json-full-spend_hook`/`msgpack-full-spend_hook` -These topics receive PUB messages when a webhook ([`webhook_add`](administration.md)), -event is triggered for a spend (`tx-spend`). If the specified URL is -`zmq`, then notifications are only done over the ZMQ-PUB socket, otherwise the -notification is sent over ZMQ-PUB socket AND the specified URL. Invoking -`webhook_add` with a `payment_id` or `confirmation` results in a NOP because -both fields are unused for spends. This event is only triggered on -confirmation==1 (`confirmation` field on `webhook_add`s have no effect, and -mempool spends are not scanned). The intent is to notify the user of unexpected -spend operations. The end user will need to use `tx_info.input.image`, -`tx_info.source.index`, and `tx_info.source.tx_public` to determine if the -output was actually spent or being used as a decoy. - -Example of the "raw" output from ZMQ-SUB side: - -```json -json-full-spend_hook:{ - "index": 0, - "event": { - "event": "tx-spend", - "token": "spend-xmr", - "event_id": "7ff047aa74e14f4aa978469bc0eec8ec", - "tx_info": { - "input": { - "height": 2464207, - "tx_hash": "97d4e66c4968b16fec7662adc9f8562c49108d3c5e7030c4d6dd32d97fb62540", - "image": "b0fe7acd9e17bb8b9ac2daae36d4cb607ac60ed8a101cc9b2e1f74016cf80b24", - "source": { - "high": 0, - "low": 6246316 - }, - "timestamp": 1711902214, - "unlock_time": 0, - "mixin_count": 15, - "sender": { - "maj_i": 0, - "min_i": 0 - } - }, - "source": { - "id": { - "high": 0, - "low": 6246316 - }, - "amount": 10000000000, - "mixin": 15, - "index": 0, - "tx_public": "426ccd6d39535a1ee8636d14978581e580fcea35c8d3843ceb32eb688a0197f7" - } - } - } -} -``` - -> `index` is a counter used to detect dropped messages diff --git a/mkdocs.yml b/mkdocs.yml new file mode 100644 index 0000000..65bad70 --- /dev/null +++ b/mkdocs.yml @@ -0,0 +1,27 @@ +site_name: docs.monerolws.com +site_url: https://docs.monerolws.com +site_description: Documentation for Monero-LWS +nav: + - Overview: index.md + - Installation: + - From Source: installation/source.md + - Docker: installation/docker.md + - Processes: + - daemon: apps/daemon.md + - admin: apps/admin.md + - client: apps/client.md + - Scan Algorithms: + - Round Robin: scan/round_robin.md + - Balance New Addresses: scan/balance_new_addresses.md + - Block Depth Threading: scan/block_depth_threading.md + - Split Synced Threads: scan/split_synced_threads.md + - API: + - Wallet: api/wallet.md + - Admin: api/admin.md + - Webhooks/ZeroMQ: api/zmq.md + - RabbitMQ: api/rmq.md +plugins: + - swagger-ui-tag +theme: readthedocs +repo_url: https://github.com/vtnerd/monero-lws +edit_uri: edit/develop/docs