npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

bip-199

v1.0.13

Published

BIP-199 helpers for Bitcoin HTLC and atomic swaps

Downloads

97

Readme

Bitcoin HTLC swaps

Release Notes

  • This code is 2 weeks old. It is not yet stable.
  • refundHTLC has not been fully tested. Please open an issue if you have problems.
  • Current support is only for Bitcoin. Litecoin and ZCash will be added in the next few weeks.
  • There is a CLI client included. node cli.js help will get you documentation for that, and examples are included at the end of this README

Use Cases

  • Submarine swaps on Lightning
  • Atomic swaps across Bitcoin forks like Litecoin or Bitcoin Cash.
  • With a little extra coding, you can use this to perform atomic swaps on non-bitcoin chains like Ethereum or Solana as well.

Documentation

See module.exports and the docstrings in htlc.js for available methods and detailed documentation. The examples below will probably be more useful for development.

Creating an HTLC

const { createHTLC } = require('bip-199')

const htlc = createHTLC({
  recipientAddress: 'bcrt1qfjwqqxmf6ajmwy48pzs7ml33udt0smhdc8seya',
  refundAddress: 'bcrt1q2yuazzncplkcexkzcayj886eugkttwxefvwvm3'
})
console.log(htlc)

Output:

{
  recipientAddress: 'bcrt1qfjwqqxmf6ajmwy48pzs7ml33udt0smhdc8seya',
  refundAddress: 'bcrt1q2yuazzncplkcexkzcayj886eugkttwxefvwvm3',
  preimage: 'c68f23c9a800799447612d1b4bc09a8a05f643c01dd7de8acbde679a808f73ed',
  contractHash: 'f0d661c0c20862a0641b953c84660c649e91fbc97abe3ffd71fd344469b61dcd',
  expiration: 1724125162,
  network: 'regtest',
  addressType: 'p2wsh',
  witnessScript: '63a820f0d661c0c20862a0641b953c84660c649e91fbc97abe3ffd71fd344469b61dcd8876a9144c9c001b69d765b712a708a1edfe31e356f86eed6704ea0fc466b17576a9145139d10a780fed8c9ac2c749239f59e22cb5b8d96888ac',
  htlcAddress: 'bcrt1qd730p4644wqtvfa5h3dpdyhfu4anm6mqlsqc7al8tv0k3smazs4qcpczrq'
}

Save the HTLC JSON somewhere secure. If you lose the HTLC, you'll be unable to retrieve your funds.

If you're doing this process non-programatically, I would recommend you use the CLI. It will automatically store a backup for you that you can access later.

Any bitcoin you send to the htlcAddress will now be locked to that hash until expiry.

> bitcoin-core.cli -regtest sendtoaddress bcrt1qd730p4644wqtvfa5h3dpdyhfu4anm6mqlsqc7al8tv0k3smazs4qcpczrq 1
2d35ca1a04dafc84abedb25577fcf45c9b1cf278e569940b1621b5060dd36d62

Using an existing hash sent from a counterparty

If your counterpary in an atomic swap is holding the preimage, he will have to send you the hash.

You can use this hash to create an HTLC, and you will be able to redeem it once he reveals the preimage on his end.

We use a custom expiration as well and conduct the transaction on Bitcoin mainnet to demonstrate it.

const { createHTLC } = require('bip-199')

const htlc2 = createHTLC({
  recipientAddress: 'bc1qqcjmr6de85qv2gq54y9x59ctqxc3pjeyskqtdr',
  refundAddress: 'bc1qwr3ksdcgy7dq0mgl7gs7a0ay3kdp5r5yudk6ma',
  hash: "368278313373e68a55c8361623fc06e1fa6c8251c90348fccac939879257144d",
  network: 'bitcoin',
  expiration: (Date.now() / 1000 | 0) + 3600, // 1 hour
})
console.log(htlc2)

Output:

