summaryrefslogtreecommitdiff
path: root/bank/src/main
diff options
context:
space:
mode:
Diffstat (limited to 'bank/src/main')
-rw-r--r--bank/src/main/kotlin/tech/libeufin/bank/Constants.kt2
-rw-r--r--bank/src/main/kotlin/tech/libeufin/bank/TalerMessage.kt3
-rw-r--r--bank/src/main/kotlin/tech/libeufin/bank/api/CoreBankApi.kt5
-rw-r--r--bank/src/main/kotlin/tech/libeufin/bank/db/AccountDAO.kt2
-rw-r--r--bank/src/main/kotlin/tech/libeufin/bank/db/TransactionDAO.kt11
5 files changed, 18 insertions, 5 deletions
diff --git a/bank/src/main/kotlin/tech/libeufin/bank/Constants.kt b/bank/src/main/kotlin/tech/libeufin/bank/Constants.kt
index 48fc3992..7a192308 100644
--- a/bank/src/main/kotlin/tech/libeufin/bank/Constants.kt
+++ b/bank/src/main/kotlin/tech/libeufin/bank/Constants.kt
@@ -40,7 +40,7 @@ const val IBAN_ALLOCATION_RETRY_COUNTER: Int = 5
const val MAX_BODY_LENGTH: Long = 4 * 1024 // 4kB
// API version
-const val COREBANK_API_VERSION: String = "4:3:0"
+const val COREBANK_API_VERSION: String = "4:4:0"
const val CONVERSION_API_VERSION: String = "0:0:0"
const val INTEGRATION_API_VERSION: String = "2:0:2"
const val WIRE_GATEWAY_API_VERSION: String = "0:2:0"
diff --git a/bank/src/main/kotlin/tech/libeufin/bank/TalerMessage.kt b/bank/src/main/kotlin/tech/libeufin/bank/TalerMessage.kt
index 0284266b..ce459baa 100644
--- a/bank/src/main/kotlin/tech/libeufin/bank/TalerMessage.kt
+++ b/bank/src/main/kotlin/tech/libeufin/bank/TalerMessage.kt
@@ -380,7 +380,8 @@ data class AccountData(
@Serializable
data class TransactionCreateRequest(
val payto_uri: Payto,
- val amount: TalerAmount?
+ val amount: TalerAmount?,
+ val request_uid: ShortHashCode?
)
@Serializable
diff --git a/bank/src/main/kotlin/tech/libeufin/bank/api/CoreBankApi.kt b/bank/src/main/kotlin/tech/libeufin/bank/api/CoreBankApi.kt
index dd6aab4b..a3bb8265 100644
--- a/bank/src/main/kotlin/tech/libeufin/bank/api/CoreBankApi.kt
+++ b/bank/src/main/kotlin/tech/libeufin/bank/api/CoreBankApi.kt
@@ -459,6 +459,7 @@ private fun Routing.coreBankTransactionsApi(db: Database, ctx: BankConfig) {
subject = subject,
amount = amount,
timestamp = Instant.now(),
+ requestUid = req.request_uid,
is2fa = challenge != null
)
when (res) {
@@ -479,6 +480,10 @@ private fun Routing.coreBankTransactionsApi(db: Database, ctx: BankConfig) {
"Insufficient funds",
TalerErrorCode.BANK_UNALLOWED_DEBIT
)
+ BankTransactionResult.RequestUidReuse -> throw conflict(
+ "request_uid used already",
+ TalerErrorCode.BANK_TRANSFER_REQUEST_UID_REUSED
+ )
is BankTransactionResult.Success -> call.respond(TransactionCreateResponse(res.id))
}
}
diff --git a/bank/src/main/kotlin/tech/libeufin/bank/db/AccountDAO.kt b/bank/src/main/kotlin/tech/libeufin/bank/db/AccountDAO.kt
index 13bc1e09..f78947e7 100644
--- a/bank/src/main/kotlin/tech/libeufin/bank/db/AccountDAO.kt
+++ b/bank/src/main/kotlin/tech/libeufin/bank/db/AccountDAO.kt
@@ -157,7 +157,7 @@ class AccountDAO(private val db: Database) {
if (bonus.value != 0L || bonus.frac != 0) {
conn.prepareStatement("""
SELECT out_balance_insufficient
- FROM bank_transaction(?,'admin','bonus',(?,?)::taler_amount,?,true)
+ FROM bank_transaction(?,'admin','bonus',(?,?)::taler_amount,?,true,NULL)
""").run {
setString(1, internalPayto.canonical)
setLong(2, bonus.value)
diff --git a/bank/src/main/kotlin/tech/libeufin/bank/db/TransactionDAO.kt b/bank/src/main/kotlin/tech/libeufin/bank/db/TransactionDAO.kt
index 9b03cd2d..81fd558f 100644
--- a/bank/src/main/kotlin/tech/libeufin/bank/db/TransactionDAO.kt
+++ b/bank/src/main/kotlin/tech/libeufin/bank/db/TransactionDAO.kt
@@ -38,6 +38,7 @@ class TransactionDAO(private val db: Database) {
data object BothPartySame: BankTransactionResult
data object BalanceInsufficient: BankTransactionResult
data object TanRequired: BankTransactionResult
+ data object RequestUidReuse: BankTransactionResult
}
/** Create a new transaction */
@@ -47,7 +48,8 @@ class TransactionDAO(private val db: Database) {
subject: String,
amount: TalerAmount,
timestamp: Instant,
- is2fa: Boolean
+ is2fa: Boolean,
+ requestUid: ShortHashCode?,
): BankTransactionResult = db.serializable { conn ->
val now = timestamp.toDbMicros() ?: throw faultyTimestampByBank()
conn.transaction {
@@ -57,6 +59,7 @@ class TransactionDAO(private val db: Database) {
,out_debtor_not_found
,out_same_account
,out_balance_insufficient
+ ,out_request_uid_reuse
,out_tan_required
,out_credit_bank_account_id
,out_debit_bank_account_id
@@ -65,7 +68,8 @@ class TransactionDAO(private val db: Database) {
,out_creditor_is_exchange
,out_debtor_is_exchange
,out_creditor_admin
- FROM bank_transaction(?,?,?,(?,?)::taler_amount,?,?)
+ ,out_idempotent
+ FROM bank_transaction(?,?,?,(?,?)::taler_amount,?,?,?)
"""
)
stmt.setString(1, creditAccountPayto.canonical)
@@ -75,6 +79,7 @@ class TransactionDAO(private val db: Database) {
stmt.setInt(5, amount.frac)
stmt.setLong(6, now)
stmt.setBoolean(7, is2fa)
+ stmt.setBytes(8, requestUid?.raw)
stmt.executeQuery().use {
when {
!it.next() -> throw internalServerError("Bank transaction didn't properly return")
@@ -83,6 +88,8 @@ class TransactionDAO(private val db: Database) {
it.getBoolean("out_same_account") -> BankTransactionResult.BothPartySame
it.getBoolean("out_balance_insufficient") -> BankTransactionResult.BalanceInsufficient
it.getBoolean("out_creditor_admin") -> BankTransactionResult.AdminCreditor
+ it.getBoolean("out_request_uid_reuse") -> BankTransactionResult.RequestUidReuse
+ it.getBoolean("out_idempotent") -> BankTransactionResult.Success(it.getLong("out_debit_row_id"))
it.getBoolean("out_tan_required") -> BankTransactionResult.TanRequired
else -> {
val creditAccountId = it.getLong("out_credit_bank_account_id")