Skip to content

Commit

Permalink
splice: Documentation for the “splice” command
Browse files Browse the repository at this point in the history
Adding schema and documentatino for how to use the scripting portion of the “splice” RPC command.
  • Loading branch information
ddustin committed Jan 27, 2024
1 parent b981245 commit ab42c23
Show file tree
Hide file tree
Showing 5 changed files with 416 additions and 0 deletions.
1 change: 1 addition & 0 deletions doc/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ MANPAGES := doc/lightning-cli.1 \
doc/lightning-sendcustommsg.7 \
doc/lightning-signinvoice.7 \
doc/lightning-signmessage.7 \
doc/lightning-splice.7 \
doc/lightning-splice_init.7 \
doc/lightning-splice_update.7 \
doc/lightning-splice_signed.7 \
Expand Down
1 change: 1 addition & 0 deletions doc/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ Core Lightning Documentation
lightning-signinvoice <lightning-signinvoice.7.md>
lightning-signmessage <lightning-signmessage.7.md>
lightning-signpsbt <lightning-signpsbt.7.md>
lightning-splice <lightning-splice.7.md>
lightning-splice_init <lightning-splice_init.7.md>
lightning-splice_signed <lightning-splice_signed.7.md>
lightning-splice_update <lightning-splice_update.7.md>
Expand Down
357 changes: 357 additions & 0 deletions doc/lightning-splice.7.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,357 @@
lightning-splice -- Command to execute a splice script
=====================================================================

SYNOPSIS
--------
**(WARNING: experimental-splicing only)**

**splice** [*script*] [*dryrun*] [*json*] [*psbt*] [*user\_provided_\sats*]

DESCRIPTION
-----------

`splice` is the command to move funds into or out of a channel. Multiple actions
can be combined together resulting in a single onchain transaction. Funds may be
moved out of a channel and into another in a single batch enabling cross-channel
movement.

The primary method is to make a `script` containing one or more splice actions
that will be merged into a single transaction. If possible the entire operation
will be completed and published on chain.

However if you specified your own inputs using `psbt`, then the command will
return a psbt that you must sign and then pass to `splice\_signed`.

It is required you pass one of `script` or `json`.

It is recommended you first do a `dryrun` to confirm your script does what you
expect it to do.

*script* The splice script to execute

*dryrun* Don't execute any actions and output a transcript of what would have
been done

*json* A json payload of instructions can be passed instead of script

*psbt* An initial psbt to begin the splice with

*user\_provided\_sats* The amount of sats being contributed by the initial psbt

The primary purpose of splice script is to execute all types of splices using
a single command. You can perform all these actions manually using the lower
level api (see `splice_init`) however this interface is much simpler to use and
it provides some security against signing maliciously inserted inputs.

A splice script is a series of 'segments' that are seperated by newlines or
semicolons. Each segment represents one splice action which is typically adding
to or removing from a channel. The funds are designated as going into the
channel or coming out of the channel by which side of an arrow "->" the channel
identifier is placed on. The amount of funds is placed on the other side of the
arrow.

Take this example:
```shell
8338aef0 -> 10000sat
```

This is how we take 10,000 sats out of channel 8338aef0.

To put 10,000 sats into the channel, we make the arrow point into the channel
like so:
```shell
10000sat -> 8338aef0
```

In the last two examples we specified the first 8 digits of the channel
identifier. You can specify as few as 4 digits of the begining of the channel
identifier and it will be autocompleted to the matching channel. If the code
matches more than one channel or node id, the script will fail with an error.

In order to put funds into a channel however, we need get the funds from
somewhere. The simplest place to get them is the built in onchain wallet. The
"wallet" operator can be placed just like channel identifiers. We can take funds
out of the wallet like so:
```shell
wallet -> 10000sat
```

We can put funds back into the wallet like so:
```shell
10000sat -> wallet
```

Now that we know how to take funds out of a wallet, let's combine them into a
combined script:
```shell
wallet -> 10000sat
10000sat -> 8338aef0
```

The first line withdraws 10,000 sats from the wallet and puts them in the
script's "general script funds." The second line takes 10,000 from the "general
script funds" and places them into channel 8338aef0. This is also called a
"splice in."

