LCOV - code coverage report
Current view: top level - util - contract_serialize.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 84.1 % 107 90
Test Date: 2026-01-01 16:44:56 Functions: 100.0 % 12 12

            Line data    Source code
       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 util/contract_serialize.c
      18              :  * @brief shared logic for contract terms serialization
      19              :  * @author Iván Ávalos
      20              :  * @author Christian Grothoff
      21              :  */
      22              : 
      23              : #include "platform.h"
      24              : #include <gnunet/gnunet_json_lib.h>
      25              : #include <gnunet/gnunet_common.h>
      26              : #include <taler/taler_json_lib.h>
      27              : #include <jansson.h>
      28              : #include "taler/taler_util.h"
      29              : #include "taler_merchant_util.h"
      30              : 
      31              : /**
      32              :  * Get JSON representation of merchant details.
      33              :  *
      34              :  * @param[in] contract contract terms
      35              :  * @return JSON object with merchant details; NULL on error
      36              :  */
      37              : static json_t *
      38            2 : json_from_merchant_details (
      39              :   const struct TALER_MERCHANT_Contract *contract)
      40              : {
      41            2 :   return GNUNET_JSON_PACK (
      42              :     GNUNET_JSON_pack_string ("name",
      43              :                              contract->merchant.name),
      44              :     GNUNET_JSON_pack_allow_null (
      45              :       GNUNET_JSON_pack_string ("email",
      46              :                                contract->merchant.email)),
      47              :     GNUNET_JSON_pack_allow_null (
      48              :       GNUNET_JSON_pack_string ("website",
      49              :                                contract->merchant.website)),
      50              :     GNUNET_JSON_pack_allow_null (
      51              :       GNUNET_JSON_pack_string ("logo",
      52              :                                contract->merchant.logo)),
      53              :     GNUNET_JSON_pack_allow_null (
      54              :       GNUNET_JSON_pack_object_steal ("address",
      55              :                                      contract->merchant.address)),
      56              :     GNUNET_JSON_pack_allow_null (
      57              :       GNUNET_JSON_pack_object_steal ("jurisdiction",
      58              :                                      contract->merchant.jurisdiction)));
      59              : }
      60              : 
      61              : 
      62              : /**
      63              :  * Get JSON representation of contract choice input.
      64              :  *
      65              :  * @param[in] input contract terms choice input
      66              :  * @return JSON representation of @a input; NULL on error
      67              :  */
      68              : static json_t *
      69            6 : json_from_contract_input (
      70              :   const struct TALER_MERCHANT_ContractInput *input)
      71              : {
      72            6 :   switch (input->type)
      73              :   {
      74            0 :   case TALER_MERCHANT_CONTRACT_INPUT_TYPE_INVALID:
      75            0 :     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
      76              :                 "invalid contract input type");
      77            0 :     GNUNET_assert (0);
      78              :     return NULL;
      79            6 :   case TALER_MERCHANT_CONTRACT_INPUT_TYPE_TOKEN:
      80            6 :     return GNUNET_JSON_PACK (
      81              :       GNUNET_JSON_pack_string ("type",
      82              :                                "token"),
      83              :       GNUNET_JSON_pack_string ("token_family_slug",
      84              :                                input->details.token.token_family_slug),
      85              :       GNUNET_JSON_pack_int64 ("count",
      86              :                               input->details.token.count));
      87              :   }
      88              : 
      89            0 :   GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
      90              :               "unsupported contract input type %d",
      91              :               input->type);
      92            0 :   GNUNET_assert (0);
      93              :   return NULL;
      94              : }
      95              : 
      96              : 
      97              : /**
      98              :  * Get JSON representation of contract choice output.
      99              :  *
     100              :  * @param[in] output contract terms choice output
     101              :  * @return JSON representation of @a output; NULL on error
     102              :  */
     103              : static json_t *
     104           10 : json_from_contract_output (
     105              :   const struct TALER_MERCHANT_ContractOutput *output)
     106              : {
     107           10 :   switch (output->type)
     108              :   {
     109            0 :   case TALER_MERCHANT_CONTRACT_OUTPUT_TYPE_INVALID:
     110            0 :     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     111              :                 "invalid contract output type");
     112            0 :     GNUNET_assert (0);
     113              :     return NULL;
     114            9 :   case TALER_MERCHANT_CONTRACT_OUTPUT_TYPE_TOKEN:
     115            9 :     return GNUNET_JSON_PACK (
     116              :       GNUNET_JSON_pack_string ("type",
     117              :                                "token"),
     118              :       GNUNET_JSON_pack_string ("token_family_slug",
     119              :                                output->details.token.token_family_slug),
     120              :       GNUNET_JSON_pack_uint64 ("count",
     121              :                                output->details.token.count),
     122              :       GNUNET_JSON_pack_uint64 ("key_index",
     123              :                                output->details.token.key_index));
     124            1 :   case TALER_MERCHANT_CONTRACT_OUTPUT_TYPE_DONATION_RECEIPT:
     125              :     {
     126              :       json_t *donau_urls;
     127              : 
     128            1 :       donau_urls = json_array ();
     129            1 :       GNUNET_assert (NULL != donau_urls);
     130            1 :       for (unsigned i = 0;
     131            4 :            i < output->details.donation_receipt.donau_urls_len;
     132            3 :            i++)
     133            3 :         GNUNET_assert (0 ==
     134              :                        json_array_append_new (
     135              :                          donau_urls,
     136              :                          json_string (
     137              :                            output->details.donation_receipt.donau_urls[i])));
     138              : 
     139            1 :       return GNUNET_JSON_PACK (
     140              :         GNUNET_JSON_pack_string ("type",
     141              :                                  "tax-receipt"),
     142              :         GNUNET_JSON_pack_array_steal ("donau_urls",
     143              :                                       donau_urls),
     144              :         GNUNET_JSON_pack_allow_null (
     145              :           TALER_JSON_pack_amount ("amount",
     146              :                                   &output->details.donation_receipt.amount)));
     147              :     }
     148              :   }
     149            0 :   GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     150              :               "Unsupported contract output type %d",
     151              :               output->type);
     152            0 :   GNUNET_assert (0);
     153              :   return NULL;
     154              : }
     155              : 
     156              : 
     157              : json_t *
     158           11 : TALER_MERCHANT_json_from_contract_choice (
     159              :   const struct TALER_MERCHANT_ContractChoice *choice,
     160              :   bool order)
     161              : {
     162              :   json_t *inputs;
     163              :   json_t *outputs;
     164              : 
     165           11 :   inputs = json_array ();
     166           11 :   GNUNET_assert (NULL != inputs);
     167           17 :   for (unsigned int i = 0; i < choice->inputs_len; i++)
     168            6 :     GNUNET_assert (0 ==
     169              :                    json_array_append_new (inputs,
     170              :                                           json_from_contract_input (
     171              :                                             &choice->inputs[i])));
     172           11 :   outputs = json_array ();
     173           11 :   GNUNET_assert (NULL != outputs);
     174           21 :   for (unsigned int i = 0; i < choice->outputs_len; i++)
     175           10 :     GNUNET_assert (0 ==
     176              :                    json_array_append_new (outputs,
     177              :                                           json_from_contract_output (
     178              :                                             &choice->outputs[i])));
     179              : 
     180           11 :   return GNUNET_JSON_PACK (
     181              :     TALER_JSON_pack_amount ("amount",
     182              :                             &choice->amount),
     183              :     GNUNET_JSON_pack_allow_null (
     184              :       GNUNET_JSON_pack_string ("description",
     185              :                                choice->description)),
     186              :     GNUNET_JSON_pack_allow_null (
     187              :       GNUNET_JSON_pack_object_incref ("description_i18n",
     188              :                                       choice->description_i18n)),
     189              :     (order)
     190              :     ? GNUNET_JSON_pack_allow_null (
     191              :       TALER_JSON_pack_amount (
     192              :         "max_fee",
     193              :         /* workaround for nullable amount */
     194              :         (GNUNET_OK ==
     195              :          TALER_amount_is_valid (&choice->max_fee))
     196              :         ? &choice->max_fee
     197              :         : NULL))
     198              :     : TALER_JSON_pack_amount ("max_fee",
     199              :                               &choice->max_fee),
     200              :     (order)
     201              :     ? GNUNET_JSON_pack_allow_null (
     202              :       GNUNET_JSON_pack_array_steal ("inputs",
     203              :                                     inputs))
     204              :     : GNUNET_JSON_pack_array_steal ("inputs",
     205              :                                     inputs),
     206              :     (order)
     207              :     ? GNUNET_JSON_pack_allow_null (
     208              :       GNUNET_JSON_pack_array_steal ("outputs",
     209              :                                     outputs))
     210              :     : GNUNET_JSON_pack_array_steal ("outputs",
     211              :                                     outputs));
     212              : }
     213              : 
     214              : 
     215              : /**
     216              :  * Get JSON representation of contract token family key.
     217              :  *
     218              :  * @param[in] key contract token family key
     219              :  * @return JSON representation of @a key; NULL on error
     220              :  */
     221              : static json_t *
     222           10 : json_from_token_family_key (
     223              :   const struct TALER_MERCHANT_ContractTokenFamilyKey *key)
     224              : {
     225           10 :   return GNUNET_JSON_PACK (
     226              :     GNUNET_JSON_pack_timestamp ("signature_validity_start",
     227              :                                 key->valid_after),
     228              :     GNUNET_JSON_pack_timestamp ("signature_validity_end",
     229              :                                 key->valid_before),
     230              :     TALER_JSON_pack_token_pub (NULL,
     231              :                                &key->pub));
     232              : }
     233              : 
     234              : 
     235              : /**
     236              :  * Get JSON representation of contract token family details.
     237              :  *
     238              :  * @param[in] family contract token family
     239              :  * @return JSON representation of @a family->details; NULL on error
     240              :  */
     241              : static json_t *
     242           11 : json_from_token_family_details (
     243              :   const struct TALER_MERCHANT_ContractTokenFamily *family)
     244              : {
     245           11 :   switch (family->kind)
     246              :   {
     247            0 :   case TALER_MERCHANT_CONTRACT_TOKEN_KIND_INVALID:
     248            0 :     break;
     249            9 :   case TALER_MERCHANT_CONTRACT_TOKEN_KIND_SUBSCRIPTION:
     250              :     {
     251              :       json_t *trusted_domains;
     252              : 
     253            9 :       trusted_domains = json_array ();
     254            9 :       GNUNET_assert (NULL != trusted_domains);
     255            9 :       for (unsigned int i = 0;
     256           12 :            i < family->details.subscription.trusted_domains_len;
     257            3 :            i++)
     258            3 :         GNUNET_assert (0 ==
     259              :                        json_array_append_new (
     260              :                          trusted_domains,
     261              :                          json_string (
     262              :                            family->details.subscription.trusted_domains[i])));
     263              : 
     264            9 :       return GNUNET_JSON_PACK (
     265              :         GNUNET_JSON_pack_string ("class",
     266              :                                  "subscription"),
     267              :         GNUNET_JSON_pack_array_steal ("trusted_domains",
     268              :                                       trusted_domains));
     269              :     }
     270            2 :   case TALER_MERCHANT_CONTRACT_TOKEN_KIND_DISCOUNT:
     271              :     {
     272              :       json_t *expected_domains;
     273              : 
     274            2 :       expected_domains = json_array ();
     275            2 :       GNUNET_assert (NULL != expected_domains);
     276            2 :       for (unsigned int i = 0;
     277            5 :            i < family->details.discount.expected_domains_len;
     278            3 :            i++)
     279            3 :         GNUNET_assert (0 ==
     280              :                        json_array_append_new (
     281              :                          expected_domains,
     282              :                          json_string (
     283              :                            family->details.discount.expected_domains[i])));
     284              : 
     285            2 :       return GNUNET_JSON_PACK (
     286              :         GNUNET_JSON_pack_string ("class",
     287              :                                  "discount"),
     288              :         GNUNET_JSON_pack_array_steal ("expected_domains",
     289              :                                       expected_domains));
     290              :     }
     291              :   }
     292              : 
     293            0 :   GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
     294              :               "unsupported token family kind %d",
     295              :               family->kind);
     296            0 :   GNUNET_assert (0);
     297              :   return NULL;
     298              : }
     299              : 
     300              : 
     301              : json_t *
     302           11 : TALER_MERCHANT_json_from_token_family (
     303              :   const struct TALER_MERCHANT_ContractTokenFamily *family)
     304              : {
     305              :   json_t *keys;
     306              : 
     307           11 :   keys = json_array ();
     308           11 :   GNUNET_assert (NULL != keys);
     309           21 :   for (unsigned int i = 0; i < family->keys_len; i++)
     310           10 :     GNUNET_assert (0 == json_array_append_new (
     311              :                      keys,
     312              :                      json_from_token_family_key (
     313              :                        &family->keys[i])));
     314              : 
     315           11 :   return GNUNET_JSON_PACK (
     316              :     GNUNET_JSON_pack_string ("name",
     317              :                              family->name),
     318              :     GNUNET_JSON_pack_string ("description",
     319              :                              family->description),
     320              :     GNUNET_JSON_pack_object_incref ("description_i18n",
     321              :                                     family->description_i18n),
     322              :     GNUNET_JSON_pack_array_steal ("keys",
     323              :                                   keys),
     324              :     GNUNET_JSON_pack_object_steal ("details",
     325              :                                    json_from_token_family_details (family)),
     326              :     GNUNET_JSON_pack_bool ("critical",
     327              :                            family->critical));
     328              : }
     329              : 
     330              : 
     331              : /**
     332              :  * Get JSON object with contract terms v0-specific fields.
     333              :  *
     334              :  * @param[in] input contract terms v0
     335              :  * @return JSON object with @a input v0 fields; NULL on error
     336              :  */
     337              : static json_t *
     338            1 : json_from_contract_v0 (
     339              :   const struct TALER_MERCHANT_Contract *input)
     340              : {
     341            1 :   return GNUNET_JSON_PACK (
     342              :     TALER_JSON_pack_amount ("amount",
     343              :                             &input->details.v0.brutto),
     344              :     TALER_JSON_pack_amount ("max_fee",
     345              :                             &input->details.v0.max_fee));
     346              : }
     347              : 
     348              : 
     349              : /**
     350              :  * Get JSON object with contract terms v1-specific fields.
     351              :  *
     352              :  * @param[in] input contract terms v1
     353              :  * @return JSON object with @a input v1 fields; NULL on error
     354              :  */
     355              : static json_t *
     356            1 : json_from_contract_v1 (
     357              :   const struct TALER_MERCHANT_Contract *input)
     358              : {
     359              :   json_t *choices;
     360              :   json_t *families;
     361              : 
     362            1 :   choices = json_array ();
     363            1 :   GNUNET_assert (0 != choices);
     364            2 :   for (unsigned i = 0; i < input->details.v1.choices_len; i++)
     365            1 :     GNUNET_assert (0 == json_array_append_new (
     366              :                      choices,
     367              :                      TALER_MERCHANT_json_from_contract_choice (
     368              :                        &input->details.v1.choices[i],
     369              :                        false)));
     370              : 
     371            1 :   families = json_object ();
     372            1 :   GNUNET_assert (0 != families);
     373            3 :   for (unsigned i = 0; i < input->details.v1.token_authorities_len; i++)
     374            2 :     GNUNET_assert (0 == json_object_set_new (
     375              :                      families,
     376              :                      input->details.v1.token_authorities[i].slug,
     377              :                      TALER_MERCHANT_json_from_token_family (
     378              :                        &input->details.v1.token_authorities[i])));
     379              : 
     380            1 :   return GNUNET_JSON_PACK (
     381              :     GNUNET_JSON_pack_array_steal ("choices",
     382              :                                   choices),
     383              :     GNUNET_JSON_pack_object_steal ("token_families",
     384              :                                    families));
     385              : }
     386              : 
     387              : 
     388              : /**
     389              :  * Convert quantity @a q into a string for JSON serialization
     390              :  *
     391              :  * @param q quantity to convert
     392              :  * @return formatted string
     393              :  */
     394              : static const char *
     395           20 : quantity_to_string (const struct TALER_MERCHANT_ProductQuantity *q)
     396              : {
     397              :   static char res[64];
     398              : 
     399           20 :   TALER_MERCHANT_vk_format_fractional_string (TALER_MERCHANT_VK_QUANTITY,
     400           20 :                                               q->integer,
     401           20 :                                               q->fractional,
     402              :                                               sizeof (res),
     403              :                                               res);
     404           20 :   return res;
     405              : }
     406              : 
     407              : 
     408              : json_t *
     409           20 : TALER_MERCHANT_product_sold_serialize (
     410              :   const struct TALER_MERCHANT_ProductSold *p)
     411              : {
     412              :   json_t *prices;
     413              : 
     414           20 :   prices = json_array ();
     415           20 :   GNUNET_assert (NULL != prices);
     416           35 :   for (unsigned int i = 0; i<p->prices_length; i++)
     417           15 :     GNUNET_assert (0 ==
     418              :                    json_array_append_new (prices,
     419              :                                           TALER_JSON_from_amount (
     420              :                                             &p->prices[i])));
     421           20 :   return GNUNET_JSON_PACK (
     422              :     GNUNET_JSON_pack_allow_null (
     423              :       GNUNET_JSON_pack_string ("product_id",
     424              :                                p->product_id)),
     425              :     GNUNET_JSON_pack_allow_null (
     426              :       GNUNET_JSON_pack_string ("product_name",
     427              :                                p->product_name)),
     428              :     GNUNET_JSON_pack_allow_null (
     429              :       GNUNET_JSON_pack_string ("description",
     430              :                                p->description)),
     431              :     GNUNET_JSON_pack_allow_null (
     432              :       GNUNET_JSON_pack_object_incref ("description_i18n",
     433              :                                       (json_t *) p->description_i18n)),
     434              :     GNUNET_JSON_pack_allow_null (
     435              :       ( (0 != p->unit_quantity.integer) ||
     436              :         (0 != p->unit_quantity.fractional) )
     437              :       ? GNUNET_JSON_pack_string ("unit_quantity",
     438              :                                  quantity_to_string (&p->unit_quantity))
     439              :       : GNUNET_JSON_pack_string ("dummy",
     440              :                                  NULL) ),
     441              :     /* Legacy */
     442              :     GNUNET_JSON_pack_allow_null (
     443              :       (0 == p->unit_quantity.fractional)
     444              :       ? GNUNET_JSON_pack_uint64 ("quantity",
     445              :                                  p->unit_quantity.integer)
     446              :       : GNUNET_JSON_pack_string ("dummy",
     447              :                                  NULL) ),
     448              :     GNUNET_JSON_pack_allow_null (
     449              :       GNUNET_JSON_pack_string ("unit",
     450              :                                p->unit)),
     451              :     /* Deprecated, use prices! */
     452              :     GNUNET_JSON_pack_allow_null (
     453              :       TALER_JSON_pack_amount ("price",
     454              :                               0 < p->prices_length
     455              :                               ? &p->prices[0]
     456              :                               : NULL)),
     457              :     GNUNET_JSON_pack_array_steal ("prices",
     458              :                                   prices),
     459              :     GNUNET_JSON_pack_allow_null (
     460              :       GNUNET_JSON_pack_string ("image",
     461              :                                p->image)),
     462              :     GNUNET_JSON_pack_allow_null (
     463              :       GNUNET_JSON_pack_array_incref ("taxes",
     464              :                                      (json_t *) p->taxes)),
     465              :     GNUNET_JSON_pack_allow_null (
     466              :       GNUNET_TIME_absolute_is_never (p->delivery_date.abs_time)
     467              :       ? GNUNET_JSON_pack_string ("dummy",
     468              :                                  NULL)
     469              :       : GNUNET_JSON_pack_timestamp ("delivery_date",
     470              :                                     p->delivery_date)),
     471              :     GNUNET_JSON_pack_uint64 ("product_money_pot",
     472              :                              p->product_money_pot));
     473              : }
     474              : 
     475              : 
     476              : json_t *
     477            2 : TALER_MERCHANT_contract_serialize (
     478              :   const struct TALER_MERCHANT_Contract *input,
     479              :   bool nonce_optional)
     480              : {
     481              :   json_t *details;
     482              :   json_t *products;
     483              : 
     484            2 :   switch (input->version)
     485              :   {
     486            1 :   case TALER_MERCHANT_CONTRACT_VERSION_0:
     487            1 :     details = json_from_contract_v0 (input);
     488            1 :     goto success;
     489            1 :   case TALER_MERCHANT_CONTRACT_VERSION_1:
     490            1 :     details = json_from_contract_v1 (input);
     491            1 :     goto success;
     492              :   }
     493              : 
     494            0 :   GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     495              :               "unknown contract type version %d",
     496              :               input->version);
     497            0 :   GNUNET_assert (0);
     498              :   return NULL;
     499              : 
     500            2 : success:
     501            2 :   products = json_array ();
     502            2 :   GNUNET_assert (NULL != products);
     503            2 :   for (size_t i = 0; i<input->products_len; i++)
     504              :   {
     505            0 :     GNUNET_assert (
     506              :       0 ==
     507              :       json_array_append_new (products,
     508              :                              TALER_MERCHANT_product_sold_serialize (
     509              :                                &input->products[i])));
     510              :   }
     511              : 
     512            2 :   return GNUNET_JSON_PACK (
     513              :     GNUNET_JSON_pack_uint64 ("version",
     514              :                              input->version),
     515              :     GNUNET_JSON_pack_string ("summary",
     516              :                              input->summary),
     517              :     GNUNET_JSON_pack_allow_null (
     518              :       GNUNET_JSON_pack_object_steal ("summary_i18n",
     519              :                                      input->summary_i18n)),
     520              :     GNUNET_JSON_pack_string ("order_id",
     521              :                              input->order_id),
     522              :     GNUNET_JSON_pack_allow_null (
     523              :       GNUNET_JSON_pack_string ("public_reorder_url",
     524              :                                input->public_reorder_url)),
     525              :     GNUNET_JSON_pack_allow_null (
     526              :       GNUNET_JSON_pack_string ("fulfillment_url",
     527              :                                input->fulfillment_url)),
     528              :     GNUNET_JSON_pack_allow_null (
     529              :       GNUNET_JSON_pack_string ("fulfillment_message",
     530              :                                input->fulfillment_message)),
     531              :     GNUNET_JSON_pack_allow_null (
     532              :       GNUNET_JSON_pack_object_steal ("fulfillment_message_i18n",
     533              :                                      input->fulfillment_message_i18n)),
     534              :     GNUNET_JSON_pack_array_steal ("products",
     535              :                                   products),
     536              :     GNUNET_JSON_pack_timestamp ("timestamp",
     537              :                                 input->timestamp),
     538              :     GNUNET_JSON_pack_timestamp ("refund_deadline",
     539              :                                 input->refund_deadline),
     540              :     GNUNET_JSON_pack_timestamp ("pay_deadline",
     541              :                                 input->pay_deadline),
     542              :     GNUNET_JSON_pack_timestamp ("wire_transfer_deadline",
     543              :                                 input->wire_deadline),
     544              :     GNUNET_JSON_pack_data_auto ("merchant_pub",
     545              :                                 &input->merchant_pub.eddsa_pub),
     546              :     GNUNET_JSON_pack_string ("merchant_base_url",
     547              :                              input->merchant_base_url),
     548              :     GNUNET_JSON_pack_object_steal ("merchant",
     549              :                                    json_from_merchant_details (input)),
     550              :     GNUNET_JSON_pack_data_auto ("h_wire",
     551              :                                 &input->h_wire),
     552              :     GNUNET_JSON_pack_string ("wire_method",
     553              :                              input->wire_method),
     554              :     GNUNET_JSON_pack_array_steal ("exchanges",
     555              :                                   input->exchanges),
     556              :     GNUNET_JSON_pack_allow_null (
     557              :       GNUNET_JSON_pack_object_steal ("delivery_location",
     558              :                                      input->delivery_location)),
     559              :     GNUNET_JSON_pack_allow_null (
     560              :       GNUNET_JSON_pack_timestamp ("delivery_date",
     561              :                                   input->delivery_date)),
     562              :     (nonce_optional)
     563              :     ? GNUNET_JSON_pack_allow_null (
     564              :       GNUNET_JSON_pack_string ("nonce",
     565              :                                input->nonce))
     566              :     : GNUNET_JSON_pack_string ("nonce",
     567              :                                input->nonce),
     568              :     GNUNET_JSON_pack_allow_null (
     569              :       GNUNET_JSON_pack_time_rel ("auto_refund",
     570              :                                  input->auto_refund)),
     571              :     GNUNET_JSON_pack_allow_null (
     572              :       GNUNET_JSON_pack_object_steal ("extra",
     573              :                                      input->extra)),
     574              :     GNUNET_JSON_pack_allow_null (
     575              :       GNUNET_JSON_pack_uint64 ("minimum_age",
     576              :                                input->minimum_age)),
     577              :     (0 == input->default_money_pot)
     578              :     ? GNUNET_JSON_pack_allow_null (
     579              :       GNUNET_JSON_pack_string ("dummy",
     580              :                                NULL))
     581              :     : GNUNET_JSON_pack_uint64 ("default_money_pot",
     582              :                                input->default_money_pot),
     583              :     GNUNET_JSON_pack_object_steal (NULL,
     584              :                                    details));
     585              : }
        

Generated by: LCOV version 2.0-1