Make saved Cashu sends recoverable and record deferred connection UX scope

This commit is contained in:
archipelago
2026-10-06 17:19:30 -04:00
parent af85d2be53
commit 4228ce443c
7 changed files with 456 additions and 19 deletions
+36 -7
View File
@@ -96,7 +96,7 @@ impl PreparedSwap {
pub(super) fn validate_for_mint(&self, mint_url: &str) -> Result<()> {
anyhow::ensure!(
self.mint_url == mint_url,
self.mint_url.trim_end_matches('/') == mint_url.trim_end_matches('/'),
"Prepared swap belongs to a different mint"
);
anyhow::ensure!(
@@ -173,7 +173,7 @@ impl PreparedSwap {
.collect::<Result<_>>()?;
for proof in proofs {
anyhow::ensure!(
proof.id == self.keyset.id
super::cashu::matches_stored_keyset_id(&proof.id, &self.keyset.id)
&& expected.remove(proof.secret.as_str()) == Some(proof.amount),
"Payment result does not match prepared outputs"
);
@@ -1009,11 +1009,40 @@ impl MintClient {
);
}
Ok(echoed
.into_iter()
.map(|o| o.b_prime)
.zip(signatures)
.collect())
let mut requested = std::collections::HashMap::new();
for output in outputs {
let point = output
.b_prime
.parse::<secp256k1::PublicKey>()
.context("Invalid restoration output point")?
.to_string();
anyhow::ensure!(
requested.insert(point, output).is_none(),
"Duplicate restoration request output"
);
}
let mut restored = Vec::new();
for (output, signature) in echoed.into_iter().zip(signatures) {
let point = output
.b_prime
.parse::<secp256k1::PublicKey>()
.context("Invalid restored output point")?
.to_string();
let original = requested
.remove(&point)
.context("Unknown or duplicate restored output")?;
anyhow::ensure!(
super::cashu::matches_stored_keyset_id(&output.id, &original.id)
&& super::cashu::matches_stored_keyset_id(&signature.id, &original.id)
&& signature.amount.is_power_of_two()
&& (original.amount == 0 || original.amount == signature.amount)
&& (output.amount == 0 || output.amount == signature.amount),
"Restored output metadata changed"
);
signature.c_prime_as_pubkey()?;
restored.push((point, signature));
}
Ok(restored)
}
/// Receive a CashuToken by swapping its proofs for fresh ones.