contract_choice_serialize.c (6092B)
1 /* 2 This file is part of GNU Taler 3 Copyright (C) 2024, 2025 Taler Systems SA 4 5 TALER is free software; you can redistribute it and/or modify it under the 6 terms of the GNU 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 General Public License for more details. 12 13 You should have received a copy of the GNU General Public License along with 14 TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> 15 */ 16 /** 17 * @file src/util/contract_choice_serialize.c 18 * @brief shared logic for contract choice serialization 19 * @author Iván Ávalos 20 * @author Christian Grothoff 21 */ 22 #include "platform.h" 23 #include <gnunet/gnunet_json_lib.h> 24 #include <gnunet/gnunet_common.h> 25 #include <taler/taler_json_lib.h> 26 #include <jansson.h> 27 #include "taler/taler_util.h" 28 #include "taler/taler_merchant_util.h" 29 30 /** 31 * Get JSON representation of contract choice input. 32 * 33 * @param[in] input contract terms choice input 34 * @return JSON representation of @a input; NULL on error 35 */ 36 static json_t * 37 json_from_contract_input ( 38 const struct TALER_MERCHANT_ContractInput *input) 39 { 40 switch (input->type) 41 { 42 case TALER_MERCHANT_CONTRACT_INPUT_TYPE_INVALID: 43 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 44 "invalid contract input type"); 45 GNUNET_assert (0); 46 return NULL; 47 case TALER_MERCHANT_CONTRACT_INPUT_TYPE_TOKEN: 48 return GNUNET_JSON_PACK ( 49 GNUNET_JSON_pack_string ("type", 50 "token"), 51 GNUNET_JSON_pack_string ("token_family_slug", 52 input->details.token.token_family_slug), 53 GNUNET_JSON_pack_uint64 ("count", 54 input->details.token.count)); 55 } 56 57 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 58 "unsupported contract input type %d", 59 input->type); 60 GNUNET_assert (0); 61 return NULL; 62 } 63 64 65 /** 66 * Get JSON representation of contract choice output. 67 * 68 * @param[in] output contract terms choice output 69 * @return JSON representation of @a output; NULL on error 70 */ 71 static json_t * 72 json_from_contract_output ( 73 const struct TALER_MERCHANT_ContractOutput *output) 74 { 75 switch (output->type) 76 { 77 case TALER_MERCHANT_CONTRACT_OUTPUT_TYPE_INVALID: 78 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 79 "invalid contract output type"); 80 GNUNET_assert (0); 81 return NULL; 82 case TALER_MERCHANT_CONTRACT_OUTPUT_TYPE_TOKEN: 83 return GNUNET_JSON_PACK ( 84 GNUNET_JSON_pack_string ("type", 85 "token"), 86 GNUNET_JSON_pack_string ("token_family_slug", 87 output->details.token.token_family_slug), 88 GNUNET_JSON_pack_uint64 ("count", 89 output->details.token.count), 90 GNUNET_TIME_absolute_is_zero (output->details.token.valid_at.abs_time) 91 ? GNUNET_JSON_pack_allow_null ( 92 GNUNET_JSON_pack_string ("dummy", 93 NULL)) 94 : GNUNET_JSON_pack_timestamp ("valid_at", 95 output->details.token.valid_at), 96 GNUNET_JSON_pack_uint64 ("key_index", 97 output->details.token.key_index)); 98 case TALER_MERCHANT_CONTRACT_OUTPUT_TYPE_DONATION_RECEIPT: 99 { 100 json_t *donau_urls; 101 102 donau_urls = json_array (); 103 GNUNET_assert (NULL != donau_urls); 104 for (unsigned i = 0; 105 i < output->details.donation_receipt.donau_urls_len; 106 i++) 107 GNUNET_assert (0 == 108 json_array_append_new ( 109 donau_urls, 110 json_string ( 111 output->details.donation_receipt.donau_urls[i]))); 112 113 return GNUNET_JSON_PACK ( 114 GNUNET_JSON_pack_string ("type", 115 "tax-receipt"), 116 GNUNET_JSON_pack_array_steal ("donau_urls", 117 donau_urls), 118 TALER_JSON_pack_amount ("amount", 119 &output->details.donation_receipt.amount)); 120 } 121 } 122 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 123 "Unsupported contract output type %d", 124 output->type); 125 GNUNET_assert (0); 126 return NULL; 127 } 128 129 130 json_t * 131 TALER_MERCHANT_json_from_contract_choice ( 132 const struct TALER_MERCHANT_ContractChoice *choice) 133 { 134 json_t *inputs; 135 json_t *outputs; 136 137 inputs = json_array (); 138 GNUNET_assert (NULL != inputs); 139 for (unsigned int i = 0; i < choice->inputs_len; i++) 140 GNUNET_assert (0 == 141 json_array_append_new (inputs, 142 json_from_contract_input ( 143 &choice->inputs[i]))); 144 outputs = json_array (); 145 GNUNET_assert (NULL != outputs); 146 for (unsigned int i = 0; i < choice->outputs_len; i++) 147 GNUNET_assert (0 == 148 json_array_append_new (outputs, 149 json_from_contract_output ( 150 &choice->outputs[i]))); 151 152 return GNUNET_JSON_PACK ( 153 TALER_JSON_pack_amount ("amount", 154 &choice->amount), 155 GNUNET_JSON_pack_allow_null ( 156 TALER_JSON_pack_amount ("tip", 157 choice->no_tip 158 ? NULL 159 : &choice->tip)), 160 GNUNET_JSON_pack_allow_null ( 161 GNUNET_JSON_pack_string ("description", 162 choice->description)), 163 GNUNET_JSON_pack_allow_null ( 164 GNUNET_JSON_pack_object_incref ("description_i18n", 165 choice->description_i18n)), 166 TALER_JSON_pack_amount ("max_fee", 167 &choice->max_fee), 168 GNUNET_JSON_pack_array_steal ("inputs", 169 inputs), 170 GNUNET_JSON_pack_array_steal ("outputs", 171 outputs)); 172 }