mod.rs 44 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411
  1. //! SQLite Mint
  2. use std::collections::HashMap;
  3. use std::path::Path;
  4. use std::str::FromStr;
  5. use std::time::Duration;
  6. use async_trait::async_trait;
  7. use bitcoin::bip32::DerivationPath;
  8. use cdk::cdk_database::{self, MintDatabase};
  9. use cdk::mint::{MintKeySetInfo, MintQuote};
  10. use cdk::mint_url::MintUrl;
  11. use cdk::nuts::nut00::ProofsMethods;
  12. use cdk::nuts::nut05::QuoteState;
  13. use cdk::nuts::{
  14. BlindSignature, BlindSignatureDleq, CurrencyUnit, Id, MeltBolt11Request, MeltQuoteState,
  15. MintQuoteState, PaymentMethod, Proof, Proofs, PublicKey, SecretKey, State,
  16. };
  17. use cdk::secret::Secret;
  18. use cdk::types::LnKey;
  19. use cdk::{mint, Amount};
  20. use error::Error;
  21. use lightning_invoice::Bolt11Invoice;
  22. use sqlx::sqlite::{SqliteConnectOptions, SqlitePool, SqlitePoolOptions, SqliteRow};
  23. use sqlx::Row;
  24. pub mod error;
  25. /// Mint SQLite Database
  26. #[derive(Debug, Clone)]
  27. pub struct MintSqliteDatabase {
  28. pool: SqlitePool,
  29. }
  30. impl MintSqliteDatabase {
  31. /// Create new [`MintSqliteDatabase`]
  32. pub async fn new(path: &Path) -> Result<Self, Error> {
  33. let path = path.to_str().ok_or(Error::InvalidDbPath)?;
  34. let db_options = SqliteConnectOptions::from_str(path)?
  35. .busy_timeout(Duration::from_secs(5))
  36. .read_only(false)
  37. .create_if_missing(true)
  38. .auto_vacuum(sqlx::sqlite::SqliteAutoVacuum::Full);
  39. let pool = SqlitePoolOptions::new()
  40. .max_connections(1)
  41. .connect_with(db_options)
  42. .await?;
  43. Ok(Self { pool })
  44. }
  45. /// Migrate [`MintSqliteDatabase`]
  46. pub async fn migrate(&self) {
  47. sqlx::migrate!("./src/mint/migrations")
  48. .run(&self.pool)
  49. .await
  50. .expect("Could not run migrations");
  51. }
  52. }
  53. #[async_trait]
  54. impl MintDatabase for MintSqliteDatabase {
  55. type Err = cdk_database::Error;
  56. async fn set_active_keyset(&self, unit: CurrencyUnit, id: Id) -> Result<(), Self::Err> {
  57. let mut transaction = self.pool.begin().await.map_err(Error::from)?;
  58. let update_res = sqlx::query(
  59. r#"
  60. UPDATE keyset
  61. SET active=FALSE
  62. WHERE unit IS ?;
  63. "#,
  64. )
  65. .bind(unit.to_string())
  66. .execute(&mut transaction)
  67. .await;
  68. match update_res {
  69. Ok(_) => (),
  70. Err(err) => {
  71. tracing::error!("SQLite Could not update keyset");
  72. if let Err(err) = transaction.rollback().await {
  73. tracing::error!("Could not rollback sql transaction: {}", err);
  74. }
  75. return Err(Error::from(err).into());
  76. }
  77. };
  78. let update_res = sqlx::query(
  79. r#"
  80. UPDATE keyset
  81. SET active=TRUE
  82. WHERE unit IS ?
  83. AND id IS ?;
  84. "#,
  85. )
  86. .bind(unit.to_string())
  87. .bind(id.to_string())
  88. .execute(&mut transaction)
  89. .await;
  90. match update_res {
  91. Ok(_) => (),
  92. Err(err) => {
  93. tracing::error!("SQLite Could not update keyset");
  94. if let Err(err) = transaction.rollback().await {
  95. tracing::error!("Could not rollback sql transaction: {}", err);
  96. }
  97. return Err(Error::from(err).into());
  98. }
  99. };
  100. transaction.commit().await.map_err(Error::from)?;
  101. Ok(())
  102. }
  103. async fn get_active_keyset_id(&self, unit: &CurrencyUnit) -> Result<Option<Id>, Self::Err> {
  104. let mut transaction = self.pool.begin().await.map_err(Error::from)?;
  105. let rec = sqlx::query(
  106. r#"
  107. SELECT id
  108. FROM keyset
  109. WHERE active = 1
  110. AND unit IS ?
  111. "#,
  112. )
  113. .bind(unit.to_string())
  114. .fetch_one(&mut transaction)
  115. .await;
  116. let rec = match rec {
  117. Ok(rec) => {
  118. transaction.commit().await.map_err(Error::from)?;
  119. rec
  120. }
  121. Err(err) => match err {
  122. sqlx::Error::RowNotFound => {
  123. transaction.commit().await.map_err(Error::from)?;
  124. return Ok(None);
  125. }
  126. _ => {
  127. return {
  128. if let Err(err) = transaction.rollback().await {
  129. tracing::error!("Could not rollback sql transaction: {}", err);
  130. }
  131. Err(Error::SQLX(err).into())
  132. }
  133. }
  134. },
  135. };
  136. Ok(Some(
  137. Id::from_str(rec.try_get("id").map_err(Error::from)?).map_err(Error::from)?,
  138. ))
  139. }
  140. async fn get_active_keysets(&self) -> Result<HashMap<CurrencyUnit, Id>, Self::Err> {
  141. let mut transaction = self.pool.begin().await.map_err(Error::from)?;
  142. let recs = sqlx::query(
  143. r#"
  144. SELECT id, unit
  145. FROM keyset
  146. WHERE active = 1
  147. "#,
  148. )
  149. .fetch_all(&mut transaction)
  150. .await;
  151. match recs {
  152. Ok(recs) => {
  153. transaction.commit().await.map_err(Error::from)?;
  154. let keysets = recs
  155. .iter()
  156. .filter_map(|r| match Id::from_str(r.get("id")) {
  157. Ok(id) => Some((
  158. CurrencyUnit::from_str(r.get::<'_, &str, &str>("unit")).unwrap(),
  159. id,
  160. )),
  161. Err(_) => None,
  162. })
  163. .collect();
  164. Ok(keysets)
  165. }
  166. Err(err) => {
  167. tracing::error!("SQLite could not get active keyset");
  168. if let Err(err) = transaction.rollback().await {
  169. tracing::error!("Could not rollback sql transaction: {}", err);
  170. }
  171. Err(Error::from(err).into())
  172. }
  173. }
  174. }
  175. async fn add_mint_quote(&self, quote: MintQuote) -> Result<(), Self::Err> {
  176. let mut transaction = self.pool.begin().await.map_err(Error::from)?;
  177. let res = sqlx::query(
  178. r#"
  179. INSERT OR REPLACE INTO mint_quote
  180. (id, mint_url, amount, unit, request, state, expiry, request_lookup_id)
  181. VALUES (?, ?, ?, ?, ?, ?, ?, ?);
  182. "#,
  183. )
  184. .bind(quote.id.to_string())
  185. .bind(quote.mint_url.to_string())
  186. .bind(u64::from(quote.amount) as i64)
  187. .bind(quote.unit.to_string())
  188. .bind(quote.request)
  189. .bind(quote.state.to_string())
  190. .bind(quote.expiry as i64)
  191. .bind(quote.request_lookup_id)
  192. .execute(&mut transaction)
  193. .await;
  194. match res {
  195. Ok(_) => {
  196. transaction.commit().await.map_err(Error::from)?;
  197. Ok(())
  198. }
  199. Err(err) => {
  200. tracing::error!("SQLite Could not update keyset");
  201. if let Err(err) = transaction.rollback().await {
  202. tracing::error!("Could not rollback sql transaction: {}", err);
  203. }
  204. Err(Error::from(err).into())
  205. }
  206. }
  207. }
  208. async fn get_mint_quote(&self, quote_id: &str) -> Result<Option<MintQuote>, Self::Err> {
  209. let mut transaction = self.pool.begin().await.map_err(Error::from)?;
  210. let rec = sqlx::query(
  211. r#"
  212. SELECT *
  213. FROM mint_quote
  214. WHERE id=?;
  215. "#,
  216. )
  217. .bind(quote_id)
  218. .fetch_one(&mut transaction)
  219. .await;
  220. match rec {
  221. Ok(rec) => {
  222. transaction.commit().await.map_err(Error::from)?;
  223. Ok(Some(sqlite_row_to_mint_quote(rec)?))
  224. }
  225. Err(err) => match err {
  226. sqlx::Error::RowNotFound => {
  227. transaction.commit().await.map_err(Error::from)?;
  228. Ok(None)
  229. }
  230. _ => {
  231. if let Err(err) = transaction.rollback().await {
  232. tracing::error!("Could not rollback sql transaction: {}", err);
  233. }
  234. Err(Error::SQLX(err).into())
  235. }
  236. },
  237. }
  238. }
  239. async fn get_mint_quote_by_request(
  240. &self,
  241. request: &str,
  242. ) -> Result<Option<MintQuote>, Self::Err> {
  243. let mut transaction = self.pool.begin().await.map_err(Error::from)?;
  244. let rec = sqlx::query(
  245. r#"
  246. SELECT *
  247. FROM mint_quote
  248. WHERE request=?;
  249. "#,
  250. )
  251. .bind(request)
  252. .fetch_one(&mut transaction)
  253. .await;
  254. match rec {
  255. Ok(rec) => {
  256. transaction.commit().await.map_err(Error::from)?;
  257. Ok(Some(sqlite_row_to_mint_quote(rec)?))
  258. }
  259. Err(err) => match err {
  260. sqlx::Error::RowNotFound => {
  261. transaction.commit().await.map_err(Error::from)?;
  262. Ok(None)
  263. }
  264. _ => {
  265. if let Err(err) = transaction.rollback().await {
  266. tracing::error!("Could not rollback sql transaction: {}", err);
  267. }
  268. Err(Error::SQLX(err).into())
  269. }
  270. },
  271. }
  272. }
  273. async fn get_mint_quote_by_request_lookup_id(
  274. &self,
  275. request_lookup_id: &str,
  276. ) -> Result<Option<MintQuote>, Self::Err> {
  277. let mut transaction = self.pool.begin().await.map_err(Error::from)?;
  278. let rec = sqlx::query(
  279. r#"
  280. SELECT *
  281. FROM mint_quote
  282. WHERE request_lookup_id=?;
  283. "#,
  284. )
  285. .bind(request_lookup_id)
  286. .fetch_one(&mut transaction)
  287. .await;
  288. match rec {
  289. Ok(rec) => {
  290. transaction.commit().await.map_err(Error::from)?;
  291. Ok(Some(sqlite_row_to_mint_quote(rec)?))
  292. }
  293. Err(err) => match err {
  294. sqlx::Error::RowNotFound => {
  295. transaction.commit().await.map_err(Error::from)?;
  296. Ok(None)
  297. }
  298. _ => {
  299. if let Err(err) = transaction.rollback().await {
  300. tracing::error!("Could not rollback sql transaction: {}", err);
  301. }
  302. Err(Error::SQLX(err).into())
  303. }
  304. },
  305. }
  306. }
  307. async fn update_mint_quote_state(
  308. &self,
  309. quote_id: &str,
  310. state: MintQuoteState,
  311. ) -> Result<MintQuoteState, Self::Err> {
  312. let mut transaction = self.pool.begin().await.map_err(Error::from)?;
  313. let rec = sqlx::query(
  314. r#"
  315. SELECT *
  316. FROM mint_quote
  317. WHERE id=?;
  318. "#,
  319. )
  320. .bind(quote_id)
  321. .fetch_one(&mut transaction)
  322. .await;
  323. let quote = match rec {
  324. Ok(row) => sqlite_row_to_mint_quote(row)?,
  325. Err(err) => {
  326. tracing::error!("SQLite Could not update keyset");
  327. if let Err(err) = transaction.rollback().await {
  328. tracing::error!("Could not rollback sql transaction: {}", err);
  329. }
  330. return Err(Error::from(err).into());
  331. }
  332. };
  333. let update = sqlx::query(
  334. r#"
  335. UPDATE mint_quote SET state = ? WHERE id = ?
  336. "#,
  337. )
  338. .bind(state.to_string())
  339. .bind(quote_id)
  340. .execute(&mut transaction)
  341. .await;
  342. match update {
  343. Ok(_) => {
  344. transaction.commit().await.map_err(Error::from)?;
  345. Ok(quote.state)
  346. }
  347. Err(err) => {
  348. tracing::error!("SQLite Could not update keyset");
  349. if let Err(err) = transaction.rollback().await {
  350. tracing::error!("Could not rollback sql transaction: {}", err);
  351. }
  352. return Err(Error::from(err).into());
  353. }
  354. }
  355. }
  356. async fn get_mint_quotes(&self) -> Result<Vec<MintQuote>, Self::Err> {
  357. let mut transaction = self.pool.begin().await.map_err(Error::from)?;
  358. let rec = sqlx::query(
  359. r#"
  360. SELECT *
  361. FROM mint_quote
  362. "#,
  363. )
  364. .fetch_all(&mut transaction)
  365. .await;
  366. match rec {
  367. Ok(rows) => {
  368. transaction.commit().await.map_err(Error::from)?;
  369. let mint_quotes = rows
  370. .into_iter()
  371. .map(sqlite_row_to_mint_quote)
  372. .collect::<Result<Vec<MintQuote>, _>>()?;
  373. Ok(mint_quotes)
  374. }
  375. Err(err) => {
  376. tracing::error!("SQLite get mint quotes");
  377. if let Err(err) = transaction.rollback().await {
  378. tracing::error!("Could not rollback sql transaction: {}", err);
  379. }
  380. return Err(Error::from(err).into());
  381. }
  382. }
  383. }
  384. async fn remove_mint_quote(&self, quote_id: &str) -> Result<(), Self::Err> {
  385. let mut transaction = self.pool.begin().await.map_err(Error::from)?;
  386. let res = sqlx::query(
  387. r#"
  388. DELETE FROM mint_quote
  389. WHERE id=?
  390. "#,
  391. )
  392. .bind(quote_id)
  393. .execute(&mut transaction)
  394. .await;
  395. match res {
  396. Ok(_) => {
  397. transaction.commit().await.map_err(Error::from)?;
  398. Ok(())
  399. }
  400. Err(err) => {
  401. tracing::error!("SQLite Could not remove mint quote");
  402. if let Err(err) = transaction.rollback().await {
  403. tracing::error!("Could not rollback sql transaction: {}", err);
  404. }
  405. Err(Error::from(err).into())
  406. }
  407. }
  408. }
  409. async fn add_melt_quote(&self, quote: mint::MeltQuote) -> Result<(), Self::Err> {
  410. let mut transaction = self.pool.begin().await.map_err(Error::from)?;
  411. let res = sqlx::query(
  412. r#"
  413. INSERT OR REPLACE INTO melt_quote
  414. (id, unit, amount, request, fee_reserve, state, expiry, payment_preimage, request_lookup_id)
  415. VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?);
  416. "#,
  417. )
  418. .bind(quote.id.to_string())
  419. .bind(quote.unit.to_string())
  420. .bind(u64::from(quote.amount) as i64)
  421. .bind(quote.request)
  422. .bind(u64::from(quote.fee_reserve) as i64)
  423. .bind(quote.state.to_string())
  424. .bind(quote.expiry as i64)
  425. .bind(quote.payment_preimage)
  426. .bind(quote.request_lookup_id)
  427. .execute(&mut transaction)
  428. .await;
  429. match res {
  430. Ok(_) => {
  431. transaction.commit().await.map_err(Error::from)?;
  432. Ok(())
  433. }
  434. Err(err) => {
  435. tracing::error!("SQLite Could not remove mint quote");
  436. if let Err(err) = transaction.rollback().await {
  437. tracing::error!("Could not rollback sql transaction: {}", err);
  438. }
  439. Err(Error::from(err).into())
  440. }
  441. }
  442. }
  443. async fn get_melt_quote(&self, quote_id: &str) -> Result<Option<mint::MeltQuote>, Self::Err> {
  444. let mut transaction = self.pool.begin().await.map_err(Error::from)?;
  445. let rec = sqlx::query(
  446. r#"
  447. SELECT *
  448. FROM melt_quote
  449. WHERE id=?;
  450. "#,
  451. )
  452. .bind(quote_id)
  453. .fetch_one(&mut transaction)
  454. .await;
  455. match rec {
  456. Ok(rec) => {
  457. transaction.commit().await.map_err(Error::from)?;
  458. Ok(Some(sqlite_row_to_melt_quote(rec)?))
  459. }
  460. Err(err) => match err {
  461. sqlx::Error::RowNotFound => {
  462. transaction.commit().await.map_err(Error::from)?;
  463. Ok(None)
  464. }
  465. _ => {
  466. if let Err(err) = transaction.rollback().await {
  467. tracing::error!("Could not rollback sql transaction: {}", err);
  468. }
  469. Err(Error::SQLX(err).into())
  470. }
  471. },
  472. }
  473. }
  474. async fn get_melt_quotes(&self) -> Result<Vec<mint::MeltQuote>, Self::Err> {
  475. let mut transaction = self.pool.begin().await.map_err(Error::from)?;
  476. let rec = sqlx::query(
  477. r#"
  478. SELECT *
  479. FROM melt_quote
  480. "#,
  481. )
  482. .fetch_all(&mut transaction)
  483. .await
  484. .map_err(Error::from);
  485. match rec {
  486. Ok(rec) => {
  487. let melt_quotes = rec
  488. .into_iter()
  489. .map(sqlite_row_to_melt_quote)
  490. .collect::<Result<Vec<mint::MeltQuote>, _>>()?;
  491. Ok(melt_quotes)
  492. }
  493. Err(err) => {
  494. if let Err(err) = transaction.rollback().await {
  495. tracing::error!("Could not rollback sql transaction: {}", err);
  496. }
  497. Err(err.into())
  498. }
  499. }
  500. }
  501. async fn update_melt_quote_state(
  502. &self,
  503. quote_id: &str,
  504. state: MeltQuoteState,
  505. ) -> Result<MeltQuoteState, Self::Err> {
  506. let mut transaction = self.pool.begin().await.map_err(Error::from)?;
  507. let rec = sqlx::query(
  508. r#"
  509. SELECT *
  510. FROM melt_quote
  511. WHERE id=?;
  512. "#,
  513. )
  514. .bind(quote_id)
  515. .fetch_one(&mut transaction)
  516. .await;
  517. let quote = match rec {
  518. Ok(rec) => sqlite_row_to_melt_quote(rec)?,
  519. Err(err) => {
  520. tracing::error!("SQLite Could not update keyset");
  521. if let Err(err) = transaction.rollback().await {
  522. tracing::error!("Could not rollback sql transaction: {}", err);
  523. }
  524. return Err(Error::from(err).into());
  525. }
  526. };
  527. let rec = sqlx::query(
  528. r#"
  529. UPDATE melt_quote SET state = ? WHERE id = ?
  530. "#,
  531. )
  532. .bind(state.to_string())
  533. .bind(quote_id)
  534. .execute(&mut transaction)
  535. .await;
  536. match rec {
  537. Ok(_) => {
  538. transaction.commit().await.map_err(Error::from)?;
  539. }
  540. Err(err) => {
  541. tracing::error!("SQLite Could not update melt quote");
  542. if let Err(err) = transaction.rollback().await {
  543. tracing::error!("Could not rollback sql transaction: {}", err);
  544. }
  545. return Err(Error::from(err).into());
  546. }
  547. };
  548. Ok(quote.state)
  549. }
  550. async fn remove_melt_quote(&self, quote_id: &str) -> Result<(), Self::Err> {
  551. let mut transaction = self.pool.begin().await.map_err(Error::from)?;
  552. let res = sqlx::query(
  553. r#"
  554. DELETE FROM melt_quote
  555. WHERE id=?
  556. "#,
  557. )
  558. .bind(quote_id)
  559. .execute(&mut transaction)
  560. .await;
  561. match res {
  562. Ok(_) => {
  563. transaction.commit().await.map_err(Error::from)?;
  564. Ok(())
  565. }
  566. Err(err) => {
  567. tracing::error!("SQLite Could not update melt quote");
  568. if let Err(err) = transaction.rollback().await {
  569. tracing::error!("Could not rollback sql transaction: {}", err);
  570. }
  571. Err(Error::from(err).into())
  572. }
  573. }
  574. }
  575. async fn add_keyset_info(&self, keyset: MintKeySetInfo) -> Result<(), Self::Err> {
  576. let mut transaction = self.pool.begin().await.map_err(Error::from)?;
  577. let res = sqlx::query(
  578. r#"
  579. INSERT OR REPLACE INTO keyset
  580. (id, unit, active, valid_from, valid_to, derivation_path, max_order, input_fee_ppk, derivation_path_index)
  581. VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?);
  582. "#,
  583. )
  584. .bind(keyset.id.to_string())
  585. .bind(keyset.unit.to_string())
  586. .bind(keyset.active)
  587. .bind(keyset.valid_from as i64)
  588. .bind(keyset.valid_to.map(|v| v as i64))
  589. .bind(keyset.derivation_path.to_string())
  590. .bind(keyset.max_order)
  591. .bind(keyset.input_fee_ppk as i64)
  592. .bind(keyset.derivation_path_index)
  593. .execute(&mut transaction)
  594. .await;
  595. match res {
  596. Ok(_) => {
  597. transaction.commit().await.map_err(Error::from)?;
  598. Ok(())
  599. }
  600. Err(err) => {
  601. tracing::error!("SQLite could not add keyset info");
  602. if let Err(err) = transaction.rollback().await {
  603. tracing::error!("Could not rollback sql transaction: {}", err);
  604. }
  605. Err(Error::from(err).into())
  606. }
  607. }
  608. }
  609. async fn get_keyset_info(&self, id: &Id) -> Result<Option<MintKeySetInfo>, Self::Err> {
  610. let mut transaction = self.pool.begin().await.map_err(Error::from)?;
  611. let rec = sqlx::query(
  612. r#"
  613. SELECT *
  614. FROM keyset
  615. WHERE id=?;
  616. "#,
  617. )
  618. .bind(id.to_string())
  619. .fetch_one(&mut transaction)
  620. .await;
  621. match rec {
  622. Ok(rec) => {
  623. transaction.commit().await.map_err(Error::from)?;
  624. Ok(Some(sqlite_row_to_keyset_info(rec)?))
  625. }
  626. Err(err) => match err {
  627. sqlx::Error::RowNotFound => {
  628. transaction.commit().await.map_err(Error::from)?;
  629. return Ok(None);
  630. }
  631. _ => {
  632. tracing::error!("SQLite could not get keyset info");
  633. if let Err(err) = transaction.rollback().await {
  634. tracing::error!("Could not rollback sql transaction: {}", err);
  635. }
  636. return Err(Error::SQLX(err).into());
  637. }
  638. },
  639. }
  640. }
  641. async fn get_keyset_infos(&self) -> Result<Vec<MintKeySetInfo>, Self::Err> {
  642. let mut transaction = self.pool.begin().await.map_err(Error::from)?;
  643. let recs = sqlx::query(
  644. r#"
  645. SELECT *
  646. FROM keyset;
  647. "#,
  648. )
  649. .fetch_all(&mut transaction)
  650. .await
  651. .map_err(Error::from);
  652. match recs {
  653. Ok(recs) => {
  654. transaction.commit().await.map_err(Error::from)?;
  655. Ok(recs
  656. .into_iter()
  657. .map(sqlite_row_to_keyset_info)
  658. .collect::<Result<_, _>>()?)
  659. }
  660. Err(err) => {
  661. tracing::error!("SQLite could not get keyset info");
  662. if let Err(err) = transaction.rollback().await {
  663. tracing::error!("Could not rollback sql transaction: {}", err);
  664. }
  665. Err(err.into())
  666. }
  667. }
  668. }
  669. async fn add_proofs(&self, proofs: Proofs, quote_id: Option<String>) -> Result<(), Self::Err> {
  670. let mut transaction = self.pool.begin().await.map_err(Error::from)?;
  671. for proof in proofs {
  672. if let Err(err) = sqlx::query(
  673. r#"
  674. INSERT INTO proof
  675. (y, amount, keyset_id, secret, c, witness, state, quote_id)
  676. VALUES (?, ?, ?, ?, ?, ?, ?, ?);
  677. "#,
  678. )
  679. .bind(proof.y()?.to_bytes().to_vec())
  680. .bind(u64::from(proof.amount) as i64)
  681. .bind(proof.keyset_id.to_string())
  682. .bind(proof.secret.to_string())
  683. .bind(proof.c.to_bytes().to_vec())
  684. .bind(proof.witness.map(|w| serde_json::to_string(&w).unwrap()))
  685. .bind("UNSPENT")
  686. .bind(quote_id.clone())
  687. .execute(&mut transaction)
  688. .await
  689. .map_err(Error::from)
  690. {
  691. tracing::debug!("Attempting to add known proof. Skipping.... {:?}", err);
  692. }
  693. }
  694. transaction.commit().await.map_err(Error::from)?;
  695. Ok(())
  696. }
  697. async fn get_proofs_by_ys(&self, ys: &[PublicKey]) -> Result<Vec<Option<Proof>>, Self::Err> {
  698. let mut transaction = self.pool.begin().await.map_err(Error::from)?;
  699. let mut proofs = Vec::with_capacity(ys.len());
  700. for y in ys {
  701. let rec = sqlx::query(
  702. r#"
  703. SELECT *
  704. FROM proof
  705. WHERE y=?;
  706. "#,
  707. )
  708. .bind(y.to_bytes().to_vec())
  709. .fetch_one(&mut transaction)
  710. .await;
  711. match rec {
  712. Ok(rec) => {
  713. proofs.push(Some(sqlite_row_to_proof(rec)?));
  714. }
  715. Err(err) => match err {
  716. sqlx::Error::RowNotFound => proofs.push(None),
  717. _ => {
  718. if let Err(err) = transaction.rollback().await {
  719. tracing::error!("Could not rollback sql transaction: {}", err);
  720. }
  721. return Err(Error::SQLX(err).into());
  722. }
  723. },
  724. };
  725. }
  726. transaction.commit().await.map_err(Error::from)?;
  727. Ok(proofs)
  728. }
  729. async fn get_proof_ys_by_quote_id(&self, quote_id: &str) -> Result<Vec<PublicKey>, Self::Err> {
  730. let mut transaction = self.pool.begin().await.map_err(Error::from)?;
  731. let rec = sqlx::query(
  732. r#"
  733. SELECT *
  734. FROM proof
  735. WHERE quote_id=?;
  736. "#,
  737. )
  738. .bind(quote_id)
  739. .fetch_all(&mut transaction)
  740. .await;
  741. let ys = match rec {
  742. Ok(rec) => {
  743. transaction.commit().await.map_err(Error::from)?;
  744. let proofs = rec
  745. .into_iter()
  746. .map(sqlite_row_to_proof)
  747. .collect::<Result<Vec<Proof>, _>>()?;
  748. proofs.ys()?
  749. }
  750. Err(err) => match err {
  751. sqlx::Error::RowNotFound => {
  752. transaction.commit().await.map_err(Error::from)?;
  753. vec![]
  754. }
  755. _ => {
  756. if let Err(err) = transaction.rollback().await {
  757. tracing::error!("Could not rollback sql transaction: {}", err);
  758. }
  759. return Err(Error::SQLX(err).into());
  760. }
  761. },
  762. };
  763. Ok(ys)
  764. }
  765. async fn get_proofs_states(&self, ys: &[PublicKey]) -> Result<Vec<Option<State>>, Self::Err> {
  766. let mut transaction = self.pool.begin().await.map_err(Error::from)?;
  767. let mut states = Vec::with_capacity(ys.len());
  768. for y in ys {
  769. let rec = sqlx::query(
  770. r#"
  771. SELECT state
  772. FROM proof
  773. WHERE y=?;
  774. "#,
  775. )
  776. .bind(y.to_bytes().to_vec())
  777. .fetch_one(&mut transaction)
  778. .await;
  779. match rec {
  780. Ok(rec) => {
  781. let state: String = rec.get("state");
  782. let state = State::from_str(&state).map_err(Error::from)?;
  783. states.push(Some(state));
  784. }
  785. Err(err) => match err {
  786. sqlx::Error::RowNotFound => states.push(None),
  787. _ => {
  788. if let Err(err) = transaction.rollback().await {
  789. tracing::error!("Could not rollback sql transaction: {}", err);
  790. }
  791. return Err(Error::SQLX(err).into());
  792. }
  793. },
  794. };
  795. }
  796. transaction.commit().await.map_err(Error::from)?;
  797. Ok(states)
  798. }
  799. async fn get_proofs_by_keyset_id(
  800. &self,
  801. keyset_id: &Id,
  802. ) -> Result<(Proofs, Vec<Option<State>>), Self::Err> {
  803. let mut transaction = self.pool.begin().await.map_err(Error::from)?;
  804. let rec = sqlx::query(
  805. r#"
  806. SELECT *
  807. FROM proof
  808. WHERE keyset_id=?;
  809. "#,
  810. )
  811. .bind(keyset_id.to_string())
  812. .fetch_all(&mut transaction)
  813. .await;
  814. match rec {
  815. Ok(rec) => {
  816. transaction.commit().await.map_err(Error::from)?;
  817. let mut proofs_for_id = vec![];
  818. let mut states = vec![];
  819. for row in rec {
  820. let (proof, state) = sqlite_row_to_proof_with_state(row)?;
  821. proofs_for_id.push(proof);
  822. states.push(state);
  823. }
  824. Ok((proofs_for_id, states))
  825. }
  826. Err(err) => {
  827. tracing::error!("SQLite could not get proofs by keysets id");
  828. if let Err(err) = transaction.rollback().await {
  829. tracing::error!("Could not rollback sql transaction: {}", err);
  830. }
  831. return Err(Error::from(err).into());
  832. }
  833. }
  834. }
  835. async fn update_proofs_states(
  836. &self,
  837. ys: &[PublicKey],
  838. proofs_state: State,
  839. ) -> Result<Vec<Option<State>>, Self::Err> {
  840. let mut transaction = self.pool.begin().await.map_err(Error::from)?;
  841. let mut states = Vec::with_capacity(ys.len());
  842. let proofs_state = proofs_state.to_string();
  843. for y in ys {
  844. let current_state;
  845. let y = y.to_bytes().to_vec();
  846. let rec = sqlx::query(
  847. r#"
  848. SELECT state
  849. FROM proof
  850. WHERE y=?;
  851. "#,
  852. )
  853. .bind(&y)
  854. .fetch_one(&mut transaction)
  855. .await;
  856. match rec {
  857. Ok(rec) => {
  858. let state: String = rec.get("state");
  859. current_state = Some(State::from_str(&state).map_err(Error::from)?);
  860. }
  861. Err(err) => match err {
  862. sqlx::Error::RowNotFound => {
  863. current_state = None;
  864. }
  865. _ => {
  866. tracing::error!("SQLite could not get state of proof");
  867. if let Err(err) = transaction.rollback().await {
  868. tracing::error!("Could not rollback sql transaction: {}", err);
  869. }
  870. return Err(Error::SQLX(err).into());
  871. }
  872. },
  873. };
  874. states.push(current_state);
  875. if current_state != Some(State::Spent) {
  876. let res = sqlx::query(
  877. r#"
  878. UPDATE proof SET state = ? WHERE y = ?
  879. "#,
  880. )
  881. .bind(&proofs_state)
  882. .bind(y)
  883. .execute(&mut transaction)
  884. .await;
  885. if let Err(err) = res {
  886. tracing::error!("SQLite could not update proof state");
  887. if let Err(err) = transaction.rollback().await {
  888. tracing::error!("Could not rollback sql transaction: {}", err);
  889. }
  890. return Err(Error::SQLX(err).into());
  891. }
  892. }
  893. }
  894. transaction.commit().await.map_err(Error::from)?;
  895. Ok(states)
  896. }
  897. async fn add_blind_signatures(
  898. &self,
  899. blinded_messages: &[PublicKey],
  900. blinded_signatures: &[BlindSignature],
  901. quote_id: Option<String>,
  902. ) -> Result<(), Self::Err> {
  903. let mut transaction = self.pool.begin().await.map_err(Error::from)?;
  904. for (message, signature) in blinded_messages.iter().zip(blinded_signatures) {
  905. let res = sqlx::query(
  906. r#"
  907. INSERT INTO blind_signature
  908. (y, amount, keyset_id, c, quote_id, dleq_e, dleq_s)
  909. VALUES (?, ?, ?, ?, ?, ?, ?);
  910. "#,
  911. )
  912. .bind(message.to_bytes().to_vec())
  913. .bind(u64::from(signature.amount) as i64)
  914. .bind(signature.keyset_id.to_string())
  915. .bind(signature.c.to_bytes().to_vec())
  916. .bind(quote_id.clone())
  917. .bind(signature.dleq.as_ref().map(|dleq| dleq.e.to_secret_hex()))
  918. .bind(signature.dleq.as_ref().map(|dleq| dleq.s.to_secret_hex()))
  919. .execute(&mut transaction)
  920. .await;
  921. if let Err(err) = res {
  922. tracing::error!("SQLite could not add blind signature");
  923. if let Err(err) = transaction.rollback().await {
  924. tracing::error!("Could not rollback sql transaction: {}", err);
  925. }
  926. return Err(Error::SQLX(err).into());
  927. }
  928. }
  929. transaction.commit().await.map_err(Error::from)?;
  930. Ok(())
  931. }
  932. async fn get_blind_signatures(
  933. &self,
  934. blinded_messages: &[PublicKey],
  935. ) -> Result<Vec<Option<BlindSignature>>, Self::Err> {
  936. let mut transaction = self.pool.begin().await.map_err(Error::from)?;
  937. let mut signatures = Vec::with_capacity(blinded_messages.len());
  938. for message in blinded_messages {
  939. let rec = sqlx::query(
  940. r#"
  941. SELECT *
  942. FROM blind_signature
  943. WHERE y=?;
  944. "#,
  945. )
  946. .bind(message.to_bytes().to_vec())
  947. .fetch_one(&mut transaction)
  948. .await;
  949. if let Ok(row) = rec {
  950. let blinded = sqlite_row_to_blind_signature(row)?;
  951. signatures.push(Some(blinded));
  952. } else {
  953. signatures.push(None);
  954. }
  955. }
  956. transaction.commit().await.map_err(Error::from)?;
  957. Ok(signatures)
  958. }
  959. async fn get_blind_signatures_for_keyset(
  960. &self,
  961. keyset_id: &Id,
  962. ) -> Result<Vec<BlindSignature>, Self::Err> {
  963. let mut transaction = self.pool.begin().await.map_err(Error::from)?;
  964. let rec = sqlx::query(
  965. r#"
  966. SELECT *
  967. FROM blind_signature
  968. WHERE keyset_id=?;
  969. "#,
  970. )
  971. .bind(keyset_id.to_string())
  972. .fetch_all(&mut transaction)
  973. .await;
  974. match rec {
  975. Ok(rec) => {
  976. transaction.commit().await.map_err(Error::from)?;
  977. let sigs = rec
  978. .into_iter()
  979. .map(sqlite_row_to_blind_signature)
  980. .collect::<Result<Vec<BlindSignature>, _>>()?;
  981. Ok(sigs)
  982. }
  983. Err(err) => {
  984. tracing::error!("SQLite could not get vlinf signatures for keyset");
  985. if let Err(err) = transaction.rollback().await {
  986. tracing::error!("Could not rollback sql transaction: {}", err);
  987. }
  988. return Err(Error::from(err).into());
  989. }
  990. }
  991. }
  992. async fn add_melt_request(
  993. &self,
  994. melt_request: MeltBolt11Request,
  995. ln_key: LnKey,
  996. ) -> Result<(), Self::Err> {
  997. let mut transaction = self.pool.begin().await.map_err(Error::from)?;
  998. let res = sqlx::query(
  999. r#"
  1000. INSERT OR REPLACE INTO melt_request
  1001. (id, inputs, outputs, method, unit)
  1002. VALUES (?, ?, ?, ?, ?);
  1003. "#,
  1004. )
  1005. .bind(melt_request.quote)
  1006. .bind(serde_json::to_string(&melt_request.inputs)?)
  1007. .bind(serde_json::to_string(&melt_request.outputs)?)
  1008. .bind(ln_key.method.to_string())
  1009. .bind(ln_key.unit.to_string())
  1010. .execute(&mut transaction)
  1011. .await;
  1012. match res {
  1013. Ok(_) => {
  1014. transaction.commit().await.map_err(Error::from)?;
  1015. Ok(())
  1016. }
  1017. Err(err) => {
  1018. tracing::error!("SQLite Could not update keyset");
  1019. if let Err(err) = transaction.rollback().await {
  1020. tracing::error!("Could not rollback sql transaction: {}", err);
  1021. }
  1022. Err(Error::from(err).into())
  1023. }
  1024. }
  1025. }
  1026. async fn get_melt_request(
  1027. &self,
  1028. quote_id: &str,
  1029. ) -> Result<Option<(MeltBolt11Request, LnKey)>, Self::Err> {
  1030. let mut transaction = self.pool.begin().await.map_err(Error::from)?;
  1031. let rec = sqlx::query(
  1032. r#"
  1033. SELECT *
  1034. FROM melt_request
  1035. WHERE id=?;
  1036. "#,
  1037. )
  1038. .bind(quote_id)
  1039. .fetch_one(&mut transaction)
  1040. .await;
  1041. match rec {
  1042. Ok(rec) => {
  1043. transaction.commit().await.map_err(Error::from)?;
  1044. let (request, key) = sqlite_row_to_melt_request(rec)?;
  1045. Ok(Some((request, key)))
  1046. }
  1047. Err(err) => match err {
  1048. sqlx::Error::RowNotFound => {
  1049. transaction.commit().await.map_err(Error::from)?;
  1050. return Ok(None);
  1051. }
  1052. _ => {
  1053. return {
  1054. if let Err(err) = transaction.rollback().await {
  1055. tracing::error!("Could not rollback sql transaction: {}", err);
  1056. }
  1057. Err(Error::SQLX(err).into())
  1058. }
  1059. }
  1060. },
  1061. }
  1062. }
  1063. /// Get [`BlindSignature`]s for quote
  1064. async fn get_blind_signatures_for_quote(
  1065. &self,
  1066. quote_id: &str,
  1067. ) -> Result<Vec<BlindSignature>, Self::Err> {
  1068. let mut transaction = self.pool.begin().await.map_err(Error::from)?;
  1069. let recs = sqlx::query(
  1070. r#"
  1071. SELECT *
  1072. FROM blind_signature
  1073. WHERE quote_id=?;
  1074. "#,
  1075. )
  1076. .bind(quote_id)
  1077. .fetch_all(&mut transaction)
  1078. .await;
  1079. match recs {
  1080. Ok(recs) => {
  1081. transaction.commit().await.map_err(Error::from)?;
  1082. let keysets = recs
  1083. .into_iter()
  1084. .map(sqlite_row_to_blind_signature)
  1085. .collect::<Result<Vec<_>, _>>()?;
  1086. Ok(keysets)
  1087. }
  1088. Err(err) => {
  1089. tracing::error!("SQLite could not get active keyset");
  1090. if let Err(err) = transaction.rollback().await {
  1091. tracing::error!("Could not rollback sql transaction: {}", err);
  1092. }
  1093. Err(Error::from(err).into())
  1094. }
  1095. }
  1096. }
  1097. }
  1098. fn sqlite_row_to_keyset_info(row: SqliteRow) -> Result<MintKeySetInfo, Error> {
  1099. let row_id: String = row.try_get("id").map_err(Error::from)?;
  1100. let row_unit: String = row.try_get("unit").map_err(Error::from)?;
  1101. let row_active: bool = row.try_get("active").map_err(Error::from)?;
  1102. let row_valid_from: i64 = row.try_get("valid_from").map_err(Error::from)?;
  1103. let row_valid_to: Option<i64> = row.try_get("valid_to").map_err(Error::from)?;
  1104. let row_derivation_path: String = row.try_get("derivation_path").map_err(Error::from)?;
  1105. let row_max_order: u8 = row.try_get("max_order").map_err(Error::from)?;
  1106. let row_keyset_ppk: Option<i64> = row.try_get("input_fee_ppk").map_err(Error::from)?;
  1107. let row_derivation_path_index: Option<i64> =
  1108. row.try_get("derivation_path_index").map_err(Error::from)?;
  1109. Ok(MintKeySetInfo {
  1110. id: Id::from_str(&row_id).map_err(Error::from)?,
  1111. unit: CurrencyUnit::from_str(&row_unit).map_err(Error::from)?,
  1112. active: row_active,
  1113. valid_from: row_valid_from as u64,
  1114. valid_to: row_valid_to.map(|v| v as u64),
  1115. derivation_path: DerivationPath::from_str(&row_derivation_path).map_err(Error::from)?,
  1116. derivation_path_index: row_derivation_path_index.map(|d| d as u32),
  1117. max_order: row_max_order,
  1118. input_fee_ppk: row_keyset_ppk.unwrap_or(0) as u64,
  1119. })
  1120. }
  1121. fn sqlite_row_to_mint_quote(row: SqliteRow) -> Result<MintQuote, Error> {
  1122. let row_id: String = row.try_get("id").map_err(Error::from)?;
  1123. let row_mint_url: String = row.try_get("mint_url").map_err(Error::from)?;
  1124. let row_amount: i64 = row.try_get("amount").map_err(Error::from)?;
  1125. let row_unit: String = row.try_get("unit").map_err(Error::from)?;
  1126. let row_request: String = row.try_get("request").map_err(Error::from)?;
  1127. let row_state: String = row.try_get("state").map_err(Error::from)?;
  1128. let row_expiry: i64 = row.try_get("expiry").map_err(Error::from)?;
  1129. let row_request_lookup_id: Option<String> =
  1130. row.try_get("request_lookup_id").map_err(Error::from)?;
  1131. let request_lookup_id = match row_request_lookup_id {
  1132. Some(id) => id,
  1133. None => match Bolt11Invoice::from_str(&row_request) {
  1134. Ok(invoice) => invoice.payment_hash().to_string(),
  1135. Err(_) => row_request.clone(),
  1136. },
  1137. };
  1138. Ok(MintQuote {
  1139. id: row_id,
  1140. mint_url: MintUrl::from_str(&row_mint_url)?,
  1141. amount: Amount::from(row_amount as u64),
  1142. unit: CurrencyUnit::from_str(&row_unit).map_err(Error::from)?,
  1143. request: row_request,
  1144. state: MintQuoteState::from_str(&row_state).map_err(Error::from)?,
  1145. expiry: row_expiry as u64,
  1146. request_lookup_id,
  1147. })
  1148. }
  1149. fn sqlite_row_to_melt_quote(row: SqliteRow) -> Result<mint::MeltQuote, Error> {
  1150. let row_id: String = row.try_get("id").map_err(Error::from)?;
  1151. let row_unit: String = row.try_get("unit").map_err(Error::from)?;
  1152. let row_amount: i64 = row.try_get("amount").map_err(Error::from)?;
  1153. let row_request: String = row.try_get("request").map_err(Error::from)?;
  1154. let row_fee_reserve: i64 = row.try_get("fee_reserve").map_err(Error::from)?;
  1155. let row_state: String = row.try_get("state").map_err(Error::from)?;
  1156. let row_expiry: i64 = row.try_get("expiry").map_err(Error::from)?;
  1157. let row_preimage: Option<String> = row.try_get("payment_preimage").map_err(Error::from)?;
  1158. let row_request_lookup: Option<String> =
  1159. row.try_get("request_lookup_id").map_err(Error::from)?;
  1160. let request_lookup_id = row_request_lookup.unwrap_or(row_request.clone());
  1161. Ok(mint::MeltQuote {
  1162. id: row_id,
  1163. amount: Amount::from(row_amount as u64),
  1164. unit: CurrencyUnit::from_str(&row_unit).map_err(Error::from)?,
  1165. request: row_request,
  1166. fee_reserve: Amount::from(row_fee_reserve as u64),
  1167. state: QuoteState::from_str(&row_state)?,
  1168. expiry: row_expiry as u64,
  1169. payment_preimage: row_preimage,
  1170. request_lookup_id,
  1171. })
  1172. }
  1173. fn sqlite_row_to_proof(row: SqliteRow) -> Result<Proof, Error> {
  1174. let row_amount: i64 = row.try_get("amount").map_err(Error::from)?;
  1175. let keyset_id: String = row.try_get("keyset_id").map_err(Error::from)?;
  1176. let row_secret: String = row.try_get("secret").map_err(Error::from)?;
  1177. let row_c: Vec<u8> = row.try_get("c").map_err(Error::from)?;
  1178. let row_witness: Option<String> = row.try_get("witness").map_err(Error::from)?;
  1179. Ok(Proof {
  1180. amount: Amount::from(row_amount as u64),
  1181. keyset_id: Id::from_str(&keyset_id)?,
  1182. secret: Secret::from_str(&row_secret)?,
  1183. c: PublicKey::from_slice(&row_c)?,
  1184. witness: row_witness.and_then(|w| serde_json::from_str(&w).ok()),
  1185. dleq: None,
  1186. })
  1187. }
  1188. fn sqlite_row_to_proof_with_state(row: SqliteRow) -> Result<(Proof, Option<State>), Error> {
  1189. let row_amount: i64 = row.try_get("amount").map_err(Error::from)?;
  1190. let keyset_id: String = row.try_get("keyset_id").map_err(Error::from)?;
  1191. let row_secret: String = row.try_get("secret").map_err(Error::from)?;
  1192. let row_c: Vec<u8> = row.try_get("c").map_err(Error::from)?;
  1193. let row_witness: Option<String> = row.try_get("witness").map_err(Error::from)?;
  1194. let row_state: Option<String> = row.try_get("state").map_err(Error::from)?;
  1195. let state = row_state.and_then(|s| State::from_str(&s).ok());
  1196. Ok((
  1197. Proof {
  1198. amount: Amount::from(row_amount as u64),
  1199. keyset_id: Id::from_str(&keyset_id)?,
  1200. secret: Secret::from_str(&row_secret)?,
  1201. c: PublicKey::from_slice(&row_c)?,
  1202. witness: row_witness.and_then(|w| serde_json::from_str(&w).ok()),
  1203. dleq: None,
  1204. },
  1205. state,
  1206. ))
  1207. }
  1208. fn sqlite_row_to_blind_signature(row: SqliteRow) -> Result<BlindSignature, Error> {
  1209. let row_amount: i64 = row.try_get("amount").map_err(Error::from)?;
  1210. let keyset_id: String = row.try_get("keyset_id").map_err(Error::from)?;
  1211. let row_c: Vec<u8> = row.try_get("c").map_err(Error::from)?;
  1212. let row_dleq_e: Option<String> = row.try_get("dleq_e").map_err(Error::from)?;
  1213. let row_dleq_s: Option<String> = row.try_get("dleq_s").map_err(Error::from)?;
  1214. let dleq = match (row_dleq_e, row_dleq_s) {
  1215. (Some(e), Some(s)) => Some(BlindSignatureDleq {
  1216. e: SecretKey::from_hex(e)?,
  1217. s: SecretKey::from_hex(s)?,
  1218. }),
  1219. _ => None,
  1220. };
  1221. Ok(BlindSignature {
  1222. amount: Amount::from(row_amount as u64),
  1223. keyset_id: Id::from_str(&keyset_id)?,
  1224. c: PublicKey::from_slice(&row_c)?,
  1225. dleq,
  1226. })
  1227. }
  1228. fn sqlite_row_to_melt_request(row: SqliteRow) -> Result<(MeltBolt11Request, LnKey), Error> {
  1229. let quote_id: String = row.try_get("id").map_err(Error::from)?;
  1230. let row_inputs: String = row.try_get("inputs").map_err(Error::from)?;
  1231. let row_outputs: Option<String> = row.try_get("outputs").map_err(Error::from)?;
  1232. let row_method: String = row.try_get("method").map_err(Error::from)?;
  1233. let row_unit: String = row.try_get("unit").map_err(Error::from)?;
  1234. let melt_request = MeltBolt11Request {
  1235. quote: quote_id,
  1236. inputs: serde_json::from_str(&row_inputs)?,
  1237. outputs: row_outputs.and_then(|o| serde_json::from_str(&o).ok()),
  1238. };
  1239. let ln_key = LnKey {
  1240. unit: CurrencyUnit::from_str(&row_unit)?,
  1241. method: PaymentMethod::from_str(&row_method)?,
  1242. };
  1243. Ok((melt_request, ln_key))
  1244. }