finish create-offer, finish sqlite init

This commit is contained in:
f321x
2024-06-26 12:48:03 +00:00
parent b4659ad912
commit 57e6a32f09
11 changed files with 73 additions and 49 deletions

View File

@ -1,4 +1,4 @@
ELECTRUM_BACKEND="127.0.0.1:50001"
DATABASE_PATH="./db/trades.db" # path to the coordinator sqlite database storing the trades
BDK_DB_PATH="./db/bdk-wallet" # Path to the BDK Sled database (no .db postfix)
ELECTRUM_BACKEND="ssl://mempool.space:40002"
DATABASE_PATH="./dbs/trades.db" # path to the coordinator sqlite database storing the trades
BDK_DB_PATH="./dbs/bdk-wallet" # Path to the BDK Sled database (no .db postfix)
WALLET_XPRV="tprv8ZgxMBicQKsPdHuCSjhQuSZP1h6ZTeiRqREYS5guGPdtL7D1uNLpnJmb2oJep99Esq1NbNZKVJBNnD2ZhuXSK7G5eFmmcx73gsoa65e2U32"

View File

@ -2277,9 +2277,9 @@ checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
[[package]]
name = "unicode-normalization"
version = "0.1.23"
version = "0.1.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5"
checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921"
dependencies = [
"tinyvec",
]

View File

@ -6,7 +6,7 @@ edition = "2021"
[dependencies]
anyhow = "1.0.86"
axum = { version = "0.7.5", features = ["tokio", "json"] }
bdk = { version = "0.29.0", features = ["key-value-db", "async-interface"] }
bdk = { version = "0.29.0", features = ["key-value-db"] }
dotenv = "0.15.0"
hex = "0.4.3"
reqwest = { version = "0.12.4", features = ["blocking", "json"] }

View File

@ -0,0 +1,4 @@
segment_size: 524288
use_compression: false
version: 0.34
v

Binary file not shown.

Binary file not shown.

View File

