Skip to content

Commit

Permalink
Merge pull request #1 from f321x/first_improvements
Browse files Browse the repository at this point in the history
LGTM
  • Loading branch information
f321x committed Jul 6, 2024
2 parents 1079849 + bc9272b commit 77b49b6
Show file tree
Hide file tree
Showing 6 changed files with 107 additions and 53 deletions.
20 changes: 11 additions & 9 deletions .env
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
# Test setup,
# in productive use pubkeys and contract information
# should be handled outside of the client
PROVIDER_NOSTR_NSEC=
BUYER_NOSTR_NSEC=
SELLER_NOSTR_NSEC=
PROVIDER_ECASH_SECRET_HEX=
BUYER_ECASH_SECRET_HEX=
SELLER_ECASH_SECRET_HEX=
# Buyer
BUYER_NSEC=nsec182ul8zg2jlje6gtejs4pp4y4un674esq9qmrdxn2mewynkegahgqudmhvh
BUYER_NPUB=npub1rsdt7jfwkk9mnzn6vne6geuaaz6rvtr6twxsedzrkan3jzk2uyjsczwcxu

# Seller
SELLER_NSEC=nsec1vackt9cn8ujwz9t2yj6x29d4tgjx3uhp5h0fyev8tp5lnw40lcls3rp7hp
SELLER_NPUB=npub1pjnvp4kwud0r80kk23h726tn8ewfqmd4y5m9g2rggs0xrdzrgexq0hv5gr

