Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Abstract HttpClient into HttpClientMethods trait #429

Merged
merged 7 commits into from
Nov 4, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions crates/cdk-cli/src/sub_commands/mint_info.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use anyhow::Result;
use cdk::mint_url::MintUrl;
use cdk::wallet::client::HttpClientMethods;
use cdk::HttpClient;
use clap::Args;
use url::Url;
Expand Down
2 changes: 1 addition & 1 deletion crates/cdk-integration-tests/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use cdk::nuts::{
Nuts, PaymentMethod, PreMintSecrets, Proofs, State,
};
use cdk::types::{LnKey, QuoteTTL};
use cdk::wallet::client::HttpClient;
use cdk::wallet::client::{HttpClient, HttpClientMethods};
use cdk::{Mint, Wallet};
use cdk_fake_wallet::FakeWallet;
use init_regtest::{get_mint_addr, get_mint_port, get_mint_url};
Expand Down
5 changes: 4 additions & 1 deletion crates/cdk-integration-tests/tests/fake_wallet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ use cdk::{
amount::SplitTarget,
cdk_database::WalletMemoryDatabase,
nuts::{CurrencyUnit, MeltQuoteState, PreMintSecrets, State},
wallet::{client::HttpClient, Wallet},
wallet::{
client::{HttpClient, HttpClientMethods},
Wallet,
},
};
use cdk_fake_wallet::{create_fake_invoice, FakeInvoiceDescription};
use cdk_integration_tests::attempt_to_swap_pending;
Expand Down
5 changes: 4 additions & 1 deletion crates/cdk-integration-tests/tests/regtest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ use cdk::{
amount::{Amount, SplitTarget},
cdk_database::WalletMemoryDatabase,
nuts::{CurrencyUnit, MeltQuoteState, MintQuoteState, PreMintSecrets, State},
wallet::{client::HttpClient, Wallet},
wallet::{
client::{HttpClient, HttpClientMethods},
Wallet,
},
};
use cdk_integration_tests::init_regtest::{get_mint_url, init_cln_client, init_lnd_client};
use lightning_invoice::Bolt11Invoice;
Expand Down
119 changes: 106 additions & 13 deletions crates/cdk/src/wallet/client.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
//! Wallet client

use std::fmt::Debug;

use async_trait::async_trait;
use reqwest::Client;
use serde_json::Value;
use tracing::instrument;
Expand Down Expand Up @@ -67,10 +70,13 @@ impl HttpClient {

Ok(Self { inner: client })
}
}

