Skip to content

Commit

Permalink
Get payjoin send-receive communicating
Browse files Browse the repository at this point in the history
  • Loading branch information
DanGould committed May 11, 2024
1 parent 3e8b5ac commit c6510a9
Show file tree
Hide file tree
Showing 14 changed files with 369 additions and 216 deletions.
34 changes: 6 additions & 28 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion dev/payjoin-cli/config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ bitcoind_rpcuser = "rpcuser"
bitcoind_rpcpass = "rpcpassword"
bitcoind_rpchost = "http://bitcoind:18443" # use default wallet
pj_endpoint = "https://payjo.in"
ohttp_relay = "https://ohttp.payjoin.org"
ohttp_relay = "https://pj.bobspacebkk.com"
4 changes: 4 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,10 @@ services:
volumes:
- ${HOST_PROJECT_PATH:-.}/dev/payjoin-cli/config.toml:/config.toml
depends_on: [ bitcoind ]
entrypoint: [ "/bin/sh", "-c" ]
command:
- |
tail -f /dev/null
lnd:
image: lightninglabs/lnd:v0.15.4-beta
volumes:
Expand Down
4 changes: 3 additions & 1 deletion src/address/repo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ impl Addresses {
account_id: AccountId,
address: String,
) -> Result<WalletAddress, AddressError> {
println!("find address: {:?}", address);
let rows = sqlx::query!(
r#"
SELECT b.id, e.sequence, e.event
Expand All @@ -161,7 +162,7 @@ impl Addresses {
)
.fetch_all(&self.pool)
.await?;

println!("found smth?");
if rows.is_empty() {
return Err(AddressError::AddressNotFound(address));
}
Expand All @@ -170,6 +171,7 @@ impl Addresses {
for row in rows {
events.load_event(row.sequence as usize, row.event)?;
}
println!("event loaded");
Ok(WalletAddress::try_from(events)?)
}

Expand Down
1 change: 1 addition & 0 deletions src/api/server/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,7 @@ impl BriaService for Bria {
) -> Result<Response<NewUriResponse>, Status> {
crate::tracing::record_error(|| async move {
extract_tracing(&request);
println!("REQ");

let key = extract_api_token(&request)?;
let profile = self.app.authenticate(key).await?;
Expand Down
94 changes: 22 additions & 72 deletions src/app/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
mod config;
pub mod error;

use bdk::bitcoin::address::NetworkChecked;
use bdk::bitcoin::{address::NetworkChecked, Amount};
use payjoin::receive::v2::Enrolled;
use sqlxmq::JobRunnerHandle;
use tracing::instrument;
Expand All @@ -13,24 +13,7 @@ pub use config::*;
use error::*;

use crate::{
account::balance::AccountBalanceSummary,
address::*,
batch::*,
batch_inclusion::*,
descriptor::*,
fees::{self, *},
job,
ledger::*,
outbox::*,
payjoin::*,
payout::*,
payout_queue::*,
primitives::*,
profile::*,
signing_session::*,
utxo::*,
wallet::{balance::*, *},
xpub::*,
account::balance::AccountBalanceSummary, address::*, api::proto::payout, batch::*, batch_inclusion::*, descriptor::*, fees::{self, *}, job, ledger::*, outbox::*, payjoin::{config::PayjoinConfig, *}, payout::*, payout_queue::*, primitives::*, profile::*, signing_session::*, utxo::*, wallet::{balance::*, *}, xpub::*
};

#[allow(dead_code)]
Expand All @@ -53,6 +36,7 @@ pub struct App {
batch_inclusion: BatchInclusion,
pool: sqlx::PgPool,
config: AppConfig,
pj: crate::payjoin::PayjoinReceiver,
}

impl App {
Expand Down Expand Up @@ -102,14 +86,15 @@ impl App {
config.jobs.respawn_all_outbox_handlers_delay,
)
.await?;
// let pj = PayjoinReceiver::new(
// PayjoinConfig { listen_port: 8088 },
// addresses.clone(),
// utxos.clone(),
// wallets.clone(),
// config.blockchain.network,
// );
//Self::spawn_payjoin_receiver(pj).await?;
let pj = PayjoinReceiver::new(
pool.clone(),
payout_queues.clone(),
PayjoinConfig { listen_port: 8088 },
addresses.clone(),
utxos.clone(),
wallets.clone(),
config.blockchain.network,
);
let app = Self {
outbox,
profiles: Profiles::new(&pool),
Expand All @@ -127,6 +112,7 @@ impl App {
fees_client,
batch_inclusion,
config,
pj,
_runner: runner,
};
crate::profile::migration::profile_event_migration(&app.pool).await?;
Expand Down Expand Up @@ -543,7 +529,8 @@ impl App {
.await?;
let keychain_wallet = wallet.current_keychain_wallet(&self.pool);
let addr = keychain_wallet.new_external_address().await?;
let address = Address::from(addr.address);
let address = Address::from(addr.address.clone());
println!("got address: {:?}", addr.address);
let mut builder = NewAddress::builder();
builder
.address(address.clone())
Expand All @@ -559,47 +546,17 @@ impl App {
}
let new_address = builder.build().expect("Couldn't build NewUri");
self.addresses.persist_new_address(new_address).await?;

let (enrolled, ohttp_keys) = Self::start_payjoin_session().await?;
println!("init payjoin");
let (enrolled, ohttp_keys) = crate::payjoin::init_payjoin_session(self.pj.clone(), profile.account_id).await?;
println!("init'd payjoin");
// TODO save session to DB
let uri = enrolled.fallback_target();

let pj_dir = enrolled.fallback_target();
let uri = payjoin::PjUriBuilder::new(addr.address, url::Url::parse(&pj_dir).map_err(|e| anyhow::anyhow!(e.to_string()))?, Some(ohttp_keys))
.amount(Amount::from_sat(600_000))
.build().to_string();
Ok((wallet.id, uri))
}

async fn start_payjoin_session() -> Result<(Enrolled, payjoin::OhttpKeys), anyhow::Error> {
let payjoin_dir = Url::parse("https://payjo.in").expect("Invalid URL");
let ohttp_relays: [Url; 2] = [
Url::parse("https://pj.bobspacebkk.com").expect("Invalid URL"),
Url::parse("https://ohttp-relay.obscuravpn.io").expect("Invalid URL"),
];
let ohttp_keys = payjoin_defaults::fetch_ohttp_keys(ohttp_relays[0].clone(), payjoin_dir.clone())?;
let http_client = reqwest::Client::builder().build()?;

fn random_ohttp_relay(ohttp_relays: [Url; 2]) -> Url {
use rand::seq::SliceRandom;
use rand::thread_rng;
ohttp_relays.choose(&mut thread_rng()).unwrap().clone()
}
let mut enroller = payjoin::receive::v2::Enroller::from_directory_config(
payjoin_dir.to_owned(),
ohttp_keys.clone(),
random_ohttp_relay(ohttp_relays).to_owned(),
);
let (req, context) = enroller.extract_req().map_err(|e| anyhow::anyhow!(e.to_string()))?;
let ohttp_response = http_client
.post(req.url)
.header("Content-Type", "message/ohttp-req")
.body(req.body)
.send()
.await?;
let ohttp_response = ohttp_response.bytes().await?;
Ok((
enroller.process_res(ohttp_response.as_ref(), context).map_err(|e| anyhow::anyhow!(e.to_string()))?,
ohttp_keys,
))
}

#[instrument(name = "app.update_address", skip(self), err)]
pub async fn update_address(
&self,
Expand Down Expand Up @@ -1182,11 +1139,4 @@ impl App {
});
Ok(())
}

async fn spawn_payjoin_receiver(pj: PayjoinReceiver) -> Result<(), ApplicationError> {
tokio::spawn(async move {
crate::payjoin::start(pj).await;
});
Ok(())
}
}
19 changes: 19 additions & 0 deletions src/cli/api_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,25 @@ impl ApiClient {
output_json(response)
}

pub async fn new_uri(
&self,
wallet: String,
external_id: Option<String>,
metadata: Option<serde_json::Value>,
) -> anyhow::Result<()> {
let request = tonic::Request::new(proto::NewAddressRequest {
wallet_name: wallet,
external_id,
metadata: metadata.map(serde_json::from_value).transpose()?,
});
let response = self
.connect()
.await?
.new_uri(self.inject_auth_token(request)?)
.await?;
output_json(response)
}

pub async fn update_address(
&self,
address: String,
Expand Down
29 changes: 29 additions & 0 deletions src/cli/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,25 @@ enum Command {
#[clap(short, long, value_parser = parse_json)]
metadata: Option<serde_json::Value>,
},
// Get a new BIP21 URI for a wallet
NewUri {
#[clap(
short,
long,
value_parser,
default_value = "http://localhost:2742",
env = "BRIA_API_URL"
)]
url: Option<Url>,
#[clap(env = "BRIA_API_KEY", default_value = "")]
api_key: String,
#[clap(short, long)]
wallet: String,
#[clap(short, long)]
external_id: Option<String>,
#[clap(short, long, value_parser = parse_json)]
metadata: Option<serde_json::Value>,
},
/// Update address information
UpdateAddress {
#[clap(
Expand Down Expand Up @@ -851,6 +870,16 @@ pub async fn run() -> anyhow::Result<()> {
let client = api_client(cli.bria_home, url, api_key);
client.new_address(wallet, external_id, metadata).await?;
}
Command::NewUri{
url,
api_key,
wallet,
external_id,
metadata,
} => {
let client = api_client(cli.bria_home, url, api_key);
client.new_uri(wallet, external_id, metadata).await?;
}
Command::UpdateAddress {
url,
api_key,
Expand Down
14 changes: 14 additions & 0 deletions src/job/process_payout_queue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -388,6 +388,20 @@ pub async fn construct_psbt(
.await?)
}

// pub async fn sign_payjoin_psbt(
// psbt: bdk::bitcoin::psbt::Psbt,
// pool: &sqlx::Pool<sqlx::Postgres>,
// tx: &mut sqlx::Transaction<'_, sqlx::Postgres>,
// unbatched_payouts: &UnbatchedPayouts,
// utxos: &Utxos,
// wallets: &Wallets,
// payout_queue: PayoutQueue,
// fee_rate: bitcoin::FeeRate,
// for_estimation: bool,
// ) -> Result<FinishedPsbtBuild, JobError> {

// }

// #[allow(clippy::too_many_arguments)]
// pub async fn construct_payjoin_psbt(
// pool: &sqlx::Pool<sqlx::Postgres>,
Expand Down
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ pub mod fees;
mod job;
pub mod ledger;
mod outbox;
mod payjoin;
pub mod payjoin;
pub mod payout;
pub mod payout_queue;
pub mod primitives;
Expand Down
Loading

0 comments on commit c6510a9

Please sign in to comment.