# Escrow Provider
ESCROW_NSEC=nsec1z62pah093gfj7wzjssc24x3nczmjgy778pxwale7hwesemmzln0qc4dhhu
ESCROW_NPUB=npub1hcsc4r3xc9ygnefp4eqyan9r46tjvd3w0dxk2hgydc9k6m5xd3jq2hkjqp
45 changes: 45 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "lldb",
"request": "launch",
"name": "Debug executable 'birdseed-escrow'",
"cargo": {
"args": [
"build",
"--bin=birdseed-escrow",
"--package=birdseed-escrow"
],
"filter": {
"name": "birdseed-escrow",
"kind": "bin"
}
},
"args": [],
"cwd": "${workspaceFolder}"
},
{
"type": "lldb",
"request": "launch",
"name": "Debug unit tests in executable 'birdseed-escrow'",
"cargo": {
"args": [
"test",
"--no-run",
"--bin=birdseed-escrow",
"--package=birdseed-escrow"
],
"filter": {
"name": "birdseed-escrow",
"kind": "bin"
}
},
"args": [],
"cwd": "${workspaceFolder}"
}
]
}
26 changes: 14 additions & 12 deletions src/escrow_client/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ impl Trader {
async fn seller_pipeline(&self, config: &EscrowUser) -> anyhow::Result<()> {
let escrow_token = config.await_and_validate_trade_token().await?;

// send product and proof of delivery (oracle) to seller


// await signature or begin dispute
Ok(())
}
Expand Down Expand Up @@ -104,12 +107,13 @@ impl EscrowUser {
trade_beginning_ts: Timestamp,
provider_npub: &String,
) -> anyhow::Result<PublicKey> {
let filter_note = Filter::new().kind(Kind::EncryptedDirectMessage);
let filter_timestamp = Filter::new().since(trade_beginning_ts);
let filter_author = Filter::new().author(nostr_sdk::PublicKey::from_bech32(provider_npub)?);
let filter_note = Filter::new()
.kind(Kind::EncryptedDirectMessage)
.since(trade_beginning_ts)
.author(nostr_sdk::PublicKey::from_bech32(provider_npub)?);
nostr_client
.client
.subscribe(vec![filter_note, filter_timestamp, filter_author], None)
.subscribe(vec![filter_note], None)
.await;

let mut notifications = nostr_client.client.notifications();
Expand All @@ -132,15 +136,13 @@ impl EscrowUser {
}

async fn await_and_validate_trade_token(&self) -> anyhow::Result<cdk::nuts::Token> {
let filter_note = Filter::new().kind(Kind::EncryptedDirectMessage);
let filter_timestamp =
Filter::new().since(Timestamp::from(self.contract.trade_beginning_ts));
let filter_author = Filter::new().author(nostr_sdk::PublicKey::from_bech32(
&self.contract.npub_buyer,
)?);
let filter_note = Filter::new()
.kind(Kind::EncryptedDirectMessage)
.since(Timestamp::from(self.contract.trade_beginning_ts))
.author(nostr_sdk::PublicKey::from_bech32(&self.contract.npub_buyer,)?);
self.nostr_client
.client
.subscribe(vec![filter_note, filter_timestamp, filter_author], None)
.subscribe(vec![filter_note], None)
.await;

let mut notifications = self.nostr_client.client.notifications();
Expand All @@ -152,7 +154,7 @@ impl EscrowUser {
.decrypt_msg(&event.content, &event.author())
.await
{
println!("Received event: {:?}", &decrypted);
dbg!("Received token event: {:?}", &decrypted);
if let Ok(escrow_token) =
self.wallet.validate_escrow_token(&decrypted, &self).await
{
Expand Down
21 changes: 12 additions & 9 deletions src/escrow_provider/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use super::*;
use cdk::nuts::SecretKey;
use hashes::hex::DisplayHex;
use nostr_sdk::{Filter, Kind, RelayPoolNotification};
use serde::{Deserialize, Serialize};
use sha2::{Digest, Sha256};
Expand Down Expand Up @@ -41,16 +42,17 @@ impl EscrowProvider {
}

pub async fn run(&mut self) -> anyhow::Result<()> {
let filter_note = Filter::new().kind(Kind::EncryptedDirectMessage);

let filter_self = Filter::new().custom_tag(
SingleLetterTag::lowercase(Alphabet::P),
[PublicKey::from_bech32(&self.nostr_client.get_npub().await?)?.to_hex()],
);
let filter_note = Filter::new()
.kind(Kind::EncryptedDirectMessage)
.custom_tag(
SingleLetterTag::lowercase(Alphabet::P),
[PublicKey::from_bech32(&self.nostr_client.get_npub()?)?.to_hex()],
)
.since(Timestamp::now());

self.nostr_client
.client
.subscribe(vec![filter_note, filter_self], None)
.subscribe(vec![filter_note], None)
.await;
let mut notifications = self.nostr_client.client.notifications();

Expand All @@ -61,8 +63,8 @@ impl EscrowProvider {
.decrypt_msg(&event.content, &event.author())
.await
{
println!("Received event: {:?}", &decrypted);
if let Ok((contract_hash, contract)) = self.parse(&event.content).await {
dbg!("Received event: {:?}", &decrypted);
if let Ok((contract_hash, contract)) = self.parse(decrypted.as_str()).await {
if self.pending_contracts.contains_key(&contract_hash) {
self.pending_contracts.remove(&contract_hash);
self.begin_trade(&contract_hash, &contract).await?;
Expand Down Expand Up @@ -93,6 +95,7 @@ impl EscrowProvider {
contract_hash: &[u8; 32],
trade: &TradeContract,
) -> anyhow::Result<()> {
dbg!("Beginning trade: {}", contract_hash.to_hex_string(hashes::hex::Case::Lower));
let contract_secret = SecretKey::generate();
self.active_contracts.insert(
contract_hash.clone(),
Expand Down
46 changes: 24 additions & 22 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ mod escrow_client;
mod escrow_provider;
mod nostr;

use std::env;

use anyhow::{anyhow, Result};
use cli::get_user_input;
use dotenv::dotenv;
Expand All @@ -18,43 +20,45 @@ async fn main() -> anyhow::Result<()> {
dotenv().ok();
// parsing was hacked together last minute :)
// information would be communicated oob
let mut buyer_npub: String = String::new();
let mut seller_npub: String = String::new();
let mut coordinator_npub: String = String::new();
let mut buyer_npub: String = env::var("BUYER_NPUB")?;
let mut seller_npub: String = env::var("SELLER_NPUB")?;
let coordinator_npub: String = env::var("ESCROW_NPUB")?;
let ecash_wallet = EcashWallet::new().await?;
let mut seller_ecash_pubkey: String = String::new();
let mut buyer_ecash_pubkey: String = String::new();
let nostr_client = NostrClient::new(&get_user_input("Enter nostr nsec: ").await?).await?;
let nostr_client: NostrClient;

let mode = match get_user_input("Select mode: buyer, seller, provider: ")
let mode = match get_user_input("Select mode: (1) buyer, (2) seller, (3) provider: ")
.await?
.as_str()
{
"buyer" => {
buyer_npub = nostr_client.get_npub().await?;
println!("Buyer npub: {}", &buyer_npub);
seller_npub = get_user_input("Enter seller's npub: ").await?;
"1" => {
nostr_client = NostrClient::new(&env::var("BUYER_NSEC")?).await?;
buyer_npub = nostr_client.get_npub()?;
//println!("Buyer npub: {}", &buyer_npub);
seller_ecash_pubkey = get_user_input("Enter seller's ecash pubkey: ").await?;
coordinator_npub = get_user_input("Enter coordinator's npub: ").await?;
buyer_ecash_pubkey = ecash_wallet.trade_pubkey.clone();
String::from("buyer")
}
"seller" => {
seller_npub = nostr_client.get_npub().await?;
println!("Seller npub: {}", &seller_npub);
"2" => {
nostr_client = NostrClient::new(&env::var("SELLER_NSEC")?).await?;
seller_npub = nostr_client.get_npub()?;
//println!("Seller npub: {}", &seller_npub);
seller_ecash_pubkey = ecash_wallet.trade_pubkey.clone();
buyer_npub = get_user_input("Enter buyer's npub: ").await?;
buyer_ecash_pubkey = get_user_input("Enter buyer's ecash pubkey: ").await?;
coordinator_npub = get_user_input("Enter coordinator's npub: ").await?;
String::from("seller")
}
"provider" => {
println!("Coordinator npub: {}", nostr_client.get_npub().await?);
"3" => {
nostr_client = NostrClient::new(&env::var("ESCROW_NSEC")?).await?;
//println!("Coordinator npub: {}", nostr_client.get_npub().await?);
let mut escrow_provider = EscrowProvider::setup(nostr_client, ecash_wallet).await?;
escrow_provider.run().await?;
return Ok(());
}
_ => String::from("none"),
_ => {
nostr_client = NostrClient::new(&env::var("ESCROW_NSEC")?).await?;//irrelevant
String::from("none")
}
};

let contract = TradeContract {
Expand All @@ -74,10 +78,8 @@ async fn main() -> anyhow::Result<()> {
EscrowUser::new(contract, ecash_wallet, nostr_client, coordinator_npub).await?;

match mode.as_str() {
"buyer" => Trader::Buyer(escrow_user).init_trade().await?,
"seller" => Trader::Seller(escrow_user).init_trade().await?,
"buyer" => Trader::Buyer(escrow_user).init_trade().await,
"seller" => Trader::Seller(escrow_user).init_trade().await,
_ => return Err(anyhow!("Invalid mode")),
}

Ok(())
}
2 changes: 1 addition & 1 deletion src/nostr/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ impl NostrClient {
Ok(Self { keypair, client })
}

pub async fn get_npub(&self) -> anyhow::Result<String> {
pub fn get_npub(&self) -> anyhow::Result<String> {
Ok(self.keypair.public_key().to_bech32()?)
}

Expand Down

0 comments on commit 77b49b6

Please sign in to comment.