#[async_trait]
impl HttpClientMethods for HttpClient {
/// Get Active Mint Keys [NUT-01]
#[instrument(skip(self), fields(mint_url = %mint_url))]
pub async fn get_mint_keys(&self, mint_url: MintUrl) -> Result<Vec<KeySet>, Error> {
async fn get_mint_keys(&self, mint_url: MintUrl) -> Result<Vec<KeySet>, Error> {
let url = mint_url.join_paths(&["v1", "keys"])?;
let keys = self.inner.get(url).send().await?.json::<Value>().await?;

Expand All @@ -82,7 +88,7 @@ impl HttpClient {

/// Get Keyset Keys [NUT-01]
#[instrument(skip(self), fields(mint_url = %mint_url))]
pub async fn get_mint_keyset(&self, mint_url: MintUrl, keyset_id: Id) -> Result<KeySet, Error> {
async fn get_mint_keyset(&self, mint_url: MintUrl, keyset_id: Id) -> Result<KeySet, Error> {
let url = mint_url.join_paths(&["v1", "keys", &keyset_id.to_string()])?;
let keys = self.inner.get(url).send().await?.json::<Value>().await?;

Expand All @@ -94,7 +100,7 @@ impl HttpClient {

/// Get Keysets [NUT-02]
#[instrument(skip(self), fields(mint_url = %mint_url))]
pub async fn get_mint_keysets(&self, mint_url: MintUrl) -> Result<KeysetResponse, Error> {
async fn get_mint_keysets(&self, mint_url: MintUrl) -> Result<KeysetResponse, Error> {
let url = mint_url.join_paths(&["v1", "keysets"])?;
let res = self.inner.get(url).send().await?.json::<Value>().await?;

Expand All @@ -106,7 +112,7 @@ impl HttpClient {

/// Mint Quote [NUT-04]
#[instrument(skip(self), fields(mint_url = %mint_url))]
pub async fn post_mint_quote(
async fn post_mint_quote(
&self,
mint_url: MintUrl,
amount: Amount,
Expand Down Expand Up @@ -141,7 +147,7 @@ impl HttpClient {

/// Mint Quote status
#[instrument(skip(self), fields(mint_url = %mint_url))]
pub async fn get_mint_quote_status(
async fn get_mint_quote_status(
&self,
mint_url: MintUrl,
quote_id: &str,
Expand All @@ -161,7 +167,7 @@ impl HttpClient {

/// Mint Tokens [NUT-04]
#[instrument(skip(self, quote, premint_secrets), fields(mint_url = %mint_url))]
pub async fn post_mint(
async fn post_mint(
&self,
mint_url: MintUrl,
quote: &str,
Expand Down Expand Up @@ -191,7 +197,7 @@ impl HttpClient {

/// Melt Quote [NUT-05]
#[instrument(skip(self, request), fields(mint_url = %mint_url))]
pub async fn post_melt_quote(
async fn post_melt_quote(
&self,
mint_url: MintUrl,
unit: CurrencyUnit,
Expand Down Expand Up @@ -225,7 +231,7 @@ impl HttpClient {

/// Melt Quote Status
#[instrument(skip(self), fields(mint_url = %mint_url))]
pub async fn get_melt_quote_status(
async fn get_melt_quote_status(
&self,
mint_url: MintUrl,
quote_id: &str,
Expand All @@ -243,7 +249,7 @@ impl HttpClient {
/// Melt [NUT-05]
/// [Nut-08] Lightning fee return if outputs defined
#[instrument(skip(self, quote, inputs, outputs), fields(mint_url = %mint_url))]
pub async fn post_melt(
async fn post_melt(
&self,
mint_url: MintUrl,
quote: String,
Expand Down Expand Up @@ -280,7 +286,7 @@ impl HttpClient {

/// Split Token [NUT-06]
#[instrument(skip(self, swap_request), fields(mint_url = %mint_url))]
pub async fn post_swap(
async fn post_swap(
&self,
mint_url: MintUrl,
swap_request: SwapRequest,
Expand All @@ -304,7 +310,7 @@ impl HttpClient {

/// Get Mint Info [NUT-06]
#[instrument(skip(self), fields(mint_url = %mint_url))]
pub async fn get_mint_info(&self, mint_url: MintUrl) -> Result<MintInfo, Error> {
async fn get_mint_info(&self, mint_url: MintUrl) -> Result<MintInfo, Error> {
let url = mint_url.join_paths(&["v1", "info"])?;

let res = self.inner.get(url).send().await?.json::<Value>().await?;
Expand All @@ -320,7 +326,7 @@ impl HttpClient {

/// Spendable check [NUT-07]
#[instrument(skip(self), fields(mint_url = %mint_url))]
pub async fn post_check_state(
async fn post_check_state(
&self,
mint_url: MintUrl,
ys: Vec<PublicKey>,
Expand All @@ -345,7 +351,7 @@ impl HttpClient {

/// Restore request [NUT-13]
#[instrument(skip(self, request), fields(mint_url = %mint_url))]
pub async fn post_restore(
async fn post_restore(
&self,
mint_url: MintUrl,
request: RestoreRequest,
Expand All @@ -367,3 +373,90 @@ impl HttpClient {
}
}
}

/// Http Client Methods
#[async_trait]
pub trait HttpClientMethods: Debug {
/// Get Active Mint Keys [NUT-01]
async fn get_mint_keys(&self, mint_url: MintUrl) -> Result<Vec<KeySet>, Error>;

/// Get Keyset Keys [NUT-01]
async fn get_mint_keyset(&self, mint_url: MintUrl, keyset_id: Id) -> Result<KeySet, Error>;

/// Get Keysets [NUT-02]
async fn get_mint_keysets(&self, mint_url: MintUrl) -> Result<KeysetResponse, Error>;

/// Mint Quote [NUT-04]
async fn post_mint_quote(
&self,
mint_url: MintUrl,
amount: Amount,
unit: CurrencyUnit,
description: Option<String>,
) -> Result<MintQuoteBolt11Response, Error>;

/// Mint Quote status
async fn get_mint_quote_status(
&self,
mint_url: MintUrl,
quote_id: &str,
) -> Result<MintQuoteBolt11Response, Error>;

/// Mint Tokens [NUT-04]
async fn post_mint(
&self,
mint_url: MintUrl,
quote: &str,
premint_secrets: PreMintSecrets,
) -> Result<MintBolt11Response, Error>;

/// Melt Quote [NUT-05]
async fn post_melt_quote(
&self,
mint_url: MintUrl,
unit: CurrencyUnit,
request: Bolt11Invoice,
mpp_amount: Option<Amount>,
) -> Result<MeltQuoteBolt11Response, Error>;

/// Melt Quote Status
async fn get_melt_quote_status(
&self,
mint_url: MintUrl,
quote_id: &str,
) -> Result<MeltQuoteBolt11Response, Error>;

/// Melt [NUT-05]
/// [Nut-08] Lightning fee return if outputs defined
async fn post_melt(
&self,
mint_url: MintUrl,
quote: String,
inputs: Vec<Proof>,
outputs: Option<Vec<BlindedMessage>>,
) -> Result<MeltQuoteBolt11Response, Error>;

/// Split Token [NUT-06]
async fn post_swap(
&self,
mint_url: MintUrl,
swap_request: SwapRequest,
) -> Result<SwapResponse, Error>;

/// Get Mint Info [NUT-06]
async fn get_mint_info(&self, mint_url: MintUrl) -> Result<MintInfo, Error>;

/// Spendable check [NUT-07]
async fn post_check_state(
&self,
mint_url: MintUrl,
ys: Vec<PublicKey>,
) -> Result<CheckStateResponse, Error>;

/// Restore request [NUT-13]
async fn post_restore(
&self,
mint_url: MintUrl,
request: RestoreRequest,
davidcaseria marked this conversation as resolved.
Show resolved Hide resolved
) -> Result<RestoreResponse, Error>;
}
9 changes: 5 additions & 4 deletions crates/cdk/src/wallet/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use std::sync::Arc;

use bitcoin::bip32::Xpriv;
use bitcoin::Network;
use client::HttpClientMethods;
use tracing::instrument;

use crate::amount::SplitTarget;
Expand Down Expand Up @@ -55,7 +56,7 @@ pub struct Wallet {
/// The targeted amount of proofs to have at each size
pub target_proof_count: usize,
xpriv: Xpriv,
client: HttpClient,
client: Arc<dyn HttpClientMethods>,
}

impl Wallet {
Expand Down Expand Up @@ -88,16 +89,16 @@ impl Wallet {
Ok(Self {
mint_url: MintUrl::from_str(mint_url)?,
unit,
client: HttpClient::new(),
client: Arc::new(HttpClient::new()),
localstore,
xpriv,
target_proof_count: target_proof_count.unwrap_or(3),
})
}

/// Change HTTP client
pub fn set_client(&mut self, client: HttpClient) {
self.client = client;
pub fn set_client<C: HttpClientMethods + 'static>(&mut self, client: C) {
self.client = Arc::new(client);
}

/// Fee required for proof set
Expand Down
Loading