From a4cc2e819c2ce74a107716e91489bfd4ff65254d Mon Sep 17 00:00:00 2001 From: Kiro Workspace Date: Tue, 20 Oct 2026 08:06:31 +0100 Subject: [PATCH 1/2] fix: surface real simulateTransaction error instead of opaque fallback Closes #903 --- backend/src/soroban.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/backend/src/soroban.rs b/backend/src/soroban.rs index 16e9477..501cf14 100644 --- a/backend/src/soroban.rs +++ b/backend/src/soroban.rs @@ -204,6 +204,18 @@ impl SorobanClient { } let result = resp.result.ok_or_else(|| anyhow!("Empty RPC result"))?; + + // `simulateTransaction` reports simulation-level failures (e.g. the + // transaction's ledger footprint has expired) inside `result.error`, + // not as a top-level JSON-RPC error, so `resp.error` above never sees + // them. Surface that message directly instead of silently falling + // through to `parse_invoice_result`, which would otherwise read a + // missing "map" field as an all-defaulted invoice. + if let Some(sim_error) = result.get("error").and_then(|e| e.as_str()) { + tracing::warn!(error = sim_error, "simulateTransaction reported a simulation error"); + return Err(anyhow!("simulation failed: {sim_error}")); + } + let invoice = parse_invoice_result(&result, invoice_id)?; tracing::debug!(status = ?invoice.status, "get_invoice RPC call succeeded"); From c586a1dc1ed2c9cf659a4852737c8399e8098c33 Mon Sep 17 00:00:00 2001 From: Kiro Workspace Date: Tue, 20 Oct 2026 08:06:34 +0100 Subject: [PATCH 2/2] fix: withdraw now transfers funds to the configured destination account Closes #904 --- COMEBACKHERE-contracts/contracts/treasury/src/lib.rs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/COMEBACKHERE-contracts/contracts/treasury/src/lib.rs b/COMEBACKHERE-contracts/contracts/treasury/src/lib.rs index 5d1e097..45fa58b 100644 --- a/COMEBACKHERE-contracts/contracts/treasury/src/lib.rs +++ b/COMEBACKHERE-contracts/contracts/treasury/src/lib.rs @@ -1126,7 +1126,7 @@ impl TreasuryContract { /// * `e` - Soroban environment handle. /// * `admin` - Admin address (must authenticate). /// * `token` - Token being withdrawn; used to look up the daily cap. - /// * `_to` - Target recipient address. + /// * `to` - Target recipient address that receives the withdrawn funds. /// * `amount` - Amount to withdraw. /// /// # Errors @@ -1139,7 +1139,7 @@ impl TreasuryContract { e: Env, admin: Address, token: Address, - _to: Address, + to: Address, amount: u64, ) -> Result<(), TreasuryError> { check_not_paused(&e)?; @@ -1181,6 +1181,12 @@ impl TreasuryContract { ); } + token::Client::new(&e, &token).transfer( + &e.current_contract_address(), + &to, + &(amount as i128), + ); + Ok(()) }