Add PostgreSQL support for mint and wallet (#878)

* Add PostgreSQL support for mint and wallet

* Fixed bug to avoid empty calls `get_proofs_states`

* Fixed SQL bug

* Avoid redudant clone()

* Add more tests for the storage layer

* Minor enhacements

* Add a generic function to execute db operations

This function would log slow operations and log errors

* Provision a postgres db for tests

* Update deps for msrv

* Add postgres to pipeline

* feat: add psgl to example and docker

* feat: db url fmt

---------

Co-authored-by: thesimplekid <tsk@thesimplekid.com>
This commit is contained in:
C
2025-08-18 13:45:11 -03:00
committed by GitHub
parent 2e424e629f
commit 28a01398fd
34 changed files with 1282 additions and 40 deletions

View File

@@ -255,6 +255,9 @@ where
ys: &[PublicKey],
_quote_id: Option<Uuid>,
) -> Result<(), Self::Err> {
if ys.is_empty() {
return Ok(());
}
let total_deleted = query(
r#"
DELETE FROM proof WHERE y IN (:ys) AND state NOT IN (:exclude_state)
@@ -314,10 +317,15 @@ where
// Get payment IDs and timestamps from the mint_quote_payments table
query(
r#"
SELECT payment_id, timestamp, amount
FROM mint_quote_payments
WHERE quote_id=:quote_id;
"#,
SELECT
payment_id,
timestamp,
amount
FROM
mint_quote_payments
WHERE
quote_id=:quote_id
"#,
)?
.bind("quote_id", quote_id.as_hyphenated().to_string())
.fetch_all(conn)
@@ -407,12 +415,12 @@ where
}
async fn set_active_keyset(&mut self, unit: CurrencyUnit, id: Id) -> Result<(), Error> {
query(r#"UPDATE keyset SET active=FALSE WHERE unit IS :unit"#)?
query(r#"UPDATE keyset SET active=FALSE WHERE unit = :unit"#)?
.bind("unit", unit.to_string())
.execute(&self.inner)
.await?;
query(r#"UPDATE keyset SET active=TRUE WHERE unit IS :unit AND id IS :id"#)?
query(r#"UPDATE keyset SET active=TRUE WHERE unit = :unit AND id = :id"#)?
.bind("unit", unit.to_string())
.bind("id", id.to_string())
.execute(&self.inner)
@@ -443,7 +451,8 @@ where
async fn get_active_keyset_id(&self, unit: &CurrencyUnit) -> Result<Option<Id>, Self::Err> {
let conn = self.pool.get().map_err(|e| Error::Database(Box::new(e)))?;
Ok(
query(r#" SELECT id FROM keyset WHERE active = 1 AND unit IS :unit"#)?
query(r#" SELECT id FROM keyset WHERE active = :active AND unit = :unit"#)?
.bind("active", true)
.bind("unit", unit.to_string())
.pluck(&*conn)
.await?
@@ -458,17 +467,20 @@ where
async fn get_active_keysets(&self) -> Result<HashMap<CurrencyUnit, Id>, Self::Err> {
let conn = self.pool.get().map_err(|e| Error::Database(Box::new(e)))?;
Ok(query(r#"SELECT id, unit FROM keyset WHERE active = 1"#)?
.fetch_all(&*conn)
.await?
.into_iter()
.map(|row| {
Ok((
column_as_string!(&row[1], CurrencyUnit::from_str),
column_as_string!(&row[0], Id::from_str, Id::from_bytes),
))
})
.collect::<Result<HashMap<_, _>, Error>>()?)
Ok(
query(r#"SELECT id, unit FROM keyset WHERE active = :active"#)?
.bind("active", true)
.fetch_all(&*conn)
.await?
.into_iter()
.map(|row| {
Ok((
column_as_string!(&row[1], CurrencyUnit::from_str),
column_as_string!(&row[0], Id::from_str, Id::from_bytes),
))
})
.collect::<Result<HashMap<_, _>, Error>>()?,
)
}
async fn get_keyset_info(&self, id: &Id) -> Result<Option<MintKeySetInfo>, Self::Err> {
@@ -658,7 +670,6 @@ where
UPDATE mint_quote
SET amount_issued = :amount_issued
WHERE id = :quote_id
FOR UPDATE
"#,
)?
.bind("amount_issued", new_amount_issued.to_i64())