mod.rs 44 KB

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