post-purses-PURSE_PUB-create.rst (9205B)
1 .. http:post:: /purses/$PURSE_PUB/create 2 3 Create a purse by depositing money into it. First step of a PUSH payment. 4 5 **Request:** 6 7 The request body must be a `PurseCreateRequest` object. 8 9 A purse that is never merged refunds its coins when it expires, and the 10 exchange must still be able to account for that refund. 11 ``purse_expiration`` is therefore limited to ``max_p2p_expiration`` (see 12 :http:get:`/keys </keys>`) from now, and in addition no coin may be 13 deposited into a purse that outlives the ``stamp_expire_legal`` of the 14 coin's own denomination. 15 16 **Response:** 17 18 :http:statuscode:`200 OK`: 19 The operation succeeded, the exchange confirms that all 20 coins were deposited into the purse. 21 The response will include a `PurseCreateSuccessResponse` object. 22 :http:statuscode:`400 Bad Request`: 23 The request is malformed or a parameter is invalid. 24 This response comes with a standard `ErrorDetail` response. 25 Possible error codes include ``TALER_EC_GENERIC_PARAMETER_MALFORMED``, 26 ``TALER_EC_EXCHANGE_PURSE_CREATE_EXPIRATION_BEFORE_NOW``, 27 ``TALER_EC_EXCHANGE_PURSE_CREATE_EXPIRATION_IS_NEVER``, 28 ``TALER_EC_EXCHANGE_PURSE_CREATE_EXPIRATION_TOO_LATE``, 29 ``TALER_EC_EXCHANGE_PURSE_DENOMINATION_LEGAL_EXPIRES_TOO_SOON``, or 30 ``TALER_EC_EXCHANGE_CREATE_PURSE_NEGATIVE_VALUE_AFTER_FEE``. 31 For the two expiration errors the ``detail`` of the `ErrorDetail` 32 gives the latest purse expiration that would have been accepted. 33 :http:statuscode:`403 Forbidden`: 34 A coin, denomination or contract signature is invalid. 35 This response comes with a standard `ErrorDetail` response. 36 Possible error codes include 37 ``TALER_EC_EXCHANGE_PURSE_CREATE_SIGNATURE_INVALID`` or 38 ``TALER_EC_EXCHANGE_PURSE_ECONTRACT_SIGNATURE_INVALID``. 39 :http:statuscode:`404 Not Found`: 40 The denomination of one of the coins is unknown to the exchange. 41 :http:statuscode:`409 Conflict`: 42 The deposit operation has either failed because a coin has insufficient 43 residual value, or because the same public key of the coin has been 44 previously used with a different denomination, or because a purse with 45 the same public key but different meta data was created previously. 46 Which case it is 47 can be decided by looking at the error code 48 (``TALER_EC_EXCHANGE_GENERIC_INSUFFICIENT_FUNDS`` or 49 ``TALER_EC_EXCHANGE_GENERIC_COIN_CONFLICTING_DENOMINATION_KEY`` or 50 ``TALER_EC_EXCHANGE_GENERIC_COIN_CONFLICTING_AGE_HASH`` or 51 ``TALER_EC_EXCHANGE_PURSE_CREATE_CONFLICTING_META_DATA`` or 52 ``TALER_EC_EXCHANGE_PURSE_DEPOSIT_CONFLICTING_META_DATA`` or 53 ``TALER_EC_EXCHANGE_PURSE_ECONTRACT_CONFLICTING_META_DATA``). 54 The specific fields of the response depend on the error code 55 and include the signatures (and what was signed over) proving the 56 conflict. The response is a `PurseConflict`. 57 :http:statuscode:`410 Gone`: 58 The requested denomination key is not yet or no longer valid. 59 It either before the validity start, past the expiration or was revoked. 60 The response is a `DenominationGoneMessage`. Clients must evaluate 61 the error code provided to understand which of the 62 cases this is and handle it accordingly. 63 :http:statuscode:`413 Request entity too large`: 64 The uploaded body is to long, it exceeds the size limit. 65 Returned with an error code of 66 ``TALER_EC_GENERIC_UPLOAD_EXCEEDS_LIMIT``. 67 :http:statuscode:`425 Too Early`: 68 This response type is used if the given purse expiration time 69 is too far in the future (at least from the perspective 70 of the exchange). Thus, retrying at a later time may 71 succeed. The client should look at the ``Date:`` header 72 of the response to see if a minor time difference is to 73 blame and possibly adjust the request accordingly. 74 (Note: this status code is not yet used.) 75 :http:statuscode:`500 Internal Server Error`: 76 The exchange encountered an internal error. 77 This response comes with a standard `ErrorDetail` response. 78 Possible error codes include 79 ``TALER_EC_EXCHANGE_GENERIC_KEYS_MISSING``, 80 ``TALER_EC_EXCHANGE_GENERIC_GLOBAL_FEES_MISSING``, 81 ``TALER_EC_GENERIC_DB_STORE_FAILED``, 82 ``TALER_EC_GENERIC_DB_FETCH_FAILED``, 83 ``TALER_EC_GENERIC_DB_START_FAILED``, or 84 ``TALER_EC_GENERIC_FAILED_COMPUTE_AMOUNT``. 85 86 87 **Details:** 88 89 .. ts:def:: PurseCreateRequest 90 91 interface PurseCreateRequest { 92 93 // Total value of the purse, excluding fees. 94 amount: Amount; 95 96 // Minimum age required for all coins deposited into the purse. 97 min_age: Integer; 98 99 // Optional encrypted contract, in case the buyer is 100 // proposing the contract and thus establishing the 101 // purse with the payment. 102 econtract?: EncryptedContract; 103 104 // EdDSA public key used to approve merges of this purse. 105 merge_pub: EddsaPublicKey; 106 107 // EdDSA signature of the purse over a 108 // `TALER_PurseRequestSignaturePS` 109 // of purpose ``TALER_SIGNATURE_WALLET_PURSE_CREATE`` 110 // confirming the key 111 // invariants associated with the purse. 112 // (amount, h_contract_terms, expiration). 113 purse_sig: EddsaSignature; 114 115 // SHA-512 hash of the contact of the purse. 116 h_contract_terms: HashCode; 117 118 // Array of coins being deposited into the purse. 119 // Maximum length is 128. 120 deposits: PurseDeposit[]; 121 122 // Indicative time by which the purse should expire 123 // if it has not been merged into an account. At this 124 // point, all of the deposits made will be auto-refunded. 125 // Must not be further in the future than 126 // ``max_p2p_expiration`` of :http:get:`/keys </keys>`. 127 purse_expiration: Timestamp; 128 129 } 130 131 .. ts:def:: EncryptedContract 132 133 interface EncryptedContract { 134 135 // Encrypted contract. 136 econtract: string; 137 138 // Signature over the (encrypted) contract. 139 econtract_sig: EddsaSignature; 140 141 // Ephemeral public key for the DH operation to decrypt the encrypted contract. 142 contract_pub: EddsaPublicKey; 143 144 } 145 146 .. ts:def:: PurseCreateSuccessResponse 147 148 interface PurseCreateSuccessResponse { 149 150 // Total amount deposited into the purse so far (without fees). 151 total_deposited: Amount; 152 153 // Time at the exchange. 154 exchange_timestamp: Timestamp; 155 156 // EdDSA signature of the exchange affirming the payment, 157 // of purpose ``TALER_SIGNATURE_PURSE_DEPOSIT_CONFIRMED`` 158 // over a `TALER_PurseDepositConfirmedSignaturePS`. 159 // Signs over the above and the purse public key and 160 // the hash of the contract terms. 161 exchange_sig: EddsaSignature; 162 163 // public key used to create the signature. 164 exchange_pub: EddsaPublicKey; 165 166 } 167 168 .. ts:def:: PurseConflict 169 170 // Union discriminated by the "code" field. 171 type PurseConflict = 172 | DepositDoubleSpendError 173 | CoinDenominationConflictError 174 | CoinAgeCommitmentConflictError 175 | PurseCreateConflict 176 | PurseDepositConflict 177 | PurseContractConflict; 178 179 .. ts:def:: PurseCreateConflict 180 181 interface PurseCreateConflict { 182 // Must be equal to TALER_EC_EXCHANGE_PURSE_CREATE_CONFLICTING_META_DATA 183 code: Integer; 184 185 // Total amount to be merged into the reserve. 186 // (excludes fees). 187 amount: Amount; 188 189 // Minimum age required for all coins deposited into the purse. 190 min_age: Integer; 191 192 // Indicative time by which the purse should expire 193 // if it has not been merged into an account. At this 194 // point, all of the deposits made should be 195 // auto-refunded. 196 purse_expiration: Timestamp; 197 198 // EdDSA signature of the purse over 199 // `TALER_PurseMergeSignaturePS` of 200 // purpose ``TALER_SIGNATURE_WALLET_PURSE_MERGE`` 201 // confirming that the 202 // above details hold for this purse. 203 purse_sig: EddsaSignature; 204 205 // SHA-512 hash of the contact of the purse. 206 h_contract_terms: HashCode; 207 208 // EdDSA public key used to approve merges of this purse. 209 merge_pub: EddsaPublicKey; 210 } 211 212 .. ts:def:: PurseDepositConflict 213 214 interface PurseDepositConflict { 215 // Must be equal to TALER_EC_EXCHANGE_PURSE_DEPOSIT_CONFLICTING_META_DATA 216 code: Integer; 217 218 // Public key of the coin being deposited into the purse. 219 coin_pub: EddsaPublicKey; 220 221 // Signature over `TALER_PurseDepositSignaturePS` 222 // of purpose ``TALER_SIGNATURE_WALLET_PURSE_DEPOSIT`` 223 // made by the customer with the 224 // `coin's private key <coin-priv>`. 225 coin_sig: EddsaSignature; 226 227 // Target exchange URL for the purse. Not present for the 228 // same exchange. 229 partner_url?: WebURL; 230 231 // Amount to be contributed to the purse by this coin. 232 amount: Amount; 233 234 } 235 236 .. ts:def:: PurseContractConflict 237 238 interface PurseContractConflict { 239 // Must be equal to TALER_EC_EXCHANGE_PURSE_ECONTRACT_CONFLICTING_META_DATA 240 code: Integer; 241 242 // Hash of the encrypted contract. 243 h_econtract: HashCode; 244 245 // Signature over the contract. 246 econtract_sig: EddsaSignature; 247 248 // Ephemeral public key for the DH operation to decrypt the contract. 249 contract_pub: EddsaPublicKey; 250 251 }