{
  recipientAddress: 'bcrt1qfjwqqxmf6ajmwy48pzs7ml33udt0smhdc8seya',
  refundAddress: 'bcrt1q2yuazzncplkcexkzcayj886eugkttwxefvwvm3',
  preimage: '',
  contractHash: '368278313373e68a55c8361623fc06e1fa6c8251c90348fccac939879257144d',
  expiration: 1724042530,
  network: 'bitcoin',
  addressType: 'p2wsh',
  witnessScript: '63a820368278313373e68a55c8361623fc06e1fa6c8251c90348fccac939879257144d8876a9144c9c001b69d765b712a708a1edfe31e356f86eed670422cdc266b17576a9145139d10a780fed8c9ac2c749239f59e22cb5b8d96888ac',
  htlcAddress: 'bc1qfy23h4gwx7q0uzwklwf89fyjq4jhwga6vhuaxetej64c87wgemgsymz2aj'
}

Determining HTLC vout

To refund or redeem an HTLC you need to know the index (vout) of the HTLC output within your creation transaction.

Programatically using Bitcoin Core RPC

If you have access to a Bitcon Core full node, you can get transaction vouts programatically using the built-in RPC server

const bitcoinCore = require('bitcoin-core')
const bitcoin = require('bitcoinjs-lib')

const client = new bitcoinCore({
  network: 'mainnet',
  username: 'hello',
  password: 'bitcoin'
});

async function getTxOuts (txid) {
  const rpcTx = await client.command('gettransaction', txid)
  return bitcoin.Transaction.fromHex(rpcTx.hex).outs
}

const TXID = "d8e375b891307145d7eec99e7077329b90f5496c983d0d7a43996d7bd2d4f437"
getTxOuts(TXID).then(console.log)

Output

[
  {
    value: 10000,
    script: <Buffer 00 14 d2 bd 7b 44 8e e1 95 98 c7 96 51 4b 60 e0 b3 b2 12 88 0a d6>
  },
  {
    value: 3156826,
    script: <Buffer 00 14 12 c6 bc a0 cb fe 19 b0 2d d5 a7 ea c8 5a 0c 02 08 1e 44 dc>
  }
]

Then you can select the index of the UTXO you want to unlock.

Programatically Using a Block Explorer

For this example, I am using mempool.space and an arbitrary txid. You can use any block explorer that supports pulling raw hex data.

const bitcoin = require('bitcoinjs-lib')
const axios = require('axios')

async function getTxOuts (txid) {
  const rawTx = await axios.get('https://mempool.space/api/tx/' + txid + '/hex')
  const tx = bitcoin.Transaction.fromHex(rawTx.data)
  return tx.outs
}

const TXID = "f318d73cae78fb9c312aac8c0bfce9d55fa9ab8e1e0ac75cb572deac74e20601"
getTxOuts(TXID).then(console.log)
[
  {
    value: 11000,
    script: <Buffer 00 14 46 ae 1e 9a 4a 3b 6d cc 70 e1 de 61 14 7e 27 31 34 e7 49 0d>
  },
  {
    value: 6482,
    script: <Buffer 51 20 9c 87 b9 0f 3a b2 6a ff b5 50 5a 68 49 df 81 7b c1 e9 6f ad f5 4e b4 ac fc d7 92 91 70 ad 3a f6>
  }
]

You can now pick the index of the output you want to unlock.

Manually using bitcoin-cli

If you are running a Bitcoin Core full node, you can get the raw transaction hex and inspect it.

