forked from such-gitea/wownero-lws
Webhooks for New Accounts (#79)
This commit is contained in:
committed by
Lee *!* Clagett
parent
524e26e1a4
commit
aa171b77c3
@@ -29,6 +29,7 @@
|
||||
#include <cstring>
|
||||
#include <memory>
|
||||
|
||||
#include "db/string.h"
|
||||
#include "wire.h"
|
||||
#include "wire/crypto.h"
|
||||
#include "wire/json/write.h"
|
||||
@@ -215,7 +216,7 @@ namespace db
|
||||
|
||||
namespace
|
||||
{
|
||||
constexpr const char* map_webhook_type[] = {"tx-confirmation"};
|
||||
constexpr const char* map_webhook_type[] = {"tx-confirmation", "new-account"};
|
||||
|
||||
template<typename F, typename T>
|
||||
void map_webhook_key(F& format, T& self)
|
||||
@@ -292,6 +293,15 @@ namespace db
|
||||
);
|
||||
}
|
||||
|
||||
void write_bytes(wire::writer& dest, const webhook_new_account& self)
|
||||
{
|
||||
wire::object(dest,
|
||||
wire::field<0>("event_id", std::cref(self.value.first.event_id)),
|
||||
wire::field<1>("token", std::cref(self.value.second.token)),
|
||||
wire::field<2>("address", address_string(self.account))
|
||||
);
|
||||
}
|
||||
|
||||
bool operator<(const webhook_dupsort& left, const webhook_dupsort& right) noexcept
|
||||
{
|
||||
return left.payment_id == right.payment_id ?
|
||||
|
||||
@@ -252,7 +252,8 @@ namespace db
|
||||
|
||||
enum class webhook_type : std::uint8_t
|
||||
{
|
||||
tx_confirmation = 0,
|
||||
tx_confirmation = 0, // cannot change values - stored in DB
|
||||
new_account
|
||||
// unconfirmed_tx,
|
||||
// new_block
|
||||
// confirmed_tx,
|
||||
@@ -316,6 +317,14 @@ namespace db
|
||||
};
|
||||
void write_bytes(wire::json_writer&, const webhook_event&);
|
||||
|
||||
//! Returned by DB when a webhook event "tripped"
|
||||
struct webhook_new_account
|
||||
{
|
||||
webhook_value value;
|
||||
account_address account;
|
||||
};
|
||||
void write_bytes(wire::writer&, const webhook_new_account&);
|
||||
|
||||
bool operator==(transaction_link const& left, transaction_link const& right) noexcept;
|
||||
bool operator<(transaction_link const& left, transaction_link const& right) noexcept;
|
||||
bool operator<=(transaction_link const& left, transaction_link const& right) noexcept;
|
||||
|
||||
@@ -1635,14 +1635,14 @@ namespace db
|
||||
});
|
||||
}
|
||||
|
||||
expect<void> storage::creation_request(account_address const& address, crypto::secret_key const& key, account_flags flags) noexcept
|
||||
expect<std::vector<webhook_new_account>> storage::creation_request(account_address const& address, crypto::secret_key const& key, account_flags flags) noexcept
|
||||
{
|
||||
MONERO_PRECOND(db != nullptr);
|
||||
|
||||
if (!db->create_queue_max)
|
||||
return {lws::error::create_queue_max};
|
||||
|
||||
return db->try_write([this, &address, &key, flags] (MDB_txn& txn) -> expect<void>
|
||||
return db->try_write([this, &address, &key, flags] (MDB_txn& txn) -> expect<std::vector<webhook_new_account>>
|
||||
{
|
||||
const expect<db::account_time> current_time = get_account_time();
|
||||
if (!current_time)
|
||||
@@ -1651,10 +1651,12 @@ namespace db
|
||||
cursor::accounts_by_address accounts_ba_cur;
|
||||
cursor::blocks blocks_cur;
|
||||
cursor::accounts requests_cur;
|
||||
cursor::webhooks webhooks_cur;
|
||||
|
||||
MONERO_CHECK(check_cursor(txn, this->db->tables.accounts_ba, accounts_ba_cur));
|
||||
MONERO_CHECK(check_cursor(txn, this->db->tables.blocks, blocks_cur));
|
||||
MONERO_CHECK(check_cursor(txn, this->db->tables.requests, requests_cur));
|
||||
MONERO_CHECK(check_cursor(txn, this->db->tables.webhooks, webhooks_cur));
|
||||
|
||||
MDB_val keyv = lmdb::to_val(by_address_version);
|
||||
MDB_val value = lmdb::to_val(address);
|
||||
@@ -1709,7 +1711,24 @@ namespace db
|
||||
if (err)
|
||||
return {lmdb::error(err)};
|
||||
|
||||
return success();
|
||||
std::vector<webhook_new_account> hooks{};
|
||||
webhook_key wkey{account_id::invalid, webhook_type::new_account};
|
||||
keyv = lmdb::to_val(wkey);
|
||||
err = mdb_cursor_get(webhooks_cur.get(), &keyv, &value, MDB_SET_KEY);
|
||||
for (;;)
|
||||
{
|
||||
if (err)
|
||||
{
|
||||
if (err == MDB_NOTFOUND)
|
||||
break;
|
||||
return {lmdb::error(err)};
|
||||
}
|
||||
|
||||
hooks.push_back(webhook_new_account{MONERO_UNWRAP(webhooks.get_value(value)), address});
|
||||
err = mdb_cursor_get(webhooks_cur.get(), &keyv, &value, MDB_NEXT_DUP);
|
||||
}
|
||||
|
||||
return hooks;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -2190,7 +2209,7 @@ namespace db
|
||||
});
|
||||
}
|
||||
|
||||
expect<void> storage::add_webhook(const webhook_type type, const account_address& address, const webhook_value& event)
|
||||
expect<void> storage::add_webhook(const webhook_type type, const boost::optional<account_address>& address, const webhook_value& event)
|
||||
{
|
||||
if (event.second.url != "zmq")
|
||||
{
|
||||
@@ -2210,10 +2229,13 @@ namespace db
|
||||
MONERO_CHECK(check_cursor(txn, this->db->tables.webhooks, webhooks_cur));
|
||||
|
||||
webhook_key key{account_id::invalid, type};
|
||||
MDB_val lmkey = lmdb::to_val(by_address_version);
|
||||
MDB_val lmvalue = lmdb::to_val(address);
|
||||
MDB_val lmkey{};
|
||||
MDB_val lmvalue{};
|
||||
|
||||
if (address)
|
||||
{
|
||||
lmkey = lmdb::to_val(by_address_version);
|
||||
lmvalue = lmdb::to_val(*address);
|
||||
const int err = mdb_cursor_get(accounts_ba_cur.get(), &lmkey, &lmvalue, MDB_GET_BOTH);
|
||||
if (err && err != MDB_NOTFOUND)
|
||||
return {lmdb::error(err)};
|
||||
|
||||
@@ -212,7 +212,7 @@ namespace db
|
||||
rescan(block_id height, epee::span<const account_address> addresses);
|
||||
|
||||
//! Add an account for later approval. For use with the login endpoint.
|
||||
expect<void> creation_request(account_address const& address, crypto::secret_key const& key, account_flags flags) noexcept;
|
||||
expect<std::vector<webhook_new_account>> creation_request(account_address const& address, crypto::secret_key const& key, account_flags flags) noexcept;
|
||||
|
||||
/*!
|
||||
Request lock height of an existing account. No effect if the `start_height`
|
||||
@@ -249,12 +249,12 @@ namespace db
|
||||
|
||||
\param type The webhook event type to be tracked by the DB.
|
||||
\param address is required for `type == tx_confirmation`, and is not
|
||||
not needed for all other types (use default construction of zeroes).
|
||||
not needed for all other types.
|
||||
\param event Additional information for the webhook. A valid "http"
|
||||
or "https" URL must be provided (or else error). All other information
|
||||
is optional.
|
||||
*/
|
||||
expect<void> add_webhook(webhook_type type, const account_address& address, const webhook_value& event);
|
||||
expect<void> add_webhook(webhook_type type, const boost::optional<account_address>& address, const webhook_value& event);
|
||||
|
||||
/*! Delete all webhooks associated with every value in `addresses`. This is
|
||||
likely only valid for `tx_confirmation` event types. */
|
||||
|
||||
Reference in New Issue
Block a user