@ -15,38 +15,44 @@ use tokio::net::TcpListener;
// Handler function to process the received data
async fn receive_order(
Extension(state): Extension<Arc<CoordinatorDB>>,
Extension(database): Extension<CoordinatorDB>,
Extension(wallet): Extension<CoordinatorWallet>,
Json(order): Json<OrderRequest>,
) -> Result<Json<BondRequirementResponse>, AppError> {
// generate locking address for bond
// insert offer into sql database
println!("Coordinator received new offer: {:?}", order);
Ok(Json(BondRequirementResponse {
bond_address: bond_address,
let bond_requirements = BondRequirementResponse {
bond_address: wallet.get_new_address().await?,
locking_amount_sat: order.amount_satoshi * order.bond_ratio as u64 / 100,
}))
};
// insert offer into sql database
database
.insert_new_maker_request(&order, &bond_requirements)
.await?;
println!("Coordinator received new offer: {:?}", order);
Ok(Json(bond_requirements))
}
// async fn submit_maker_bond(
// Json(payload): Json<BondSubmissionRequest>,
// ) -> Result<Json<OrderActivatedResponse>, AppError> {
// // Process the payload
// // For now, we'll just return a dummy success response
// let response = OrderActivatedResponse {
// bond_locked_until_timestamp: 0 as u128,
// order_id_hex: "Bond submitted successfully".to_string(),
// };
async fn submit_maker_bond(
Extension(database): Extension<CoordinatorDB>,
Extension(wallet): Extension<CoordinatorWallet>,
Json(payload): Json<BondSubmissionRequest>,
) -> Result<Json<OrderActivatedResponse>, AppError> {
// Process the payload
// For now, we'll just return a dummy success response
let response = OrderActivatedResponse {
bond_locked_until_timestamp: 0 as u128,
order_id_hex: "Bond submitted successfully".to_string(),
};
// // Create the JSON response
// Json(response)
// }
// Create the JSON response
Json(response)
}
pub async fn api_server(database: CoordinatorDB) -> Result<()> {
pub async fn api_server(database: CoordinatorDB, wallet: CoordinatorWallet) -> Result<()> {
let app = Router::new()
.route("/create-offer", post(receive_order))
.layer(Extension(database));
// .route("/submit-maker-bond", post(submit_maker_bond));
.route("/submit-maker-bond", post(submit_maker_bond))
.layer(Extension(database))
.layer(Extension(wallet));
// add other routes here
// Run the server on localhost:9999

View File

@ -12,16 +12,18 @@ pub struct CoordinatorDB {
impl CoordinatorDB {
// will either create a new db or load existing one. Will create according tables in new db
pub async fn init() -> Result<Self> {
dbg!(env::var("DATABASE_PATH")?);
let db_path =
env::var("DATABASE_PATH").context("Parsing DATABASE_PATH from .env failed")?;
// Add the `?mode=rwc` parameter to create the database if it doesn't exist
let connection_string = format!("sqlite:{}?mode=rwc", db_path);
let db_pool = SqlitePoolOptions::new()
.connect(
&("sqlite:".to_string()
+ &env::var("DATABASE_PATH")
.context("Parsing DATABASE_PATH from .env failed")?),
)
.connect(&connection_string)
.await
.map_err(|e| anyhow!("Failed to connect to SQLite database: {}", e))?;
let shared_db_pool = Arc::new(db_pool);
// Create the trades table if it doesn't exist
sqlx::query(
// robohash is binary hash
@ -32,12 +34,13 @@ impl CoordinatorDB {
bond_ratio INTEGER NOT NULL,
offer_duration_ts INTEGER NOT NULL,
bond_address TEXT NOT NULL,
bond_amount_sat INTEGER NOT NULL,
bond_amount_sat INTEGER NOT NULL
)",
)
.execute(&*shared_db_pool)
.execute(&db_pool)
.await?;
dbg!("Database initialized");
let shared_db_pool = Arc::new(db_pool);
Ok(Self {
db_pool: shared_db_pool,
})

View File

@ -1,24 +1,25 @@
mod communication;
mod coordinator;
// mod coordinator;
mod database;
mod wallet;
use anyhow::{anyhow, Result};
use bdk::{database::MemoryDatabase, Wallet};
use communication::{api::*, api_server};
use database::CoordinatorDB;
use dotenv::dotenv;
use std::{env, sync::Arc};
use tokio::sync::Mutex;
use wallet::CoordinatorWallet;
// populate .env with values before starting
#[tokio::main]
async fn main() -> Result<()> {
dotenv().ok();
// Initialize the database pool
let coordinator_db = CoordinatorDB::init().await?;
let wallet = CoordinatorWallet::init().await?;
let wallet = CoordinatorWallet::init()?;
api_server(coordinator_db).await?;
api_server(coordinator_db, wallet).await?;
Ok(())
}

View File

@ -3,20 +3,20 @@ use anyhow::Context;
use bdk::{
bitcoin::{self, bip32::ExtendedPrivKey},
blockchain::ElectrumBlockchain,
database::any::SledDbConfiguration,
electrum_client::Client,
sled,
sled::{self, Tree},
template::Bip86,
KeychainKind, SyncOptions, Wallet,
};
use std::str::FromStr;
#[derive(Clone, Debug)]
pub struct CoordinatorWallet {
pub wallet: Wallet<SledDbConfiguration>,
pub wallet: Arc<Mutex<Wallet<Tree>>>,
}
impl CoordinatorWallet {
pub async fn init() -> Result<Self> {
pub fn init() -> Result<Self> {
let wallet_xprv = ExtendedPrivKey::from_str(
&env::var("WALLET_XPRV").context("loading WALLET_XPRV from .env failed")?,
)?;
@ -32,8 +32,18 @@ impl CoordinatorWallet {
sled_db,
)?;
wallet.sync(&backend, SyncOptions::default()).await?;
dbg!("BDK Wallet loaded, Balance: {} SAT", wallet.get_balance()?);
Ok(CoordinatorWallet { wallet })
wallet
.sync(&backend, SyncOptions::default())
.context("Connection to electrum server failed.")?; // we could also use Esplora to make this async
dbg!(wallet.get_balance()?);
Ok(CoordinatorWallet {
wallet: Arc::new(Mutex::new(wallet)),
})
}
pub async fn get_new_address(&self) -> Result<String> {
let wallet = self.wallet.lock().await;
let address = wallet.get_address(bdk::wallet::AddressIndex::New)?;
Ok(address.address.to_string())
}
}