Skip to content

Commit 8b1c70d

Browse files
authored
Merge pull request #144 from MostroP2P/aligning-message
Completed big refactoring of codebase
2 parents 5f4c207 + 4edef4d commit 8b1c70d

14 files changed

Lines changed: 566 additions & 394 deletions

File tree

Cargo.lock

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ uuid = { version = "1.18.1", features = [
3939
dotenvy = "0.15.6"
4040
lightning-invoice = { version = "0.33.2", features = ["std"] }
4141
reqwest = { version = "0.12.23", features = ["json"] }
42-
mostro-core = "0.6.50"
42+
mostro-core = "0.6.56"
4343
lnurl-rs = "0.9.0"
4444
pretty_env_logger = "0.5.0"
4545
openssl = { version = "0.10.73", features = ["vendored"] }

README.md

Lines changed: 37 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -4,52 +4,58 @@
44

55
Very simple command line interface that show all new replaceable events from [Mostro](https://github.com/MostroP2P/mostro)
66

7-
## Requirements:
7+
## Requirements
88

99
0. You need Rust version 1.64 or higher to compile.
1010
1. You will need a lightning network node
1111

12-
## Install dependencies:
12+
## Install dependencies
1313

1414
To compile on Ubuntu/Pop!\_OS, please install [cargo](https://www.rust-lang.org/tools/install), then run the following commands:
1515

16-
```
17-
$ sudo apt update
18-
$ sudo apt install -y cmake build-essential pkg-config
16+
```bash
17+
sudo apt update
18+
sudo apt install -y cmake build-essential pkg-config
1919
```
2020

2121
## Install
2222

2323
To install you need to fill the env vars (`.env`) on the with your own private key and add a Mostro pubkey.
2424

25-
```
26-
$ git clone https://github.com/MostroP2P/mostro-cli.git
27-
$ cd mostro-cli
28-
$ cp .env-sample .env
29-
$ cargo run
25+
```bash
26+
git clone https://github.com/MostroP2P/mostro-cli.git
27+
cd mostro-cli
28+
cp .env-sample .env
29+
cargo run
3030
```
3131

32-
# Usage
32+
## Usage
3333

34-
```
34+
```bash
3535
Commands:
36-
listorders Requests open orders from Mostro pubkey
37-
neworder Create a new buy/sell order on Mostro
38-
takesell Take a sell order from a Mostro pubkey
39-
takebuy Take a buy order from a Mostro pubkey
40-
addinvoice Buyer add a new invoice to receive the payment
41-
getdm Get the latest direct messages from Mostro
42-
fiatsent Send fiat sent message to confirm payment to other user
43-
release Settle the hold invoice and pay to buyer
44-
cancel Cancel a pending order
45-
rate Rate counterpart after a successful trade
46-
dispute Start a dispute
47-
admcancel Cancel an order (only admin)
48-
admsettle Settle a seller's hold invoice (only admin)
49-
admlistdisputes Requests open disputes from Mostro pubkey
50-
admaddsolver Add a new dispute's solver (only admin)
51-
admtakedispute Admin or solver take a Pending dispute (only admin)
52-
help Print this message or the help of the given subcommand(s)
36+
listorders Requests open orders from Mostro pubkey
37+
neworder Create a new buy/sell order on Mostro
38+
takesell Take a sell order from a Mostro pubkey
39+
takebuy Take a buy order from a Mostro pubkey
40+
addinvoice Buyer add a new invoice to receive the payment
41+
getdm Get the latest direct messages
42+
getadmindm Get the latest direct messages for admin
43+
senddm Send direct message to a user
44+
fiatsent Send fiat sent message to confirm payment to other user
45+
release Settle the hold invoice and pay to buyer
46+
cancel Cancel a pending order
47+
rate Rate counterpart after a successful trade
48+
restore Restore session to recover all pending orders and disputes
49+
dispute Start a dispute
50+
admcancel Cancel an order (only admin)
51+
admsettle Settle a seller's hold invoice (only admin)
52+
admlistdisputes Requests open disputes from Mostro pubkey
53+
admaddsolver Add a new dispute's solver (only admin)
54+
admtakedispute Admin or solver take a Pending dispute (only admin)
55+
admsenddm Send gift wrapped direct message to a user (only admin)
56+
conversationkey Get the conversation key for direct messaging with a user
57+
getlasttradeindex Get last trade index of user
58+
help Print this message or the help of the given subcommand(s)
5359

5460
Options:
5561
-v, --verbose
@@ -60,9 +66,9 @@ Options:
6066
-V, --version Print version
6167
```
6268

63-
# Examples
69+
## Examples
6470

65-
```
71+
```bash
6672
$ mostro-cli -m npub1ykvsmrmw2hk7jgxgy64zr8tfkx4nnjhq9eyfxdlg3caha3ph0skq6jr3z0 -r 'wss://nos.lol,wss://relay.damus.io,wss://nostr-pub.wellorder.net,wss://nostr.mutinywallet.com,wss://relay.nostr.band,wss://nostr.cizmar.net,wss://140.f7z.io,wss://nostrrelay.com,wss://relay.nostrr.de' listorders
6773

6874
# You can set the env vars to avoid the -m, -n and -r flags

src/cli.rs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ pub mod conversation_key;
44
pub mod dm_to_user;
55
pub mod get_dm;
66
pub mod get_dm_user;
7+
pub mod last_trade_index;
78
pub mod list_disputes;
89
pub mod list_orders;
910
pub mod new_order;
@@ -20,6 +21,7 @@ use crate::cli::conversation_key::execute_conversation_key;
2021
use crate::cli::dm_to_user::execute_dm_to_user;
2122
use crate::cli::get_dm::execute_get_dm;
2223
use crate::cli::get_dm_user::execute_get_dm_user;
24+
use crate::cli::last_trade_index::execute_last_trade_index;
2325
use crate::cli::list_disputes::execute_list_disputes;
2426
use crate::cli::list_orders::execute_list_orders;
2527
use crate::cli::new_order::execute_new_order;
@@ -291,6 +293,8 @@ pub enum Commands {
291293
#[arg(short, long)]
292294
pubkey: String,
293295
},
296+
/// Get last trade index of user
297+
GetLastTradeIndex {},
294298
}
295299

296300
fn get_env_var(cli: &Cli) {
@@ -415,9 +419,12 @@ impl Commands {
415419
| Commands::Release { order_id }
416420
| Commands::Dispute { order_id }
417421
| Commands::Cancel { order_id } => {
418-
crate::util::run_simple_order_msg(self.clone(), order_id, ctx).await
422+
crate::util::run_simple_order_msg(self.clone(), Some(*order_id), ctx).await
423+
}
424+
// Last trade index commands
425+
Commands::GetLastTradeIndex {} => {
426+
execute_last_trade_index(&ctx.identity_keys, ctx.mostro_pubkey, ctx).await
419427
}
420-
421428
// DM commands with pubkey parsing
422429
Commands::SendDm {
423430
pubkey,
@@ -489,11 +496,11 @@ impl Commands {
489496

490497
// DM retrieval commands
491498
Commands::GetDm { since, from_user } => {
492-
execute_get_dm(Some(since), false, from_user, ctx).await
499+
execute_get_dm(since, false, from_user, ctx).await
493500
}
494501
Commands::GetDmUser { since } => execute_get_dm_user(since, ctx).await,
495502
Commands::GetAdminDm { since, from_user } => {
496-
execute_get_dm(Some(since), true, from_user, ctx).await
503+
execute_get_dm(since, true, from_user, ctx).await
497504
}
498505

499506
// Admin commands

src/cli/add_invoice.rs

Lines changed: 18 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::util::{send_dm, wait_for_dm};
1+
use crate::util::{print_dm_events, send_dm, wait_for_dm};
22
use crate::{cli::Context, db::Order, lightning::is_valid_invoice};
33
use anyhow::Result;
44
use lnurl::lightning_address::LightningAddress;
@@ -8,11 +8,14 @@ use std::str::FromStr;
88
use uuid::Uuid;
99

1010
pub async fn execute_add_invoice(order_id: &Uuid, invoice: &str, ctx: &Context) -> Result<()> {
11+
// Get order from order id
1112
let order = Order::get_by_id(&ctx.pool, &order_id.to_string()).await?;
13+
// Get trade keys of specific order
1214
let trade_keys = order
1315
.trade_keys
1416
.clone()
1517
.ok_or(anyhow::anyhow!("Missing trade keys"))?;
18+
1619
let order_trade_keys = Keys::parse(&trade_keys)?;
1720
println!(
1821
"Order trade keys: {:?}",
@@ -52,45 +55,22 @@ pub async fn execute_add_invoice(order_id: &Uuid, invoice: &str, ctx: &Context)
5255
.as_json()
5356
.map_err(|_| anyhow::anyhow!("Failed to serialize message"))?;
5457

55-
// Subscribe to gift wrap events - ONLY NEW ONES WITH LIMIT 0
56-
let subscription = Filter::new()
57-
.pubkey(order_trade_keys.clone().public_key())
58-
.kind(nostr_sdk::Kind::GiftWrap)
59-
.limit(0);
60-
61-
let opts = SubscribeAutoCloseOptions::default().exit_policy(ReqExitPolicy::WaitForEvents(1));
62-
ctx.client.subscribe(subscription, Some(opts)).await?;
58+
// Send the DM
59+
let sent_message = send_dm(
60+
&ctx.client,
61+
Some(&ctx.identity_keys),
62+
&order_trade_keys,
63+
&ctx.mostro_pubkey,
64+
message_json,
65+
None,
66+
false,
67+
);
6368

64-
// Clone the keys and client for the async call
65-
let identity_keys_clone = ctx.identity_keys.clone();
66-
let client_clone = ctx.client.clone();
67-
let mostro_pubkey_clone = ctx.mostro_pubkey;
68-
let order_trade_keys_clone = order_trade_keys.clone();
69+
// Wait for the DM to be sent from mostro
70+
let recv_event = wait_for_dm(ctx, Some(&order_trade_keys), sent_message).await?;
6971

70-
// Spawn a new task to send the DM
71-
// This is so we can wait for the gift wrap event in the main thread
72-
tokio::spawn(async move {
73-
let _ = send_dm(
74-
&client_clone,
75-
Some(&identity_keys_clone),
76-
&order_trade_keys,
77-
&mostro_pubkey_clone,
78-
message_json,
79-
None,
80-
false,
81-
)
82-
.await;
83-
});
72+
// Parse the incoming DM
73+
print_dm_events(recv_event, request_id, ctx, Some(&order_trade_keys)).await?;
8474

85-
// Wait for the DM to be sent from mostro and update the order
86-
wait_for_dm(
87-
&ctx.client,
88-
&order_trade_keys_clone,
89-
request_id,
90-
None,
91-
Some(order),
92-
&ctx.pool,
93-
)
94-
.await?;
9575
Ok(())
9676
}

src/cli/get_dm.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use crate::{
88
};
99

1010
pub async fn execute_get_dm(
11-
since: Option<&i64>,
11+
since: &i64,
1212
admin: bool,
1313
from_user: &bool,
1414
ctx: &Context,
@@ -22,7 +22,8 @@ pub async fn execute_get_dm(
2222
};
2323

2424
// Fetch the requested events
25-
let all_fetched_events = { fetch_events_list(list_kind, None, None, None, ctx, since).await? };
25+
let all_fetched_events =
26+
fetch_events_list(list_kind, None, None, None, ctx, Some(since)).await?;
2627

2728
// Extract (Message, u64) tuples from Event::MessageTuple variants
2829
let mut dm_events: Vec<(Message, u64)> = Vec::new();

src/cli/last_trade_index.rs

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
use anyhow::Result;
2+
use mostro_core::prelude::*;
3+
use nostr_sdk::prelude::*;
4+
5+
use crate::{
6+
cli::Context,
7+
parser::{dms::print_commands_results, parse_dm_events},
8+
util::{send_dm, wait_for_dm},
9+
};
10+
11+
pub async fn execute_last_trade_index(
12+
identity_keys: &Keys,
13+
mostro_key: PublicKey,
14+
ctx: &Context,
15+
) -> Result<()> {
16+
let kind = MessageKind::new(None, None, None, Action::LastTradeIndex, None);
17+
let last_trade_index_message = Message::Restore(kind);
18+
let message_json = last_trade_index_message
19+
.as_json()
20+
.map_err(|_| anyhow::anyhow!("Failed to serialize message"))?;
21+
22+
// Send the last trade index message to Mostro server
23+
let sent_message = send_dm(
24+
&ctx.client,
25+
Some(identity_keys),
26+
identity_keys,
27+
&mostro_key,
28+
message_json,
29+
None,
30+
false,
31+
);
32+
33+
// Log the sent message
34+
println!(
35+
"Sent request to Mostro to get last trade index of user {}",
36+
identity_keys.public_key()
37+
);
38+
39+
// Wait for incoming DM
40+
let recv_event = wait_for_dm(ctx, Some(identity_keys), sent_message).await?;
41+
42+
// Parse the incoming DM
43+
let messages = parse_dm_events(recv_event, identity_keys, None).await;
44+
if let Some((message, _, _)) = messages.first() {
45+
let message = message.get_inner_message_kind();
46+
if message.action == Action::LastTradeIndex {
47+
print_commands_results(message, None, ctx).await?
48+
} else {
49+
return Err(anyhow::anyhow!(
50+
"Received response with mismatched action. Expected: {:?}, Got: {:?}",
51+
Action::LastTradeIndex,
52+
message.action
53+
));
54+
}
55+
} else {
56+
return Err(anyhow::anyhow!("No response received from Mostro"));
57+
}
58+
59+
Ok(())
60+
}

0 commit comments

Comments
 (0)