taler_merchant_util.h (21505B)
1 /* 2 This file is part of GNU Taler 3 Copyright (C) 2024 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 include/taler_merchant_util.h 18 * @brief Interface for common utility functions 19 * @author Christian Grothoff 20 */ 21 #ifndef TALER_MERCHANT_UTIL_H 22 #define TALER_MERCHANT_UTIL_H 23 24 #include <gnunet/gnunet_common.h> 25 #include <gnunet/gnunet_util_lib.h> 26 #include <gnunet/gnunet_json_lib.h> 27 #include <stdint.h> 28 #include <taler/taler_util.h> 29 #include <jansson.h> 30 31 /** 32 * Fixed-point base for inventory quantities (powers of 10). 33 * Six decimal digits are supported to match the maximum unit precision. 34 */ 35 #define MERCHANT_UNIT_FRAC_BASE 1000000U 36 #define MERCHANT_UNIT_FRAC_MAX_DIGITS 6U 37 38 /** 39 * Return default project data used by Taler merchant. 40 */ 41 const struct GNUNET_OS_ProjectData * 42 TALER_MERCHANT_project_data (void); 43 44 45 /** 46 * Channel used to transmit MFA authorization request. 47 */ 48 enum TALER_MERCHANT_MFA_Channel 49 { 50 /** 51 * No MFA channel. 52 */ 53 TALER_MERCHANT_MFA_CHANNEL_NONE = 0, 54 55 /** 56 * SMS ("sms") 57 */ 58 TALER_MERCHANT_MFA_CHANNEL_SMS = 1, 59 60 /** 61 * E-mail ("email") 62 */ 63 TALER_MERCHANT_MFA_CHANNEL_EMAIL, 64 65 /** 66 * TOTP ("totp"). (Not yet implemented, #10327.) 67 */ 68 TALER_MERCHANT_MFA_CHANNEL_TOTP 69 }; 70 71 72 /** 73 * Types of critical operations of a merchant backend that may require 74 * multi-factor authorization. 75 */ 76 enum TALER_MERCHANT_MFA_CriticalOperation 77 { 78 /** 79 * Marker used to indicate that this is NOT a critical operation. 80 */ 81 TALER_MERCHANT_MFA_CO_NONE = 0, 82 83 /** 84 * Instance provisioning ("instance_provision"). 85 */ 86 TALER_MERCHANT_MFA_CO_INSTANCE_PROVISION, 87 88 /** 89 * Bank account configuration or reconfiguration ("account_config"). 90 */ 91 TALER_MERCHANT_MFA_CO_ACCOUNT_CONFIGURATION, 92 93 /** 94 * Authentication configuration change ("auth_config"). 95 */ 96 TALER_MERCHANT_MFA_CO_AUTH_CONFIGURATION, 97 98 /** 99 * Instance deletion ("instance_deletion"). 100 */ 101 TALER_MERCHANT_MFA_CO_INSTANCE_DELETION, 102 103 /** 104 * Authentication token creation ("auth_token_creation"). 105 */ 106 TALER_MERCHANT_MFA_CO_AUTH_TOKEN_CREATION 107 108 109 }; 110 111 112 /** 113 * Convert critical operation enumeration value to string 114 * suitable for human readers. 115 * 116 * @param co input to convert 117 * @return operation value as string 118 */ 119 const char * 120 TALER_MERCHANT_MFA_co2s ( 121 enum TALER_MERCHANT_MFA_CriticalOperation co); 122 123 124 /** 125 * Convert critical operation enumeration value to string. 126 * 127 * @param co input to convert 128 * @return operation value as string 129 */ 130 const char * 131 TALER_MERCHANT_MFA_co_to_string ( 132 enum TALER_MERCHANT_MFA_CriticalOperation co); 133 134 135 /** 136 * Convert string to critical operation enumeration value. 137 * 138 * @param str input to convert 139 * @return #TALER_MERCHANT_MFA_CO_NONE on failure 140 */ 141 enum TALER_MERCHANT_MFA_CriticalOperation 142 TALER_MERCHANT_MFA_co_from_string (const char *str); 143 144 145 /** 146 * Convert MFA channel enumeration value to string. 147 * 148 * @param ch input to convert 149 * @return operation value as string 150 */ 151 const char * 152 TALER_MERCHANT_MFA_channel_to_string ( 153 enum TALER_MERCHANT_MFA_Channel ch); 154 155 156 /** 157 * Convert string to MFA channel enumeration value. 158 * 159 * @param str input to convert 160 * @return #TALER_MERCHANT_MFA_CHANNEL_NONE on failure 161 */ 162 enum TALER_MERCHANT_MFA_Channel 163 TALER_MERCHANT_MFA_channel_from_string (const char *str); 164 165 166 /** 167 * @brief Salted hash of a body for a request that required MFA. 168 */ 169 struct TALER_MERCHANT_MFA_BodyHash 170 { 171 /** 172 * Hash of the body and salt. 173 */ 174 struct GNUNET_ShortHashCode hash; 175 }; 176 177 178 /** 179 * @brief Salt used when computing a `struct TALER_MERCHANT_MFA_BodyHash` 180 */ 181 struct TALER_MERCHANT_MFA_BodySalt 182 { 183 /** 184 * Salt. 185 */ 186 uint64_t salt[128 / 64]; 187 }; 188 189 190 /** 191 * Hash the given request @a body with the given @a salt to 192 * produce @a h_body for MFA checks. 193 * 194 * @param body HTTP request body, NULL if body was empty 195 * @param salt salt to use 196 * @param h_body resulting hash 197 */ 198 void 199 TALER_MERCHANT_mfa_body_hash ( 200 const json_t *body, 201 const struct TALER_MERCHANT_MFA_BodySalt *salt, 202 struct TALER_MERCHANT_MFA_BodyHash *h_body); 203 204 205 /** 206 * Possible versions of the contract terms. 207 */ 208 enum TALER_MERCHANT_ContractVersion 209 { 210 211 /** 212 * Version 0 213 */ 214 TALER_MERCHANT_CONTRACT_VERSION_0 = 0, 215 216 /** 217 * Version 1 218 */ 219 TALER_MERCHANT_CONTRACT_VERSION_1 = 1 220 }; 221 222 /** 223 * Possible token kinds. 224 */ 225 enum TALER_MERCHANT_ContractTokenKind 226 { 227 /** 228 * Token kind invalid 229 */ 230 TALER_MERCHANT_CONTRACT_TOKEN_KIND_INVALID = 0, 231 232 /** 233 * Subscription token kind 234 */ 235 TALER_MERCHANT_CONTRACT_TOKEN_KIND_SUBSCRIPTION = 1, 236 237 /** 238 * Discount token kind 239 */ 240 TALER_MERCHANT_CONTRACT_TOKEN_KIND_DISCOUNT = 2, 241 }; 242 243 /** 244 * Possible input types for the contract terms. 245 */ 246 enum TALER_MERCHANT_ContractInputType 247 { 248 249 /** 250 * Input type invalid 251 */ 252 TALER_MERCHANT_CONTRACT_INPUT_TYPE_INVALID = 0, 253 254 #if FUTURE 255 /** 256 * Input type coin 257 */ 258 TALER_MERCHANT_CONTRACT_INPUT_TYPE_COIN = 1, 259 #endif 260 /** 261 * Input type token 262 */ 263 TALER_MERCHANT_CONTRACT_INPUT_TYPE_TOKEN = 2 264 }; 265 266 /** 267 * Contract input (part of the v1 contract terms). 268 */ 269 struct TALER_MERCHANT_ContractInput 270 { 271 /** 272 * Type of the input. 273 */ 274 enum TALER_MERCHANT_ContractInputType type; 275 276 union 277 { 278 #if FUTURE 279 /** 280 * Coin-based input (ration). (Future work, only here for reference) 281 */ 282 struct 283 { 284 /** 285 * Price to be paid. 286 */ 287 struct TALER_Amount price; 288 289 /** 290 * Base URL of the ration authority. 291 */ 292 const char *ration_authority_url; 293 } coin; 294 #endif 295 296 /** 297 * Token-based input. 298 */ 299 struct 300 { 301 /** 302 * Slug of the token family to be used. 303 */ 304 const char *token_family_slug; 305 306 /** 307 * Number of tokens of this type required. Defaults to one if the 308 * field is not provided. 309 */ 310 unsigned int count; 311 } token; 312 } details; 313 }; 314 315 /** 316 * Possible output types for the contract terms. 317 */ 318 enum TALER_MERCHANT_ContractOutputType 319 { 320 321 /** 322 * Invalid output type 323 */ 324 TALER_MERCHANT_CONTRACT_OUTPUT_TYPE_INVALID = 0, 325 326 /** 327 * Output type token 328 */ 329 TALER_MERCHANT_CONTRACT_OUTPUT_TYPE_TOKEN = 1, 330 331 /** 332 * Output type donation-receipt 333 */ 334 TALER_MERCHANT_CONTRACT_OUTPUT_TYPE_DONATION_RECEIPT = 2, 335 #if FUTURE 336 /** 337 * Output type coin 338 */ 339 TALER_MERCHANT_CONTRACT_OUTPUT_TYPE_COIN = 3 340 #endif 341 342 }; 343 344 /** 345 * Contract output (part of the v1 contract terms). 346 */ 347 struct TALER_MERCHANT_ContractOutput 348 { 349 /** 350 * Type of the output. 351 */ 352 enum TALER_MERCHANT_ContractOutputType type; 353 354 union 355 { 356 #if FUTURE 357 /** 358 * Coin-based output. 359 */ 360 struct 361 { 362 /** 363 * Coins that will be yielded. This excludes any applicable withdraw fees. 364 */ 365 struct TALER_Amount brutto_yield; 366 367 /** 368 * Base URL of the exchange that will issue the coins. 369 * 370 * NOTE: Once implemented, check if we need to allocate this here or if 371 * we again reference the JSON as we do in other places. 372 */ 373 char *exchange_url; 374 375 } coin; 376 #endif 377 /** 378 * DONAU-receipt output. 379 */ 380 struct 381 { 382 /** 383 * Amount of the donation. (optional) 384 */ 385 struct TALER_Amount amount; 386 387 /** 388 * Base URLs of the donation authorities that will issue the tax receipt. 389 */ 390 char **donau_urls; 391 392 /** 393 * Length of the @e donau_urls array. 394 */ 395 unsigned int donau_urls_len; 396 397 } donation_receipt; 398 399 /** 400 * Token-based output. 401 */ 402 struct 403 { 404 /** 405 * Slug of the token family to be issued. 406 * Note: this is a pointer into the JSON of the 407 * respective contract/request and not owned here. 408 */ 409 const char *token_family_slug; 410 411 /** 412 * Index of the public key in the @a token_family_slug's token family 413 * ``keys`` array that this output token will have. 414 */ 415 unsigned int key_index; 416 417 /** 418 * Number of tokens of this type required. Defaults to one if the 419 * field is not provided. 420 */ 421 unsigned int count; 422 423 /** 424 * Determines when the output token should be valid. 425 * Optional, set to zero for not specified (then we 426 * use the current time). 427 */ 428 struct GNUNET_TIME_Timestamp valid_at; 429 430 } token; 431 432 } details; 433 434 }; 435 436 /** 437 * Contract choice (part of the v1 contract terms). 438 */ 439 struct TALER_MERCHANT_ContractChoice 440 { 441 442 /** 443 * Amount to be paid for this choice. 444 */ 445 struct TALER_Amount amount; 446 447 /** 448 * Human readable description of the semantics of the choice within the 449 * contract to be shown to the user at payment. 450 */ 451 char *description; 452 453 /** 454 * Map from IETF BCP 47 language tags to localized description. 455 */ 456 json_t *description_i18n; 457 458 /** 459 * Maximum fee the merchant is willing to pay for this choice. 460 * Set to an invalid amount to use instance defaults (zero or STEFAN). 461 */ 462 struct TALER_Amount max_fee; 463 464 /** 465 * List of inputs the wallet must provision (all of them) to satisfy the 466 * conditions for the contract. 467 */ 468 struct TALER_MERCHANT_ContractInput *inputs; 469 470 /** 471 * Length of the @e inputs array. 472 */ 473 unsigned int inputs_len; 474 475 /** 476 * List of outputs the merchant promises to yield (all of them) once 477 * the contract is paid. 478 */ 479 struct TALER_MERCHANT_ContractOutput *outputs; 480 481 /** 482 * Length of the @e outputs array. 483 */ 484 unsigned int outputs_len; 485 }; 486 487 /** 488 * Public key and corresponding metadata for a token family. 489 */ 490 struct TALER_MERCHANT_ContractTokenFamilyKey 491 { 492 /** 493 * Public key. 494 */ 495 struct TALER_TokenIssuePublicKey pub; 496 497 /** 498 * Start time of the token family duration. 499 */ 500 struct GNUNET_TIME_Timestamp valid_after; 501 502 /** 503 * Tokens signed by this key will be valid until this time. 504 */ 505 struct GNUNET_TIME_Timestamp valid_before; 506 }; 507 508 509 /** 510 * Represents a family of tokens issued by merchants that can be used in contracts. 511 */ 512 struct TALER_MERCHANT_ContractTokenFamily 513 { 514 /** 515 * Slug of the token family. 516 */ 517 char *slug; 518 519 /** 520 * Human-readable name of the token family. 521 */ 522 char *name; 523 524 /** 525 * Human-readable description of the semantics of the tokens issued by 526 * this token family. 527 */ 528 char *description; 529 530 /** 531 * Map from IETF BCP 47 language tags to localized description. 532 */ 533 json_t *description_i18n; 534 535 /** 536 * Relevant public keys of this token family for the given contract. 537 */ 538 struct TALER_MERCHANT_ContractTokenFamilyKey *keys; 539 540 /** 541 * Length of the @e keys array. 542 */ 543 unsigned int keys_len; 544 545 /** 546 * Must a wallet understand this token type to process contracts that 547 * consume or yield it? 548 */ 549 bool critical; 550 551 /** 552 * Kind of the token family. 553 */ 554 enum TALER_MERCHANT_ContractTokenKind kind; 555 556 /** 557 * Kind-specific information about the token. 558 */ 559 union 560 { 561 /** 562 * Subscription token. 563 */ 564 struct 565 { 566 /** 567 * Array of domain names where this subscription can be safely used 568 * (e.g. the issuer warrants that these sites will re-issue tokens of 569 * this type if the respective contract says so). May contain "*" for 570 * any domain or subdomain. 571 */ 572 char **trusted_domains; 573 574 /** 575 * Length of the @e trusted_domains array. 576 */ 577 unsigned int trusted_domains_len; 578 } subscription; 579 580 /** 581 * Discount token. 582 */ 583 struct 584 { 585 /** 586 * Array of domain names where this discount token is intended to be 587 * used. May contain "*" for any domain or subdomain. Users should be 588 * warned about sites proposing to consume discount tokens of this 589 * type that are not in this list that the merchant is accepting a 590 * coupon from a competitor and thus may be attaching different 591 * semantics (like get 20% discount for my competitors 30% discount 592 * token). 593 */ 594 char **expected_domains; 595 596 /** 597 * Length of the @e expected_domains array. 598 */ 599 unsigned int expected_domains_len; 600 601 } discount; 602 } details; 603 }; 604 605 606 /** 607 * Struct to hold contract terms. 608 */ 609 struct TALER_MERCHANT_Contract 610 { 611 /** 612 * URL where the same contract could be ordered again (if available). 613 */ 614 char *public_reorder_url; 615 616 /** 617 * Our order ID. 618 */ 619 char *order_id; 620 621 /** 622 * Merchant base URL. 623 */ 624 char *merchant_base_url; 625 626 /** 627 * Merchant information. 628 */ 629 struct 630 { 631 /** 632 * Legal name of the instance 633 */ 634 char *name; 635 636 /** 637 * Merchant's site url 638 */ 639 char *website; 640 641 /** 642 * Email contact for customers 643 */ 644 char *email; 645 646 /** 647 * merchant's logo data uri 648 */ 649 char *logo; 650 651 /** 652 * Merchant address 653 */ 654 json_t *address; 655 656 /** 657 * Jurisdiction of the business 658 */ 659 json_t *jurisdiction; 660 661 } merchant; 662 663 /** 664 * Summary of the contract. 665 */ 666 char *summary; 667 668 /** 669 * Internationalized summary. 670 */ 671 json_t *summary_i18n; 672 673 /** 674 * URL that will show that the contract was successful 675 * after it has been paid for. 676 */ 677 char *fulfillment_url; 678 679 /** 680 * Message shown to the customer after paying for the contract. 681 * Either fulfillment_url or fulfillment_message must be specified. 682 */ 683 char *fulfillment_message; 684 685 /** 686 * Map from IETF BCP 47 language tags to localized fulfillment messages. 687 */ 688 json_t *fulfillment_message_i18n; 689 690 /** 691 * Array of products that are part of the purchase. 692 */ 693 json_t *products; 694 695 /** 696 * Timestamp of the contract. 697 */ 698 struct GNUNET_TIME_Timestamp timestamp; 699 700 /** 701 * Deadline for refunds. 702 */ 703 struct GNUNET_TIME_Timestamp refund_deadline; 704 705 /** 706 * Specifies for how long the wallet should try to get an 707 * automatic refund for the purchase. 708 */ 709 struct GNUNET_TIME_Relative auto_refund; 710 711 /** 712 * Payment deadline. 713 */ 714 struct GNUNET_TIME_Timestamp pay_deadline; 715 716 /** 717 * Wire transfer deadline. 718 */ 719 struct GNUNET_TIME_Timestamp wire_deadline; 720 721 /** 722 * Delivery date. 723 */ 724 struct GNUNET_TIME_Timestamp delivery_date; 725 726 727 /** 728 * Merchant public key. 729 */ 730 struct TALER_MerchantPublicKeyP merchant_pub; 731 732 /** 733 * The hash of the merchant instance's wire details. 734 * TODO: appropriate type 735 */ 736 struct TALER_MerchantWireHashP h_wire; 737 738 /** 739 * Wire transfer method identifier for the wire method associated with 740 h_wire. 741 */ 742 char *wire_method; 743 744 /** 745 * Exchanges that the merchant accepts even if it does not accept any auditors that audit them. 746 * TODO: appropriate type 747 */ 748 json_t *exchanges; 749 750 /** 751 * Delivery location. 752 */ 753 json_t *delivery_location; 754 755 /** 756 * Nonce generated by the wallet and echoed by the merchant 757 * in this field when the proposal is generated. 758 */ 759 char *nonce; 760 761 /** 762 * Extra data that is only interpreted by the merchant frontend. 763 */ 764 json_t *extra; 765 766 /** 767 * Minimum age the buyer must have (in years). 768 */ 769 uint8_t minimum_age; 770 771 /** 772 * Specified version of the contract. 773 */ 774 enum TALER_MERCHANT_ContractVersion version; 775 776 /** 777 * Details depending on the @e version. 778 */ 779 union 780 { 781 782 /** 783 * Details for v0 contracts. 784 */ 785 struct 786 { 787 788 /** 789 * Price to be paid for the transaction. Could be 0. The price is in addition 790 * to other instruments, such as rations and tokens. 791 * The exchange will subtract deposit fees from that amount 792 * before transferring it to the merchant. 793 */ 794 struct TALER_Amount brutto; 795 796 /** 797 * Maximum fee as given by the client request. 798 */ 799 struct TALER_Amount max_fee; 800 801 } v0; 802 803 /** 804 * Details for v1 contracts. 805 */ 806 struct 807 { 808 809 /** 810 * Array of possible specific contracts the wallet/customer may choose 811 * from by selecting the respective index when signing the deposit 812 * confirmation. 813 */ 814 struct TALER_MERCHANT_ContractChoice *choices; 815 816 /** 817 * Length of the @e choices array. 818 */ 819 unsigned int choices_len; 820 821 /** 822 * Array of token authorities. 823 */ 824 struct TALER_MERCHANT_ContractTokenFamily *token_authorities; 825 826 /** 827 * Length of the @e token_authorities array. 828 */ 829 unsigned int token_authorities_len; 830 831 } v1; 832 833 } details; 834 835 }; 836 837 838 /** 839 * Parse JSON contract terms in @a input. 840 * 841 * @param[in] input JSON object containing contract terms 842 * @param nonce_optional whether `nonce' field is optional 843 * @return parsed contract terms; NULL if @a input is malformed 844 */ 845 struct TALER_MERCHANT_Contract * 846 TALER_MERCHANT_contract_parse (json_t *input, 847 bool nonce_optional); 848 849 850 /** 851 * Provide specification to parse an JSON contract input type. 852 * The value is provided as a descriptive string. 853 * 854 * @param name name of the JSON member with the contract type 855 * @param[out] cit where to store the contract input type 856 * @return spec for parsing a contract input type 857 */ 858 struct GNUNET_JSON_Specification 859 TALER_MERCHANT_json_spec_cit (const char *name, 860 enum TALER_MERCHANT_ContractInputType *cit); 861 862 863 /** 864 * Parse JSON contract terms choice input. 865 * 866 * @param[in] root JSON object containing choice input 867 * @param[out] input parsed choice input, NULL if @a input is malformed 868 * @param index index of choice input in inputs array 869 * @param order whether @a input is contained in order or contract terms 870 * @return #GNUNET_SYSERR if @a input is malformed; #GNUNET_OK otherwise 871 */ 872 enum GNUNET_GenericReturnValue 873 TALER_MERCHANT_parse_choice_input ( 874 json_t *root, 875 struct TALER_MERCHANT_ContractInput *input, 876 size_t index, 877 bool order); 878 879 880 /** 881 * Provide specification to parse an JSON contract output type. 882 * The value is provided as a descriptive string. 883 * 884 * @param name name of the JSON member with the contract type 885 * @param[out] cot where to store the contract output type 886 * @return spec for parsing a contract output type 887 */ 888 struct GNUNET_JSON_Specification 889 TALER_MERCHANT_json_spec_cot (const char *name, 890 enum TALER_MERCHANT_ContractOutputType *cot); 891 892 893 /** 894 * Parse JSON contract terms choice output. 895 * 896 * @param[in] root JSON object containing choice output 897 * @param[out] output parsed choice output, NULL if @a output is malformed 898 * @param index index of choice output in outputs array 899 * @param order whether @a output is contained in order or contract terms 900 * @return #GNUNET_SYSERR if @a output is malformed; #GNUNET_OK otherwise 901 */ 902 enum GNUNET_GenericReturnValue 903 TALER_MERCHANT_parse_choice_output ( 904 json_t *root, 905 struct TALER_MERCHANT_ContractOutput *output, 906 size_t index, 907 bool order); 908 909 910 /** 911 * Serialize contract terms into JSON object. 912 * 913 * @param[in] input contract terms to serialize 914 * @param nonce_optional whether `nonce' field is optional 915 * @return JSON representation of @a input; NULL on error 916 */ 917 json_t * 918 TALER_MERCHANT_contract_serialize ( 919 const struct TALER_MERCHANT_Contract *input, 920 bool nonce_optional); 921 922 923 /** 924 * Get JSON representation of contract choice. 925 * 926 * @param[in] choice contract choice to serialize 927 * @param order whether @a choice is contained in order or contract terms 928 * @return JSON representation of @a choice; NULL on error 929 */ 930 json_t * 931 TALER_MERCHANT_json_from_contract_choice ( 932 const struct TALER_MERCHANT_ContractChoice *choice, 933 bool order); 934 935 936 /** 937 * Get JSON representation of contract token family. 938 * 939 * @param[in] family contract token family to serialize 940 * @return JSON representation of @a family; NULL on error 941 */ 942 json_t * 943 TALER_MERCHANT_json_from_token_family ( 944 const struct TALER_MERCHANT_ContractTokenFamily *family); 945 946 947 /** 948 * Find token family in contract terms from slug and validity date. 949 * 950 * @param slug slug of the token family 951 * @param valid_after validity start of the token family 952 * @param[in] families array of token families in the contract terms 953 * @param families_len length of @a families array 954 * @param[out] family matching token family; NULL if no result 955 * @param[out] key key of matching token family; NULL if no result 956 * @return #GNUNET_SYSERR if no matching family found; #GNUNET_OK otherwise 957 */ 958 enum GNUNET_GenericReturnValue 959 TALER_MERCHANT_find_token_family_key ( 960 const char *slug, 961 struct GNUNET_TIME_Timestamp valid_after, 962 const struct TALER_MERCHANT_ContractTokenFamily *families, 963 unsigned int families_len, 964 struct TALER_MERCHANT_ContractTokenFamily *family, 965 struct TALER_MERCHANT_ContractTokenFamilyKey *key); 966 967 968 /** 969 * Free all the fields in the given @a choice, but not @a choice itself, since 970 * it is normally part of an array. 971 * 972 * @param[in] choice contract terms choice to free 973 */ 974 void 975 TALER_MERCHANT_contract_choice_free ( 976 struct TALER_MERCHANT_ContractChoice *choice); 977 978 979 /** 980 * Free the @a contract and all fields in it. 981 * 982 * @param[in] contract contract to free 983 */ 984 void 985 TALER_MERCHANT_contract_free (struct TALER_MERCHANT_Contract *contract); 986 987 #endif