feat: wallet mpp

This commit is contained in:
thesimplekid
2024-06-06 12:19:26 +01:00
parent 8f5e9df7f7
commit 16dbc48012
8 changed files with 61 additions and 5 deletions

View File

@@ -218,11 +218,17 @@ impl JsWallet {
mint_url: String, mint_url: String,
unit: JsCurrencyUnit, unit: JsCurrencyUnit,
request: String, request: String,
mpp_amount: Option<JsAmount>,
) -> Result<JsMeltQuote> { ) -> Result<JsMeltQuote> {
let mint_url = UncheckedUrl::from_str(&mint_url).map_err(into_err)?; let mint_url = UncheckedUrl::from_str(&mint_url).map_err(into_err)?;
let melt_quote = self let melt_quote = self
.inner .inner
.melt_quote(mint_url, unit.into(), request) .melt_quote(
mint_url,
unit.into(),
request,
mpp_amount.map(|a| *a.deref()),
)
.await .await
.map_err(into_err)?; .map_err(into_err)?;

View File

@@ -57,6 +57,7 @@ pub async fn melt(wallet: Wallet, _sub_command_args: &MeltSubCommand) -> Result<
mint_url.clone(), mint_url.clone(),
cdk::nuts::CurrencyUnit::Sat, cdk::nuts::CurrencyUnit::Sat,
bolt11.to_string(), bolt11.to_string(),
None,
) )
.await?; .await?;

View File

@@ -13,6 +13,7 @@ pub mod nut11;
pub mod nut12; pub mod nut12;
pub mod nut13; pub mod nut13;
pub mod nut14; pub mod nut14;
pub mod nut15;
pub use nut00::{ pub use nut00::{
BlindSignature, BlindedMessage, CurrencyUnit, MintProofs, PaymentMethod, PreMint, BlindSignature, BlindedMessage, CurrencyUnit, MintProofs, PaymentMethod, PreMint,
@@ -40,3 +41,4 @@ pub use nut10::{Kind, Secret as Nut10Secret, SecretData};
pub use nut11::{Conditions, P2PKWitness, SigFlag, SpendingConditions}; pub use nut11::{Conditions, P2PKWitness, SigFlag, SpendingConditions};
pub use nut12::{BlindSignatureDleq, ProofDleq}; pub use nut12::{BlindSignatureDleq, ProofDleq};
pub use nut14::HTLCWitness; pub use nut14::HTLCWitness;
pub use nut15::{Mpp, MppMethodSettings, Settings as NUT15Settings};

View File

@@ -5,16 +5,19 @@
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use super::nut00::{BlindSignature, BlindedMessage, CurrencyUnit, PaymentMethod, Proofs}; use super::nut00::{BlindSignature, BlindedMessage, CurrencyUnit, PaymentMethod, Proofs};
use super::nut15::Mpp;
use crate::types::MeltQuote; use crate::types::MeltQuote;
use crate::{Amount, Bolt11Invoice}; use crate::{Amount, Bolt11Invoice};
/// Melt quote request [NUT-05] /// Melt quote request [NUT-05]
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] #[derive(Debug, Clone, Hash, PartialEq, Eq, Serialize, Deserialize)]
pub struct MeltQuoteBolt11Request { pub struct MeltQuoteBolt11Request {
/// Bolt11 invoice to be paid /// Bolt11 invoice to be paid
pub request: Bolt11Invoice, pub request: Bolt11Invoice,
/// Unit wallet would like to pay with /// Unit wallet would like to pay with
pub unit: CurrencyUnit, pub unit: CurrencyUnit,
/// Payment Options
pub options: Option<Mpp>,
} }
/// Melt quote response [NUT-05] /// Melt quote response [NUT-05]

View File

@@ -5,7 +5,7 @@
use serde::{Deserialize, Deserializer, Serialize, Serializer}; use serde::{Deserialize, Deserializer, Serialize, Serializer};
use super::nut01::PublicKey; use super::nut01::PublicKey;
use super::{nut04, nut05}; use super::{nut04, nut05, nut15};
/// Mint Version /// Mint Version
#[derive(Debug, Clone, PartialEq, Eq, Hash)] #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -102,6 +102,9 @@ pub struct Nuts {
#[serde(default)] #[serde(default)]
#[serde(rename = "14")] #[serde(rename = "14")]
pub nut14: SupportedSettings, pub nut14: SupportedSettings,
#[serde(default)]
#[serde(rename = "15")]
pub nut15: nut15::MppMethodSettings,
} }
/// Check state Settings /// Check state Settings

