TalerMessage.kt (8443B)
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 /** Request POST /taler-wire-gateway/admin/add-mapped */ 128 @Serializable 129 data class AddMappedRequest( 130 val amount: TalerAmount, 131 val authorization_pub: EddsaPublicKey, 132 val debit_account: Payto 133 ) 134 135 /** Response GET /taler-wire-gateway/history/incoming */ 136 @Serializable 137 data class IncomingHistory( 138 val incoming_transactions: List<IncomingBankTransaction>, 139 val credit_account: String 140 ) 141 142 /** Inner response GET /taler-wire-gateway/history/incoming */ 143 @Serializable 144 sealed interface IncomingBankTransaction { 145 val row_id: Long 146 val date: TalerTimestamp 147 val amount: TalerAmount 148 val debit_account: String 149 val credit_fee: TalerAmount? 150 } 151 152 @Serializable 153 @SerialName("KYCAUTH") 154 data class IncomingKycAuthTransaction( 155 override val row_id: Long, 156 override val date: TalerTimestamp, 157 override val amount: TalerAmount, 158 override val credit_fee: TalerAmount? = null, 159 override val debit_account: String, 160 val account_pub: EddsaPublicKey, 161 val authorization_pub: EddsaPublicKey? = null, 162 val authorization_sig: EddsaSignature? = null, 163 ) : IncomingBankTransaction 164 165 @Serializable 166 @SerialName("RESERVE") 167 data class IncomingReserveTransaction( 168 override val row_id: Long, 169 override val date: TalerTimestamp, 170 override val amount: TalerAmount, 171 override val credit_fee: TalerAmount? = null, 172 override val debit_account: String, 173 val reserve_pub: EddsaPublicKey, 174 val authorization_pub: EddsaPublicKey? = null, 175 val authorization_sig: EddsaSignature? = null, 176 ) : IncomingBankTransaction 177 178 @Serializable 179 @SerialName("WAD") 180 data class IncomingWadTransaction( 181 override val row_id: Long, 182 override val date: TalerTimestamp, 183 override val amount: TalerAmount, 184 override val credit_fee: TalerAmount? = null, 185 override val debit_account: String, 186 val origin_exchange_url: String, 187 val wad_id: String // TODO 24 bytes Base32 188 ) : IncomingBankTransaction 189 190 /** Response GET /taler-wire-gateway/history/outgoing */ 191 @Serializable 192 data class OutgoingHistory( 193 val outgoing_transactions: List<OutgoingTransaction>, 194 val debit_account: String 195 ) 196 197 /** Inner response GET /taler-wire-gateway/history/outgoing */ 198 @Serializable 199 data class OutgoingTransaction( 200 val row_id: Long, // DB row ID of the payment. 201 val date: TalerTimestamp, 202 val amount: TalerAmount, 203 val credit_account: String, 204 val wtid: ShortHashCode, 205 val exchange_base_url: String, 206 val metadata: String? = null, 207 val debit_fee: TalerAmount? = null 208 ) 209 210 /** Response GET /taler-wire-gateway/account/check */ 211 @Serializable 212 class AccountInfo() 213 214 /** Response GET /taler-prepared-transfer/config */ 215 @Serializable 216 data class PreparedTransferConfig( 217 val currency: String, 218 val supported_formats: List<SubjectFormat> 219 ) { 220 val name: String = "taler-prepared-transfer" 221 val version: String = WIRE_TRANSFER_API_VERSION 222 } 223 224 225 /** Inner response GET /taler-prepared-transfer/registration */ 226 @Serializable 227 sealed interface TransferSubject { 228 @Serializable 229 @SerialName("SIMPLE") 230 data class Simple( 231 val subject: String, 232 val credit_amount: TalerAmount 233 ) : TransferSubject 234 235 @Serializable 236 @SerialName("URI") 237 data class Uri( 238 val uri: String, 239 val credit_amount: TalerAmount 240 ) : TransferSubject 241 242 @Serializable 243 @SerialName("CH_QR_BILL") 244 data class QrBill( 245 val qr_reference_number: String, 246 val credit_amount: TalerAmount, 247 ) : TransferSubject 248 } 249 250 @Serializable 251 enum class SubjectFormat { 252 SIMPLE, 253 URI, 254 CH_QR_BILL 255 } 256 257 @Serializable 258 enum class PublicKeyAlg { 259 EdDSA 260 } 261 262 @Serializable 263 enum class TransferType { 264 reserve, 265 kyc 266 } 267 268 @Serializable 269 data class SubjectRequest( 270 val credit_amount: TalerAmount, 271 val type: TransferType, 272 val alg: PublicKeyAlg, 273 val account_pub: EddsaPublicKey, 274 val authorization_pub: EddsaPublicKey, 275 val authorization_sig: EddsaSignature, 276 val recurrent: Boolean 277 ) 278 279 @Serializable 280 data class SubjectResult( 281 val subjects: List<TransferSubject>, 282 val expiration: TalerTimestamp 283 ) 284 285 @Serializable 286 data class Unregistration( 287 val timestamp: String, 288 val authorization_pub: EddsaPublicKey, 289 val authorization_sig: EddsaSignature 290 ) 291 292 /** Response GET /taler-revenue/config */ 293 @Serializable 294 data class RevenueConfig( 295 val currency: String 296 ) { 297 val name: String = "taler-revenue" 298 val version: String = REVENUE_API_VERSION 299 } 300 301 /** Request GET /taler-revenue/history */ 302 @Serializable 303 data class RevenueIncomingHistory( 304 val incoming_transactions: List<RevenueIncomingBankTransaction>, 305 val credit_account: String 306 ) 307 308 /** Inner request GET /taler-revenue/history */ 309 @Serializable 310 data class RevenueIncomingBankTransaction( 311 val row_id: Long, 312 val date: TalerTimestamp, 313 val amount: TalerAmount, 314 val credit_fee: TalerAmount? = null, 315 val debit_account: String, 316 val subject: String 317 ) 318 319 /** Response GET /taler-observability/config */ 320 @Serializable 321 class TalerObservabilityConfig() { 322 val name: String = "taler-observability" 323 val version: String = OBSERVABILITY_API_VERSION 324 }