wallet.rs 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800
  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 NOSTR_LAST_CHECKED: &str = "nostr_last_check";
  28. const DATABASE_VERSION: u32 = 3;
  29. /// Rexie Database Error
  30. #[derive(Debug, Error)]
  31. pub enum Error {
  32. /// CDK Database Error
  33. #[error(transparent)]
  34. CDKDatabase(#[from] cdk::cdk_database::Error),
  35. /// Rexie Error
  36. #[error(transparent)]
  37. Rexie(#[from] rexie::Error),
  38. /// Serde Wasm Error
  39. #[error(transparent)]
  40. SerdeBindgen(#[from] serde_wasm_bindgen::Error),
  41. /// NUT00 Error
  42. #[error(transparent)]
  43. NUT00(cdk::nuts::nut00::Error),
  44. #[error("Not found")]
  45. /// Not Found
  46. NotFound,
  47. }
  48. impl From<Error> for cdk::cdk_database::Error {
  49. fn from(e: Error) -> Self {
  50. Self::Database(Box::new(e))
  51. }
  52. }
  53. // These are okay because we never actually send across threads in the browser
  54. unsafe impl Send for Error {}
  55. unsafe impl Sync for Error {}
  56. /// Wallet Rexie Database
  57. #[derive(Debug, Clone)]
  58. pub struct WalletRexieDatabase {
  59. db: Rc<Mutex<Rexie>>,
  60. }
  61. // These are okay because we never actually send across threads in the browser
  62. unsafe impl Send for WalletRexieDatabase {}
  63. unsafe impl Sync for WalletRexieDatabase {}
  64. impl WalletRexieDatabase {
  65. /// Create new [`WalletRexieDatabase`]
  66. pub async fn new() -> Result<Self, Error> {
  67. let rexie = Rexie::builder("cdk")
  68. .version(DATABASE_VERSION)
  69. .add_object_store(
  70. ObjectStore::new(PROOFS)
  71. .add_index(Index::new("y", "y").unique(true))
  72. .add_index(Index::new("mint_url", "mint_url"))
  73. .add_index(Index::new("state", "state"))
  74. .add_index(Index::new("unit", "unit")),
  75. )
  76. .add_object_store(
  77. ObjectStore::new(MINTS).add_index(Index::new("mint_url", "mint_url").unique(true)),
  78. )
  79. .add_object_store(ObjectStore::new(MINT_KEYSETS))
  80. .add_object_store(
  81. ObjectStore::new(KEYSETS)
  82. .add_index(Index::new("keyset_id", "keyset_id").unique(true)),
  83. )
  84. .add_object_store(
  85. ObjectStore::new(MINT_KEYS)
  86. .add_index(Index::new("keyset_id", "keyset_id").unique(true)),
  87. )
  88. .add_object_store(ObjectStore::new(MINT_QUOTES))
  89. .add_object_store(ObjectStore::new(MELT_QUOTES))
  90. .add_object_store(ObjectStore::new(CONFIG))
  91. .add_object_store(ObjectStore::new(KEYSET_COUNTER))
  92. .add_object_store(ObjectStore::new(NOSTR_LAST_CHECKED))
  93. // Build the database
  94. .build()
  95. .await
  96. .unwrap();
  97. Ok(Self {
  98. db: Rc::new(Mutex::new(rexie)),
  99. })
  100. }
  101. async fn set_proof_states(
  102. &self,
  103. ys: Vec<PublicKey>,
  104. state: State,
  105. ) -> Result<(), cdk_database::Error> {
  106. let rexie = self.db.lock().await;
  107. let transaction = rexie
  108. .transaction(&[PROOFS], TransactionMode::ReadWrite)
  109. .map_err(Error::from)?;
  110. let proofs_store = transaction.store(PROOFS).map_err(Error::from)?;
  111. for y in ys {
  112. let y = serde_wasm_bindgen::to_value(&y).map_err(Error::from)?;
  113. let mut proof: ProofInfo = proofs_store
  114. .get(y.clone())
  115. .await
  116. .map_err(Error::from)?
  117. .and_then(|p| serde_wasm_bindgen::from_value(p).ok())
  118. .ok_or(Error::NotFound)?;
  119. proof.state = state;
  120. let proof = serde_wasm_bindgen::to_value(&proof).map_err(Error::from)?;
  121. proofs_store
  122. .put(&proof, Some(&y))
  123. .await
  124. .map_err(Error::from)?;
  125. }
  126. transaction.done().await.map_err(Error::from)?;
  127. Ok(())
  128. }
  129. }
  130. #[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
  131. #[cfg_attr(not(target_arch = "wasm32"), async_trait)]
  132. impl WalletDatabase for WalletRexieDatabase {
  133. type Err = cdk::cdk_database::Error;
  134. async fn add_mint(
  135. &self,
  136. mint_url: MintUrl,
  137. mint_info: Option<MintInfo>,
  138. ) -> Result<(), Self::Err> {
  139. let rexie = self.db.lock().await;
  140. let transaction = rexie
  141. .transaction(&[MINTS], TransactionMode::ReadWrite)
  142. .map_err(Error::from)?;
  143. let mints_store = transaction.store(MINTS).map_err(Error::from)?;
  144. let mint_url = serde_wasm_bindgen::to_value(&mint_url).map_err(Error::from)?;
  145. let mint_info = serde_wasm_bindgen::to_value(&mint_info).map_err(Error::from)?;
  146. mints_store
  147. .put(&mint_info, Some(&mint_url))
  148. .await
  149. .map_err(Error::from)?;
  150. transaction.done().await.map_err(Error::from)?;
  151. Ok(())
  152. }
  153. async fn remove_mint(&self, mint_url: MintUrl) -> Result<(), Self::Err> {
  154. let rexie = self.db.lock().await;
  155. let transaction = rexie
  156. .transaction(&[MINTS], TransactionMode::ReadWrite)
  157. .map_err(Error::from)?;
  158. let mints_store = transaction.store(MINTS).map_err(Error::from)?;
  159. let mint_url = serde_wasm_bindgen::to_value(&mint_url).map_err(Error::from)?;
  160. mints_store.delete(mint_url).await.map_err(Error::from)?;
  161. transaction.done().await.map_err(Error::from)?;
  162. Ok(())
  163. }
  164. async fn get_mint(&self, mint_url: MintUrl) -> Result<Option<MintInfo>, Self::Err> {
  165. let rexie = self.db.lock().await;
  166. let transaction = rexie
  167. .transaction(&[MINTS], TransactionMode::ReadOnly)
  168. .map_err(Error::from)?;
  169. let mints_store = transaction.store(MINTS).map_err(Error::from)?;
  170. let mint_url = serde_wasm_bindgen::to_value(&mint_url).map_err(Error::from)?;
  171. let mint_info = mints_store
  172. .get(mint_url)
  173. .await
  174. .map_err(Error::from)?
  175. .and_then(|m| serde_wasm_bindgen::from_value(m).ok());
  176. Ok(mint_info)
  177. }
  178. async fn get_mints(&self) -> Result<HashMap<MintUrl, Option<MintInfo>>, Self::Err> {
  179. let rexie = self.db.lock().await;
  180. let transaction = rexie
  181. .transaction(&[MINTS], TransactionMode::ReadOnly)
  182. .map_err(Error::from)?;
  183. let mints_store = transaction.store(MINTS).map_err(Error::from)?;
  184. let mints = mints_store
  185. .scan(None, None, None, None)
  186. .await
  187. .map_err(Error::from)?;
  188. let mints: HashMap<MintUrl, Option<MintInfo>> = mints
  189. .into_iter()
  190. .map(|(url, info)| {
  191. (
  192. serde_wasm_bindgen::from_value(url).unwrap(),
  193. serde_wasm_bindgen::from_value(info).unwrap(),
  194. )
  195. })
  196. .collect();
  197. Ok(mints)
  198. }
  199. async fn update_mint_url(
  200. &self,
  201. old_mint_url: MintUrl,
  202. new_mint_url: MintUrl,
  203. ) -> Result<(), Self::Err> {
  204. let proofs = self
  205. .get_proofs(Some(old_mint_url), None, None, None)
  206. .await
  207. .map_err(Error::from)?;
  208. let updated_proofs: Vec<ProofInfo> = proofs
  209. .into_iter()
  210. .map(|mut p| {
  211. p.mint_url = new_mint_url.clone();
  212. p
  213. })
  214. .collect();
  215. if !updated_proofs.is_empty() {
  216. self.update_proofs(updated_proofs, vec![]).await?;
  217. }
  218. // Update mint quotes
  219. {
  220. let quotes = self.get_mint_quotes().await?;
  221. let unix_time = unix_time();
  222. let quotes: Vec<MintQuote> = quotes
  223. .into_iter()
  224. .filter_map(|mut q| {
  225. if q.expiry < unix_time {
  226. q.mint_url = new_mint_url.clone();
  227. Some(q)
  228. } else {
  229. None
  230. }
  231. })
  232. .collect();
  233. for quote in quotes {
  234. self.add_mint_quote(quote).await?;
  235. }
  236. }
  237. Ok(())
  238. }
  239. async fn add_mint_keysets(
  240. &self,
  241. mint_url: MintUrl,
  242. keysets: Vec<KeySetInfo>,
  243. ) -> Result<(), Self::Err> {
  244. let rexie = self.db.lock().await;
  245. let transaction = rexie
  246. .transaction(&[MINT_KEYSETS, KEYSETS], TransactionMode::ReadWrite)
  247. .map_err(Error::from)?;
  248. let mint_keysets_store = transaction.store(MINT_KEYSETS).map_err(Error::from)?;
  249. let keysets_store = transaction.store(KEYSETS).map_err(Error::from)?;
  250. let mint_url = serde_wasm_bindgen::to_value(&mint_url).map_err(Error::from)?;
  251. let mut mint_keysets = mint_keysets_store
  252. .get(mint_url.clone())
  253. .await
  254. .map_err(Error::from)?
  255. .and_then(|m| serde_wasm_bindgen::from_value(m).ok());
  256. let new_keyset_ids: Vec<Id> = keysets.iter().map(|k| k.id).collect();
  257. mint_keysets
  258. .as_mut()
  259. .unwrap_or(&mut HashSet::new())
  260. .extend(new_keyset_ids);
  261. let mint_keysets = serde_wasm_bindgen::to_value(&mint_keysets).map_err(Error::from)?;
  262. mint_keysets_store
  263. .put(&mint_keysets, Some(&mint_url))
  264. .await
  265. .map_err(Error::from)?;
  266. for keyset in keysets {
  267. let id = serde_wasm_bindgen::to_value(&keyset.id).map_err(Error::from)?;
  268. let keyset = serde_wasm_bindgen::to_value(&keyset).map_err(Error::from)?;
  269. keysets_store
  270. .put(&keyset, Some(&id))
  271. .await
  272. .map_err(Error::from)?;
  273. }
  274. transaction.done().await.map_err(Error::from)?;
  275. Ok(())
  276. }
  277. async fn get_mint_keysets(
  278. &self,
  279. mint_url: MintUrl,
  280. ) -> Result<Option<Vec<KeySetInfo>>, Self::Err> {
  281. let rexie = self.db.lock().await;
  282. let transaction = rexie
  283. .transaction(&[MINT_KEYSETS, KEYSETS], TransactionMode::ReadOnly)
  284. .map_err(Error::from)?;
  285. let mints_store = transaction.store(MINT_KEYSETS).map_err(Error::from)?;
  286. let mint_url = serde_wasm_bindgen::to_value(&mint_url).map_err(Error::from)?;
  287. let mint_keysets: Option<HashSet<Id>> = mints_store
  288. .get(mint_url)
  289. .await
  290. .map_err(Error::from)?
  291. .and_then(|m| serde_wasm_bindgen::from_value(m).ok());
  292. let keysets_store = transaction.store(KEYSETS).map_err(Error::from)?;
  293. let keysets = match mint_keysets {
  294. Some(mint_keysets) => {
  295. let mut keysets = vec![];
  296. for mint_keyset in mint_keysets {
  297. let id = serde_wasm_bindgen::to_value(&mint_keyset).map_err(Error::from)?;
  298. let keyset = keysets_store
  299. .get(id)
  300. .await
  301. .map_err(Error::from)?
  302. .and_then(|k| serde_wasm_bindgen::from_value(k).ok());
  303. keysets.push(keyset);
  304. }
  305. let keysets = keysets.iter().flatten().cloned().collect();
  306. Some(keysets)
  307. }
  308. None => None,
  309. };
  310. transaction.done().await.map_err(Error::from)?;
  311. Ok(keysets)
  312. }
  313. async fn get_keyset_by_id(&self, keyset_id: &Id) -> Result<Option<KeySetInfo>, Self::Err> {
  314. let rexie = self.db.lock().await;
  315. let transaction = rexie
  316. .transaction(&[KEYSETS], TransactionMode::ReadOnly)
  317. .map_err(Error::from)?;
  318. let keysets_store = transaction.store(KEYSETS).map_err(Error::from)?;
  319. let keyset_id = serde_wasm_bindgen::to_value(keyset_id).map_err(Error::from)?;
  320. let keyset = keysets_store
  321. .get(keyset_id)
  322. .await
  323. .map_err(Error::from)?
  324. .and_then(|k| serde_wasm_bindgen::from_value(k).ok());
  325. Ok(keyset)
  326. }
  327. async fn add_mint_quote(&self, quote: MintQuote) -> Result<(), Self::Err> {
  328. let rexie = self.db.lock().await;
  329. let transaction = rexie
  330. .transaction(&[MINT_QUOTES], TransactionMode::ReadWrite)
  331. .map_err(Error::from)?;
  332. let quotes_store = transaction.store(MINT_QUOTES).map_err(Error::from)?;
  333. let quote_id = serde_wasm_bindgen::to_value(&quote.id).map_err(Error::from)?;
  334. let quote = serde_wasm_bindgen::to_value(&quote).map_err(Error::from)?;
  335. quotes_store
  336. .put(&quote, Some(&quote_id))
  337. .await
  338. .map_err(Error::from)?;
  339. transaction.done().await.map_err(Error::from)?;
  340. Ok(())
  341. }
  342. async fn get_mint_quote(&self, quote_id: &str) -> Result<Option<MintQuote>, Self::Err> {
  343. let rexie = self.db.lock().await;
  344. let transaction = rexie
  345. .transaction(&[MINT_QUOTES], TransactionMode::ReadOnly)
  346. .map_err(Error::from)?;
  347. let quotes_store = transaction.store(MINT_QUOTES).map_err(Error::from)?;
  348. let quote_id = serde_wasm_bindgen::to_value(&quote_id).map_err(Error::from)?;
  349. let quote = quotes_store
  350. .get(quote_id)
  351. .await
  352. .map_err(Error::from)?
  353. .and_then(|q| serde_wasm_bindgen::from_value(q).ok());
  354. Ok(quote)
  355. }
  356. async fn get_mint_quotes(&self) -> Result<Vec<MintQuote>, Self::Err> {
  357. let rexie = self.db.lock().await;
  358. let transaction = rexie
  359. .transaction(&[MINT_QUOTES], TransactionMode::ReadOnly)
  360. .map_err(Error::from)?;
  361. let quotes_store = transaction.store(MINT_QUOTES).map_err(Error::from)?;
  362. let quotes = quotes_store
  363. .scan(None, None, None, None)
  364. .await
  365. .map_err(Error::from)?;
  366. Ok(quotes
  367. .into_iter()
  368. .map(|(_id, q)| serde_wasm_bindgen::from_value(q))
  369. .collect::<Result<Vec<MintQuote>, serde_wasm_bindgen::Error>>()
  370. .map_err(<serde_wasm_bindgen::Error as Into<Error>>::into)?)
  371. }
  372. async fn remove_mint_quote(&self, quote_id: &str) -> Result<(), Self::Err> {
  373. let rexie = self.db.lock().await;
  374. let transaction = rexie
  375. .transaction(&[MINT_QUOTES], TransactionMode::ReadWrite)
  376. .map_err(Error::from)?;
  377. let quotes_store = transaction.store(MINT_QUOTES).map_err(Error::from)?;
  378. let quote_id = serde_wasm_bindgen::to_value(&quote_id).map_err(Error::from)?;
  379. quotes_store.delete(quote_id).await.map_err(Error::from)?;
  380. transaction.done().await.map_err(Error::from)?;
  381. Ok(())
  382. }
  383. async fn add_melt_quote(&self, quote: MeltQuote) -> Result<(), Self::Err> {
  384. let rexie = self.db.lock().await;
  385. let transaction = rexie
  386. .transaction(&[MELT_QUOTES], TransactionMode::ReadWrite)
  387. .map_err(Error::from)?;
  388. let quotes_store = transaction.store(MELT_QUOTES).map_err(Error::from)?;
  389. let quote_id = serde_wasm_bindgen::to_value(&quote.id).map_err(Error::from)?;
  390. let quote = serde_wasm_bindgen::to_value(&quote).map_err(Error::from)?;
  391. quotes_store
  392. .put(&quote, Some(&quote_id))
  393. .await
  394. .map_err(Error::from)?;
  395. transaction.done().await.map_err(Error::from)?;
  396. Ok(())
  397. }
  398. async fn get_melt_quote(&self, quote_id: &str) -> Result<Option<MeltQuote>, Self::Err> {
  399. let rexie = self.db.lock().await;
  400. let transaction = rexie
  401. .transaction(&[MELT_QUOTES], TransactionMode::ReadOnly)
  402. .map_err(Error::from)?;
  403. let quotes_store = transaction.store(MELT_QUOTES).map_err(Error::from)?;
  404. let quote_id = serde_wasm_bindgen::to_value(&quote_id).map_err(Error::from)?;
  405. let quote = quotes_store
  406. .get(quote_id)
  407. .await
  408. .map_err(Error::from)?
  409. .and_then(|q| serde_wasm_bindgen::from_value(q).ok());
  410. Ok(quote)
  411. }
  412. async fn remove_melt_quote(&self, quote_id: &str) -> Result<(), Self::Err> {
  413. let rexie = self.db.lock().await;
  414. let transaction = rexie
  415. .transaction(&[MELT_QUOTES], TransactionMode::ReadWrite)
  416. .map_err(Error::from)?;
  417. let quotes_store = transaction.store(MELT_QUOTES).map_err(Error::from)?;
  418. let quote_id = serde_wasm_bindgen::to_value(&quote_id).map_err(Error::from)?;
  419. quotes_store.delete(quote_id).await.map_err(Error::from)?;
  420. transaction.done().await.map_err(Error::from)?;
  421. Ok(())
  422. }
  423. async fn add_keys(&self, keys: Keys) -> Result<(), Self::Err> {
  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(&Id::from(&keys)).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. async fn add_nostr_last_checked(
  569. &self,
  570. verifying_key: PublicKey,
  571. last_checked: u32,
  572. ) -> Result<(), Self::Err> {
  573. let rexie = self.db.lock().await;
  574. let transaction = rexie
  575. .transaction(&[NOSTR_LAST_CHECKED], TransactionMode::ReadWrite)
  576. .map_err(Error::from)?;
  577. let counter_store = transaction.store(NOSTR_LAST_CHECKED).map_err(Error::from)?;
  578. let verifying_key = serde_wasm_bindgen::to_value(&verifying_key).map_err(Error::from)?;
  579. let last_checked = serde_wasm_bindgen::to_value(&last_checked).map_err(Error::from)?;
  580. counter_store
  581. .put(&last_checked, Some(&verifying_key))
  582. .await
  583. .map_err(Error::from)?;
  584. transaction.done().await.map_err(Error::from)?;
  585. Ok(())
  586. }
  587. async fn get_nostr_last_checked(
  588. &self,
  589. verifying_key: &PublicKey,
  590. ) -> Result<Option<u32>, Self::Err> {
  591. let rexie = self.db.lock().await;
  592. let transaction = rexie
  593. .transaction(&[NOSTR_LAST_CHECKED], TransactionMode::ReadOnly)
  594. .map_err(Error::from)?;
  595. let nostr_last_check_store = transaction.store(NOSTR_LAST_CHECKED).map_err(Error::from)?;
  596. let verifying_key = serde_wasm_bindgen::to_value(verifying_key).map_err(Error::from)?;
  597. let last_checked = nostr_last_check_store
  598. .get(verifying_key)
  599. .await
  600. .map_err(Error::from)?
  601. .and_then(|l| serde_wasm_bindgen::from_value(l).ok());
  602. Ok(last_checked)
  603. }
  604. }