View File

@@ -0,0 +1,31 @@
//! NUT-15: Multipart payments
//!
//! <https://github.com/cashubtc/nuts/blob/main/15.md>
use serde::{Deserialize, Serialize};
use super::{CurrencyUnit, PaymentMethod};
use crate::Amount;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(rename = "lowercase")]
pub struct Mpp {
pub amount: Amount,
}
/// Mpp Method Settings
#[derive(Debug, Default, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct MppMethodSettings {
/// Payment Method e.g. bolt11
pub method: PaymentMethod,
/// Currency Unit e.g. sat
pub unit: CurrencyUnit,
/// Multi part payment support
pub mpp: bool,
}
/// Mpp Settings
#[derive(Debug, Default, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct Settings {
pub methods: Vec<MppMethodSettings>,
}

View File

@@ -7,6 +7,7 @@ use url::Url;
use super::Error; use super::Error;
use crate::error::ErrorResponse; use crate::error::ErrorResponse;
use crate::nuts::nut15::Mpp;
use crate::nuts::{ use crate::nuts::{
BlindedMessage, CheckStateRequest, CheckStateResponse, CurrencyUnit, Id, KeySet, KeysResponse, BlindedMessage, CheckStateRequest, CheckStateResponse, CurrencyUnit, Id, KeySet, KeysResponse,
KeysetResponse, MeltBolt11Request, MeltBolt11Response, MeltQuoteBolt11Request, KeysetResponse, MeltBolt11Request, MeltBolt11Response, MeltQuoteBolt11Request,
@@ -169,10 +170,17 @@ impl HttpClient {
mint_url: Url, mint_url: Url,
unit: CurrencyUnit, unit: CurrencyUnit,
request: Bolt11Invoice, request: Bolt11Invoice,
mpp_amount: Option<Amount>,
) -> Result<MeltQuoteBolt11Response, Error> { ) -> Result<MeltQuoteBolt11Response, Error> {
let url = join_url(mint_url, &["v1", "melt", "quote", "bolt11"])?; let url = join_url(mint_url, &["v1", "melt", "quote", "bolt11"])?;
let request = MeltQuoteBolt11Request { request, unit }; let options = mpp_amount.map(|amount| Mpp { amount });
let request = MeltQuoteBolt11Request {
request,
unit,
options,
};
let res = self let res = self
.inner .inner

View File

@@ -965,6 +965,7 @@ impl Wallet {
mint_url: UncheckedUrl, mint_url: UncheckedUrl,
unit: CurrencyUnit, unit: CurrencyUnit,
request: String, request: String,
mpp: Option<Amount>,
) -> Result<MeltQuote, Error> { ) -> Result<MeltQuote, Error> {
let quote_res = self let quote_res = self
.client .client
@@ -972,6 +973,7 @@ impl Wallet {
mint_url.clone().try_into()?, mint_url.clone().try_into()?,
unit.clone(), unit.clone(),
Bolt11Invoice::from_str(&request.clone())?, Bolt11Invoice::from_str(&request.clone())?,
mpp,
) )
.await?; .await?;
@@ -1018,7 +1020,7 @@ impl Wallet {
} }
/// Melt /// Melt
#[instrument(skip(self, quote_id), fields(mint_url = %mint_url))] #[instrument(skip(self), fields(mint_url = %mint_url))]
pub async fn melt( pub async fn melt(
&self, &self,
mint_url: &UncheckedUrl, mint_url: &UncheckedUrl,