> bitcoin-core.cli -regtest gettransaction 2d35ca1a04dafc84abedb25577fcf45c9b1cf278e569940b1621b5060dd36d62
{
  "amount": -1.00000000,
  "fee": -0.00000165,
  "confirmations": 0,
  "trusted": true,
  "txid": "2d35ca1a04dafc84abedb25577fcf45c9b1cf278e569940b1621b5060dd36d62",
  "wtxid": "ce8e06e525c9f1276e7218b70eeee0f094c6b519c71f3ce9a3f71203b5253b1a",
  "walletconflicts": [
  ],
  "time": 1724109556,
  "timereceived": 1724109556,
  "bip125-replaceable": "yes",
  "details": [
    {
      "address": "bcrt1qqkc7qgklc4sud3pnwypj6cfdyfpyth2j4l7pygwhk5dj0wwy3jyqtceq0e",
      "category": "send",
      "amount": -1.00000000,
      "vout": 1,
      "fee": -0.00000165,
      "abandoned": false
    }
  ],
  "hex": "020000000001012bf80655c8814052821b9074bd32c0c3c3db57386d44726ee8c4ef48617c98460000000000fdffffff02db9a8b4400000000225120646101eab9a0dfe659fe8513564c1083c0120b0ed82c6079d0771f3fa2f184da00e1f5050000000022002005b1e022dfc561c6c43371032d612d224245dd52affc1221d7b51b27b9c48c880247304402201d69c58e9b3a87446c87a894cc229dd7ee4717ade2019bd4a7f1a88cb5d2efe602201fe656f527c20fca4b96a3605ea6a208c4262763c6e34309cf8236ad9a313451012102315063935d93222af241cbb82ac86f2d7abe660a68354bb06eadd0799b56ddde00000000",
  "lastprocessedblock": {
    "hash": "31762bb1a0105488e8bb1a805c99aba64c1462c8f1de50d3a2a6d2b0b337fa1e",
    "height": 506
  }
}
> bitcoin-core.cli -regtest decoderawtransaction 020000000001012bf80655c8814052821b9074bd32c0c3c3db57386d44726ee8c4ef48617c98460000000000fdffffff02db9a8b4400000000225120646101eab9a0dfe659fe8513564c1083c0120b0ed82c6079d0771f3fa2f184da00e1f5050000000022002005b1e022dfc561c6c43371032d612d224245dd52affc1221d7b51b27b9c48c880247304402201d69c58e9b3a87446c87a894cc229dd7ee4717ade2019bd4a7f1a88cb5d2efe602201fe656f527c20fca4b96a3605ea6a208c4262763c6e34309cf8236ad9a313451012102315063935d93222af241cbb82ac86f2d7abe660a68354bb06eadd0799b56ddde00000000
{
  "txid": "2d35ca1a04dafc84abedb25577fcf45c9b1cf278e569940b1621b5060dd36d62",
  "hash": "ce8e06e525c9f1276e7218b70eeee0f094c6b519c71f3ce9a3f71203b5253b1a",
  "version": 2,
  "size": 246,
  "vsize": 165,
  "weight": 657,
  "locktime": 0,
  "vin": [
    {
      "txid": "46987c6148efc4e86e72446d3857dbc3c3c032bd74901b82524081c85506f82b",
      "vout": 0,
      "scriptSig": {
        "asm": "",
        "hex": ""
      },
      "txinwitness": [
        "304402201d69c58e9b3a87446c87a894cc229dd7ee4717ade2019bd4a7f1a88cb5d2efe602201fe656f527c20fca4b96a3605ea6a208c4262763c6e34309cf8236ad9a31345101",
        "02315063935d93222af241cbb82ac86f2d7abe660a68354bb06eadd0799b56ddde"
      ],
      "sequence": 4294967293
    }
  ],
  "vout": [
    {
      "value": 11.49999835,
      "n": 0,
      "scriptPubKey": {
        "asm": "1 646101eab9a0dfe659fe8513564c1083c0120b0ed82c6079d0771f3fa2f184da",
        "desc": "rawtr(646101eab9a0dfe659fe8513564c1083c0120b0ed82c6079d0771f3fa2f184da)#qy2l8r53",
        "hex": "5120646101eab9a0dfe659fe8513564c1083c0120b0ed82c6079d0771f3fa2f184da",
        "address": "bcrt1pv3ssr64e5r07vk07s5f4vnqss0qpyzcwmqkxq7wswu0nlgh3sndqluzggh",
        "type": "witness_v1_taproot"
      }
    },
    {
      "value": 1.00000000,
      "n": 1,
      "scriptPubKey": {
        "asm": "0 05b1e022dfc561c6c43371032d612d224245dd52affc1221d7b51b27b9c48c88",
        "desc": "addr(bcrt1qqkc7qgklc4sud3pnwypj6cfdyfpyth2j4l7pygwhk5dj0wwy3jyqtceq0e)#gwjyyzfy",
        "hex": "002005b1e022dfc561c6c43371032d612d224245dd52affc1221d7b51b27b9c48c88",
        "address": "bcrt1qqkc7qgklc4sud3pnwypj6cfdyfpyth2j4l7pygwhk5dj0wwy3jyqtceq0e",
        "type": "witness_v0_scripthash"
      }
    }
  ]
}

