wallet.rs 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. use std::ops::Deref;
  2. use std::sync::Arc;
  3. use cashu_ffi::{
  4. BlindedSignature, Bolt11Invoice, PreMintSecrets, Proof, RequestMintResponse, Token,
  5. };
  6. use cashu_sdk::client::minreq_client::HttpClient;
  7. use cashu_sdk::types::ProofsStatus;
  8. use cashu_sdk::url::UncheckedUrl;
  9. use cashu_sdk::wallet::Wallet as WalletSdk;
  10. use once_cell::sync::Lazy;
  11. use tokio::runtime::Runtime;
  12. use crate::error::Result;
  13. use crate::types::{Melted, SendProofs};
  14. use crate::{Amount, Keys};
  15. static RUNTIME: Lazy<Runtime> = Lazy::new(|| Runtime::new().expect("Can't start Tokio runtime"));
  16. pub struct Wallet {
  17. inner: WalletSdk<HttpClient>,
  18. }
  19. impl Wallet {
  20. pub fn new(mint_url: &str, mint_keys: Arc<Keys>) -> Self {
  21. let client = HttpClient {};
  22. Self {
  23. inner: WalletSdk::new(
  24. client,
  25. UncheckedUrl::new(mint_url),
  26. mint_keys.as_ref().deref().clone(),
  27. ),
  28. }
  29. }
  30. pub fn check_proofs_spent(&self, proofs: Vec<Arc<Proof>>) -> Result<Arc<ProofsStatus>> {
  31. let proofs = RUNTIME.block_on(async {
  32. self.inner
  33. .check_proofs_spent(proofs.iter().map(|p| p.as_ref().deref().clone()).collect())
  34. .await
  35. })?;
  36. Ok(Arc::new(proofs))
  37. }
  38. pub fn request_mint(&self, amount: Arc<Amount>) -> Result<Arc<RequestMintResponse>> {
  39. let mint_response = RUNTIME
  40. .block_on(async { self.inner.request_mint(*amount.as_ref().deref()).await })?
  41. .into();
  42. Ok(Arc::new(mint_response))
  43. }
  44. pub fn mint_token(
  45. &self,
  46. amount: Arc<Amount>,
  47. hash: String,
  48. unit: Option<String>,
  49. memo: Option<String>,
  50. ) -> Result<Arc<Token>> {
  51. let token = RUNTIME.block_on(async {
  52. self.inner
  53. .mint_token(*amount.as_ref().deref(), &hash, unit, memo)
  54. .await
  55. })?;
  56. Ok(Arc::new(token.into()))
  57. }
  58. pub fn mint(&self, amount: Arc<Amount>, hash: String) -> Result<Vec<Arc<Proof>>> {
  59. let proofs =
  60. RUNTIME.block_on(async { self.inner.mint(*amount.as_ref().deref(), &hash).await })?;
  61. Ok(proofs.into_iter().map(|p| Arc::new(p.into())).collect())
  62. }
  63. pub fn check_fee(&self, invoice: Arc<Bolt11Invoice>) -> Result<Arc<Amount>> {
  64. let amount = RUNTIME
  65. .block_on(async { self.inner.check_fee(invoice.as_ref().deref().clone()).await })?;
  66. Ok(Arc::new(amount.into()))
  67. }
  68. pub fn receive(&self, encoded_token: String) -> Result<Vec<Arc<Proof>>> {
  69. let proofs = RUNTIME.block_on(async { self.inner.receive(&encoded_token).await })?;
  70. Ok(proofs.into_iter().map(|p| Arc::new(p.into())).collect())
  71. }
  72. pub fn process_split_response(
  73. &self,
  74. blinded_messages: Arc<PreMintSecrets>,
  75. promises: Vec<Arc<BlindedSignature>>,
  76. ) -> Result<Vec<Arc<Proof>>> {
  77. Ok(self
  78. .inner
  79. .process_split_response(
  80. blinded_messages.as_ref().deref().clone(),
  81. promises.iter().map(|p| p.as_ref().into()).collect(),
  82. )?
  83. .into_iter()
  84. .map(|p| Arc::new(p.into()))
  85. .collect())
  86. }
  87. pub fn send(&self, amount: Arc<Amount>, proofs: Vec<Arc<Proof>>) -> Result<Arc<SendProofs>> {
  88. let send_proofs = RUNTIME.block_on(async {
  89. self.inner
  90. .send(
  91. *amount.as_ref().deref(),
  92. proofs.iter().map(|p| p.as_ref().deref().clone()).collect(),
  93. )
  94. .await
  95. })?;
  96. Ok(Arc::new(send_proofs.into()))
  97. }
  98. pub fn melt(
  99. &self,
  100. invoice: Arc<Bolt11Invoice>,
  101. proofs: Vec<Arc<Proof>>,
  102. fee_reserve: Arc<Amount>,
  103. ) -> Result<Arc<Melted>> {
  104. let melted = RUNTIME.block_on(async {
  105. self.inner
  106. .melt(
  107. invoice.as_ref().deref().clone(),
  108. proofs.iter().map(|p| p.as_ref().deref().clone()).collect(),
  109. *fee_reserve.as_ref().deref(),
  110. )
  111. .await
  112. })?;
  113. Ok(Arc::new(melted.into()))
  114. }
  115. pub fn proof_to_token(
  116. &self,
  117. proofs: Vec<Arc<Proof>>,
  118. unit: Option<String>,
  119. memo: Option<String>,
  120. ) -> Result<String> {
  121. Ok(self.inner.proofs_to_token(
  122. proofs.iter().map(|p| p.as_ref().deref().clone()).collect(),
  123. unit,
  124. memo,
  125. )?)
  126. }
  127. }