wallet.rs 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751
  1. //! Rexie Browser Database
  2. use std::collections::{HashMap, HashSet};
  3. use std::rc::Rc;
  4. use std::result::Result;
  5. use async_trait::async_trait;
  6. use cdk::cdk_database::{self, WalletDatabase};
  7. use cdk::mint_url::MintUrl;
  8. use cdk::nuts::{
  9. CurrencyUnit, Id, KeySetInfo, Keys, MintInfo, PublicKey, SpendingConditions, State,
  10. };
  11. use cdk::types::ProofInfo;
  12. use cdk::util::unix_time;
  13. use cdk::wallet::{MeltQuote, MintQuote};
  14. use rexie::*;
  15. use thiserror::Error;
  16. use tokio::sync::Mutex;
  17. // Tables
  18. const MINTS: &str = "mints";
  19. const MINT_KEYSETS: &str = "keysets_by_mint";
  20. const KEYSETS: &str = "keysets";
  21. const MINT_KEYS: &str = "mint_keys";
  22. const MINT_QUOTES: &str = "mint_quotes";
  23. const MELT_QUOTES: &str = "melt_quotes";
  24. const PROOFS: &str = "proofs";
  25. const CONFIG: &str = "config";
  26. const KEYSET_COUNTER: &str = "keyset_counter";
  27. const DATABASE_VERSION: u32 = 4;
  28. /// Rexie Database Error
  29. #[derive(Debug, Error)]
  30. pub enum Error {
  31. /// CDK Database Error
  32. #[error(transparent)]
  33. CDKDatabase(#[from] cdk::cdk_database::Error),
  34. /// Rexie Error
  35. #[error(transparent)]
  36. Rexie(#[from] rexie::Error),
  37. /// Serde Wasm Error
  38. #[error(transparent)]
  39. SerdeBindgen(#[from] serde_wasm_bindgen::Error),
  40. /// NUT00 Error
  41. #[error(transparent)]
  42. NUT00(cdk::nuts::nut00::Error),
  43. #[error("Not found")]
  44. /// Not Found
  45. NotFound,
  46. }
  47. impl From<Error> for cdk::cdk_database::Error {
  48. fn from(e: Error) -> Self {
  49. Self::Database(Box::new(e))
  50. }
  51. }
  52. // These are okay because we never actually send across threads in the browser
  53. unsafe impl Send for Error {}
  54. unsafe impl Sync for Error {}
  55. /// Wallet Rexie Database
  56. #[derive(Debug, Clone)]
  57. pub struct WalletRexieDatabase {
  58. db: Rc<Mutex<Rexie>>,
  59. }
  60. // These are okay because we never actually send across threads in the browser
  61. unsafe impl Send for WalletRexieDatabase {}
  62. unsafe impl Sync for WalletRexieDatabase {}
  63. impl WalletRexieDatabase {
  64. /// Create new [`WalletRexieDatabase`]
  65. pub async fn new() -> Result<Self, Error> {
  66. let rexie = Rexie::builder("cdk")
  67. .version(DATABASE_VERSION)
  68. .add_object_store(
  69. ObjectStore::new(PROOFS)
  70. .add_index(Index::new("y", "y").unique(true))
  71. .add_index(Index::new("mint_url", "mint_url"))
  72. .add_index(Index::new("state", "state"))
  73. .add_index(Index::new("unit", "unit")),
  74. )
  75. .add_object_store(
  76. ObjectStore::new(MINTS).add_index(Index::new("mint_url", "mint_url").unique(true)),
  77. )
  78. .add_object_store(ObjectStore::new(MINT_KEYSETS))
  79. .add_object_store(
  80. ObjectStore::new(KEYSETS)
  81. .add_index(Index::new("keyset_id", "keyset_id").unique(true)),
  82. )
  83. .add_object_store(
  84. ObjectStore::new(MINT_KEYS)
  85. .add_index(Index::new("keyset_id", "keyset_id").unique(true)),
  86. )
  87. .add_object_store(ObjectStore::new(MINT_QUOTES))
  88. .add_object_store(ObjectStore::new(MELT_QUOTES))
  89. .add_object_store(ObjectStore::new(CONFIG))
  90. .add_object_store(ObjectStore::new(KEYSET_COUNTER))
  91. // Build the database
  92. .build()
  93. .await
  94. .unwrap();
  95. Ok(Self {
  96. db: Rc::new(Mutex::new(rexie)),
  97. })
  98. }
  99. async fn set_proof_states(
  100. &self,
  101. ys: Vec<PublicKey>,
  102. state: State,
  103. ) -> Result<(), cdk_database::Error> {
  104. let rexie = self.db.lock().await;
  105. let transaction = rexie
  106. .transaction(&[PROOFS], TransactionMode::ReadWrite)
  107. .map_err(Error::from)?;
  108. let proofs_store = transaction.store(PROOFS).map_err(Error::from)?;
  109. for y in ys {
  110. let y = serde_wasm_bindgen::to_value(&y).map_err(Error::from)?;
  111. let mut proof: ProofInfo = proofs_store
  112. .get(y.clone())
  113. .await
  114. .map_err(Error::from)?
  115. .and_then(|p| serde_wasm_bindgen::from_value(p).ok())
  116. .ok_or(Error::NotFound)?;
  117. proof.state = state;
  118. let proof = serde_wasm_bindgen::to_value(&proof).map_err(Error::from)?;
  119. proofs_store
  120. .put(&proof, Some(&y))
  121. .await
  122. .map_err(Error::from)?;
  123. }
  124. transaction.done().await.map_err(Error::from)?;
  125. Ok(())
  126. }
  127. }
  128. #[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
  129. #[cfg_attr(not(target_arch = "wasm32"), async_trait)]
  130. impl WalletDatabase for WalletRexieDatabase {
  131. type Err = cdk::cdk_database::Error;
  132. async fn add_mint(
  133. &self,
  134. mint_url: MintUrl,
  135. mint_info: Option<MintInfo>,
  136. ) -> Result<(), Self::Err> {
  137. let rexie = self.db.lock().await;
  138. let transaction = rexie
  139. .transaction(&[MINTS], TransactionMode::ReadWrite)
  140. .map_err(Error::from)?;
  141. let mints_store = transaction.store(MINTS).map_err(Error::from)?;
  142. let mint_url = serde_wasm_bindgen::to_value(&mint_url).map_err(Error::from)?;
  143. let mint_info = serde_wasm_bindgen::to_value(&mint_info).map_err(Error::from)?;
  144. mints_store
  145. .put(&mint_info, Some(&mint_url))
  146. .await
  147. .map_err(Error::from)?;
  148. transaction.done().await.map_err(Error::from)?;
  149. Ok(())
  150. }
  151. async fn remove_mint(&self, mint_url: MintUrl) -> Result<(), Self::Err> {
  152. let rexie = self.db.lock().await;
  153. let transaction = rexie
  154. .transaction(&[MINTS], TransactionMode::ReadWrite)
  155. .map_err(Error::from)?;
  156. let mints_store = transaction.store(MINTS).map_err(Error::from)?;
  157. let mint_url = serde_wasm_bindgen::to_value(&mint_url).map_err(Error::from)?;
  158. mints_store.delete(mint_url).await.map_err(Error::from)?;
  159. transaction.done().await.map_err(Error::from)?;
  160. Ok(())
  161. }
  162. async fn get_mint(&self, mint_url: MintUrl) -> Result<Option<MintInfo>, Self::Err> {
  163. let rexie = self.db.lock().await;
  164. let transaction = rexie
  165. .transaction(&[MINTS], TransactionMode::ReadOnly)
  166. .map_err(Error::from)?;
  167. let mints_store = transaction.store(MINTS).map_err(Error::from)?;
  168. let mint_url = serde_wasm_bindgen::to_value(&mint_url).map_err(Error::from)?;
  169. let mint_info = mints_store
  170. .get(mint_url)
  171. .await
  172. .map_err(Error::from)?
  173. .and_then(|m| serde_wasm_bindgen::from_value(m).ok());
  174. Ok(mint_info)
  175. }
  176. async fn get_mints(&self) -> Result<HashMap<MintUrl, Option<MintInfo>>, Self::Err> {
  177. let rexie = self.db.lock().await;
  178. let transaction = rexie
  179. .transaction(&[MINTS], TransactionMode::ReadOnly)
  180. .map_err(Error::from)?;
  181. let mints_store = transaction.store(MINTS).map_err(Error::from)?;
  182. let mints = mints_store
  183. .scan(None, None, None, None)
  184. .await
  185. .map_err(Error::from)?;
  186. let mints: HashMap<MintUrl, Option<MintInfo>> = mints
  187. .into_iter()
  188. .map(|(url, info)| {
  189. (
  190. serde_wasm_bindgen::from_value(url).unwrap(),
  191. serde_wasm_bindgen::from_value(info).unwrap(),
  192. )
  193. })
  194. .collect();
  195. Ok(mints)
  196. }
  197. async fn update_mint_url(
  198. &self,
  199. old_mint_url: MintUrl,
  200. new_mint_url: MintUrl,
  201. ) -> Result<(), Self::Err> {
  202. let proofs = self
  203. .get_proofs(Some(old_mint_url), None, None, None)
  204. .await
  205. .map_err(Error::from)?;
  206. let updated_proofs: Vec<ProofInfo> = proofs
  207. .into_iter()
  208. .map(|mut p| {
  209. p.mint_url = new_mint_url.clone();
  210. p
  211. })
  212. .collect();
  213. if !updated_proofs.is_empty() {
  214. self.update_proofs(updated_proofs, vec![]).await?;
  215. }
  216. // Update mint quotes
  217. {
  218. let quotes = self.get_mint_quotes().await?;
  219. let unix_time = unix_time();
  220. let quotes: Vec<MintQuote> = quotes
  221. .into_iter()
  222. .filter_map(|mut q| {
  223. if q.expiry < unix_time {
  224. q.mint_url = new_mint_url.clone();
  225. Some(q)
  226. } else {
  227. None
  228. }
  229. })
  230. .collect();
  231. for quote in quotes {
  232. self.add_mint_quote(quote).await?;
  233. }
  234. }
  235. Ok(())
  236. }
  237. async fn add_mint_keysets(
  238. &self,
  239. mint_url: MintUrl,
  240. keysets: Vec<KeySetInfo>,
  241. ) -> Result<(), Self::Err> {
  242. let rexie = self.db.lock().await;
  243. let transaction = rexie
  244. .transaction(&[MINT_KEYSETS, KEYSETS], TransactionMode::ReadWrite)
  245. .map_err(Error::from)?;
  246. let mint_keysets_store = transaction.store(MINT_KEYSETS).map_err(Error::from)?;
  247. let keysets_store = transaction.store(KEYSETS).map_err(Error::from)?;
  248. let mint_url = serde_wasm_bindgen::to_value(&mint_url).map_err(Error::from)?;
  249. let mut mint_keysets = mint_keysets_store
  250. .get(mint_url.clone())
  251. .await
  252. .map_err(Error::from)?
  253. .and_then(|m| serde_wasm_bindgen::from_value(m).ok());
  254. let new_keyset_ids: Vec<Id> = keysets.iter().map(|k| k.id).collect();
  255. mint_keysets
  256. .as_mut()
  257. .unwrap_or(&mut HashSet::new())
  258. .extend(new_keyset_ids);
  259. let mint_keysets = serde_wasm_bindgen::to_value(&mint_keysets).map_err(Error::from)?;
  260. mint_keysets_store
  261. .put(&mint_keysets, Some(&mint_url))
  262. .await
  263. .map_err(Error::from)?;
  264. for keyset in keysets {
  265. let id = serde_wasm_bindgen::to_value(&keyset.id).map_err(Error::from)?;
  266. let keyset = serde_wasm_bindgen::to_value(&keyset).map_err(Error::from)?;
  267. keysets_store
  268. .put(&keyset, Some(&id))
  269. .await
  270. .map_err(Error::from)?;
  271. }
  272. transaction.done().await.map_err(Error::from)?;
  273. Ok(())
  274. }
  275. async fn get_mint_keysets(
  276. &self,
  277. mint_url: MintUrl,
  278. ) -> Result<Option<Vec<KeySetInfo>>, Self::Err> {
  279. let rexie = self.db.lock().await;
  280. let transaction = rexie
  281. .transaction(&[MINT_KEYSETS, KEYSETS], TransactionMode::ReadOnly)
  282. .map_err(Error::from)?;
  283. let mints_store = transaction.store(MINT_KEYSETS).map_err(Error::from)?;
  284. let mint_url = serde_wasm_bindgen::to_value(&mint_url).map_err(Error::from)?;
  285. let mint_keysets: Option<HashSet<Id>> = mints_store
  286. .get(mint_url)
  287. .await
  288. .map_err(Error::from)?
  289. .and_then(|m| serde_wasm_bindgen::from_value(m).ok());
  290. let keysets_store = transaction.store(KEYSETS).map_err(Error::from)?;
  291. let keysets = match mint_keysets {
  292. Some(mint_keysets) => {
  293. let mut keysets = vec![];
  294. for mint_keyset in mint_keysets {
  295. let id = serde_wasm_bindgen::to_value(&mint_keyset).map_err(Error::from)?;
  296. let keyset = keysets_store
  297. .get(id)
  298. .await
  299. .map_err(Error::from)?
  300. .and_then(|k| serde_wasm_bindgen::from_value(k).ok());
  301. keysets.push(keyset);
  302. }
  303. let keysets = keysets.iter().flatten().cloned().collect();
  304. Some(keysets)
  305. }
  306. None => None,
  307. };
  308. transaction.done().await.map_err(Error::from)?;
  309. Ok(keysets)
  310. }
  311. async fn get_keyset_by_id(&self, keyset_id: &Id) -> Result<Option<KeySetInfo>, Self::Err> {
  312. let rexie = self.db.lock().await;
  313. let transaction = rexie
  314. .transaction(&[KEYSETS], TransactionMode::ReadOnly)
  315. .map_err(Error::from)?;
  316. let keysets_store = transaction.store(KEYSETS).map_err(Error::from)?;
  317. let keyset_id = serde_wasm_bindgen::to_value(keyset_id).map_err(Error::from)?;
  318. let keyset = keysets_store
  319. .get(keyset_id)
  320. .await
  321. .map_err(Error::from)?
  322. .and_then(|k| serde_wasm_bindgen::from_value(k).ok());
  323. Ok(keyset)
  324. }
  325. async fn add_mint_quote(&self, quote: MintQuote) -> Result<(), Self::Err> {
  326. let rexie = self.db.lock().await;
  327. let transaction = rexie
  328. .transaction(&[MINT_QUOTES], TransactionMode::ReadWrite)
  329. .map_err(Error::from)?;
  330. let quotes_store = transaction.store(MINT_QUOTES).map_err(Error::from)?;
  331. let quote_id = serde_wasm_bindgen::to_value(&quote.id).map_err(Error::from)?;
  332. let quote = serde_wasm_bindgen::to_value(&quote).map_err(Error::from)?;
  333. quotes_store
  334. .put(&quote, Some(&quote_id))
  335. .await
  336. .map_err(Error::from)?;
  337. transaction.done().await.map_err(Error::from)?;
  338. Ok(())
  339. }
  340. async fn get_mint_quote(&self, quote_id: &str) -> Result<Option<MintQuote>, Self::Err> {
  341. let rexie = self.db.lock().await;
  342. let transaction = rexie
  343. .transaction(&[MINT_QUOTES], TransactionMode::ReadOnly)
  344. .map_err(Error::from)?;
  345. let quotes_store = transaction.store(MINT_QUOTES).map_err(Error::from)?;
  346. let quote_id = serde_wasm_bindgen::to_value(&quote_id).map_err(Error::from)?;
  347. let quote = quotes_store
  348. .get(quote_id)
  349. .await
  350. .map_err(Error::from)?
  351. .and_then(|q| serde_wasm_bindgen::from_value(q).ok());
  352. Ok(quote)
  353. }
  354. async fn get_mint_quotes(&self) -> Result<Vec<MintQuote>, Self::Err> {
  355. let rexie = self.db.lock().await;
  356. let transaction = rexie
  357. .transaction(&[MINT_QUOTES], TransactionMode::ReadOnly)
  358. .map_err(Error::from)?;
  359. let quotes_store = transaction.store(MINT_QUOTES).map_err(Error::from)?;
  360. let quotes = quotes_store
  361. .scan(None, None, None, None)
  362. .await
  363. .map_err(Error::from)?;
  364. Ok(quotes
  365. .into_iter()
  366. .map(|(_id, q)| serde_wasm_bindgen::from_value(q))
  367. .collect::<Result<Vec<MintQuote>, serde_wasm_bindgen::Error>>()
  368. .map_err(<serde_wasm_bindgen::Error as Into<Error>>::into)?)
  369. }
  370. async fn remove_mint_quote(&self, quote_id: &str) -> Result<(), Self::Err> {
  371. let rexie = self.db.lock().await;
  372. let transaction = rexie
  373. .transaction(&[MINT_QUOTES], TransactionMode::ReadWrite)
  374. .map_err(Error::from)?;
  375. let quotes_store = transaction.store(MINT_QUOTES).map_err(Error::from)?;
  376. let quote_id = serde_wasm_bindgen::to_value(&quote_id).map_err(Error::from)?;
  377. quotes_store.delete(quote_id).await.map_err(Error::from)?;
  378. transaction.done().await.map_err(Error::from)?;
  379. Ok(())
  380. }
  381. async fn add_melt_quote(&self, quote: MeltQuote) -> Result<(), Self::Err> {
  382. let rexie = self.db.lock().await;
  383. let transaction = rexie
  384. .transaction(&[MELT_QUOTES], TransactionMode::ReadWrite)
  385. .map_err(Error::from)?;
  386. let quotes_store = transaction.store(MELT_QUOTES).map_err(Error::from)?;
  387. let quote_id = serde_wasm_bindgen::to_value(&quote.id).map_err(Error::from)?;
  388. let quote = serde_wasm_bindgen::to_value(&quote).map_err(Error::from)?;
  389. quotes_store
  390. .put(&quote, Some(&quote_id))
  391. .await
  392. .map_err(Error::from)?;
  393. transaction.done().await.map_err(Error::from)?;
  394. Ok(())
  395. }
  396. async fn get_melt_quote(&self, quote_id: &str) -> Result<Option<MeltQuote>, Self::Err> {
  397. let rexie = self.db.lock().await;
  398. let transaction = rexie
  399. .transaction(&[MELT_QUOTES], TransactionMode::ReadOnly)
  400. .map_err(Error::from)?;
  401. let quotes_store = transaction.store(MELT_QUOTES).map_err(Error::from)?;
  402. let quote_id = serde_wasm_bindgen::to_value(&quote_id).map_err(Error::from)?;
  403. let quote = quotes_store
  404. .get(quote_id)
  405. .await
  406. .map_err(Error::from)?
  407. .and_then(|q| serde_wasm_bindgen::from_value(q).ok());
  408. Ok(quote)
  409. }
  410. async fn remove_melt_quote(&self, quote_id: &str) -> Result<(), Self::Err> {
  411. let rexie = self.db.lock().await;
  412. let transaction = rexie
  413. .transaction(&[MELT_QUOTES], TransactionMode::ReadWrite)
  414. .map_err(Error::from)?;
  415. let quotes_store = transaction.store(MELT_QUOTES).map_err(Error::from)?;
  416. let quote_id = serde_wasm_bindgen::to_value(&quote_id).map_err(Error::from)?;
  417. quotes_store.delete(quote_id).await.map_err(Error::from)?;
  418. transaction.done().await.map_err(Error::from)?;
  419. Ok(())
  420. }
  421. async fn add_keys(&self, keyset: KeySet) -> Result<(), Self::Err> {
  422. // Verify ID by recomputing id
  423. keyset.verify_id()?;
  424. let rexie = self.db.lock().await;
  425. let transaction = rexie
  426. .transaction(&[MINT_KEYS], TransactionMode::ReadWrite)
  427. .map_err(Error::from)?;
  428. let keys_store = transaction.store(MINT_KEYS).map_err(Error::from)?;
  429. let keyset_id = serde_wasm_bindgen::to_value(&keyset.id).map_err(Error::from)?;
  430. let keys = serde_wasm_bindgen::to_value(&keys).map_err(Error::from)?;
  431. keys_store
  432. .put(&keys, Some(&keyset_id))
  433. .await
  434. .map_err(Error::from)?;
  435. transaction.done().await.map_err(Error::from)?;
  436. Ok(())
  437. }
  438. async fn get_keys(&self, id: &Id) -> Result<Option<Keys>, Self::Err> {
  439. let rexie = self.db.lock().await;
  440. let transaction = rexie
  441. .transaction(&[MINT_KEYS], TransactionMode::ReadOnly)
  442. .map_err(Error::from)?;
  443. let keys_store = transaction.store(MINT_KEYS).map_err(Error::from)?;
  444. let keyset_id = serde_wasm_bindgen::to_value(id).map_err(Error::from)?;
  445. let keys = keys_store
  446. .get(keyset_id)
  447. .await
  448. .map_err(Error::from)?
  449. .and_then(|k| serde_wasm_bindgen::from_value(k).ok());
  450. Ok(keys)
  451. }
  452. async fn remove_keys(&self, id: &Id) -> Result<(), Self::Err> {
  453. let rexie = self.db.lock().await;
  454. let transaction = rexie
  455. .transaction(&[MINT_KEYS], TransactionMode::ReadWrite)
  456. .map_err(Error::from)?;
  457. let keys_store = transaction.store(MINT_KEYS).map_err(Error::from)?;
  458. let keyset_id = serde_wasm_bindgen::to_value(id).map_err(Error::from)?;
  459. keys_store.delete(keyset_id).await.map_err(Error::from)?;
  460. Ok(())
  461. }
  462. async fn update_proofs(
  463. &self,
  464. added: Vec<ProofInfo>,
  465. removed_ys: Vec<PublicKey>,
  466. ) -> Result<(), Self::Err> {
  467. let rexie = self.db.lock().await;
  468. let transaction = rexie
  469. .transaction(&[PROOFS], TransactionMode::ReadWrite)
  470. .map_err(Error::from)?;
  471. let proofs_store = transaction.store(PROOFS).map_err(Error::from)?;
  472. for proof in added {
  473. let y = serde_wasm_bindgen::to_value(&proof.y).map_err(Error::from)?;
  474. let proof = serde_wasm_bindgen::to_value(&proof).map_err(Error::from)?;
  475. proofs_store
  476. .put(&proof, Some(&y))
  477. .await
  478. .map_err(Error::from)?;
  479. }
  480. for y in removed_ys {
  481. let y = serde_wasm_bindgen::to_value(&y).map_err(Error::from)?;
  482. proofs_store.delete(y).await.map_err(Error::from)?;
  483. }
  484. transaction.done().await.map_err(Error::from)?;
  485. Ok(())
  486. }
  487. async fn set_pending_proofs(&self, ys: Vec<PublicKey>) -> Result<(), Self::Err> {
  488. self.set_proof_states(ys, State::Pending).await
  489. }
  490. async fn reserve_proofs(&self, ys: Vec<PublicKey>) -> Result<(), Self::Err> {
  491. self.set_proof_states(ys, State::Reserved).await
  492. }
  493. async fn set_unspent_proofs(&self, ys: Vec<PublicKey>) -> Result<(), Self::Err> {
  494. self.set_proof_states(ys, State::Unspent).await
  495. }
  496. async fn get_proofs(
  497. &self,
  498. mint_url: Option<MintUrl>,
  499. unit: Option<CurrencyUnit>,
  500. state: Option<Vec<State>>,
  501. spending_conditions: Option<Vec<SpendingConditions>>,
  502. ) -> Result<Vec<ProofInfo>, Self::Err> {
  503. let rexie = self.db.lock().await;
  504. let transaction = rexie
  505. .transaction(&[PROOFS], TransactionMode::ReadOnly)
  506. .map_err(Error::from)?;
  507. let proofs_store = transaction.store(PROOFS).map_err(Error::from)?;
  508. let proofs = proofs_store
  509. .scan(None, None, None, None)
  510. .await
  511. .map_err(Error::from)?;
  512. let proofs: Vec<ProofInfo> = proofs
  513. .into_iter()
  514. .filter_map(|(_k, v)| {
  515. let mut proof = None;
  516. if let Ok(proof_info) = serde_wasm_bindgen::from_value::<ProofInfo>(v) {
  517. proof = match proof_info.matches_conditions(
  518. &mint_url,
  519. &unit,
  520. &state,
  521. &spending_conditions,
  522. ) {
  523. true => Some(proof_info),
  524. false => None,
  525. };
  526. }
  527. proof
  528. })
  529. .collect();
  530. transaction.done().await.map_err(Error::from)?;
  531. Ok(proofs)
  532. }
  533. async fn increment_keyset_counter(&self, keyset_id: &Id, count: u32) -> Result<(), Self::Err> {
  534. let rexie = self.db.lock().await;
  535. let transaction = rexie
  536. .transaction(&[KEYSET_COUNTER], TransactionMode::ReadWrite)
  537. .map_err(Error::from)?;
  538. let counter_store = transaction.store(KEYSET_COUNTER).map_err(Error::from)?;
  539. let keyset_id = serde_wasm_bindgen::to_value(keyset_id).map_err(Error::from)?;
  540. let current_count: Option<u32> = counter_store
  541. .get(keyset_id.clone())
  542. .await
  543. .map_err(Error::from)?
  544. .and_then(|c| serde_wasm_bindgen::from_value(c).ok());
  545. let new_count = current_count.unwrap_or_default() + count;
  546. let new_count = serde_wasm_bindgen::to_value(&new_count).map_err(Error::from)?;
  547. counter_store
  548. .put(&new_count, Some(&keyset_id))
  549. .await
  550. .map_err(Error::from)?;
  551. transaction.done().await.map_err(Error::from)?;
  552. Ok(())
  553. }
  554. async fn get_keyset_counter(&self, keyset_id: &Id) -> Result<Option<u32>, Self::Err> {
  555. let rexie = self.db.lock().await;
  556. let transaction = rexie
  557. .transaction(&[KEYSET_COUNTER], TransactionMode::ReadWrite)
  558. .map_err(Error::from)?;
  559. let counter_store = transaction.store(KEYSET_COUNTER).map_err(Error::from)?;
  560. let keyset_id = serde_wasm_bindgen::to_value(keyset_id).map_err(Error::from)?;
  561. let current_count = counter_store
  562. .get(keyset_id)
  563. .await
  564. .map_err(Error::from)?
  565. .and_then(|c| serde_wasm_bindgen::from_value(c).ok());
  566. Ok(current_count)
  567. }
  568. }