We're looking for the 1 BTC output, so you can see the vout index is 1.

Redeeming an HTLC

We will redeem the bitcoin sent to the HTLC in TXID 2d35ca1a04dafc84abedb25577fcf45c9b1cf278e569940b1621b5060dd36d62 in Creating an HTLC.

See Determining HTLC vout for instructions on getting the vout of your HTLC.

Run your redeem tx using the txid, value, and vout of your HTLC.

const TXID = "2d35ca1a04dafc84abedb25577fcf45c9b1cf278e569940b1621b5060dd36d62"
const value = 1e8 // 1 bitcoin in sats
const vout = 1
const redeemTxRaw = redeemHTLC({
  preimage: htlc.preimage,
  recipientWIF: recipientKeypair.toWIF(),
  witnessScript: htlc.witnessScript,
  txHash: TXID,
  value,
  feeRate: 10, // sat/vB
  vout
})
console.log(redeemTxRaw)

Output:

02000000000101626dd30d06b521160b9469e578f21c9b5cf4fc7755b2edab84fcda041aca352d0100000000ffffffff0130d9f505000000001600144775723b2f720f03489abb90356e6408e22fd0ce05473044022004235b860b5af19f13f58af6c16fb21496dc74acbb00b91ca3e2303248d08ec3022046f38e94f17286740a56f41b60068c39e90674277d132cd0821c4d1c2f89e4430121028c38a7431c0d87d69c7d4d0bc0d2ba394e59f9493990d1998b40612416bc651b2074279120f6fe355c598f0411f115a0398aa07db066ea81136f5c85219bfa0bdb01015d63a8209aa0fe59b6373bd6758caa9cb4278934568f437615937ecc4c4f8c2a0030759e8876a9144775723b2f720f03489abb90356e6408e22fd0ce6704a825c566b17576a9144775723b2f720f03489abb90356e6408e22fd0ce6888ac00000000

Broadcast the transaction to the network

> bitcoin-core.cli sendrawtransaction 02000000000101626dd30d06b521160b9469e578f21c9b5cf4fc7755b2edab84fcda041aca352d0100000000ffffffff0130d9f505000000001600144775723b2f720f03489abb90356e6408e22fd0ce05473044022004235b860b5af19f13f58af6c16fb21496dc74acbb00b91ca3e2303248d08ec3022046f38e94f17286740a56f41b60068c39e90674277d132cd0821c4d1c2f89e4430121028c38a7431c0d87d69c7d4d0bc0d2ba394e59f9493990d1998b40612416bc651b2074279120f6fe355c598f0411f115a0398aa07db066ea81136f5c85219bfa0bdb01015d63a8209aa0fe59b6373bd6758caa9cb4278934568f437615937ecc4c4f8c2a0030759e8876a9144775723b2f720f03489abb90356e6408e22fd0ce6704a825c566b17576a9144775723b2f720f03489abb90356e6408e22fd0ce6888ac00000000

