fix(ecash): sign with the mint's SAT keyset, not whichever came first
`get_active_sat_keyset` picked the first keyset with a non-empty key map,
and `MintKeyset` had no `unit` field to filter on — so on a multi-unit mint
the wallet signed sat-denominated mint/swap requests against a usd or eur
keyset. The mint refuses that with `11013 Unit unsupported`, which is
exactly what claiming minted coins hit against testnut.cashu.space (it
serves usd, eur, msat and sat keysets). Minibits is sat-only, so this
latent bug never surfaced in production — the test-mint switch found it on
its first run.
MintKeyset now carries `unit` and `active`, both defaulted so a sat-only
mint that omits them still parses, and selection filters to sat and prefers
an active keyset.
Also: pin BIP-39 seed derivation to the specification's own test vectors.
The node's entire identity hangs off `Mnemonic::to_seed("")`, and the
`bip39` crate is no longer version-pinned (the exact pin had to be relaxed
so `cashu` could resolve). A bump that changed derivation would silently
re-key every node on the fleet and orphan every backup; both vectors —
empty passphrase and the NFKD-exercising passphrase arm — now fail the
suite instead. Verified byte-identical under the newly resolved 2.2.2.
And the route script polls the mint's quote state before claiming: the test
mint settles its own invoices, but not instantly, so claiming immediately
raced the settlement and reported a spurious "Quote not paid".
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
be2cfb8293
commit
26638aa621
@@ -314,10 +314,28 @@ pub struct KeysetInfo {
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct MintKeyset {
|
||||
pub id: String,
|
||||
/// Currency unit this keyset signs for ("sat", "usd", "eur", "msat"…).
|
||||
///
|
||||
/// Defaulted rather than required: a mint that omits it is sat-only in
|
||||
/// practice, and refusing to parse would break wallets against mints that
|
||||
/// predate multi-unit support.
|
||||
#[serde(default = "default_unit")]
|
||||
pub unit: String,
|
||||
/// Whether the mint will still sign with this keyset.
|
||||
#[serde(default = "default_true")]
|
||||
pub active: bool,
|
||||
/// Map of amount (as string) to hex-encoded public key.
|
||||
pub keys: std::collections::HashMap<String, String>,
|
||||
}
|
||||
|
||||
fn default_unit() -> String {
|
||||
"sat".to_string()
|
||||
}
|
||||
|
||||
fn default_true() -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
impl MintKeyset {
|
||||
/// Get the mint's public key for a given denomination amount.
|
||||
pub fn key_for_amount(&self, amount: u64) -> Result<PublicKey> {
|
||||
|
||||
Reference in New Issue
Block a user