taler-docs

Documentation for GNU Taler components, APIs and protocols
Log | Files | Refs | README | LICENSE

commit e8074877853620103e72f5854d24ab686a020857
parent 316a6dfce7f8c191c4db6253beb9a9217f6be34e
Author: Christian Grothoff <christian@grothoff.org>
Date:   Fri, 11 Aug 2023 13:43:51 +0200

update

Diffstat:
Mcore/api-common.rst | 2++
Mdesign-documents/046-mumimo-contracts.rst | 250+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
2 files changed, 248 insertions(+), 4 deletions(-)

diff --git a/core/api-common.rst b/core/api-common.rst @@ -1046,6 +1046,8 @@ within the struct TALER_AmountNBO amount_with_fee; struct TALER_AmountNBO deposit_fee; struct TALER_MerchantPublicKeyP merchant; + struct TALER_OutputCommitmentHash h_outputs; + uint32_t subcontract_index_field; }; .. _TALER_DepositConfirmationPS: diff --git a/design-documents/046-mumimo-contracts.rst b/design-documents/046-mumimo-contracts.rst @@ -66,9 +66,11 @@ the selected sub-contract index and a hash committing it to the blinded envelopes (if any). The merchant backend will (probably?) need to be changed to truly support multiple currencies (ugh). - .. _contract-terms-v1: +New Contract Terms Format +------------------------- + The contract terms v1 will have the following structure: .. ts:def:: ContractTermsV1 @@ -249,19 +251,42 @@ The contract terms v1 will have the following structure: type ContractInput = | ContractInputCurrency + | ContractInputRation | ContractInputToken; .. ts:def:: ContractInputCurrency interface ContractInputCurrency { - type: "currency"; + type: "coin"; // Price to be paid for the transaction. // The exchange will subtract deposit fees from that amount // before transferring it to the merchant. price: Amount; + // FIXME-DOLD: do we want to move this into a 'details' + // sub-structure as done with tokens below? + class: "currency"; + + }; + + .. ts:def:: ContractInputRation + + interface ContractInputRation { + + type: "coin"; + + // Price to be paid for the transaction. + price: Amount; + + // FIXME-DOLD: do we want to move this into a 'details' + // sub-structure as done with tokens below? + class: "ration"; + + // Base URL of the ration authority. + ration_authority_url: string; + }; .. ts:def:: ContractInputToken @@ -347,10 +372,14 @@ The contract terms v1 will have the following structure: // When does the subscription period start? start_date: Timestamp; + // When does the subscription period end? + end_date: Timestamp; + // Array of domain names where this subscription // can be safely used (e.g. the issuer warrants that // these sites will re-issue tokens of this type - // if the respective contract says so). + // if the respective contract says so). May contain + // "*" for any domain or subdomain. trusted_domains: string[]; }; @@ -361,6 +390,16 @@ The contract terms v1 will have the following structure: class: "discount"; + // Array of domain names where this discount token + // is intended to be used. May contain "*" for any + // domain or subdomain. Users should be warned about + // sites proposing to consume discount tokens of this + // type that are not in this list that the merchant + // is accepting a coupon from a competitor and thus + // may be attaching different semantics (like get 20% + // discount for my competitors 30% discount token). + expected_domains: string[]; + }; @@ -380,7 +419,6 @@ The contract terms v1 will have the following structure: key: TokenSignerPublicKey; // When will tokens signed by this key expire? - // (also the expiration for 'subscriptions'). token_expiration: Timestamp; // Number of tokens issued according to ASS authority @@ -409,6 +447,208 @@ TODO: may want to do a deep copy and rename DenomGroup* to TokenSignerPublicKey* here. +Alternative Contracts +--------------------- + +The contract terms object may contain any number of alternative contracts that +the user must choose between. The alternatives can differ by inputs, outputs +or other details. The wallet must filter the contracts by those that the user +can actually pay for, and move those that the user could currently not pay for +to the end of the rendered list. Similarly, the wallet must move up the +cheaper contracts, so if a contract has a definitively lower price and +consumes an available discount token, that contract should be moved up in the +list. + +Which specific alternative contract was chosen by the user is indicated in the +subcontract index field of the `TALER_DepositRequestPS`. + +FIXME-DOLD: Should we also sign over this in the +`TALER_DepositConfirmationPS`? + + +Output Commitments +------------------ + +When a contract has outputs, the wallet must send an array of blinded tokens, +coins or tax receipts together with the payment request. The order in the +array must match the order in the outputs field of the contract. For currency outputs, one array element must include all of the required planchets for a batch withdrawal, +but of course not the reserve signature. + + .. note:: + + We can probably spec this rather nicely if we first change the +batch-withdraw API to only use a single reserve signature. + +This array of blinded values is hashed to create the output commitment hash +(``h_outputs``) in the `TALER_DepositRequestPS`. + +FIXME-DOLD: Should we also sign over this in the +`TALER_DepositConfirmationPS`? + + + +Subscriptions +------------- + +The user buys a subscription (and possibly at the same time an article) using +currency and the contract yields an additional subscription token as an +output. Active subscriptions are listed below the currencies in the wallet +under a new heading. Subscriptions are never auto-renewing, if the user wants +to extend the subscription they can trivially pay for it with one click. + +When a contract consumes and yields exactly one subscription +token of the same type in a trusted domain, the wallet may automatically +approve the transaction without asking the user for confirmation (as it is free). + +The token expiration for a subscription can be past the "end date" to enable a +previous subscription to be used to get a discount on renewing the +subscription. The wallet should show applicable contracts with a lower price +that only additionally consume subscription tokens after their end date before +higher-priced alternative offers. + +Subscription tokens are "critical" in that a wallet implementation must +understand them before allowing a user to interact with this class of token. + +The merchant SPA should allow the administrator to create (maybe update) and +delete subscriptions. Each subscription is identified by a subscription +label and includes a validity period. + +The merchant backend must then automatically manage (create, use, delete) the +respective signing keys. When creating an order, the frontend can just refer +to the subscription label (and possibly a start date) in the inputs or +outputs. The backend should then automatically substitute this with the +respective cryptographic fields for the respective time period and +subscription label. + + +Discounts +--------- + +To offer a discount based on one or more previous purchases, a merchant must +yield some discount-specific token as an output with the previous purchase, +and then offer an alternative contract with a lower price that consumes currency +and the discount token. The wallet should show contracts with a lower price that +only additionally consume discount tokens + +The merchant SPA should allow the administrator to create (maybe update) and +delete discount tokens. Each discount token is identified by a discount +label and includes an expiration time or validity duration. + +The merchant backend must then automatically manage (create, use, delete) the +respective signing keys. When creating an order, the frontend can just refer +to the discount token label in the inputs or outputs. The backend should then +automatically substitute this with the respective cryptographic fields for the +respective discount token. + + +Donation Authority +------------------ + +A donation authority (DONAU) implements a service that is expected to be run +by a government authority that determines eligibility for tax deduction. A +DONAU blindly signs tax receipts using a protocol very close to that of the +Taler exchange's withdraw protocol, except that the reserves are not filled +via wire transfers but instead represent accounts of the organizations +eligible to issue tax deduction receipts. These accounts are bascially +expected to have only negative balances, but the DONAU may have a +per-organization negative balance limit to cap tax deduction receipt +generation to a plausible account. DONAU administators are expected to be +able to add, update or remove these accounts using a SPA. Tax receipts +are blindly signed by keys that always have a usage period of one calendar +year. + +A stand-alone app for tax authorities can scan QR codes representing DONAU +signatures to validate that a given tax payer has donated a certain amount. +As RSA signatures are typically very large and a single donation may require +multiple blind signatures, CS blind signatures must also be supported. To +avoid encoding the public keys, QR codes with tax receipts should reference +the DONAU, the year and the amount, but not the specific public key. A +single donation may nevertheless be rendered using multiple QR codes. + +Revocations, refresh, deposits, age-restrictions and other exchange features +are not applicable for a DONAU. + +The merchant SPA should allow the administrator to manage DONAU accounts in +the merchant backend. Each DONAU account includes a base URL and a private +signing key for signing the requests to the DONAU on behalf of the eligible +organization. + +When creating an order, the frontend must specify a configured DONAU base URL +in the outputs. The backend should then automatically interact with the DONAU +when the wallet supplies the payment request with the blinded tax receipts. +The DONAU interaction must only happen after the exchange confirmed that the +contract was successfully paid. A partial error must be returned if the +exchange interaction was successful but the DONAU interaction failed. In this +case, the fulfillment action should still be triggered, but the wallet should +display a warning that the donation receipt could not be obtained. The wallet +should then re-try the payment (in the background with an exponential +back-off) to possibly obtain the tax receipt at a later time. + + +Tax Receipts +------------ + +Tax receipts differ from coins and tokens in that what is blindly signed over +should be the taxpayer identification number of the tax payer. The format of +the taxpayer identification number should simply be a string, with the rest +being defined by the national authority. The DONAU should indicate in its +``/config`` response what format this string should have, using possibly both +an Anastasis-style regex and an Anastasis-style function name (to check things +like checksums that cannot be validated using a regex). Wallets must then +validate the regex (if given) and if possible should implement the +Anastasis-style logic. + +Wallets should collect tax receipts by year and offer an +export functionality. The export should generate either + + (a) a JSON file, + (b) a PDF (with QR codes), or + (c) a series of screens with QR codes. + +Wallets may only implement some of the above options due to resource +constraints. + +The documents should encode the taxpayer ID, the amount and the DONAU +signature (including the year, excluding the exact public key as there should +only be one possible). + + +Rationing (future work) +----------------------- + +If per-capita rationing must be imposed on certain transactions, a rationing +authority (RA) must exist that identifies each eligible human and issues that +human a number of ration coins for the respective rationing period. An RA +largely functions like a regular exchange, except that eligible humans will +need to authenticate directly to withdraw rations (instead of transferring +fiat to an exchange). Merchants selling rationed goods will be (legally) +required to collect deposit confirmations in proportion to the amount of +rationed goods sold. A difference to regular exchanges is that RAs do not +charge any fees. RAs may or may not allow refreshing rations that are about +to expire for ration coins in the next period. + +Once an RA is added to a wallet, it should automatically try to withdraw the +maximum amount of ration coins it is eligible for. Available rations should be +shown below the subscriptions by RA (if any). + + ..note:: + + RAs are considered an idea for future work and not part of our current timeline. + + +Limited Donations per Capita (future work) +------------------------------------------ + +If per-capita limitations must be imposed on anonymous donations (for example +for donations to political parties), an RA can be used to issue donation +rations that limit the amount of donations that can be made for the respective +period. + + ..note:: + + RAs are considered an idea for future work and not part of our current timeline. + + Definition of Done ================== @@ -427,6 +667,7 @@ Definition of Done - Bachelor thesis written on applications and design - Academic paper written on DONAU (requirements, design, implementation) - DONAU implemented, documented + - DONAU receipt validation application implemented - Integration tests exist in wallet-core - Deliverables accepted by EC @@ -436,6 +677,7 @@ Alternatives None. + Drawbacks =========