Congratulations. The receiver should have received the Bitcoin.

Refunding an HTLC

We will refund the bitcoin sent to the HTLC in TXID 2d35ca1a04dafc84abedb25577fcf45c9b1cf278e569940b1621b5060dd36d62 in Creating an HTLC.

See Determining HTLC vout for instructions on getting the vout of your HTLC.

The first step is to expire your HTLC. There's really no other way to do that then to wait until the expiration has been hit. You can create another HTLC without a shorter custom expiration if you don't want to wait a day. Once you have an HTLC that is expired, you can proceed with the refund.

Run your refund tx using the txid, value, and vout of your HTLC.

// Example values
const TXID = "2d35ca1a04dafc84abedb25577fcf45c9b1cf278e569940b1621b5060dd36d62"
const value = 1e8 // 1 bitcoin in sats
const vout = 1

const refundTxRaw = refundHTLC({
  refundWIF: refundKeypair.toWIF(),
  witnessScript: htlc.witnessScript,
  txHash: TXID,
  value,
  feeRate: 10, // sat/vB
  vout
})
console.log(refundTxRaw)

Output

02000000000101626dd30d06b521160b9469e578f21c9b5cf4fc7755b2edab84fcda041aca352d0100000000ffffffff0130d9f50500000000160014fd017c2bbed1821caa3b089d24343274047d4ef20448304502210085be9c286ef56bb98ddfba7638c48e359aea3ebb91227dd06c4a43a99ee1b7cb02203ce37f32cec277c5d83d72b42c65ea0ba571239808ed02ce2e1cd82b27c409230121039ab7c891dc72e793e82c2391f59fd6ad9f81a6cf038f4425cd3ebf4e509f7a3b005d63a82061736afa42077c2b014e42b76c2c1e6b10ad66f1cc5d9d97a0c0ba8a6622c7f48876a9146cf511286ed4bd6d699d12ee81cef4bc1dd90bc467049630c566b17576a914fd017c2bbed1821caa3b089d24343274047d4ef26888ac00000000

Broadcast the transaction to the network

> bitcoin-core.cli sendrawtransaction 02000000000101626dd30d06b521160b9469e578f21c9b5cf4fc7755b2edab84fcda041aca352d0100000000ffffffff0130d9f50500000000160014fd017c2bbed1821caa3b089d24343274047d4ef20448304502210085be9c286ef56bb98ddfba7638c48e359aea3ebb91227dd06c4a43a99ee1b7cb02203ce37f32cec277c5d83d72b42c65ea0ba571239808ed02ce2e1cd82b27c409230121039ab7c891dc72e793e82c2391f59fd6ad9f81a6cf038f4425cd3ebf4e509f7a3b005d63a82061736afa42077c2b014e42b76c2c1e6b10ad66f1cc5d9d97a0c0ba8a6622c7f48876a9146cf511286ed4bd6d699d12ee81cef4bc1dd90bc467049630c566b17576a914fd017c2bbed1821caa3b089d24343274047d4ef26888ac00000000

Congratulations. The refund address should have been refunded the Bitcoin.

CLI

The cli.js files contains a command-line client to interact with the BIP-199 library.

Run the client without any arguments to get a help page.

> node cli.js

Usage: bitcoin-htlc [options] [command]

BIP-199 and atomic swap helpers for Node.js

Options:
  -V, --version                                            output the version number
  -h, --help                                               display help for command

Commands:
  createkeypair [options]                                  Create a keypair
  createhtlc [options] <recipientAddress> <refundAddress>  Create an HTLC
  redeemhtlc [options] <txhash> <vout>                     Redeem an HTLC
  refundhtlc [options] <txhash> <vout>                     Refund an HTLC
  help [command]                                           display help for command

Each command has a help page as well:

> node cli.js help createhtlc

Usage: bitcoin-htlc createhtlc [options] <recipientAddress> <refundAddress>

