|
@ -157,15 +157,15 @@ static struct command_result *json_prepare_tx(struct command *cmd, |
|
|
struct unreleased_tx **utx, |
|
|
struct unreleased_tx **utx, |
|
|
bool for_withdraw) |
|
|
bool for_withdraw) |
|
|
{ |
|
|
{ |
|
|
u32 *feerate_per_kw; |
|
|
u32 *feerate_per_kw = NULL; |
|
|
struct command_result *res; |
|
|
struct command_result *result; |
|
|
u32 *minconf, maxheight; |
|
|
u32 *minconf, maxheight; |
|
|
struct pubkey *changekey; |
|
|
struct pubkey *changekey; |
|
|
struct bitcoin_tx_output **outputs; |
|
|
struct bitcoin_tx_output **outputs; |
|
|
const jsmntok_t *outputstok, *t; |
|
|
const jsmntok_t *outputstok = NULL, *t; |
|
|
const u8 *destination = NULL; |
|
|
const u8 *destination = NULL; |
|
|
size_t out_len, i; |
|
|
size_t out_len, i; |
|
|
const struct utxo **chosen_utxos; |
|
|
const struct utxo **chosen_utxos = NULL; |
|
|
|
|
|
|
|
|
*utx = tal(cmd, struct unreleased_tx); |
|
|
*utx = tal(cmd, struct unreleased_tx); |
|
|
(*utx)->wtx = tal(*utx, struct wallet_tx); |
|
|
(*utx)->wtx = tal(*utx, struct wallet_tx); |
|
@ -174,29 +174,123 @@ static struct command_result *json_prepare_tx(struct command *cmd, |
|
|
if (!for_withdraw) { |
|
|
if (!for_withdraw) { |
|
|
/* From v0.7.3, the new style for *txprepare* use array of outputs
|
|
|
/* From v0.7.3, the new style for *txprepare* use array of outputs
|
|
|
* to replace original 'destination' and 'satoshi' parameters.*/ |
|
|
* to replace original 'destination' and 'satoshi' parameters.*/ |
|
|
|
|
|
/* For generating help, give new-style. */ |
|
|
|
|
|
if (!params || !deprecated_apis) { |
|
|
if (!param(cmd, buffer, params, |
|
|
if (!param(cmd, buffer, params, |
|
|
p_req("outputs", param_array, &outputstok), |
|
|
p_req("outputs", param_array, &outputstok), |
|
|
p_opt("feerate", param_feerate, &feerate_per_kw), |
|
|
p_opt("feerate", param_feerate, &feerate_per_kw), |
|
|
p_opt_def("minconf", param_number, &minconf, 1), |
|
|
p_opt_def("minconf", param_number, &minconf, 1), |
|
|
p_opt("utxos", param_utxos, &chosen_utxos), |
|
|
p_opt("utxos", param_utxos, &chosen_utxos), |
|
|
NULL)) { |
|
|
NULL)) |
|
|
|
|
|
return command_param_failed(); |
|
|
|
|
|
} else if (params->type == JSMN_ARRAY) { |
|
|
|
|
|
const jsmntok_t *firsttok, *secondtok, *thirdtok, *fourthtok; |
|
|
|
|
|
|
|
|
/* For generating help, give new-style. */ |
|
|
/* FIXME: This change completely destroyes the support for `check`. */ |
|
|
if (!params || !deprecated_apis) |
|
|
if (!param(cmd, buffer, params, |
|
|
|
|
|
p_req("outputs_or_destination", param_tok, &firsttok), |
|
|
|
|
|
p_opt("feerate_or_sat", param_tok, &secondtok), |
|
|
|
|
|
p_opt("minconf_or_feerate", param_tok, &thirdtok), |
|
|
|
|
|
p_opt("utxos_or_minconf", param_tok, &fourthtok), |
|
|
|
|
|
NULL)) |
|
|
return command_param_failed(); |
|
|
return command_param_failed(); |
|
|
|
|
|
|
|
|
/* For the old style:
|
|
|
if (firsttok->type == JSMN_ARRAY) { |
|
|
|
|
|
/* New style:
|
|
|
|
|
|
* *txprepare* 'outputs' ['feerate'] ['minconf'] ['utxos'] */ |
|
|
|
|
|
|
|
|
|
|
|
/* outputs (required) */ |
|
|
|
|
|
outputstok = firsttok; |
|
|
|
|
|
|
|
|
|
|
|
/* feerate (optional) */ |
|
|
|
|
|
if (secondtok) { |
|
|
|
|
|
result = param_feerate(cmd, "feerate", buffer, |
|
|
|
|
|
secondtok, &feerate_per_kw); |
|
|
|
|
|
if (result) |
|
|
|
|
|
return result; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* minconf (optional) */ |
|
|
|
|
|
if (thirdtok) { |
|
|
|
|
|
result = param_number(cmd, "minconf", buffer, |
|
|
|
|
|
thirdtok, &minconf); |
|
|
|
|
|
if (result) |
|
|
|
|
|
return result; |
|
|
|
|
|
} else { |
|
|
|
|
|
minconf = tal(cmd, u32); |
|
|
|
|
|
*minconf = 1; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* utxos (optional) */ |
|
|
|
|
|
if (fourthtok) { |
|
|
|
|
|
result = param_utxos(cmd, "utxos", buffer, |
|
|
|
|
|
fourthtok, &chosen_utxos); |
|
|
|
|
|
if (result) |
|
|
|
|
|
return result; |
|
|
|
|
|
} |
|
|
|
|
|
} else { |
|
|
|
|
|
/* Old style:
|
|
|
* *txprepare* 'destination' 'satoshi' ['feerate'] ['minconf'] */ |
|
|
* *txprepare* 'destination' 'satoshi' ['feerate'] ['minconf'] */ |
|
|
|
|
|
|
|
|
|
|
|
/* destination (required) */ |
|
|
|
|
|
result = param_bitcoin_address(cmd, "destination", buffer, |
|
|
|
|
|
firsttok, &destination); |
|
|
|
|
|
if (result) |
|
|
|
|
|
return result; |
|
|
|
|
|
|
|
|
|
|
|
/* satoshi (required) */ |
|
|
|
|
|
if (!secondtok) |
|
|
|
|
|
return command_fail(cmd, JSONRPC2_INVALID_PARAMS, |
|
|
|
|
|
"Need set 'satoshi' field."); |
|
|
|
|
|
result = param_wtx(cmd, "satoshi", buffer, |
|
|
|
|
|
secondtok, (*utx)->wtx); |
|
|
|
|
|
if (result) |
|
|
|
|
|
return result; |
|
|
|
|
|
|
|
|
|
|
|
/* feerate (optional) */ |
|
|
|
|
|
if (thirdtok) { |
|
|
|
|
|
result = param_feerate(cmd, "feerate", buffer, |
|
|
|
|
|
thirdtok, &feerate_per_kw); |
|
|
|
|
|
if (result) |
|
|
|
|
|
return result; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* minconf (optional) */ |
|
|
|
|
|
if (fourthtok) { |
|
|
|
|
|
result = param_number(cmd, "minconf", buffer, |
|
|
|
|
|
fourthtok, &minconf); |
|
|
|
|
|
if (result) |
|
|
|
|
|
return result; |
|
|
|
|
|
} else { |
|
|
|
|
|
minconf = tal(cmd, u32); |
|
|
|
|
|
*minconf = 1; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
} else { |
|
|
|
|
|
const jsmntok_t *satoshitok = NULL; |
|
|
if (!param(cmd, buffer, params, |
|
|
if (!param(cmd, buffer, params, |
|
|
p_req("destination", param_bitcoin_address, |
|
|
p_opt("outputs", param_array, &outputstok), |
|
|
|
|
|
p_opt("destination", param_bitcoin_address, |
|
|
&destination), |
|
|
&destination), |
|
|
p_req("satoshi", param_wtx, (*utx)->wtx), |
|
|
p_opt("satoshi", param_tok, &satoshitok), |
|
|
p_opt("feerate", param_feerate, &feerate_per_kw), |
|
|
p_opt("feerate", param_feerate, &feerate_per_kw), |
|
|
p_opt_def("minconf", param_number, &minconf, 1), |
|
|
p_opt_def("minconf", param_number, &minconf, 1), |
|
|
|
|
|
p_opt("utxos", param_utxos, &chosen_utxos), |
|
|
NULL)) |
|
|
NULL)) |
|
|
/* If the parameters mixed the new style and the old style,
|
|
|
/* If the parameters mixed the new style and the old style,
|
|
|
* fail it. */ |
|
|
* fail it. */ |
|
|
return command_param_failed(); |
|
|
return command_param_failed(); |
|
|
|
|
|
|
|
|
|
|
|
if (!outputstok) { |
|
|
|
|
|
if (!destination || !satoshitok) |
|
|
|
|
|
return command_fail(cmd, JSONRPC2_INVALID_PARAMS, |
|
|
|
|
|
"Need set 'outputs' field."); |
|
|
|
|
|
|
|
|
|
|
|
result = param_wtx(cmd, "satoshi", buffer, |
|
|
|
|
|
satoshitok, (*utx)->wtx); |
|
|
|
|
|
if (result) |
|
|
|
|
|
return result; |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
} else { |
|
|
} else { |
|
|
/* *withdraw* command still use 'destination' and 'satoshi' as parameters. */ |
|
|
/* *withdraw* command still use 'destination' and 'satoshi' as parameters. */ |
|
@ -212,10 +306,10 @@ static struct command_result *json_prepare_tx(struct command *cmd, |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
if (!feerate_per_kw) { |
|
|
if (!feerate_per_kw) { |
|
|
res = param_feerate_estimate(cmd, &feerate_per_kw, |
|
|
result = param_feerate_estimate(cmd, &feerate_per_kw, |
|
|
FEERATE_NORMAL); |
|
|
FEERATE_NORMAL); |
|
|
if (res) |
|
|
if (result) |
|
|
return res; |
|
|
return result; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
maxheight = minconf_to_maxheight(*minconf, cmd->ld); |
|
|
maxheight = minconf_to_maxheight(*minconf, cmd->ld); |
|
@ -302,15 +396,15 @@ create_tx: |
|
|
(*utx)->outputs = tal_steal(*utx, outputs); |
|
|
(*utx)->outputs = tal_steal(*utx, outputs); |
|
|
|
|
|
|
|
|
if (chosen_utxos) |
|
|
if (chosen_utxos) |
|
|
res = wtx_from_utxos((*utx)->wtx, *feerate_per_kw, |
|
|
result = wtx_from_utxos((*utx)->wtx, *feerate_per_kw, |
|
|
out_len, maxheight, |
|
|
out_len, maxheight, |
|
|
chosen_utxos); |
|
|
chosen_utxos); |
|
|
else |
|
|
else |
|
|
res = wtx_select_utxos((*utx)->wtx, *feerate_per_kw, |
|
|
result = wtx_select_utxos((*utx)->wtx, *feerate_per_kw, |
|
|
out_len, maxheight); |
|
|
out_len, maxheight); |
|
|
|
|
|
|
|
|
if (res) |
|
|
if (result) |
|
|
return res; |
|
|
return result; |
|
|
|
|
|
|
|
|
/* Because of the max limit of AMOUNT_SAT(-1ULL),
|
|
|
/* Because of the max limit of AMOUNT_SAT(-1ULL),
|
|
|
* `(*utx)->wtx->all_funds` won't change in `wtx_select_utxos()` */ |
|
|
* `(*utx)->wtx->all_funds` won't change in `wtx_select_utxos()` */ |
|
|