transfer.rs (2526B)
1 /* 2 This file is part of TALER 3 Copyright (C) 2026 Taler Systems SA 4 5 TALER is free software; you can redistribute it and/or modify it under the 6 terms of the GNU Affero General Public License as published by the Free Software 7 Foundation; either version 3, or (at your option) any later version. 8 9 TALER is distributed in the hope that it will be useful, but WITHOUT ANY 10 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR 11 A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 12 13 You should have received a copy of the GNU Affero General Public License along with 14 TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> 15 */ 16 17 use jiff::Timestamp; 18 use sqlx::{PgPool, postgres::PgRow}; 19 use taler_api::{ 20 db::{BindHelper as _, TypeHelper as _}, 21 serialized, 22 }; 23 use taler_common::{ 24 api::{EddsaPublicKey, EddsaSignature}, 25 db::IncomingType, 26 }; 27 28 #[derive(Debug, Clone, Copy, PartialEq, Eq)] 29 pub enum RegistrationResult { 30 Success, 31 ReservePubReuse, 32 SubjectReuse, 33 } 34 35 pub async fn transfer_register( 36 db: &PgPool, 37 ty: IncomingType, 38 account_pub: &EddsaPublicKey, 39 auth_pub: &EddsaPublicKey, 40 auth_sig: &EddsaSignature, 41 recurrent: bool, 42 reference_number: Option<&str>, 43 timestamp: &Timestamp, 44 ) -> sqlx::Result<RegistrationResult> { 45 serialized!( 46 sqlx::query( 47 " 48 SELECT 49 out_subject_reuse, 50 out_reserve_pub_reuse 51 FROM register_prepared_transfers ( 52 $1::taler_incoming_type,$2,$3,$4,$5,$6,$7 53 ) 54 ", 55 ) 56 .bind(ty.as_ref()) 57 .bind(account_pub) 58 .bind(auth_pub) 59 .bind(auth_sig) 60 .bind(recurrent) 61 .bind(reference_number) 62 .bind_timestamp(timestamp) 63 .try_map(|r: PgRow| { 64 Ok(if r.try_get_flag("out_subject_reuse")? { 65 RegistrationResult::SubjectReuse 66 } else if r.try_get_flag("out_reserve_pub_reuse")? { 67 RegistrationResult::ReservePubReuse 68 } else { 69 RegistrationResult::Success 70 }) 71 }) 72 .fetch_one(db) 73 ) 74 } 75 76 pub async fn transfer_unregister( 77 db: &PgPool, 78 auth_pub: &EddsaPublicKey, 79 timestamp: &Timestamp, 80 ) -> sqlx::Result<bool> { 81 serialized!( 82 sqlx::query_scalar("SELECT out_found FROM delete_prepared_transfers($1,$2)") 83 .bind(auth_pub) 84 .bind_timestamp(timestamp) 85 .fetch_one(db) 86 ) 87 }