libeufin

Integration and sandbox testing for FinTech APIs and data formats
Log | Files | Refs | Submodules | README | LICENSE

prepared.rs (3082B)


      1 /*
      2 * This file is part of LibEuFin.
      3 * Copyright (C) 2026 Taler Systems S.A.
      4 
      5 * LibEuFin is free software; you can redistribute it and/or modify
      6 * it under the terms of the GNU Affero General Public License as
      7 * published by the Free Software Foundation; either version 3, or
      8 * (at your option) any later version.
      9 
     10 * LibEuFin is distributed in the hope that it will be useful, but
     11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
     12 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Affero General
     13 * Public License for more details.
     14 
     15 * You should have received a copy of the GNU Affero General Public
     16 * License along with LibEuFin; see the file COPYING.  If not, see
     17 * <http://www.gnu.org/licenses/>
     18 */
     19 
     20 //! Data access logic for prepared transfer specific logic
     21 
     22 use jiff::Timestamp;
     23 use sqlx::{PgPool, Row, postgres::PgRow};
     24 use taler_api::{
     25     db::{BindHelper, TypeHelper},
     26     serialized,
     27 };
     28 use taler_common::{
     29     api::{EddsaPublicKey, EddsaSignature, prepared::TransferType},
     30     db::IncomingType,
     31     types::amount::Amount,
     32 };
     33 use uuid::Uuid;
     34 
     35 use crate::payto::BankPayto;
     36 
     37 /** Result of prepared transfer registration */
     38 pub enum RegistrationResult {
     39     Success(Option<Uuid>),
     40     UnknownCreditor,
     41     NotExchange,
     42     ReservePubReuse,
     43 }
     44 
     45 /** Register a prepared transfer */
     46 pub async fn register(
     47     db: &PgPool,
     48     creditor: &BankPayto,
     49     ty: TransferType,
     50     account_pub: &EddsaPublicKey,
     51     auth_pub: &EddsaPublicKey,
     52     auth_sig: &EddsaSignature,
     53     recurrent: bool,
     54     amount: &Amount,
     55     timestamp: &Timestamp,
     56 ) -> sqlx::Result<RegistrationResult> {
     57     let ty: IncomingType = ty.into();
     58     serialized!(
     59         sqlx::query(
     60             "
     61             SELECT out_unknown_creditor, out_not_exchange, out_reserve_pub_reuse, out_withdrawal_uuid
     62             FROM register_prepared_transfers($1,$2::taler_incoming_type,$3,$4,$5,$6,$7,$8,$9)
     63             "
     64         )
     65         .bind(creditor.canonical())
     66         .bind(ty.as_ref())
     67         .bind(account_pub)
     68         .bind(auth_pub)
     69         .bind(auth_sig)
     70         .bind(recurrent)
     71         .bind(amount)
     72         .bind_timestamp(timestamp)
     73         .bind(format!("Taler prepared MAP:{auth_pub}"))
     74         .try_map(|r: PgRow| {
     75             Ok(if r.try_get_flag("out_unknown_creditor")? {
     76                 RegistrationResult::UnknownCreditor
     77             } else if r.try_get_flag("out_not_exchange")? {
     78                 RegistrationResult::NotExchange
     79             } else if r.try_get_flag("out_reserve_pub_reuse")? {
     80                 RegistrationResult::ReservePubReuse
     81             } else {
     82                 RegistrationResult::Success(r.try_get("out_withdrawal_uuid")?)
     83             })
     84         })
     85         .fetch_one(db)
     86     )
     87 }
     88 
     89 /** Register a prepared transfer */
     90 pub async fn unregister(
     91     db: &PgPool,
     92     auth_pub: &EddsaPublicKey,
     93     timestamp: &Timestamp,
     94 ) -> sqlx::Result<bool> {
     95     serialized!(
     96         sqlx::query_scalar("SELECT out_found FROM delete_prepared_transfers($1,$2)")
     97             .bind(auth_pub)
     98             .bind_timestamp(timestamp)
     99             .fetch_one(db)
    100     )
    101 }