version: bump to v0.12.0-beta
|13 hours ago|
|.github||5 months ago|
|cmd||2 days ago|
|docs||2 days ago|
|labels||1 month ago|
|liquidity||1 day ago|
|loopd||2 days ago|
|loopdb||4 months ago|
|looprpc||2 days ago|
|lsat||8 months ago|
|swap||6 months ago|
|sweep||6 months ago|
|test||3 days ago|
|.gitignore||10 months ago|
|.golangci.yml||1 year ago|
|.travis.yml||4 months ago|
|DOCKER.md||4 weeks ago|
|Dockerfile||1 day ago|
|LICENSE||2 years ago|
|Makefile||4 months ago|
|README.md||2 weeks ago|
|client.go||5 months ago|
|client_test.go||4 months ago|
|config.go||8 months ago|
|executor.go||8 months ago|
|go.mod||1 month ago|
|go.sum||1 month ago|
|interface.go||4 months ago|
|log.go||1 year ago|
|loopin.go||3 days ago|
|loopin_test.go||3 days ago|
|loopin_testcontext_test.go||5 months ago|
|loopout.go||4 months ago|
|loopout_test.go||5 months ago|
|release.sh||6 months ago|
|release_notes.md||1 day ago|
|server_mock_test.go||4 months ago|
|store_mock_test.go||8 months ago|
|swap.go||5 months ago|
|swap_server_client.go||1 month ago|
|testcontext_test.go||5 months ago|
|uncharge_state.go||2 years ago|
|updates.go||7 months ago|
|version.go||1 day ago|
Lightning Loop is a non-custodial service offered by Lightning Labs to bridge on-chain and off-chain Bitcoin using submarine swaps. This repository is home to the Loop client and depends on the Lightning Network daemon lnd. All of lnd’s supported chain backends are fully supported when using the Loop client: Neutrino, Bitcoin Core, and btcd.
In the current iteration of the Loop software, two swap types are supported:
We call off-chain to on-chain swaps, a Loop Out. The service can be used in various situations:
We call our on-chain to off-chain swaps, a Loop In. This allows you to use on-chain funds to increase the local balance of a channel, effectively "refilling" an existing channel.
Potential uses for Loop In:
The Loop client is currently in an early beta state, and offers a simple command line application. Future APIs will be added to support implementation or use of the Loop service.
LND and the loop client are using Go modules. Make sure that the
env variable is set to
In order to execute a swap, you need to run a compatible lnd version built with the correct sub-servers enabled.
To run loop, you need a compatible version of
lnd running. It is generally
recommended to always keep both
loop updated to the most recent
If you are building from source make sure you are using the latest tagged version of lnd. You can get this by git cloning the repository and checking out a specific tag:
git clone https://github.com/lightningnetwork/lnd.git cd lnd git checkout v0.x.x-beta
Once the lnd repository is cloned, it will need to be built with special build tags that enable the swap. This enables the required lnd rpc services.
make install tags="signrpc walletrpc chainrpc invoicesrpc"
Check to see if you have already installed lnd. If you have, you will need to
.macaroon files from your lnd directory and restart lnd.
Do not delete any other files other than the
// Example on Linux to see macaroons in the default directory: ls ~/.lnd/data/chain/bitcoin/mainnet
This should show no
.macaroon files. If it does? Stop lnd, delete macaroons,
Now delete the .macaroon files and restart lnd. (don't delete any other files)
After lnd is installed, you will need to clone the Lightning Loop repo and install the command line interface and swap client service.
git clone https://github.com/lightninglabs/loop.git cd loop/cmd go install ./...
After you have lnd and the Loop client installed, you can execute a Loop swap.
The Loop client needs its own short-lived daemon which will deal with the swaps in progress.
Command to start
loopd // Or if you want to do everything in the same terminal and background loopd loopd & // For testnet mode, you'll need to specify the network as mainnet is the default: loopd --network=testnet
loopd attempts to connect to the lnd instance running on
localhost:10009 and reads the macaroon and tls certificate from
This can be altered using command line flags. See
loopd only listens on localhost and uses an unencrypted and unauthenticated
connection. If you set
loop will use TLS encryption
and macaroon authentication, see Authentication and transport security
for more details.
Now that loopd is running, you can initiate a simple Loop Out. This will pay out Lightning off-chain funds and you will receive Bitcoin on-chain funds in return. There will be some chain and routing fees associated with this swap.
NAME: loop out - perform an off-chain to on-chain swap (looping out) USAGE: loop out [command options] amt [addr] DESCRIPTION: Attempts to loop out the target amount into either the backing lnd's wallet, or a targeted address. The amount is to be specified in satoshis. Optionally a BASE58/bech32 encoded bitcoin destination address may be specified. If not specified, a new wallet address will be generated. OPTIONS: --channel value the 8-byte compact channel ID of the channel to loop out (default: 0) --addr value the optional address that the looped out funds should be sent to, if let blank the funds will go to lnd's wallet --amt value the amount in satoshis to loop out (default: 0) --conf_target value the number of blocks from the swap initiation height that the on-chain HTLC should be swept within (default: 6) --max_swap_routing_fee value the max off-chain swap routing fee in satoshis, if not specified, a default max fee will be used (default: 0) --fast Indicate you want to swap immediately, paying potentially a higher fee. If not set the swap server might choose to wait up to 30 minutes before publishing the swap HTLC on-chain, to save on its chain fees. Not setting this flag therefore might result in a lower swap fee.
It's possible to receive more inbound capacity on a particular channel
--channel), and also have the
loop daemon send the coins to a target
addr). The latter option allows ones to effectively send on-chain
from their existing channels!
loop out <amt_in_satoshis>
This will take some time, as it requires an on-chain confirmation. When the
swap is initiated successfully,
loopd will see the process through.
To query in-flight swap statuses, run
The loop client also has the ability to automatically dispatch loop out swaps on your behalf - see our autoloop documentation for details.
The following is an example output of a 0.01 BTC fast (non-batched) Loop Out
$ loop out --amt 1000000 --fast Max swap fees for 1000000 sat Loop Out: 36046 sat Fast swap requested. CONTINUE SWAP? (y/n), expand fee detail (x): x Estimated on-chain sweep fee: 149 sat Max on-chain sweep fee: 14900 sat Max off-chain swap routing fee: 20010 sat Max off-chain prepay routing fee: 36 sat Max no show penalty (prepay): 1337 sat Max swap fee: 1100 sat CONTINUE SWAP? (y/n):
14900 + 20010 + 36 + 1100(see below).
miner_feein the gRPC/REST responses.
--conf_targetflag is always performed before sweeping. The factor of
100times the estimated fee is applied in case the fees spike between the time the swap is initiated and the time the HTLC can be swept. But that is the absolute worst-case fee that will be paid. If there is no fee spike, a normal, much lower fee will be used.
prepay_amtin the gRPC/REST responses.
swap_feein the gRPC/REST responses.
By default, Loop Outs are executed as normal speed swaps. This means the server will wait up to 30 minutes until it publishes the HTLC on-chain to improve the chances that it can be batched together with other user's swaps to reduce the on-chain footprint and fees. The server offers a reduced swap fee for slow swaps to incentivize users to batch more.
If a swap should be executed immediately, the
--fast flag can be used. Fast
swaps won't benefit from a reduced swap fee.
Additionally, Loop In is now also supported for mainnet as well. A Loop In swap lets one refill their channel (ability to send more coins) by sending to a special script on-chain.
NAME: loop in - perform an on-chain to off-chain swap (loop in) USAGE: loop in [command options] amt DESCRIPTION: Send the amount in satoshis specified by the amt argument off-chain. OPTIONS: --amt value the amount in satoshis to loop in (default: 0) --external expect htlc to be published externally --conf_target value the target number of blocks the on-chain htlc broadcast by the swap client should confirm within (default: 0) --last_hop value the pubkey of the last hop to use for this swap
--external argument allows the on-chain HTLC transacting to be published
externally. This allows for a number of use cases like using this address to
withdraw from an exchange into your Lightning channel!
A Loop In swap can be executed a follows:
loop in <amt_in_satoshis>
The following is an example output of a 0.01 BTC Loop In swap from
$ loop in --amt 1000000 Max swap fees for 1000000 sat Loop In: 1562 sat CONTINUE SWAP? (y/n), expand fee detail (x): x Estimated on-chain HTLC fee: 154 sat Max swap fee: 1100 sat CONTINUE SWAP? (y/n):
lnd's wallet based on the available UTXOs and current network fees. This value is called
miner_feein the gRPC/REST responses.
swap_feein the gRPC/REST responses.
loopd is terminated (or killed) for whatever reason, it will pickup
pending swaps after a restart.
Information about pending swaps is stored persistently in the swap database.
Its location is
The gRPC and REST connections of
loopd are encrypted with TLS and secured with
macaroon authentication the same way
If no custom loop directory is set then the TLS certificate is stored in
~/.loop/<network>/tls.cert and the base macaroon in
loop command will pick up these file automatically on mainnet if no custom
loop directory is used. For other networks it should be sufficient to add the
--network flag to tell the CLI in what sub directory to look for the files.
For more information on macaroons, see the macaroon documentation of lnd.
NOTE: Loop's macaroons are independent from
lnd's. The same macaroon
cannot be used for both
It is possible to execute multiple swaps simultaneously. Just keep loopd running.
The Loop server API and on-chain scripts are kept backwards compatible as long as reasonably possible.
When breaking changes to the Loop client daemon API are made, old fields will be marked as deprecated. Deprecated fields will remain supported until the next minor release.