libeufin

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

TalerMessage.kt (8247B)


      1 /*
      2  * This file is part of LibEuFin.
      3  * Copyright (C) 2024, 2025, 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 package tech.libeufin.common
     21 
     22 import kotlinx.serialization.SerialName
     23 import kotlinx.serialization.Serializable
     24 
     25 enum class IncomingType {
     26     reserve,
     27     kyc,
     28     map
     29 }
     30 
     31 enum class TransferStatusState {
     32     pending,
     33     transient_failure,
     34     permanent_failure,
     35     success
     36 }
     37 
     38 /** Response GET /taler-wire-gateway/config */
     39 @Serializable
     40 data class WireGatewayConfig(
     41     val currency: String,
     42     val support_account_check: Boolean
     43 ) {
     44     val name: String = "taler-wire-gateway"
     45     val version: String = WIRE_GATEWAY_API_VERSION
     46 }
     47 
     48 /** Request POST /taler-wire-gateway/transfer */
     49 @Serializable
     50 data class TransferRequest(
     51     val request_uid: HashCode,
     52     val amount: TalerAmount,
     53     val exchange_base_url: BaseURL,
     54     val wtid: ShortHashCode,
     55     val credit_account: Payto,
     56     val metadata: String? = null,
     57 ) {
     58     init {
     59         if (metadata != null && !METADATA_REGEX.matches(metadata))
     60             throw badRequest("metadata '$metadata' is malformed, must match [a-zA-Z0-9-.+:]{1,40}")
     61     }
     62     
     63     companion object {
     64         private val METADATA_REGEX = Regex("^[a-zA-Z0-9-.:]{1,40}$")
     65     }
     66 }
     67 
     68 /** Response POST /taler-wire-gateway/transfer */
     69 @Serializable
     70 data class TransferResponse(
     71     val timestamp: TalerTimestamp,
     72     val row_id: Long
     73 )
     74 
     75 /** Request GET /taler-wire-gateway/transfers */
     76 @Serializable
     77 data class TransferList(
     78     val transfers: List<TransferListStatus>,
     79     val debit_account: String
     80 )
     81 
     82 @Serializable
     83 data class TransferListStatus(
     84     val row_id: Long,
     85     val status: TransferStatusState,
     86     val amount: TalerAmount,
     87     val credit_account: String,
     88     val timestamp: TalerTimestamp
     89 )
     90 
     91 /** Request GET /taler-wire-gateway/transfers/{ROW_iD} */
     92 @Serializable
     93 data class TransferStatus(
     94     val status: TransferStatusState,
     95     val status_msg: String? = null,
     96     val amount: TalerAmount,
     97     val origin_exchange_url: String,
     98     val metadata: String? = null,
     99     val wtid: ShortHashCode,
    100     val credit_account: String,
    101     val timestamp: TalerTimestamp
    102 )
    103 
    104 /** Request POST /taler-wire-gateway/admin/add-incoming */
    105 @Serializable
    106 data class AddIncomingRequest(
    107     val amount: TalerAmount,
    108     val reserve_pub: EddsaPublicKey,
    109     val debit_account: Payto
    110 )
    111 
    112 /** Response POST /taler-wire-gateway/admin/add-incoming */
    113 @Serializable
    114 data class AddIncomingResponse(
    115     val timestamp: TalerTimestamp,
    116     val row_id: Long
    117 )
    118 
    119 /** Request POST /taler-wire-gateway/admin/add-kycauth */
    120 @Serializable
    121 data class AddKycauthRequest(
    122     val amount: TalerAmount,
    123     val account_pub: EddsaPublicKey,
    124     val debit_account: Payto
    125 )
    126 
    127 /** Response GET /taler-wire-gateway/history/incoming */
    128 @Serializable
    129 data class IncomingHistory(
    130     val incoming_transactions: List<IncomingBankTransaction>,
    131     val credit_account: String
    132 )
    133 
    134 /** Inner response GET /taler-wire-gateway/history/incoming */
    135 @Serializable
    136 sealed interface IncomingBankTransaction {
    137     val row_id: Long
    138     val date: TalerTimestamp
    139     val amount: TalerAmount
    140     val debit_account: String
    141     val credit_fee: TalerAmount?
    142 }
    143 
    144 @Serializable
    145 @SerialName("KYCAUTH")
    146 data class IncomingKycAuthTransaction(
    147     override val row_id: Long,
    148     override val date: TalerTimestamp,
    149     override val amount: TalerAmount,
    150     override val credit_fee: TalerAmount? = null,
    151     override val debit_account: String,
    152     val account_pub: EddsaPublicKey,
    153     val authorization_pub: EddsaPublicKey? = null,
    154     val authorization_sig: EddsaSignature? = null,
    155 ) : IncomingBankTransaction
    156 
    157 @Serializable
    158 @SerialName("RESERVE")
    159 data class IncomingReserveTransaction(
    160     override val row_id: Long,
    161     override val date: TalerTimestamp,
    162     override val amount: TalerAmount,
    163     override val credit_fee: TalerAmount? = null,
    164     override val debit_account: String,
    165     val reserve_pub: EddsaPublicKey,
    166     val authorization_pub: EddsaPublicKey? = null,
    167     val authorization_sig: EddsaSignature? = null,
    168 ) : IncomingBankTransaction
    169 
    170 @Serializable
    171 @SerialName("WAD")
    172 data class IncomingWadTransaction(
    173     override val row_id: Long,
    174     override val date: TalerTimestamp,
    175     override val amount: TalerAmount,
    176     override val credit_fee: TalerAmount? = null,
    177     override val debit_account: String,
    178     val origin_exchange_url: String,
    179     val wad_id: String // TODO 24 bytes Base32
    180 ) : IncomingBankTransaction
    181 
    182 /** Response GET /taler-wire-gateway/history/outgoing */
    183 @Serializable
    184 data class OutgoingHistory(
    185     val outgoing_transactions: List<OutgoingTransaction>,
    186     val debit_account: String
    187 )
    188 
    189 /** Inner response GET /taler-wire-gateway/history/outgoing */
    190 @Serializable
    191 data class OutgoingTransaction(
    192     val row_id: Long, // DB row ID of the payment.
    193     val date: TalerTimestamp,
    194     val amount: TalerAmount,
    195     val credit_account: String,
    196     val wtid: ShortHashCode,
    197     val exchange_base_url: String,
    198     val metadata: String? = null,
    199     val debit_fee: TalerAmount? = null
    200 )
    201 
    202 /** Response GET /taler-wire-gateway/account/check */
    203 @Serializable
    204 class AccountInfo()
    205 
    206 /** Response GET /taler-wire-transfer-gateway/config */
    207 @Serializable
    208 data class WireTransferConfig(
    209     val currency: String,
    210     val supported_formats: List<SubjectFormat>
    211 ) {
    212     val name: String = "taler-wire-transfer-gateway"
    213     val version: String = WIRE_TRANSFER_API_VERSION
    214 }
    215 
    216 
    217 /** Inner response GET /taler-wire-transfer-gateway/registration */
    218 @Serializable
    219 sealed interface TransferSubject {
    220     @Serializable
    221     @SerialName("SIMPLE")
    222     data class Simple(
    223         val subject: String,
    224         val credit_amount: TalerAmount
    225     ) : TransferSubject
    226 
    227     @Serializable
    228     @SerialName("URI")
    229     data class Uri(
    230         val uri: String,
    231         val credit_amount: TalerAmount
    232     ) : TransferSubject
    233 
    234     @Serializable
    235     @SerialName("CH_QR_BILL")
    236     data class QrBill(
    237         val qr_reference_number: String,
    238         val credit_amount: TalerAmount,
    239     ) : TransferSubject
    240 }
    241 
    242 @Serializable
    243 enum class SubjectFormat {
    244     SIMPLE,
    245     URI,
    246     CH_QR_BILL
    247 }
    248 
    249 @Serializable
    250 enum class PublicKeyAlg {
    251     ECDSA
    252 }
    253 
    254 @Serializable
    255 enum class TransferType {
    256     reserve,
    257     kyc
    258 }
    259 
    260 @Serializable
    261 data class SubjectRequest(
    262     val credit_amount: TalerAmount,
    263     val type: TransferType,
    264     val alg: PublicKeyAlg,
    265     val account_pub: EddsaPublicKey,
    266     val authorization_pub: EddsaPublicKey,
    267     val authorization_sig: EddsaSignature,
    268     val recurrent: Boolean
    269 )
    270 
    271 @Serializable
    272 data class SubjectResult(
    273     val subjects: List<TransferSubject>,
    274     val expiration: TalerTimestamp
    275 )
    276 
    277 @Serializable
    278 data class Unregistration(
    279     val timestamp: String,
    280     val authorization_pub: EddsaPublicKey,
    281     val authorization_sig: EddsaSignature
    282 )
    283 
    284 /** Response GET /taler-revenue/config */
    285 @Serializable
    286 data class RevenueConfig(
    287     val currency: String
    288 ) {
    289     val name: String = "taler-revenue"
    290     val version: String = REVENUE_API_VERSION
    291 }
    292 
    293 /** Request GET /taler-revenue/history */
    294 @Serializable
    295 data class RevenueIncomingHistory(
    296     val incoming_transactions: List<RevenueIncomingBankTransaction>,
    297     val credit_account: String
    298 )
    299 
    300 /** Inner request GET /taler-revenue/history */
    301 @Serializable
    302 data class RevenueIncomingBankTransaction(
    303     val row_id: Long,
    304     val date: TalerTimestamp,
    305     val amount: TalerAmount,
    306     val credit_fee: TalerAmount? = null,
    307     val debit_account: String,
    308     val subject: String
    309 )
    310 
    311 /** Response GET /taler-observability/config */
    312 @Serializable
    313 class TalerObservabilityConfig() {
    314     val name: String = "taler-observability"
    315     val version: String = OBSERVABILITY_API_VERSION
    316 }