taler-docs

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

get-keys.rst (22651B)


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