add TALER_EXCHANGE_reserve_withdraw2 function for easy withdrawal of tips
This commit is contained in:
parent
2f2930f1ba
commit
beeece1d6a
@ -967,97 +967,57 @@ handle_reserve_withdraw_finished (void *cls,
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Withdraw a coin from the exchange using a /reserve/withdraw request. Note
|
* Helper function for #TALER_EXCHANGE_reserve_withdraw2() and
|
||||||
* that to ensure that no money is lost in case of hardware failures,
|
* #TALER_EXCHANGE_reserve_withdraw().
|
||||||
* the caller must have committed (most of) the arguments to disk
|
|
||||||
* before calling, and be ready to repeat the request with the same
|
|
||||||
* arguments in case of failures.
|
|
||||||
*
|
*
|
||||||
* @param exchange the exchange handle; the exchange must be ready to operate
|
* @param exchange the exchange handle; the exchange must be ready to operate
|
||||||
* @param pk kind of coin to create
|
* @param pk kind of coin to create
|
||||||
* @param reserve_priv private key of the reserve to withdraw from
|
* @param reserve_sig signature from the reserve authorizing the withdrawal
|
||||||
|
* @param reserve_pub public key of the reserve to withdraw from
|
||||||
* @param ps secrets of the planchet
|
* @param ps secrets of the planchet
|
||||||
* caller must have committed this value to disk before the call (with @a pk)
|
* caller must have committed this value to disk before the call (with @a pk)
|
||||||
|
* @param pd planchet details matching @a ps
|
||||||
* @param res_cb the callback to call when the final result for this request is available
|
* @param res_cb the callback to call when the final result for this request is available
|
||||||
* @param res_cb_cls closure for the above callback
|
* @param res_cb_cls closure for @a res_cb
|
||||||
* @return handle for the operation on success, NULL on error, i.e.
|
* @return NULL
|
||||||
* if the inputs are invalid (i.e. denomination key not with this exchange).
|
* if the inputs are invalid (i.e. denomination key not with this exchange).
|
||||||
* In this case, the callback is not called.
|
* In this case, the callback is not called.
|
||||||
*/
|
*/
|
||||||
struct TALER_EXCHANGE_ReserveWithdrawHandle *
|
struct TALER_EXCHANGE_ReserveWithdrawHandle *
|
||||||
TALER_EXCHANGE_reserve_withdraw (struct TALER_EXCHANGE_Handle *exchange,
|
reserve_withdraw_internal (struct TALER_EXCHANGE_Handle *exchange,
|
||||||
const struct TALER_EXCHANGE_DenomPublicKey *pk,
|
const struct TALER_EXCHANGE_DenomPublicKey *pk,
|
||||||
const struct TALER_ReservePrivateKeyP *reserve_priv,
|
const struct TALER_ReserveSignatureP *reserve_sig,
|
||||||
const struct TALER_PlanchetSecretsP *ps,
|
const struct TALER_ReservePublicKeyP *reserve_pub,
|
||||||
TALER_EXCHANGE_ReserveWithdrawResultCallback res_cb,
|
const struct TALER_PlanchetSecretsP *ps,
|
||||||
void *res_cb_cls)
|
const struct TALER_PlanchetDetail *pd,
|
||||||
|
TALER_EXCHANGE_ReserveWithdrawResultCallback res_cb,
|
||||||
|
void *res_cb_cls)
|
||||||
{
|
{
|
||||||
struct TALER_EXCHANGE_ReserveWithdrawHandle *wsh;
|
struct TALER_EXCHANGE_ReserveWithdrawHandle *wsh;
|
||||||
struct TALER_WithdrawRequestPS req;
|
|
||||||
struct TALER_ReserveSignatureP reserve_sig;
|
|
||||||
struct GNUNET_CURL_Context *ctx;
|
struct GNUNET_CURL_Context *ctx;
|
||||||
struct TALER_Amount amount_with_fee;
|
|
||||||
json_t *withdraw_obj;
|
json_t *withdraw_obj;
|
||||||
CURL *eh;
|
CURL *eh;
|
||||||
struct TALER_PlanchetDetail pd;
|
|
||||||
|
|
||||||
if (GNUNET_OK !=
|
|
||||||
TALER_planchet_prepare (&pk->key,
|
|
||||||
ps,
|
|
||||||
&pd))
|
|
||||||
{
|
|
||||||
GNUNET_break_op (0);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
wsh = GNUNET_new (struct TALER_EXCHANGE_ReserveWithdrawHandle);
|
wsh = GNUNET_new (struct TALER_EXCHANGE_ReserveWithdrawHandle);
|
||||||
wsh->exchange = exchange;
|
wsh->exchange = exchange;
|
||||||
wsh->cb = res_cb;
|
wsh->cb = res_cb;
|
||||||
wsh->cb_cls = res_cb_cls;
|
wsh->cb_cls = res_cb_cls;
|
||||||
wsh->pk = pk;
|
wsh->pk = pk;
|
||||||
wsh->c_hash = pd.c_hash;
|
wsh->reserve_pub = *reserve_pub;
|
||||||
GNUNET_CRYPTO_eddsa_key_get_public (&reserve_priv->eddsa_priv,
|
wsh->c_hash = pd->c_hash;
|
||||||
&wsh->reserve_pub.eddsa_pub);
|
|
||||||
req.purpose.size = htonl (sizeof (struct TALER_WithdrawRequestPS));
|
|
||||||
req.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_WITHDRAW);
|
|
||||||
req.reserve_pub = wsh->reserve_pub;
|
|
||||||
if (GNUNET_OK !=
|
|
||||||
TALER_amount_add (&amount_with_fee,
|
|
||||||
&pk->fee_withdraw,
|
|
||||||
&pk->value))
|
|
||||||
{
|
|
||||||
/* exchange gave us denomination keys that overflow like this!? */
|
|
||||||
GNUNET_break_op (0);
|
|
||||||
GNUNET_free (pd.coin_ev);
|
|
||||||
GNUNET_free (wsh);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
TALER_amount_hton (&req.amount_with_fee,
|
|
||||||
&amount_with_fee);
|
|
||||||
TALER_amount_hton (&req.withdraw_fee,
|
|
||||||
&pk->fee_withdraw);
|
|
||||||
req.h_denomination_pub = pd.denom_pub_hash;
|
|
||||||
GNUNET_CRYPTO_hash (pd.coin_ev,
|
|
||||||
pd.coin_ev_size,
|
|
||||||
&req.h_coin_envelope);
|
|
||||||
GNUNET_assert (GNUNET_OK ==
|
|
||||||
GNUNET_CRYPTO_eddsa_sign (&reserve_priv->eddsa_priv,
|
|
||||||
&req.purpose,
|
|
||||||
&reserve_sig.eddsa_signature));
|
|
||||||
withdraw_obj = json_pack ("{s:o, s:o," /* denom_pub and coin_ev */
|
withdraw_obj = json_pack ("{s:o, s:o," /* denom_pub and coin_ev */
|
||||||
" s:o, s:o}",/* reserve_pub and reserve_sig */
|
" s:o, s:o}",/* reserve_pub and reserve_sig */
|
||||||
"denom_pub", GNUNET_JSON_from_rsa_public_key (pk->key.rsa_public_key),
|
"denom_pub", GNUNET_JSON_from_rsa_public_key (pk->key.rsa_public_key),
|
||||||
"coin_ev", GNUNET_JSON_from_data (pd.coin_ev,
|
"coin_ev", GNUNET_JSON_from_data (pd->coin_ev,
|
||||||
pd.coin_ev_size),
|
pd->coin_ev_size),
|
||||||
"reserve_pub", GNUNET_JSON_from_data_auto (&wsh->reserve_pub),
|
"reserve_pub", GNUNET_JSON_from_data_auto (reserve_pub),
|
||||||
"reserve_sig", GNUNET_JSON_from_data_auto (&reserve_sig));
|
"reserve_sig", GNUNET_JSON_from_data_auto (reserve_sig));
|
||||||
GNUNET_free (pd.coin_ev);
|
|
||||||
if (NULL == withdraw_obj)
|
if (NULL == withdraw_obj)
|
||||||
{
|
{
|
||||||
GNUNET_break (0);
|
GNUNET_break (0);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
wsh->ps = *ps;
|
wsh->ps = *ps;
|
||||||
wsh->url = MAH_path_to_url (exchange, "/reserve/withdraw");
|
wsh->url = MAH_path_to_url (exchange, "/reserve/withdraw");
|
||||||
|
|
||||||
@ -1088,6 +1048,142 @@ TALER_EXCHANGE_reserve_withdraw (struct TALER_EXCHANGE_Handle *exchange,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Withdraw a coin from the exchange using a /reserve/withdraw request. Note
|
||||||
|
* that to ensure that no money is lost in case of hardware failures,
|
||||||
|
* the caller must have committed (most of) the arguments to disk
|
||||||
|
* before calling, and be ready to repeat the request with the same
|
||||||
|
* arguments in case of failures.
|
||||||
|
*
|
||||||
|
* @param exchange the exchange handle; the exchange must be ready to operate
|
||||||
|
* @param pk kind of coin to create
|
||||||
|
* @param reserve_priv private key of the reserve to withdraw from
|
||||||
|
* @param ps secrets of the planchet
|
||||||
|
* caller must have committed this value to disk before the call (with @a pk)
|
||||||
|
* @param res_cb the callback to call when the final result for this request is available
|
||||||
|
* @param res_cb_cls closure for the above callback
|
||||||
|
* @return handle for the operation on success, NULL on error, i.e.
|
||||||
|
* if the inputs are invalid (i.e. denomination key not with this exchange).
|
||||||
|
* In this case, the callback is not called.
|
||||||
|
*/
|
||||||
|
struct TALER_EXCHANGE_ReserveWithdrawHandle *
|
||||||
|
TALER_EXCHANGE_reserve_withdraw (struct TALER_EXCHANGE_Handle *exchange,
|
||||||
|
const struct TALER_EXCHANGE_DenomPublicKey *pk,
|
||||||
|
const struct TALER_ReservePrivateKeyP *reserve_priv,
|
||||||
|
const struct TALER_PlanchetSecretsP *ps,
|
||||||
|
TALER_EXCHANGE_ReserveWithdrawResultCallback res_cb,
|
||||||
|
void *res_cb_cls)
|
||||||
|
{
|
||||||
|
struct TALER_Amount amount_with_fee;
|
||||||
|
struct TALER_ReservePublicKeyP reserve_pub;
|
||||||
|
struct TALER_ReserveSignatureP reserve_sig;
|
||||||
|
struct TALER_WithdrawRequestPS req;
|
||||||
|
struct TALER_PlanchetDetail pd;
|
||||||
|
struct TALER_EXCHANGE_ReserveWithdrawHandle *wsh;
|
||||||
|
|
||||||
|
GNUNET_CRYPTO_eddsa_key_get_public (&reserve_priv->eddsa_priv,
|
||||||
|
&reserve_pub.eddsa_pub);
|
||||||
|
GNUNET_CRYPTO_eddsa_key_get_public (&reserve_priv->eddsa_priv,
|
||||||
|
&req.reserve_pub.eddsa_pub);
|
||||||
|
req.purpose.size = htonl (sizeof (struct TALER_WithdrawRequestPS));
|
||||||
|
req.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_WITHDRAW);
|
||||||
|
if (GNUNET_OK !=
|
||||||
|
TALER_amount_add (&amount_with_fee,
|
||||||
|
&pk->fee_withdraw,
|
||||||
|
&pk->value))
|
||||||
|
{
|
||||||
|
/* exchange gave us denomination keys that overflow like this!? */
|
||||||
|
GNUNET_break_op (0);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
TALER_amount_hton (&req.amount_with_fee,
|
||||||
|
&amount_with_fee);
|
||||||
|
TALER_amount_hton (&req.withdraw_fee,
|
||||||
|
&pk->fee_withdraw);
|
||||||
|
req.h_denomination_pub = pd.denom_pub_hash;
|
||||||
|
if (GNUNET_OK !=
|
||||||
|
TALER_planchet_prepare (&pk->key,
|
||||||
|
ps,
|
||||||
|
&pd))
|
||||||
|
{
|
||||||
|
GNUNET_break_op (0);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
GNUNET_CRYPTO_hash (pd.coin_ev,
|
||||||
|
pd.coin_ev_size,
|
||||||
|
&req.h_coin_envelope);
|
||||||
|
GNUNET_assert (GNUNET_OK ==
|
||||||
|
GNUNET_CRYPTO_eddsa_sign (&reserve_priv->eddsa_priv,
|
||||||
|
&req.purpose,
|
||||||
|
&reserve_sig.eddsa_signature));
|
||||||
|
wsh = reserve_withdraw_internal (exchange,
|
||||||
|
pk,
|
||||||
|
&reserve_sig,
|
||||||
|
&req.reserve_pub,
|
||||||
|
ps,
|
||||||
|
&pd,
|
||||||
|
res_cb,
|
||||||
|
res_cb_cls);
|
||||||
|
GNUNET_free (pd.coin_ev);
|
||||||
|
return wsh;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Withdraw a coin from the exchange using a /reserve/withdraw
|
||||||
|
* request. This API is typically used by a wallet to withdraw a tip
|
||||||
|
* where the reserve's signature was created by the merchant already.
|
||||||
|
*
|
||||||
|
* Note that to ensure that no money is lost in case of hardware
|
||||||
|
* failures, the caller must have committed (most of) the arguments to
|
||||||
|
* disk before calling, and be ready to repeat the request with the
|
||||||
|
* same arguments in case of failures.
|
||||||
|
*
|
||||||
|
* @param exchange the exchange handle; the exchange must be ready to operate
|
||||||
|
* @param pk kind of coin to create
|
||||||
|
* @param reserve_sig signature from the reserve authorizing the withdrawal
|
||||||
|
* @param reserve_pub public key of the reserve to withdraw from
|
||||||
|
* @param ps secrets of the planchet
|
||||||
|
* caller must have committed this value to disk before the call (with @a pk)
|
||||||
|
* @param res_cb the callback to call when the final result for this request is available
|
||||||
|
* @param res_cb_cls closure for @a res_cb
|
||||||
|
* @return NULL
|
||||||
|
* if the inputs are invalid (i.e. denomination key not with this exchange).
|
||||||
|
* In this case, the callback is not called.
|
||||||
|
*/
|
||||||
|
struct TALER_EXCHANGE_ReserveWithdrawHandle *
|
||||||
|
TALER_EXCHANGE_reserve_withdraw2 (struct TALER_EXCHANGE_Handle *exchange,
|
||||||
|
const struct TALER_EXCHANGE_DenomPublicKey *pk,
|
||||||
|
const struct TALER_ReserveSignatureP *reserve_sig,
|
||||||
|
const struct TALER_ReservePublicKeyP *reserve_pub,
|
||||||
|
const struct TALER_PlanchetSecretsP *ps,
|
||||||
|
TALER_EXCHANGE_ReserveWithdrawResultCallback res_cb,
|
||||||
|
void *res_cb_cls)
|
||||||
|
{
|
||||||
|
struct TALER_EXCHANGE_ReserveWithdrawHandle *wsh;
|
||||||
|
struct TALER_PlanchetDetail pd;
|
||||||
|
|
||||||
|
if (GNUNET_OK !=
|
||||||
|
TALER_planchet_prepare (&pk->key,
|
||||||
|
ps,
|
||||||
|
&pd))
|
||||||
|
{
|
||||||
|
GNUNET_break_op (0);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
wsh = reserve_withdraw_internal (exchange,
|
||||||
|
pk,
|
||||||
|
reserve_sig,
|
||||||
|
reserve_pub,
|
||||||
|
ps,
|
||||||
|
&pd,
|
||||||
|
res_cb,
|
||||||
|
res_cb_cls);
|
||||||
|
GNUNET_free (pd.coin_ev);
|
||||||
|
return wsh;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cancel a withdraw status request. This function cannot be used
|
* Cancel a withdraw status request. This function cannot be used
|
||||||
* on a request handle if a response is already served for it.
|
* on a request handle if a response is already served for it.
|
||||||
|
@ -966,12 +966,14 @@ typedef void
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Withdraw a coin from the exchange using a /reserve/withdraw request. This
|
* Withdraw a coin from the exchange using a /reserve/withdraw
|
||||||
* API is typically used by a wallet. Note that to ensure that no
|
* request. This API is typically used by a wallet to withdraw from a
|
||||||
* money is lost in case of hardware failures, the caller must have
|
* reserve.
|
||||||
* committed (most of) the arguments to disk before calling, and be
|
*
|
||||||
* ready to repeat the request with the same arguments in case of
|
* Note that to ensure that no money is lost in case of hardware
|
||||||
* failures.
|
* failures, the caller must have committed (most of) the arguments to
|
||||||
|
* disk before calling, and be ready to repeat the request with the
|
||||||
|
* same arguments in case of failures.
|
||||||
*
|
*
|
||||||
* @param exchange the exchange handle; the exchange must be ready to operate
|
* @param exchange the exchange handle; the exchange must be ready to operate
|
||||||
* @param pk kind of coin to create
|
* @param pk kind of coin to create
|
||||||
@ -993,6 +995,38 @@ TALER_EXCHANGE_reserve_withdraw (struct TALER_EXCHANGE_Handle *exchange,
|
|||||||
void *res_cb_cls);
|
void *res_cb_cls);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Withdraw a coin from the exchange using a /reserve/withdraw
|
||||||
|
* request. This API is typically used by a wallet to withdraw a tip
|
||||||
|
* where the reserve's signature was created by the merchant already.
|
||||||
|
*
|
||||||
|
* Note that to ensure that no money is lost in case of hardware
|
||||||
|
* failures, the caller must have committed (most of) the arguments to
|
||||||
|
* disk before calling, and be ready to repeat the request with the
|
||||||
|
* same arguments in case of failures.
|
||||||
|
*
|
||||||
|
* @param exchange the exchange handle; the exchange must be ready to operate
|
||||||
|
* @param pk kind of coin to create
|
||||||
|
* @param reserve_sig signature from the reserve authorizing the withdrawal
|
||||||
|
* @param reserve_pub public key of the reserve to withdraw from
|
||||||
|
* @param ps secrets of the planchet
|
||||||
|
* caller must have committed this value to disk before the call (with @a pk)
|
||||||
|
* @param res_cb the callback to call when the final result for this request is available
|
||||||
|
* @param res_cb_cls closure for @a res_cb
|
||||||
|
* @return NULL
|
||||||
|
* if the inputs are invalid (i.e. denomination key not with this exchange).
|
||||||
|
* In this case, the callback is not called.
|
||||||
|
*/
|
||||||
|
struct TALER_EXCHANGE_ReserveWithdrawHandle *
|
||||||
|
TALER_EXCHANGE_reserve_withdraw2 (struct TALER_EXCHANGE_Handle *exchange,
|
||||||
|
const struct TALER_EXCHANGE_DenomPublicKey *pk,
|
||||||
|
const struct TALER_ReserveSignatureP *reserve_sig,
|
||||||
|
const struct TALER_ReservePublicKeyP *reserve_pub,
|
||||||
|
const struct TALER_PlanchetSecretsP *ps,
|
||||||
|
TALER_EXCHANGE_ReserveWithdrawResultCallback res_cb,
|
||||||
|
void *res_cb_cls);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cancel a withdraw status request. This function cannot be used
|
* Cancel a withdraw status request. This function cannot be used
|
||||||
* on a request handle if a response is already served for it.
|
* on a request handle if a response is already served for it.
|
||||||
|
Loading…
Reference in New Issue
Block a user