Added webhook tx-confirmation support (#66)

This commit is contained in:
Lee *!* Clagett
2023-05-11 13:13:10 -04:00
committed by Lee *!* Clagett
parent 990e86f701
commit 3e0555e07d
32 changed files with 2051 additions and 122 deletions

View File

@@ -45,7 +45,7 @@ to put the account into the "inactive" state. Deleting accounts is not
currently supported.
Every admin REST request must be a `POST` that contains a JSON object with
an `auth` field and an optional `params` field:
an `auth` field (in default settings) and an optional `params` field:
```json
{
@@ -53,26 +53,276 @@ an `auth` field and an optional `params` field:
"params":{...}
}
```
where the `params` object is specified below.
where the `params` object is specified below. The `auth` field can be omitted
if `--disable-admin-auth` is specified in the CLI arguments for the REST
server.
## Commands
## 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:
* **accept_requests**: `{"type": "import"|"create", "addresses":[...]}`
* **add_account**: `{"address": ..., "key": ...}`
* **list_accounts**: `{}`
* **list_requests**: `{}`
* **modify_account_status**: `{"status": "active"|"hidden"|"inactive", "addresses":[...]}`
* **reject_requests**: `{"type": "import"|"create", "addresses":[...]}`
* **rescan**: `{"height":..., "addresses":[...]}`
* [**accept_requests**](#accept_requests): `{"type": "import"|"create", "addresses":[...]}`
* [**add_account**](#add_account): `{"address": ..., "key": ...}`
* [**list_accounts**](#list_accounts): `{}`
* [**list_requests**](#list_requests): `{}`
* [**modify_account_status**](#modify_account_status): `{"status": "active"|"hidden"|"inactive", "addresses":[...]}`
* [**reject_requests**](#reject_requests): `{"type": "import"|"create", "addresses":[...]}`
* [**rescan**](#rescan): `{"height":..., "addresses":[...]}`
* [**webhook_add**](#webhook_add): `{"type":"tx-confirmation", "address":"...", "url":"...", ...}` with optional fields:
* **token**: A string to be returned when the webhook is triggered
* **payment_id**: 16 hex characters representing a unique identifier for a transaction
* [**webhook_delete**](#webhook_delete): `{"addresses":[...]}`
* [**webhook_delete_uuid**](#webhook_delete_uuid): `{"event_ids": [...]}`
* [**webhook_list**](#webhook_list): `{}`
where the listed object must be the `params` field above.
### accept_requests
Accepts new account and rescan from block 0 requests in the incoming
queue.
### add_account
Add account for view-key scanning. An example of the JSON:
```json
{
"params": {
"address": "9uTcr6T9GURRt7UADQc2rhjg5oMYBDyoQ5jgx8nAvVvs757WwDkc2vHLPJhwZfCnfVdnWNvuuKzJe8eMVTKwadYzBrYRG5j",
"key": "deadbeef"
},
"auth": "f50922f5fcd186eaa4bd7070b8072b66fea4fd736f06bd82df702e2314187d09"
}
```
### list_accounts
Request a listing of all active accounts in the datbase. The request
should looke like:
```bash
curl -v -H "Content-Type: application/json" -d '{}' http://127.0.0.1:8081/list_accounts
```
when auth is disabled, and when enabled:
```bash
curl -v -H "Content-Type: application/json" -d '{"auth": "f50922f5fcd186eaa4bd7070b8072b66fea4fd736f06bd82df702e2314187d09"}' http://127.0.0.1:8081/list_accounts
```
The response will look something like:
```json
{
"active": [
{
"address": "9wRAu3giCtKhSsVnkZJ7LLE6zqzrmMKpPg39S8aoC7T6F6GobeDpz8TcvVfTQT3ucW82oTYKG8v3ZMAeh8SZVXWwMdvwZew",
"scan_height": 2220875,
"access_time": 1681244149
}
]
}
```
### list_requests
This is a listing of all pending new account requests and all requests
to import from genesis block requests. When auth is disabled usage
looks like:
```bash
curl -v -H "Content-Type: application/json" -d '{}' http://127.0.0.1:8081/list_requests
```
and with auth enabled looks like:
```bash
curl -v -H "Content-Type: application/json" -d '{"auth": "f50922f5fcd186eaa4bd7070b8072b66fea4fd736f06bd82df702e2314187d09"}' http://127.0.0.1:8081/list_requests
```
### modify_account_status
This can change an account status to `active`, `inactive` or `hidden`. The
`active` state is the normal state - the account is being scanned and
returned by the API. The `inactive` state is still returned by the API,
but is no longer being scanned. The `hidden` is the current way to
"delete" an account - it is not scanned nor returned by the API. Accounts
cannot currently be deleted due to internal DB requirements.
### reject_requests
This is the opposite of [`accept_requests`](#accept_requests) above. See
information from that endpoint on how to use this one.
### rescan
This tells the scanner to rescan specific account(s) from the specified
height.
### webhook_add
This is used to track a specific payment ID to an address or all general
payments to an address (where payment ID is zero). Using this endpint requires
a web address for callback purposes, a primary (not integrated!) address, and
finally the type ("tx-confirmation"). The event will remain in the database
until one of the delete commands ([webhook_delete_uuid](#webhook_delete_uuid)
or [webhook_delete](#webhook_delete)) is used to remove it.
> The provided URL will use SSL/TLS if `https://` is prefixed in the URL and
will use plaintext if `http://` is prefixed in the URL. SSL/TLS connections
will use the system certificate authority (root-CAs) by default, and will
ignore all authority checks if `--webhook-ssl-verification none` is provided
on the command line when starting `monero-lws-daemon`. The webhook will fail
if there is a mismatch of `http` and `https` between the two servers, and
will also fail if `https` verification is mismatched. The rule is: (1) if
the callback server has SSL/TLS disabled, the webhook should use `http://`,
(2) if the callback server has a self-signed certificate, `https://` and
`--webhook-ssl-verification none` should be used, and (3) if the callback
server is using "Let's Encrypt" (or similar), then `https://` with no
additional command line flag should be used.
#### Initial Request to server
Example where admin authentication is required (`--disable-admin-auth` NOT
set on start which is the default):
```json
{
"auth": "f50922f5fcd186eaa4bd7070b8072b66fea4fd736f06bd82df702e2314187d09",
"params": {
"type": "tx-confirmation",
"url": "http://127.0.0.1:7000",
"payment_id": "df034c176eca3296",
"token": "1234",
"address": "9uTcr6T9GURRt7UADQc2rhjg5oMYBDyoQ5jgx8nAvVvs757WwDkc2vHLPJhwZfCnfVdnWNvuuKzJe8eMVTKwadYzBrYRG5j"
}
}
```
Example where admin authentication is not required (`--disable-admin-auth` set on start):
```json
{
"params": {
"type": "tx-confirmation",
"url": "http://127.0.0.1:7000",
"payment_id": "df034c176eca3296",
"token": "1234",
"address": "9uTcr6T9GURRt7UADQc2rhjg5oMYBDyoQ5jgx8nAvVvs757WwDkc2vHLPJhwZfCnfVdnWNvuuKzJe8eMVTKwadYzBrYRG5j"
}
}
```
As noted above - `payment_id` and `token` are both optional - `token` will
default to the empty string, and `payment_id` will default to zero.
##### Initial Response from Server
The server will replay all values back to the user for confirmation. An
additional field - `event_id` - is also returned which contains a globally
unique value (internally this is a 128-bit `UUID`).
Example response:
```json
{
"payment_id": "df034c176eca3296",
"event_id": "fa10a4db485145f1a24dc09c19a79d43",
"token": "1234",
"confirmations": 1,
"url": "http://127.0.0.1:7000"
}
```
If you use the `debug_database` command provided by the `monero-lws-admin`
executable, the event should be listed in the
`webhooks_by_account_id,payment_id` field of the returned JSON object. The
event will remain in the database until an explicit
[`webhook_delete_uuid`](#webhook_delete_uuid) is invoked.
#### Callback from Server
When the event "fires" due to a transaction, the provided URL is invoked
with a JSON payload that looks like the below:
```json
{
"event": "tx-confirmation",
"payment_id": "df034c176eca3296",
"token": "1234",
"confirmations": 1,
"id": "fa10a4db485145f1a24dc09c19a79d43",
"tx_info": {
"id": {
"high": 0,
"low": 5550229
},
"block": 2192100,
"index": 0,
"amount": 4949570000,
"timestamp": 1678324181,
"tx_hash": "901f9a2a919b6312131537ff6117d56ce2c0dc1f1341b845d7667299e1ef892f",
"tx_prefix_hash": "89685cb7acb836fde30fae8be5d8b884e92706df086960d0508e146979ef80dc",
"tx_public": "54c153792e47c1da8ceb3979560c424c1928b7b4a089c1c8b3ce99c563e1d240",
"rct_mask": "f3449407dc3721299b5309c0c336a17daeebce55165ddd447ba28bbd1f46c201",
"payment_id": "df034c176eca3296",
"unlock_time": 0,
"mixin_count": 15,
"coinbase": false
}
}
```
which is the same information provided by the user API. The database will
contain an entry in the `webhook_events_by_account_id,type,block_id,tx_hash,output_id,payment_id,event_id`
field of the JSON object provided by the `debug_database` command. The
entry will be removed when the number of confirmations has been reached.
### webhook_delete
Deletes all webhooks associated with a specific Monero primary address.
### webhook_delete_uuid
Deletes all references to a specific webhook referenced by its UUID
(`event_id`)
### webhook_list
This will list every webhook that is currently "listening" for
incoming transactions. If the server has auth disabled, the
request is simply:
```bash
curl -v -H "Content-Type: application/json" -d '{}' http://127.0.0.1:8081/webhook_list
```
and with auth enabled looks like:
```bash
curl -v -H "Content-Type: application/json" -d '{"auth": "f50922f5fcd186eaa4bd7070b8072b66fea4fd736f06bd82df702e2314187d09"}' http://127.0.0.1:8081/webhook_list
```
which returns a JSON object that looks like:
```json
{
"webhooks": [
{
"key": {
"user": 1,
"type": "tx-confirmation"
},
"value": [
{
"payment_id": "9bc1a59b34253896",
"event_id": "4dc201838af54dfe88686bea7e2b599f",
"token": "12345",
"confirmations": 5,
"url": "http://127.0.0.1:8082"
},
{
"payment_id": "9bc1a59b34253896",
"event_id": "615171e477464401a1a23cdb45b3b433",
"token": "12345",
"confirmations": 5,
"url": "http://127.0.0.1:8082"
},
{
"payment_id": "9bc1a59b34253896",
"event_id": "e64be3ad6d1647618fbd292be0485901",
"token": "this is a fresh test",
"confirmations": 1,
"url": "http://127.0.0.1:8082/foobar"
},
{
"payment_id": "9bc1a59b34253896",
"event_id": "fe692cdf7de1453898ad453d8fabce42",
"token": "12345",
"confirmations": 5,
"url": "http://127.0.0.1:8082/foobar"
}
]
}
]
}
```
# Examples
## Admin REST API
### Default Settings
```json
{
"auth":"6d732245002a9499b3842c0a7f9fc6b2d657c77bd612dbefa4f7f9357d08530a",
@@ -84,6 +334,16 @@ where the listed object must be the `params` field above.
```
will put the listed address into the "inactive" state.
### `--disable-admin-auth` Setting
```json
{
"params":{
"status": "inactive",
"addresses": ["9sAejnQ9EBR1111111111111111111111111111111111AdYmVTw2Tv6L9KYkHjJ2wd737ov8ZL5QU7CJ4zV6basGP9fyno"]
}
}
```
## monero-lws-admin
**List every active Monero address on a newline:**
@@ -95,7 +355,6 @@ will put the listed address into the "inactive" state.
```bash
monero-lws-admin accept_requests create $(monero-lws-admin list_requests | jq -j '.create? | .[]? | .address?+" "')
```
# Debugging
`monero-lws-admin` has a debug mode that dumps everything stored in the