Comment on page
🤖
REST API
This page lists all available endpoints of Boltz's RESTful HTTP API and shows how to use them.
All the responses to all calls are encoded as
JSON
objects. If endpoints require the client to provide any kind of arguments these also have to be encoded as JSON
and sent in the body of a POST
request. Make sure to set the Content-Type
header of your POST
requests to application/json
if you are sending JSON
encoded data in the body of the request.If a call fails for some reason the returned HTTP status code will indicate that, and an object will be returned that looks like this and gives the reason why the call failed:
{
"error": "message explaining why the call failed"
}
Returns the version of Boltz Backend serving the API. A good call to get started and see if Boltz API requests and responses are working.
URL | Response |
---|---|
GET /version | JSON object |
Status Codes:
200 OK
Response object:
version
: the deployed version of Boltz Backend
Examples:
GET /version
{
"version":"3.2.1-7c38088"
}
In order to create a swap, one first has to know which pairs are supported and what kind of rates, limits and fees are applied when creating a new swap. The following call returns this information.
URL | Response |
---|---|
GET /getpairs | JSON object |
Status Codes:
200 OK
Response object:
info
: contains information about special configuration parameters of the Boltz Backend deployment. As of writing this there is only one possible value:prepay.minerfee
: If the array contains this value, Boltz requires a small invoice for the miner fee to be paid before the actual hold invoice of a Reverse Swap is revealed. As of writing, Boltz does not require this prepayment and thus returns an empty array.
warnings
: an array of strings that indicate that some feature of Boltz might me disabled or restricted. An example of a warning is:reverse.swaps.disabled
: Means that all reverse swaps (from Lightning to the chain) are disabled.
pairs
: an object containing the supported pairs. The keys of the values are the IDs of the pairs (BTC/BTC
is a special case with mainchain bitcoin as base asset and Lightning bitcoin as quote asset) and the values itself contain information about the pair:hash
: SHA256 hash of theJSON
encoded data in the pair object.rate
: The exchange rate of the pair.limits
: aJSON
Object containing the minimal and maximal amount of the pair's swap. The numbers are denominated 10 ** -8 of the quote asset.maximalZeroConf
: The maximal amounts that will be accepted without chain confirmations by Boltz.
fees
: AJSON
object that contains different kinds of fees:percentage
: The percentage of the "send amount" that is charged by Boltz as "Boltz Fee" for swaps from quote to base asset (e.g. Lightning -> Bitcoin).percentageSwapIn
: The percentage of the "send amount" that is charged by Boltz as "Boltz Fee" for a swap from base to quote asset (e.g. Bitcoin -> Lightning).minerFees
: The network fees charged for locking up and claiming funds on the chain. These values are absolute, denominated in 10 ** -8 of the quote asset.
Examples:
GET /getpairs
Response:
{
"info": [],
"warnings": [],
"pairs": {
"BTC/BTC": {
"hash": "05d0f522ef08dd66fa0f87f167cc1380eaf7e5227e698941ecb44876e0736cb8",
"rate": 1,
"limits": {
"maximal": 10000000,
"minimal": 50000,
"maximalZeroConf": {
"baseAsset": 0,
"quoteAsset": 0
}
},
"fees": {
"percentage": 0.5,
"percentageSwapIn": 0.1,
"minerFees": {
"baseAsset": {
"normal": 1360,
"reverse": {
"claim": 1104,
"lockup": 1224
}
},
"quoteAsset": {
"normal": 1360,
"reverse": {
"claim": 1104,
"lockup": 1224
}
}
}
}
},
"L-BTC/BTC": {
"hash": "769215ae0f8cb14d250374a77de530ac2887c927dc08f8efce74f3634df03171",
"rate": 1,
"limits": {
"maximal": 10000000,
"minimal": 10000,
"maximalZeroConf": {
"baseAsset": 0,
"quoteAsset": 0
}
},
"fees": {
"percentage": 0.25,
"percentageSwapIn": 0.1,
"minerFees": {
"baseAsset": {
"normal": 147,
"reverse": {
"claim": 152,
"lockup": 276
}
},
"quoteAsset": {
"normal": 1360,
"reverse": {
"claim": 1104,
"lockup": 1224
}
}
}
}
}
}
}
This section walks you through creating Normal Submarine Swaps (Chain -> Lightning). They differ slightly depending on the kind of bitcoin that are swapped, more information below. Please note that Boltz works with 10 ** -8 decimals internally and all amounts in the API endpoints follow this denomination. All requests to create swaps have the following common values in the API request:
type
: type of the swap to create. For Normal Submarine Swaps this issubmarine
.orderSide
: currently we recommend usingsell
across all pairs of swap typesubmarine
. The valuebuy
for e.g. theL-BTC/BTC
pair signifies a swap from mainchain Bitcoin to Liquid Lightning. As of writing, this is not supported and the backend will return"error": "L-BTC has no lightning support"
Normal Submarine Swaps: If you already know the amount to be swapped, you should also set
invoice
.invoice
: the invoice of the user that should be paid
If the amount is not known yet, a preimage hash has be specified. The invoice that is provided later during the lifecycle of the Submarine Swap has to have the same preimage hash as the one specified here.
preimageHash
: hash of a preimage that will be used for the invoice that is set later on
We recommend verifing that pair data fetched previously is still accurate by additionally passing the
pairHash
argument in this call.URL | Response |
---|---|
POST /createswap | JSON object |
Status Codes:
201 Created
400 Bad Request
: if the swap could not be created. Check theerror
string in theJSON
object of the body of the response for more information
Response objects:
Response objects of all swaps have these value in common:
id
: id of the newly created swaptimeoutBlockHeight
: base asset block height at which the swap will expire and be cancelledaddress
: address in which the bitcoin will be locked up. For UTXO chains this is a SegWitP2SHP2WSH
(P2WSH
nested in aP2SH
) for the sake of compatibility and for RSK it is the address of the contract that needs to be used
If a lightning invoice is set in this call, one will also find the following values in the response:
acceptZeroConf
: whether Boltz will accept 0-conf for this swapexpectedAmount
: the amount that Boltz expects to be locked on the chain
Normal Submarine Swaps from UTXO chains like Bitcoin work by deriving an address based on the preimage hash (of the invoice) and the refund public key of the user. Boltz then waits until the user sent bitcoin to the generated address.
Requests for these kind of swaps have to contain one additional parameter:
refundPublicKey
: public key of a keypair that will allow the user to refund the locked up bitcoin once the time lock is expired. This keypair has to be generated and stored by the client integrating Boltz API.
Responses also contain one additional value:
redeemScript
: redeem script from which theaddress
is derived. The redeem script can (and should!) be used to verify that the Boltz didn't try to cheat by providing an address without HTLC
In case the address is for the Liquid Network, it will be blinded by a key that is also in the response:
blindingKey
: hex encoded private key with which the address was blinded
If the invoice has been set, you will also get this value:
Examples:
POST /createswap
Request body:
{
"type": "submarine",
"pairId": "BTC/BTC",
"orderSide": "sell",
"refundPublicKey": "AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBGBkraVi05Eyn6slRQV5h+fX6rtpudOq0LqPEnbnbxRshMdhS56vKWawUNLkLZZ4hKsTdbJZvgTtO/rDc2WI/Gw",
"invoice": "lntb1m1pjv0dt5pp5y9dl3z50c5g6p26a86g432zdzvdlx6a565hk55a2ellz3t9f84jsdqqcqzzsxqyz5vqsp5a4k0f59u62na3fngv24nv5xjuxyf6qjnnj806se373h4gt9fmejq9qyyssqpeh42yy72pqzfwdfehvuru9s735vrgg324lxdp9gg8w6m379w8ajd3sxyy6f0qqfqa6vhk5k4pqfz6nys3u5xf68wcjyjygykn7za6cqf6flce"
}
Response:
{
"id": "E63LC4",
"bip21": "bitcoin:2NBBYeBZgY64nJKiibnGokwrBBPjoQeMzyx?amount=0.0010054&label=Send%20to%20BTC%20lightning",
"address": "2NBBYeBZgY64nJKiibnGokwrBBPjoQeMzyx",
"redeemScript": "a9148f8d01a3e1a794024fa78bd9c81d5ae9bb1c56d287632102bba4fbfe50ea8caf880cb367f7b0083c7e91c2bc2808c817823bd36385e3a376670319b125b17503aaaae268ac",
"acceptZeroConf": false,
"expectedAmount": 100540,
"timeoutBlockHeight": 2470169
}
POST /createswap
Request body:
{
"type": "submarine",
"pairId": "BTC/BTC",
"orderSide": "sell",
"refundPublicKey": "AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBGBkraVi05Eyn6slRQV5h+fX6rtpudOq0LqPEnbnbxRshMdhS56vKWawUNLkLZZ4hKsTdbJZvgTtO/rDc2WI/Gw",
"invoice": "lntb10m1pjv0w7jpp5upaf56avdlkjv9h602m9heaa004reuc36yjf2hwzcv3tk0kjaekqdqqcqzzsxqyz5vqsp5klkwplct9kuzp8whrmjvqxqjhnga907aa953xdeaqypa8mn6chtq9qyyssqlywerx9cdqxukf640kphw2rtz6uamtc0g94h7jt99jpspjxn653h6gn30a6ejndh4xuxuf2gxn2sndgqhvs33s5ayg70z4p4f7n267gp4tytl0",
"channel": {
"auto": true,
"private": false,
"inboundLiquidity": 30
}
}
Response:
{
"id": "e1Qtxa",
"bip21": "bitcoin:2Muq74He81w8Ts4n3zhPFd1JZbuWC62czux?amount=0.0100234&label=Send%20to%20BTC%20lightning",
"address": "2Muq74He81w8Ts4n3zhPFd1JZbuWC62czux",
"redeemScript": "a91479674970eaa348958799f6fc41ef379d00f9060f8763210385ad894cdd1f27f4c88ef403100420eed6cc006965a3a58e277cb05c6f469d6667031ab125b17503aaaae268ac",
"acceptZeroConf": false,
"expectedAmount": 1002340,
"timeoutBlockHeight": 2470170
}
Currently Boltz only supports RSK Testnet
Swaps from account-based EVM chains like RSK do not require a new address for every swap.
/createswap
takes the details of the swap (like lightning invoice and pair) and Boltz waits until the user locked e.g. RBTC in the contract. The addresses of those contracts can be queried with /getcontracts
and the address of the contract that needs to be used for the swap is also returned in the response of this request.The request does not require any additional values.
But the response has one additional value:
claimAddress
: which is e.g. the RSK address of Boltz. It is specified in thelock
function of the swap contract
Examples:
POST /createswap
Request body:
{
"type": "submarine",
"pairId": "RBTC/BTC",
"orderSide": "buy",
"invoice": "lnbcrt1m1p0c26rvpp5hctw8zukj00tsxay5436y43qxc5gwvdc6k9zcxnce4zer7p5a4eqdqqcqzpgsp59mwcr4cj6wq68qj6pzyjtq2j89vnpumsejdmhw5uy4yukq3vd64s9qy9qsq2537ph4kt4xryq27g5juc27v2tkx9y90hpweyqluku9rt5zfexfj6n2fqcgy7g8xx72fklr6r7qul27jd0jzvssvrhxmwth7w4lrq7sqgyv0m7"
}
Response:
{
"id": "7PSEtx",
"address": "0xD104195e630A2E26D33c8B215710E940Ca041351",
"claimAddress": "0xe20fC13bad486fEB7F0C87Cad42bC74aAc319684",
"acceptZeroConf": false,
"expectedAmount": 1387707329,
"timeoutBlockHeight": 2006
}
When sending chain bitcoin, before setting the invoice of a Normal Submarine Swap, you'll need to use this endpoint to figure out what the amount of the invoice you set should be. Send a
POST
request with a JSON
encoded body with this value:id
: id of the Submarine Swap
URL | Response |
---|---|
POST /swaprates | JSON object |
Status Codes:
200 OK
400 Bad Request
: if the invoice amount could not be calculated. Check theerror
string in theJSON
object of the body of the response for more information. A common case is where the user did not lock up chain bitcoin yet, which is a requirement in order to calculate an invoice amount:"error": "no coins were locked up yet"
Response object:
Examples:
Request body:
{
"id": "BY8asG"
}
Response:
{
"invoiceAmount": 15713393
}
In case the amount to be swapped is not known when creating a Normal Submarine Swap, the invoice can be set afterwards; even if the chain bitcoin were sent already. Please keep in mind that the invoice has to have the same preimage hash that was specified when creating the swap. Although the invoice can be changed after setting it initially, this endpoint will only work if Boltz did not try to pay the initial invoice yet. Requests to this endpoint have to be
POST
and should have the following values in its JSON
encoded body:id
: id of the swap for which the invoice should be setinvoice
: invoice of the user that should be paid
URL | Response |
---|---|
POST /setinvoice | JSON object |
Status Codes:
200 OK
400 Bad Request
: if the invoice could not be set. Check theerror
string in theJSON
object of the body of the response for more information
Response objects:
What is returned when the invoice is set depends on the status of the Submarine Swap. If no funds were sent (status
swap.created
) the endpoint will return a JSON
object with these values:acceptZeroConf
: whether Boltz will accept 0-conf for this swapexpectedAmount
: the amount that Boltz expects you to lock in the chain HTLCbip21
: a BIP21 payment request for theexpectedAmount
of bitcoin and theaddress
(only set when swapping from UTXO chains)
If chain bitcoin were sent already (status
transaction.mempool
or transaction.confirmed
) the endpoint will return an empty JSON
object, signifying success.In case this endpoint is called again after an invoice was set and Boltz tried to pay it already:
error
: error message explaining that Boltz tried to pay the invoice already and that it cannot be changed anymoreinvoice
: the invoice that was set and that will be used for the swap
Examples:
If no bitcoin were sent yet:
POST /setinvoice
Request body:
{
"id": "UwHIPg",
"invoice": "lnbcrt1m1p08epqjpp5yvv222x7te9asyzuhmjym083lwqpp5vlem09ewfeufyrp6f76w2sdql2djkuepqw3hjqnz5gvsxzerywfjhxuccqzpgsp5u6kxgf9daf64ptvl2ht74m6duc2neywx3ecvwxs07vf7egw5dy5s9qy9qsqakms0e7ww46q9cq2fa2ymrcx6nucfknjalkm5w4ywvjpfxdp5ya82drvdvxhqzzt2ysysh5u7rellzjse37fng3vsqafuwwz3kv4ykcquy8k29"
}
Response:
{
"acceptZeroConf": true,
"expectedAmount": 1359564,
"bip21": "bitcoin:QNaGS7WM31xANXQCbmrhXfnxUjxiGFpFwM?amount=0.01359564&label=Submarine%20Swap%20to%20BTC"
}
If bitcoin were sent already:
POST /setinvoice
Request body:
{
"id": "UwHIPg",
"invoice": "lnbcrt1m1p08epqjpp5yvv222x7te9asyzuhmjym083lwqpp5vlem09ewfeufyrp6f76w2sdql2djkuepqw3hjqnz5gvsxzerywfjhxuccqzpgsp5u6kxgf9daf64ptvl2ht74m6duc2neywx3ecvwxs07vf7egw5dy5s9qy9qsqakms0e7ww46q9cq2fa2ymrcx6nucfknjalkm5w4ywvjpfxdp5ya82drvdvxhqzzt2ysysh5u7rellzjse37fng3vsqafuwwz3kv4ykcquy8k29"
}
Response:
{}
If the invoice was previously set and Boltz tried to pay it already:
POST /setinvoice
Request body:
{
"id": "UwHIPg",
"invoice": "lnbcrt100u1p0gv8hjpp5j0vs0te6wykahrp3aammm46m73n2afzk6a87ezfp3p58qpcpu4wqdqqcqzpgsp5j6wue634lac577xnupy8auvq7n9062vshvvc6xszq4jt5q9phhzq9qy9qsqhs7zrs98tu669xz7w0gqy96g5pvs9p6lssmyseg7a92kpjlzramk8khyzkd8x4nl2zasekmwt45z6pe78rk032lkmshjdnesw2vukwgqtglt89"
}
Response:
{
"error": "lightning payment in progress already",
"invoice": "lnbcrt1m1p08epqjpp5yvv222x7te9asyzuhmjym083lwqpp5vlem09ewfeufyrp6f76w2sdql2djkuepqw3hjqnz5gvsxzerywfjhxuccqzpgsp5u6kxgf9daf64ptvl2ht74m6duc2neywx3ecvwxs07vf7egw5dy5s9qy9qsqakms0e7ww46q9cq2fa2ymrcx6nucfknjalkm5w4ywvjpfxdp5ya82drvdvxhqzzt2ysysh5u7rellzjse37fng3vsqafuwwz3kv4ykcquy8k29"
}
This section walks you creating Reverse Submarine Swaps (Lightning -> Chain) and is similar to creating Normal Submarine Swaps. In the same way, requests and responses change slightly depending on the kind of bitcoin involved in the swap. Keep in mind, Boltz uses 10 ** -8 as denomination for responses on the API.
All requests bodies extend from:
type
: type of the swap to create. For Reverse Submarine Swaps this isreversesubmarine
.orderSide
: currently we recommend usingbuy
across all pairs of swap typereversesubmarine
. The valuesell
for e.g. theL-BTC/BTC
pair signifies a swap from mainchain Bitcoin to Lightning on Liquid. As of writing, this is not supported and the backend will return"error": "L-BTC has no lightning support"
preimageHash
: the SHA256 hash of a preimage that was generated by the client. The size of that preimage has to be 32 bytes or claiming will fail
There are two ways to set the amount of a Reverse Swap. Either by specifying the amount of the invoice Boltz will generate:
invoiceAmount
: amount of the invoice that will be generated by Boltz
Or by setting the amount that will be locked in the chain HTLC. That amount is not what you will actually receive because of transaction fees required to claim the HTLC. But those can be approximated easily in advance and when overestimating a little, a quick confirmation of the claim transaction can be ensured.
onchainAmount
: amount Boltz will lock in the chain HTLC
We recommend verifing that pair data fetched previously is still accurate by additionally passing the
pairHash
argument in this call.URL | Response |
---|---|
POST /createswap | JSON object |
Status Codes:
201 Created
400 Bad Request
: if the swap could not be created. Check theerror
string in theJSON
object of the body of the response for more information
The
JSON
object in the response extends from:id
: id of the newly created swaplockupAddress
: address derived from theredeemScript
or contract in which Boltz will lock up bitcoininvoice
: hold invoice that needs to be paid before Boltz locks up bitcointimeoutBlockHeight
: block height at which the Reverse Swap will be cancelled
In case the invoice amount was specified, the amount that will be locked in the chain HTLC is also returned:
onchainAmount
: amount of chain bitcoin that will be locked by Boltz
Boltz backend also supports a different protocol that requires an invoice for miner fees to be paid before the actual hold
invoice
of the Reverse Submarine Swap. If that protocol is enabled, the response object will also contain a minerFeeInvoice
. Once the minerFeeInvoice
is paid, Boltz will send the event minerfee.paid
and when the actual hold invoice
is paid, the chain bitcoin will be sent.The request has to contain one additional value:
claimPublicKey
: public key of a keypair that will allow the user to claim the locked up bitcoin with the preimage. This keypair has to be generated and stored by the client integrating Boltz API.
And so has the response:
redeemScript
: redeem script from which the lockup address was derived. The redeem script can (and should!) be used to verify that Boltz didn't try to cheat by creating an address without a HTLC
In case the lockup address is on the Liquid Network, it will be blinded by a key that is also in the response:
blindingKey
: hex encoded private key with which the address was blinded
Examples:
POST /createswap
Request body:
{
"type": "reversesubmarine",
"pairId": "L-BTC/BTC",
"orderSide": "buy",
"invoiceAmount": 1000000,
"preimageHash": "51a05b15e66ecd12bf6b1b62a678e63add0185bc5f41d2cd013611f7a4b6703f",
"claimPublicKey": "03b76c1fe14bab50e52a026f35287fda75b9304bcf311ee85b4d32482400a436f5"
}
Response:
{
"id": "v3CfMa",
"invoice": "lntb10m1pjvsy8ppp52xs9k90xdmx390mtrd32v78x8twsrpdutaqa9ngpxcgl0f9kwqlsdpz2djkuepqw3hjqnpdgf2yxgrpv3j8yetnwvcqz95xqrrsssp5hzcjq972f9cl8c6u3zechepm65hjceaqvlzye6kc23qkz5rhva6q9qyyssq4kkw9fwjq7n9cm4j3ajj2a92ka0zyeg3sxppfy932c62pnsqkw7nhvg9rrxztszw37wqtal4cchw2f4s09qe48pngsl9euv7wjlz93qqrfx60s",
"blindingKey": "897034f717beb12a3c2b7ae8c08c5c4def7bc7cfb6efa3713c617f28d90d1419",
"redeemScript": "8201208763a914be1abd8e8d7ef7e64a9c6e1e2f498f3a92e078a2882103b76c1fe14bab50e52a026f35287fda75b9304bcf311ee85b4d32482400a436f5677503dbf40eb175210330fd4cfd53b5c20886415c1b67d2daa87bce2761b9be009e9d1f9eec4419ba5968ac",
"lockupAddress": "tlq1qqdd0v79wcqnpvujf5mfp88d5cz8rynk0awr6m84ca8pzn39kwagsh4z204s9d5sww3cxckd47wjxlqwl3u6tgdqfa877txqt9m8wgk22qwyp5yzxaf40",
"timeoutBlockHeight": 980187,
"onchainAmount": 995724
}
In case the prepay miner fee protocol is enabled:
Request body:
{
"type": "reversesubmarine",
"pairId": "BTC/BTC",
"orderSide": "buy",
"claimPublicKey": "0391fbaf549578fd7c2cb26b216441825bd780d85dba1f3d706e2f206587e96266",
"invoiceAmount": 100000,
"preimageHash": "2215034def003b63b2717fccd4ce8259f4807a39318c14e2bdd42639ca989a45"
}
Response body:
{
"id": "mVSKyF",
"invoice": "lnbcrt996940n1p0dhjr3pp5yg2sxn00qqak8vn30lxdfn5zt86gq73exxxpfc4a6snrnj5cnfzsdql2djkuepqw3hjqsj5gvsxzerywfjhxuccqzy0sp5hjcvwl2glrq9n3vzm8072cdruz3hhz70edml8g0u76gryve6np4q9qy9qsqzw5w8ulxjgrg478hz4enjrw0a9tedl8s3n879xqh3mhn0pxrvajrz9qnnsr58twx4a30gk57d4fykm7x3v2vcamw7k4ny9fkpwl65vcpw8v5em",
"redeemScript": "8201208763a914fb75ff5dc4272c2da33d744615905f54b62de41588210391fbaf549578fd7c2cb26b216441825bd780d85dba1f3d706e2f206587e962666775028e01b1752102c22801bd7dd3a6afb780671c1c983fcd91fa46826eadd82e325e7e13bb348a9768ac",
"lockupAddress": "bcrt1qweryu6nk8gn5lj8ar5kjdy476wynheszg0lumu6jx83l2v6f435stlel03",
"onchainAmount": 98694,
"timeoutBlockHeight": 398,
"minerFeeInvoice": "lnbcrt3060n1p0dhjr3pp5sk2u4rt0z8rrl6jj62d6szqvsdejj8kjcxa8tdt4dau5rtyskj6qdp4f45kuetjypnx2efqvehhygznwashqgr5dusyy4zrypskgerjv4ehxcqzpgsp5qtsm5vfy9yq8kjpthla67jagmcxnj529pm3edk94npf6fekq2sxq9qy9qsqmun0z8ed4kp9dhp7lthvzdrx3ngmjs32smx6l4hvyyktv92mf348aftgrwf44sl94ewywr3sw8dc4acy63yamxxpjtd4pkkr2uw2h5gpqc3d3y"
}
Currently Boltz only supports RSK Testnet
Requests to create swaps for Reverse Submarine Swaps from account-based EVM chains like RSK have to contain one additional value:
claimAddress
: address from which the bitcoin will be claimed
The response also has one more property:
refundAddress
: the address of Boltz which is specified as refund address when it is locking up funds
Also, Boltz offers an optional protocol called EVM prepay miner fee that allows the user to pay an additional lightning invoice to pay for gas on the EVM chain to claim funds. In this process, Boltz sends some e.g. RBTC to the
claimAddress
in the lockup process in case the user's claimAddress
does not have enough RBTC to pay gas to claim the funds. To use that protocol set the following property in the request body to true
.prepayMinerFee
: if the prepay miner fee protocol should be used for the Reverse Swap
When the EVM prepay miner fee protocol is used the response will contain two more values. One is the amount of RBTC that will be sent to
claimAddress
in the lockup process. The other is an invoice for the RBTC sent. Only when both invoices are paid the chain bitcoin will get locked.prepayMinerFeeAmount
: amount of e.g. RBTC that will be sent to theclaimAddress
with the lockup transaction from BoltzminerFeeInvoice
: invoice that pays for the RBTC sent in the lockup process
Examples:
POST /createswap
Request body:
{
"type": "reversesubmarine",
"pairId": "RBTC/BTC",
"orderSide": "sell",
"claimAddress": "0x88532974EC20559608681A53F4Ac8C34dd5e2804",
"invoiceAmount": 100000,
"preimageHash": "295b93a766959d607861ab7b7a6bf9e178e7c69c3cc4ca715065dfe9d6eea351"
}
Response body:
{
"id": "1H6eCx",
"invoice": "lnbcrt1m1p0ega6epp599de8fmxjkwkq7rp4dah56leu9uw035u8nzv5u2svh07n4hw5dgsdpq2djkuepqw3hjq42ng32zqctyv3ex2umncqzphsp5gxshtrx3y0mt3llm3537qqy0ylf722hykv2zm777dwap9e60glfq9qy9qsqa93q725njkt9dupu9cddtchwcmyg7zsltrw8gcyzsc4tv74ss26y00z7tutrqks8wgh8s286ayy2tmrul0q0ysvxjzv793ylcdr553gqjhgny2",
"refundAddress": "0xe20fC13bad486fEB7F0C87Cad42bC74aAc319684",
"lockupAddress": "0xD104195e630A2E26D33c8B215710E940Ca041351",
"onchainAmount": 1210297576,
"timeoutBlockHeight": 2006
}
To query the status of a swap one can use this endpoint which returns a
JSON
object containing the status of the swap. Possible states and status events are documented in the section Swap Types & States.Requests querying the status of a swap have to be
POST
and contain a single value in its JSON
encoded body:id
: the id of the swap of which the status should be queried
URL | Response |
---|---|
POST /swapstatus | JSON object |
Status Codes:
200 OK
404 Not Found
: if the swap with the provided id couldn't be found400 Bad Request
: if theid
argument wasn't provided
Response object:
status
: status of the swap, e.g.transaction.mempool
&transaction.claimed
for successful Normal Submarine Swaps andtransaction.mempool
andtransaction.confirmed
for successful Reverse Submarine Swapstransaction
: for Reverse Submarine Swaps, this field contains lockup transaction details in the statestransaction.mempool
andtransaction.confirmed
id
: id of the lockup transactionhex
: hex encoded lockup transaction (only set for transactions on UTXO chains)eta
: if the status istransaction.mempool
, this value is the estimated time of arrival (ETA) in blocks of when the transaction will be confirmed. Only set for transactions on UTXO chains.
zeroConfRejected
: set totrue
for Swaps with the statustransaction.mempool
and a lockup transaction that is not eligible for 0-conffailureReason
: set when it's necessary to further clarify the failure reason
Examples:
POST /swapstatus
Request body:
{
"id": "Asnj2Y"
}
Response:
{
"status": "invoice.paid"
}
POST /swapstatus
Request body:
{
"id": "ryUK9G"
}
Response:
{
"status": "transaction.mempool",
"transaction": {
"id": "31fcddf287d985eef85211b75976cd903dba3008a8e13b597e1b54941278c29f",
"hex": "01000000000101618cd5c50221577a1b98ae4a73f652917f9d2e343b9bc6a978239da78dfcbc630000000000ffffffff02b878010000000000220020ddc8dd3bcb45660e421fc3129bfdcb317446c27ce909369d4c8cb17bbd6d4951c718393b00000000160014ea9e0fc9432fc8b6831e94ac3974d46d1ba1c62f024830450221008b14ecce2eebb2ec7e56c53de4796603fbd22cfd269f3a5249446b79987dec36022059b68568a57ebfbd50cc792af3d514c507af20e795ff5f0bf2a02d2fc44be223012103a1ad2a3891018e856700a20a4dea6bea9f4bba58ab3ca7cbaefaa06e805770d100000000",
"eta": 2
}
}
POST /swapstatus
Request body:
{
"id": "gnIthU"
}
Response:
{
"status": "transaction.lockupFailed",
"failureReason": "locked 1396075383 is less than expected 1396075384"
}
To avoid querying the
/swapstatus
endpoint regularly to get the latest swap status, this endpoint streams swap status updates via Server-Side Events.Requests to this endpoint have to provide the required swap
id
parameter via an URL parameter because all requests have to be of the method GET
.Every event in the Server-Side stream has data that is encoded exactly like the
JSON
object of the /swapstatus
endpoint. Please have a look at the examples below for a reference implementation in JavaScript of handling the stream.URL | Response |
---|---|
GET /streamswapstatus | Server-Side event stream |
Examples:
Server-Side event streams have to be handled differently from regular HTTP responses. Below is a sample implementation in JavaScript and also what a raw response of a Server-Side event stream looks like.
Sample implementation in JavaScript:
var stream = new EventSource(boltzApi + '/streamswapstatus?id=' + swapId);
source.onmessage = function(event) {
const data = JSON.parse(event.data);
console.log('Swap status update:' + data.status);
};
Raw response:
data: {"status":"transaction.mempool"}
data: {"status":"invoice.paid"}
Boltz Swaps have different timeouts for each pair. This endpoint allows querying those timeouts denominated in blocks of the base and quote chain.
URL | Response |
---|---|
GET /timeouts | JSON object |
Status Codes:
200 OK
Response object:
timeouts
: aJSON
object with the pairs as keys and aJSON
object with the timeouts as values
Examples:
GET /timeouts
Response:
{
"timeouts": {
"BTC/BTC": {
"base": {
"reverse": 144,
"swapMinimal": 144,
"swapMaximal": 288
},
"quote": {
"reverse": 144,
"swapMinimal": 144,
"swapMaximal": 288
}
},
"L-BTC/BTC": {
"base": {
"reverse": 1440,
"swapMinimal": 1440,
"swapMaximal": 2880
},
"quote": {
"reverse": 144,
"swapMinimal": 144,
"swapMaximal": 288
}
}
}
}
Currently Boltz only supports RSK Testnet
To query the addresses of contracts used by Boltz for swaps on EVM chains like RSK, the following endpoint can be queried:
URL | Response |
---|---|
GET /getcontracts | JSON object |
Status Codes:
200 OK
Response object:
rsk
: aJSON
object that contains all relevant RSK addressesnetwork
:JSON
object that contains information about the networkchainId
: id of the RSK chain
swapContracts
:JSON
object containing swap contract addresses as valuestokens
:JSON
object with the ticker symbol of the supported token as key and its address as value
Examples:
GET /getcontracts
Response:
{
"rsk": {
"network": {
"chainId": 1337
},
"swapContracts": {
"EtherSwap": "0x165F8E654b3Fe310A854805323718D51977ad95F",
"ERC20Swap": "0x5F51247606d29Df75Af11475A85F7072f6472345"
},
"tokens": {
}
}
}
Boltz provides an API endpoint that returns fee estimations for all supported chains. These fee estimations are not enforced by Boltz and merely represent a recommendation.
For UTXO chains like Bitcoin it is important to mention that if 0-conf is accepted by Boltz for a particular pair and to be used with Normal Submarine Swaps, the lockup transaction has to have at least 80% of the recommended
sat/vbyte
value. One can read more about the what and why in the 0-conf docs.URL | Response |
---|---|
GET /getfeeestimation | JSON object |
Status Codes:
200 OK
Response object:
This endpoint returns a
JSON
object of which each key is the symbol of a chain and each value the estimated fee for that chain denominated in sat/vbyte
for UTXO chains like Bitcoin or GWEI
for EVM chains like RSK.Examples:
GET /getfeeestimation
Response:
{
"BTC": 16,
"L-BTC": 0.11
}
Boltz API also allows for querying raw transactions of all supported UTXO chains, irrespective of whether the transactions are still in the mempool or already included in a block. Note, that Boltz does not provide any kind of cryptographic proof that the transaction was included in a block. Also this call is primarily kept for backward compatibility with older integrations, it is not needed to construct transactions as the response of
/swapstatus
provides all necessary info.Requests querying for transactions have to be
POST
and contain two arguments in its JSON encoded body:currency
: which chain should be queried for the transactiontransactionId
: the id of the transaction that should be queried
URL | Response |
---|---|
POST /gettransaction | JSON object |
Status Codes:
200 OK
400 Bad Request
: if an argument wasn't provided or the transaction can't be found
Response object:
transactionHex
: the requested transaction encoded in hex
Examples:
POST /gettransaction
Request body:
{
"currency": "BTC",
"transactionId": "0e3e2357e806b6cdb1f70b54c3a3a17b6714ee1f0e68bebb44a74b1efd512098"
}
Response:
{
"transactionHex": "01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0704ffff001d0104ffffffff0100f2052a0100000043410496b538e853519c726a2c91e61ec11600ae1390813a627c66fb8be7947be63c52da7589379515d4e0a604f8141781e62294721166bf621e73a82cbf2342c858eeac00000000"
}
The following endpoint can be used to query the user's lockup transaction of a Normal Submarine Swap on UTXO chains. The request has to be
POST
and contain the following argument in the JSON
encoded body:id
: id of the Submarine Swap
URL | Response |
---|---|
POST /getswaptransaction | JSON object |
Status Codes:
200 OK
400 Bad Request
: if an argument wasn't provided, or the Submarine Swap can't be found
Response object:
transactionHex
: the lockup transaction of the Normal Submarine Swap encoded in hextimeoutBlockHeight
: block height at which the HTLC in the lockup transaction will time out
If the HTLC has not timed out yet, there will be an additional value in the response: