feat(NUT05): update with quote state

feat(NUT04): update with quote state

feat: db migrations for mint state

chore: remove logging
This commit is contained in:
thesimplekid
2024-06-18 21:09:49 +01:00
parent bfb59f6bec
commit 7223c5bda8
37 changed files with 1050 additions and 199 deletions

View File

@@ -5,12 +5,18 @@ pub enum Error {
/// SQLX Error
#[error(transparent)]
SQLX(#[from] sqlx::Error),
/// NUT02 Error
#[error(transparent)]
CDKNUT02(#[from] cdk::nuts::nut02::Error),
/// NUT01 Error
#[error(transparent)]
CDKNUT01(#[from] cdk::nuts::nut01::Error),
/// NUT02 Error
#[error(transparent)]
CDKNUT02(#[from] cdk::nuts::nut02::Error),
/// NUT04 Error
#[error(transparent)]
CDKNUT04(#[from] cdk::nuts::nut04::Error),
/// NUT05 Error
#[error(transparent)]
CDKNUT05(#[from] cdk::nuts::nut05::Error),
/// Secret Error
#[error(transparent)]
CDKSECRET(#[from] cdk::secret::Error),

View File

@@ -0,0 +1,5 @@
ALTER TABLE melt_quote ADD state TEXT CHECK ( state IN ('UNPAID', 'PENDING', 'PAID' ) ) NOT NULL;
ALTER TABLE melt_quote ADD payment_preimage TEXT;
ALTER TABLE melt_quote DROP COLUMN paid;
CREATE INDEX IF NOT EXISTS melt_quote_state_index ON melt_quote(state);
DROP INDEX IF EXISTS paid_index;

View File

@@ -0,0 +1,3 @@
ALTER TABLE mint_quote ADD state TEXT CHECK ( state IN ('UNPAID', 'PENDING', 'PAID', 'ISSUED' ) ) NOT NULL;
ALTER TABLE mint_quote DROP COLUMN paid;
CREATE INDEX IF NOT EXISTS mint_quote_state_index ON mint_quote(state);

View File

@@ -8,7 +8,10 @@ use async_trait::async_trait;
use bitcoin::bip32::DerivationPath;
use cdk::cdk_database::{self, MintDatabase};
use cdk::mint::MintKeySetInfo;
use cdk::nuts::{BlindSignature, CurrencyUnit, Id, Proof, PublicKey};
use cdk::nuts::nut05::QuoteState;
use cdk::nuts::{
BlindSignature, CurrencyUnit, Id, MeltQuoteState, MintQuoteState, Proof, PublicKey,
};
use cdk::secret::Secret;
use cdk::types::{MeltQuote, MintQuote};
use cdk::Amount;
@@ -122,7 +125,7 @@ WHERE active = 1
sqlx::query(
r#"
INSERT OR REPLACE INTO mint_quote
(id, mint_url, amount, unit, request, paid, expiry)
(id, mint_url, amount, unit, request, state, expiry)
VALUES (?, ?, ?, ?, ?, ?, ?);
"#,
)
@@ -131,7 +134,7 @@ VALUES (?, ?, ?, ?, ?, ?, ?);
.bind(u64::from(quote.amount) as i64)
.bind(quote.unit.to_string())
.bind(quote.request)
.bind(quote.paid)
.bind(quote.state.to_string())
.bind(quote.expiry as i64)
.execute(&self.pool)
.await
@@ -162,6 +165,44 @@ WHERE id=?;
Ok(Some(sqlite_row_to_mint_quote(rec)?))
}
async fn update_mint_quote_state(
&self,
quote_id: &str,
state: MintQuoteState,
) -> Result<MintQuoteState, Self::Err> {
let mut transaction = self.pool.begin().await.map_err(Error::from)?;
let rec = sqlx::query(
r#"
SELECT *
FROM mint_quote
WHERE id=?;
"#,
)
.bind(quote_id)
.fetch_one(&mut transaction)
.await
.map_err(Error::from)?;
let quote = sqlite_row_to_mint_quote(rec)?;
sqlx::query(
r#"
UPDATE mint_quote SET state = ? WHERE id = ?
"#,
)
.bind(state.to_string())
.bind(quote_id)
.execute(&mut transaction)
.await
.map_err(Error::from)?;
transaction.commit().await.map_err(Error::from)?;
Ok(quote.state)
}
async fn get_mint_quotes(&self) -> Result<Vec<MintQuote>, Self::Err> {
let rec = sqlx::query(
r#"
@@ -196,8 +237,8 @@ WHERE id=?
sqlx::query(
r#"
INSERT OR REPLACE INTO melt_quote
(id, unit, amount, request, fee_reserve, paid, expiry)
VALUES (?, ?, ?, ?, ?, ?, ?);
(id, unit, amount, request, fee_reserve, state, expiry, payment_preimage)
VALUES (?, ?, ?, ?, ?, ?, ?, ?);
"#,
)
.bind(quote.id.to_string())
@@ -205,8 +246,9 @@ VALUES (?, ?, ?, ?, ?, ?, ?);
.bind(u64::from(quote.amount) as i64)
.bind(quote.request)
.bind(u64::from(quote.fee_reserve) as i64)
.bind(quote.paid)
.bind(quote.state.to_string())
.bind(quote.expiry as i64)
.bind(quote.payment_preimage)
.execute(&self.pool)
.await
.map_err(Error::from)?;
@@ -250,6 +292,44 @@ FROM melt_quote
Ok(melt_quotes)
}
async fn update_melt_quote_state(
&self,
quote_id: &str,
state: MeltQuoteState,
) -> Result<MeltQuoteState, Self::Err> {
let mut transaction = self.pool.begin().await.map_err(Error::from)?;
let rec = sqlx::query(
r#"
SELECT *
FROM melt_quote
WHERE id=?;
"#,
)
.bind(quote_id)
.fetch_one(&mut transaction)
.await
.map_err(Error::from)?;
let quote = sqlite_row_to_melt_quote(rec)?;
sqlx::query(
r#"
UPDATE melt_quote SET state = ? WHERE id = ?
"#,
)
.bind(state.to_string())
.bind(quote_id)
.execute(&mut transaction)
.await
.map_err(Error::from)?;
transaction.commit().await.map_err(Error::from)?;
Ok(quote.state)
}
async fn remove_melt_quote(&self, quote_id: &str) -> Result<(), Self::Err> {
sqlx::query(
r#"
@@ -581,7 +661,7 @@ fn sqlite_row_to_mint_quote(row: SqliteRow) -> Result<MintQuote, Error> {
let row_amount: i64 = row.try_get("amount").map_err(Error::from)?;
let row_unit: String = row.try_get("unit").map_err(Error::from)?;
let row_request: String = row.try_get("request").map_err(Error::from)?;
let row_paid: bool = row.try_get("paid").map_err(Error::from)?;
let row_state: String = row.try_get("state").map_err(Error::from)?;
let row_expiry: i64 = row.try_get("expiry").map_err(Error::from)?;
Ok(MintQuote {
@@ -590,7 +670,7 @@ fn sqlite_row_to_mint_quote(row: SqliteRow) -> Result<MintQuote, Error> {
amount: Amount::from(row_amount as u64),
unit: CurrencyUnit::from(row_unit),
request: row_request,
paid: row_paid,
state: MintQuoteState::from_str(&row_state).map_err(Error::from)?,
expiry: row_expiry as u64,
})
}
@@ -601,8 +681,9 @@ fn sqlite_row_to_melt_quote(row: SqliteRow) -> Result<MeltQuote, Error> {
let row_amount: i64 = row.try_get("amount").map_err(Error::from)?;
let row_request: String = row.try_get("request").map_err(Error::from)?;
let row_fee_reserve: i64 = row.try_get("fee_reserve").map_err(Error::from)?;
let row_paid: bool = row.try_get("paid").map_err(Error::from)?;
let row_state: String = row.try_get("state").map_err(Error::from)?;
let row_expiry: i64 = row.try_get("expiry").map_err(Error::from)?;
let row_preimage: Option<String> = row.try_get("payment_preimage").map_err(Error::from)?;
Ok(MeltQuote {
id: row_id,
@@ -610,8 +691,9 @@ fn sqlite_row_to_melt_quote(row: SqliteRow) -> Result<MeltQuote, Error> {
unit: CurrencyUnit::from(row_unit),
request: row_request,
fee_reserve: Amount::from(row_fee_reserve as u64),
paid: row_paid,
state: QuoteState::from_str(&row_state)?,
expiry: row_expiry as u64,
payment_preimage: row_preimage,
})
}

View File

@@ -17,6 +17,12 @@ pub enum Error {
/// NUT02 Error
#[error(transparent)]
CDKNUT02(#[from] cdk::nuts::nut02::Error),
/// NUT04 Error
#[error(transparent)]
CDKNUT04(#[from] cdk::nuts::nut04::Error),
/// NUT05 Error
#[error(transparent)]
CDKNUT05(#[from] cdk::nuts::nut05::Error),
/// NUT07 Error
#[error(transparent)]
CDKNUT07(#[from] cdk::nuts::nut07::Error),

View File

@@ -0,0 +1,5 @@
ALTER TABLE melt_quote ADD state TEXT CHECK ( state IN ('UNPAID', 'PENDING', 'PAID' ) ) NOT NULL;
ALTER TABLE melt_quote ADD payment_preimage TEXT;
ALTER TABLE melt_quote DROP COLUMN paid;
CREATE INDEX IF NOT EXISTS melt_quote_state_index ON melt_quote(state);
DROP INDEX IF EXISTS paid_index;

View File

@@ -0,0 +1,3 @@
ALTER TABLE mint_quote ADD state TEXT CHECK ( state IN ('UNPAID', 'PENDING', 'PAID', 'ISSUED' ) ) NOT NULL;
ALTER TABLE mint_quote DROP COLUMN paid;
CREATE INDEX IF NOT EXISTS mint_quote_state_index ON mint_quote(state);

View File

@@ -7,8 +7,8 @@ use std::str::FromStr;
use async_trait::async_trait;
use cdk::cdk_database::{self, WalletDatabase};
use cdk::nuts::{
CurrencyUnit, Id, KeySetInfo, Keys, MintInfo, Proof, Proofs, PublicKey, SpendingConditions,
State,
CurrencyUnit, Id, KeySetInfo, Keys, MeltQuoteState, MintInfo, MintQuoteState, Proof, Proofs,
PublicKey, SpendingConditions, State,
};
use cdk::secret::Secret;
use cdk::types::{MeltQuote, MintQuote, ProofInfo};
@@ -278,7 +278,7 @@ WHERE id=?
sqlx::query(
r#"
INSERT OR REPLACE INTO mint_quote
(id, mint_url, amount, unit, request, paid, expiry)
(id, mint_url, amount, unit, request, state, expiry)
VALUES (?, ?, ?, ?, ?, ?, ?);
"#,
)
@@ -287,7 +287,7 @@ VALUES (?, ?, ?, ?, ?, ?, ?);
.bind(u64::from(quote.amount) as i64)
.bind(quote.unit.to_string())
.bind(quote.request)
.bind(quote.paid)
.bind(quote.state.to_string())
.bind(quote.expiry as i64)
.execute(&self.pool)
.await
@@ -351,7 +351,7 @@ WHERE id=?
sqlx::query(
r#"
INSERT OR REPLACE INTO melt_quote
(id, unit, amount, request, fee_reserve, paid, expiry)
(id, unit, amount, request, fee_reserve, state, expiry)
VALUES (?, ?, ?, ?, ?, ?, ?);
"#,
)
@@ -360,7 +360,7 @@ VALUES (?, ?, ?, ?, ?, ?, ?);
.bind(u64::from(quote.amount) as i64)
.bind(quote.request)
.bind(u64::from(quote.fee_reserve) as i64)
.bind(quote.paid)
.bind(quote.state.to_string())
.bind(quote.expiry as i64)
.execute(&self.pool)
.await
@@ -502,8 +502,6 @@ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?);
state: Option<Vec<State>>,
spending_conditions: Option<Vec<SpendingConditions>>,
) -> Result<Option<Vec<ProofInfo>>, Self::Err> {
tracing::debug!("{:?}", mint_url);
tracing::debug!("{:?}", unit);
let recs = sqlx::query(
r#"
SELECT *
@@ -719,16 +717,18 @@ fn sqlite_row_to_mint_quote(row: &SqliteRow) -> Result<MintQuote, Error> {
let row_amount: i64 = row.try_get("amount").map_err(Error::from)?;
let row_unit: String = row.try_get("unit").map_err(Error::from)?;
let row_request: String = row.try_get("request").map_err(Error::from)?;
let row_paid: bool = row.try_get("paid").map_err(Error::from)?;
let row_state: String = row.try_get("state").map_err(Error::from)?;
let row_expiry: i64 = row.try_get("expiry").map_err(Error::from)?;
let state = MintQuoteState::from_str(&row_state)?;
Ok(MintQuote {
id: row_id,
mint_url: row_mint_url.into(),
amount: Amount::from(row_amount as u64),
unit: CurrencyUnit::from(row_unit),
request: row_request,
paid: row_paid,
state,
expiry: row_expiry as u64,
})
}
@@ -739,17 +739,20 @@ fn sqlite_row_to_melt_quote(row: &SqliteRow) -> Result<MeltQuote, Error> {
let row_amount: i64 = row.try_get("amount").map_err(Error::from)?;
let row_request: String = row.try_get("request").map_err(Error::from)?;
let row_fee_reserve: i64 = row.try_get("fee_reserve").map_err(Error::from)?;
let row_paid: bool = row.try_get("paid").map_err(Error::from)?;
let row_state: String = row.try_get("state").map_err(Error::from)?;
let row_expiry: i64 = row.try_get("expiry").map_err(Error::from)?;
let row_preimage: Option<String> = row.try_get("payment_preimage").map_err(Error::from)?;
let state = MeltQuoteState::from_str(&row_state)?;
Ok(MeltQuote {
id: row_id,
amount: Amount::from(row_amount as u64),
unit: CurrencyUnit::from(row_unit),
request: row_request,
fee_reserve: Amount::from(row_fee_reserve as u64),
paid: row_paid,
state,
expiry: row_expiry as u64,
payment_preimage: row_preimage,
})
}