taler-docs

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

get-keys.rst (23368B)


      1 .. http:get:: /keys
      2 
      3   Get a list of all denomination keys offered by the exchange,
      4   as well as the exchange's current online signing key.
      5 
      6   **Request:**
      7 
      8   :query last_issue_date: Optional argument specifying the maximum value of any of the ``stamp_start`` members of the denomination keys of a ``/keys`` response that is already known to the client. Allows the exchange to only return keys that have changed since that timestamp.  The given value must be an unsigned 64-bit integer representing seconds after 1970.  If the timestamp does not exactly match the ``stamp_start`` of one of the denomination keys, all keys are returned.
      9 
     10   **Response:**
     11 
     12   :http:statuscode:`200 OK`:
     13     The exchange responds with a `ExchangeKeysResponse` object. This request should
     14     virtually always be successful. It only fails if the exchange is misconfigured or
     15     has not yet been provisioned with key signatures via ``taler-exchange-offline``.
     16   :http:statuscode:`400 Bad Request`:
     17     A query parameter is malformed.
     18     This response comes with a standard `ErrorDetail` response with
     19     a code of ``TALER_EC_GENERIC_PARAMETER_MALFORMED``.
     20   :http:statuscode:`502 Bad Gateway`:
     21     A denomination or signing key helper is unavailable.
     22     This response comes with a standard `ErrorDetail` response with
     23     a code of ``TALER_EC_EXCHANGE_DENOMINATION_HELPER_UNAVAILABLE`` or
     24     ``TALER_EC_EXCHANGE_SIGNKEY_HELPER_UNAVAILABLE``.
     25   :http:statuscode:`503 Service Unavailable`:
     26     The exchange has no valid denomination keys available.
     27     This response comes with a standard `ErrorDetail` response with
     28     a code of ``TALER_EC_EXCHANGE_GENERIC_KEYS_MISSING``.
     29 
     30   **Details:**
     31 
     32   .. ts:def:: ExchangeKeysResponse
     33 
     34     interface ExchangeKeysResponse {
     35       // libtool-style representation of the Exchange protocol version, see
     36       // https://www.gnu.org/software/libtool/manual/html_node/Versioning.html#Versioning
     37       // The format is "current:revision:age".
     38       version: string;
     39 
     40       // The exchange's base URL.
     41       base_url: string;
     42 
     43       // The exchange's currency or asset unit.
     44       currency: string;
     45 
     46       // Shopping URL where users may find shops that accept
     47       // digital cash issued by this exchange.
     48       // @since protocol **v21**.
     49       shopping_url?: string;
     50 
     51       // Instructs wallets to use certain bank-specific
     52       // language (for buttons) and/or other UI/UX customization
     53       // for compliance with the rules of that bank.
     54       // The specific customizations to apply are done on a per-wallet
     55       // basis as requested by the specific bank. They only
     56       // apply when it is clear that the wallet is using digital
     57       // cash from that bank.  This is an advisory option, not
     58       // all wallets must support all compliance languages.
     59       // @since protocol **v24**.
     60       bank_compliance_language?: string;
     61 
     62       // How wallets should render this currency.
     63       currency_specification: CurrencySpecification;
     64 
     65       // Small(est?) amount that can likely be transferred to
     66       // the exchange. Should be the default amount for KYC
     67       // authentication wire transfers to this exchange.
     68       // @since protocol **v21**. Mandatory since **v33**.
     69       tiny_amount?: Amount;
     70 
     71       // Absolute cost offset for the STEFAN curve used
     72       // to (over) approximate fees payable by amount.
     73       stefan_abs: Amount;
     74 
     75       // Factor to multiply the logarithm of the amount
     76       // with to (over) approximate fees payable by amount.
     77       // Note that the total to be paid is first to be
     78       // divided by the smallest denomination to obtain
     79       // the value that the logarithm is to be taken of.
     80       stefan_log: Amount;
     81 
     82       // Linear cost factor for the STEFAN curve used
     83       // to (over) approximate fees payable by amount.
     84       //
     85       // Note that this is a scalar, as it is multiplied
     86       // with the actual amount.
     87       stefan_lin: Float;
     88 
     89       // Type of the asset. "fiat", "crypto", "regional"
     90       // or "stock".  Wallets should adjust their UI/UX
     91       // based on this value.
     92       asset_type: string;
     93 
     94       // Array of wire accounts operated by the exchange for
     95       // incoming wire transfers.
     96       accounts: ExchangeWireAccount[];
     97 
     98       // Object mapping names of wire methods (i.e. "iban" or "x-taler-bank")
     99       // to wire fees.
    100       wire_fees: { method : AggregateTransferFee[] };
    101 
    102       // List of exchanges that this exchange is partnering
    103       // with to enable wallet-to-wallet transfers.
    104       wads: ExchangePartnerListEntry[];
    105 
    106       // Set to true if this exchange allows the use
    107       // of reserves for rewards.
    108       // @deprecated in protocol **v18**.
    109       rewards_allowed: false;
    110 
    111       // Set to true if this exchange has KYC enabled and thus
    112       // requires KYC auth wire transfers prior to a first deposit.
    113       // @since in protocol **v24**.
    114       kyc_enabled: boolean;
    115 
    116       // Set to TRUE if wallets should disable the direct deposit feature
    117       // and deposits should only go via Taler merchant APIs.
    118       // Mainly used for regional currency and event currency deployments
    119       // where wallets are not eligible to deposit back into originating
    120       // bank accounts and, because KYC is not enabled, wallets are thus
    121       // likely to send money to nirvana instead of where users want it.
    122       // @since in protocol **v30**.
    123       disable_direct_deposit: boolean;
    124 
    125       // EdDSA master public key of the exchange, used to sign entries
    126       // in ``denoms`` and ``signkeys``.
    127       master_public_key: EddsaPublicKey;
    128 
    129       // Relative duration until inactive reserves are closed;
    130       // not signed (!), can change without notice.
    131       reserve_closing_delay: RelativeTime;
    132 
    133       // Threshold amounts beyond which wallet should
    134       // trigger the KYC process of the issuing exchange.
    135       // Optional option, if not given there is no limit.
    136       // Currency must match ``currency``.
    137       wallet_balance_limit_without_kyc?: Amount[];
    138 
    139       // Array of limits that apply to all accounts.
    140       // All of the given limits will be hard limits.
    141       // Wallets and merchants are expected to obey them
    142       // and not even allow the user to cross them.
    143       // @since protocol **v21**.
    144       hard_limits: AccountLimit[];
    145 
    146       // Array of limits with a soft threshold of zero
    147       // that apply to all accounts without KYC.
    148       // Wallets and merchants are expected to trigger
    149       // a KYC process before attempting any zero-limited
    150       // operations.
    151       // @since protocol **v21**.
    152       zero_limits: ZeroLimitedOperation[];
    153 
    154       // Denominations offered by this exchange
    155       denominations: DenomGroup[];
    156 
    157       // Compact EdDSA `signature` (binary-only) over the
    158       // contatentation of all of the master_sigs (in reverse
    159       // chronological order by group) in the arrays under
    160       // "denominations".  Signature of `TALER_ExchangeKeySetPS`
    161       exchange_sig: EddsaSignature;
    162 
    163       // Public EdDSA key of the exchange that was used to generate the signature.
    164       // Should match one of the exchange's signing keys from ``signkeys``.  It is given
    165       // explicitly as the client might otherwise be confused by clock skew as to
    166       // which signing key was used for the ``exchange_sig``.
    167       exchange_pub: EddsaPublicKey;
    168 
    169       // Denominations for which the exchange currently offers/requests recoup.
    170       recoup: RecoupDenoms[];
    171 
    172       // Array of globally applicable fees by time range.
    173       global_fees: GlobalFees[];
    174 
    175       // The date when the denomination keys were last updated.
    176       list_issue_date: Timestamp;
    177 
    178       // Auditors of the exchange.
    179       auditors: AuditorKeys[];
    180 
    181       // The exchange's signing keys.
    182       signkeys: SignKey[];
    183 
    184       // Optional field with a dictionary of (name, object) pairs defining the
    185       // supported and enabled extensions, such as ``age_restriction``.
    186       extensions?: { name: ExtensionManifest };
    187 
    188       // Signature by the exchange master key of the SHA-256 hash of the
    189       // normalized JSON-object of field extensions, if it was set.
    190       // The signature has purpose TALER_SIGNATURE_MASTER_EXTENSIONS.
    191       extensions_sig?: EddsaSignature;
    192 
    193     }
    194 
    195   The specification for the account object is:
    196 
    197   .. ts:def:: ExchangeWireAccount
    198 
    199     interface ExchangeWireAccount {
    200       // Full ``payto://`` URI identifying the account and wire method
    201       payto_uri: string;
    202 
    203       // URI to convert amounts from or to the currency used by
    204       // this wire account of the exchange. Missing if no
    205       // conversion is applicable.
    206       conversion_url?: string;
    207 
    208       // Open banking gateway base URL where wallets can
    209       // initiate wire transfers to withdraw
    210       // digital cash from this exchange.
    211       // @since protocol **v34**.
    212       open_banking_gateway?: string;
    213 
    214       // Wire transfer gateway base URL where wallets and merchants can
    215       // request (short) wire transfer subjects to wire funds to this
    216       // exchange without having to encode the full public key.
    217       // @since protocol **v34**.
    218       wire_transfer_gateway?: string;
    219 
    220       // Restrictions that apply to bank accounts that would send
    221       // funds to the exchange (crediting this exchange bank account).
    222       // Optional, empty array for unrestricted.
    223       credit_restrictions: AccountRestriction[];
    224 
    225       // Restrictions that apply to bank accounts that would receive
    226       // funds from the exchange (debiting this exchange bank account).
    227       // Optional, empty array for unrestricted.
    228       debit_restrictions: AccountRestriction[];
    229 
    230       // Signature using the exchange's offline key over
    231       // a `TALER_MasterWireDetailsPS`
    232       // with purpose ``TALER_SIGNATURE_MASTER_WIRE_DETAILS``.
    233       master_sig: EddsaSignature;
    234 
    235       // Display label wallets should use to show this
    236       // bank account.
    237       // @since protocol **v19**.
    238       bank_label?: string;
    239 
    240       // *Signed* integer with the display priority for
    241       // this bank account. Optional, 0 if missing.
    242       // @since protocol **v19**.
    243       priority?: Integer;
    244 
    245     }
    246 
    247   .. ts:def:: AccountRestriction
    248 
    249     type AccountRestriction =
    250       | RegexAccountRestriction
    251       | DenyAllAccountRestriction
    252 
    253   .. ts:def:: DenyAllAccountRestriction
    254 
    255     // Account restriction that disables this type of
    256     // account for the indicated operation categorically.
    257     interface DenyAllAccountRestriction {
    258 
    259       type: "deny";
    260     }
    261 
    262   .. ts:def:: RegexAccountRestriction
    263 
    264     // Accounts interacting with this type of account
    265     // restriction must have a normalized payto://-URI matching
    266     // the given regex.
    267     interface RegexAccountRestriction {
    268 
    269       type: "regex";
    270 
    271       // Regular expression that the payto://-URI of the
    272       // partner account must follow.  The regular expression
    273       // should follow posix-egrep, but without support for character
    274       // classes, GNU extensions, back-references or intervals. See
    275       // https://www.gnu.org/software/findutils/manual/html_node/find_html/posix_002degrep-regular-expression-syntax.html
    276       // for a description of the posix-egrep syntax. Applications
    277       // may support regexes with additional features, but exchanges
    278       // must not use such regexes.
    279       payto_regex: string;
    280 
    281       // Hint for a human to understand the restriction
    282       // (that is hopefully easier to comprehend than the regex itself).
    283       human_hint: string;
    284 
    285       // Map from IETF BCP 47 language tags to localized
    286       // human hints.
    287       human_hint_i18n?: { [lang_tag: string]: string };
    288 
    289     }
    290 
    291   .. ts:def:: ZeroLimitedOperation
    292 
    293     interface ZeroLimitedOperation {
    294 
    295       // Operation that is limited to an amount of
    296       // zero until the client has passed some KYC check.
    297       // Must be one of "WITHDRAW", "DEPOSIT",
    298       // (p2p) "MERGE", (wallet) "BALANCE",
    299       // (reserve) "CLOSE", "AGGREGATE",
    300       // "TRANSACTION" or "REFUND".
    301       operation_type: string;
    302 
    303     }
    304 
    305 
    306   .. ts:def:: AccountLimit
    307 
    308     interface AccountLimit {
    309 
    310       // Operation that is limited.
    311       // Must be one of "WITHDRAW", "DEPOSIT",
    312       // (p2p) "MERGE", (wallet) "BALANCE",
    313       // (reserve) "CLOSE", "AGGREGATE",
    314       // "TRANSACTION" or "REFUND".
    315       operation_type: string;
    316 
    317       // Timeframe during which the limit applies.
    318       // Not applicable for all operation_types
    319       // (but always present in this object anyway).
    320       timeframe: RelativeTime;
    321 
    322       // Maximum amount allowed during the given timeframe.
    323       // Zero if the operation is simply forbidden.
    324       threshold: Amount;
    325 
    326       // True if this is a soft limit that could be raised
    327       // by passing KYC checks.  Clients *may* deliberately
    328       // try to cross limits and trigger measures resulting
    329       // in 451 responses to begin KYC processes.
    330       // Clients that are aware of hard limits *should*
    331       // inform users about the hard limit and prevent flows
    332       // in the UI that would cause violations of hard limits.
    333       // Made optional in **v21** with a default of 'false' if missing.
    334       soft_limit?: boolean;
    335     }
    336 
    337   .. ts:def:: GlobalFees
    338 
    339     interface GlobalFees {
    340 
    341       // What date (inclusive) does these fees go into effect?
    342       start_date: Timestamp;
    343 
    344       // What date (exclusive) does this fees stop going into effect?
    345       end_date: Timestamp;
    346 
    347       // Account history fee, charged when a user wants to
    348       // obtain a reserve/account history.
    349       history_fee: Amount;
    350 
    351       // Annual fee charged for having an open account at the
    352       // exchange.  Charged to the account.  If the account
    353       // balance is insufficient to cover this fee, the account
    354       // is automatically deleted/closed. (Note that the exchange
    355       // will keep the account history around for longer for
    356       // regulatory reasons.)
    357       account_fee: Amount;
    358 
    359       // Purse fee, charged only if a purse is abandoned
    360       // and was not covered by the account limit.
    361       purse_fee: Amount;
    362 
    363       // How long will the exchange preserve the account history?
    364       // After an account was deleted/closed, the exchange will
    365       // retain the account history for legal reasons until this time.
    366       history_expiration: RelativeTime;
    367 
    368       // Non-negative number of concurrent purses that any
    369       // account holder is allowed to create without having
    370       // to pay the purse_fee.
    371       purse_account_limit: Integer;
    372 
    373       // How long does an exchange keep a purse around after a purse
    374       // has expired (or been successfully merged)?  A 'GET' request
    375       // for a purse will succeed until the purse expiration time
    376       // plus this value.
    377       purse_timeout: RelativeTime;
    378 
    379       // Signature of `TALER_GlobalFeesPS`.
    380       master_sig: EddsaSignature;
    381 
    382     }
    383 
    384   .. ts:def:: DenomGroup
    385 
    386     type DenomGroup =
    387       | DenomGroupRsa
    388       | DenomGroupCs
    389       | DenomGroupRsaAgeRestricted
    390       | DenomGroupCsAgeRestricted;
    391 
    392   .. ts:def:: DenomGroupRsa
    393 
    394     interface DenomGroupRsa extends DenomGroupCommon {
    395       cipher: "RSA";
    396 
    397       denoms: ({
    398         rsa_pub: RsaPublicKey;
    399       } & DenomCommon)[];
    400     }
    401 
    402   .. ts:def:: DenomGroupCs
    403 
    404     interface DenomGroupCs extends DenomGroupCommon {
    405       cipher: "CS";
    406 
    407       denoms: ({
    408         cs_pub: Cs25519Point;
    409       } & DenomCommon)[];
    410     }
    411 
    412   .. ts:def:: DenomGroupRsaAgeRestricted
    413 
    414     interface DenomGroupRsaAgeRestricted extends DenomGroupCommon {
    415       cipher: "RSA+age_restricted";
    416       age_mask: AgeMask;
    417 
    418       denoms: ({
    419         rsa_pub: RsaPublicKey;
    420       } & DenomCommon)[];
    421     }
    422 
    423   .. ts:def:: DenomGroupCsAgeRestricted
    424 
    425     interface DenomGroupCsAgeRestricted extends DenomGroupCommon {
    426       cipher: "CS+age_restricted";
    427       age_mask: AgeMask;
    428 
    429       denoms: ({
    430         cs_pub: Cs25519Point;
    431       } & DenomCommon)[];
    432     }
    433 
    434   .. ts:def:: DenomGroupCommon
    435 
    436     // Common attributes for all denomination groups
    437     interface DenomGroupCommon {
    438       // How much are coins of this denomination worth?
    439       value: Amount;
    440 
    441       // Fee charged by the exchange for withdrawing a coin of this denomination.
    442       fee_withdraw: Amount;
    443 
    444       // Fee charged by the exchange for depositing a coin of this denomination.
    445       fee_deposit: Amount;
    446 
    447       // Fee charged by the exchange for refreshing a coin of this denomination.
    448       fee_refresh: Amount;
    449 
    450       // Fee charged by the exchange for refunding a coin of this denomination.
    451       fee_refund: Amount;
    452 
    453     }
    454 
    455   .. ts:def:: DenomCommon
    456 
    457     interface DenomCommon {
    458       // Signature of `TALER_DenominationKeyValidityPS`.
    459       master_sig: EddsaSignature;
    460 
    461       // When does the denomination key become valid?
    462       stamp_start: Timestamp;
    463 
    464       // When is it no longer possible to withdraw coins
    465       // of this denomination? Note that while this option
    466       // is given per denomination, all concurrently active
    467       // denominations (of the same cipher type)
    468       // will have exactly the same withdraw
    469       // expiration time. Thus, the wallet can be sure what
    470       // is the smallest denomination being offered at any
    471       // particular point in time, and not worry about the
    472       // exchange having merely failed to sign the key of
    473       // only the smallest denomination unit.
    474       stamp_expire_withdraw: Timestamp;
    475 
    476       // When is it no longer possible to deposit coins
    477       // of this denomination?
    478       stamp_expire_deposit: Timestamp;
    479 
    480       // Timestamp indicating by when legal disputes relating to these coins must
    481       // be settled, as the exchange will afterwards destroy its evidence relating to
    482       // transactions involving this coin.
    483       stamp_expire_legal: Timestamp;
    484 
    485       // Set to 'true' if the exchange somehow "lost"
    486       // the private key. The denomination was not
    487       // necessarily revoked, but still cannot be used
    488       // to withdraw coins at this time (theoretically,
    489       // the private key could be recovered in the
    490       // future; coins signed with the private key
    491       // remain valid).
    492       lost?: boolean;
    493     }
    494 
    495   Fees for any of the operations can be zero, but the fields must still be
    496   present. The currency of the ``fee_deposit``, ``fee_refresh`` and ``fee_refund`` must match the
    497   currency of the ``value``.  Theoretically, the ``fee_withdraw`` could be in a
    498   different currency, but this is not currently supported by the
    499   implementation.
    500 
    501   .. ts:def:: RecoupDenoms
    502 
    503     interface RecoupDenoms {
    504       // Hash of the public key of the denomination that is being revoked under
    505       // emergency protocol (see ``/recoup``).
    506       h_denom_pub: HashCode;
    507 
    508       // We do not include any signature here, as the primary use-case for
    509       // this emergency involves the exchange having lost its signing keys,
    510       // so such a signature here would be pretty worthless.  However, the
    511       // exchange will not honor ``/recoup`` requests unless they are for
    512       // denomination keys listed here.
    513     }
    514 
    515   A signing key in the ``signkeys`` list is a JSON object with the following fields:
    516 
    517   .. ts:def:: SignKey
    518 
    519     interface SignKey {
    520       // The actual exchange's EdDSA signing public key.
    521       key: EddsaPublicKey;
    522 
    523       // Initial validity date for the signing key.
    524       stamp_start: Timestamp;
    525 
    526       // Date when the exchange will stop using the signing key, allowed to overlap
    527       // slightly with the next signing key's validity to allow for clock skew.
    528       stamp_expire: Timestamp;
    529 
    530       // Date when all signatures made by the signing key expire and should
    531       // henceforth no longer be considered valid in legal disputes.
    532       stamp_end: Timestamp;
    533 
    534       // Signature over ``key`` and ``stamp_expire`` by the exchange master key.
    535       // Signature of `TALER_ExchangeSigningKeyValidityPS`.
    536       // Must have purpose ``TALER_SIGNATURE_MASTER_SIGNING_KEY_VALIDITY``.
    537       master_sig: EddsaSignature;
    538     }
    539 
    540   An entry in the ``auditors`` list is a JSON object with the following fields:
    541 
    542   .. ts:def:: AuditorKeys
    543 
    544     interface AuditorKeys {
    545       // The auditor's EdDSA signing public key.
    546       auditor_pub: EddsaPublicKey;
    547 
    548       // The auditor's URL.
    549       auditor_url: string;
    550 
    551       // The auditor's name (for humans).
    552       auditor_name: string;
    553 
    554       // An array of denomination keys the auditor affirms with its signature.
    555       // Note that the message only includes the hash of the public key, while the
    556       // signature is actually over the expanded information including expiration
    557       // times and fees.  The exact format is described below.
    558       denomination_keys: AuditorDenominationKey[];
    559     }
    560 
    561   .. ts:def:: AuditorDenominationKey
    562 
    563     interface AuditorDenominationKey {
    564       // Hash of the public RSA key used to sign coins of the respective
    565       // denomination.  Note that the auditor's signature covers more than just
    566       // the hash, but this other information is already provided in ``denoms`` and
    567       // thus not repeated here.
    568       denom_pub_h: HashCode;
    569 
    570       // Signature of `TALER_ExchangeKeyValidityPS`.
    571       auditor_sig: EddsaSignature;
    572     }
    573 
    574   The same auditor may appear multiple times in the array for different subsets
    575   of denomination keys, and the same denomination key hash may be listed
    576   multiple times for the same or different auditors.  The wallet or merchant
    577   just should check that the denomination keys they use are in the set for at
    578   least one of the auditors that they accept.
    579 
    580   .. note::
    581 
    582     Both the individual denominations *and* the denomination list is signed,
    583     allowing customers to prove that they received an inconsistent list.
    584 
    585   Aggregate wire transfer fees representing the fees the exchange
    586   charges per wire transfer to a merchant must be specified as an
    587   array in all wire transfer response objects under ``fees``.  The
    588   respective array contains objects with the following members:
    589 
    590   .. ts:def:: AggregateTransferFee
    591 
    592     interface AggregateTransferFee {
    593       // Per transfer wire transfer fee.
    594       wire_fee: Amount;
    595 
    596       // Per transfer closing fee.
    597       closing_fee: Amount;
    598 
    599       // What date (inclusive) does this fee go into effect?
    600       // The different fees must cover the full time period in which
    601       // any of the denomination keys are valid without overlap.
    602       start_date: Timestamp;
    603 
    604       // What date (exclusive) does this fee stop going into effect?
    605       // The different fees must cover the full time period in which
    606       // any of the denomination keys are valid without overlap.
    607       end_date: Timestamp;
    608 
    609       // Signature of `TALER_MasterWireFeePS` with
    610       // purpose ``TALER_SIGNATURE_MASTER_WIRE_FEES``.
    611       sig: EddsaSignature;
    612     }
    613 
    614   .. ts:def:: ExchangePartnerListEntry
    615 
    616     interface ExchangePartnerListEntry {
    617       // Base URL of the partner exchange.
    618       partner_base_url: string;
    619 
    620       // Public master key of the partner exchange.
    621       partner_master_pub: EddsaPublicKey;
    622 
    623       // Per exchange-to-exchange transfer (wad) fee.
    624       wad_fee: Amount;
    625 
    626       // Exchange-to-exchange wad (wire) transfer frequency.
    627       wad_frequency: RelativeTime;
    628 
    629       // When did this partnership begin (under these conditions)?
    630       start_date: Timestamp;
    631 
    632       // How long is this partnership expected to last?
    633       end_date: Timestamp;
    634 
    635       // Signature using the exchange's offline key over
    636       // `TALER_WadPartnerSignaturePS`
    637       // with purpose ``TALER_SIGNATURE_MASTER_PARTNER_DETAILS``.
    638       master_sig: EddsaSignature;
    639     }