Skip to content

Commit

Permalink
Fix compile
Browse files Browse the repository at this point in the history
  • Loading branch information
benthecarman committed Oct 1, 2023
1 parent c859a25 commit 256b8a7
Show file tree
Hide file tree
Showing 6 changed files with 70 additions and 47 deletions.
12 changes: 3 additions & 9 deletions mutiny-core/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ pub enum MutinyError {
PayjoinCreateRequest,
/// Payjoin response validation failed.
#[error("Failed to validate payjoin response.")]
PayjoinValidateResponse,
PayjoinValidateResponse(payjoin::send::ValidationError),
/// Payjoin configuration error
#[error("Payjoin configuration failed.")]
PayjoinConfigError,
Expand Down Expand Up @@ -394,13 +394,7 @@ impl From<payjoin::send::CreateRequestError> for MutinyError {
}

impl From<payjoin::send::ValidationError> for MutinyError {
fn from(_e: payjoin::send::ValidationError) -> Self {
Self::PayjoinValidateResponse
}
}

impl From<payjoin::send::ConfigurationError> for MutinyError {
fn from(_e: payjoin::send::ConfigurationError) -> Self {
Self::PayjoinConfigError
fn from(e: payjoin::send::ValidationError) -> Self {
Self::PayjoinValidateResponse(e)
}
}
66 changes: 45 additions & 21 deletions mutiny-core/src/nodemanager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,11 @@ use crate::{gossip::*, scorer::HubPreferentialScorer};
use crate::{labels::LabelStorage, subscription::MutinySubscriptionClient};
use anyhow::anyhow;
use bdk::chain::{BlockId, ConfirmationTime};
use bdk::{wallet::AddressIndex, LocalUtxo};
use bdk::{wallet::AddressIndex, FeeRate, LocalUtxo};
use bitcoin::blockdata::script;
use bitcoin::hashes::hex::ToHex;
use bitcoin::hashes::{sha256, Hash};
use bitcoin::psbt::PartiallySignedTransaction;
use bitcoin::secp256k1::{rand, PublicKey, Secp256k1, SecretKey};
use bitcoin::util::bip32::{DerivationPath, ExtendedPrivKey};
use bitcoin::{Address, Network, OutPoint, Transaction, Txid};
Expand All @@ -59,10 +60,11 @@ use lnurl::lnurl::LnUrl;
use lnurl::{AsyncClient as LnUrlClient, LnUrlResponse, Response};
use nostr::key::XOnlyPublicKey;
use nostr::{EventBuilder, Keys, Kind, Tag, TagKind};
use payjoin::PjUri;
use payjoin::{PjUri, PjUriExt};
use reqwest::Client;
use serde::{Deserialize, Serialize};
use serde_json::Value;
use std::io::Cursor;
use std::str::FromStr;
use std::sync::atomic::{AtomicBool, Ordering};
use std::{collections::HashMap, ops::Deref, sync::Arc};
Expand Down Expand Up @@ -1063,53 +1065,75 @@ impl<S: MutinyStorage> NodeManager<S> {

pub async fn send_payjoin(
&self,
pj_uri: PjUri,
uri: PjUri<'_>,
amount: u64,
labels: Vec<String>,
fee_rate: Option<f32>,
) -> Result<Txid, MutinyError> {
let uri = payjoin::Uri::try_from(uri)?
.require_network(self.network)
.map_err(|_| MutinyError::IncorrectNetwork(self.network))?
.check_pj_supported()
let address = Address::from_str(&uri.address.to_string())
.map_err(|_| MutinyError::PayjoinConfigError)?;
let original_psbt = self.wallet.create_signed_psbt(address, amount, fee_rate)?;

let original_psbt = self
.wallet
.create_signed_psbt(uri.address, amount, Some(fee_rate))?;

let payout_scripts = std::iter::once(uri.address.script_pubkey()).collect();
let payout_scripts = std::iter::once(uri.address.script_pubkey()).collect::<Vec<_>>();
let fee_rate = if let Some(rate) = fee_rate {
FeeRate::from_sat_per_vb(rate)
} else {
let sat_per_kwu = self
.fees
.fee_estimator
.get_est_sat_per_1000_weight(ConfirmationTarget::Normal);
FeeRate::from_sat_per_kwu(sat_per_kwu as f32)
};
let fee_rate = payjoin::bitcoin::FeeRate::from_sat_per_kwu(fee_rate.sat_per_kwu() as u64);
let original_psbt = payjoin::bitcoin::psbt::PartiallySignedTransaction::from_str(
&original_psbt.to_string(),
)
.map_err(|_| MutinyError::PayjoinConfigError)?;
let pj_params =
payjoin::send::Configuration::recommended(original_psbt, payout_scripts, fee_rate)?;
let (req, ctx) = uri.create_pj_request(psbt, pj_params)?;
payjoin::send::Configuration::recommended(&original_psbt, payout_scripts, fee_rate)
.map_err(|_| MutinyError::PayjoinConfigError)?;

log_debug!(self.logger, "Creating payjoin request");
let (req, ctx) = uri.create_pj_request(original_psbt.clone(), pj_params)?;

let client = Client::builder()
.build()
.map_err(|_| MutinyError::PayjoinConfigError)?;

let mut res = client
log_debug!(self.logger, "Sending payjoin request");
let res = client
.post(req.url)
.body(req.body)
.header("Content-Type", "text/plain")
.send()
.await
.map_err(|_| MutinyError::PayjoinValidateResponseError)?
.text()
.map_err(|_| MutinyError::PayjoinCreateRequest)?
.bytes()
.await
.map_err(|_| MutinyError::PayjoinValidateResponseError)?;
.map_err(|_| MutinyError::PayjoinCreateRequest)?;

let mut cursor = Cursor::new(res.to_vec());

let mut proposal_psbt = ctx.process_response(res)?;
log_debug!(self.logger, "Processing payjoin response");
let proposal_psbt = ctx.process_response(&mut cursor).map_err(|e| {
log_error!(self.logger, "Error processing payjoin response: {e}");
e
})?;

self.wallet.send_payjoin(original_psbt, proposal_psbt).await
// convert to pdk types
let original_psbt = PartiallySignedTransaction::from_str(&original_psbt.to_string())
.map_err(|_| MutinyError::PayjoinConfigError)?;
let proposal_psbt = PartiallySignedTransaction::from_str(&proposal_psbt.to_string())
.map_err(|_| MutinyError::PayjoinConfigError)?;

log_debug!(self.logger, "Sending payjoin..");
let tx = self
.wallet
.send_payjoin(original_psbt, proposal_psbt, labels)
.await?;
let txid = tx.txid();
self.broadcast_transaction(tx).await?;
log_debug!(self.logger, "Payjoin broadcast! TXID: {txid}");
Ok(txid)
}

/// Sends an on-chain transaction to the given address.
Expand Down
29 changes: 14 additions & 15 deletions mutiny-core/src/onchain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,13 @@ use bdk::{FeeRate, LocalUtxo, SignOptions, TransactionDetails, Wallet};
use bdk_esplora::EsploraAsyncExt;
use bitcoin::consensus::serialize;
use bitcoin::hashes::hex::ToHex;
use bitcoin::psbt::PartiallySignedTransaction;
use bitcoin::psbt::{Input, PartiallySignedTransaction};
use bitcoin::util::bip32::{ChildNumber, DerivationPath, ExtendedPrivKey};
use bitcoin::{Address, Network, OutPoint, Script, Transaction, Txid};
use lightning::chain::chaininterface::{ConfirmationTarget, FeeEstimator};
use lightning::events::bump_transaction::{Utxo, WalletSource};
use lightning::util::logger::Logger;
use lightning::{log_debug, log_error, log_info, log_warn};
use payjoin::{PjUri, PjUriExt, UriExt};

use crate::error::MutinyError;
use crate::fees::MutinyFeeEstimator;
Expand Down Expand Up @@ -486,19 +485,20 @@ impl<S: MutinyStorage> OnChainWallet<S> {
Ok(txid)
}

pub fn send_payjoin(
pub async fn send_payjoin(
&self,
original_psbt: PartiallySignedTransaction,
proposal_psbt: PartiallySignedTransaction,
) -> Result<Txid, MutinyError> {
let mut wallet = self.wallet.try_write()?;
mut original_psbt: PartiallySignedTransaction,
mut proposal_psbt: PartiallySignedTransaction,
labels: Vec<String>,
) -> Result<Transaction, MutinyError> {
let wallet = self.wallet.try_read()?;

// add original psbt input map data in place so BDK knows which scripts to sign,
// proposal_psbt only contains the sender input outpoints, not scripts, which BDK
// does not look up
fn input_pairs(
psbt: &mut PartiallySignedTransaction,
) -> Box<dyn Iterator<Item = (&bdk::bitcoin::TxIn, &mut Input)> + '_> {
) -> Box<dyn Iterator<Item = (&bitcoin::TxIn, &mut Input)> + '_> {
Box::new(psbt.unsigned_tx.input.iter().zip(&mut psbt.inputs))
}

Expand All @@ -515,14 +515,13 @@ impl<S: MutinyStorage> OnChainWallet<S> {
}

// sign and finalize payjoin
let payjoin = wallet
.sign(&mut proposal_psbt, SignOptions::default())?
.extract_tx();
let txid = payjoin.txid();
wallet.sign(&mut proposal_psbt, SignOptions::default())?;
drop(wallet);

self.broadcast_transaction(payjoin.clone()).await?;
log_debug!(self.logger, "Payjoin broadcast! TXID: {txid}");
Ok(txid)
self.label_psbt(&proposal_psbt, labels)?;
let payjoin = proposal_psbt.extract_tx();

Ok(payjoin)
}

pub fn create_sweep_psbt(
Expand Down
1 change: 1 addition & 0 deletions mutiny-wasm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ bip39 = { version = "2.0.0" }
getrandom = { version = "0.2", features = ["js"] }
futures = "0.3.25"
urlencoding = "2.1.2"
payjoin = { version = "0.10.0", features = ["send", "base64"] }

# The `console_error_panic_hook` crate provides better debugging of panics by
# logging them with `console.error`. This is great for development, but requires
Expand Down
2 changes: 1 addition & 1 deletion mutiny-wasm/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ impl From<MutinyError> for MutinyJsError {
MutinyError::LspAmountTooHighError => MutinyJsError::LspAmountTooHighError,
MutinyError::PayjoinConfigError => MutinyJsError::PayjoinConfigError,
MutinyError::PayjoinCreateRequest => MutinyJsError::PayjoinCreateRequest,
MutinyError::PayjoinValidateResponse => MutinyJsError::PayjoinValidateResponse,
MutinyError::PayjoinValidateResponse(_) => MutinyJsError::PayjoinValidateResponse,
}
}
}
Expand Down
7 changes: 6 additions & 1 deletion mutiny-wasm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ use mutiny_core::{labels::LabelStorage, nodemanager::NodeManager};
use mutiny_core::{logging::MutinyLogger, nostr::ProfileType};
use nostr::key::XOnlyPublicKey;
use nostr::prelude::FromBech32;
use payjoin::UriExt;
use std::str::FromStr;
use std::sync::Arc;
use std::{
Expand Down Expand Up @@ -355,7 +356,11 @@ impl MutinyWallet {
fee_rate: Option<f32>,
) -> Result<String, MutinyJsError> {
// I know walia parses `pj=` and `pjos=` but payjoin::Uri parses the whole bip21 uri
let pj_uri = payjoin::Uri::try_from(payjoin_uri.as_str())?;
let pj_uri = payjoin::Uri::try_from(payjoin_uri.as_str())
.map_err(|_| MutinyJsError::InvalidArgumentsError)?
.assume_checked()
.check_pj_supported()
.map_err(|_| MutinyJsError::InvalidArgumentsError)?;
let labels: Vec<String> = labels
.into_serde()
.map_err(|_| MutinyJsError::InvalidArgumentsError)?;
Expand Down

0 comments on commit 256b8a7

Please sign in to comment.