wallet.rs 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748
  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, keys: Keys) -> Result<(), Self::Err> {
  422. let rexie = self.db.lock().await;
  423. let transaction = rexie
  424. .transaction(&[MINT_KEYS], TransactionMode::ReadWrite)
  425. .map_err(Error::from)?;
  426. let keys_store = transaction.store(MINT_KEYS).map_err(Error::from)?;
  427. let keyset_id = serde_wasm_bindgen::to_value(&Id::from(&keys)).map_err(Error::from)?;
  428. let keys = serde_wasm_bindgen::to_value(&keys).map_err(Error::from)?;
  429. keys_store
  430. .put(&keys, Some(&keyset_id))
  431. .await
  432. .map_err(Error::from)?;
  433. transaction.done().await.map_err(Error::from)?;
  434. Ok(())
  435. }
  436. async fn get_keys(&self, id: &Id) -> Result<Option<Keys>, Self::Err> {
  437. let rexie = self.db.lock().await;
  438. let transaction = rexie
  439. .transaction(&[MINT_KEYS], TransactionMode::ReadOnly)
  440. .map_err(Error::from)?;
  441. let keys_store = transaction.store(MINT_KEYS).map_err(Error::from)?;
  442. let keyset_id = serde_wasm_bindgen::to_value(id).map_err(Error::from)?;
  443. let keys = keys_store
  444. .get(keyset_id)
  445. .await
  446. .map_err(Error::from)?
  447. .and_then(|k| serde_wasm_bindgen::from_value(k).ok());
  448. Ok(keys)
  449. }
  450. async fn remove_keys(&self, id: &Id) -> Result<(), Self::Err> {
  451. let rexie = self.db.lock().await;
  452. let transaction = rexie
  453. .transaction(&[MINT_KEYS], TransactionMode::ReadWrite)
  454. .map_err(Error::from)?;
  455. let keys_store = transaction.store(MINT_KEYS).map_err(Error::from)?;
  456. let keyset_id = serde_wasm_bindgen::to_value(id).map_err(Error::from)?;
  457. keys_store.delete(keyset_id).await.map_err(Error::from)?;
  458. Ok(())
  459. }
  460. async fn update_proofs(
  461. &self,
  462. added: Vec<ProofInfo>,
  463. removed_ys: Vec<PublicKey>,
  464. ) -> Result<(), Self::Err> {
  465. let rexie = self.db.lock().await;
  466. let transaction = rexie
  467. .transaction(&[PROOFS], TransactionMode::ReadWrite)
  468. .map_err(Error::from)?;
  469. let proofs_store = transaction.store(PROOFS).map_err(Error::from)?;
  470. for proof in added {
  471. let y = serde_wasm_bindgen::to_value(&proof.y).map_err(Error::from)?;
  472. let proof = serde_wasm_bindgen::to_value(&proof).map_err(Error::from)?;
  473. proofs_store
  474. .put(&proof, Some(&y))
  475. .await
  476. .map_err(Error::from)?;
  477. }
  478. for y in removed_ys {
  479. let y = serde_wasm_bindgen::to_value(&y).map_err(Error::from)?;
  480. proofs_store.delete(y).await.map_err(Error::from)?;
  481. }
  482. transaction.done().await.map_err(Error::from)?;
  483. Ok(())
  484. }
  485. async fn set_pending_proofs(&self, ys: Vec<PublicKey>) -> Result<(), Self::Err> {
  486. self.set_proof_states(ys, State::Pending).await
  487. }
  488. async fn reserve_proofs(&self, ys: Vec<PublicKey>) -> Result<(), Self::Err> {
  489. self.set_proof_states(ys, State::Reserved).await
  490. }
  491. async fn set_unspent_proofs(&self, ys: Vec<PublicKey>) -> Result<(), Self::Err> {
  492. self.set_proof_states(ys, State::Unspent).await
  493. }
  494. async fn get_proofs(
  495. &self,
  496. mint_url: Option<MintUrl>,
  497. unit: Option<CurrencyUnit>,
  498. state: Option<Vec<State>>,
  499. spending_conditions: Option<Vec<SpendingConditions>>,
  500. ) -> Result<Vec<ProofInfo>, Self::Err> {
  501. let rexie = self.db.lock().await;
  502. let transaction = rexie
  503. .transaction(&[PROOFS], TransactionMode::ReadOnly)
  504. .map_err(Error::from)?;
  505. let proofs_store = transaction.store(PROOFS).map_err(Error::from)?;
  506. let proofs = proofs_store
  507. .scan(None, None, None, None)
  508. .await
  509. .map_err(Error::from)?;
  510. let proofs: Vec<ProofInfo> = proofs
  511. .into_iter()
  512. .filter_map(|(_k, v)| {
  513. let mut proof = None;
  514. if let Ok(proof_info) = serde_wasm_bindgen::from_value::<ProofInfo>(v) {
  515. proof = match proof_info.matches_conditions(
  516. &mint_url,
  517. &unit,
  518. &state,
  519. &spending_conditions,
  520. ) {
  521. true => Some(proof_info),
  522. false => None,
  523. };
  524. }
  525. proof
  526. })
  527. .collect();
  528. transaction.done().await.map_err(Error::from)?;
  529. Ok(proofs)
  530. }
  531. async fn increment_keyset_counter(&self, keyset_id: &Id, count: u32) -> Result<(), Self::Err> {
  532. let rexie = self.db.lock().await;
  533. let transaction = rexie
  534. .transaction(&[KEYSET_COUNTER], TransactionMode::ReadWrite)
  535. .map_err(Error::from)?;
  536. let counter_store = transaction.store(KEYSET_COUNTER).map_err(Error::from)?;
  537. let keyset_id = serde_wasm_bindgen::to_value(keyset_id).map_err(Error::from)?;
  538. let current_count: Option<u32> = counter_store
  539. .get(keyset_id.clone())
  540. .await
  541. .map_err(Error::from)?
  542. .and_then(|c| serde_wasm_bindgen::from_value(c).ok());
  543. let new_count = current_count.unwrap_or_default() + count;
  544. let new_count = serde_wasm_bindgen::to_value(&new_count).map_err(Error::from)?;
  545. counter_store
  546. .put(&new_count, Some(&keyset_id))
  547. .await
  548. .map_err(Error::from)?;
  549. transaction.done().await.map_err(Error::from)?;
  550. Ok(())
  551. }
  552. async fn get_keyset_counter(&self, keyset_id: &Id) -> Result<Option<u32>, Self::Err> {
  553. let rexie = self.db.lock().await;
  554. let transaction = rexie
  555. .transaction(&[KEYSET_COUNTER], TransactionMode::ReadWrite)
  556. .map_err(Error::from)?;
  557. let counter_store = transaction.store(KEYSET_COUNTER).map_err(Error::from)?;
  558. let keyset_id = serde_wasm_bindgen::to_value(keyset_id).map_err(Error::from)?;
  559. let current_count = counter_store
  560. .get(keyset_id)
  561. .await
  562. .map_err(Error::from)?
  563. .and_then(|c| serde_wasm_bindgen::from_value(c).ok());
  564. Ok(current_count)
  565. }
  566. }