Skip to content

Commit

Permalink
feat: add entity events and repo
Browse files Browse the repository at this point in the history
  • Loading branch information
thevaibhav-dixit committed Oct 4, 2023
1 parent 29e0bdb commit b95e5c3
Show file tree
Hide file tree
Showing 8 changed files with 139 additions and 4 deletions.
1 change: 1 addition & 0 deletions migrations/20231004130543_stablesats_quotes.down.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
-- Add down migration script here
19 changes: 19 additions & 0 deletions migrations/20231004130543_stablesats_quotes.up.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
CREATE TYPE direction_enum AS ENUM ('BuyCents', 'SellCents');

CREATE TABLE stablesats_quote (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
direction direction_enum NOT NULL,
immediate_execution BOOLEAN NOT NULL,
sat_amount BIGINT NOT NULL,
cent_amount BIGINT NOT NULL,
expires_at TIMESTAMPTZ NOT NULL
);

CREATE TABLE stablesats_quote_events (
id UUID REFERENCES stablesats_quote(id) NOT NULL,
sequence INT NOT NULL,
event_type VARCHAR NOT NULL,
event JSONB NOT NULL,
recorded_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
UNIQUE(id, sequence)
);
2 changes: 1 addition & 1 deletion quotes-server/src/app/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ impl QuotesApp {
.price_calculator
.cents_from_sats_for_buy(Satoshis::from(sats), immediate_execution)
.await?;
let _quote = NewQuote::builder()
let quote = NewQuote::builder()
.direction(Direction::BuyCents)
.immediate_execution(immediate_execution)
.build()
Expand Down
6 changes: 3 additions & 3 deletions quotes-server/src/price/converter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,13 +136,13 @@ mod tests {
let latest_snapshot = get_trivial_payload();
let converter = VolumeBasedPriceConverter::new(latest_snapshot.asks.iter());

let sats = converter.sats_from_cents(UsdCents::from_decimal(dec!(10)));
let sats = converter.sats_from_cents(UsdCents::from(dec!(10)));
assert_eq!(sats, Satoshis::from(dec!(100)));

let sats = converter.sats_from_cents(UsdCents::from_decimal(dec!(150)));
let sats = converter.sats_from_cents(UsdCents::from(dec!(150)));
assert_eq!(sats, Satoshis::from(dec!(1010)));

let sats = converter.sats_from_cents(UsdCents::from_decimal(dec!(1500)));
let sats = converter.sats_from_cents(UsdCents::from(dec!(1500)));
assert_eq!(sats, Satoshis::from(dec!(1280)));

Ok(())
Expand Down
47 changes: 47 additions & 0 deletions quotes-server/src/quote/entity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use derive_builder::Builder;
use serde::{Deserialize, Serialize};

use crate::currency::*;
use crate::EntityEvents;

shared::entity_id! { QuoteId }

Expand Down Expand Up @@ -36,14 +37,60 @@ pub struct NewQuote {
pub(super) cent_amount: UsdCents,
pub(super) expires_at: DateTime<Utc>,
}

impl NewQuote {
pub fn builder() -> NewQuoteBuilder {
let mut builder = NewQuoteBuilder::default();
builder.id(QuoteId::new());
builder
}

pub(super) fn initial_events(self) -> EntityEvents<QuoteEvent> {
let mut events = EntityEvents::init([QuoteEvent::Initialized {
id: self.id,
direction: self.direction,
immediate_execution: self.immediate_execution,
sat_amount: self.sat_amount,
cent_amount: self.cent_amount,
expires_at: self.expires_at,
}]);
events
}
}

pub struct Quote {
pub id: QuoteId,
pub direction: Direction,
pub immediate_execution: bool,
pub sat_amount: Satoshis,
pub cent_amount: UsdCents,

pub(super) events: EntityEvents<QuoteEvent>,
}

pub mod pg {
#[derive(Debug, Clone, Copy, PartialEq, Eq, sqlx::Type)]
#[sqlx(type_name = "direction_enum", rename_all = "snake_case")]
pub enum PgDirection {
BuyCents,
SellCents,
}

impl From<super::Direction> for PgDirection {
fn from(direction: super::Direction) -> Self {
match direction {
super::Direction::BuyCents => Self::BuyCents,
super::Direction::SellCents => Self::SellCents,
}
}
}

impl From<PgDirection> for super::Direction {
fn from(direction: PgDirection) -> Self {
match direction {
PgDirection::BuyCents => Self::BuyCents,
PgDirection::SellCents => Self::SellCents,
}
}
}
}
9 changes: 9 additions & 0 deletions quotes-server/src/quote/error.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
use thiserror::Error;

#[derive(Error, Debug)]
pub enum QuoteError {
#[error("WalletError - Sqlx: {0}")]
Sqlx(#[from] sqlx::Error),
#[error("WalletError - EntityError: {0}")]
EntityError(#[from] crate::entity::EntityError),
}
4 changes: 4 additions & 0 deletions quotes-server/src/quote/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
mod entity;
mod error;
mod repo;

pub use entity::*;
pub use error::*;
pub use repo::*;
55 changes: 55 additions & 0 deletions quotes-server/src/quote/repo.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
use rust_decimal::prelude::ToPrimitive;
use sqlx::{Pool, Postgres};
use tracing::instrument;

use crate::entity::*;

use super::{pg, NewQuote, Quote, QuoteError, QuoteEvent, QuoteId};

#[derive(Debug, Clone)]
pub struct Quotes {
pool: Pool<Postgres>,
}

impl Quotes {
pub fn new(pool: &Pool<Postgres>) -> Self {
Self { pool: pool.clone() }
}

#[instrument(name = "quotes.create", skip(self))]
pub async fn create(&self, quote: NewQuote) -> Result<Quote, QuoteError> {
let mut tx = self.pool.begin().await?;
sqlx::query!(
r#"
INSERT INTO stablesats_quote (id, direction, immediate_execution, sat_amount, cent_amount, expires_at)
VALUES ($1, $2, $3, $4, $5, $6)
"#,
quote.id as QuoteId,
pg::PgDirection::from(quote.direction.clone()) as pg::PgDirection,
quote.immediate_execution,
quote.sat_amount.amount().to_i64(),
quote.cent_amount.amount().to_i64(),
quote.expires_at
)
.execute(&mut *tx)
.await?;
let res = Quote {
id: quote.id,
direction: quote.direction.clone(),
immediate_execution: quote.immediate_execution,
sat_amount: quote.sat_amount.clone(),
cent_amount: quote.cent_amount.clone(),
events: quote.clone().initial_events(),
};

EntityEvents::<QuoteEvent>::persist(
"stablesats_quote_events",
&mut tx,
quote.initial_events().new_serialized_events(res.id),
)
.await?;

tx.commit().await?;
Ok(res)
}
}

0 comments on commit b95e5c3

Please sign in to comment.