mirror of
https://github.com/ElementsProject/lightning.git
synced 2024-11-19 09:54:16 +01:00
newaddr: support getting both bech32 and p2sh addresses.
Higher layers consume less addresses this way. Fixes: #2390 Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
parent
5518c7cba8
commit
3e67c09d5e
@ -8,6 +8,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
### Added
|
||||
|
||||
- JSON API: `newaddr` outputs `bech32` or `p2sh-segwit`, or both with new `all` parameter (#2390)
|
||||
|
||||
### Changed
|
||||
|
||||
### Deprecated
|
||||
|
@ -2,12 +2,12 @@
|
||||
.\" Title: lightning-newaddr
|
||||
.\" Author: [see the "AUTHOR" section]
|
||||
.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
|
||||
.\" Date: 07/23/2018
|
||||
.\" Date: 02/23/2019
|
||||
.\" Manual: \ \&
|
||||
.\" Source: \ \&
|
||||
.\" Language: English
|
||||
.\"
|
||||
.TH "LIGHTNING\-NEWADDR" "7" "07/23/2018" "\ \&" "\ \&"
|
||||
.TH "LIGHTNING\-NEWADDR" "7" "02/23/2019" "\ \&" "\ \&"
|
||||
.\" -----------------------------------------------------------------
|
||||
.\" * Define some portability stuff
|
||||
.\" -----------------------------------------------------------------
|
||||
@ -38,12 +38,12 @@ The \fBnewaddr\fR RPC command generates a new address which can subsequently be
|
||||
.sp
|
||||
The funding transaction needs to be confirmed before funds can be used\&.
|
||||
.sp
|
||||
\fIaddresstype\fR specifies the type of address wanted; i\&.e\&. p2sh\-segwit (e\&.g\&. 2MxaozoqWwiUcuD9KKgUSrLFDafLqimT9Ta on bitcoin testnet or 3MZxzq3jBSKNQ2e7dzneo9hy4FvNzmMmt3 on bitcoin mainnet) or bech32 (e\&.g\&. tb1qu9j4lg5f9rgjyfhvfd905vw46eg39czmktxqgg on bitcoin testnet or bc1qwqdg6squsna38e46795at95yu9atm8azzmyvckulcc7kytlcckxswvvzej on bitcoin mainnet)\&.
|
||||
\fIaddresstype\fR specifies the type of address wanted; i\&.e\&. \fIp2sh\-segwit\fR (e\&.g\&. 2MxaozoqWwiUcuD9KKgUSrLFDafLqimT9Ta on bitcoin testnet or 3MZxzq3jBSKNQ2e7dzneo9hy4FvNzmMmt3 on bitcoin mainnet) or \fIbech32 \*(Aq (e\&.g\&. tb1qu9j4lg5f9rgjyfhvfd905vw46eg39czmktxqgg on bitcoin testnet or bc1qwqdg6squsna38e46795at95yu9atm8azzmyvckulcc7kytlcckxswvvzej on bitcoin mainnet)\&. The special value \*(Aqall\fR generates both address types for the same underlying key\&.
|
||||
.sp
|
||||
If not specified the address generated is bech32\&.
|
||||
.SH "RETURN VALUE"
|
||||
.sp
|
||||
On success, a new address will be returned\&.
|
||||
On success, a \fIbech32\fR address and/or a \fIp2sh\-segwit\fR address will be returned\&.
|
||||
.SH "ERRORS"
|
||||
.sp
|
||||
If an unrecognized address type is requested an error message will be returned\&.
|
||||
|
@ -19,16 +19,17 @@ subsequently be used to fund channels managed by the c-lightning node.
|
||||
The funding transaction needs to be confirmed before funds can be used.
|
||||
|
||||
'addresstype' specifies the type of address wanted; i.e.
|
||||
p2sh-segwit (e.g. 2MxaozoqWwiUcuD9KKgUSrLFDafLqimT9Ta on bitcoin testnet
|
||||
or 3MZxzq3jBSKNQ2e7dzneo9hy4FvNzmMmt3 on bitcoin mainnet) or bech32
|
||||
'p2sh-segwit' (e.g. 2MxaozoqWwiUcuD9KKgUSrLFDafLqimT9Ta on bitcoin testnet
|
||||
or 3MZxzq3jBSKNQ2e7dzneo9hy4FvNzmMmt3 on bitcoin mainnet) or 'bech32 '
|
||||
(e.g. tb1qu9j4lg5f9rgjyfhvfd905vw46eg39czmktxqgg on bitcoin testnet or
|
||||
bc1qwqdg6squsna38e46795at95yu9atm8azzmyvckulcc7kytlcckxswvvzej on bitcoin mainnet).
|
||||
The special value 'all' generates both address types for the same underlying key.
|
||||
|
||||
If not specified the address generated is bech32.
|
||||
|
||||
RETURN VALUE
|
||||
------------
|
||||
On success, a new address will be returned.
|
||||
On success, a 'bech32' address and/or a 'p2sh-segwit' address will be returned.
|
||||
|
||||
ERRORS
|
||||
------
|
||||
|
@ -1232,3 +1232,16 @@ def test_bad_onion(node_factory, bitcoind):
|
||||
assert err.value.error['data']['failcode'] == WIRE_INVALID_ONION_HMAC
|
||||
assert err.value.error['data']['erring_node'] == mangled_nodeid
|
||||
assert err.value.error['data']['erring_channel'] == route[1]['channel']
|
||||
|
||||
|
||||
def test_newaddr(node_factory):
|
||||
l1 = node_factory.get_node()
|
||||
p2sh = l1.rpc.newaddr('p2sh-segwit')
|
||||
assert 'bech32' not in p2sh
|
||||
assert p2sh['p2sh-segwit'].startswith('2')
|
||||
bech32 = l1.rpc.newaddr('bech32')
|
||||
assert 'p2sh-segwit' not in bech32
|
||||
assert bech32['bech32'].startswith('bcrt1')
|
||||
both = l1.rpc.newaddr('all')
|
||||
assert both['p2sh-segwit'].startswith('2')
|
||||
assert both['bech32'].startswith('bcrt1')
|
||||
|
@ -266,25 +266,31 @@ encode_scriptpubkey_to_addr(const tal_t *ctx,
|
||||
return out;
|
||||
}
|
||||
|
||||
/* Extract a bool indicating "p2sh-segwit" or "bech32" */
|
||||
enum addrtype {
|
||||
ADDR_P2SH_SEGWIT = 1,
|
||||
ADDR_BECH32 = 2,
|
||||
ADDR_ALL = (ADDR_P2SH_SEGWIT + ADDR_BECH32)
|
||||
};
|
||||
|
||||
/* Extract bool indicating "p2sh-segwit" or "bech32" */
|
||||
static struct command_result *param_newaddr(struct command *cmd,
|
||||
const char *name,
|
||||
const char *buffer,
|
||||
const jsmntok_t *tok,
|
||||
bool **is_p2wpkh)
|
||||
enum addrtype **addrtype)
|
||||
{
|
||||
*is_p2wpkh = tal(cmd, bool);
|
||||
if (json_tok_streq(buffer, tok, "p2sh-segwit")) {
|
||||
**is_p2wpkh = false;
|
||||
return NULL;
|
||||
}
|
||||
if (json_tok_streq(buffer, tok, "bech32")) {
|
||||
**is_p2wpkh = true;
|
||||
return NULL;
|
||||
}
|
||||
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||
"'%s' should be 'bech32' or 'p2sh-segwit', not '%.*s'",
|
||||
name, tok->end - tok->start, buffer + tok->start);
|
||||
*addrtype = tal(cmd, enum addrtype);
|
||||
if (json_tok_streq(buffer, tok, "p2sh-segwit"))
|
||||
**addrtype = ADDR_P2SH_SEGWIT;
|
||||
else if (json_tok_streq(buffer, tok, "bech32"))
|
||||
**addrtype = ADDR_BECH32;
|
||||
else if (json_tok_streq(buffer, tok, "all"))
|
||||
**addrtype = ADDR_ALL;
|
||||
else
|
||||
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||
"'%s' should be 'bech32', 'p2sh-segwit' or 'all', not '%.*s'",
|
||||
name, tok->end - tok->start, buffer + tok->start);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct command_result *json_newaddr(struct command *cmd,
|
||||
@ -295,12 +301,12 @@ static struct command_result *json_newaddr(struct command *cmd,
|
||||
struct json_stream *response;
|
||||
struct ext_key ext;
|
||||
struct pubkey pubkey;
|
||||
bool *is_p2wpkh;
|
||||
enum addrtype *addrtype;
|
||||
s64 keyidx;
|
||||
char *out;
|
||||
char *p2sh, *bech32;
|
||||
|
||||
if (!param(cmd, buffer, params,
|
||||
p_opt_def("addresstype", param_newaddr, &is_p2wpkh, true),
|
||||
p_opt_def("addresstype", param_newaddr, &addrtype, ADDR_BECH32),
|
||||
NULL))
|
||||
return command_param_failed();
|
||||
|
||||
@ -321,17 +327,20 @@ static struct command_result *json_newaddr(struct command *cmd,
|
||||
|
||||
txfilter_add_derkey(cmd->ld->owned_txfilter, ext.pub_key);
|
||||
|
||||
out = encode_pubkey_to_addr(cmd, cmd->ld,
|
||||
&pubkey, !*is_p2wpkh,
|
||||
NULL);
|
||||
if (!out) {
|
||||
p2sh = encode_pubkey_to_addr(cmd, cmd->ld, &pubkey, true, NULL);
|
||||
bech32 = encode_pubkey_to_addr(cmd, cmd->ld, &pubkey, false, NULL);
|
||||
if (!p2sh || !bech32) {
|
||||
return command_fail(cmd, LIGHTNINGD,
|
||||
"p2wpkh address encoding failure.");
|
||||
}
|
||||
|
||||
response = json_stream_success(cmd);
|
||||
json_object_start(response, NULL);
|
||||
json_add_string(response, "address", out);
|
||||
json_add_string(response, "address", bech32 ? bech32 : p2sh);
|
||||
if (*addrtype & ADDR_BECH32)
|
||||
json_add_string(response, "bech32", bech32);
|
||||
if (*addrtype & ADDR_P2SH_SEGWIT)
|
||||
json_add_string(response, "p2sh-segwit", p2sh);
|
||||
json_object_end(response);
|
||||
return command_success(cmd, response);
|
||||
}
|
||||
@ -339,8 +348,8 @@ static struct command_result *json_newaddr(struct command *cmd,
|
||||
static const struct json_command newaddr_command = {
|
||||
"newaddr",
|
||||
json_newaddr,
|
||||
"Get a new {bech32, p2sh-segwit} address to fund a channel (default is bech32)", false,
|
||||
"Generates a new address that belongs to the internal wallet. Funds sent to these addresses will be managed by lightningd. Use `withdraw` to withdraw funds to an external wallet."
|
||||
"Get a new {bech32, p2sh-segwit} (or all) address to fund a channel (default is bech32)", false,
|
||||
"Generates a new address (or both) that belongs to the internal wallet. Funds sent to these addresses will be managed by lightningd. Use `withdraw` to withdraw funds to an external wallet."
|
||||
};
|
||||
AUTODATA(json_command, &newaddr_command);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user