Introduce nyxd client

This commit is contained in:
Bogdan-Ștefan Neacșu
2023-08-24 13:09:55 +03:00
parent f26aad9880
commit a7c71ab3d4
11 changed files with 117 additions and 6 deletions
Generated
+2
View File
@@ -6580,8 +6580,10 @@ dependencies = [
"anyhow",
"log",
"nym-bin-common",
"nym-network-defaults",
"nym-payment-manager-common",
"nym-task",
"nym-validator-client",
"rocket",
"rocket_cors",
"rocket_okapi",
+2
View File
@@ -28,8 +28,10 @@ tokio = { version = "1.24.1", features = [
] }
nym-bin-common = { path = "../../common/bin-common" }
nym-network-defaults = { path = "../../common/network-defaults" }
nym-payment-manager-common = { path = "../../common/payment-manager" }
nym-task = { path = "../../common/task" }
nym-validator-client = { path = "../../common/client-libs/validator-client" }
[build-dependencies]
sqlx = { version = "0.6.2", features = [
@@ -3,5 +3,5 @@ CREATE TABLE payments
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
serial_number VARCHAR NOT NULL UNIQUE,
unyms_bought INTEGER NOT NULL,
status VARCHAR NOT NULL
paid BOOLEAN NOT NULL
);
+36
View File
@@ -0,0 +1,36 @@
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::error::Error;
use nym_network_defaults::NymNetworkDetails;
use nym_validator_client::{nyxd, DirectSigningHttpRpcNyxdClient};
use std::sync::Arc;
use tokio::sync::RwLock;
pub(crate) struct Client(pub(crate) Arc<RwLock<DirectSigningHttpRpcNyxdClient>>);
impl Clone for Client {
fn clone(&self) -> Self {
Client(Arc::clone(&self.0))
}
}
impl Client {
pub(crate) fn new(details: &NymNetworkDetails) -> Result<Self, Error> {
let client_config = nyxd::Config::try_from_nym_network_details(details)?;
let endpoint = details
.endpoints
.first()
.ok_or(Error::EmptyValidatorList)?
.nyxd_url
.as_str();
let inner = DirectSigningHttpRpcNyxdClient::connect_with_mnemonic(
client_config,
endpoint,
"".parse().unwrap(),
)?;
Ok(Client(Arc::new(RwLock::new(inner))))
}
}
+9
View File
@@ -18,6 +18,15 @@ pub enum Error {
#[error("SQL migrate error - {0}")]
DatabaseMigrateError(#[from] sqlx::migrate::MigrateError),
#[error("NyxdError - {0}")]
NyxdError(#[from] nym_validator_client::nyxd::error::NyxdError),
#[error("Bad deposit address")]
BadAddress,
#[error("Empty list of validators")]
EmptyValidatorList,
}
impl<'r, 'o: 'r> Responder<'r, 'o> for Error {
+7 -2
View File
@@ -1,9 +1,11 @@
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::state::State;
use crate::client::Client;
use crate::state::{Config, State};
use crate::storage::Storage;
use anyhow::Result;
use nym_network_defaults::NymNetworkDetails;
use rocket::http::Method;
use rocket::{Ignite, Rocket, Route};
use rocket_cors::{AllowedHeaders, AllowedOrigins, Cors};
@@ -51,8 +53,11 @@ pub(crate) async fn setup_rocket() -> Result<Rocket<Ignite>> {
"" => routes(&openapi_settings),
}
let details = NymNetworkDetails::new_from_env();
let client = Client::new(&details)?;
let config = Config::new(details.chain_details.mix_denom.base.clone());
let rocket = rocket
.manage(State::new(storage))
.manage(State::new(storage, client, config))
.mount("/swagger", make_swagger_ui(&openapi::get_docs()))
.attach(setup_cors()?);
@@ -4,12 +4,14 @@
use crate::error::Error;
use crate::state::State;
use nym_payment_manager_common::PaymentResponse;
use nym_validator_client::nyxd::{AccountId, Coin};
use rocket::serde::json::Json;
use rocket::{post, State as RocketState};
use rocket_okapi::okapi::schemars;
use rocket_okapi::openapi;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use std::str::FromStr;
// All strings are base58 encoded representations of structs
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
@@ -30,6 +32,22 @@ pub async fn claim_payment(
.get_payment(&claim_payment_request_body.serial_number)
.await?;
let recipient = AccountId::from_str(&claim_payment_request_body.deposit_address)
.map_err(|_| Error::BadAddress)?;
let amount = vec![Coin::new(
payment.unyms_bought as u128,
state.config.denom(),
)];
state
.client
.0
.read()
.await
.send(&recipient, amount, "deposit via payment", None)
.await?;
state.storage.manager.update_payment(payment.id).await?;
Ok(Json(PaymentResponse {
unyms_bought: payment.unyms_bought as u64,
}))
+3
View File
@@ -2,9 +2,11 @@
// SPDX-License-Identifier: Apache-2.0
use nym_bin_common::logging::setup_logging;
use nym_network_defaults::setup_env;
use nym_task::TaskManager;
use std::error::Error;
mod client;
mod error;
mod http;
mod state;
@@ -13,6 +15,7 @@ mod storage;
#[tokio::main]
async fn main() -> Result<(), Box<dyn Error + Send + Sync>> {
setup_logging();
setup_env(None);
// let's build our rocket!
let rocket = http::setup_rocket().await?;
+23 -2
View File
@@ -1,14 +1,35 @@
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::client::Client;
use crate::storage::Storage;
pub struct Config {
denom: String,
}
impl Config {
pub fn new(denom: String) -> Self {
Config { denom }
}
pub fn denom(&self) -> &str {
&self.denom
}
}
pub struct State {
pub(crate) storage: Storage,
pub(crate) client: Client,
pub(crate) config: Config,
}
impl State {
pub(crate) async fn new(storage: Storage) -> Self {
State { storage }
pub(crate) async fn new(storage: Storage, client: Client, config: Config) -> Self {
State {
storage,
client,
config,
}
}
}
@@ -23,4 +23,19 @@ impl StorageManager {
.fetch_one(&self.connection_pool)
.await
}
pub(crate) async fn update_payment(&self, id: i64) -> Result<(), sqlx::Error> {
sqlx::query!(
r#"
UPDATE payments
SET paid = true
WHERE id = ?
"#,
id
)
.execute(&self.connection_pool)
.await?;
Ok(())
}
}
@@ -8,7 +8,7 @@ pub(crate) struct Payment {
pub(crate) id: i64,
pub(crate) serial_number: String,
pub(crate) unyms_bought: i64,
pub(crate) status: String,
pub(crate) paid: bool,
}
#[derive(Clone, Serialize, Deserialize, schemars::JsonSchema)]