Submarine Swaps is a novel way of bridging the gap between the Lightning Network and onchain Bitcoin blockchain funds. The scenario is as follows: Alice and Bob has a Lightning Network channel. All the money is on Alice’s side, and Bob would like to have some funds on his side. He sends Alice money on the Bitcoin blockchain, and Alice sends him money on Lightning. This is done in such a way that either both transactions happen, or both parties get their money back. This is what is called an atomic swap, where no funds are at risk because the other party is malicious.

In this post we will try and explain Submarine Swaps on a technical level. If you’re not familiar with technical concepts of Bitcoin and Lightning, you’ll most likely have a hard time following along. Feel free to check out our two blog post series on Lightning: Lightning 101 and Lightning 101 For Exchanges.

We will be using code samples from Bitcoin-S, an open source Bitcoin library for the JVM platform.

We provide actual values from a submarine swap that took place through the service submarineswaps.org (available on GitHub as swaps-service), on testnet. In this scenario Alice is the one running swaps-service. She takes a small cut of all submarine swaps offered through her site, so she can earn some money on her excess Lightning liquidity.

First, Bob generates a Lightning invoice: lntb50u1pw2ccvqpp5n9rqyqg73hat5zcyqhy062vzmn50xdnft4cd454le0nn32vtcddqdqqcqzpgxqyz5vq4g47trzjl92w3pjv0yvle76kv3rmktw73qutxku7zqjkxjs7w3x53w0t88vvdyqagjze32qp77zatgkpep6xm2a4863r6cmt3de0m8cpjjh2ug. We will need the payment hash of this invoice:

Alice generates a refund paper wallet, with a redeem script that says the following:

Either
Alice provides a valid signature AND the preimage to Bob's
invoice hash
# Alice obtains this preimage by paying Bob's invoice
# this branch pays out to Alice
Or
Bob provides a valid signature AFTER a set period of time
# this branch pays out to the paper wallet Alice generated
# for Bob, and is Bob's way of getting a refund if something
# goes wrong, or Alice stops cooperating

In our case, this redeem script looks like 76a914e61b3856d9bd9fa6fbda05e2b8b23c233d0d1b1987637521024727ccb84a422147672cbe753cb21d604ef7591d407b34cb87b9c54765467d42670380bd16b17576a914fb5ae6f8db1ce86021250e8b7f7f0c5f1b80c6478868acwhich decodes to:

OP_DUP
OP_HASH160
# this is the hash in the invoice Bob sent to Alice
e61b3856d9bd9fa6fbda05e2b8b23c233d0d1b19
OP_EQUAL
OP_IF
OP_DROP
# Alice's pubkey, first branch from above
024727ccb84a422147672cbe753cb21d60...
OP_ELSE
# wait until block 1490304
1490304
OP_CHECKLOCKTIMEVERIFY
OP_DROP

# and then refund to Bob, second branch from above
OP_DUP
OP_HASH160
fb5ae6f8db1ce86021250e8b7f7f0c5f1b80c647
OP_EQUALVERIFY
OP_ENDIF
OP_CHECKSIG

There’s multiple different scenarios possible when executing a submarine swap, when it comes to whether to check for public key equality or hashed public key equality in our Bitcoin Script smart contract. In this post we’ll be looking at the variant that uses the latter.

If you’re curious about the other variants, you can read chain_swap_script.mdin the swaps-service repo.

The paper wallet Alice generated and sent to Bob contains the redeem script above, as well as the WIF private keycRdnwhNmB9FjZqCXw6vpbDfQ1c2KoUP5o3qefwmJ9UZk2EyfErey. If we then convert the WIF private key to a public key and do OP_HASH160(pub) we get fb5ae6f8db1ce86021250e8b7f7f0c5f1b80c647, which matches the refund clause in the script above.

Alice then provides Bob with an address he can pay to, generated from the ASM above. In our case that address is 2N1WmDrnhkaSuMu7wbd7EkRqHfReVjTHqat.

Bob sends the amount he wants to swap (plus a fee to Alice), resulting in the transaction with txid ebecb6fd9df03c8f1b961c871fe1448d48962cffb3f4c30e8c547103851f97c5.

Alice sees that Bob just sent money she can claim up if she obtains the preimage to Bob’s Lightning invoice. She pays his invoice, and gets the preimage in return. She then uses that preimage to claim her money, in the transaction with txid 8855b6cf2b7cc6d8ed0dd7b9d072179a8b385037bba924865009bdae36d32042.

Note that Alice might want to wait for confirmations on Bob’s transaction on the blockchain before she pays the Lightning invoice. This is the same as when accepting any other unconfirmed transaction, and it’s up to each merchant/swaps operator how much risk tolerance they have

The end result is that the parties have swapped funds, with neither person having to trust the other. Alice has even gained a little money for providing liquidity services, and Bob can go and be #reckless on Lightning, for example by buying microdata subscriptions from the Suredbits Lightning APIs.