contract_choice_serialize.c (6015B)
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_JSON_pack_conditional ( 91 ! GNUNET_TIME_absolute_is_zero (output->details.token.valid_at.abs_time), 92 GNUNET_JSON_pack_timestamp ("valid_at", 93 output->details.token.valid_at)), 94 GNUNET_JSON_pack_uint64 ("key_index", 95 output->details.token.key_index)); 96 case TALER_MERCHANT_CONTRACT_OUTPUT_TYPE_DONATION_RECEIPT: 97 { 98 json_t *donau_urls; 99 100 donau_urls = json_array (); 101 GNUNET_assert (NULL != donau_urls); 102 for (unsigned i = 0; 103 i < output->details.donation_receipt.donau_urls_len; 104 i++) 105 GNUNET_assert (0 == 106 json_array_append_new ( 107 donau_urls, 108 json_string ( 109 output->details.donation_receipt.donau_urls[i]))); 110 111 return GNUNET_JSON_PACK ( 112 GNUNET_JSON_pack_string ("type", 113 "tax-receipt"), 114 GNUNET_JSON_pack_array_steal ("donau_urls", 115 donau_urls), 116 TALER_JSON_pack_amount ("amount", 117 &output->details.donation_receipt.amount)); 118 } 119 } 120 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 121 "Unsupported contract output type %d", 122 output->type); 123 GNUNET_assert (0); 124 return NULL; 125 } 126 127 128 json_t * 129 TALER_MERCHANT_json_from_contract_choice ( 130 const struct TALER_MERCHANT_ContractChoice *choice) 131 { 132 json_t *inputs; 133 json_t *outputs; 134 135 inputs = json_array (); 136 GNUNET_assert (NULL != inputs); 137 for (unsigned int i = 0; i < choice->inputs_len; i++) 138 GNUNET_assert (0 == 139 json_array_append_new (inputs, 140 json_from_contract_input ( 141 &choice->inputs[i]))); 142 outputs = json_array (); 143 GNUNET_assert (NULL != outputs); 144 for (unsigned int i = 0; i < choice->outputs_len; i++) 145 GNUNET_assert (0 == 146 json_array_append_new (outputs, 147 json_from_contract_output ( 148 &choice->outputs[i]))); 149 150 return GNUNET_JSON_PACK ( 151 TALER_JSON_pack_amount ("amount", 152 &choice->amount), 153 GNUNET_JSON_pack_allow_null ( 154 TALER_JSON_pack_amount ("tip", 155 choice->no_tip 156 ? NULL 157 : &choice->tip)), 158 GNUNET_JSON_pack_allow_null ( 159 GNUNET_JSON_pack_string ("description", 160 choice->description)), 161 GNUNET_JSON_pack_allow_null ( 162 GNUNET_JSON_pack_object_incref ("description_i18n", 163 choice->description_i18n)), 164 TALER_JSON_pack_amount ("max_fee", 165 &choice->max_fee), 166 GNUNET_JSON_pack_array_steal ("inputs", 167 inputs), 168 GNUNET_JSON_pack_array_steal ("outputs", 169 outputs)); 170 }