In order for this script to work, we need one more thing. Onchain fees must be
funded from somewhere. The simplest way to pay the fee from the "general script
funds." If we change the amount going into the channel to a percentage, the fee
will automatically be taken from the "general script funds" like so:
```shell
wallet -> 10000sat
100% -> 8338aef0
```

When specify a percentage instead of an amount, it means take that percentage
out of the "general script fund."

This will take 10,000 sats from the onchain wallet and put that amount less any
onchain fees into channel 8338aef0. The feerate used will be the node's
standard opening feerate. In order to use your own feerate you must us the fee
operator.

The fee operator is attached to an amount. If you want to take out extra to
cover the fee, use "+fee" and if you want to reduce the amount being sent
somewhere use the "-fee" suffix. Take this example:
```shell
wallet -> 10000sat+fee
10000sat -> 8338aef0
```

In this example we add precisely 10,000 sats to channel 8338aef0 and withdraw
enough from the wallet to cover the 10,000 sats and the onchain fee.

To control the amount of fee, you can specify a fee-rate with the use of the at
"@" symbol after fee. Afer the at symbol, specify a number of sats to pay per
kiloweight (aka. perkw) like so:
```shell
wallet -> 10000sat+fee@300
10000sat -> 8338aef0
```

This example pays a fee rate of 300 sats per thousand weight units. To view this
amount in other units (ie. sats/vbyte) execute a `dryrun` of the script.

Instead of withdrawing extra from the wallet, we can reduce the amount going to
channel 8338aef0 using the "-fee" operator like so:
```shell
wallet -> 10000sat
10000sat-fee -> 8338aef0
```

You can also specify the feerate here like so:
```shell
wallet -> 10000sat
10000sat-fee@300 -> 8338aef0
```

Now let's build a script that takes funds out of a channel and puts them into
the onchain wallet:
```shell
8338aef0 -> 10000sat
100% -> wallet
```

By default however, scripts that leave sats in the "general script fund," will
be automatically sent to the wallet. So the second line is not needed, we can
simplify the script to:
```shell
8338aef0 -> 10000sat
```

We can can also move sats to a specific bitcoin address like so:
```shell
8338aef0 -> 10000sat+fee
100% -> 1JfbZRwdDHKZmuiZgYArJZhcuuzuw2HuMu
```

This example pays 10,000 sats to the address 1JfbZRwdDHKZmuiZgYArJZhcuuzuw2HuMu
out of your channel balance in 8338aef0.

Percentages on the right side take out that amount of available funds from a
channel. For example:
```shell
8338aef0 -> 100%
```

This takes all available funds out of channel 8338aef0 and puts them into the
onchain wallet. Note that available funds is restricted by pending HTLCs and
the 1% reserve requirement. To get all the funds you need to close the channel.
More useful would be something like this:
```shell
8338aef0 -> 50%
100% -> 07bfddea
```

This example takes half the available funds from channel 8338aef0 and puts them
into channel 07bfddea.

We can also split this amount like so:
```shell
8338aef0 -> 50%
50% -> 07bfddea
50% -> 09ad6278
```

This example takes half the funds in 8338aef0 and splits them between channels
07bfddea and 09ad6278.

If we want to send funds to more channels calculating percentages can get
unwieldly so we can use the asterisk operator "\*" which divides the "general
script funds" amount all destinations using it, like so:
```shell
8338aef0 -> 50%
* -> 07bfddea
* -> 09ad6278
* -> efc2a7ff
```

This example takes half the funds in 8338aef0 and splits them evenly among three
channels.

Sats can be specified with multiple suffixes including sat, msat, btc, M, or K.
The M suffix is shorthand for a million satoshis and the K suffix is shorthand
for a thousand satoshis. These can combined with a decimal point like so:
```shell
07bfddea -> 1.23M
09ad6278 -> 900K
efc2a7ff -> 0.01btc
```

This example takes 1,230,000 sats from 07bfddea, 900,000 sats from 09ad6278 and
1,000,000 sats from efc2a7ff and puts them in the onchain wallet.

Another way to specify channel ids is a channel query. These take the form of a
node id, a colon, and a number or symbol "034645dc:0" which results in your
first channel with the peer whose node id starts with 034645dc. Change the
number after the colon to get a different index like so:
```shell
034645dc:0 -> 10K
034645dc:1 -> 10K
034645dc:2 -> 10K
```

