From 7214412a05e38b8b957257c3ee99d8acb6571179 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Thu, 6 May 2021 15:33:52 +0200 Subject: work on w2w spec --- core/api-exchange.rst | 403 ++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 328 insertions(+), 75 deletions(-) (limited to 'core/api-exchange.rst') diff --git a/core/api-exchange.rst b/core/api-exchange.rst index 654ce31e..27886c24 100644 --- a/core/api-exchange.rst +++ b/core/api-exchange.rst @@ -978,14 +978,12 @@ exchange. advertise those terms of service. -.. http:get:: /reserves/$RESERVE_PUB +.. http:post:: /reserves/$RESERVE_PUB/status Request information about a reserve or an account. **Request:** - *Account-Request-Signature*: The client must provide Base-32 encoded EdDSA signature made with ``$ACCOUNT_PRIV``, affirming its authorization to access the account status. The purpose used MUST be ``TALER_SIGNATURE_ACCOUNT_STATUS`` (NUMBER: TBD). - :query history=BOOLEAN: *Optional.* If specified, the exchange will return the recent account history. This is still free of charge. @@ -993,6 +991,8 @@ exchange. the exchange will return the full account history. This may incur a fee that will be charged to the account. + The request body must be a `ReserveStatusRequest` object. + **Response:** :http:statuscode:`200 OK`: @@ -1005,6 +1005,14 @@ exchange. **Details:** + .. ts:def:: ReserveStatusRequest + + interface ReserveStatusRequest { + // Signature of type + // TALER_SIGNATURE_RESERVE_STATUS_REQUEST + reserve_sig: EddsaSignature; + } + .. ts:def:: ReserveStatus interface ReserveStatus { @@ -1020,6 +1028,7 @@ exchange. kyc_required: boolean; // Transaction history for this reserve. + // May be partial (!). history: TransactionHistoryItem[]; } @@ -1030,29 +1039,84 @@ exchange. // Union discriminated by the "type" field. type TransactionHistoryItem = | AccountMergeTransaction + | AccountSetupTransaction + | ReserveHistoryTransaction | ReserveWithdrawTransaction | ReserveCreditTransaction | ReserveClosingTransaction | ReserveRecoupTransaction; + .. ts:def:: AccountHistoryTransaction + + interface AccountHistoryTransaction { + type: "HISTORY"; + + // Fee agreed to by the reserve owner. + history_fee: Amount; + + // Time when the request was made. + request_timestamp: Timestamp; + + // Signature created with the reserve's private key. + // Must be of purpose TALER_SIGNATURE_RESERVE_HISTORY_REQUEST. + reserve_sig: EddsaSignature; + + } + + .. ts:def:: AccountSetupTransaction + + interface AccountSetupTransaction { + type: "SETUP"; + + // KYC fee agreed to by the reserve owner. + kyc_fee: Amount; + + // Time when the KYC was triggered. + kyc_timestamp: Timestamp; + + // Hash of the wire details of the account. + // Note that this hash is unsalted and potentially + // private (as it could be inverted), hence access + // to this endpoint must be authorized using the + // private key of the reserve. + h_wire: HashCode; + + // Signature created with the reserve's private key. + // Must be of purpose TALER_SIGNATURE_ACCOUNT_SETUP_REQUEST. + reserve_sig: EddsaSignature; + + } + .. ts:def:: AccountMergeTransaction interface AccountMergeTransaction { type: "MERGE"; - // Amount merged (what was left after fees). + // Actual amount merged (what was left after fees). amount: Amount; + // Minimum amount merged (amount signed by the + // reserve and purse signatures). + minimum_amount: Amount; + // Purse that was merged. purse_pub: EddsaPublicKey; + // Time of the merge. + merge_timestamp: Timestamp; + + // Expiration time of the purse. + purse_expiration: Timestamp; + // Hash of the contract. h_contract: HashCode; - // Signature created with the account's private key. - account_sig: EddsaSignature; + // Signature created with the reserve's private key. + // Must be of purpose TALER_SIGNATURE_ACCOUNT_MERGE. + reserve_sig: EddsaSignature; // Signature created with the purse's private key. + // Must be of purpose TALER_SIGNATURE_PURSE_MERGE. purse_sig: EddsaSignature; // Deposit fees that were charged to the purse. @@ -1155,6 +1219,46 @@ exchange. coin_pub: CoinPublicKey; } + +.. http:post:: /reserves/$RESERVE_PUB/history + + Request information about the full history of + a reserve or an account. + + **Request:** + + The request body must be a `ReserveHistoryRequest` object. + + **Response:** + + :http:statuscode:`200 OK`: + The exchange responds with a `ReserveStatus` object; the reserve was known to the exchange. + :http:statuscode:`401 Unauthorized`: + The *Account-Request-Signature* is invalid. + This response comes with a standard `ErrorDetail` response. + :http:statuscode:`404 Not found`: + The reserve key does not belong to a reserve known to the exchange. + :http:statuscode:`412 Precondition failed`: + The balance in the reserve is insufficient to pay for the history request. + This response comes with a standard `ErrorDetail` response. + + **Details:** + + .. ts:def:: ReserveHistoryRequest + + interface ReserveHistoryRequest { + // Signature of type + // TALER_SIGNATURE_RESERVE_HISTORY_REQUEST + reserve_sig: EddsaSignature; + + // Time when the client made the request. + // Timestamp must be reasonably close to the time of + // the exchange, otherwise the exchange may reject + // the request. + request_timestamp: Timestamp; + } + + .. http:post:: /reserves/$RESERVE_PUB/withdraw Withdraw a coin of the specified denomination. Note that the client should @@ -1450,101 +1554,244 @@ denomination. .. ts:def:: CoinSpendHistoryItem - interface CoinSpendHistoryItem { - // Either "DEPOSIT", "MELT", "REFUND", "RECOUP", - // "OLD-COIN-RECOUP" or "RECOUP-REFRESH". - type: string; + // Union discriminated by the "type" field. + type CoinSpendHistoryItem = + | CoinDepositTransaction + | CoinMeltTransaction + | CoinRefundTransaction + | CoinRecoupTransaction + | CoinOldCoinRecoupTransaction + | CoinRecoupRefreshTransaction + | CoinPursePaymentTransaction; + + + .. ts:def:: CoinDepositTransaction + + interface CoinDepositTransaction { + type: "DEPOSIT"; // The total amount of the coin's value absorbed (or restored in the // case of a refund) by this transaction. - // Note that for deposit and melt this means the amount given includes - // the transaction fee, while for refunds the amount given excludes - // the transaction fee. The current coin value can thus be computed by - // subtracting deposit and melt amounts and adding refund amounts from - // the coin's denomination value. + // The amount given includes + // the deposit fee. The current coin value can thus be computed by + // subtracting this amount. amount: Amount; - // Deposit fee in case of type "DEPOSIT". + // Deposit fee. deposit_fee: Amount; - // Public key of the merchant, for "DEPOSIT" operations. - merchant_pub?: EddsaPublicKey; + // Public key of the merchant. + merchant_pub: EddsaPublicKey; // Date when the operation was made. - // Only for "DEPOSIT", "RECOUP", "OLD-COIN-RECOUP" and - // "RECOUP-REFRESH" operations. - timestamp?: Timestamp; + timestamp: Timestamp; // Date until which the merchant can issue a refund to the customer via the - // exchange, possibly zero if refunds are not allowed. Only for "DEPOSIT" operations. - refund_deadline?: Timestamp; + // exchange, possibly zero if refunds are not allowed. + refund_deadline: Timestamp; - // Signature by the coin, only present if ``type`` is "DEPOSIT", "MELT", "RECOUP", - // or "RECOUP-REFRESH". - coin_sig?: EddsaSignature; + // Signature by the coin. + coin_sig: EddsaSignature; - // Deposit fee in case of type "MELT". - melt_fee: Amount; + // Hash of the bank account from where we received the funds. + h_wire: HashCode; - // Commitment from the melt operation, only for "MELT". - rc?: TALER_RefreshCommitmentP; + // Hash of the public denomination key used to sign the coin. + // FIXME: why do we care to have this? + h_denom_pub: HashCode; + + // Hash over the proposal data of the contract that + // is being paid. + h_contract_terms: HashCode; + + } + + .. ts:def:: CoinMeltTransaction + + interface CoinMeltTransaction { + type: "MELT"; + + // The total amount of the coin's value absorbed by this transaction. + // Note that for melt this means the amount given includes + // the melt fee. The current coin value can thus be computed by + // subtracting the amounts. + amount: Amount; + + // Signature by the coin. + coin_sig: EddsaSignature; + + // Melt fee. + melt_fee: Amount; - // Hash of the bank account from where we received the funds, - // only present if ``type`` is "DEPOSIT". - h_wire?: HashCode; + // Commitment from the melt operation. + rc: TALER_RefreshCommitmentP; // Hash of the public denomination key used to sign the coin. - // only present if ``type`` is "DEPOSIT", "RECOUP", - // "RECOUP-REFRESH", or "MELT". - h_denom_pub?: HashCode; + // FIXME: why do we care to have this? + h_denom_pub: HashCode; - // Deposit fee in case of type "REFUND". - refund_fee?: Amount; + } - // Hash over the proposal data of the contract that - // is being paid (if type is "DEPOSIT") or refunded (if - // ``type`` is "REFUND"); otherwise absent. - h_contract_terms?: HashCode; + .. ts:def:: CoinRefundTransaction - // Refund transaction ID. Only present if ``type`` is - // "REFUND". - rtransaction_id?: Integer; + interface CoinRefundTransaction { + type: "REFUND"; - // Coin blinding key. Only present if ``type`` is - // "RECOUP" or "RECOUP-REFRESH". - coin_blind?: DenominationBlindingKeyP; + // The total amount of the coin's value restored + // by this transaction. + // The amount given excludes the transaction fee. + // The current coin value can thus be computed by + // adding the amounts to the coin's denomination value. + amount: Amount; - // Reserve receiving the recoup. Only present if ``type`` is - // "RECOUP". - reserve_pub?: EddsaPublicKey; + // Refund fee in case of type "REFUND". + refund_fee: Amount; + + // Hash over the proposal data of the contract that + // is being refunded. + h_contract_terms: HashCode; + + // Refund transaction ID. + rtransaction_id: Integer; // `EdDSA Signature ` authorizing the REFUND. Made with // the `public key of the merchant `. - // Only present if ``type`` is "REFUND". - merchant_sig?: EddsaSignature; + merchant_sig: EddsaSignature; + + } + + .. ts:def:: CoinRecoupTransaction + + interface CoinRecoupTransaction { + type: "RECOUP"; + + // The total amount of the coin's value absorbed + // by this transaction. + // The current coin value can thus be computed by + // subtracting the amount from + // the coin's denomination value. + amount: Amount; + + // Date when the operation was made. + timestamp: Timestamp; + + // Signature by the coin. + coin_sig: EddsaSignature; + + // Hash of the public denomination key used to sign the coin. + // FIXME: why do we care to have this? + h_denom_pub: HashCode; + + // Coin blinding key. + coin_blind: DenominationBlindingKeyP; + + // Reserve receiving the recoup. + reserve_pub: EddsaPublicKey; + + // Signature by the exchange, must be + // of type TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP. + exchange_sig: EddsaSignature; + + // Public key used to sign ``exchange_sig`` + exchange_pub: EddsaPublicKey; + + } + + .. ts:def:: CoinOldCoinRecoupTransaction + + interface CoinOldCoinRecoupTransaction { + type: "OLD-COIN-RECOUP"; + + // The total amount of the coin's value restored + // by this transaction. + // The current coin value can thus be computed by + // adding the amount to the coin's denomination value. + amount: Amount; + + // Date when the operation was made. + timestamp: Timestamp; + + // Signature by the exchange + // of type TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP_REFRESH. + exchange_sig: EddsaSignature; + + // Public key used to sign ``exchange_sig``, + exchange_pub: EddsaPublicKey; + + } + + .. ts:def:: CoinRecoupRefreshTransaction + + interface CoinRecoupRefreshTransaction { + type: "RECOUP-REFRESH"; + + // The total amount of the coin's value absorbed + // by this transaction. + // The current coin value can thus be computed by + // subtracting this amounts from + // the coin's denomination value. + amount: Amount; - // Public key of the reserve that will receive the funds, for "RECOUP" operations. - reserve_pub?: EddsaPublicKey; + // Date when the operation was made. + timestamp: Timestamp; + + // Signature by the coin. + coin_sig: EddsaSignature; - // Signature by the exchange, only present if ``type`` is "RECOUP", - // "OLD-COIN-RECOUP" or "RECOUP-REFRESH". Signature is - // of type TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP for "RECOUP", - // and of type TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP_REFRESH otherwise. - exchange_sig?: EddsaSignature; + // Hash of the public denomination key used to sign the coin. + // FIXME: why do we care to have this? + h_denom_pub: HashCode; + + // Coin blinding key. + coin_blind: DenominationBlindingKeyP; + + // Signature by the exchange + // of type TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP_REFRESH. + exchange_sig: EddsaSignature; // Public key used to sign ``exchange_sig``, - // only present if ``exchange_sig`` present. - exchange_pub?: EddsaPublicKey; + exchange_pub: EddsaPublicKey; - // Blinding factor of the revoked new coin, - // only present if ``type`` is "REFRESH_RECOUP". + // Blinding factor of the revoked new coin. new_coin_blinding_secret: RsaBlindingKeySecret; - // Blinded public key of the revoked new coin, - // only present if ``type`` is "REFRESH_RECOUP". + // Blinded public key of the revoked new coin. new_coin_ev: RsaBlindingKeySecret; } + .. ts:def:: CoinPursePaymentTransaction + + interface CoinPursePaymentTransaction { + type: "PURSE_PAYMENT"; + + // The total amount of the coin's value absorbed + // by this transaction. + // Note that this means the amount given includes + // the deposit fee. The current coin value can thus be computed by + // subtracting the amount from + // the coin's denomination value. + amount: Amount; + + // Deposit fee. + deposit_fee: Amount; + + // Public key of the purse. + purse_pub: EddsaPublicKey; + + // Date when the purse was set to expire. + purse_expiration: Timestamp; + + // Signature by the coin. + coin_sig: EddsaSignature; + + // Hash of the public denomination key used to sign the coin. + // FIXME: why do we care to have this? + h_denom_pub: HashCode; + + } + + + ---------- Refreshing ---------- @@ -2185,12 +2432,12 @@ Wallet-to-wallet transfers TODO for the spec: - * Update coin history replies to include purse actions: - - TALER_SIGNATURE_PURSE_PAYMENT! - * Update reserve history replies to include merge & kyc actions: - - TALER_SIGNATURE_ACCOUNT_MERGE - - TALER_SIGNATURE_ACCOUNT_SETUP_REQUEST + * add reserve history requests (with fee!) + to reserve history (changes balance!) * specify new database schema at exchange (add SQL to DD13!) + - something for in-progress kyc vs. completed kyc? + => add kyc_date to reserves? + => or have separate KYC table instead of NULLs in reserves! * update wire transfer API to enable WAD IDs (and while we are at it, should probably also write extended version to allow _merchants_ to query for their inbound transfers, so spec @@ -2544,6 +2791,12 @@ Discussion: // Must be of purpose TALER_SIGNATURE_PURSE_MERGE. purse_sig: EddsaSignature; + // Minimum amount that must be credited to the reserve, that is + // the total value of the purse minus the deposit fees. + // If the deposit fees are lower, the contribution to the + // reserve can be higher! + minimum_amount_contributed: Amount; + // SHA-512 hash of the contact of the purse. h_contract_terms: HashCode; @@ -2677,10 +2930,10 @@ Discussion: // this is a ``Bad Request`` (HTTP status 400). payto_uri: string; - // EdDSA signature of the account affirming the request + // EdDSA signature of the reserve affirming the request // to create the account, must be of purpose // TALER_SIGNATURE_ACCOUNT_SETUP_REQUEST - account_sig: EddsaPublicKey; + reserve_sig: EddsaPublicKey; } @@ -2787,9 +3040,9 @@ wallet-to-wallet payments. Only another exchange should access this endpoint. // Client-side timestamp of when the merge request was made. merge_timestamp: Timestamp; - // Signature created with the account's private key. + // Signature created with the reserve's private key. // Must be of purpose TALER_SIGNATURE_ACCOUNT_MERGE - account_sig: EddsaSignature; + reserve_sig: EddsaSignature; // Signature created with the purse's private key. // Must be of purpose TALER_SIGNATURE_PURSE_MERGE -- cgit v1.2.3