walletrpc: add PsbtCoinSelect option to FundPsbt

This commit is contained in:
Oliver Gugger 2024-02-06 12:25:57 +01:00
parent 446152e1a5
commit 0f6c25a773
No known key found for this signature in database
GPG Key ID: 8E4256593F177720
5 changed files with 741 additions and 458 deletions

File diff suppressed because it is too large Load Diff

View File

@ -288,15 +288,25 @@ service WalletKit {
/* lncli: `wallet psbt fund`
FundPsbt creates a fully populated PSBT that contains enough inputs to fund
the outputs specified in the template. There are two ways of specifying a
template: Either by passing in a PSBT with at least one output declared or
by passing in a raw TxTemplate message.
the outputs specified in the template. There are three ways a user can
specify what we call the template (a list of inputs and outputs to use in
the PSBT): Either as a PSBT packet directly with no coin selection (using
the legacy "psbt" field), a PSBT with advanced coin selection support (using
the new "coin_select" field) or as a raw RPC message (using the "raw"
field).
The legacy "psbt" and "raw" modes, the following restrictions apply:
1. If there are no inputs specified in the template, coin selection is
performed automatically.
2. If the template does contain any inputs, it is assumed that full
coin selection happened externally and no additional inputs are added. If
the specified inputs aren't enough to fund the outputs with the given fee
rate, an error is returned.
If there are no inputs specified in the template, coin selection is
performed automatically. If the template does contain any inputs, it is
assumed that full coin selection happened externally and no additional
inputs are added. If the specified inputs aren't enough to fund the outputs
with the given fee rate, an error is returned.
The new "coin_select" mode does not have these restrictions and allows the
user to specify a PSBT with inputs and outputs and still perform coin
selection on top of that.
For all modes this RPC requires any inputs that are specified to be locked
by the user (if they belong to this node in the first place).
After either selecting or verifying the inputs, all input UTXOs are locked
with an internal app ID.
@ -1238,6 +1248,26 @@ message FundPsbtRequest {
Use the outputs and optional inputs from this raw template.
*/
TxTemplate raw = 2;
/*
Use an existing PSBT packet as the template for the funded PSBT.
The difference to the pure PSBT template above is that coin selection is
performed even if inputs are specified. The output amounts are summed up
and used as the target amount for coin selection. A change output must
either already exist in the PSBT and be marked as such, otherwise a new
change output of the specified output type will be added. Any inputs
already specified in the PSBT must already be locked (if they belong to
this node), only newly added inputs will be locked by this RPC.
In case the sum of the already provided inputs exceeds the required
output amount, no new coins are selected. Instead only the fee and
change amount calculation is performed (e.g. a change output is added if
requested or the change is added to the specified existing change
output, given there is any non-dust change). This can be identified by
the returned locked UTXOs being empty.
*/
PsbtCoinSelect coin_select = 9;
}
oneof fees {
@ -1285,7 +1315,8 @@ message FundPsbtResponse {
/*
The list of lock leases that were acquired for the inputs in the funded PSBT
packet.
packet. Only inputs added to the PSBT by this RPC are locked, inputs that
were already present in the PSBT are not locked.
*/
repeated UtxoLease locked_utxos = 3;
}
@ -1308,6 +1339,38 @@ message TxTemplate {
map<string, uint64> outputs = 2;
}
message PsbtCoinSelect {
/*
The template to use for the funded PSBT. The template must contain at least
one non-dust output. The amount to be funded is calculated by summing up the
amounts of all outputs in the template, subtracting all the input values of
the already specified inputs. The change value is added to the output that
is marked as such (or a new change output is added if none is marked). For
the input amount calculation to be correct, the template must have the
WitnessUtxo field set for all inputs. Any inputs already specified in the
PSBT must already be locked (if they belong to this node), only newly added
inputs will be locked by this RPC.
*/
bytes psbt = 1;
oneof change_output {
/*
Use the existing output within the template PSBT with the specified
index as the change output. Any leftover change will be added to the
already specified amount of that output. To add a new change output to
the PSBT, set the "add" field below instead. The type of change output
added is defined by change_type in the parent message.
*/
int32 existing_output_index = 2;
/*
Add a new change output to the PSBT using the change_type specified in
the parent message.
*/
bool add = 3;
}
}
message UtxoLease {
/*
A 32 byte random ID that identifies the lease.

View File

@ -440,8 +440,8 @@
},
"/v2/wallet/psbt/fund": {
"post": {
"summary": "lncli: `wallet psbt fund`\nFundPsbt creates a fully populated PSBT that contains enough inputs to fund\nthe outputs specified in the template. There are two ways of specifying a\ntemplate: Either by passing in a PSBT with at least one output declared or\nby passing in a raw TxTemplate message.",
"description": "If there are no inputs specified in the template, coin selection is\nperformed automatically. If the template does contain any inputs, it is\nassumed that full coin selection happened externally and no additional\ninputs are added. If the specified inputs aren't enough to fund the outputs\nwith the given fee rate, an error is returned.\n\nAfter either selecting or verifying the inputs, all input UTXOs are locked\nwith an internal app ID.\n\nNOTE: If this method returns without an error, it is the caller's\nresponsibility to either spend the locked UTXOs (by finalizing and then\npublishing the transaction) or to unlock/release the locked UTXOs in case of\nan error on the caller's side.",
"summary": "lncli: `wallet psbt fund`\nFundPsbt creates a fully populated PSBT that contains enough inputs to fund\nthe outputs specified in the template. There are three ways a user can\nspecify what we call the template (a list of inputs and outputs to use in\nthe PSBT): Either as a PSBT packet directly with no coin selection (using\nthe legacy \"psbt\" field), a PSBT with advanced coin selection support (using\nthe new \"coin_select\" field) or as a raw RPC message (using the \"raw\"\nfield).\nThe legacy \"psbt\" and \"raw\" modes, the following restrictions apply:\n1. If there are no inputs specified in the template, coin selection is\nperformed automatically.\n2. If the template does contain any inputs, it is assumed that full\ncoin selection happened externally and no additional inputs are added. If\nthe specified inputs aren't enough to fund the outputs with the given fee\nrate, an error is returned.",
"description": "The new \"coin_select\" mode does not have these restrictions and allows the\nuser to specify a PSBT with inputs and outputs and still perform coin\nselection on top of that.\nFor all modes this RPC requires any inputs that are specified to be locked\nby the user (if they belong to this node in the first place).\n\nAfter either selecting or verifying the inputs, all input UTXOs are locked\nwith an internal app ID.\n\nNOTE: If this method returns without an error, it is the caller's\nresponsibility to either spend the locked UTXOs (by finalizing and then\npublishing the transaction) or to unlock/release the locked UTXOs in case of\nan error on the caller's side.",
"operationId": "WalletKit_FundPsbt",
"responses": {
"200": {
@ -1428,6 +1428,10 @@
"$ref": "#/definitions/walletrpcTxTemplate",
"description": "Use the outputs and optional inputs from this raw template."
},
"coin_select": {
"$ref": "#/definitions/walletrpcPsbtCoinSelect",
"description": "Use an existing PSBT packet as the template for the funded PSBT.\n\nThe difference to the pure PSBT template above is that coin selection is\nperformed even if inputs are specified. The output amounts are summed up\nand used as the target amount for coin selection. A change output must\neither already exist in the PSBT and be marked as such, otherwise a new\nchange output of the specified output type will be added. Any inputs\nalready specified in the PSBT must already be locked (if they belong to\nthis node), only newly added inputs will be locked by this RPC.\n\nIn case the sum of the already provided inputs exceeds the required\noutput amount, no new coins are selected. Instead only the fee and\nchange amount calculation is performed (e.g. a change output is added if\nrequested or the change is added to the specified existing change\noutput, given there is any non-dust change). This can be identified by\nthe returned locked UTXOs being empty."
},
"target_conf": {
"type": "integer",
"format": "int64",
@ -1475,7 +1479,7 @@
"items": {
"$ref": "#/definitions/walletrpcUtxoLease"
},
"description": "The list of lock leases that were acquired for the inputs in the funded PSBT\npacket."
"description": "The list of lock leases that were acquired for the inputs in the funded PSBT\npacket. Only inputs added to the PSBT by this RPC are locked, inputs that\nwere already present in the PSBT are not locked."
}
}
},
@ -1805,6 +1809,25 @@
}
}
},
"walletrpcPsbtCoinSelect": {
"type": "object",
"properties": {
"psbt": {
"type": "string",
"format": "byte",
"description": "The template to use for the funded PSBT. The template must contain at least\none non-dust output. The amount to be funded is calculated by summing up the\namounts of all outputs in the template, subtracting all the input values of\nthe already specified inputs. The change value is added to the output that\nis marked as such (or a new change output is added if none is marked). For\nthe input amount calculation to be correct, the template must have the\nWitnessUtxo field set for all inputs. Any inputs already specified in the\nPSBT must already be locked (if they belong to this node), only newly added\ninputs will be locked by this RPC."
},
"existing_output_index": {
"type": "integer",
"format": "int32",
"description": "Use the existing output within the template PSBT with the specified\nindex as the change output. Any leftover change will be added to the\nalready specified amount of that output. To add a new change output to\nthe PSBT, set the \"add\" field below instead. The type of change output\nadded is defined by change_type in the parent message."
},
"add": {
"type": "boolean",
"description": "Add a new change output to the PSBT using the change_type specified in\nthe parent message."
}
}
},
"walletrpcPublishResponse": {
"type": "object",
"properties": {

View File

@ -218,15 +218,25 @@ type WalletKitClient interface {
LabelTransaction(ctx context.Context, in *LabelTransactionRequest, opts ...grpc.CallOption) (*LabelTransactionResponse, error)
// lncli: `wallet psbt fund`
// FundPsbt creates a fully populated PSBT that contains enough inputs to fund
// the outputs specified in the template. There are two ways of specifying a
// template: Either by passing in a PSBT with at least one output declared or
// by passing in a raw TxTemplate message.
// the outputs specified in the template. There are three ways a user can
// specify what we call the template (a list of inputs and outputs to use in
// the PSBT): Either as a PSBT packet directly with no coin selection (using
// the legacy "psbt" field), a PSBT with advanced coin selection support (using
// the new "coin_select" field) or as a raw RPC message (using the "raw"
// field).
// The legacy "psbt" and "raw" modes, the following restrictions apply:
// 1. If there are no inputs specified in the template, coin selection is
// performed automatically.
// 2. If the template does contain any inputs, it is assumed that full
// coin selection happened externally and no additional inputs are added. If
// the specified inputs aren't enough to fund the outputs with the given fee
// rate, an error is returned.
//
// If there are no inputs specified in the template, coin selection is
// performed automatically. If the template does contain any inputs, it is
// assumed that full coin selection happened externally and no additional
// inputs are added. If the specified inputs aren't enough to fund the outputs
// with the given fee rate, an error is returned.
// The new "coin_select" mode does not have these restrictions and allows the
// user to specify a PSBT with inputs and outputs and still perform coin
// selection on top of that.
// For all modes this RPC requires any inputs that are specified to be locked
// by the user (if they belong to this node in the first place).
//
// After either selecting or verifying the inputs, all input UTXOs are locked
// with an internal app ID.
@ -716,15 +726,25 @@ type WalletKitServer interface {
LabelTransaction(context.Context, *LabelTransactionRequest) (*LabelTransactionResponse, error)
// lncli: `wallet psbt fund`
// FundPsbt creates a fully populated PSBT that contains enough inputs to fund
// the outputs specified in the template. There are two ways of specifying a
// template: Either by passing in a PSBT with at least one output declared or
// by passing in a raw TxTemplate message.
// the outputs specified in the template. There are three ways a user can
// specify what we call the template (a list of inputs and outputs to use in
// the PSBT): Either as a PSBT packet directly with no coin selection (using
// the legacy "psbt" field), a PSBT with advanced coin selection support (using
// the new "coin_select" field) or as a raw RPC message (using the "raw"
// field).
// The legacy "psbt" and "raw" modes, the following restrictions apply:
// 1. If there are no inputs specified in the template, coin selection is
// performed automatically.
// 2. If the template does contain any inputs, it is assumed that full
// coin selection happened externally and no additional inputs are added. If
// the specified inputs aren't enough to fund the outputs with the given fee
// rate, an error is returned.
//
// If there are no inputs specified in the template, coin selection is
// performed automatically. If the template does contain any inputs, it is
// assumed that full coin selection happened externally and no additional
// inputs are added. If the specified inputs aren't enough to fund the outputs
// with the given fee rate, an error is returned.
// The new "coin_select" mode does not have these restrictions and allows the
// user to specify a PSBT with inputs and outputs and still perform coin
// selection on top of that.
// For all modes this RPC requires any inputs that are specified to be locked
// by the user (if they belong to this node in the first place).
//
// After either selecting or verifying the inputs, all input UTXOs are locked
// with an internal app ID.

View File

@ -1152,13 +1152,24 @@ func (w *WalletKit) LabelTransaction(ctx context.Context,
}
// FundPsbt creates a fully populated PSBT that contains enough inputs to fund
// the outputs specified in the template. There are two ways of specifying a
// template: Either by passing in a PSBT with at least one output declared or
// by passing in a raw TxTemplate message. If there are no inputs specified in
// the template, coin selection is performed automatically. If the template does
// contain any inputs, it is assumed that full coin selection happened
// externally and no additional inputs are added. If the specified inputs aren't
// enough to fund the outputs with the given fee rate, an error is returned.
// the outputs specified in the template. There are three ways a user can
// specify what we call the template (a list of inputs and outputs to use in the
// PSBT): Either as a PSBT packet directly with no coin selection (using the
// legacy "psbt" field), a PSBT with advanced coin selection support (using the
// new "coin_select" field) or as a raw RPC message (using the "raw" field).
// The legacy "psbt" and "raw" modes, the following restrictions apply:
// 1. If there are no inputs specified in the template, coin selection is
// performed automatically.
// 2. If the template does contain any inputs, it is assumed that full coin
// selection happened externally and no additional inputs are added. If the
// specified inputs aren't enough to fund the outputs with the given fee
// rate, an error is returned.
//
// The new "coin_select" mode does not have these restrictions and allows the
// user to specify a PSBT with inputs and outputs and still perform coin
// selection on top of that.
// For all modes this RPC requires any inputs that are specified to be locked by
// the user (if they belong to this node in the first place).
// After either selecting or verifying the inputs, all input UTXOs are locked
// with an internal app ID. A custom address type for change can be specified
// for default accounts and single imported public keys (only P2TR for now).