TalerMessage.kt (15015B)
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 io.github.smiley4.schemakenerator.core.annotations.Description 23 import kotlinx.serialization.SerialName 24 import kotlinx.serialization.Serializable 25 26 enum class IncomingType { 27 reserve, 28 kyc, 29 map 30 } 31 32 @Description("State of a wire transfer") 33 enum class TransferStatusState { 34 pending, 35 transient_failure, 36 permanent_failure, 37 success 38 } 39 40 /** Response GET /taler-wire-gateway/config */ 41 @Serializable 42 @Description("Wire gateway configuration response") 43 data class WireGatewayConfig( 44 @Description("Currency supported by the gateway") 45 val currency: String, 46 @Description("Whether account check is supported") 47 val support_account_check: Boolean 48 ) { 49 @Description("API name identifier") 50 val name: String = "taler-wire-gateway" 51 @Description("API version string") 52 val version: String = WIRE_GATEWAY_API_VERSION 53 } 54 55 /** Request POST /taler-wire-gateway/transfer */ 56 @Serializable 57 @Description("Wire transfer request") 58 data class TransferRequest( 59 @Description("Unique identifier for this request") 60 val request_uid: HashCode, 61 @Description("Amount to transfer") 62 val amount: TalerAmount, 63 @Description("Base URL of the exchange") 64 val exchange_base_url: BaseURL, 65 @Description("Wire transfer identifier") 66 val wtid: ShortHashCode, 67 @Description("Payto URI of the credit account") 68 val credit_account: Payto, 69 @Description("Optional transfer metadata") 70 val metadata: String? = null, 71 ) { 72 init { 73 if (metadata != null && !METADATA_REGEX.matches(metadata)) 74 throw badRequest("metadata '$metadata' is malformed, must match [a-zA-Z0-9-.+:]{1,40}") 75 } 76 77 companion object { 78 private val METADATA_REGEX = Regex("^[a-zA-Z0-9-.:]{1,40}$") 79 } 80 } 81 82 /** Response POST /taler-wire-gateway/transfer */ 83 @Serializable 84 @Description("Wire transfer response") 85 data class TransferResponse( 86 @Description("Timestamp of the transfer") 87 val timestamp: TalerTimestamp, 88 @Description("Database row identifier") 89 val row_id: Long 90 ) 91 92 /** Request GET /taler-wire-gateway/transfers */ 93 @Serializable 94 @Description("List of wire transfers") 95 data class TransferList( 96 @Description("List of transfer statuses") 97 val transfers: List<TransferListStatus>, 98 @Description("Payto URI of the debit account") 99 val debit_account: String 100 ) 101 102 @Serializable 103 @Description("Transfer status in a list response") 104 data class TransferListStatus( 105 @Description("Database row identifier") 106 val row_id: Long, 107 @Description("Current transfer status") 108 val status: TransferStatusState, 109 @Description("Transfer amount") 110 val amount: TalerAmount, 111 @Description("Payto URI of the credit account") 112 val credit_account: String, 113 @Description("Timestamp of the transfer") 114 val timestamp: TalerTimestamp 115 ) 116 117 /** Request GET /taler-wire-gateway/transfers/{ROW_iD} */ 118 @Serializable 119 @Description("Detailed status of a single transfer") 120 data class TransferStatus( 121 @Description("Current transfer status") 122 val status: TransferStatusState, 123 @Description("Optional status message") 124 val status_msg: String? = null, 125 @Description("Transfer amount") 126 val amount: TalerAmount, 127 @Description("URL of the originating exchange") 128 val origin_exchange_url: String, 129 @Description("Optional transfer metadata") 130 val metadata: String? = null, 131 @Description("Wire transfer identifier") 132 val wtid: ShortHashCode, 133 @Description("Payto URI of the credit account") 134 val credit_account: String, 135 @Description("Timestamp of the transfer") 136 val timestamp: TalerTimestamp 137 ) 138 139 /** Request POST /taler-wire-gateway/admin/add-incoming */ 140 @Serializable 141 @Description("Request to add an incoming transaction") 142 data class AddIncomingRequest( 143 @Description("Amount of the incoming transaction") 144 val amount: TalerAmount, 145 @Description("Reserve public key") 146 val reserve_pub: EddsaPublicKey, 147 @Description("Payto URI of the debit account") 148 val debit_account: Payto 149 ) 150 151 /** Response POST /taler-wire-gateway/admin/add-incoming */ 152 @Serializable 153 @Description("Response to adding an incoming transaction") 154 data class AddIncomingResponse( 155 @Description("Timestamp of the transaction") 156 val timestamp: TalerTimestamp, 157 @Description("Database row identifier") 158 val row_id: Long 159 ) 160 161 /** Request POST /taler-wire-gateway/admin/add-kycauth */ 162 @Serializable 163 @Description("Request to add a KYC auth transaction") 164 data class AddKycauthRequest( 165 @Description("Amount of the KYC auth transaction") 166 val amount: TalerAmount, 167 @Description("Account public key for KYC") 168 val account_pub: EddsaPublicKey, 169 @Description("Payto URI of the debit account") 170 val debit_account: Payto 171 ) 172 173 /** Request POST /taler-wire-gateway/admin/add-mapped */ 174 @Serializable 175 data class AddMappedRequest( 176 val amount: TalerAmount, 177 val authorization_pub: EddsaPublicKey, 178 val debit_account: Payto 179 ) 180 181 /** Response GET /taler-wire-gateway/history/incoming */ 182 @Serializable 183 @Description("History of incoming transactions") 184 data class IncomingHistory( 185 @Description("List of incoming transactions") 186 val incoming_transactions: List<IncomingBankTransaction>, 187 @Description("Payto URI of the credit account") 188 val credit_account: String 189 ) 190 191 /** Inner response GET /taler-wire-gateway/history/incoming */ 192 @Serializable 193 @Description("Incoming bank transaction details") 194 sealed interface IncomingBankTransaction { 195 val row_id: Long 196 val date: TalerTimestamp 197 val amount: TalerAmount 198 val debit_account: String 199 val credit_fee: TalerAmount? 200 } 201 202 @Serializable 203 @SerialName("KYCAUTH") 204 @Description("Incoming KYC authentication transaction") 205 data class IncomingKycAuthTransaction( 206 @Description("Database row identifier") 207 override val row_id: Long, 208 @Description("Timestamp of the transaction") 209 override val date: TalerTimestamp, 210 @Description("Transaction amount") 211 override val amount: TalerAmount, 212 @Description("Optional credit fee") 213 override val credit_fee: TalerAmount? = null, 214 @Description("Payto URI of the debit account") 215 override val debit_account: String, 216 @Description("Account public key for KYC") 217 val account_pub: EddsaPublicKey, 218 @Description("Optional authorization public key") 219 val authorization_pub: EddsaPublicKey? = null, 220 @Description("Optional authorization signature") 221 val authorization_sig: EddsaSignature? = null, 222 ) : IncomingBankTransaction 223 224 @Serializable 225 @SerialName("RESERVE") 226 @Description("Incoming reserve transaction") 227 data class IncomingReserveTransaction( 228 @Description("Database row identifier") 229 override val row_id: Long, 230 @Description("Timestamp of the transaction") 231 override val date: TalerTimestamp, 232 @Description("Transaction amount") 233 override val amount: TalerAmount, 234 @Description("Optional credit fee") 235 override val credit_fee: TalerAmount? = null, 236 @Description("Payto URI of the debit account") 237 override val debit_account: String, 238 @Description("Reserve public key") 239 val reserve_pub: EddsaPublicKey, 240 @Description("Optional authorization public key") 241 val authorization_pub: EddsaPublicKey? = null, 242 @Description("Optional authorization signature") 243 val authorization_sig: EddsaSignature? = null, 244 ) : IncomingBankTransaction 245 246 @Serializable 247 @SerialName("WAD") 248 @Description("Incoming WAD transaction") 249 data class IncomingWadTransaction( 250 @Description("Database row identifier") 251 override val row_id: Long, 252 @Description("Timestamp of the transaction") 253 override val date: TalerTimestamp, 254 @Description("Transaction amount") 255 override val amount: TalerAmount, 256 @Description("Optional credit fee") 257 override val credit_fee: TalerAmount? = null, 258 @Description("Payto URI of the debit account") 259 override val debit_account: String, 260 @Description("URL of the originating exchange") 261 val origin_exchange_url: String, 262 @Description("WAD identifier") 263 val wad_id: String // TODO 24 bytes Base32 264 ) : IncomingBankTransaction 265 266 /** Response GET /taler-wire-gateway/history/outgoing */ 267 @Serializable 268 @Description("History of outgoing transactions") 269 data class OutgoingHistory( 270 @Description("List of outgoing transactions") 271 val outgoing_transactions: List<OutgoingTransaction>, 272 @Description("Payto URI of the debit account") 273 val debit_account: String 274 ) 275 276 /** Inner response GET /taler-wire-gateway/history/outgoing */ 277 @Serializable 278 @Description("Single outgoing transaction details") 279 data class OutgoingTransaction( 280 @Description("Database row identifier") 281 val row_id: Long, // DB row ID of the payment. 282 @Description("Timestamp of the transaction") 283 val date: TalerTimestamp, 284 @Description("Transaction amount") 285 val amount: TalerAmount, 286 @Description("Payto URI of the credit account") 287 val credit_account: String, 288 @Description("Wire transfer identifier") 289 val wtid: ShortHashCode, 290 @Description("Base URL of the exchange") 291 val exchange_base_url: String, 292 @Description("Optional transfer metadata") 293 val metadata: String? = null, 294 @Description("Optional debit fee") 295 val debit_fee: TalerAmount? = null 296 ) 297 298 /** Response GET /taler-wire-gateway/account/check */ 299 @Serializable 300 @Description("Account information response") 301 class AccountInfo() 302 303 /** Response GET /taler-prepared-transfer/config */ 304 @Serializable 305 @Description("Prepared transfer configuration") 306 data class PreparedTransferConfig( 307 @Description("Currency supported") 308 val currency: String, 309 @Description("List of supported subject formats") 310 val supported_formats: List<SubjectFormat> 311 ) { 312 @Description("API name identifier") 313 val name: String = "taler-prepared-transfer" 314 @Description("API version string") 315 val version: String = WIRE_TRANSFER_API_VERSION 316 } 317 318 319 /** Inner response GET /taler-prepared-transfer/registration */ 320 @Serializable 321 @Description("Transfer subject information") 322 sealed interface TransferSubject { 323 @Serializable 324 @SerialName("SIMPLE") 325 @Description("Simple text transfer subject") 326 data class Simple( 327 @Description("Plain text transfer subject") 328 val subject: String, 329 @Description("Credit amount for the transfer") 330 val credit_amount: TalerAmount 331 ) : TransferSubject 332 333 @Serializable 334 @SerialName("URI") 335 @Description("URI-based transfer subject") 336 data class Uri( 337 @Description("Taler URI for the transfer") 338 val uri: String, 339 @Description("Credit amount for the transfer") 340 val credit_amount: TalerAmount 341 ) : TransferSubject 342 343 @Serializable 344 @SerialName("CH_QR_BILL") 345 @Description("Swiss QR bill transfer subject") 346 data class QrBill( 347 @Description("QR reference number for the bill") 348 val qr_reference_number: String, 349 @Description("Credit amount for the transfer") 350 val credit_amount: TalerAmount, 351 ) : TransferSubject 352 } 353 354 @Serializable 355 @Description("Supported transfer subject format") 356 enum class SubjectFormat { 357 SIMPLE, 358 URI, 359 CH_QR_BILL 360 } 361 362 @Serializable 363 @Description("Public key algorithm") 364 enum class PublicKeyAlg { 365 EdDSA 366 } 367 368 @Serializable 369 @Description("Type of wire transfer") 370 enum class TransferType { 371 reserve, 372 kyc 373 } 374 375 @Serializable 376 @Description("Request to generate a transfer subject") 377 data class SubjectRequest( 378 @Description("Credit amount for the transfer") 379 val credit_amount: TalerAmount, 380 @Description("Type of transfer") 381 val type: TransferType, 382 @Description("Public key algorithm") 383 val alg: PublicKeyAlg, 384 @Description("Account public key") 385 val account_pub: EddsaPublicKey, 386 @Description("Authorization public key") 387 val authorization_pub: EddsaPublicKey, 388 @Description("Authorization signature") 389 val authorization_sig: EddsaSignature, 390 @Description("Whether subject is recurrent") 391 val recurrent: Boolean 392 ) 393 394 @Serializable 395 @Description("Result of subject generation") 396 data class SubjectResult( 397 @Description("List of generated transfer subjects") 398 val subjects: List<TransferSubject>, 399 @Description("Expiration timestamp of the subjects") 400 val expiration: TalerTimestamp 401 ) 402 403 @Serializable 404 @Description("Request to unregister a subject") 405 data class Unregistration( 406 @Description("Timestamp of the unregistration") 407 val timestamp: String, 408 @Description("Authorization public key") 409 val authorization_pub: EddsaPublicKey, 410 @Description("Authorization signature") 411 val authorization_sig: EddsaSignature 412 ) 413 414 /** Response GET /taler-revenue/config */ 415 @Serializable 416 @Description("Revenue API configuration response") 417 data class RevenueConfig( 418 @Description("Currency supported by the API") 419 val currency: String 420 ) { 421 @Description("API name identifier") 422 val name: String = "taler-revenue" 423 @Description("API version string") 424 val version: String = REVENUE_API_VERSION 425 } 426 427 /** Request GET /taler-revenue/history */ 428 @Serializable 429 @Description("History of revenue incoming transactions") 430 data class RevenueIncomingHistory( 431 @Description("List of incoming revenue transactions") 432 val incoming_transactions: List<RevenueIncomingBankTransaction>, 433 @Description("Payto URI of the credit account") 434 val credit_account: String 435 ) 436 437 /** Inner request GET /taler-revenue/history */ 438 @Serializable 439 @Description("Single revenue incoming bank transaction") 440 data class RevenueIncomingBankTransaction( 441 @Description("Database row identifier") 442 val row_id: Long, 443 @Description("Timestamp of the transaction") 444 val date: TalerTimestamp, 445 @Description("Transaction amount") 446 val amount: TalerAmount, 447 @Description("Optional credit fee") 448 val credit_fee: TalerAmount? = null, 449 @Description("Payto URI of the debit account") 450 val debit_account: String, 451 @Description("Transaction subject line") 452 val subject: String 453 ) 454 455 /** Response GET /taler-observability/config */ 456 @Serializable 457 @Description("Observability API configuration response") 458 class TalerObservabilityConfig() { 459 @Description("API name identifier") 460 val name: String = "taler-observability" 461 @Description("API version string") 462 val version: String = OBSERVABILITY_API_VERSION 463 }