This example takes 10,000 sats out of the first three channels with peer
034645dc and puts the total into the onchain wallet.

In addition to index numbers, the symbol after the colon can be a question mark
"?" or a asterisk "\*" which mean match the first unused channel or all the
remaining channels respectively like so:
```shell
* -> 034645dc:?
* -> 03e3d03e:0
03e3d03e:* -> 100%
```

This example takes 100% of available funds from all of 03e3d03e's channels
except the first one and splits them between 03e3d03e's first channel and
034645dc's first channel.

The node id prefix can also be replaced with the asterisk "\*" which means match
all nodes. This can be combined with the asterisk "\*" that matches all unused
channels like so:
```shell
wallet -> 10000sat
100% -> *:*
```

This example takes 10,000 sats from the onchain wallet and divides them between
all channels.

It is possible to request a peer to add funds to a channel with a lease request.
This is done using the pipe "|" symbol and optionally specifying the maximum fee
you authorize using the at "@" symbol. After the pipe you specify the amount of
sats you would like to lease, followed by the at symbol and a percentage value
like so:
```shell
wallet -> 10M+fee
100%|10M@1% -> 8338aef0
```

This example splices 10,000,000 sats into channel and requests your peer also
add 10,000,000 sats to the channel. If they fee they demand is over 1% the
operation will be aborted. Whatever lease fee they do charge will come out of
the 10,000,000 sats going into the channel balance. The onchain fee will be paid
by taking extra funds out of the onchain wallet.

Lease requests do not need to combined with splicing in funds but you must pay
the onchain fee from somewhere. One simple location to take the fees from is
your existing channel balance. Doing so requires using two arrows since funds
are going into and out of the channel at the same time, like so:
```shell
|10M@1% -> 8338aef0 -> 0+fee
```

This example makes a lease request from your peer on 8338aef0 for 10,000,000
sats and pays the onchain fee using the channel balance. This is a particularlly
elegant way to pay the onchain fee without adding any inputs or outputs beyond
the channel funding itself.

When passing via the command line using semicolons can be simpler instead of
newlines. Here are some command line examples:

Splice out 10 million satoshis to the onchain wallet
```shell
lightning-cli splice "8338aef0 -> 10M"
```

Splice in 10 thousand satoshis from the onchain wallet
```shell
lightning-cli splice "wallet -> 10K; 100% -> 8338aef0"
```

Send 900 thousand satoshis from a channel to an onchain adddress
```shell
lightning-cli splice "8338aef0 -> 0.9M+fee; 0.9M -> 1JfbZRwdDHKZmuiZgYArJZhcuuzuw2HuMu"
```

Move 1 bitcoin between two channels
```shell
lightning-cli splice "8338aef0 -> 1btc; 100% -> 07bfddea"
```

Splice in 100 thousand sats to the first channel with peer id 034645dc
```shell
lightning-cli splice "wallet -> 0.1M; 1008 -> 034645dc:?"
```

Splice in 100 thousand sats split across *all* channels with peer id 034645dc
```shell
lightning-cli splice "wallet -> 100000; 100% -> 034645dc:*"
```

Take the maximum out of one chanel and split the value across peer 034645dc's
channel plus one more channel
```shell
lightning-cli splice "8338aef0 -> 100%; * -> 034645dc:*; * -> 07bfddea"
```

RETURN VALUE
------------

[comment]: # (GENERATE-FROM-SCHEMA-START)
On success, an object is returned, containing:

- **dryrun** (array of strings, optional): The transcript of what the script would have done:
- One action line of the splice script result
- **psbt** (string, optional): The final transaction
- **txid** (string, optional): The txid of the final transaction

[comment]: # (GENERATE-FROM-SCHEMA-END)

SEE ALSO
--------

lightning-splice\_signed(7)

AUTHOR
------

@dusty\_daemon

RESOURCES
---------

Main web site: <https://github.com/ElementsProject/lightning>

[comment]: # ( SHA256STAMP:28429623ddad3b5886899314dfb364d44f598f016cc25ea10f05754b6b51c4a9)
Loading

0 comments on commit ab42c23

Please sign in to comment.