Contents

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_REQUEST made with the respective $COIN_PRIV, affirming desire to download the coin’s transaction history.

If-None-Match:

The client MAY provide an If-None-Match header with an ETag. The client MAY provide an If-None-Match header with an Etag. In that case, the server MUST additionally respond with an 304 status code in case the coin history matches the provided Etag.

Query Parameters:
  • start=OFFSETOptional. 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-Match was 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, or TALER_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[];
}
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;

}