Create an HTLC

Arguments:
  recipientAddress        bech32 address of recipient
  refundAddress           bech32 address for refund if HTLC expires

Options:
  --network <network>     regtest|testnet|bitcoin (default: "bitcoin")
  --hash <hash>           custom hash to lock HTLC. hash and preimage are generated if not provided.
  --expiration <expires>  UNIX timestamp to expire the HTLC. defaults to 1 day ahead of current time.
  -h, --help              display help for command

Examples

> node cli.js createkeypair --network regtest
Private Key (WIF): L34qRfch5BZFA4DS7BuNSZR632QZUtLA4YzaqYMbZF7WoRR7KdRX
Address (bech32): bcrt1q2ykrmuu5ue6j30900z7urlxr2feu4r0cfv0hr4
> node cli.js createhtlc bcrt1q4dphx2tr62z0apa4a76g9gezraqgzkvgtaev3l bcrt1qkg3u49vxfergs9ygz2q6tjhnuvv5uulc0t7ad7 --network regtest
{
  recipientAddress: 'bcrt1q4dphx2tr62z0apa4a76g9gezraqgzkvgtaev3l',
  refundAddress: 'bcrt1qkg3u49vxfergs9ygz2q6tjhnuvv5uulc0t7ad7',
  preimage: '29a96993b68c87ef3f55c67e2773b90139c521025b0b18919484bcd3ae94eb01',
  contractHash: '4413078df9063acbfdaed6ada9a44e6051965ed8a547d9ea040b1ebe41bf8ade',
  expiration: 1724428870,
  network: 'regtest',
  addressType: 'p2wsh',
  witnessScript: '63a8204413078df9063acbfdaed6ada9a44e6051965ed8a547d9ea040b1ebe41bf8ade8876a914ab43732963d284fe87b5efb482a3221f40815988670446b2c866b17576a914b223ca95864e468814881281a5caf3e3194e73f86888ac',
  htlcAddress: 'bcrt1qkugjjsckkwq44774xrw882fdmfeumngxhhnpg3uquarurwrwjl6swdycru'
}
> bitcoin-cli -regtest sendtoaddress bcrt1qkugjjsckkwq44774xrw882fdmfeumngxhhnpg3uquarurwrwjl6swdycru 1
9b3d8d2f72a8ee6d2b69f1db1b431f3a3d1af80648f4d9a257b3423e9adb4a8f

Save the preimage somewhere safe. you will need it to redeem the HTLC.

redeemhtlc and refundhtlc return raw signed transactions that need to be broadcast to the network

