commit d459c57867415b9f095ac4726aeef1096ad4c1e6
parent b3bb50692eaf339ba3989b83bb0fbf0f69f7e95a
Author: Antoine A <>
Date: Wed, 16 Sep 2026 16:07:39 +0200
bank: fix prepared transfer initiated withdrawals not being accessible to the wallet app
Diffstat:
5 files changed, 37 insertions(+), 19 deletions(-)
diff --git a/Cargo.lock b/Cargo.lock
@@ -107,7 +107,7 @@ dependencies = [
"proc-macro2",
"quote",
"syn 2.0.119",
- "synstructure",
+ "synstructure 0.13.2",
]
[[package]]
@@ -3501,6 +3501,17 @@ dependencies = [
]
[[package]]
+name = "synstructure"
+version = "0.14.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "901704edd0dfe137f1987838ee4f259e4e063c31371bdb423f7ae38ec6f77f02"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 3.0.5",
+]
+
+[[package]]
name = "system-configuration"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -4597,14 +4608,14 @@ dependencies = [
[[package]]
name = "yoke-derive"
-version = "0.8.2"
+version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "de844c262c8848816172cef550288e7dc6c7b7814b4ee56b3e1553f275f1858e"
+checksum = "33811428bee40dbceb6d545e95754741d17a6aef9a4849f0fd62e2ba4f412a78"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.119",
- "synstructure",
+ "syn 3.0.5",
+ "synstructure 0.14.0",
]
[[package]]
@@ -4638,14 +4649,14 @@ dependencies = [
[[package]]
name = "zerofrom-derive"
-version = "0.1.7"
+version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "11532158c46691caf0f2593ea8358fed6bbf68a0315e80aae9bd41fbade684a1"
+checksum = "f75b4683f6c7f45248d4d64056a24298c6281e0993356d7d1b4a1a962ef10d4a"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.119",
- "synstructure",
+ "syn 3.0.5",
+ "synstructure 0.14.0",
]
[[package]]
diff --git a/database-versioning/libeufin-bank-procedures.sql b/database-versioning/libeufin-bank-procedures.sql
@@ -221,7 +221,8 @@ WITH computed AS (
INTO out_max_amount.val, out_max_amount.frac
FROM computed;
-IF in_max_amount.val < out_max_amount.val
+IF in_account_id IS NULL
+ OR in_max_amount.val < out_max_amount.val
OR (in_max_amount.val = out_max_amount.val AND in_max_amount.frac < out_max_amount.frac) THEN
out_max_amount = in_max_amount;
END IF;
diff --git a/libeufin-bank/src/api.rs b/libeufin-bank/src/api.rs
@@ -328,7 +328,7 @@ pub mod test {
use jiff::Timestamp;
use rand::{random_range, seq::IndexedRandom};
use sqlx::PgPool;
- use taler_api::db::BindHelper;
+ use taler_api::{api::TalerRouter, db::BindHelper};
use taler_common::{
api::{EddsaPublicKey, HashCode, ShortHashCode},
config::Config,
@@ -668,7 +668,7 @@ pub mod test {
drop(conn);
let state = Arc::new(BankState::start(db.clone(), cfg).await);
- let server = bank_api(state.clone());
+ let server = bank_api(state.clone()).finalize();
let merchant_payto = db::account::create(
&db,
diff --git a/libeufin-bank/src/api/prepared.rs b/libeufin-bank/src/api/prepared.rs
@@ -247,6 +247,11 @@ mod test {
TransferSubject::Uri { uri, .. } => uri.as_str().rsplit('/').next().unwrap(),
_ => unreachable!(),
};
+
+ ctx.get(format!("/withdrawals/{uuid}")).await.assert_ok();
+ ctx.get(format!("/taler-integration/withdrawal-operation/{uuid}"))
+ .await
+ .assert_ok();
ctx.posta(format!("/accounts/customer/withdrawals/{uuid}/confirm"))
.json(json!({}))
.await
diff --git a/libeufin-bank/src/db/withdrawal.rs b/libeufin-bank/src/db/withdrawal.rs
@@ -341,8 +341,8 @@ pub async fn poll_info(
,exchange_account.internal_payto as exchange_payto
,exchange_user.name as exchange_name
FROM taler_withdrawal_operations
- JOIN bank_accounts AS wallet_account ON wallet_bank_account=wallet_account.bank_account_id
- JOIN customers AS wallet_user ON wallet_user.customer_id=wallet_account.owning_customer_id
+ LEFT JOIN bank_accounts AS wallet_account ON wallet_bank_account=wallet_account.bank_account_id
+ LEFT JOIN customers AS wallet_user ON wallet_user.customer_id=wallet_account.owning_customer_id
LEFT JOIN bank_accounts AS exchange_account ON exchange_bank_account=exchange_account.bank_account_id
LEFT JOIN customers AS exchange_user ON exchange_user.customer_id=exchange_account.owning_customer_id
WHERE withdrawal_uuid=$1
@@ -353,7 +353,7 @@ pub async fn poll_info(
amount: r.try_get_opt_amount("amount", currency)?,
suggested_amount: r.try_get_opt_amount("suggested_amount", currency)?,
no_amount_to_wallet: r.try_get("no_amount_to_wallet")?,
- username: r.try_get("username")?,
+ username: r.try_get::<Option<CompactString>, _>("username")?.unwrap_or(CompactString::const_new("Uknonwn")),
selected_reserve_pub: r.try_get("reserve_pub")?,
selected_exchange_account: sql_opt_bank_payto(&r, ctx, "exchange_payto", "exchange_name")?
}))
@@ -403,8 +403,8 @@ pub async fn poll_status(
,max_amount
,no_amount_to_wallet
FROM taler_withdrawal_operations
- JOIN bank_accounts AS wallet_account ON wallet_bank_account=wallet_account.bank_account_id
- JOIN customers AS wallet_user ON wallet_user.customer_id=wallet_account.owning_customer_id
+ LEFT JOIN bank_accounts AS wallet_account ON wallet_bank_account=wallet_account.bank_account_id
+ LEFT JOIN customers AS wallet_user ON wallet_user.customer_id=wallet_account.owning_customer_id
LEFT JOIN bank_accounts AS exchange_account ON exchange_bank_account=exchange_account.bank_account_id
LEFT JOIN customers AS exchange_user ON exchange_user.customer_id=exchange_account.owning_customer_id
,account_max_amount(wallet_account.bank_account_id, $1) AS max_amount
@@ -413,7 +413,8 @@ pub async fn poll_status(
)
.bind(max)
.bind(uuid)
- .try_map(|r: PgRow| Ok(BankWithdrawalOperationStatus {
+ .try_map(|r: PgRow| {
+ Ok(BankWithdrawalOperationStatus {
status: r.try_get("status")?,
amount: r.try_get_opt_amount("amount", currency)?,
suggested_amount: r.try_get_opt_amount("suggested_amount", currency)?,
@@ -432,7 +433,7 @@ pub async fn poll_status(
sender_wire: sql_opt_bank_payto(&r, ctx, "internal_payto", "name")?,
suggested_exchange: None,
wire_types: vec![wire.to_compact_string()]
- }))
+ })})
.fetch_optional(db))
,
|init| init.as_ref().map(|it| it.status != params.status).unwrap_or(true),