Skip to content

Commit 2fab244

Browse files
grunchclaude
andcommitted
fix: sign restore and last-trade-index requests with identity keys
Restore and LastTradeIndex are account-scoped queries: Mostro looks up the user by the sender pubkey on the gift wrap, so signing with a per-trade key leaves the request either resolving to an unknown user or to stale trade-index state — either way, recovery flows silently return nothing. Revert these two call sites to `identity_keys` as the signer, and route `wait_for_dm` / `parse_dm_events` on the same key so the response (which Mostro addresses back to the sender pubkey) is the one we subscribe to and can decrypt. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 0c4551d commit 2fab244

2 files changed

Lines changed: 14 additions & 8 deletions

File tree

src/cli/last_trade_index.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,13 @@ pub async fn execute_last_trade_index(
2323
.as_json()
2424
.map_err(|_| anyhow::anyhow!("Failed to serialize message"))?;
2525

26-
// Send the last trade index message to Mostro server
26+
// LastTradeIndex is account-scoped: the answer depends on which user
27+
// is asking, and Mostro looks that up by the sender pubkey. Sign with
28+
// `identity_keys` so the request resolves to the account, not to a
29+
// (possibly unregistered) trade key.
2730
let sent_message = send_dm(
2831
&ctx.client,
29-
&ctx.trade_keys,
32+
identity_keys,
3033
&mostro_key,
3134
message_json,
3235
None,
@@ -41,10 +44,10 @@ pub async fn execute_last_trade_index(
4144
println!();
4245

4346
// Wait for incoming DM
44-
let recv_event = wait_for_dm(ctx, Some(&ctx.trade_keys), sent_message).await?;
47+
let recv_event = wait_for_dm(ctx, Some(identity_keys), sent_message).await?;
4548

4649
// Parse the incoming DM
47-
let messages = parse_dm_events(recv_event, &ctx.trade_keys, None).await;
50+
let messages = parse_dm_events(recv_event, identity_keys, None).await;
4851
if let Some((message, _, _)) = messages.first() {
4952
let message = message.get_inner_message_kind();
5053
if message.action == Action::LastTradeIndex {

src/cli/restore.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,13 @@ pub async fn execute_restore(
1919
.as_json()
2020
.map_err(|_| anyhow::anyhow!("Failed to serialize message"))?;
2121

22-
// Send the restore message to Mostro server
22+
// Restore is account-scoped: Mostro indexes users by their identity
23+
// pubkey, so the whole exchange (send, wait, decrypt) runs on
24+
// `identity_keys` — an unregistered trade key would look like an
25+
// unknown user and recovery would silently return nothing.
2326
let sent_message = send_dm(
2427
&ctx.client,
25-
&ctx.trade_keys,
28+
identity_keys,
2629
&mostro_key,
2730
message_json,
2831
None,
@@ -48,10 +51,10 @@ pub async fn execute_restore(
4851
println!("⏳ Recovering pending orders and disputes...\n");
4952

5053
// Wait for incoming DM
51-
let recv_event = wait_for_dm(ctx, Some(&ctx.trade_keys), sent_message).await?;
54+
let recv_event = wait_for_dm(ctx, Some(identity_keys), sent_message).await?;
5255

5356
// Parse the incoming DM
54-
let messages = parse_dm_events(recv_event, &ctx.trade_keys, None).await;
57+
let messages = parse_dm_events(recv_event, identity_keys, None).await;
5558
if let Some((message, _, _)) = messages.first() {
5659
let message = message.get_inner_message_kind();
5760
if message.action == Action::RestoreSession {

0 commit comments

Comments
 (0)