> node cli.js redeemhtlc 1e8ca887798d302d0e673e454ec151d89442d85812cbaddd2da4fdfb3a16fae0 1 --network regtest --preimage ccf49d8f0c8995e597dd87b360ea6208d7db20ec3ea60f305b16ab9dcb10899c --recipientWIF L2ip9uxsG5oqJZbpN4GFvmPFns2MBNMJG1yriZccWBNVB46nWYrz --witnessScript 63a820a81ecf3772bac085103b62e67d1d138499b1becd0f308afc6e426500b40c3d268876a914ab43732963d284fe87b5efb482a3221f40815988670492a7c866b17576a914b223ca95864e468814881281a5caf3e3194e73f86888ac --feeRate 10 --valueBTC 0.2
02000000000101e0fa163afbfda42dddadcb1258d84294d851c14e453e670e2d308d7987a88c1e0100000000ffffffff018020310100000000160014ab43732963d284fe87b5efb482a3221f40815988054730440220213797ec18aee4857e1067212314fe2857d90d2da6dbcf2166db5739fc4d907602204dbe6fbb33a078939f8cb33039bc2cd97f9f7b2d88a6b794ba0e4b582a5d4ee00121035f15f7a38030e59c33e066cba47eb66153882fbc6a7dc477ba82973862573b5520ccf49d8f0c8995e597dd87b360ea6208d7db20ec3ea60f305b16ab9dcb10899c01015d63a820a81ecf3772bac085103b62e67d1d138499b1becd0f308afc6e426500b40c3d268876a914ab43732963d284fe87b5efb482a3221f40815988670492a7c866b17576a914b223ca95864e468814881281a5caf3e3194e73f86888ac00000000
> bitcoin-cli sendrawtransaction 02000000000101e0fa163afbfda42dddadcb1258d84294d851c14e453e670e2d308d7987a88c1e0100000000ffffffff018020310100000000160014ab43732963d284fe87b5efb482a3221f40815988054730440220213797ec18aee4857e1067212314fe2857d90d2da6dbcf2166db5739fc4d907602204dbe6fbb33a078939f8cb33039bc2cd97f9f7b2d88a6b794ba0e4b582a5d4ee00121035f15f7a38030e59c33e066cba47eb66153882fbc6a7dc477ba82973862573b5520ccf49d8f0c8995e597dd87b360ea6208d7db20ec3ea60f305b16ab9dcb10899c01015d63a820a81ecf3772bac085103b62e67d1d138499b1becd0f308afc6e426500b40c3d268876a914ab43732963d284fe87b5efb482a3221f40815988670492a7c866b17576a914b223ca95864e468814881281a5caf3e3194e73f86888ac00000000
f3af089519fa5a77354797f8dcb6cbc099f44eca3bc7a67b4962277d10ec29e4
> node cli.js refundhtlc 1e8ca887798d302d0e673e454ec151d89442d85812cbaddd2da4fdfb3a16fae0 1 --network regtest --refundWIF L2ip9uxsG5oqJZbpN4GFvmPFns2MBNMJG1yriZccWBNVB46nWYrz --witnessScript 63a820a81ecf3772bac085103b62e67d1d138499b1becd0f308afc6e426500b40c3d268876a914ab43732963d284fe87b5efb482a3221f40815988670492a7c866b17576a914b223ca95864e468814881281a5caf3e3194e73f86888ac --feeRate 10 --valueBTC 0.2
02000000000101e0fa163afbfda42dddadcb1258d84294d851c14e453e670e2d308d7987a88c1e0100000000ffffffff018020310100000000160014ab43732963d284fe87b5efb482a3221f40815988044730440220213797ec18aee4857e1067212314fe2857d90d2da6dbcf2166db5739fc4d907602204dbe6fbb33a078939f8cb33039bc2cd97f9f7b2d88a6b794ba0e4b582a5d4ee00121035f15f7a38030e59c33e066cba47eb66153882fbc6a7dc477ba82973862573b55005d63a820a81ecf3772bac085103b62e67d1d138499b1becd0f308afc6e426500b40c3d268876a914ab43732963d284fe87b5efb482a3221f40815988670492a7c866b17576a914b223ca95864e468814881281a5caf3e3194e73f86888ac00000000
> bitcoin-cli sendrawtransaction 02000000000101e0fa163afbfda42dddadcb1258d84294d851c14e453e670e2d308d7987a88c1e0100000000ffffffff018020310100000000160014ab43732963d284fe87b5efb482a3221f40815988044730440220213797ec18aee4857e1067212314fe2857d90d2da6dbcf2166db5739fc4d907602204dbe6fbb33a078939f8cb33039bc2cd97f9f7b2d88a6b794ba0e4b582a5d4ee00121035f15f7a38030e59c33e066cba47eb66153882fbc6a7dc477ba82973862573b55005d63a820a81ecf3772bac085103b62e67d1d138499b1becd0f308afc6e426500b40c3d268876a914ab43732963d284fe87b5efb482a3221f40815988670492a7c866b17576a914b223ca95864e468814881281a5caf3e3194e73f86888ac00000000
f3af089519fa5a77354797f8dcb6cbc099f44eca3bc7a67b4962277d10ec29e4