- GET /coins/$COIN_PUB/history#
Obtain the transaction history of a coin. Used only in special cases, like when the exchange claims a double-spending error and the wallet does not believe it. Usually, the wallet knows the transaction history of each coin and thus has no need to inquire.
Request:
- Taler-Coin-History-Signature:
The client MUST provide Base-32 encoded EdDSA signature over a
TALER_SIGNATURE_COIN_HISTORY_REQUESTmade with the respective$COIN_PRIV, affirming desire to download the coin’s transaction history.- If-None-Match:
The client MAY provide an
If-None-Matchheader with an ETag. The client MAY provide anIf-None-Matchheader with an Etag. In that case, the server MUST additionally respond with an304status code in case the coin history matches the provided Etag.
- Query Parameters:
start=OFFSET – Optional. Only return coin history entries with offsets above the given OFFSET. Allows clients to not retrieve history entries they already have.
Response:
- 200 OK:
The coin is known to the exchange and the response is the coin’s transaction history. The response will be a CoinHistoryResponse object.
- 204 No content:
The reserve history is known, but at this point from the given starting point it is empty. Can only happen if OFFSET was positive (and the ETag changed or
If-None-Matchwas not given).- 304 Not modified:
The coin history has not changed since the previous query (detected via Etag in “If-none-match” header).
- 403 Forbidden:
The TALER_SIGNATURE_COIN_HISTORY_REQUEST signature is invalid. This response comes with a standard ErrorDetail response with a code of
TALER_EC_EXCHANGE_COIN_HISTORY_BAD_SIGNATURE.- 404 Not found:
The coin is unknown to the exchange. This response comes with a standard ErrorDetail response with a code of
TALER_EC_EXCHANGE_GENERIC_COIN_UNKNOWN.- 500 Internal Server Error:
The server experienced an internal error. This response comes with a standard ErrorDetail response. Possible error codes include
TALER_EC_GENERIC_DB_FETCH_FAILED,TALER_EC_GENERIC_DB_SOFT_FAILURE, orTALER_EC_GENERIC_JSON_ALLOCATION_FAILURE
Details:
interface CoinHistoryResponse { // Current balance of the coin. balance: Amount; // Hash of the coin's denomination. h_denom_pub: HashCode; // Transaction history for the coin. history: CoinSpendHistoryItem[]; }
// Union discriminated by the "type" field. type CoinSpendHistoryItem = | CoinDepositTransaction | CoinMeltTransaction | CoinRefundTransaction | CoinRecoupWithdrawTransaction | CoinRecoupRefreshTransaction | CoinRecoupRefreshReceiverTransaction | CoinPurseDepositTransaction | CoinPurseRefundTransaction | CoinReserveOpenDepositTransaction;
interface CoinDepositTransaction { type: "DEPOSIT"; // Offset of this entry in the reserve history. // Useful to request incremental histories via // the "start" query parameter. history_offset: Integer; // The total amount of the coin's value absorbed (or restored in the // case of a refund) by this transaction. // The amount given includes // the deposit fee. The current coin value can thus be computed by // subtracting this amount. amount: Amount; // Deposit fee. deposit_fee: Amount; // Public key of the merchant. merchant_pub: EddsaPublicKey; // Date when the operation was made. timestamp: Timestamp; // Date until which the merchant can issue a refund to the customer via the // exchange, possibly zero if refunds are not allowed. refund_deadline?: Timestamp; // Hash over the proposal data of the contract that // is being paid. h_contract_terms: HashCode; // Hash of the bank account from where we received the funds. h_wire: HashCode; // Hash of the public denomination key used to sign the coin. // Needed because 'coin_sig' signs over this, and // that is important to fix the coin's denomination. h_denom_pub: HashCode; // Hash over the deposit policy extension. Optional. h_policy?: HashCode; // Hash over auxiliary wallet data provided by the wallet // to complete the contract. Optional. wallet_data_hash?: HashCode; // Hash over the age commitment of the coin. Optional. h_age_commitment?: HashCode; // Signature over TALER_DepositRequestPS, made by the customer with the // coin's private key. coin_sig: EddsaSignature; }
interface CoinMeltTransaction { type: "MELT"; // Offset of this entry in the reserve history. // Useful to request incremental histories via // the "start" query parameter. history_offset: Integer; // 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; // Melt fee. melt_fee: Amount; // Commitment from the melt operation, see TALER_RefreshCommitmentP rc: HashCode; // Hash of the public denomination key used to sign the old coin. // Needed because 'coin_sig' signs over this, and // that is important to fix the coin's denomination. old_denom_pub_h: HashCode; // Hash over the age commitment of the coin. Optional. old_age_commitment_h?: AgeCommitmentHash; // @since **v32** // This value is opaque to the exchange. It was provided by the client // as part of the original refresh request, and was therefore verified // with the confirm_sig below. // If the reveal step was not performed yet by the old coin owner, // they can use this value and the old coin's private key to derive // all indivual seeds for the n*κ coin candidates for the original // refresh request and replay it refresh_seed: HashCode; // @since **v32** // The kappa*n list of transfer public keys that were provided by the // old coin owner during the melt request. transfer_pubs: EddsaPublicKey[kappa][]; // @since **v32** // The n denomination public keys for the fresh coins // that the coin owner had requested. denoms_h: HashCode[]; // @since **v32** // The noreveal_index value that was returned by the exchange as response // to the melt request. noreveal_index: Integer; // @since **v32** // If the reveal step was successfully peformed by the coin owner, // this field contains the blind coin signatures that were returned // by the exchange for the chosen batch of coins. ev_sigs?: BlindedDenominationSignature[]; // Master seed for the Clause-Schnorr R-value // Present if one of the fresh coin's // denominations is of type Clause-Schnorr. blinding_seed?: BlindingMasterSeed; // Signature by the coin over a // TALER_RefreshMeltCoinAffirmationPS of // purpose TALER_SIGNATURE_WALLET_COIN_MELT. confirm_sig: EddsaSignature; }
interface CoinRefundTransaction { type: "REFUND"; // Offset of this entry in the reserve history. // Useful to request incremental histories via // the "start" query parameter. history_offset: Integer; // 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; // Refund fee. refund_fee: Amount; // Hash over the proposal data of the contract that // is being refunded. h_contract_terms: HashCode; // Public key of the merchant. merchant_pub: EddsaPublicKey; // Refund transaction ID. rtransaction_id: Integer; // EdDSA Signature authorizing the REFUND over a // TALER_MerchantRefundConfirmationPS with // purpose TALER_SIGNATURE_MERCHANT_REFUND_OK. Made with // the public key of the merchant. merchant_sig: EddsaSignature; }
Note
The CoinRecoupWithdrawTransaction interface defintion is WIP. It will be fully specified and implemented with vRECOUP.
// This represents a transaction of a call to /recoup-withdraw // where the coin's residual value has been credited to the // original reserve, from which this coin was withdrawn. interface CoinRecoupWithdrawTransaction { type: "RECOUP-WITHDRAW"; // Offset of this entry in the reserve history. // Useful to request incremental histories via // the "start" query parameter. history_offset: Integer; // 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; // Signature by the exchange over a // TALER_RecoupConfirmationPS, must be // of purpose TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP. exchange_sig: EddsaSignature; // Public key of the private key used to create 'exchange_sig'. exchange_pub: EddsaPublicKey; // Signature by the coin over a // TALER_RecoupRequestPS with purpose // TALER_SIGNATURE_WALLET_COIN_RECOUP. coin_sig: EddsaSignature; // Hash of the public denomination key used to sign the coin. // Needed because 'coin_sig' signs over this, and // that is important to fix the coin's denomination. h_denom_pub: HashCode; // Coin blinding key that was used in the original withdraw request. coin_blind: DenominationBlindingKeyP; // The hash of the withdraw commitment of the original withdraw // request that this coin was part of h_commitment: HashCode; // Coin's index in the original withdraw request, starting at 0 coin_index: Integer; // Reserve receiving the recoup. reserve_pub: EddsaPublicKey; // Date when the operation was made. timestamp: Timestamp; }
Note
The CoinRecoupRefreshTransaction interface defintion is WIP. It will be fully specified and implemented with vRECOUP.
// This represents a transaction of a call to /recoup-refresh // where this coin was _part_ of the batch of coins whose // residual values were credited to the original coin, from // which also this coin was refresh from. interface CoinRecoupRefreshTransaction { type: "RECOUP-REFRESH"; // Offset of this entry in the reserve history. // Useful to request incremental histories via // the "start" query parameter. history_offset: Integer; // 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; // Signature by the exchange over a // TALER_RecoupRefreshConfirmationPS // of purpose TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP_REFRESH. exchange_sig: EddsaSignature; // Public key used to sign 'exchange_sig'. exchange_pub: EddsaPublicKey; // The original coin, from which this coin was derived from // in a call to /refresh, and which was then credited with // the residual value of this coin in a call to /recoup-refresh. old_coin_pub: EddsaPublicKey; // Signature by the coin over a TALER_RecoupRequestPS // with purpose TALER_SIGNATURE_WALLET_COIN_RECOUP. coin_sig: EddsaSignature; // Hash of the public denomination key used to sign the coin. // Needed because 'coin_sig' signs over this, and // that is important to fix the coin's denomination. h_denom_pub: HashCode; // Coin blinding key that was used in the original refresh request. coin_blind: DenominationBlindingKeyP; // The hash of the refresh commitment of the original refresh // request that this coin was derived from. h_commitment: HashCode; // Coin's index in the original refresh request, starting at 0 coin_index: Integer; // Blinding factor of the revoked new coin. new_coin_blinding_secret: DenominationBlindingKeySecret; // Blinded public key of the revoked new coin. new_coin_ev: DenominationBlindingKeySecret; // Date when the operation was made. timestamp: Timestamp; }
Note
The CoinRecoupRefreshReceiverTransaction interface defintion is WIP. It will be fully specified and implemented with vRECOUP.
// This represents a transaction of a call to /recoup-refresh // where this coin was the _receiver_ of the residual values // from coins, that originated from a call to /refresh of this coin. interface CoinRecoupRefreshReceiverTransaction { type: "RECOUP-REFRESH-RECEIVER"; // Offset of this entry in the reserve history. // Useful to request incremental histories via // the "start" query parameter. history_offset: Integer; // 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 over a // TALER_RecoupRefreshConfirmationPS // of purpose TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP_REFRESH. exchange_sig: EddsaSignature; // Public key of the private key used to create 'exchange_sig'. exchange_pub: EddsaPublicKey; }
interface CoinPurseDepositTransaction { type: "PURSE-DEPOSIT"; // Offset of this entry in the reserve history. // Useful to request incremental histories via // the "start" query parameter. history_offset: Integer; // 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; // Base URL of the exchange the purse lives at. exchange_base_url: string; // The hash of the age-commitment for the coin. Only present // if the denomination has support for age restriction. h_age_commitment?: AgeCommitmentHash; // Deposit fee. deposit_fee: Amount; // Public key of the purse. purse_pub: EddsaPublicKey; // True if the deposit was refunded for any reason. refunded: boolean; // Signature by the coin over a // TALER_PurseDepositSignaturePS of // purpose TALER_SIGNATURE_PURSE_DEPOSIT. coin_sig: EddsaSignature; // Hash of the public denomination key used to sign the coin. // Needed because 'coin_sig' signs over this, and // that is important to fix the coin's denomination. h_denom_pub: HashCode; }
interface CoinPurseRefundTransaction { type: "PURSE-REFUND"; // Offset of this entry in the reserve history. // Useful to request incremental histories via // the "start" query parameter. history_offset: Integer; // The total amount of the coin's value restored // by this transaction. // The amount given excludes the refund fee. // The current coin value can thus be computed by // adding the amount to the coin's denomination value. amount: Amount; // Refund fee (of the coin's denomination). The deposit // fee will be waived. refund_fee: Amount; // Signature by the exchange over a // TALER_CoinPurseRefundConfirmationPS // of purpose TALER_SIGNATURE_EXCHANGE_CONFIRM_PURSE_REFUND. exchange_sig: EddsaSignature; // Public key used to sign 'exchange_sig'. exchange_pub: EddsaPublicKey; // Public key of the purse that expired. purse_pub: EddsaPublicKey; }
interface CoinReserveOpenDepositTransaction { type: "RESERVE-OPEN-DEPOSIT"; // Offset of this entry in the reserve history. // Useful to request incremental histories via // the "start" query parameter. history_offset: Integer; // The total amount of the coin's value absorbed // by this transaction. // Note that this means the amount given includes // the deposit fee. coin_contribution: Amount; // Hash over the age commitment of the coin. Optional. // Since **v35**. h_age_commitment?: HashCode; // Signature of the reserve open operation being paid for. reserve_sig: EddsaSignature; // Signature by the coin over a // TALER_ReserveOpenDepositSignaturePS of // purpose TALER_SIGNATURE_RESERVE_OPEN_DEPOSIT. coin_sig: EddsaSignature; }