@atomiqlabs/sdk 8.9.3 → 8.9.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (366) hide show
  1. package/LICENSE +201 -201
  2. package/README.md +1763 -1760
  3. package/api/index.d.ts +1 -1
  4. package/api/index.js +3 -3
  5. package/dist/ApiList.d.ts +37 -37
  6. package/dist/ApiList.js +30 -30
  7. package/dist/SmartChainAssets.d.ts +181 -181
  8. package/dist/SmartChainAssets.js +181 -181
  9. package/dist/api/ApiEndpoints.d.ts +415 -393
  10. package/dist/api/ApiEndpoints.js +2 -2
  11. package/dist/api/ApiParser.d.ts +10 -10
  12. package/dist/api/ApiParser.js +134 -134
  13. package/dist/api/ApiTypes.d.ts +157 -157
  14. package/dist/api/ApiTypes.js +75 -75
  15. package/dist/api/SerializedAction.d.ts +40 -40
  16. package/dist/api/SerializedAction.js +59 -59
  17. package/dist/api/SwapperApi.d.ts +50 -50
  18. package/dist/api/SwapperApi.js +442 -431
  19. package/dist/api/index.d.ts +5 -5
  20. package/dist/api/index.js +24 -24
  21. package/dist/bitcoin/coinselect2/accumulative.d.ts +7 -7
  22. package/dist/bitcoin/coinselect2/accumulative.js +52 -52
  23. package/dist/bitcoin/coinselect2/blackjack.d.ts +7 -7
  24. package/dist/bitcoin/coinselect2/blackjack.js +38 -38
  25. package/dist/bitcoin/coinselect2/index.d.ts +20 -20
  26. package/dist/bitcoin/coinselect2/index.js +69 -69
  27. package/dist/bitcoin/coinselect2/utils.d.ts +82 -82
  28. package/dist/bitcoin/coinselect2/utils.js +158 -158
  29. package/dist/bitcoin/wallet/BitcoinWallet.d.ts +113 -113
  30. package/dist/bitcoin/wallet/BitcoinWallet.js +335 -335
  31. package/dist/bitcoin/wallet/IBitcoinWallet.d.ts +116 -116
  32. package/dist/bitcoin/wallet/IBitcoinWallet.js +21 -21
  33. package/dist/bitcoin/wallet/SingleAddressBitcoinWallet.d.ts +106 -106
  34. package/dist/bitcoin/wallet/SingleAddressBitcoinWallet.js +196 -196
  35. package/dist/enums/FeeType.d.ts +15 -15
  36. package/dist/enums/FeeType.js +19 -19
  37. package/dist/enums/SwapAmountType.d.ts +15 -15
  38. package/dist/enums/SwapAmountType.js +19 -19
  39. package/dist/enums/SwapDirection.d.ts +15 -15
  40. package/dist/enums/SwapDirection.js +19 -19
  41. package/dist/enums/SwapSide.d.ts +15 -15
  42. package/dist/enums/SwapSide.js +19 -19
  43. package/dist/enums/SwapType.d.ts +75 -75
  44. package/dist/enums/SwapType.js +79 -79
  45. package/dist/errors/IntermediaryError.d.ts +13 -13
  46. package/dist/errors/IntermediaryError.js +27 -27
  47. package/dist/errors/RequestError.d.ts +32 -32
  48. package/dist/errors/RequestError.js +54 -54
  49. package/dist/errors/UserError.d.ts +8 -8
  50. package/dist/errors/UserError.js +16 -16
  51. package/dist/events/UnifiedSwapEventListener.d.ts +24 -24
  52. package/dist/events/UnifiedSwapEventListener.js +138 -138
  53. package/dist/http/HttpUtils.d.ts +29 -29
  54. package/dist/http/HttpUtils.js +97 -97
  55. package/dist/http/paramcoders/IParamReader.d.ts +8 -8
  56. package/dist/http/paramcoders/IParamReader.js +2 -2
  57. package/dist/http/paramcoders/ParamDecoder.d.ts +44 -44
  58. package/dist/http/paramcoders/ParamDecoder.js +137 -137
  59. package/dist/http/paramcoders/ParamEncoder.d.ts +20 -20
  60. package/dist/http/paramcoders/ParamEncoder.js +36 -36
  61. package/dist/http/paramcoders/SchemaVerifier.d.ts +26 -26
  62. package/dist/http/paramcoders/SchemaVerifier.js +145 -145
  63. package/dist/http/paramcoders/client/ResponseParamDecoder.d.ts +11 -11
  64. package/dist/http/paramcoders/client/ResponseParamDecoder.js +57 -57
  65. package/dist/http/paramcoders/client/StreamParamEncoder.d.ts +13 -13
  66. package/dist/http/paramcoders/client/StreamParamEncoder.js +26 -26
  67. package/dist/http/paramcoders/client/StreamingFetchPromise.d.ts +17 -17
  68. package/dist/http/paramcoders/client/StreamingFetchPromise.js +175 -175
  69. package/dist/index.d.ts +86 -86
  70. package/dist/index.js +159 -159
  71. package/dist/intermediaries/Intermediary.d.ts +178 -178
  72. package/dist/intermediaries/Intermediary.js +166 -166
  73. package/dist/intermediaries/IntermediaryDiscovery.d.ts +216 -216
  74. package/dist/intermediaries/IntermediaryDiscovery.js +424 -424
  75. package/dist/intermediaries/apis/IntermediaryAPI.d.ts +607 -607
  76. package/dist/intermediaries/apis/IntermediaryAPI.js +764 -764
  77. package/dist/intermediaries/apis/TrustedIntermediaryAPI.d.ts +155 -155
  78. package/dist/intermediaries/apis/TrustedIntermediaryAPI.js +137 -137
  79. package/dist/intermediaries/auth/SignedKeyBasedAuth.d.ts +14 -14
  80. package/dist/intermediaries/auth/SignedKeyBasedAuth.js +68 -68
  81. package/dist/lnurl/LNURL.d.ts +102 -102
  82. package/dist/lnurl/LNURL.js +321 -321
  83. package/dist/prices/RedundantSwapPrice.d.ts +110 -110
  84. package/dist/prices/RedundantSwapPrice.js +222 -222
  85. package/dist/prices/SingleSwapPrice.d.ts +34 -34
  86. package/dist/prices/SingleSwapPrice.js +44 -44
  87. package/dist/prices/SwapPriceWithChain.d.ts +107 -107
  88. package/dist/prices/SwapPriceWithChain.js +128 -128
  89. package/dist/prices/abstract/ICachedSwapPrice.d.ts +28 -28
  90. package/dist/prices/abstract/ICachedSwapPrice.js +62 -62
  91. package/dist/prices/abstract/IPriceProvider.d.ts +81 -81
  92. package/dist/prices/abstract/IPriceProvider.js +74 -74
  93. package/dist/prices/abstract/ISwapPrice.d.ts +168 -168
  94. package/dist/prices/abstract/ISwapPrice.js +279 -279
  95. package/dist/prices/providers/BinancePriceProvider.d.ts +23 -23
  96. package/dist/prices/providers/BinancePriceProvider.js +30 -30
  97. package/dist/prices/providers/CoinGeckoPriceProvider.d.ts +23 -23
  98. package/dist/prices/providers/CoinGeckoPriceProvider.js +29 -29
  99. package/dist/prices/providers/CoinPaprikaPriceProvider.d.ts +25 -25
  100. package/dist/prices/providers/CoinPaprikaPriceProvider.js +29 -29
  101. package/dist/prices/providers/CustomPriceProvider.d.ts +24 -24
  102. package/dist/prices/providers/CustomPriceProvider.js +35 -35
  103. package/dist/prices/providers/KrakenPriceProvider.d.ts +38 -38
  104. package/dist/prices/providers/KrakenPriceProvider.js +45 -45
  105. package/dist/prices/providers/OKXPriceProvider.d.ts +34 -34
  106. package/dist/prices/providers/OKXPriceProvider.js +29 -29
  107. package/dist/prices/providers/abstract/ExchangePriceProvider.d.ts +17 -17
  108. package/dist/prices/providers/abstract/ExchangePriceProvider.js +21 -21
  109. package/dist/prices/providers/abstract/HttpPriceProvider.d.ts +7 -7
  110. package/dist/prices/providers/abstract/HttpPriceProvider.js +12 -12
  111. package/dist/storage/IUnifiedStorage.d.ts +127 -127
  112. package/dist/storage/IUnifiedStorage.js +2 -2
  113. package/dist/storage/UnifiedSwapStorage.d.ts +120 -120
  114. package/dist/storage/UnifiedSwapStorage.js +154 -154
  115. package/dist/storage-browser/IndexedDBUnifiedStorage.d.ts +63 -63
  116. package/dist/storage-browser/IndexedDBUnifiedStorage.js +298 -298
  117. package/dist/storage-browser/LocalStorageManager.d.ts +49 -49
  118. package/dist/storage-browser/LocalStorageManager.js +93 -93
  119. package/dist/swapper/Swapper.d.ts +770 -770
  120. package/dist/swapper/Swapper.js +1758 -1758
  121. package/dist/swapper/SwapperFactory.d.ts +135 -135
  122. package/dist/swapper/SwapperFactory.js +162 -162
  123. package/dist/swapper/SwapperUtils.d.ts +222 -222
  124. package/dist/swapper/SwapperUtils.js +519 -519
  125. package/dist/swapper/SwapperWithChain.d.ts +404 -404
  126. package/dist/swapper/SwapperWithChain.js +469 -469
  127. package/dist/swapper/SwapperWithSigner.d.ts +322 -322
  128. package/dist/swapper/SwapperWithSigner.js +318 -318
  129. package/dist/swaps/IAddressSwap.d.ts +22 -22
  130. package/dist/swaps/IAddressSwap.js +14 -14
  131. package/dist/swaps/IBTCWalletSwap.d.ts +73 -73
  132. package/dist/swaps/IBTCWalletSwap.js +18 -18
  133. package/dist/swaps/IClaimableSwap.d.ts +49 -49
  134. package/dist/swaps/IClaimableSwap.js +15 -15
  135. package/dist/swaps/IClaimableSwapWrapper.d.ts +15 -15
  136. package/dist/swaps/IClaimableSwapWrapper.js +2 -2
  137. package/dist/swaps/IRefundableSwap.d.ts +43 -43
  138. package/dist/swaps/IRefundableSwap.js +14 -14
  139. package/dist/swaps/ISwap.d.ts +453 -453
  140. package/dist/swaps/ISwap.js +371 -371
  141. package/dist/swaps/ISwapWithGasDrop.d.ts +21 -21
  142. package/dist/swaps/ISwapWithGasDrop.js +12 -12
  143. package/dist/swaps/ISwapWrapper.d.ts +295 -295
  144. package/dist/swaps/ISwapWrapper.js +373 -373
  145. package/dist/swaps/escrow_swaps/IEscrowSelfInitSwap.d.ts +98 -98
  146. package/dist/swaps/escrow_swaps/IEscrowSelfInitSwap.js +126 -126
  147. package/dist/swaps/escrow_swaps/IEscrowSwap.d.ts +139 -139
  148. package/dist/swaps/escrow_swaps/IEscrowSwap.js +172 -172
  149. package/dist/swaps/escrow_swaps/IEscrowSwapWrapper.d.ts +129 -129
  150. package/dist/swaps/escrow_swaps/IEscrowSwapWrapper.js +167 -167
  151. package/dist/swaps/escrow_swaps/frombtc/IFromBTCLNWrapper.d.ts +107 -107
  152. package/dist/swaps/escrow_swaps/frombtc/IFromBTCLNWrapper.js +130 -130
  153. package/dist/swaps/escrow_swaps/frombtc/IFromBTCSelfInitSwap.d.ts +162 -162
  154. package/dist/swaps/escrow_swaps/frombtc/IFromBTCSelfInitSwap.js +190 -190
  155. package/dist/swaps/escrow_swaps/frombtc/IFromBTCWrapper.d.ts +64 -64
  156. package/dist/swaps/escrow_swaps/frombtc/IFromBTCWrapper.js +82 -82
  157. package/dist/swaps/escrow_swaps/frombtc/ln/FromBTCLNSwap.d.ts +547 -547
  158. package/dist/swaps/escrow_swaps/frombtc/ln/FromBTCLNSwap.js +1419 -1419
  159. package/dist/swaps/escrow_swaps/frombtc/ln/FromBTCLNWrapper.d.ts +192 -192
  160. package/dist/swaps/escrow_swaps/frombtc/ln/FromBTCLNWrapper.js +432 -432
  161. package/dist/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoSwap.d.ts +650 -650
  162. package/dist/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoSwap.js +1577 -1577
  163. package/dist/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoWrapper.d.ts +237 -237
  164. package/dist/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoWrapper.js +525 -525
  165. package/dist/swaps/escrow_swaps/frombtc/onchain/FromBTCSwap.d.ts +491 -491
  166. package/dist/swaps/escrow_swaps/frombtc/onchain/FromBTCSwap.js +1463 -1463
  167. package/dist/swaps/escrow_swaps/frombtc/onchain/FromBTCWrapper.d.ts +204 -204
  168. package/dist/swaps/escrow_swaps/frombtc/onchain/FromBTCWrapper.js +406 -406
  169. package/dist/swaps/escrow_swaps/tobtc/IToBTCSwap.d.ts +446 -446
  170. package/dist/swaps/escrow_swaps/tobtc/IToBTCSwap.js +1097 -1097
  171. package/dist/swaps/escrow_swaps/tobtc/IToBTCWrapper.d.ts +68 -68
  172. package/dist/swaps/escrow_swaps/tobtc/IToBTCWrapper.js +117 -117
  173. package/dist/swaps/escrow_swaps/tobtc/ln/ToBTCLNSwap.d.ts +136 -127
  174. package/dist/swaps/escrow_swaps/tobtc/ln/ToBTCLNSwap.js +269 -256
  175. package/dist/swaps/escrow_swaps/tobtc/ln/ToBTCLNWrapper.d.ts +275 -252
  176. package/dist/swaps/escrow_swaps/tobtc/ln/ToBTCLNWrapper.js +574 -535
  177. package/dist/swaps/escrow_swaps/tobtc/onchain/ToBTCSwap.d.ts +73 -73
  178. package/dist/swaps/escrow_swaps/tobtc/onchain/ToBTCSwap.js +155 -155
  179. package/dist/swaps/escrow_swaps/tobtc/onchain/ToBTCWrapper.d.ts +134 -134
  180. package/dist/swaps/escrow_swaps/tobtc/onchain/ToBTCWrapper.js +286 -286
  181. package/dist/swaps/spv_swaps/SpvFromBTCSwap.d.ts +694 -694
  182. package/dist/swaps/spv_swaps/SpvFromBTCSwap.js +1687 -1687
  183. package/dist/swaps/spv_swaps/SpvFromBTCWrapper.d.ts +259 -259
  184. package/dist/swaps/spv_swaps/SpvFromBTCWrapper.js +947 -947
  185. package/dist/swaps/trusted/ln/LnForGasSwap.d.ts +302 -302
  186. package/dist/swaps/trusted/ln/LnForGasSwap.js +625 -625
  187. package/dist/swaps/trusted/ln/LnForGasWrapper.d.ts +40 -40
  188. package/dist/swaps/trusted/ln/LnForGasWrapper.js +82 -82
  189. package/dist/swaps/trusted/onchain/OnchainForGasSwap.d.ts +343 -343
  190. package/dist/swaps/trusted/onchain/OnchainForGasSwap.js +698 -698
  191. package/dist/swaps/trusted/onchain/OnchainForGasWrapper.d.ts +71 -71
  192. package/dist/swaps/trusted/onchain/OnchainForGasWrapper.js +93 -93
  193. package/dist/types/AmountData.d.ts +10 -10
  194. package/dist/types/AmountData.js +2 -2
  195. package/dist/types/CustomPriceFunction.d.ts +11 -11
  196. package/dist/types/CustomPriceFunction.js +2 -2
  197. package/dist/types/PriceInfoType.d.ts +28 -28
  198. package/dist/types/PriceInfoType.js +57 -57
  199. package/dist/types/SwapExecutionAction.d.ts +195 -195
  200. package/dist/types/SwapExecutionAction.js +106 -106
  201. package/dist/types/SwapExecutionStep.d.ts +144 -144
  202. package/dist/types/SwapExecutionStep.js +87 -87
  203. package/dist/types/SwapStateInfo.d.ts +5 -5
  204. package/dist/types/SwapStateInfo.js +2 -2
  205. package/dist/types/SwapWithSigner.d.ts +17 -17
  206. package/dist/types/SwapWithSigner.js +43 -43
  207. package/dist/types/Token.d.ts +99 -99
  208. package/dist/types/Token.js +76 -76
  209. package/dist/types/TokenAmount.d.ts +75 -75
  210. package/dist/types/TokenAmount.js +85 -85
  211. package/dist/types/fees/Fee.d.ts +50 -50
  212. package/dist/types/fees/Fee.js +2 -2
  213. package/dist/types/fees/FeeBreakdown.d.ts +11 -11
  214. package/dist/types/fees/FeeBreakdown.js +2 -2
  215. package/dist/types/fees/PercentagePPM.d.ts +17 -17
  216. package/dist/types/fees/PercentagePPM.js +18 -18
  217. package/dist/types/lnurl/LNURLPay.d.ts +61 -61
  218. package/dist/types/lnurl/LNURLPay.js +31 -31
  219. package/dist/types/lnurl/LNURLWithdraw.d.ts +48 -48
  220. package/dist/types/lnurl/LNURLWithdraw.js +27 -27
  221. package/dist/types/wallets/LightningInvoiceCreateService.d.ts +24 -24
  222. package/dist/types/wallets/LightningInvoiceCreateService.js +15 -15
  223. package/dist/types/wallets/MinimalBitcoinWalletInterface.d.ts +23 -23
  224. package/dist/types/wallets/MinimalBitcoinWalletInterface.js +2 -2
  225. package/dist/types/wallets/MinimalLightningNetworkWalletInterface.d.ts +9 -9
  226. package/dist/types/wallets/MinimalLightningNetworkWalletInterface.js +2 -2
  227. package/dist/utils/AutomaticClockDriftCorrection.d.ts +1 -1
  228. package/dist/utils/AutomaticClockDriftCorrection.js +70 -70
  229. package/dist/utils/BitcoinUtils.d.ts +18 -18
  230. package/dist/utils/BitcoinUtils.js +174 -174
  231. package/dist/utils/BitcoinWalletUtils.d.ts +7 -7
  232. package/dist/utils/BitcoinWalletUtils.js +14 -14
  233. package/dist/utils/Logger.d.ts +7 -7
  234. package/dist/utils/Logger.js +12 -12
  235. package/dist/utils/RetryUtils.d.ts +22 -22
  236. package/dist/utils/RetryUtils.js +67 -67
  237. package/dist/utils/SwapUtils.d.ts +88 -88
  238. package/dist/utils/SwapUtils.js +72 -72
  239. package/dist/utils/TimeoutUtils.d.ts +17 -17
  240. package/dist/utils/TimeoutUtils.js +55 -55
  241. package/dist/utils/TokenUtils.d.ts +19 -19
  242. package/dist/utils/TokenUtils.js +37 -37
  243. package/dist/utils/TypeUtils.d.ts +7 -7
  244. package/dist/utils/TypeUtils.js +2 -2
  245. package/dist/utils/Utils.d.ts +69 -69
  246. package/dist/utils/Utils.js +214 -214
  247. package/package.json +46 -46
  248. package/src/SmartChainAssets.ts +186 -186
  249. package/src/api/ApiEndpoints.ts +450 -427
  250. package/src/api/ApiParser.ts +138 -138
  251. package/src/api/ApiTypes.ts +229 -229
  252. package/src/api/SerializedAction.ts +97 -97
  253. package/src/api/SwapperApi.ts +558 -545
  254. package/src/api/index.ts +5 -5
  255. package/src/bitcoin/coinselect2/accumulative.ts +69 -69
  256. package/src/bitcoin/coinselect2/blackjack.ts +50 -50
  257. package/src/bitcoin/coinselect2/index.ts +93 -93
  258. package/src/bitcoin/coinselect2/utils.ts +236 -236
  259. package/src/bitcoin/wallet/BitcoinWallet.ts +439 -439
  260. package/src/bitcoin/wallet/IBitcoinWallet.ts +140 -140
  261. package/src/bitcoin/wallet/SingleAddressBitcoinWallet.ts +225 -225
  262. package/src/enums/FeeType.ts +15 -15
  263. package/src/enums/SwapAmountType.ts +16 -16
  264. package/src/enums/SwapDirection.ts +15 -15
  265. package/src/enums/SwapSide.ts +16 -16
  266. package/src/enums/SwapType.ts +75 -75
  267. package/src/errors/IntermediaryError.ts +28 -28
  268. package/src/errors/RequestError.ts +64 -64
  269. package/src/errors/UserError.ts +15 -15
  270. package/src/events/UnifiedSwapEventListener.ts +181 -181
  271. package/src/http/HttpUtils.ts +97 -97
  272. package/src/http/paramcoders/IParamReader.ts +9 -9
  273. package/src/http/paramcoders/ParamDecoder.ts +145 -145
  274. package/src/http/paramcoders/ParamEncoder.ts +40 -40
  275. package/src/http/paramcoders/SchemaVerifier.ts +153 -153
  276. package/src/http/paramcoders/client/ResponseParamDecoder.ts +57 -57
  277. package/src/http/paramcoders/client/StreamParamEncoder.ts +28 -28
  278. package/src/http/paramcoders/client/StreamingFetchPromise.ts +194 -194
  279. package/src/index.ts +141 -141
  280. package/src/intermediaries/Intermediary.ts +280 -280
  281. package/src/intermediaries/IntermediaryDiscovery.ts +548 -548
  282. package/src/intermediaries/apis/IntermediaryAPI.ts +1247 -1247
  283. package/src/intermediaries/auth/SignedKeyBasedAuth.ts +69 -69
  284. package/src/lnurl/LNURL.ts +402 -402
  285. package/src/prices/RedundantSwapPrice.ts +264 -264
  286. package/src/prices/SingleSwapPrice.ts +50 -50
  287. package/src/prices/SwapPriceWithChain.ts +194 -194
  288. package/src/prices/abstract/ICachedSwapPrice.ts +85 -85
  289. package/src/prices/abstract/IPriceProvider.ts +127 -127
  290. package/src/prices/abstract/ISwapPrice.ts +390 -390
  291. package/src/prices/providers/BinancePriceProvider.ts +48 -48
  292. package/src/prices/providers/CoinGeckoPriceProvider.ts +46 -46
  293. package/src/prices/providers/CoinPaprikaPriceProvider.ts +49 -49
  294. package/src/prices/providers/CustomPriceProvider.ts +40 -40
  295. package/src/prices/providers/KrakenPriceProvider.ts +83 -83
  296. package/src/prices/providers/OKXPriceProvider.ts +59 -59
  297. package/src/prices/providers/abstract/ExchangePriceProvider.ts +31 -31
  298. package/src/prices/providers/abstract/HttpPriceProvider.ts +14 -14
  299. package/src/storage/IUnifiedStorage.ts +136 -136
  300. package/src/storage/UnifiedSwapStorage.ts +175 -175
  301. package/src/storage-browser/IndexedDBUnifiedStorage.ts +350 -350
  302. package/src/storage-browser/LocalStorageManager.ts +106 -106
  303. package/src/swapper/Swapper.ts +2570 -2570
  304. package/src/swapper/SwapperFactory.ts +307 -307
  305. package/src/swapper/SwapperUtils.ts +610 -610
  306. package/src/swapper/SwapperWithChain.ts +707 -707
  307. package/src/swapper/SwapperWithSigner.ts +511 -511
  308. package/src/swaps/IAddressSwap.ts +30 -30
  309. package/src/swaps/IBTCWalletSwap.ts +92 -92
  310. package/src/swaps/IClaimableSwap.ts +65 -65
  311. package/src/swaps/IClaimableSwapWrapper.ts +17 -17
  312. package/src/swaps/IRefundableSwap.ts +58 -58
  313. package/src/swaps/ISwap.ts +775 -775
  314. package/src/swaps/ISwapWithGasDrop.ts +25 -25
  315. package/src/swaps/ISwapWrapper.ts +564 -564
  316. package/src/swaps/escrow_swaps/IEscrowSelfInitSwap.ts +217 -217
  317. package/src/swaps/escrow_swaps/IEscrowSwap.ts +271 -271
  318. package/src/swaps/escrow_swaps/IEscrowSwapWrapper.ts +284 -284
  319. package/src/swaps/escrow_swaps/frombtc/IFromBTCLNWrapper.ts +172 -172
  320. package/src/swaps/escrow_swaps/frombtc/IFromBTCSelfInitSwap.ts +300 -300
  321. package/src/swaps/escrow_swaps/frombtc/IFromBTCWrapper.ts +107 -107
  322. package/src/swaps/escrow_swaps/frombtc/ln/FromBTCLNSwap.ts +1670 -1670
  323. package/src/swaps/escrow_swaps/frombtc/ln/FromBTCLNWrapper.ts +603 -603
  324. package/src/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoSwap.ts +1883 -1883
  325. package/src/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoWrapper.ts +752 -752
  326. package/src/swaps/escrow_swaps/frombtc/onchain/FromBTCSwap.ts +1753 -1753
  327. package/src/swaps/escrow_swaps/frombtc/onchain/FromBTCWrapper.ts +612 -612
  328. package/src/swaps/escrow_swaps/tobtc/IToBTCSwap.ts +1327 -1327
  329. package/src/swaps/escrow_swaps/tobtc/IToBTCWrapper.ts +138 -138
  330. package/src/swaps/escrow_swaps/tobtc/ln/ToBTCLNSwap.ts +320 -304
  331. package/src/swaps/escrow_swaps/tobtc/ln/ToBTCLNWrapper.ts +851 -787
  332. package/src/swaps/escrow_swaps/tobtc/onchain/ToBTCSwap.ts +206 -206
  333. package/src/swaps/escrow_swaps/tobtc/onchain/ToBTCWrapper.ts +403 -403
  334. package/src/swaps/spv_swaps/SpvFromBTCSwap.ts +2148 -2148
  335. package/src/swaps/spv_swaps/SpvFromBTCWrapper.ts +1238 -1238
  336. package/src/swaps/trusted/ln/LnForGasSwap.ts +753 -753
  337. package/src/swaps/trusted/ln/LnForGasWrapper.ts +90 -90
  338. package/src/swaps/trusted/onchain/OnchainForGasSwap.ts +843 -843
  339. package/src/swaps/trusted/onchain/OnchainForGasWrapper.ts +133 -133
  340. package/src/types/AmountData.ts +9 -9
  341. package/src/types/CustomPriceFunction.ts +11 -11
  342. package/src/types/PriceInfoType.ts +66 -66
  343. package/src/types/SwapExecutionAction.ts +323 -323
  344. package/src/types/SwapExecutionStep.ts +224 -224
  345. package/src/types/SwapStateInfo.ts +6 -6
  346. package/src/types/SwapWithSigner.ts +61 -61
  347. package/src/types/Token.ts +163 -163
  348. package/src/types/TokenAmount.ts +167 -167
  349. package/src/types/fees/Fee.ts +56 -56
  350. package/src/types/fees/FeeBreakdown.ts +11 -11
  351. package/src/types/fees/PercentagePPM.ts +26 -26
  352. package/src/types/lnurl/LNURLPay.ts +79 -79
  353. package/src/types/lnurl/LNURLWithdraw.ts +61 -61
  354. package/src/types/wallets/LightningInvoiceCreateService.ts +30 -30
  355. package/src/types/wallets/MinimalBitcoinWalletInterface.ts +21 -21
  356. package/src/types/wallets/MinimalLightningNetworkWalletInterface.ts +9 -9
  357. package/src/utils/AutomaticClockDriftCorrection.ts +71 -71
  358. package/src/utils/BitcoinUtils.ts +164 -164
  359. package/src/utils/BitcoinWalletUtils.ts +15 -15
  360. package/src/utils/Logger.ts +14 -14
  361. package/src/utils/RetryUtils.ts +78 -78
  362. package/src/utils/SwapUtils.ts +99 -99
  363. package/src/utils/TimeoutUtils.ts +49 -49
  364. package/src/utils/TokenUtils.ts +33 -33
  365. package/src/utils/TypeUtils.ts +8 -8
  366. package/src/utils/Utils.ts +221 -221
package/README.md CHANGED
@@ -1,1760 +1,1763 @@
1
- # atomiqlabs SDK
2
-
3
- A typescript multichain client for atomiqlabs trustlesss cross-chain swaps. Enables trustless swaps between smart chains (Solana, EVM, Starknet, etc.) and bitcoin (on-chain - L1 and lightning network - L2).
4
-
5
- Example SDK integration in NodeJS available [here](https://github.com/atomiqlabs/atomiq-sdk-demo)
6
-
7
- ## Installation
8
- ```
9
- npm install @atomiqlabs/sdk@latest
10
- ```
11
-
12
- ## Installing chain-specific connectors
13
-
14
- You can install only the chain-specific connectors that your project requires
15
-
16
- ```
17
- npm install @atomiqlabs/chain-solana@latest
18
- npm install @atomiqlabs/chain-starknet@latest
19
- npm install @atomiqlabs/chain-evm@latest
20
- ```
21
-
22
- ## How to use?
23
-
24
- - [Preparations](#preparations)
25
- - [Setting up signers](#signer)
26
- - [Initialization](#initialization)
27
- - Swaps:
28
- - [Smart Chain -> BTC L1](#swap-smart-chain---bitcoin-on-chain)
29
- - [BTC L1 -> Solana (Old swap protocol)](#swap-bitcoin-on-chain---solana)
30
- - [BTC L1 -> Starknet/EVM (New swap protocol)](#swap-bitcoin-on-chain---starknetevm)
31
- - [Smart Chain -> BTC Lightning network L2](#swap-smart-chain---bitcoin-lightning-network)
32
- - [Smart Chain -> BTC Lightning network L2 (LNURL-pay)](#swap-smart-chain---bitcoin-lightning-network-1)
33
- - [BTC Lightning network L2 -> Solana (Old swap protocol)](#swap-bitcoin-lightning-network---solana)
34
- - [BTC Lightning network L2 -> Starknet/EVM (New swap protocol)](#swap-bitcoin-lightning-network---starknetevm)
35
- - [BTC Lightning network L2 (LNURL-withdraw) -> Solana (Old swap protocol)](#swap-bitcoin-lightning-network---solana-1)
36
- - [BTC Lightning network L2 (LNURL-withdraw) -> Starknet/EVM (New swap protocol)](#swap-bitcoin-lightning-network---starknetevm-1)
37
- - [Swap states](#getting-state-of-the-swap)
38
- - [Swap size limits](#swap-size-limits)
39
- - [Stored swaps](#stored-swaps)
40
- - [Get existing swaps](#get-swap-by-id)
41
- - [Refundable swaps](#get-refundable-swaps)
42
- - [Claimable swaps](#get-claimable-swaps)
43
- - [Helpers](#helpers)
44
- - [Wallet spendable balance](#getting-wallet-balances)
45
- - [Unified address parsers](#unified-address-parser)
46
- - [Customize swapper instance](#additional-swapper-options)
47
-
48
- ### Preparations
49
-
50
- Set Solana & Starknet RPC URL to use
51
-
52
- ```typescript
53
- const solanaRpc = "https://api.mainnet-beta.solana.com";
54
- const starknetRpc = "https://rpc.starknet.lava.build/"; //Alternatively: https://starknet.api.onfinality.io/public or https://api.zan.top/public/starknet-mainnet
55
- const citreaRpc = "https://rpc.mainnet.citrea.xyz";
56
- ```
57
-
58
- Create swapper factory, here we can pick and choose which chains we want to have supported in the SDK, ensure the "as const" keyword is used such that the typescript compiler can properly infer the types.
59
-
60
- ```typescript
61
- import {SolanaInitializer, SolanaInitializerType} from "@atomiqlabs/chain-solana";
62
- import {StarknetInitializer, StarknetInitializerType} from "@atomiqlabs/chain-starknet";
63
- import {CitreaInitializer, CitreaInitializerType} from "@atomiqlabs/chain-evm";
64
- import {SwapperFactory, TypedTokens} from "@atomiqlabs/sdk";
65
-
66
- //Define chains that you want to support here
67
- const chains = [SolanaInitializer, StarknetInitializer, CitreaInitializer] as const;
68
- type SupportedChains = typeof chains; //It's helpful that we also get the type of the chains array
69
-
70
- const Factory = new SwapperFactory<SupportedChains>(chains); //Create swapper factory
71
- const Tokens: TypedTokens<SupportedChains> = Factory.Tokens; //Get the supported tokens for all the specified chains.
72
- ```
73
-
74
- #### Browser
75
-
76
- This uses browser's Indexed DB by default
77
-
78
- ```typescript
79
- import {BitcoinNetwork, TypedSwapper} from "@atomiqlabs/sdk";
80
-
81
- const swapper: TypedSwapper<SupportedChains> = Factory.newSwapper({
82
- chains: {
83
- SOLANA: {
84
- rpcUrl: solanaRpc //You can also pass Connection object here
85
- },
86
- STARKNET: {
87
- rpcUrl: starknetRpc //You can also pass Provider object here
88
- },
89
- CITREA: {
90
- rpcUrl: citreaRpc, //You can also pass JsonRpcApiProvider object here
91
- }
92
- },
93
- bitcoinNetwork: BitcoinNetwork.MAINNET //or BitcoinNetwork.TESTNET3, BitcoinNetwork.TESTNET4 - this also sets the network to use for Solana (solana devnet for bitcoin testnet) & Starknet (sepolia for bitcoin testnet)
94
- });
95
- ```
96
-
97
- if you want to use custom pricing api, mempool.space RPC url, or tune HTTP request timeouts check out [additional options](#additional-swapper-options)
98
-
99
- #### NodeJS
100
-
101
- For NodeJS we need to use sqlite storage, for that we first need to install the sqlite storage adaptor
102
-
103
- ```
104
- npm install @atomiqlabs/storage-sqlite@latest
105
- ```
106
-
107
- Then use pass it in the newSwapper function
108
-
109
- ```typescript
110
- import {SqliteStorageManager, SqliteUnifiedStorage} from "@atomiqlabs/storage-sqlite";
111
- import {BitcoinNetwork, TypedSwapper} from "@atomiqlabs/sdk";
112
-
113
- const swapper: TypedSwapper<SupportedChains> = Factory.newSwapper({
114
- chains: {
115
- SOLANA: {
116
- rpcUrl: solanaRpc //You can also pass Connection object here
117
- },
118
- STARKNET: {
119
- rpcUrl: starknetRpc //You can also pass Provider object here
120
- },
121
- CITREA: {
122
- rpcUrl: citreaRpc, //You can also pass JsonApiProvider object here
123
- }
124
- },
125
- bitcoinNetwork: BitcoinNetwork.MAINNET //or BitcoinNetwork.TESTNET3, BitcoinNetwork.TESTNET4 - this also sets the network to use for Solana (solana devnet for bitcoin testnet) & Starknet (sepolia for bitcoin testnet)
126
- //The following lines are important for running on backend node.js,
127
- // because the SDK by default uses browser's Indexed DB
128
- swapStorage: chainId => new SqliteUnifiedStorage("CHAIN_"+chainId+".sqlite3"),
129
- chainStorageCtor: name => new SqliteStorageManager("STORE_"+name+".sqlite3"),
130
- });
131
- ```
132
-
133
- if you want to use custom pricing api, mempool.space RPC url, or tune HTTP request timeouts check out [additional options](#additional-swapper-options)
134
-
135
- ### Signer
136
-
137
- ```typescript
138
- import {SolanaSigner} from "@atomiqlabs/chain-solana";
139
- //Browser - react, using solana wallet adapter
140
- const anchorWallet = useAnchorWallet();
141
- const wallet = new SolanaSigner(anchorWallet);
142
- ```
143
-
144
- ```typescript
145
- import {WalletAccount} from "starknet";
146
- import {StarknetBrowserSigner} from "@atomiqlabs/chain-starknet";
147
- //Browser, using get-starknet
148
- const swo = await connect();
149
- const wallet = new StarknetBrowserSigner(new WalletAccount(starknetRpc, swo.wallet));
150
- ```
151
-
152
- or
153
-
154
- ```typescript
155
- import {Keypair} from "@solana/web3.js";
156
- import {SolanaKeypairWallet, SolanaSigner} from "@atomiqlabs/chain-solana";
157
- //Creating Solana signer from private key
158
- const solanaSigner = new SolanaSigner(new SolanaKeypairWallet(Keypair.fromSecretKey(solanaKey)), Keypair.fromSecretKey(solanaKey));
159
- ```
160
-
161
- ```typescript
162
- import {StarknetSigner, StarknetKeypairWallet} from "@atomiqlabs/chain-starknet";
163
- //Creating Starknet signer from private key
164
- const starknetSigner = new StarknetSigner(new StarknetKeypairWallet(starknetRpc, starknetKey));
165
- ```
166
-
167
- ```typescript
168
- import {BaseWallet, SigningKey} from "ethers";
169
- import {EVMSigner} from "@atomiqlabs/chain-evm";
170
- //Creating EVM signer from private key
171
- const wallet = new BaseWallet(new SigningKey(evmKey));
172
- const evmWallet = new EVMSigner(wallet, wallet.address);
173
- ```
174
-
175
- ### Initialization
176
-
177
- Initialize the swapper, this should be done once when your app starts. Checks existing in-progress swaps and does initial LP discovery
178
-
179
- ```typescript
180
- await swapper.init();
181
- ```
182
-
183
- Now we have the multichain swapper initialized
184
-
185
- ### Extract chain-specific swapper with signer
186
-
187
- To make it easier to do swaps between bitcoin and a specific chain we can extract a chain-specific swapper, and also set a signer. e.g.:
188
-
189
- ```typescript
190
- const solanaSwapper = swapper.withChain<"SOLANA">("SOLANA");
191
- ```
192
-
193
- ### Bitcoin on-chain swaps
194
-
195
- #### Swap Smart chain -> Bitcoin on-chain
196
-
197
- Getting swap quote
198
-
199
- ```typescript
200
- //Create the swap: swapping SOL to Bitcoin on-chain, receiving _amount of satoshis (smallest unit of bitcoin) to _address
201
- const swap: ToBTCSwap<SolanaChainType> = await swapper.swap(
202
- Tokens.SOLANA.SOL, //From specified source token
203
- Tokens.BITCOIN.BTC, //Swap to BTC
204
- "0.0001", //Amount can be either passed in base units as bigint or in decimal format as string
205
- SwapAmountType.EXACT_OUT, //EXACT_OUT, so we specify the output amount
206
- solanaSigner.getAddress(), //Source address and smart chain signer
207
- "bc1qtw67hj77rt8zrkkg3jgngutu0yfgt9czjwusxt" //BTC address of the recipient
208
- );
209
-
210
- //Get the amount required to pay and fee
211
- const input: string = swap.getInputWithoutFee().toString(); //Input amount excluding fees
212
- const fee: string = swap.getFee().amountInSrcToken.toString(); //Fees paid on the output
213
- const inputWithFees: string = swap.getInput().toString(); //Total amount paid including fees
214
-
215
- const output: string = swap.getOutput().toString(); //Total output amount
216
-
217
- //Get swap expiration time
218
- const expiry: number = swap.getQuoteExpiry(); //Expiration time of the swap quote in UNIX milliseconds, swap needs to be initiated before this time
219
-
220
- //Get pricing info
221
- const swapPrice = swap.getPriceInfo().swapPrice; //Price of the current swap (excluding fees)
222
- const marketPrice = swap.getPriceInfo().marketPrice; //Current market price
223
- const difference = swap.getPriceInfo().difference; //Difference between the swap price & current market price
224
- ```
225
-
226
- Executing the swap (simple)
227
-
228
- ```typescript
229
- const swapSuccessful = await swap.execute(
230
- solanaSigner,
231
- { //Callbacks
232
- onSourceTransactionSent: (txId: string) => {
233
- //Transaction on the source chain was sent
234
- },
235
- onSourceTransactionConfirmed: (txId: string) => {
236
- //Transaction on the source chain was confirmed
237
- },
238
- onSwapSettled: (destinationTxId: string) => {
239
- //Bitcoin transaction on the destination chain was sent and swap settled
240
- }
241
- }
242
- );
243
-
244
- //Refund in case of failure
245
- if(!swapSuccessful) {
246
- //Swap failed, money can be refunded
247
- await swap.refund(solanaSigner);
248
- } else {
249
- //Swap successful!
250
- }
251
- ```
252
-
253
- <details>
254
- <summary>Manual swap execution (advanced)</summary>
255
-
256
- - __1.__ Initiate the swap on the smart-chain side
257
-
258
- - __a.__ Commit with a signer
259
- ```typescript
260
- await swap.commit(solanaSigner);
261
- ```
262
-
263
- - __b.__ Or get the transactions & [sign and send transaction manually](#manually-signing-smart-chain-transactions)
264
- ```typescript
265
- const txsCommit = await swap.txsCommit();
266
- //Sign and send these...
267
- ...
268
- //Important to wait till SDK processes the swap initialization
269
- await swap.waitTillCommited();
270
- ```
271
-
272
- - __2.__ Wait for the swap to execute and for the payment to be sent
273
- ```typescript
274
- const swapSuccessful = await swap.waitForPayment();
275
- ```
276
-
277
- - __3.__ In case the swap fails we can refund our funds on the source chain
278
-
279
- - __a.__ Refund with a signer
280
- ```typescript
281
- if(!swapSuccessful) {
282
- await swap.refund(solanaSigner);
283
- return;
284
- }
285
- ```
286
-
287
- - __b.__ Or get the transactions & [sign and send transaction manually](#manually-signing-smart-chain-transactions)
288
- ```typescript
289
- if(!swapSuccessful) {
290
- const txsRefund = await swap.txsRefund();
291
- //Sign and send these...
292
- ...
293
- }
294
- ```
295
-
296
- </details>
297
-
298
- <details>
299
- <summary>Swap states</summary>
300
-
301
- - ToBTCSwapState.REFUNDED = -3
302
- - Swap failed and was successfully refunded
303
- - ToBTCSwapState.QUOTE_EXPIRED = -2
304
- - Swap quote expired and cannot be executed anymore
305
- - ToBTCSwapState.QUOTE_SOFT_EXPIRED = -1
306
- - Swap quote soft-expired (i.e. the quote probably expired, but if there is already an initialization transaction sent it might still succeed)
307
- - ToBTCSwapState.CREATED = 0
308
- - Swap quote is created, waiting to be executed
309
- - ToBTCSwapState.COMMITED = 1,
310
- - Swap was initiated (init transaction sent)
311
- - ToBTCSwapState.SOFT_CLAIMED = 2,
312
- - Swap was processed by the counterparty but not yet claimed on-chain (bitcoin transaction was sent, but unconfirmed yet)
313
- - ToBTCSwapState.CLAIMED = 3
314
- - Swap was finished and funds were successfully claimed by the counterparty
315
- - ToBTCSwapState.REFUNDABLE = 4
316
- - Swap was initiated but counterparty failed to process it, the user can now refund his funds
317
-
318
- </details>
319
-
320
- #### Swap Bitcoin on-chain -> Solana
321
-
322
- NOTE: Solana uses an old swap protocol for Bitcoin on-chain -> Solana swaps, the flow here is different from the one for Starknet and other chains.
323
-
324
- Getting swap quote
325
-
326
- ```typescript
327
- //Create the swap: swapping _amount of satoshis of Bitcoin on-chain to SOL
328
- const swap: FromBTCSwap<SolanaChainType> = await swapper.swap(
329
- Tokens.BITCOIN.BTC, //Swap from BTC
330
- Tokens.SOLANA.SOL, //Into specified destination token
331
- "0.0001", //Amount can be either passed in base units as bigint or in decimal format as string
332
- SwapAmountType.EXACT_IN, //EXACT_IN, so we specify the input amount
333
- undefined, //Source address for the swap, not used for swaps from BTC
334
- solanaSigner.getAddress() //Destination address
335
- );
336
-
337
- //Get the amount required to pay and fee
338
- const input: string = swap.getInputWithoutFee().toString(); //Input amount excluding fees
339
- const fee: string = swap.getFee().amountInSrcToken.toString(); //Fees paid on the output
340
- const inputWithFees: string = swap.getInput().toString(); //Total amount paid including fees
341
-
342
- const output: string = swap.getOutput().toString(); //Total output amount
343
-
344
- //Get swap expiration time
345
- const expiry: number = swap.getQuoteExpiry(); //Expiration time of the swap quote in UNIX milliseconds, swap needs to be initiated before this time
346
-
347
- //Get security deposit amount (Human readable amount of SOL that needs to be put down to rent the liquidity from swap intermediary), you will get this deposit back if the swap succeeds
348
- const securityDeposit: string = swap.getSecurityDeposit().toString();
349
- //Get claimer bounty (Human readable amount of SOL reserved as a reward for watchtowers to claim the swap on your behalf)
350
- const claimerBounty: string = swap.getClaimerBounty().toString();
351
-
352
- //Get pricing info
353
- const swapPrice = swap.getPriceInfo().swapPrice; //Price of the current swap (excluding fees)
354
- const marketPrice = swap.getPriceInfo().marketPrice; //Current market price
355
- const difference = swap.getPriceInfo().difference; //Difference between the swap price & current market price
356
- ```
357
-
358
- Executing the swap (simple)
359
-
360
- ```typescript
361
- const automaticSettlementSuccess = await swap.execute(
362
- solanaSigner,
363
- { //Bitcoin wallet, you can also pass null/undefined and send the bitcoin transaction from an external wallet
364
- address: "bc1pscnrk588hdj79mwccucu06007mj5np2jurwfwp5mvhkjldzyphzqyk62m5",
365
- publicKey: "03a2d8b728935f61d5bcba0cfb09c2c443c483b5c31ebd180e1833f37344bd34ba",
366
- signPsbt: (psbt: {psbt, psbtHex: string, psbtBase64: string}, signInputs: number[]) => {
367
- //Sign the PSBT with the bitcoin wallet
368
- ...
369
- //Return the signed PSBT in the hex or base64 format!
370
- return "<signed PSBT>";
371
- }
372
- },
373
- { //Callbacks
374
- onDestinationCommitSent: (swapAddressOpeningTxId: string) => {
375
- //Swap address opening transaction sent on the destination chain
376
- },
377
- onSourceTransactionSent: (txId: string) => {
378
- //Bitcoin transaction sent on the source
379
- },
380
- onSourceTransactionConfirmationStatus: (txId: string, confirmations: number, targetConfirmations: number, txEtaMs: number) => {
381
- //Bitcoin transaction confirmation status updates
382
- },
383
- onSourceTransactionConfirmed: (txId: string) => {
384
- //Bitcoin transaction confirmed
385
- },
386
- onSwapSettled: (destinationTxId: string) => {
387
- //Swap settled on the destination
388
- }
389
- }
390
- );
391
-
392
- //In case the automatic swap settlement fails, we can settle it manually using the wallet of the destination chain
393
- if(!automaticSettlementSuccess) {
394
- await swap.claim(solanaSigner);
395
- }
396
- ```
397
-
398
- <details>
399
- <summary>Manual swap execution (advanced)</summary>
400
-
401
- - __1.__ Initiate the swap on the destination chain (Solana) by opening up the bitcoin swap address
402
-
403
- - __a.__ Commit using signer
404
- ```typescript
405
- await swap.commit(solanaWallet);
406
- ```
407
-
408
- - __b.__ Or get the transactions & [sign and send transaction manually](#manually-signing-smart-chain-transactions)
409
- ```typescript
410
- const txsCommit = await swap.txsCommit();
411
- //Sign and send these...
412
- ...
413
- //Important to wait till SDK processes the swap initialization
414
- await swap.waitTillCommited();
415
- ```
416
-
417
- - __2.__ Send bitcoin transaction
418
-
419
- - __a.__ Get funded PSBT and sign it
420
- ```typescript
421
- const {psbt, psbtHex, psbtBase64, signInputs} = await swap.getFundedPsbt({
422
- address: "bc1pscnrk588hdj79mwccucu06007mj5np2jurwfwp5mvhkjldzyphzqyk62m5",
423
- publicKey: "03a2d8b728935f61d5bcba0cfb09c2c443c483b5c31ebd180e1833f37344bd34ba"
424
- });
425
- //Sign the psbt
426
- const signedPsbt = ...; //Can be hex or base64 encoded
427
- const bitcoinTxId = await swap.submitPsbt(signedPsbt);
428
- ```
429
-
430
- - __b.__ Get the bitcoin address or deeplink and send from external wallet
431
- ```typescript
432
- //It is imporant to send the EXACT amount, sending different amount will lead to loss of funds!
433
- const btcSwapAddress = swap.getAddress();
434
- const btcDeepLink = swap.getHyperlink();
435
- ```
436
-
437
- - __3.__ Wait for the bitcoin on-chain transaction to confirm
438
- ```typescript
439
- await swap.waitForBitcoinTransaction(
440
- (txId, confirmations, targetConfirmations, txEtaMs) => {
441
- //Bitcoin transaction confirmation status callback
442
- }
443
- );
444
- ```
445
-
446
- - __4.__ Wait for the automatic settlement of the swap
447
- ```typescript
448
- const automaticSettlementSuccess = await swap.waitTillClaimed(30);
449
- ```
450
-
451
- - __5.__ In case the automatic swap settlement fails, we can settle it manually using the wallet of the destination chain
452
-
453
- - __a.__ Claim with a signer
454
- ```typescript
455
- if(!automaticSettlementSuccess) {
456
- await swap.claim(solanaSigner);
457
- }
458
- ```
459
-
460
- - __b.__ Or get the transactions & [sign and send transaction manually](#manually-signing-smart-chain-transactions)
461
- ```typescript
462
- if(!automaticSettlementSuccess) {}
463
- const txsClaim = await swap.txsClaim();
464
- //Sign and send these...
465
- ...
466
- //Important to wait till SDK processes the swap initialization
467
- await swap.waitTillCommited();
468
- }
469
- ```
470
-
471
- </details>
472
-
473
- <details>
474
- <summary>Swap states</summary>
475
-
476
- - FromBTCSwapState.EXPIRED = -3
477
- - Bitcoin swap address expired
478
- - FromBTCSwapState.QUOTE_EXPIRED = -2
479
- - Swap quote expired and cannot be executed anymore
480
- - FromBTCSwapState.QUOTE_SOFT_EXPIRED = -1
481
- - Swap quote soft-expired (i.e. the quote probably expired, but if there is already an initialization transaction sent it might still succeed)
482
- - FromBTCSwapState.PR_CREATED = 0
483
- - Swap quote is created, waiting for the user to open a bitcoin swap address
484
- - FromBTCSwapState.CLAIM_COMMITED = 1
485
- - Bitcoin swap address is opened
486
- - FromBTCSwapState.BTC_TX_CONFIRMED = 2
487
- - Bitcoin transaction sending funds to the swap address is confirmed
488
- - FromBTCSwapState.CLAIM_CLAIMED = 3
489
- - Swap funds are claimed to the user's wallet
490
-
491
- </details>
492
-
493
- #### Swap Bitcoin on-chain -> Starknet/EVM
494
-
495
- NOTE: Starknet & EVM uses a new swap protocol for Bitcoin on-chain -> Smart chain swaps, the flow here is different from the one for Solana!
496
-
497
- Getting swap quote
498
-
499
- ```typescript
500
- //Create the swap: swapping _amount of satoshis of Bitcoin on-chain to SOL
501
- const swap: SpvFromBTCSwap<StarknetChainType> = await swapper.swap(
502
- Tokens.BITCOIN.BTC, //Swap from BTC
503
- Tokens.STARKNET.STRK, //Into specified destination token
504
- "0.0001", //Amount can be either passed in base units as bigint or in decimal format as string
505
- SwapAmountType.EXACT_IN, //EXACT_IN, so we specify the input amount
506
- undefined, //Source address for the swap, not used for swaps from BTC
507
- starknetSigner.getAddress(), //Destination address
508
- {
509
- gasAmount: 1_000_000_000_000_000_000n //We can also request a gas drop on the destination chain (here requesting 1 STRK)
510
- }
511
- );
512
-
513
- //Get the amount required to pay and fee
514
- const input: string = swap.getInputWithoutFee().toString(); //Input amount excluding fees
515
- const fee: string = swap.getFee().amountInSrcToken.toString(); //Fees paid on the output
516
- const inputWithFees: string = swap.getInput().toString(); //Total amount paid including fees
517
-
518
- const output: string = swap.getOutput().toString(); //Total output amount
519
-
520
- //Get swap expiration time
521
- const expiry: number = swap.getQuoteExpiry(); //Expiration time of the swap quote in UNIX milliseconds, swap needs to be initiated before this time
522
-
523
- //Get pricing info
524
- const swapPrice = swap.getPriceInfo().swapPrice; //Price of the current swap (excluding fees)
525
- const marketPrice = swap.getPriceInfo().marketPrice; //Current market price
526
- const difference = swap.getPriceInfo().difference; //Difference between the swap price & current market price
527
- ```
528
-
529
- Executing the swap (simple)
530
-
531
- ```typescript
532
- const automaticSettlementSuccess = await swap.execute(
533
- { //Bitcoin wallet
534
- address: "bc1pscnrk588hdj79mwccucu06007mj5np2jurwfwp5mvhkjldzyphzqyk62m5",
535
- publicKey: "03a2d8b728935f61d5bcba0cfb09c2c443c483b5c31ebd180e1833f37344bd34ba",
536
- signPsbt: (psbt: {psbt, psbtHex: string, psbtBase64: string}, signInputs: number[]) => {
537
- //Sign the PSBT with the bitcoin wallet
538
- ...
539
- //Return the signed PSBT in the hex or base64 format!
540
- return "<signed PSBT>";
541
- }
542
- },
543
- { //Callbacks
544
- onSourceTransactionSent: (txId: string) => {
545
- //Bitcoin transaction sent on the source
546
- },
547
- onSourceTransactionConfirmationStatus: (txId: string, confirmations: number, targetConfirmations: number, txEtaMs: number) => {
548
- //Bitcoin transaction confirmation status updates
549
- },
550
- onSourceTransactionConfirmed: (txId: string) => {
551
- //Bitcoin transaction confirmed
552
- },
553
- onSwapSettled: (destinationTxId: string) => {
554
- //Swap settled on the destination
555
- }
556
- }
557
- );
558
-
559
- //In case the automatic swap settlement fails, we can settle it manually using the wallet of the destination chain
560
- if(!automaticSettlementSuccess) {
561
- await swap.claim(starknetWallet);
562
- }
563
- ```
564
-
565
-
566
- <details>
567
- <summary>Manual swap execution (advanced)</summary>
568
-
569
- - __1.__ Send bitcoin transaction
570
-
571
- - __a.__ Get funded PSBT and sign it using external wallet (e.g. browser-based like Xverse, Unisat, Phantom, etc.)
572
- ```typescript
573
- //Obtain the funded PSBT (input already added) - ready for signing
574
- const {psbt, psbtHex, psbtBase64, signInputs} = await swap.getFundedPsbt({address: "", publicKey: ""});
575
- //Pass `psbtBase64` or `psbtHex` (and also `signInputs`) to an external signer like Xverse, Unisat, etc.
576
- const signedPsbtHexOrBase64 = await <signPsbt function of the external wallet>; //Call the signPsbt function of the external signer with psbtBase64 or psbtHex and signInputs
577
- //The SDK automatically recognizes hex & base64 encoded PSBTs
578
- const bitcoinTxId = await swap.submitPsbt(signedPsbtHexOrBase64);
579
- ```
580
-
581
- - __b.__ Or obtain raw PSBT to which inputs still need to be added
582
- ```typescript
583
- const {psbt, psbtHex, psbtBase64, in1sequence} = await swap.getPsbt();
584
- psbt.addInput(...);
585
- //Make sure the second input's sequence (index 1) is as specified in the in1sequence variable
586
- psbt.updateInput(1, {sequence: in1sequence});
587
- //Sign the PSBT, sign every input except the first one
588
- for(let i=1;i<psbt.inputsLength; i++) psbt.signIdx(..., i); //Or pass it to external signer
589
- //Submit the signed PSBT, can be the Transaction object, or hex/base64 serialized
590
- const bitcoinTxId = await swap.submitPsbt(psbt);
591
- ```
592
-
593
- - __2.__ Wait for the bitcoin on-chain transaction to confirm
594
- ```typescript
595
- await swap.waitForBitcoinTransaction(
596
- (txId, confirmations, targetConfirmations, txEtaMs) => {
597
- //Bitcoin transaction confirmation status callback
598
- }
599
- );
600
- ```
601
-
602
- - __3.__ Wait for the automatic settlement of the swap
603
- ```typescript
604
- const automaticSettlementSuccess = await swap.waitTillClaimed(60);
605
- ```
606
-
607
- - __4.__ In case the automatic swap settlement fails, we can settle it manually using the wallet of the destination chain
608
-
609
- - __a.__ Claim with a signer
610
- ```typescript
611
- if(!automaticSettlementSuccess) {
612
- await swap.claim(starknetSigner);
613
- }
614
- ```
615
-
616
- - __b.__ Or get the transactions & [sign and send transaction manually](#manually-signing-smart-chain-transactions)
617
- ```typescript
618
- if(!automaticSettlementSuccess) {}
619
- const txsClaim = await swap.txsClaim();
620
- //Sign and send these...
621
- ...
622
- //Important to wait till SDK processes the swap initialization
623
- await swap.waitTillCommited();
624
- }
625
- ```
626
-
627
- </details>
628
-
629
- <details>
630
- <summary>Swap states</summary>
631
-
632
- - SpvFromBTCSwapState.CLOSED = -5
633
- - Catastrophic failure during swap, shall never happen
634
- - SpvFromBTCSwapState.FAILED = -4
635
- - Bitcoin transaction was sent, but was double-spent later, therefore the swap was failed (no BTC was sent)
636
- - SpvFromBTCSwapState.DECLINED = -3
637
- - LP declined to process the swap transaction, no BTC was sent
638
- - SpvFromBTCSwapState.QUOTE_EXPIRED = -2
639
- - Swap quote expired and cannot be executed anymore
640
- - SpvFromBTCSwapState.QUOTE_SOFT_EXPIRED = -1
641
- - Swap quote soft-expired (i.e. the quote probably expired, but if there is a bitcoin transaction being submitted it might still succeed)
642
- - SpvFromBTCSwapState.CREATED = 0
643
- - Swap quote is created, waiting on user to sign the bitcoin swap transaction
644
- - SpvFromBTCSwapState.SIGNED = 1
645
- - Bitcoin swap transaction was signed by the client
646
- - SpvFromBTCSwapState.POSTED = 2
647
- - Bitcoin swap transaction was posted to the LP
648
- - SpvFromBTCSwapState.BROADCASTED = 3
649
- - LP broadcasted the bitcoin swap transaction
650
- - SpvFromBTCSwapState.FRONTED = 4
651
- - Swap funds have been deposited to the user's wallet in front of the time
652
- - SpvFromBTCSwapState.BTC_TX_CONFIRMED = 5
653
- - Bitcoin swap transaction is confirmed
654
- - SpvFromBTCSwapState.CLAIM_CLAIMED = 6
655
- - Swap funds are claimed to the user's wallet
656
- -
657
- </details>
658
-
659
- ### Bitcoin lightning network swaps
660
-
661
- #### Swap Smart chain -> Bitcoin lightning network
662
-
663
- Getting swap quote
664
-
665
- ```typescript
666
- //Create the swap: swapping SOL to Bitcoin lightning
667
- const swap: ToBTCLNSwap<SolanaChainType> = await swapper.swap(
668
- Tokens.SOLANA.SOL, //From specified source token
669
- Tokens.BITCOIN.BTCLN, //Swap to BTC-LN
670
- undefined, //Amount is specified in the lightning network invoice!
671
- SwapAmountType.EXACT_OUT, //Make sure we use EXACT_OUT for swaps to BTC-LN, if you want to use EXACT_IN and set an amount, use LNURL-pay!
672
- solanaSigner.getAddress(), //Source address and smart chain signer
673
- //Destination lightning network invoice, amount needs to be part of the invoice!
674
- "lnbc10u1pj2q0g9pp5ejs6m677m39cznpzum7muruvh50ys93ln82p4j9ks2luqm56xxlshp52r2anlhddfa9ex9vpw9gstxujff8a0p8s3pzvua930js0kwfea6scqzzsxqyz5vqsp5073zskc5qfgp7lre0t6s8uexxxey80ax564hsjklfwfjq2ew0ewq9qyyssqvzmgs6f8mvuwgfa9uqxhtza07qem4yfhn9wwlpskccmuwplsqmh8pdy6c42kqdu8p73kky9lsnl40qha5396d8lpgn90y27ltfc5rfqqq59cya"
675
- );
676
-
677
- //Get the amount required to pay and fee
678
- const input: string = swap.getInputWithoutFee().toString(); //Input amount excluding fees
679
- const fee: string = swap.getFee().amountInSrcToken.toString(); //Fees paid on the output
680
- const inputWithFees: string = swap.getInput().toString(); //Total amount paid including fees
681
-
682
- const output: string = swap.getOutput().toString(); //Total output amount
683
-
684
- //Get swap expiration time
685
- const expiry: number = swap.getQuoteExpiry(); //Expiration time of the swap quote in UNIX milliseconds, swap needs to be initiated before this time
686
-
687
- //Get pricing info
688
- const swapPrice = swap.getPriceInfo().swapPrice; //Price of the current swap (excluding fees)
689
- const marketPrice = swap.getPriceInfo().marketPrice; //Current market price
690
- const difference = swap.getPriceInfo().difference; //Difference between the swap price & current market price
691
- ```
692
-
693
- Executing the swap (simple)
694
-
695
- ```typescript
696
- const swapSuccessful = await swap.execute(
697
- solanaSigner,
698
- { //Callbacks
699
- onSourceTransactionSent: (txId: string) => {
700
- //Transaction on the source chain was sent
701
- },
702
- onSourceTransactionConfirmed: (txId: string) => {
703
- //Transaction on the source chain was confirmed
704
- },
705
- onSwapSettled: (destinationTxId: string) => {
706
- //Lightning payment on the destination chain was sent and swap settled
707
- }
708
- }
709
- );
710
-
711
- //Refund in case of failure
712
- if(!swapSuccessful) {
713
- //Swap failed, money can be refunded
714
- await swap.refund(solanaSigner);
715
- } else {
716
- //Swap successful!
717
- }
718
- ```
719
-
720
- <details>
721
- <summary>Manual swap execution (advanced)</summary>
722
-
723
- - __1.__ Initiate the swap on the smart-chain side
724
-
725
- - __a.__ Commit with a signer
726
- ```typescript
727
- await swap.commit(solanaSigner);
728
- ```
729
-
730
- - __b.__ Or get the transactions & [sign and send transaction manually](#manually-signing-smart-chain-transactions)
731
- ```typescript
732
- const txsCommit = await swap.txsCommit();
733
- //Sign and send these...
734
- ...
735
- //Important to wait till SDK processes the swap initialization
736
- await swap.waitTillCommited();
737
- ```
738
-
739
- - __2.__ Wait for the swap to execute and for the payment to be sent
740
- ```typescript
741
- const swapSuccessful = await swap.waitForPayment();
742
- ```
743
-
744
- - __3.__ In case the swap fails we can refund our funds on the source chain
745
-
746
- - __a.__ Refund with a signer
747
- ```typescript
748
- if(!swapSuccessful) {
749
- await swap.refund(solanaSigner);
750
- return;
751
- }
752
- ```
753
-
754
- - __b.__ Or get the transactions & [sign and send transaction manually](#manually-signing-smart-chain-transactions)
755
- ```typescript
756
- if(!swapSuccessful) {
757
- const txsRefund = await swap.txsRefund();
758
- //Sign and send these...
759
- ...
760
- }
761
- ```
762
-
763
- </details>
764
-
765
- <details>
766
- <summary>Swap states</summary>
767
-
768
- - ToBTCSwapState.REFUNDED = -3
769
- - Swap failed and was successfully refunded
770
- - ToBTCSwapState.QUOTE_EXPIRED = -2
771
- - Swap quote expired and cannot be executed anymore
772
- - ToBTCSwapState.QUOTE_SOFT_EXPIRED = -1
773
- - Swap quote soft-expired (i.e. the quote probably expired, but if there is already an initialization transaction sent it might still succeed)
774
- - ToBTCSwapState.CREATED = 0
775
- - Swap quote is created, waiting to be executed
776
- - ToBTCSwapState.COMMITED = 1,
777
- - Swap was initiated (init transaction sent)
778
- - ToBTCSwapState.SOFT_CLAIMED = 2,
779
- - Swap was processed by the counterparty but not yet claimed on-chain (lightning network payment secret was revealed)
780
- - ToBTCSwapState.CLAIMED = 3
781
- - Swap was finished and funds were successfully claimed by the counterparty
782
- - ToBTCSwapState.REFUNDABLE = 4
783
- - Swap was initiated but counterparty failed to process it, the user can now refund his funds
784
-
785
- </details>
786
-
787
- #### Swap Bitcoin lightning network -> Solana
788
-
789
- NOTE: Solana uses an old swap protocol for Bitcoin lightning network -> Solana swaps, the flow here is different from the one for Starknet and other chains.
790
-
791
- Getting swap quote
792
-
793
- ```typescript
794
- const swap: FromBTCLNSwap<SolanaChainType> = await swapper.swap(
795
- Tokens.BITCOIN.BTCLN, //Swap from BTC-LN
796
- Tokens.SOLANA.SOL, //Into specified destination token
797
- 10000n, //Amount can be either passed in base units as bigint or in decimal format as string
798
- SwapAmountType.EXACT_IN, //SwapAmountType.EXACT_IN, so we specify the input amount
799
- undefined, //Source address for the swap, not used for swaps from BTC-LN
800
- signer.getAddress() //Destination address
801
- );
802
-
803
- //Get the bitcoin lightning network invoice (the invoice contains pre-entered amount)
804
- const receivingLightningInvoice: string = swap.getAddress();
805
- //Get the URI hyperlink (contains the lightning network invoice) which can be displayed also as QR code
806
- const qrCodeData: string = swap.getHyperlink();
807
-
808
- //Get the amount required to pay and fee
809
- const input: string = swap.getInputWithoutFee().toString(); //Input amount excluding fees
810
- const fee: string = swap.getFee().amountInSrcToken.toString(); //Fees paid on the output
811
- const inputWithFees: string = swap.getInput().toString(); //Total amount paid including fees
812
-
813
- const output: string = swap.getOutput().toString(); //Total output amount
814
-
815
- //Get swap expiration time
816
- const expiry: number = swap.getQuoteExpiry(); //Expiration time of the swap quote in UNIX milliseconds, swap needs to be initiated before this time
817
-
818
- //Get security deposit amount (Human readable amount of STRK that needs to be put down to rent the liquidity from swap intermediary), you will get this deposit back if the swap succeeds
819
- const securityDeposit: string = swap.getSecurityDeposit().toString();
820
-
821
- //Get pricing info
822
- const swapPrice = swap.getPriceInfo().swapPrice; //Price of the current swap (excluding fees)
823
- const marketPrice = swap.getPriceInfo().marketPrice; //Current market price
824
- const difference = swap.getPriceInfo().difference; //Difference between the swap price & current market price
825
- ```
826
-
827
- Executing the swap (simple)
828
-
829
- ```typescript
830
- await swap.execute(
831
- solanaSigner,
832
- { //Lightning network wallet, you can also pass null/undefined and pay the LN invoice from an external wallet
833
- payInvoice: (bolt11PaymentRequest: string) => {
834
- //Here you would usually call the WebLN or NWC to execute the payment, it's completely fine if the
835
- // promise here would block till the payment is settled
836
- return Promise.resolve("");
837
- }
838
- },
839
- { //Callbacks
840
- onSourceTransactionReceived: (sourceLnPaymentHash: string) => {
841
- //Lightning network payment received by the LP
842
- },
843
- onDestinationCommitSent: (destinationCommitTxId: string) => {
844
- //HTLC initialization transaction sent on the destination chain
845
- },
846
- onDestinationClaimSent: (destinationClaimTxId: string) => {
847
- //HTLC claim transaction sent on the destination chain
848
- },
849
- onSwapSettled: (destinationClaimTxId: string) => {
850
- //Swap settled and funds received on destination
851
- }
852
- }
853
- );
854
- ```
855
-
856
- <details>
857
- <summary>Manual swap execution (advanced)</summary>
858
-
859
- - __1.__ Pay the LN invoice from a lightning network wallet
860
- ```typescript
861
- const lightningInvoice = swap.getAddress();
862
- ```
863
-
864
- - __2.__ Start listening to incoming lightning network payment
865
- ```typescript
866
- const success = await swap.waitForPayment();
867
- if(!success) {
868
- //Lightning network payment not received in time and quote expired
869
- return;
870
- }
871
- ```
872
-
873
- - __3.__ Claim the swap at the destination
874
-
875
- - __a.__ Commit & claim with signer
876
- ```typescript
877
- await swap.commitAndClaim(solanaSigner);
878
- ```
879
-
880
- - __b.__ Or get the transactions & [sign and send transaction manually](#manually-signing-smart-chain-transactions)
881
- ```typescript
882
- const txsCommitAndClaim = await swap.txsCommitAndClaim();
883
- //Take EXTRA care to make sure transaction are sent sequentially and in order - always wait
884
- // for prior transaction confirmation before sending the next one
885
- //Sign and send these...
886
- ...
887
- ```
888
-
889
- </details>
890
-
891
- <details>
892
- <summary>Swap states</summary>
893
-
894
- - FromBTCLNSwapState.FAILED = -4
895
- - If the claiming of the funds was initiated, but never concluded, the user will get his lightning network payment refunded
896
- - FromBTCLNSwapState.QUOTE_EXPIRED = -3
897
- - Swap quote expired and cannot be executed anymore
898
- - FromBTCLNSwapState.QUOTE_SOFT_EXPIRED = -2
899
- - Swap quote soft-expired (i.e. the quote probably expired, but if there is already an initialization transaction sent it might still succeed)
900
- - FromBTCLNSwapState.EXPIRED = -1
901
- - Lightning network invoice expired, meaning the swap is expired
902
- - FromBTCLNSwapState.PR_CREATED = 0
903
- - Swap is created, the user should now pay the provided lightning network invoice
904
- - FromBTCLNSwapState.PR_PAID = 1
905
- - Lightning network invoice payment was received (but cannot be settled by the counterparty yet)
906
- - FromBTCLNSwapState.CLAIM_COMMITED = 2
907
- - Claiming of the funds was initiated
908
- - FromBTCLNSwapState.CLAIM_CLAIMED = 3
909
- - Funds were successfully claimed & lightning network secret pre-image revealed, so the lightning network payment will settle now
910
-
911
- </details>
912
-
913
- #### Swap Bitcoin lightning network -> Starknet/EVM
914
-
915
- Getting swap quote
916
-
917
- ```typescript
918
- const swap: FromBTCLNAutoSwap<StarknetChainType> = await swapper.swap(
919
- Tokens.BITCOIN.BTCLN, //Swap from BTC-LN
920
- Tokens.STARKNET.STRK, //Into specified destination token
921
- 10000n, //Amount can be either passed in base units as bigint or in decimal format as string
922
- SwapAmountType.EXACT_IN, //SwapAmountType.EXACT_IN, so we specify the input amount
923
- undefined, //Source address for the swap, not used for swaps from BTC-LN
924
- signer.getAddress(), //Destination address
925
- {
926
- gasAmount: 1_000_000_000_000_000_000n //We can also request a gas drop on the destination chain (here requesting 1 STRK)
927
- }
928
- );
929
-
930
- //Get the bitcoin lightning network invoice (the invoice contains pre-entered amount)
931
- const receivingLightningInvoice: string = swap.getAddress();
932
- //Get the URI hyperlink (contains the lightning network invoice) which can be displayed also as QR code
933
- const qrCodeData: string = swap.getHyperlink();
934
-
935
- //Get the amount required to pay and fee
936
- const input: string = swap.getInputWithoutFee().toString(); //Input amount excluding fees
937
- const fee: string = swap.getFee().amountInSrcToken.toString(); //Fees paid on the output
938
- const inputWithFees: string = swap.getInput().toString(); //Total amount paid including fees
939
-
940
- const output: string = swap.getOutput().toString(); //Total output amount
941
-
942
- //Get swap expiration time
943
- const expiry: number = swap.getQuoteExpiry(); //Expiration time of the swap quote in UNIX milliseconds, swap needs to be initiated before this time
944
-
945
- //Get pricing info
946
- const swapPrice = swap.getPriceInfo().swapPrice; //Price of the current swap (excluding fees)
947
- const marketPrice = swap.getPriceInfo().marketPrice; //Current market price
948
- const difference = swap.getPriceInfo().difference; //Difference between the swap price & current market price
949
- ```
950
-
951
- Executing the swap (simple)
952
-
953
- ```typescript
954
- const automaticSettlementSuccess = await swap.execute(
955
- { //Lightning network wallet, you can also pass null/undefined and pay the LN invoice from an external wallet
956
- payInvoice: (bolt11PaymentRequest: string) => {
957
- //Here you would usually call the WebLN or NWC to execute the payment, it's completely fine if the
958
- // promise here would block till the payment is settled
959
- return Promise.resolve("");
960
- }
961
- },
962
- { //Callbacks
963
- onSourceTransactionReceived: (sourceLnPaymentHash: string) => {
964
- //Lightning network payment received by the LP
965
- },
966
- onSwapSettled: (destinationClaimTxId: string) => {
967
- //Swap settled and funds received on destination
968
- }
969
- }
970
- );
971
-
972
- //In case the automatic swap settlement fails, we can settle it manually using the wallet of the destination chain
973
- if(!automaticSettlementSuccess) {
974
- await swap.claim(starknetSigner);
975
- }
976
- ```
977
-
978
-
979
- <details>
980
- <summary>Manual swap execution (advanced)</summary>
981
-
982
- - __1.__ Pay the LN invoice from a lightning network wallet
983
- ```typescript
984
- const lightningInvoice = swap.getAddress();
985
- ```
986
-
987
- - __2.__ Start listening to incoming lightning network payment
988
- ```typescript
989
- const success = await swap.waitForPayment();
990
- if(!success) {
991
- //Lightning network payment not received in time and quote expired
992
- return;
993
- }
994
- ```
995
-
996
- - __3.__ Wait for the swap to be automatically settled
997
- ```typescript
998
- const automaticSettlementSuccess = await swap.waitTillClaimed(60);
999
- ```
1000
-
1001
- - __4.__ In case the automatic swap settlement fails, we can settle it manually using the wallet of the destination chain
1002
-
1003
- - __a.__ Claim with signer
1004
- ```typescript
1005
- if(!automaticSettlementSuccess) {
1006
- await swap.claim(starknetSigner);
1007
- }
1008
- ```
1009
-
1010
- - __b.__ Or get the transactions & [sign and send transaction manually](#manually-signing-smart-chain-transactions)
1011
- ```typescript
1012
- if(!automaticSettlementSuccess) {
1013
- const txsClaim = await swap.txsClaim();
1014
- //Sign and send these...
1015
- ...
1016
- }
1017
- ```
1018
-
1019
- </details>
1020
-
1021
- <details>
1022
- <summary>Swap states</summary>
1023
-
1024
- - FromBTCLNAutoSwapState.FAILED = -4
1025
- - If the claiming of the funds was initiated, but never concluded, the user will get his lightning network payment refunded
1026
- - FromBTCLNAutoSwapState.QUOTE_EXPIRED = -3
1027
- - Swap quote expired and cannot be executed anymore
1028
- - FromBTCLNAutoSwapState.QUOTE_SOFT_EXPIRED = -2
1029
- - Swap quote soft-expired (i.e. the quote probably expired, but if there is already an initialization transaction sent it might still succeed)
1030
- - FromBTCLNAutoSwapState.EXPIRED = -1
1031
- - Lightning network invoice expired, meaning the swap is expired
1032
- - FromBTCLNAutoSwapState.PR_CREATED = 0
1033
- - Swap is created, the user should now pay the provided lightning network invoice
1034
- - FromBTCLNAutoSwapState.PR_PAID = 1
1035
- - Lightning network invoice payment was received (but cannot be settled by the counterparty yet)
1036
- - FromBTCLNAutoSwapState.CLAIM_COMMITED = 2
1037
- - A swap HTLC was offered by the LP to the user
1038
- - FromBTCLNAutoSwapState.CLAIM_CLAIMED = 3
1039
- - Funds were successfully claimed & lightning network secret pre-image revealed, so the lightning network payment will settle now
1040
-
1041
- </details>
1042
-
1043
- ### LNURLs & readable lightning identifiers
1044
-
1045
- LNURLs extend the lightning network functionality by creating static lightning addreses (LNURL-pay & static internet identifiers) and QR codes which allow you to pull funds from them (LNURL-withdraw)
1046
-
1047
- This SDK supports:
1048
- * LNURL-pay ([LUD-6](https://github.com/lnurl/luds/blob/luds/06.md), [LUD-9](https://github.com/lnurl/luds/blob/luds/09.md), [LUD-10](https://github.com/lnurl/luds/blob/luds/10.md), [LUD-12](https://github.com/lnurl/luds/blob/luds/12.md))
1049
- * LNURL-withdraw ([LUD-3](https://github.com/lnurl/luds/blob/luds/03.md))
1050
- * Static internet identifiers ([LUD-16](https://github.com/lnurl/luds/blob/luds/16.md))
1051
-
1052
- You can parse LNURLs and lightning invoices automatically using the [Unified address parser](#unified-address-parser)
1053
-
1054
- #### Differences
1055
-
1056
- Lightning invoices:
1057
- * One time use only
1058
- * Need to have a fixed amount, therefore recipient has to set the amount
1059
- * Static and bounded expiration
1060
- * You can only pay to a lightning invoice, not withdraw funds from it
1061
-
1062
- LNURLs & lightning identifiers:
1063
- * Reusable
1064
- * Programmable expiry
1065
- * Allows payer to set an amount
1066
- * Supports both, paying (LNURL-pay) and withdrawing (LNURL-withdraw)
1067
- * Possibility to attach a message/comment to a payment
1068
- * Receive a message/url as a result of the payment
1069
-
1070
- #### Swap Smart chain -> Bitcoin lightning network
1071
-
1072
- Getting swap quote
1073
-
1074
- ```typescript
1075
- //Create the swap: swapping SOL to Bitcoin lightning
1076
- const swap: ToBTCLNSwap<SolanaChainType> = await swapper.swap(
1077
- Tokens.SOLANA.SOL, //From specified source token
1078
- Tokens.BITCOIN.BTCLN, //Swap to BTC-LN
1079
- 10000n, //Now we can specify an amount for a lightning network payment!
1080
- SwapAmountType.EXACT_OUT, //We can also use exactIn=true here and set an amount in input token
1081
- solanaSigner.getAddress(), //Source address and smart chain signer
1082
- //Destination LNURL-pay or readable identifier
1083
- "lnurl1dp68gurn8ghj7ampd3kx2ar0veekzar0wd5xjtnrdakj7tnhv4kxctttdehhwm30d3h82unvwqhkx6rfvdjx2ctvxyesuk0a27",
1084
- {
1085
- comment: "Hello world" //For LNURL-pay we can also pass a comment to the recipient
1086
- }
1087
- );
1088
-
1089
- //Get the amount required to pay and fee
1090
- const input: string = swap.getInputWithoutFee().toString(); //Input amount excluding fees
1091
- const fee: string = swap.getFee().amountInSrcToken.toString(); //Fees paid on the output
1092
- const inputWithFees: string = swap.getInput().toString(); //Total amount paid including fees
1093
-
1094
- const output: string = swap.getOutput().toString(); //Total output amount
1095
-
1096
- //Get swap expiration time
1097
- const expiry: number = swap.getQuoteExpiry(); //Expiration time of the swap quote in UNIX milliseconds, swap needs to be initiated before this time
1098
-
1099
- //Get pricing info
1100
- const swapPrice = swap.getPriceInfo().swapPrice; //Price of the current swap (excluding fees)
1101
- const marketPrice = swap.getPriceInfo().marketPrice; //Current market price
1102
- const difference = swap.getPriceInfo().difference; //Difference between the swap price & current market price
1103
- ```
1104
-
1105
-
1106
- Executing the swap (simple)
1107
-
1108
- ```typescript
1109
- const swapSuccessful = await swap.execute(
1110
- solanaSigner,
1111
- { //Callbacks
1112
- onSourceTransactionSent: (txId: string) => {
1113
- //Transaction on the source chain was sent
1114
- },
1115
- onSourceTransactionConfirmed: (txId: string) => {
1116
- //Transaction on the source chain was confirmed
1117
- },
1118
- onSwapSettled: (destinationTxId: string) => {
1119
- //Lightning payment on the destination chain was sent and swap settled
1120
- }
1121
- }
1122
- );
1123
-
1124
- //Refund in case of failure
1125
- if(!swapSuccessful) {
1126
- //Swap failed, money can be refunded
1127
- await swap.refund(solanaSigner);
1128
- return;
1129
- }
1130
-
1131
- //Swap successful!
1132
- const lightningSecret = swap.getSecret();
1133
- //In case the LNURL contained a success action, we can read it now and display it to user
1134
- if(swap.hasSuccessAction()) {
1135
- //Contains a success action that should displayed to the user
1136
- const successMessage = swap.getSuccessAction();
1137
- const description: string = successMessage.description; //Description of the message
1138
- const text: (string | null) = successMessage.text; //Main text of the message
1139
- const url: (string | null) = successMessage.url; //URL link which should be displayed
1140
- }
1141
- ```
1142
-
1143
- <details>
1144
- <summary>Manual swap execution (advanced)</summary>
1145
-
1146
- - __1.__ Initiate the swap on the smart-chain side
1147
-
1148
- - __a.__ Commit with a signer
1149
- ```typescript
1150
- await swap.commit(solanaSigner);
1151
- ```
1152
-
1153
- - __b.__ Or get the transactions & [sign and send transaction manually](#manually-signing-smart-chain-transactions)
1154
- ```typescript
1155
- const txsCommit = await swap.txsCommit();
1156
- //Sign and send these...
1157
- ...
1158
- //Important to wait till SDK processes the swap initialization
1159
- await swap.waitTillCommited();
1160
- ```
1161
-
1162
- - __2.__ Wait for the swap to execute and for the payment to be sent
1163
-
1164
- ```typescript
1165
- const swapSuccessful = await swap.waitForPayment();
1166
- ```
1167
-
1168
- - __3.__ In case the swap fails we can refund our funds on the source chain
1169
-
1170
- - __a.__ Refund with a signer
1171
- ```typescript
1172
- if(!swapSuccessful) {
1173
- await swap.refund(solanaSigner);
1174
- return;
1175
- }
1176
- ```
1177
-
1178
- - __b.__ Or get the transactions & [sign and send transaction manually](#manually-signing-smart-chain-transactions)
1179
- ```typescript
1180
- if(!swapSuccessful) {
1181
- const txsRefund = await swap.txsRefund();
1182
- //Sign and send these...
1183
- ...
1184
- }
1185
- ```
1186
-
1187
- </details>
1188
-
1189
- #### Swap Bitcoin lightning network -> Solana
1190
-
1191
- NOTE: Solana uses an old swap protocol for Bitcoin lightning network -> Solana swaps, the flow here is different from the one for Starknet and other chains.
1192
-
1193
- Getting swap quote
1194
-
1195
- ```typescript
1196
- const swap: FromBTCLNSwap<SolanaChainType> = await swapper.swap(
1197
- Tokens.BITCOIN.BTCLN, //Swap from BTC-LN
1198
- Tokens.SOLANA.SOL, //Into specified destination token
1199
- 10000n,
1200
- SwapAmountType.EXACT_IN, //EXACT_IN, so we specify the input amount
1201
- //Source LNURL-withdraw link
1202
- "lnurl1dp68gurn8ghj7ampd3kx2ar0veekzar0wd5xjtnrdakj7tnhv4kxctttdehhwm30d3h82unvwqhkx6rfvdjx2ctvxyesuk0a27",
1203
- signer.getAddress(), //Destination address
1204
- );
1205
-
1206
- //Get the amount required to pay and fee
1207
- const input: string = swap.getInputWithoutFee().toString(); //Input amount excluding fees
1208
- const fee: string = swap.getFee().amountInSrcToken.toString(); //Fees paid on the output
1209
- const inputWithFees: string = swap.getInput().toString(); //Total amount paid including fees
1210
-
1211
- const output: string = swap.getOutput().toString(); //Total output amount
1212
-
1213
- //Get swap expiration time
1214
- const expiry: number = swap.getQuoteExpiry(); //Expiration time of the swap quote in UNIX milliseconds, swap needs to be initiated before this time
1215
-
1216
- //Get security deposit amount (Human readable amount of STRK that needs to be put down to rent the liquidity from swap intermediary), you will get this deposit back if the swap succeeds
1217
- const securityDeposit: string = swap.getSecurityDeposit().toString();
1218
-
1219
- //Get pricing info
1220
- const swapPrice = swap.getPriceInfo().swapPrice; //Price of the current swap (excluding fees)
1221
- const marketPrice = swap.getPriceInfo().marketPrice; //Current market price
1222
- const difference = swap.getPriceInfo().difference; //Difference between the swap price & current market price
1223
- ```
1224
-
1225
- Executing the swap (simple)
1226
-
1227
- ```typescript
1228
- await swap.execute(
1229
- solanaSigner,
1230
- undefined, //No need to specify a wallet, we are sourcing the fund from LNURL-withdraw link
1231
- { //Callbacks
1232
- onSourceTransactionReceived: (sourceLnPaymentHash: string) => {
1233
- //Lightning network payment received by the LP
1234
- },
1235
- onDestinationCommitSent: (destinationCommitTxId: string) => {
1236
- //HTLC initialization transaction sent on the destination chain
1237
- },
1238
- onDestinationClaimSent: (destinationClaimTxId: string) => {
1239
- //HTLC claim transaction sent on the destination chain
1240
- },
1241
- onSwapSettled: (destinationClaimTxId: string) => {
1242
- //Swap settled and funds received on destination
1243
- }
1244
- }
1245
- );
1246
- ```
1247
-
1248
- <details>
1249
- <summary>Manual swap execution (advanced)</summary>
1250
-
1251
- - __1.__ Start listening to incoming lightning network payment (this also requests the payment from LNURL-withdraw service)
1252
- ```typescript
1253
- const success = await swap.waitForPayment();
1254
- if(!success) {
1255
- //Lightning network payment not received in time and quote expired
1256
- return;
1257
- }
1258
- ```
1259
-
1260
- - __2.__ Claim the swap at the destination
1261
-
1262
- - __a.__ Commit & claim with signer
1263
- ```typescript
1264
- await swap.commitAndClaim(solanaSigner);
1265
- ```
1266
-
1267
- - __b.__ Or get the transactions & [sign and send transaction manually](#manually-signing-smart-chain-transactions)
1268
- ```typescript
1269
- const txsCommitAndClaim = await swap.txsCommitAndClaim();
1270
- //Take EXTRA care to make sure transaction are sent sequentially and in order - always wait
1271
- // for prior transaction confirmation before sending the next one
1272
- //Sign and send these...
1273
- ...
1274
- ```
1275
-
1276
- </details>
1277
-
1278
- #### Swap Bitcoin lightning network -> Starknet/EVM
1279
-
1280
- Getting swap quote
1281
-
1282
- ```typescript
1283
- const swap: FromBTCLNAutoSwap<StarknetChainType> = await swapper.swap(
1284
- Tokens.BITCOIN.BTCLN, //Swap from BTC-LN
1285
- Tokens.STARKNET.STRK, //Into specified destination token
1286
- 10000n,
1287
- SwapAmountType.EXACT_IN, //EXACT_IN, so we specify the input amount
1288
- //Source LNURL-withdraw link
1289
- "lnurl1dp68gurn8ghj7ampd3kx2ar0veekzar0wd5xjtnrdakj7tnhv4kxctttdehhwm30d3h82unvwqhkx6rfvdjx2ctvxyesuk0a27",
1290
- signer.getAddress(), //Destination address
1291
- {
1292
- gasAmount: 1_000_000_000_000_000_000n //We can also request a gas drop on the destination chain (here requesting 1 STRK)
1293
- }
1294
- );
1295
-
1296
- //Get the amount required to pay and fee
1297
- const input: string = swap.getInputWithoutFee().toString(); //Input amount excluding fees
1298
- const fee: string = swap.getFee().amountInSrcToken.toString(); //Fees paid on the output
1299
- const inputWithFees: string = swap.getInput().toString(); //Total amount paid including fees
1300
-
1301
- const output: string = swap.getOutput().toString(); //Total output amount
1302
-
1303
- //Get swap expiration time
1304
- const expiry: number = swap.getQuoteExpiry(); //Expiration time of the swap quote in UNIX milliseconds, swap needs to be initiated before this time
1305
-
1306
- //Get pricing info
1307
- const swapPrice = swap.getPriceInfo().swapPrice; //Price of the current swap (excluding fees)
1308
- const marketPrice = swap.getPriceInfo().marketPrice; //Current market price
1309
- const difference = swap.getPriceInfo().difference; //Difference between the swap price & current market price
1310
- ```
1311
-
1312
-
1313
- Executing the swap (simple)
1314
-
1315
- ```typescript
1316
- const automaticSettlementSuccess = await swap.execute(
1317
- undefined, //No need to specify a wallet, we are sourcing the funds from LNURL-withdraw link
1318
- { //Callbacks
1319
- onSourceTransactionReceived: (sourceLnPaymentHash: string) => {
1320
- //Lightning network payment received by the LP
1321
- },
1322
- onSwapSettled: (destinationClaimTxId: string) => {
1323
- //Swap settled and funds received on destination
1324
- }
1325
- }
1326
- );
1327
-
1328
- //In case the automatic swap settlement fails, we can settle it manually using the wallet of the destination chain
1329
- if(!automaticSettlementSuccess) {
1330
- await swap.claim(starknetSigner);
1331
- }
1332
- ```
1333
-
1334
-
1335
- <details>
1336
- <summary>Manual swap execution (advanced)</summary>
1337
-
1338
- - __1.__ Start listening to incoming lightning network payment (this also requests the payment from LNURL-withdraw service)
1339
- ```typescript
1340
- const success = await swap.waitForPayment();
1341
- if(!success) {
1342
- //Lightning network payment not received in time and quote expired
1343
- return;
1344
- }
1345
- ```
1346
-
1347
- - __2.__ Wait for the swap to be automatically settled
1348
- ```typescript
1349
- const automaticSettlementSuccess = await swap.waitTillClaimed(60);
1350
- ```
1351
-
1352
- - __3.__ In case the automatic swap settlement fails, we can settle it manually using the wallet of the destination chain
1353
-
1354
- - __a.__ Claim with signer
1355
- ```typescript
1356
- if(!automaticSettlementSuccess) {
1357
- await swap.claim(starknetSigner);
1358
- }
1359
- ```
1360
-
1361
- - __b.__ Or get the transactions & [sign and send transaction manually](#manually-signing-smart-chain-transactions)
1362
- ```typescript
1363
- if(!automaticSettlementSuccess) {
1364
- const txsClaim = await swap.txsClaim();
1365
- //Sign and send these...
1366
- ...
1367
- }
1368
- ```
1369
-
1370
- </details>
1371
-
1372
- ### Exact-In Smart Chain - Lightning swaps
1373
-
1374
- The main limitation of regular lightning network swaps (Smart chains -> Lightning), is the fact that exactIn swaps are not possible (as invoices need to have a fixed amount). LNURL-pay links solve this issue, but are not supported by all the wallets. Therefore, the SDK exposes a hook/callback that can be implemented by lightning wallets directly, which request fixed amount invoices on-demand. This then makes exact input amount swaps possible. The way it works:
1375
-
1376
- 1. SDK sends a request to the LP saying it wants to swap `x` USDC to BTC, with a dummy invoice (either 1 sat or as specified in the `minMsats` parameter - this is requested from the `getInvoice()` function) - this dummy invoice is used to estimate the routing fees by the LP (extra care must be taken for both invoices, dummy and the real one to have the same destination node public key & routing hints).
1377
- 2. LP responds with the output amount of `y` BTC
1378
- 3. SDK calls the provided `getInvoice()` callback to request the real invoice for the `y` amount of BTC (in satoshis)
1379
- 4. SDK forwards the returned fixed amount (`y` BTC) lightning network invoice back to the LP to finish creating the quote
1380
-
1381
- Getting swap quote
1382
-
1383
- ```typescript
1384
- //Create the swap: swapping SOL to Bitcoin lightning
1385
- const swap: ToBTCLNSwap<SolanaChainType> = await swapper.swap(
1386
- Tokens.SOLANA.SOL, //From specified source token
1387
- Tokens.BITCOIN.BTCLN, //Swap to BTC-LN
1388
- 1_000_000_000n, //We can specify an amount for a lightning network payment!
1389
- SwapAmountType.EXACT_IN, //We can use exactIn=true here and set an amount in input token
1390
- solanaSigner.getAddress(), //Source address and smart chain signer
1391
- //Instead of the destination we pass a handler object
1392
- {
1393
- getInvoice: async (amountSats: number, abortSignal?: AbortSignal) => {
1394
- //Generate invoice with fixed amountSats here!
1395
- ...
1396
- return invoice;
1397
- },
1398
- //Optionally you can also specify minimum and maximum in msats (millisatoshis, 1 sat = 1000 msats)
1399
- minMsats: 1_000_000n,
1400
- maxMsats: 1_000_000_000n
1401
- },
1402
- {
1403
- comment: "Hello world" //For LNURL-pay we can also pass a comment to the recipient
1404
- }
1405
- );
1406
-
1407
- //Get the amount required to pay and fee
1408
- const input: string = swap.getInputWithoutFee().toString(); //Input amount excluding fees
1409
- const fee: string = swap.getFee().amountInSrcToken.toString(); //Fees paid on the output
1410
- const inputWithFees: string = swap.getInput().toString(); //Total amount paid including fees
1411
-
1412
- const output: string = swap.getOutput().toString(); //Total output amount
1413
-
1414
- //Get swap expiration time
1415
- const expiry: number = swap.getQuoteExpiry(); //Expiration time of the swap quote in UNIX milliseconds, swap needs to be initiated before this time
1416
-
1417
- //Get pricing info
1418
- const swapPrice = swap.getPriceInfo().swapPrice; //Price of the current swap (excluding fees)
1419
- const marketPrice = swap.getPriceInfo().marketPrice; //Current market price
1420
- const difference = swap.getPriceInfo().difference; //Difference between the swap price & current market price
1421
- ```
1422
-
1423
-
1424
- Executing the swap (simple)
1425
-
1426
- ```typescript
1427
- const swapSuccessful = await swap.execute(
1428
- solanaSigner,
1429
- { //Callbacks
1430
- onSourceTransactionSent: (txId: string) => {
1431
- //Transaction on the source chain was sent
1432
- },
1433
- onSourceTransactionConfirmed: (txId: string) => {
1434
- //Transaction on the source chain was confirmed
1435
- },
1436
- onSwapSettled: (destinationTxId: string) => {
1437
- //Lightning payment on the destination chain was sent and swap settled
1438
- }
1439
- }
1440
- );
1441
-
1442
- //Refund in case of failure
1443
- if(!swapSuccessful) {
1444
- //Swap failed, money can be refunded
1445
- await swap.refund(solanaSigner);
1446
- return;
1447
- }
1448
-
1449
- //Swap successful!
1450
- const lightningSecret = swap.getSecret();
1451
- ```
1452
-
1453
- <details>
1454
- <summary>Manual swap execution (advanced)</summary>
1455
-
1456
- - __1.__ Initiate the swap on the smart-chain side
1457
-
1458
- - __a.__ Commit with a signer
1459
- ```typescript
1460
- await swap.commit(solanaSigner);
1461
- ```
1462
-
1463
- - __b.__ Or get the transactions & [sign and send transaction manually](#manually-signing-smart-chain-transactions)
1464
- ```typescript
1465
- const txsCommit = await swap.txsCommit();
1466
- //Sign and send these...
1467
- ...
1468
- //Important to wait till SDK processes the swap initialization
1469
- await swap.waitTillCommited();
1470
- ```
1471
-
1472
- - __2.__ Wait for the swap to execute and for the payment to be sent
1473
-
1474
- ```typescript
1475
- const swapSuccessful = await swap.waitForPayment();
1476
- ```
1477
-
1478
- - __3.__ In case the swap fails we can refund our funds on the source chain
1479
-
1480
- - __a.__ Refund with a signer
1481
- ```typescript
1482
- if(!swapSuccessful) {
1483
- await swap.refund(solanaSigner);
1484
- return;
1485
- }
1486
- ```
1487
-
1488
- - __b.__ Or get the transactions & [sign and send transaction manually](#manually-signing-smart-chain-transactions)
1489
- ```typescript
1490
- if(!swapSuccessful) {
1491
- const txsRefund = await swap.txsRefund();
1492
- //Sign and send these...
1493
- ...
1494
- }
1495
- ```
1496
-
1497
- </details>
1498
-
1499
- ### Getting state of the swap
1500
-
1501
- You can get the current state of the swap with:
1502
-
1503
- ```typescript
1504
- const state = swap.getState();
1505
- ```
1506
-
1507
- You can also set a listener to listen for swap state changes:
1508
-
1509
- ```typescript
1510
- swap.events.on("swapState", swap => {
1511
- const newState = swap.getState();
1512
- });
1513
- ```
1514
-
1515
- For the meaning of the states please refer to the "Swap state" section under each swap type.
1516
-
1517
- ### Swap size limits
1518
-
1519
- Swap sizes are limited by the LPs you are connected to, they are advertised in BTC terms by LPs during handshake
1520
-
1521
- ```typescript
1522
- const swapLimits = swapper.getSwapLimits(srcToken, dstToken);
1523
- const inputMin = swapLimits.input.min;
1524
- const inputMax = swapLimits.input.max;
1525
- const outputMin = swapLimits.output.min;
1526
- const outputMax = swapLimits.output.max;
1527
- ```
1528
-
1529
- NOTE: swap limits denominated in BTC are retrieved from the LPs during initial handshake, however limits in other tokens are only returned when getting a quote fails due to amount being too low or too high. For example if you want to get swap limits for the BTC -> SOL swap, the input limits will be immediately available, while the output limits will only get populated once a quote request fails due to amount being too low or high.
1530
-
1531
- ```typescript
1532
- let swapLimits = swapper.getSwapLimits(Tokens.BITCOIN.BTC, Tokens.SOLANA.SOL);
1533
- let inputMin = swapLimits.input.min; //Immediately available
1534
- let inputMax = swapLimits.input.max; //Immediately available
1535
- let outputMin = swapLimits.output.min; //Not available from the get-go
1536
- let outputMax = swapLimits.output.max; //Not available from the get-go
1537
-
1538
- //You can also listen to swap limit changes (optional)
1539
- swapper.on("swapLimitsChanged", () => {
1540
- //New limits available with swapper.getSwapLimits(srcToken, dstToken)
1541
- //Useful in e.g. a react application where you want to dynamically set min/max swappable amount
1542
- })
1543
-
1544
- //Try to swap really small amount of SOL with exactOut swap
1545
- try {
1546
- const swap = await swapper.swap(
1547
- Tokens.BITCOIN.BTC, //Swap from BTC
1548
- Tokens.SOLANA.SOL, //Into specified destination token
1549
- 1n, //1 lamport = 0.000000001 SOL
1550
- false, //Whether we define an input or output amount
1551
- undefined, //Source address for the swap, not used for swaps from BTC
1552
- solanaSigner.getAddress() //Destination address
1553
- );
1554
- } catch (e) {
1555
- //Fails with OutOfBoundsError
1556
- }
1557
-
1558
- swapLimits = swapper.getSwapLimits(Tokens.BITCOIN.BTC, Tokens.SOLANA.SOL);
1559
- inputMin = swapLimits.input.min; //Immediately available
1560
- inputMax = swapLimits.input.max; //Immediately available
1561
- outputMin = swapLimits.output.min; //Now available due to failed quote
1562
- outputMax = swapLimits.output.max; //Now available due to failed quote
1563
- ```
1564
-
1565
- ### Stored swaps
1566
-
1567
- #### Get swap by ID
1568
-
1569
- You can retrieve a swap by it's id, you can get an ID of the swap with
1570
-
1571
- ```typescript
1572
- const swapId = swap.getId();
1573
- ```
1574
-
1575
- And then later retrieve it from the storage
1576
-
1577
- ```typescript
1578
- import {isSwapType} from "@atomiqlabs/sdk";
1579
-
1580
- //Use this to obtain a correctly typed swap, returns `undefined` if the type of the
1581
- // underlying swap is not as requested, `swapType` uses the SwapType enum
1582
- const typedSwap = await swapper.getTypedSwapById(swapId, chainId, swapType);
1583
-
1584
- //This returns just a base type `ISwap`, so you have to do typecasting yourself, useful
1585
- // if you don't know which type of the swap to expect
1586
- const swap = await swapper.getSwapById(swapId);
1587
- //You can later narrow this down with the `isSwapType()` typeguard
1588
- if(isSwapType(swap, swapType)) {
1589
- //You now have a properly narrowed down type of the swap here
1590
- }
1591
- ```
1592
-
1593
- #### Get refundable swaps
1594
- You can refund the swaps in one of two cases:
1595
- * In case intermediary is non-cooperative and goes offline, you can claim the funds from the swap contract back after some time.
1596
- * In case intermediary tried to pay but was unsuccessful, so he sent you signed message with which you can refund now without waiting.
1597
-
1598
- This call can be checked on every startup and periodically every few minutes.
1599
- ```typescript
1600
- //Get refundable swaps and refund them
1601
- const refundableSolanaSwaps = await swapper.getRefundableSwaps("SOLANA", solanaSigner.getAddress());
1602
- for(let swap of refundableSolanaSwaps) await swap.refund(solanaSigner);
1603
- const refundableStarknetSwaps = await swapper.getRefundableSwaps("STARKNET", starknetSigner.getAddress());
1604
- for(let swap of refundableStarknetSwaps) await swap.refund(starknetSigner);
1605
- ```
1606
-
1607
- #### Get claimable swaps
1608
- Returns swaps that are ready to be claimed by the client, this can happen if client closes the application when a swap is in-progress and the swap is concluded while the client is offline.
1609
-
1610
- ```typescript
1611
- //Get the swaps
1612
- const claimableSolanaSwaps = await swapper.getClaimableSwaps("SOLANA", solanaSigner.getAddress());
1613
- //Claim all the claimable swaps
1614
- for(let swap of claimableSolanaSwaps) {
1615
- await swap.claim(solanaSigner);
1616
- }
1617
- //Get the swaps
1618
- const claimableStarknetSwaps = await swapper.getClaimableSwaps("STARKNET", starknetSigner.getAddress());
1619
- //Claim all the claimable swaps
1620
- for(let swap of claimableStarknetSwaps) {
1621
- await swap.claim(starknetSigner);
1622
- }
1623
- ```
1624
-
1625
- ### Helpers
1626
-
1627
- #### Getting wallet balances
1628
-
1629
- The SDK also contains helper functions for getting the maximum spendable balance of wallets
1630
-
1631
- ```typescript
1632
- //Spendable balance of the starknet wallet address (discounting transaction fees)
1633
- const strkBalance = await swapper.Utils.getSpendableBalance(starknetSigner, Tokens.STARKNET.STRK);
1634
- //Spendable balance of the solana wallet address (discounting transaction fees)
1635
- const solBalance = await swapper.Utils.getSpendableBalance(solanaSigner, Tokens.SOLANA.SOL);
1636
- //Spendable balance of the bitcoin wallet - here we also need to specify the destination chain (as there are different swap protocols available with different on-chain footprints)
1637
- const {balance: btcBalance, feeRate: btcFeeRate} = await swapper.Utils.getBitcoinSpendableBalance(bitcoinWalletAddress, "SOLANA");
1638
- ```
1639
-
1640
- #### Unified address parser
1641
-
1642
- A common way for parsing all address formats supported by the SDK, automatically recognizes:
1643
- - Bitcoin on-chain L1 address formats (p2pkh, p2wpkh, p2wsh, p2wsh, p2tr)
1644
- - [BIP-21](https://en.bitcoin.it/wiki/BIP_0021) bitcoin payment URI
1645
- - BOLT11 lightning network invoices
1646
- - [LUD-6](https://github.com/lnurl/luds/blob/luds/06.md) LNURL-pay links
1647
- - [LUD-3](https://github.com/lnurl/luds/blob/luds/03.md) LNURL-withdraw links
1648
- - [LUD-16](https://github.com/lnurl/luds/blob/luds/16.md) Lightning static internet identifiers
1649
- - Smart chain addresses (Solana, Starknet, etc.)
1650
-
1651
- ```typescript
1652
- const res = await swapper.Utils.parseAddress(address);
1653
- switch(res.type) {
1654
- case "BITCOIN":
1655
- //Bitcoin on-chain L1 address or BIP-21 URI scheme with amount
1656
- const btcAmount = res.amount;
1657
- break;
1658
- case "LIGHTNING":
1659
- //BOLT11 lightning network invoice with pre-set amount
1660
- const lnAmount = res.amount;
1661
- break;
1662
- case "LNURL":
1663
- //LNURL payment or withdrawal link
1664
- if(isLNURLWithdraw(res.lnurl)) {
1665
- //LNURL-withdraw allowing withdrawals over the lightning network
1666
- const lnurlWithdrawData: LNURLWithdraw = res.lnurl;
1667
- const minWithdrawable = res.min; //Minimum payment amount
1668
- const maxWithdrawable = res.max; //Maximum payment amount
1669
- const fixedAmount = res.amount; //If res.min===res.max, an fixed amount is returned instead
1670
- //Should show a UI allowing the user to choose an amount he wishes to withdraw
1671
- }
1672
- if(isLNURLPay(res.lnurl)) {
1673
- //LNURL-pay or static lightning internet identifier allowing repeated payments over the lightning network
1674
- const lnurlPayData: LNURLPay = res.lnurl;
1675
- const minPayable = res.min; //Minimum payment amount
1676
- const maxPayable = res.max; //Maximum payment amount
1677
- const fixedAmount = res.amount; //If res.min===res.max, an fixed amount is returned instead
1678
- const icon: (string | null) = res.lnurl.icon; //URL encoded icon that should be displayed on the UI
1679
- const shortDescription: (string | null) = res.lnurl.shortDescription; //Short description of the payment
1680
- const longDescription: (string | null) = res.lnurl.longDescription; //Long description of the payment
1681
- const maxCommentLength: (number | 0) = res.lnurl.commentMaxLength; //Maximum allowed length of the payment message/comment (0 means no comment allowed)
1682
- //Should show a UI displaying the icon, short description, long description, allowing the user to choose an amount he wishes to pay and possibly also a comment
1683
- }
1684
- break;
1685
- default:
1686
- //Addresses for smart chains
1687
- break;
1688
- }
1689
- ```
1690
-
1691
- ### Manually signing smart chain transactions
1692
-
1693
- You can also sign the transactions on smart chain side (Solana, Starknet, etc.) of the SDK externally by a separate wallet. Each function which executes any transaction has its txs(action) counterpart, e.g.:
1694
- - commit() -> txsCommit()
1695
- - claim() -> txsClaim()
1696
- - commitAndClaim -> txsCommitAndClaim()
1697
- - refund() -> txsRefund()
1698
-
1699
- After sending the transactions, you also need to make sure the SDK has enough time to receive an event notification of the transaction being executed, for this you have the waitTill(action) functions, e.g.:
1700
-
1701
- - commit() -> waitTillCommited()
1702
- - claim() -> waitTillClaimed()
1703
- - commitAndClaim -> waitTillClaimed()
1704
- - refund() -> waitTillRefunded()
1705
-
1706
- ```typescript
1707
- //Example for Solana
1708
- const txns = await swap.txsCommit(); //Also works with txsClaim, txsRefund, txCommitAndClaim
1709
- txns.forEach(val => if(val.signers.length>0) { val.tx.sign(...val.signers) });
1710
- const signedTransactions = await solanaSigner.wallet.signAllTransactions(txns.map(val => val.tx));
1711
- for(let tx of signedTransactions) {
1712
- const res = await solanaRpc.sendRawTransaction(tx.serialize());
1713
- await solanaRpc.confirmTransaction(res);
1714
- }
1715
- await swap.waitTillCommited(); //Or other relevant waitTillClaimed, waitTillRefunded
1716
-
1717
- //Example for Starknet
1718
- const txns = await swap.txsCommit(); //Also works with txsClaim, txsRefund, txCommitAndClaim
1719
- for(let tx of txns) {
1720
- if(tx.type==="INVOKE") await starknetSigner.account.execute(tx.tx, tx.details);
1721
- if(tx.type==="DEPLOY_ACCOUNT") await starknetSigner.account.deployAccount(tx.tx, tx.details);
1722
- }
1723
- await swap.waitTillCommited(); //Or other relevant waitTillClaimed, waitTillRefunded
1724
-
1725
- //Example for EVM
1726
- const txns = await swap.txsCommit(); //Also works with txsClaim, txsRefund, txCommitAndClaim
1727
- for(let tx of txns) {
1728
- await evmSigner.account.sendTransaction(tx);
1729
- }
1730
- await swap.waitTillCommited(); //Or other relevant waitTillClaimed, waitTillRefunded
1731
- ```
1732
-
1733
- ### Additional swapper options
1734
-
1735
- You can further customize the swapper instance with these options, you can:
1736
- - adjust the maximum accepted pricing difference from the LPs
1737
- - use custom mempool.space instance
1738
- - use custom pricing API
1739
- - use own LP node for swaps
1740
- - adjust HTTP request timeouts
1741
- - add parameters to be sent with each LP request
1742
-
1743
- ```typescript
1744
- const swapper = Factory.newSwapper({
1745
- ...
1746
- //Additional optional options
1747
- pricingFeeDifferencePPM: 20000n, //Maximum allowed pricing difference for quote (between swap & market price) in ppm (parts per million) (20000 == 2%)
1748
- mempoolApi: new MempoolApi("<url to custom mempool.space instance>"), //Set the SDK to use a custom mempool.space instance instead of the public one
1749
- getPriceFn: (tickers: string[], abortSignal?: AbortSignal) => customPricingApi.getUsdPriceForTickers(tickers) //Overrides the default pricing API engine with a custom price getter
1750
-
1751
- intermediaryUrl: "<url to custom LP node>",
1752
- registryUrl: "<url to custom LP node registry>",
1753
-
1754
- getRequestTimeout: 10000, //Timeout in milliseconds for GET requests
1755
- postRequestTimeout: 10000, //Timeout in milliseconds for POST requests
1756
- defaultAdditionalParameters: {lpData: "Pls give gud price"}, //Additional request data sent to LPs
1757
-
1758
- defaultTrustedIntermediaryUrl: "<url to custom LP node>" //LP node/intermediary to use for trusted gas swaps
1759
- });
1760
- ```
1
+ # atomiqlabs SDK
2
+
3
+ A typescript multichain client for atomiqlabs trustlesss cross-chain swaps. Enables trustless swaps between smart chains (Solana, EVM, Starknet, etc.) and bitcoin (on-chain - L1 and lightning network - L2).
4
+
5
+ Example SDK integration in NodeJS available [here](https://github.com/atomiqlabs/atomiq-sdk-demo)
6
+
7
+ ## Installation
8
+ ```
9
+ npm install @atomiqlabs/sdk@latest
10
+ ```
11
+
12
+ ## Installing chain-specific connectors
13
+
14
+ You can install only the chain-specific connectors that your project requires
15
+
16
+ ```
17
+ npm install @atomiqlabs/chain-solana@latest
18
+ npm install @atomiqlabs/chain-starknet@latest
19
+ npm install @atomiqlabs/chain-evm@latest
20
+ ```
21
+
22
+ ## How to use?
23
+
24
+ - [Preparations](#preparations)
25
+ - [Setting up signers](#signer)
26
+ - [Initialization](#initialization)
27
+ - Swaps:
28
+ - [Smart Chain -> BTC L1](#swap-smart-chain---bitcoin-on-chain)
29
+ - [BTC L1 -> Solana (Old swap protocol)](#swap-bitcoin-on-chain---solana)
30
+ - [BTC L1 -> Starknet/EVM (New swap protocol)](#swap-bitcoin-on-chain---starknetevm)
31
+ - [Smart Chain -> BTC Lightning network L2](#swap-smart-chain---bitcoin-lightning-network)
32
+ - [Smart Chain -> BTC Lightning network L2 (LNURL-pay)](#swap-smart-chain---bitcoin-lightning-network-1)
33
+ - [BTC Lightning network L2 -> Solana (Old swap protocol)](#swap-bitcoin-lightning-network---solana)
34
+ - [BTC Lightning network L2 -> Starknet/EVM (New swap protocol)](#swap-bitcoin-lightning-network---starknetevm)
35
+ - [BTC Lightning network L2 (LNURL-withdraw) -> Solana (Old swap protocol)](#swap-bitcoin-lightning-network---solana-1)
36
+ - [BTC Lightning network L2 (LNURL-withdraw) -> Starknet/EVM (New swap protocol)](#swap-bitcoin-lightning-network---starknetevm-1)
37
+ - [Swap states](#getting-state-of-the-swap)
38
+ - [Swap size limits](#swap-size-limits)
39
+ - [Stored swaps](#stored-swaps)
40
+ - [Get existing swaps](#get-swap-by-id)
41
+ - [Refundable swaps](#get-refundable-swaps)
42
+ - [Claimable swaps](#get-claimable-swaps)
43
+ - [Helpers](#helpers)
44
+ - [Wallet spendable balance](#getting-wallet-balances)
45
+ - [Unified address parsers](#unified-address-parser)
46
+ - [Customize swapper instance](#additional-swapper-options)
47
+
48
+ ### Preparations
49
+
50
+ Set Solana & Starknet RPC URL to use
51
+
52
+ ```typescript
53
+ const solanaRpc = "https://api.mainnet-beta.solana.com";
54
+ const starknetRpc = "https://rpc.starknet.lava.build/"; //Alternatively: https://starknet.api.onfinality.io/public or https://api.zan.top/public/starknet-mainnet
55
+ const citreaRpc = "https://rpc.mainnet.citrea.xyz";
56
+ ```
57
+
58
+ Create swapper factory, here we can pick and choose which chains we want to have supported in the SDK, ensure the "as const" keyword is used such that the typescript compiler can properly infer the types.
59
+
60
+ ```typescript
61
+ import {SolanaInitializer, SolanaInitializerType} from "@atomiqlabs/chain-solana";
62
+ import {StarknetInitializer, StarknetInitializerType} from "@atomiqlabs/chain-starknet";
63
+ import {CitreaInitializer, CitreaInitializerType} from "@atomiqlabs/chain-evm";
64
+ import {SwapperFactory, TypedTokens} from "@atomiqlabs/sdk";
65
+
66
+ //Define chains that you want to support here
67
+ const chains = [SolanaInitializer, StarknetInitializer, CitreaInitializer] as const;
68
+ type SupportedChains = typeof chains; //It's helpful that we also get the type of the chains array
69
+
70
+ const Factory = new SwapperFactory<SupportedChains>(chains); //Create swapper factory
71
+ const Tokens: TypedTokens<SupportedChains> = Factory.Tokens; //Get the supported tokens for all the specified chains.
72
+ ```
73
+
74
+ #### Browser
75
+
76
+ This uses browser's Indexed DB by default
77
+
78
+ ```typescript
79
+ import {BitcoinNetwork, TypedSwapper} from "@atomiqlabs/sdk";
80
+
81
+ const swapper: TypedSwapper<SupportedChains> = Factory.newSwapper({
82
+ chains: {
83
+ SOLANA: {
84
+ rpcUrl: solanaRpc //You can also pass Connection object here
85
+ },
86
+ STARKNET: {
87
+ rpcUrl: starknetRpc //You can also pass Provider object here
88
+ },
89
+ CITREA: {
90
+ rpcUrl: citreaRpc, //You can also pass JsonRpcApiProvider object here
91
+ }
92
+ },
93
+ bitcoinNetwork: BitcoinNetwork.MAINNET //or BitcoinNetwork.TESTNET3, BitcoinNetwork.TESTNET4 - this also sets the network to use for Solana (solana devnet for bitcoin testnet) & Starknet (sepolia for bitcoin testnet)
94
+ });
95
+ ```
96
+
97
+ if you want to use custom pricing api, mempool.space RPC url, or tune HTTP request timeouts check out [additional options](#additional-swapper-options)
98
+
99
+ #### NodeJS
100
+
101
+ For NodeJS we need to use sqlite storage, for that we first need to install the sqlite storage adaptor
102
+
103
+ ```
104
+ npm install @atomiqlabs/storage-sqlite@latest
105
+ ```
106
+
107
+ Then use pass it in the newSwapper function
108
+
109
+ ```typescript
110
+ import {SqliteStorageManager, SqliteUnifiedStorage} from "@atomiqlabs/storage-sqlite";
111
+ import {BitcoinNetwork, TypedSwapper} from "@atomiqlabs/sdk";
112
+
113
+ const swapper: TypedSwapper<SupportedChains> = Factory.newSwapper({
114
+ chains: {
115
+ SOLANA: {
116
+ rpcUrl: solanaRpc //You can also pass Connection object here
117
+ },
118
+ STARKNET: {
119
+ rpcUrl: starknetRpc //You can also pass Provider object here
120
+ },
121
+ CITREA: {
122
+ rpcUrl: citreaRpc, //You can also pass JsonApiProvider object here
123
+ }
124
+ },
125
+ bitcoinNetwork: BitcoinNetwork.MAINNET //or BitcoinNetwork.TESTNET3, BitcoinNetwork.TESTNET4 - this also sets the network to use for Solana (solana devnet for bitcoin testnet) & Starknet (sepolia for bitcoin testnet)
126
+ //The following lines are important for running on backend node.js,
127
+ // because the SDK by default uses browser's Indexed DB
128
+ swapStorage: chainId => new SqliteUnifiedStorage("CHAIN_"+chainId+".sqlite3"),
129
+ chainStorageCtor: name => new SqliteStorageManager("STORE_"+name+".sqlite3"),
130
+ });
131
+ ```
132
+
133
+ if you want to use custom pricing api, mempool.space RPC url, or tune HTTP request timeouts check out [additional options](#additional-swapper-options)
134
+
135
+ ### Signer
136
+
137
+ ```typescript
138
+ import {SolanaSigner} from "@atomiqlabs/chain-solana";
139
+ //Browser - react, using solana wallet adapter
140
+ const anchorWallet = useAnchorWallet();
141
+ const wallet = new SolanaSigner(anchorWallet);
142
+ ```
143
+
144
+ ```typescript
145
+ import {RpcProvider, WalletAccount} from "starknet";
146
+ import {StarknetBrowserSigner} from "@atomiqlabs/chain-starknet";
147
+ //Browser, using get-starknet
148
+ const swo = await connect();
149
+ const starknetProvider = new RpcProvider({nodeUrl: starknetRpc});
150
+ const wallet = new StarknetBrowserSigner(await WalletAccount.connect(starknetProvider, swo.wallet));
151
+ ```
152
+
153
+ or
154
+
155
+ ```typescript
156
+ import {Keypair} from "@solana/web3.js";
157
+ import {SolanaKeypairWallet, SolanaSigner} from "@atomiqlabs/chain-solana";
158
+ //Creating Solana signer from private key
159
+ const solanaSigner = new SolanaSigner(new SolanaKeypairWallet(Keypair.fromSecretKey(solanaKey)), Keypair.fromSecretKey(solanaKey));
160
+ ```
161
+
162
+ ```typescript
163
+ import {RpcProvider} from "starknet";
164
+ import {StarknetSigner, StarknetKeypairWallet} from "@atomiqlabs/chain-starknet";
165
+ //Creating Starknet signer from private key
166
+ const starknetProvider = new RpcProvider({nodeUrl: starknetRpc});
167
+ const starknetSigner = new StarknetSigner(new StarknetKeypairWallet(starknetProvider, starknetKey));
168
+ ```
169
+
170
+ ```typescript
171
+ import {BaseWallet, SigningKey} from "ethers";
172
+ import {EVMSigner} from "@atomiqlabs/chain-evm";
173
+ //Creating EVM signer from private key
174
+ const wallet = new BaseWallet(new SigningKey(evmKey));
175
+ const evmWallet = new EVMSigner(wallet, wallet.address);
176
+ ```
177
+
178
+ ### Initialization
179
+
180
+ Initialize the swapper, this should be done once when your app starts. Checks existing in-progress swaps and does initial LP discovery
181
+
182
+ ```typescript
183
+ await swapper.init();
184
+ ```
185
+
186
+ Now we have the multichain swapper initialized
187
+
188
+ ### Extract chain-specific swapper with signer
189
+
190
+ To make it easier to do swaps between bitcoin and a specific chain we can extract a chain-specific swapper, and also set a signer. e.g.:
191
+
192
+ ```typescript
193
+ const solanaSwapper = swapper.withChain<"SOLANA">("SOLANA");
194
+ ```
195
+
196
+ ### Bitcoin on-chain swaps
197
+
198
+ #### Swap Smart chain -> Bitcoin on-chain
199
+
200
+ Getting swap quote
201
+
202
+ ```typescript
203
+ //Create the swap: swapping SOL to Bitcoin on-chain, receiving _amount of satoshis (smallest unit of bitcoin) to _address
204
+ const swap: ToBTCSwap<SolanaChainType> = await swapper.swap(
205
+ Tokens.SOLANA.SOL, //From specified source token
206
+ Tokens.BITCOIN.BTC, //Swap to BTC
207
+ "0.0001", //Amount can be either passed in base units as bigint or in decimal format as string
208
+ SwapAmountType.EXACT_OUT, //EXACT_OUT, so we specify the output amount
209
+ solanaSigner.getAddress(), //Source address and smart chain signer
210
+ "bc1qtw67hj77rt8zrkkg3jgngutu0yfgt9czjwusxt" //BTC address of the recipient
211
+ );
212
+
213
+ //Get the amount required to pay and fee
214
+ const input: string = swap.getInputWithoutFee().toString(); //Input amount excluding fees
215
+ const fee: string = swap.getFee().amountInSrcToken.toString(); //Fees paid on the output
216
+ const inputWithFees: string = swap.getInput().toString(); //Total amount paid including fees
217
+
218
+ const output: string = swap.getOutput().toString(); //Total output amount
219
+
220
+ //Get swap expiration time
221
+ const expiry: number = swap.getQuoteExpiry(); //Expiration time of the swap quote in UNIX milliseconds, swap needs to be initiated before this time
222
+
223
+ //Get pricing info
224
+ const swapPrice = swap.getPriceInfo().swapPrice; //Price of the current swap (excluding fees)
225
+ const marketPrice = swap.getPriceInfo().marketPrice; //Current market price
226
+ const difference = swap.getPriceInfo().difference; //Difference between the swap price & current market price
227
+ ```
228
+
229
+ Executing the swap (simple)
230
+
231
+ ```typescript
232
+ const swapSuccessful = await swap.execute(
233
+ solanaSigner,
234
+ { //Callbacks
235
+ onSourceTransactionSent: (txId: string) => {
236
+ //Transaction on the source chain was sent
237
+ },
238
+ onSourceTransactionConfirmed: (txId: string) => {
239
+ //Transaction on the source chain was confirmed
240
+ },
241
+ onSwapSettled: (destinationTxId: string) => {
242
+ //Bitcoin transaction on the destination chain was sent and swap settled
243
+ }
244
+ }
245
+ );
246
+
247
+ //Refund in case of failure
248
+ if(!swapSuccessful) {
249
+ //Swap failed, money can be refunded
250
+ await swap.refund(solanaSigner);
251
+ } else {
252
+ //Swap successful!
253
+ }
254
+ ```
255
+
256
+ <details>
257
+ <summary>Manual swap execution (advanced)</summary>
258
+
259
+ - __1.__ Initiate the swap on the smart-chain side
260
+
261
+ - __a.__ Commit with a signer
262
+ ```typescript
263
+ await swap.commit(solanaSigner);
264
+ ```
265
+
266
+ - __b.__ Or get the transactions & [sign and send transaction manually](#manually-signing-smart-chain-transactions)
267
+ ```typescript
268
+ const txsCommit = await swap.txsCommit();
269
+ //Sign and send these...
270
+ ...
271
+ //Important to wait till SDK processes the swap initialization
272
+ await swap.waitTillCommited();
273
+ ```
274
+
275
+ - __2.__ Wait for the swap to execute and for the payment to be sent
276
+ ```typescript
277
+ const swapSuccessful = await swap.waitForPayment();
278
+ ```
279
+
280
+ - __3.__ In case the swap fails we can refund our funds on the source chain
281
+
282
+ - __a.__ Refund with a signer
283
+ ```typescript
284
+ if(!swapSuccessful) {
285
+ await swap.refund(solanaSigner);
286
+ return;
287
+ }
288
+ ```
289
+
290
+ - __b.__ Or get the transactions & [sign and send transaction manually](#manually-signing-smart-chain-transactions)
291
+ ```typescript
292
+ if(!swapSuccessful) {
293
+ const txsRefund = await swap.txsRefund();
294
+ //Sign and send these...
295
+ ...
296
+ }
297
+ ```
298
+
299
+ </details>
300
+
301
+ <details>
302
+ <summary>Swap states</summary>
303
+
304
+ - ToBTCSwapState.REFUNDED = -3
305
+ - Swap failed and was successfully refunded
306
+ - ToBTCSwapState.QUOTE_EXPIRED = -2
307
+ - Swap quote expired and cannot be executed anymore
308
+ - ToBTCSwapState.QUOTE_SOFT_EXPIRED = -1
309
+ - Swap quote soft-expired (i.e. the quote probably expired, but if there is already an initialization transaction sent it might still succeed)
310
+ - ToBTCSwapState.CREATED = 0
311
+ - Swap quote is created, waiting to be executed
312
+ - ToBTCSwapState.COMMITED = 1,
313
+ - Swap was initiated (init transaction sent)
314
+ - ToBTCSwapState.SOFT_CLAIMED = 2,
315
+ - Swap was processed by the counterparty but not yet claimed on-chain (bitcoin transaction was sent, but unconfirmed yet)
316
+ - ToBTCSwapState.CLAIMED = 3
317
+ - Swap was finished and funds were successfully claimed by the counterparty
318
+ - ToBTCSwapState.REFUNDABLE = 4
319
+ - Swap was initiated but counterparty failed to process it, the user can now refund his funds
320
+
321
+ </details>
322
+
323
+ #### Swap Bitcoin on-chain -> Solana
324
+
325
+ NOTE: Solana uses an old swap protocol for Bitcoin on-chain -> Solana swaps, the flow here is different from the one for Starknet and other chains.
326
+
327
+ Getting swap quote
328
+
329
+ ```typescript
330
+ //Create the swap: swapping _amount of satoshis of Bitcoin on-chain to SOL
331
+ const swap: FromBTCSwap<SolanaChainType> = await swapper.swap(
332
+ Tokens.BITCOIN.BTC, //Swap from BTC
333
+ Tokens.SOLANA.SOL, //Into specified destination token
334
+ "0.0001", //Amount can be either passed in base units as bigint or in decimal format as string
335
+ SwapAmountType.EXACT_IN, //EXACT_IN, so we specify the input amount
336
+ undefined, //Source address for the swap, not used for swaps from BTC
337
+ solanaSigner.getAddress() //Destination address
338
+ );
339
+
340
+ //Get the amount required to pay and fee
341
+ const input: string = swap.getInputWithoutFee().toString(); //Input amount excluding fees
342
+ const fee: string = swap.getFee().amountInSrcToken.toString(); //Fees paid on the output
343
+ const inputWithFees: string = swap.getInput().toString(); //Total amount paid including fees
344
+
345
+ const output: string = swap.getOutput().toString(); //Total output amount
346
+
347
+ //Get swap expiration time
348
+ const expiry: number = swap.getQuoteExpiry(); //Expiration time of the swap quote in UNIX milliseconds, swap needs to be initiated before this time
349
+
350
+ //Get security deposit amount (Human readable amount of SOL that needs to be put down to rent the liquidity from swap intermediary), you will get this deposit back if the swap succeeds
351
+ const securityDeposit: string = swap.getSecurityDeposit().toString();
352
+ //Get claimer bounty (Human readable amount of SOL reserved as a reward for watchtowers to claim the swap on your behalf)
353
+ const claimerBounty: string = swap.getClaimerBounty().toString();
354
+
355
+ //Get pricing info
356
+ const swapPrice = swap.getPriceInfo().swapPrice; //Price of the current swap (excluding fees)
357
+ const marketPrice = swap.getPriceInfo().marketPrice; //Current market price
358
+ const difference = swap.getPriceInfo().difference; //Difference between the swap price & current market price
359
+ ```
360
+
361
+ Executing the swap (simple)
362
+
363
+ ```typescript
364
+ const automaticSettlementSuccess = await swap.execute(
365
+ solanaSigner,
366
+ { //Bitcoin wallet, you can also pass null/undefined and send the bitcoin transaction from an external wallet
367
+ address: "bc1pscnrk588hdj79mwccucu06007mj5np2jurwfwp5mvhkjldzyphzqyk62m5",
368
+ publicKey: "03a2d8b728935f61d5bcba0cfb09c2c443c483b5c31ebd180e1833f37344bd34ba",
369
+ signPsbt: (psbt: {psbt, psbtHex: string, psbtBase64: string}, signInputs: number[]) => {
370
+ //Sign the PSBT with the bitcoin wallet
371
+ ...
372
+ //Return the signed PSBT in the hex or base64 format!
373
+ return "<signed PSBT>";
374
+ }
375
+ },
376
+ { //Callbacks
377
+ onDestinationCommitSent: (swapAddressOpeningTxId: string) => {
378
+ //Swap address opening transaction sent on the destination chain
379
+ },
380
+ onSourceTransactionSent: (txId: string) => {
381
+ //Bitcoin transaction sent on the source
382
+ },
383
+ onSourceTransactionConfirmationStatus: (txId: string, confirmations: number, targetConfirmations: number, txEtaMs: number) => {
384
+ //Bitcoin transaction confirmation status updates
385
+ },
386
+ onSourceTransactionConfirmed: (txId: string) => {
387
+ //Bitcoin transaction confirmed
388
+ },
389
+ onSwapSettled: (destinationTxId: string) => {
390
+ //Swap settled on the destination
391
+ }
392
+ }
393
+ );
394
+
395
+ //In case the automatic swap settlement fails, we can settle it manually using the wallet of the destination chain
396
+ if(!automaticSettlementSuccess) {
397
+ await swap.claim(solanaSigner);
398
+ }
399
+ ```
400
+
401
+ <details>
402
+ <summary>Manual swap execution (advanced)</summary>
403
+
404
+ - __1.__ Initiate the swap on the destination chain (Solana) by opening up the bitcoin swap address
405
+
406
+ - __a.__ Commit using signer
407
+ ```typescript
408
+ await swap.commit(solanaWallet);
409
+ ```
410
+
411
+ - __b.__ Or get the transactions & [sign and send transaction manually](#manually-signing-smart-chain-transactions)
412
+ ```typescript
413
+ const txsCommit = await swap.txsCommit();
414
+ //Sign and send these...
415
+ ...
416
+ //Important to wait till SDK processes the swap initialization
417
+ await swap.waitTillCommited();
418
+ ```
419
+
420
+ - __2.__ Send bitcoin transaction
421
+
422
+ - __a.__ Get funded PSBT and sign it
423
+ ```typescript
424
+ const {psbt, psbtHex, psbtBase64, signInputs} = await swap.getFundedPsbt({
425
+ address: "bc1pscnrk588hdj79mwccucu06007mj5np2jurwfwp5mvhkjldzyphzqyk62m5",
426
+ publicKey: "03a2d8b728935f61d5bcba0cfb09c2c443c483b5c31ebd180e1833f37344bd34ba"
427
+ });
428
+ //Sign the psbt
429
+ const signedPsbt = ...; //Can be hex or base64 encoded
430
+ const bitcoinTxId = await swap.submitPsbt(signedPsbt);
431
+ ```
432
+
433
+ - __b.__ Get the bitcoin address or deeplink and send from external wallet
434
+ ```typescript
435
+ //It is imporant to send the EXACT amount, sending different amount will lead to loss of funds!
436
+ const btcSwapAddress = swap.getAddress();
437
+ const btcDeepLink = swap.getHyperlink();
438
+ ```
439
+
440
+ - __3.__ Wait for the bitcoin on-chain transaction to confirm
441
+ ```typescript
442
+ await swap.waitForBitcoinTransaction(
443
+ (txId, confirmations, targetConfirmations, txEtaMs) => {
444
+ //Bitcoin transaction confirmation status callback
445
+ }
446
+ );
447
+ ```
448
+
449
+ - __4.__ Wait for the automatic settlement of the swap
450
+ ```typescript
451
+ const automaticSettlementSuccess = await swap.waitTillClaimed(30);
452
+ ```
453
+
454
+ - __5.__ In case the automatic swap settlement fails, we can settle it manually using the wallet of the destination chain
455
+
456
+ - __a.__ Claim with a signer
457
+ ```typescript
458
+ if(!automaticSettlementSuccess) {
459
+ await swap.claim(solanaSigner);
460
+ }
461
+ ```
462
+
463
+ - __b.__ Or get the transactions & [sign and send transaction manually](#manually-signing-smart-chain-transactions)
464
+ ```typescript
465
+ if(!automaticSettlementSuccess) {}
466
+ const txsClaim = await swap.txsClaim();
467
+ //Sign and send these...
468
+ ...
469
+ //Important to wait till SDK processes the swap initialization
470
+ await swap.waitTillCommited();
471
+ }
472
+ ```
473
+
474
+ </details>
475
+
476
+ <details>
477
+ <summary>Swap states</summary>
478
+
479
+ - FromBTCSwapState.EXPIRED = -3
480
+ - Bitcoin swap address expired
481
+ - FromBTCSwapState.QUOTE_EXPIRED = -2
482
+ - Swap quote expired and cannot be executed anymore
483
+ - FromBTCSwapState.QUOTE_SOFT_EXPIRED = -1
484
+ - Swap quote soft-expired (i.e. the quote probably expired, but if there is already an initialization transaction sent it might still succeed)
485
+ - FromBTCSwapState.PR_CREATED = 0
486
+ - Swap quote is created, waiting for the user to open a bitcoin swap address
487
+ - FromBTCSwapState.CLAIM_COMMITED = 1
488
+ - Bitcoin swap address is opened
489
+ - FromBTCSwapState.BTC_TX_CONFIRMED = 2
490
+ - Bitcoin transaction sending funds to the swap address is confirmed
491
+ - FromBTCSwapState.CLAIM_CLAIMED = 3
492
+ - Swap funds are claimed to the user's wallet
493
+
494
+ </details>
495
+
496
+ #### Swap Bitcoin on-chain -> Starknet/EVM
497
+
498
+ NOTE: Starknet & EVM uses a new swap protocol for Bitcoin on-chain -> Smart chain swaps, the flow here is different from the one for Solana!
499
+
500
+ Getting swap quote
501
+
502
+ ```typescript
503
+ //Create the swap: swapping _amount of satoshis of Bitcoin on-chain to SOL
504
+ const swap: SpvFromBTCSwap<StarknetChainType> = await swapper.swap(
505
+ Tokens.BITCOIN.BTC, //Swap from BTC
506
+ Tokens.STARKNET.STRK, //Into specified destination token
507
+ "0.0001", //Amount can be either passed in base units as bigint or in decimal format as string
508
+ SwapAmountType.EXACT_IN, //EXACT_IN, so we specify the input amount
509
+ undefined, //Source address for the swap, not used for swaps from BTC
510
+ starknetSigner.getAddress(), //Destination address
511
+ {
512
+ gasAmount: 1_000_000_000_000_000_000n //We can also request a gas drop on the destination chain (here requesting 1 STRK)
513
+ }
514
+ );
515
+
516
+ //Get the amount required to pay and fee
517
+ const input: string = swap.getInputWithoutFee().toString(); //Input amount excluding fees
518
+ const fee: string = swap.getFee().amountInSrcToken.toString(); //Fees paid on the output
519
+ const inputWithFees: string = swap.getInput().toString(); //Total amount paid including fees
520
+
521
+ const output: string = swap.getOutput().toString(); //Total output amount
522
+
523
+ //Get swap expiration time
524
+ const expiry: number = swap.getQuoteExpiry(); //Expiration time of the swap quote in UNIX milliseconds, swap needs to be initiated before this time
525
+
526
+ //Get pricing info
527
+ const swapPrice = swap.getPriceInfo().swapPrice; //Price of the current swap (excluding fees)
528
+ const marketPrice = swap.getPriceInfo().marketPrice; //Current market price
529
+ const difference = swap.getPriceInfo().difference; //Difference between the swap price & current market price
530
+ ```
531
+
532
+ Executing the swap (simple)
533
+
534
+ ```typescript
535
+ const automaticSettlementSuccess = await swap.execute(
536
+ { //Bitcoin wallet
537
+ address: "bc1pscnrk588hdj79mwccucu06007mj5np2jurwfwp5mvhkjldzyphzqyk62m5",
538
+ publicKey: "03a2d8b728935f61d5bcba0cfb09c2c443c483b5c31ebd180e1833f37344bd34ba",
539
+ signPsbt: (psbt: {psbt, psbtHex: string, psbtBase64: string}, signInputs: number[]) => {
540
+ //Sign the PSBT with the bitcoin wallet
541
+ ...
542
+ //Return the signed PSBT in the hex or base64 format!
543
+ return "<signed PSBT>";
544
+ }
545
+ },
546
+ { //Callbacks
547
+ onSourceTransactionSent: (txId: string) => {
548
+ //Bitcoin transaction sent on the source
549
+ },
550
+ onSourceTransactionConfirmationStatus: (txId: string, confirmations: number, targetConfirmations: number, txEtaMs: number) => {
551
+ //Bitcoin transaction confirmation status updates
552
+ },
553
+ onSourceTransactionConfirmed: (txId: string) => {
554
+ //Bitcoin transaction confirmed
555
+ },
556
+ onSwapSettled: (destinationTxId: string) => {
557
+ //Swap settled on the destination
558
+ }
559
+ }
560
+ );
561
+
562
+ //In case the automatic swap settlement fails, we can settle it manually using the wallet of the destination chain
563
+ if(!automaticSettlementSuccess) {
564
+ await swap.claim(starknetWallet);
565
+ }
566
+ ```
567
+
568
+
569
+ <details>
570
+ <summary>Manual swap execution (advanced)</summary>
571
+
572
+ - __1.__ Send bitcoin transaction
573
+
574
+ - __a.__ Get funded PSBT and sign it using external wallet (e.g. browser-based like Xverse, Unisat, Phantom, etc.)
575
+ ```typescript
576
+ //Obtain the funded PSBT (input already added) - ready for signing
577
+ const {psbt, psbtHex, psbtBase64, signInputs} = await swap.getFundedPsbt({address: "", publicKey: ""});
578
+ //Pass `psbtBase64` or `psbtHex` (and also `signInputs`) to an external signer like Xverse, Unisat, etc.
579
+ const signedPsbtHexOrBase64 = await <signPsbt function of the external wallet>; //Call the signPsbt function of the external signer with psbtBase64 or psbtHex and signInputs
580
+ //The SDK automatically recognizes hex & base64 encoded PSBTs
581
+ const bitcoinTxId = await swap.submitPsbt(signedPsbtHexOrBase64);
582
+ ```
583
+
584
+ - __b.__ Or obtain raw PSBT to which inputs still need to be added
585
+ ```typescript
586
+ const {psbt, psbtHex, psbtBase64, in1sequence} = await swap.getPsbt();
587
+ psbt.addInput(...);
588
+ //Make sure the second input's sequence (index 1) is as specified in the in1sequence variable
589
+ psbt.updateInput(1, {sequence: in1sequence});
590
+ //Sign the PSBT, sign every input except the first one
591
+ for(let i=1;i<psbt.inputsLength; i++) psbt.signIdx(..., i); //Or pass it to external signer
592
+ //Submit the signed PSBT, can be the Transaction object, or hex/base64 serialized
593
+ const bitcoinTxId = await swap.submitPsbt(psbt);
594
+ ```
595
+
596
+ - __2.__ Wait for the bitcoin on-chain transaction to confirm
597
+ ```typescript
598
+ await swap.waitForBitcoinTransaction(
599
+ (txId, confirmations, targetConfirmations, txEtaMs) => {
600
+ //Bitcoin transaction confirmation status callback
601
+ }
602
+ );
603
+ ```
604
+
605
+ - __3.__ Wait for the automatic settlement of the swap
606
+ ```typescript
607
+ const automaticSettlementSuccess = await swap.waitTillClaimed(60);
608
+ ```
609
+
610
+ - __4.__ In case the automatic swap settlement fails, we can settle it manually using the wallet of the destination chain
611
+
612
+ - __a.__ Claim with a signer
613
+ ```typescript
614
+ if(!automaticSettlementSuccess) {
615
+ await swap.claim(starknetSigner);
616
+ }
617
+ ```
618
+
619
+ - __b.__ Or get the transactions & [sign and send transaction manually](#manually-signing-smart-chain-transactions)
620
+ ```typescript
621
+ if(!automaticSettlementSuccess) {}
622
+ const txsClaim = await swap.txsClaim();
623
+ //Sign and send these...
624
+ ...
625
+ //Important to wait till SDK processes the swap initialization
626
+ await swap.waitTillCommited();
627
+ }
628
+ ```
629
+
630
+ </details>
631
+
632
+ <details>
633
+ <summary>Swap states</summary>
634
+
635
+ - SpvFromBTCSwapState.CLOSED = -5
636
+ - Catastrophic failure during swap, shall never happen
637
+ - SpvFromBTCSwapState.FAILED = -4
638
+ - Bitcoin transaction was sent, but was double-spent later, therefore the swap was failed (no BTC was sent)
639
+ - SpvFromBTCSwapState.DECLINED = -3
640
+ - LP declined to process the swap transaction, no BTC was sent
641
+ - SpvFromBTCSwapState.QUOTE_EXPIRED = -2
642
+ - Swap quote expired and cannot be executed anymore
643
+ - SpvFromBTCSwapState.QUOTE_SOFT_EXPIRED = -1
644
+ - Swap quote soft-expired (i.e. the quote probably expired, but if there is a bitcoin transaction being submitted it might still succeed)
645
+ - SpvFromBTCSwapState.CREATED = 0
646
+ - Swap quote is created, waiting on user to sign the bitcoin swap transaction
647
+ - SpvFromBTCSwapState.SIGNED = 1
648
+ - Bitcoin swap transaction was signed by the client
649
+ - SpvFromBTCSwapState.POSTED = 2
650
+ - Bitcoin swap transaction was posted to the LP
651
+ - SpvFromBTCSwapState.BROADCASTED = 3
652
+ - LP broadcasted the bitcoin swap transaction
653
+ - SpvFromBTCSwapState.FRONTED = 4
654
+ - Swap funds have been deposited to the user's wallet in front of the time
655
+ - SpvFromBTCSwapState.BTC_TX_CONFIRMED = 5
656
+ - Bitcoin swap transaction is confirmed
657
+ - SpvFromBTCSwapState.CLAIM_CLAIMED = 6
658
+ - Swap funds are claimed to the user's wallet
659
+ -
660
+ </details>
661
+
662
+ ### Bitcoin lightning network swaps
663
+
664
+ #### Swap Smart chain -> Bitcoin lightning network
665
+
666
+ Getting swap quote
667
+
668
+ ```typescript
669
+ //Create the swap: swapping SOL to Bitcoin lightning
670
+ const swap: ToBTCLNSwap<SolanaChainType> = await swapper.swap(
671
+ Tokens.SOLANA.SOL, //From specified source token
672
+ Tokens.BITCOIN.BTCLN, //Swap to BTC-LN
673
+ undefined, //Amount is specified in the lightning network invoice!
674
+ SwapAmountType.EXACT_OUT, //Make sure we use EXACT_OUT for swaps to BTC-LN, if you want to use EXACT_IN and set an amount, use LNURL-pay!
675
+ solanaSigner.getAddress(), //Source address and smart chain signer
676
+ //Destination lightning network invoice, amount needs to be part of the invoice!
677
+ "lnbc10u1pj2q0g9pp5ejs6m677m39cznpzum7muruvh50ys93ln82p4j9ks2luqm56xxlshp52r2anlhddfa9ex9vpw9gstxujff8a0p8s3pzvua930js0kwfea6scqzzsxqyz5vqsp5073zskc5qfgp7lre0t6s8uexxxey80ax564hsjklfwfjq2ew0ewq9qyyssqvzmgs6f8mvuwgfa9uqxhtza07qem4yfhn9wwlpskccmuwplsqmh8pdy6c42kqdu8p73kky9lsnl40qha5396d8lpgn90y27ltfc5rfqqq59cya"
678
+ );
679
+
680
+ //Get the amount required to pay and fee
681
+ const input: string = swap.getInputWithoutFee().toString(); //Input amount excluding fees
682
+ const fee: string = swap.getFee().amountInSrcToken.toString(); //Fees paid on the output
683
+ const inputWithFees: string = swap.getInput().toString(); //Total amount paid including fees
684
+
685
+ const output: string = swap.getOutput().toString(); //Total output amount
686
+
687
+ //Get swap expiration time
688
+ const expiry: number = swap.getQuoteExpiry(); //Expiration time of the swap quote in UNIX milliseconds, swap needs to be initiated before this time
689
+
690
+ //Get pricing info
691
+ const swapPrice = swap.getPriceInfo().swapPrice; //Price of the current swap (excluding fees)
692
+ const marketPrice = swap.getPriceInfo().marketPrice; //Current market price
693
+ const difference = swap.getPriceInfo().difference; //Difference between the swap price & current market price
694
+ ```
695
+
696
+ Executing the swap (simple)
697
+
698
+ ```typescript
699
+ const swapSuccessful = await swap.execute(
700
+ solanaSigner,
701
+ { //Callbacks
702
+ onSourceTransactionSent: (txId: string) => {
703
+ //Transaction on the source chain was sent
704
+ },
705
+ onSourceTransactionConfirmed: (txId: string) => {
706
+ //Transaction on the source chain was confirmed
707
+ },
708
+ onSwapSettled: (destinationTxId: string) => {
709
+ //Lightning payment on the destination chain was sent and swap settled
710
+ }
711
+ }
712
+ );
713
+
714
+ //Refund in case of failure
715
+ if(!swapSuccessful) {
716
+ //Swap failed, money can be refunded
717
+ await swap.refund(solanaSigner);
718
+ } else {
719
+ //Swap successful!
720
+ }
721
+ ```
722
+
723
+ <details>
724
+ <summary>Manual swap execution (advanced)</summary>
725
+
726
+ - __1.__ Initiate the swap on the smart-chain side
727
+
728
+ - __a.__ Commit with a signer
729
+ ```typescript
730
+ await swap.commit(solanaSigner);
731
+ ```
732
+
733
+ - __b.__ Or get the transactions & [sign and send transaction manually](#manually-signing-smart-chain-transactions)
734
+ ```typescript
735
+ const txsCommit = await swap.txsCommit();
736
+ //Sign and send these...
737
+ ...
738
+ //Important to wait till SDK processes the swap initialization
739
+ await swap.waitTillCommited();
740
+ ```
741
+
742
+ - __2.__ Wait for the swap to execute and for the payment to be sent
743
+ ```typescript
744
+ const swapSuccessful = await swap.waitForPayment();
745
+ ```
746
+
747
+ - __3.__ In case the swap fails we can refund our funds on the source chain
748
+
749
+ - __a.__ Refund with a signer
750
+ ```typescript
751
+ if(!swapSuccessful) {
752
+ await swap.refund(solanaSigner);
753
+ return;
754
+ }
755
+ ```
756
+
757
+ - __b.__ Or get the transactions & [sign and send transaction manually](#manually-signing-smart-chain-transactions)
758
+ ```typescript
759
+ if(!swapSuccessful) {
760
+ const txsRefund = await swap.txsRefund();
761
+ //Sign and send these...
762
+ ...
763
+ }
764
+ ```
765
+
766
+ </details>
767
+
768
+ <details>
769
+ <summary>Swap states</summary>
770
+
771
+ - ToBTCSwapState.REFUNDED = -3
772
+ - Swap failed and was successfully refunded
773
+ - ToBTCSwapState.QUOTE_EXPIRED = -2
774
+ - Swap quote expired and cannot be executed anymore
775
+ - ToBTCSwapState.QUOTE_SOFT_EXPIRED = -1
776
+ - Swap quote soft-expired (i.e. the quote probably expired, but if there is already an initialization transaction sent it might still succeed)
777
+ - ToBTCSwapState.CREATED = 0
778
+ - Swap quote is created, waiting to be executed
779
+ - ToBTCSwapState.COMMITED = 1,
780
+ - Swap was initiated (init transaction sent)
781
+ - ToBTCSwapState.SOFT_CLAIMED = 2,
782
+ - Swap was processed by the counterparty but not yet claimed on-chain (lightning network payment secret was revealed)
783
+ - ToBTCSwapState.CLAIMED = 3
784
+ - Swap was finished and funds were successfully claimed by the counterparty
785
+ - ToBTCSwapState.REFUNDABLE = 4
786
+ - Swap was initiated but counterparty failed to process it, the user can now refund his funds
787
+
788
+ </details>
789
+
790
+ #### Swap Bitcoin lightning network -> Solana
791
+
792
+ NOTE: Solana uses an old swap protocol for Bitcoin lightning network -> Solana swaps, the flow here is different from the one for Starknet and other chains.
793
+
794
+ Getting swap quote
795
+
796
+ ```typescript
797
+ const swap: FromBTCLNSwap<SolanaChainType> = await swapper.swap(
798
+ Tokens.BITCOIN.BTCLN, //Swap from BTC-LN
799
+ Tokens.SOLANA.SOL, //Into specified destination token
800
+ 10000n, //Amount can be either passed in base units as bigint or in decimal format as string
801
+ SwapAmountType.EXACT_IN, //SwapAmountType.EXACT_IN, so we specify the input amount
802
+ undefined, //Source address for the swap, not used for swaps from BTC-LN
803
+ signer.getAddress() //Destination address
804
+ );
805
+
806
+ //Get the bitcoin lightning network invoice (the invoice contains pre-entered amount)
807
+ const receivingLightningInvoice: string = swap.getAddress();
808
+ //Get the URI hyperlink (contains the lightning network invoice) which can be displayed also as QR code
809
+ const qrCodeData: string = swap.getHyperlink();
810
+
811
+ //Get the amount required to pay and fee
812
+ const input: string = swap.getInputWithoutFee().toString(); //Input amount excluding fees
813
+ const fee: string = swap.getFee().amountInSrcToken.toString(); //Fees paid on the output
814
+ const inputWithFees: string = swap.getInput().toString(); //Total amount paid including fees
815
+
816
+ const output: string = swap.getOutput().toString(); //Total output amount
817
+
818
+ //Get swap expiration time
819
+ const expiry: number = swap.getQuoteExpiry(); //Expiration time of the swap quote in UNIX milliseconds, swap needs to be initiated before this time
820
+
821
+ //Get security deposit amount (Human readable amount of STRK that needs to be put down to rent the liquidity from swap intermediary), you will get this deposit back if the swap succeeds
822
+ const securityDeposit: string = swap.getSecurityDeposit().toString();
823
+
824
+ //Get pricing info
825
+ const swapPrice = swap.getPriceInfo().swapPrice; //Price of the current swap (excluding fees)
826
+ const marketPrice = swap.getPriceInfo().marketPrice; //Current market price
827
+ const difference = swap.getPriceInfo().difference; //Difference between the swap price & current market price
828
+ ```
829
+
830
+ Executing the swap (simple)
831
+
832
+ ```typescript
833
+ await swap.execute(
834
+ solanaSigner,
835
+ { //Lightning network wallet, you can also pass null/undefined and pay the LN invoice from an external wallet
836
+ payInvoice: (bolt11PaymentRequest: string) => {
837
+ //Here you would usually call the WebLN or NWC to execute the payment, it's completely fine if the
838
+ // promise here would block till the payment is settled
839
+ return Promise.resolve("");
840
+ }
841
+ },
842
+ { //Callbacks
843
+ onSourceTransactionReceived: (sourceLnPaymentHash: string) => {
844
+ //Lightning network payment received by the LP
845
+ },
846
+ onDestinationCommitSent: (destinationCommitTxId: string) => {
847
+ //HTLC initialization transaction sent on the destination chain
848
+ },
849
+ onDestinationClaimSent: (destinationClaimTxId: string) => {
850
+ //HTLC claim transaction sent on the destination chain
851
+ },
852
+ onSwapSettled: (destinationClaimTxId: string) => {
853
+ //Swap settled and funds received on destination
854
+ }
855
+ }
856
+ );
857
+ ```
858
+
859
+ <details>
860
+ <summary>Manual swap execution (advanced)</summary>
861
+
862
+ - __1.__ Pay the LN invoice from a lightning network wallet
863
+ ```typescript
864
+ const lightningInvoice = swap.getAddress();
865
+ ```
866
+
867
+ - __2.__ Start listening to incoming lightning network payment
868
+ ```typescript
869
+ const success = await swap.waitForPayment();
870
+ if(!success) {
871
+ //Lightning network payment not received in time and quote expired
872
+ return;
873
+ }
874
+ ```
875
+
876
+ - __3.__ Claim the swap at the destination
877
+
878
+ - __a.__ Commit & claim with signer
879
+ ```typescript
880
+ await swap.commitAndClaim(solanaSigner);
881
+ ```
882
+
883
+ - __b.__ Or get the transactions & [sign and send transaction manually](#manually-signing-smart-chain-transactions)
884
+ ```typescript
885
+ const txsCommitAndClaim = await swap.txsCommitAndClaim();
886
+ //Take EXTRA care to make sure transaction are sent sequentially and in order - always wait
887
+ // for prior transaction confirmation before sending the next one
888
+ //Sign and send these...
889
+ ...
890
+ ```
891
+
892
+ </details>
893
+
894
+ <details>
895
+ <summary>Swap states</summary>
896
+
897
+ - FromBTCLNSwapState.FAILED = -4
898
+ - If the claiming of the funds was initiated, but never concluded, the user will get his lightning network payment refunded
899
+ - FromBTCLNSwapState.QUOTE_EXPIRED = -3
900
+ - Swap quote expired and cannot be executed anymore
901
+ - FromBTCLNSwapState.QUOTE_SOFT_EXPIRED = -2
902
+ - Swap quote soft-expired (i.e. the quote probably expired, but if there is already an initialization transaction sent it might still succeed)
903
+ - FromBTCLNSwapState.EXPIRED = -1
904
+ - Lightning network invoice expired, meaning the swap is expired
905
+ - FromBTCLNSwapState.PR_CREATED = 0
906
+ - Swap is created, the user should now pay the provided lightning network invoice
907
+ - FromBTCLNSwapState.PR_PAID = 1
908
+ - Lightning network invoice payment was received (but cannot be settled by the counterparty yet)
909
+ - FromBTCLNSwapState.CLAIM_COMMITED = 2
910
+ - Claiming of the funds was initiated
911
+ - FromBTCLNSwapState.CLAIM_CLAIMED = 3
912
+ - Funds were successfully claimed & lightning network secret pre-image revealed, so the lightning network payment will settle now
913
+
914
+ </details>
915
+
916
+ #### Swap Bitcoin lightning network -> Starknet/EVM
917
+
918
+ Getting swap quote
919
+
920
+ ```typescript
921
+ const swap: FromBTCLNAutoSwap<StarknetChainType> = await swapper.swap(
922
+ Tokens.BITCOIN.BTCLN, //Swap from BTC-LN
923
+ Tokens.STARKNET.STRK, //Into specified destination token
924
+ 10000n, //Amount can be either passed in base units as bigint or in decimal format as string
925
+ SwapAmountType.EXACT_IN, //SwapAmountType.EXACT_IN, so we specify the input amount
926
+ undefined, //Source address for the swap, not used for swaps from BTC-LN
927
+ signer.getAddress(), //Destination address
928
+ {
929
+ gasAmount: 1_000_000_000_000_000_000n //We can also request a gas drop on the destination chain (here requesting 1 STRK)
930
+ }
931
+ );
932
+
933
+ //Get the bitcoin lightning network invoice (the invoice contains pre-entered amount)
934
+ const receivingLightningInvoice: string = swap.getAddress();
935
+ //Get the URI hyperlink (contains the lightning network invoice) which can be displayed also as QR code
936
+ const qrCodeData: string = swap.getHyperlink();
937
+
938
+ //Get the amount required to pay and fee
939
+ const input: string = swap.getInputWithoutFee().toString(); //Input amount excluding fees
940
+ const fee: string = swap.getFee().amountInSrcToken.toString(); //Fees paid on the output
941
+ const inputWithFees: string = swap.getInput().toString(); //Total amount paid including fees
942
+
943
+ const output: string = swap.getOutput().toString(); //Total output amount
944
+
945
+ //Get swap expiration time
946
+ const expiry: number = swap.getQuoteExpiry(); //Expiration time of the swap quote in UNIX milliseconds, swap needs to be initiated before this time
947
+
948
+ //Get pricing info
949
+ const swapPrice = swap.getPriceInfo().swapPrice; //Price of the current swap (excluding fees)
950
+ const marketPrice = swap.getPriceInfo().marketPrice; //Current market price
951
+ const difference = swap.getPriceInfo().difference; //Difference between the swap price & current market price
952
+ ```
953
+
954
+ Executing the swap (simple)
955
+
956
+ ```typescript
957
+ const automaticSettlementSuccess = await swap.execute(
958
+ { //Lightning network wallet, you can also pass null/undefined and pay the LN invoice from an external wallet
959
+ payInvoice: (bolt11PaymentRequest: string) => {
960
+ //Here you would usually call the WebLN or NWC to execute the payment, it's completely fine if the
961
+ // promise here would block till the payment is settled
962
+ return Promise.resolve("");
963
+ }
964
+ },
965
+ { //Callbacks
966
+ onSourceTransactionReceived: (sourceLnPaymentHash: string) => {
967
+ //Lightning network payment received by the LP
968
+ },
969
+ onSwapSettled: (destinationClaimTxId: string) => {
970
+ //Swap settled and funds received on destination
971
+ }
972
+ }
973
+ );
974
+
975
+ //In case the automatic swap settlement fails, we can settle it manually using the wallet of the destination chain
976
+ if(!automaticSettlementSuccess) {
977
+ await swap.claim(starknetSigner);
978
+ }
979
+ ```
980
+
981
+
982
+ <details>
983
+ <summary>Manual swap execution (advanced)</summary>
984
+
985
+ - __1.__ Pay the LN invoice from a lightning network wallet
986
+ ```typescript
987
+ const lightningInvoice = swap.getAddress();
988
+ ```
989
+
990
+ - __2.__ Start listening to incoming lightning network payment
991
+ ```typescript
992
+ const success = await swap.waitForPayment();
993
+ if(!success) {
994
+ //Lightning network payment not received in time and quote expired
995
+ return;
996
+ }
997
+ ```
998
+
999
+ - __3.__ Wait for the swap to be automatically settled
1000
+ ```typescript
1001
+ const automaticSettlementSuccess = await swap.waitTillClaimed(60);
1002
+ ```
1003
+
1004
+ - __4.__ In case the automatic swap settlement fails, we can settle it manually using the wallet of the destination chain
1005
+
1006
+ - __a.__ Claim with signer
1007
+ ```typescript
1008
+ if(!automaticSettlementSuccess) {
1009
+ await swap.claim(starknetSigner);
1010
+ }
1011
+ ```
1012
+
1013
+ - __b.__ Or get the transactions & [sign and send transaction manually](#manually-signing-smart-chain-transactions)
1014
+ ```typescript
1015
+ if(!automaticSettlementSuccess) {
1016
+ const txsClaim = await swap.txsClaim();
1017
+ //Sign and send these...
1018
+ ...
1019
+ }
1020
+ ```
1021
+
1022
+ </details>
1023
+
1024
+ <details>
1025
+ <summary>Swap states</summary>
1026
+
1027
+ - FromBTCLNAutoSwapState.FAILED = -4
1028
+ - If the claiming of the funds was initiated, but never concluded, the user will get his lightning network payment refunded
1029
+ - FromBTCLNAutoSwapState.QUOTE_EXPIRED = -3
1030
+ - Swap quote expired and cannot be executed anymore
1031
+ - FromBTCLNAutoSwapState.QUOTE_SOFT_EXPIRED = -2
1032
+ - Swap quote soft-expired (i.e. the quote probably expired, but if there is already an initialization transaction sent it might still succeed)
1033
+ - FromBTCLNAutoSwapState.EXPIRED = -1
1034
+ - Lightning network invoice expired, meaning the swap is expired
1035
+ - FromBTCLNAutoSwapState.PR_CREATED = 0
1036
+ - Swap is created, the user should now pay the provided lightning network invoice
1037
+ - FromBTCLNAutoSwapState.PR_PAID = 1
1038
+ - Lightning network invoice payment was received (but cannot be settled by the counterparty yet)
1039
+ - FromBTCLNAutoSwapState.CLAIM_COMMITED = 2
1040
+ - A swap HTLC was offered by the LP to the user
1041
+ - FromBTCLNAutoSwapState.CLAIM_CLAIMED = 3
1042
+ - Funds were successfully claimed & lightning network secret pre-image revealed, so the lightning network payment will settle now
1043
+
1044
+ </details>
1045
+
1046
+ ### LNURLs & readable lightning identifiers
1047
+
1048
+ LNURLs extend the lightning network functionality by creating static lightning addreses (LNURL-pay & static internet identifiers) and QR codes which allow you to pull funds from them (LNURL-withdraw)
1049
+
1050
+ This SDK supports:
1051
+ * LNURL-pay ([LUD-6](https://github.com/lnurl/luds/blob/luds/06.md), [LUD-9](https://github.com/lnurl/luds/blob/luds/09.md), [LUD-10](https://github.com/lnurl/luds/blob/luds/10.md), [LUD-12](https://github.com/lnurl/luds/blob/luds/12.md))
1052
+ * LNURL-withdraw ([LUD-3](https://github.com/lnurl/luds/blob/luds/03.md))
1053
+ * Static internet identifiers ([LUD-16](https://github.com/lnurl/luds/blob/luds/16.md))
1054
+
1055
+ You can parse LNURLs and lightning invoices automatically using the [Unified address parser](#unified-address-parser)
1056
+
1057
+ #### Differences
1058
+
1059
+ Lightning invoices:
1060
+ * One time use only
1061
+ * Need to have a fixed amount, therefore recipient has to set the amount
1062
+ * Static and bounded expiration
1063
+ * You can only pay to a lightning invoice, not withdraw funds from it
1064
+
1065
+ LNURLs & lightning identifiers:
1066
+ * Reusable
1067
+ * Programmable expiry
1068
+ * Allows payer to set an amount
1069
+ * Supports both, paying (LNURL-pay) and withdrawing (LNURL-withdraw)
1070
+ * Possibility to attach a message/comment to a payment
1071
+ * Receive a message/url as a result of the payment
1072
+
1073
+ #### Swap Smart chain -> Bitcoin lightning network
1074
+
1075
+ Getting swap quote
1076
+
1077
+ ```typescript
1078
+ //Create the swap: swapping SOL to Bitcoin lightning
1079
+ const swap: ToBTCLNSwap<SolanaChainType> = await swapper.swap(
1080
+ Tokens.SOLANA.SOL, //From specified source token
1081
+ Tokens.BITCOIN.BTCLN, //Swap to BTC-LN
1082
+ 10000n, //Now we can specify an amount for a lightning network payment!
1083
+ SwapAmountType.EXACT_OUT, //We can also use exactIn=true here and set an amount in input token
1084
+ solanaSigner.getAddress(), //Source address and smart chain signer
1085
+ //Destination LNURL-pay or readable identifier
1086
+ "lnurl1dp68gurn8ghj7ampd3kx2ar0veekzar0wd5xjtnrdakj7tnhv4kxctttdehhwm30d3h82unvwqhkx6rfvdjx2ctvxyesuk0a27",
1087
+ {
1088
+ comment: "Hello world" //For LNURL-pay we can also pass a comment to the recipient
1089
+ }
1090
+ );
1091
+
1092
+ //Get the amount required to pay and fee
1093
+ const input: string = swap.getInputWithoutFee().toString(); //Input amount excluding fees
1094
+ const fee: string = swap.getFee().amountInSrcToken.toString(); //Fees paid on the output
1095
+ const inputWithFees: string = swap.getInput().toString(); //Total amount paid including fees
1096
+
1097
+ const output: string = swap.getOutput().toString(); //Total output amount
1098
+
1099
+ //Get swap expiration time
1100
+ const expiry: number = swap.getQuoteExpiry(); //Expiration time of the swap quote in UNIX milliseconds, swap needs to be initiated before this time
1101
+
1102
+ //Get pricing info
1103
+ const swapPrice = swap.getPriceInfo().swapPrice; //Price of the current swap (excluding fees)
1104
+ const marketPrice = swap.getPriceInfo().marketPrice; //Current market price
1105
+ const difference = swap.getPriceInfo().difference; //Difference between the swap price & current market price
1106
+ ```
1107
+
1108
+
1109
+ Executing the swap (simple)
1110
+
1111
+ ```typescript
1112
+ const swapSuccessful = await swap.execute(
1113
+ solanaSigner,
1114
+ { //Callbacks
1115
+ onSourceTransactionSent: (txId: string) => {
1116
+ //Transaction on the source chain was sent
1117
+ },
1118
+ onSourceTransactionConfirmed: (txId: string) => {
1119
+ //Transaction on the source chain was confirmed
1120
+ },
1121
+ onSwapSettled: (destinationTxId: string) => {
1122
+ //Lightning payment on the destination chain was sent and swap settled
1123
+ }
1124
+ }
1125
+ );
1126
+
1127
+ //Refund in case of failure
1128
+ if(!swapSuccessful) {
1129
+ //Swap failed, money can be refunded
1130
+ await swap.refund(solanaSigner);
1131
+ return;
1132
+ }
1133
+
1134
+ //Swap successful!
1135
+ const lightningSecret = swap.getSecret();
1136
+ //In case the LNURL contained a success action, we can read it now and display it to user
1137
+ if(swap.hasSuccessAction()) {
1138
+ //Contains a success action that should displayed to the user
1139
+ const successMessage = swap.getSuccessAction();
1140
+ const description: string = successMessage.description; //Description of the message
1141
+ const text: (string | null) = successMessage.text; //Main text of the message
1142
+ const url: (string | null) = successMessage.url; //URL link which should be displayed
1143
+ }
1144
+ ```
1145
+
1146
+ <details>
1147
+ <summary>Manual swap execution (advanced)</summary>
1148
+
1149
+ - __1.__ Initiate the swap on the smart-chain side
1150
+
1151
+ - __a.__ Commit with a signer
1152
+ ```typescript
1153
+ await swap.commit(solanaSigner);
1154
+ ```
1155
+
1156
+ - __b.__ Or get the transactions & [sign and send transaction manually](#manually-signing-smart-chain-transactions)
1157
+ ```typescript
1158
+ const txsCommit = await swap.txsCommit();
1159
+ //Sign and send these...
1160
+ ...
1161
+ //Important to wait till SDK processes the swap initialization
1162
+ await swap.waitTillCommited();
1163
+ ```
1164
+
1165
+ - __2.__ Wait for the swap to execute and for the payment to be sent
1166
+
1167
+ ```typescript
1168
+ const swapSuccessful = await swap.waitForPayment();
1169
+ ```
1170
+
1171
+ - __3.__ In case the swap fails we can refund our funds on the source chain
1172
+
1173
+ - __a.__ Refund with a signer
1174
+ ```typescript
1175
+ if(!swapSuccessful) {
1176
+ await swap.refund(solanaSigner);
1177
+ return;
1178
+ }
1179
+ ```
1180
+
1181
+ - __b.__ Or get the transactions & [sign and send transaction manually](#manually-signing-smart-chain-transactions)
1182
+ ```typescript
1183
+ if(!swapSuccessful) {
1184
+ const txsRefund = await swap.txsRefund();
1185
+ //Sign and send these...
1186
+ ...
1187
+ }
1188
+ ```
1189
+
1190
+ </details>
1191
+
1192
+ #### Swap Bitcoin lightning network -> Solana
1193
+
1194
+ NOTE: Solana uses an old swap protocol for Bitcoin lightning network -> Solana swaps, the flow here is different from the one for Starknet and other chains.
1195
+
1196
+ Getting swap quote
1197
+
1198
+ ```typescript
1199
+ const swap: FromBTCLNSwap<SolanaChainType> = await swapper.swap(
1200
+ Tokens.BITCOIN.BTCLN, //Swap from BTC-LN
1201
+ Tokens.SOLANA.SOL, //Into specified destination token
1202
+ 10000n,
1203
+ SwapAmountType.EXACT_IN, //EXACT_IN, so we specify the input amount
1204
+ //Source LNURL-withdraw link
1205
+ "lnurl1dp68gurn8ghj7ampd3kx2ar0veekzar0wd5xjtnrdakj7tnhv4kxctttdehhwm30d3h82unvwqhkx6rfvdjx2ctvxyesuk0a27",
1206
+ signer.getAddress(), //Destination address
1207
+ );
1208
+
1209
+ //Get the amount required to pay and fee
1210
+ const input: string = swap.getInputWithoutFee().toString(); //Input amount excluding fees
1211
+ const fee: string = swap.getFee().amountInSrcToken.toString(); //Fees paid on the output
1212
+ const inputWithFees: string = swap.getInput().toString(); //Total amount paid including fees
1213
+
1214
+ const output: string = swap.getOutput().toString(); //Total output amount
1215
+
1216
+ //Get swap expiration time
1217
+ const expiry: number = swap.getQuoteExpiry(); //Expiration time of the swap quote in UNIX milliseconds, swap needs to be initiated before this time
1218
+
1219
+ //Get security deposit amount (Human readable amount of STRK that needs to be put down to rent the liquidity from swap intermediary), you will get this deposit back if the swap succeeds
1220
+ const securityDeposit: string = swap.getSecurityDeposit().toString();
1221
+
1222
+ //Get pricing info
1223
+ const swapPrice = swap.getPriceInfo().swapPrice; //Price of the current swap (excluding fees)
1224
+ const marketPrice = swap.getPriceInfo().marketPrice; //Current market price
1225
+ const difference = swap.getPriceInfo().difference; //Difference between the swap price & current market price
1226
+ ```
1227
+
1228
+ Executing the swap (simple)
1229
+
1230
+ ```typescript
1231
+ await swap.execute(
1232
+ solanaSigner,
1233
+ undefined, //No need to specify a wallet, we are sourcing the fund from LNURL-withdraw link
1234
+ { //Callbacks
1235
+ onSourceTransactionReceived: (sourceLnPaymentHash: string) => {
1236
+ //Lightning network payment received by the LP
1237
+ },
1238
+ onDestinationCommitSent: (destinationCommitTxId: string) => {
1239
+ //HTLC initialization transaction sent on the destination chain
1240
+ },
1241
+ onDestinationClaimSent: (destinationClaimTxId: string) => {
1242
+ //HTLC claim transaction sent on the destination chain
1243
+ },
1244
+ onSwapSettled: (destinationClaimTxId: string) => {
1245
+ //Swap settled and funds received on destination
1246
+ }
1247
+ }
1248
+ );
1249
+ ```
1250
+
1251
+ <details>
1252
+ <summary>Manual swap execution (advanced)</summary>
1253
+
1254
+ - __1.__ Start listening to incoming lightning network payment (this also requests the payment from LNURL-withdraw service)
1255
+ ```typescript
1256
+ const success = await swap.waitForPayment();
1257
+ if(!success) {
1258
+ //Lightning network payment not received in time and quote expired
1259
+ return;
1260
+ }
1261
+ ```
1262
+
1263
+ - __2.__ Claim the swap at the destination
1264
+
1265
+ - __a.__ Commit & claim with signer
1266
+ ```typescript
1267
+ await swap.commitAndClaim(solanaSigner);
1268
+ ```
1269
+
1270
+ - __b.__ Or get the transactions & [sign and send transaction manually](#manually-signing-smart-chain-transactions)
1271
+ ```typescript
1272
+ const txsCommitAndClaim = await swap.txsCommitAndClaim();
1273
+ //Take EXTRA care to make sure transaction are sent sequentially and in order - always wait
1274
+ // for prior transaction confirmation before sending the next one
1275
+ //Sign and send these...
1276
+ ...
1277
+ ```
1278
+
1279
+ </details>
1280
+
1281
+ #### Swap Bitcoin lightning network -> Starknet/EVM
1282
+
1283
+ Getting swap quote
1284
+
1285
+ ```typescript
1286
+ const swap: FromBTCLNAutoSwap<StarknetChainType> = await swapper.swap(
1287
+ Tokens.BITCOIN.BTCLN, //Swap from BTC-LN
1288
+ Tokens.STARKNET.STRK, //Into specified destination token
1289
+ 10000n,
1290
+ SwapAmountType.EXACT_IN, //EXACT_IN, so we specify the input amount
1291
+ //Source LNURL-withdraw link
1292
+ "lnurl1dp68gurn8ghj7ampd3kx2ar0veekzar0wd5xjtnrdakj7tnhv4kxctttdehhwm30d3h82unvwqhkx6rfvdjx2ctvxyesuk0a27",
1293
+ signer.getAddress(), //Destination address
1294
+ {
1295
+ gasAmount: 1_000_000_000_000_000_000n //We can also request a gas drop on the destination chain (here requesting 1 STRK)
1296
+ }
1297
+ );
1298
+
1299
+ //Get the amount required to pay and fee
1300
+ const input: string = swap.getInputWithoutFee().toString(); //Input amount excluding fees
1301
+ const fee: string = swap.getFee().amountInSrcToken.toString(); //Fees paid on the output
1302
+ const inputWithFees: string = swap.getInput().toString(); //Total amount paid including fees
1303
+
1304
+ const output: string = swap.getOutput().toString(); //Total output amount
1305
+
1306
+ //Get swap expiration time
1307
+ const expiry: number = swap.getQuoteExpiry(); //Expiration time of the swap quote in UNIX milliseconds, swap needs to be initiated before this time
1308
+
1309
+ //Get pricing info
1310
+ const swapPrice = swap.getPriceInfo().swapPrice; //Price of the current swap (excluding fees)
1311
+ const marketPrice = swap.getPriceInfo().marketPrice; //Current market price
1312
+ const difference = swap.getPriceInfo().difference; //Difference between the swap price & current market price
1313
+ ```
1314
+
1315
+
1316
+ Executing the swap (simple)
1317
+
1318
+ ```typescript
1319
+ const automaticSettlementSuccess = await swap.execute(
1320
+ undefined, //No need to specify a wallet, we are sourcing the funds from LNURL-withdraw link
1321
+ { //Callbacks
1322
+ onSourceTransactionReceived: (sourceLnPaymentHash: string) => {
1323
+ //Lightning network payment received by the LP
1324
+ },
1325
+ onSwapSettled: (destinationClaimTxId: string) => {
1326
+ //Swap settled and funds received on destination
1327
+ }
1328
+ }
1329
+ );
1330
+
1331
+ //In case the automatic swap settlement fails, we can settle it manually using the wallet of the destination chain
1332
+ if(!automaticSettlementSuccess) {
1333
+ await swap.claim(starknetSigner);
1334
+ }
1335
+ ```
1336
+
1337
+
1338
+ <details>
1339
+ <summary>Manual swap execution (advanced)</summary>
1340
+
1341
+ - __1.__ Start listening to incoming lightning network payment (this also requests the payment from LNURL-withdraw service)
1342
+ ```typescript
1343
+ const success = await swap.waitForPayment();
1344
+ if(!success) {
1345
+ //Lightning network payment not received in time and quote expired
1346
+ return;
1347
+ }
1348
+ ```
1349
+
1350
+ - __2.__ Wait for the swap to be automatically settled
1351
+ ```typescript
1352
+ const automaticSettlementSuccess = await swap.waitTillClaimed(60);
1353
+ ```
1354
+
1355
+ - __3.__ In case the automatic swap settlement fails, we can settle it manually using the wallet of the destination chain
1356
+
1357
+ - __a.__ Claim with signer
1358
+ ```typescript
1359
+ if(!automaticSettlementSuccess) {
1360
+ await swap.claim(starknetSigner);
1361
+ }
1362
+ ```
1363
+
1364
+ - __b.__ Or get the transactions & [sign and send transaction manually](#manually-signing-smart-chain-transactions)
1365
+ ```typescript
1366
+ if(!automaticSettlementSuccess) {
1367
+ const txsClaim = await swap.txsClaim();
1368
+ //Sign and send these...
1369
+ ...
1370
+ }
1371
+ ```
1372
+
1373
+ </details>
1374
+
1375
+ ### Exact-In Smart Chain - Lightning swaps
1376
+
1377
+ The main limitation of regular lightning network swaps (Smart chains -> Lightning), is the fact that exactIn swaps are not possible (as invoices need to have a fixed amount). LNURL-pay links solve this issue, but are not supported by all the wallets. Therefore, the SDK exposes a hook/callback that can be implemented by lightning wallets directly, which request fixed amount invoices on-demand. This then makes exact input amount swaps possible. The way it works:
1378
+
1379
+ 1. SDK sends a request to the LP saying it wants to swap `x` USDC to BTC, with a dummy invoice (either 1 sat or as specified in the `minMsats` parameter - this is requested from the `getInvoice()` function) - this dummy invoice is used to estimate the routing fees by the LP (extra care must be taken for both invoices, dummy and the real one to have the same destination node public key & routing hints).
1380
+ 2. LP responds with the output amount of `y` BTC
1381
+ 3. SDK calls the provided `getInvoice()` callback to request the real invoice for the `y` amount of BTC (in satoshis)
1382
+ 4. SDK forwards the returned fixed amount (`y` BTC) lightning network invoice back to the LP to finish creating the quote
1383
+
1384
+ Getting swap quote
1385
+
1386
+ ```typescript
1387
+ //Create the swap: swapping SOL to Bitcoin lightning
1388
+ const swap: ToBTCLNSwap<SolanaChainType> = await swapper.swap(
1389
+ Tokens.SOLANA.SOL, //From specified source token
1390
+ Tokens.BITCOIN.BTCLN, //Swap to BTC-LN
1391
+ 1_000_000_000n, //We can specify an amount for a lightning network payment!
1392
+ SwapAmountType.EXACT_IN, //We can use exactIn=true here and set an amount in input token
1393
+ solanaSigner.getAddress(), //Source address and smart chain signer
1394
+ //Instead of the destination we pass a handler object
1395
+ {
1396
+ getInvoice: async (amountSats: number, abortSignal?: AbortSignal) => {
1397
+ //Generate invoice with fixed amountSats here!
1398
+ ...
1399
+ return invoice;
1400
+ },
1401
+ //Optionally you can also specify minimum and maximum in msats (millisatoshis, 1 sat = 1000 msats)
1402
+ minMsats: 1_000_000n,
1403
+ maxMsats: 1_000_000_000n
1404
+ },
1405
+ {
1406
+ comment: "Hello world" //For LNURL-pay we can also pass a comment to the recipient
1407
+ }
1408
+ );
1409
+
1410
+ //Get the amount required to pay and fee
1411
+ const input: string = swap.getInputWithoutFee().toString(); //Input amount excluding fees
1412
+ const fee: string = swap.getFee().amountInSrcToken.toString(); //Fees paid on the output
1413
+ const inputWithFees: string = swap.getInput().toString(); //Total amount paid including fees
1414
+
1415
+ const output: string = swap.getOutput().toString(); //Total output amount
1416
+
1417
+ //Get swap expiration time
1418
+ const expiry: number = swap.getQuoteExpiry(); //Expiration time of the swap quote in UNIX milliseconds, swap needs to be initiated before this time
1419
+
1420
+ //Get pricing info
1421
+ const swapPrice = swap.getPriceInfo().swapPrice; //Price of the current swap (excluding fees)
1422
+ const marketPrice = swap.getPriceInfo().marketPrice; //Current market price
1423
+ const difference = swap.getPriceInfo().difference; //Difference between the swap price & current market price
1424
+ ```
1425
+
1426
+
1427
+ Executing the swap (simple)
1428
+
1429
+ ```typescript
1430
+ const swapSuccessful = await swap.execute(
1431
+ solanaSigner,
1432
+ { //Callbacks
1433
+ onSourceTransactionSent: (txId: string) => {
1434
+ //Transaction on the source chain was sent
1435
+ },
1436
+ onSourceTransactionConfirmed: (txId: string) => {
1437
+ //Transaction on the source chain was confirmed
1438
+ },
1439
+ onSwapSettled: (destinationTxId: string) => {
1440
+ //Lightning payment on the destination chain was sent and swap settled
1441
+ }
1442
+ }
1443
+ );
1444
+
1445
+ //Refund in case of failure
1446
+ if(!swapSuccessful) {
1447
+ //Swap failed, money can be refunded
1448
+ await swap.refund(solanaSigner);
1449
+ return;
1450
+ }
1451
+
1452
+ //Swap successful!
1453
+ const lightningSecret = swap.getSecret();
1454
+ ```
1455
+
1456
+ <details>
1457
+ <summary>Manual swap execution (advanced)</summary>
1458
+
1459
+ - __1.__ Initiate the swap on the smart-chain side
1460
+
1461
+ - __a.__ Commit with a signer
1462
+ ```typescript
1463
+ await swap.commit(solanaSigner);
1464
+ ```
1465
+
1466
+ - __b.__ Or get the transactions & [sign and send transaction manually](#manually-signing-smart-chain-transactions)
1467
+ ```typescript
1468
+ const txsCommit = await swap.txsCommit();
1469
+ //Sign and send these...
1470
+ ...
1471
+ //Important to wait till SDK processes the swap initialization
1472
+ await swap.waitTillCommited();
1473
+ ```
1474
+
1475
+ - __2.__ Wait for the swap to execute and for the payment to be sent
1476
+
1477
+ ```typescript
1478
+ const swapSuccessful = await swap.waitForPayment();
1479
+ ```
1480
+
1481
+ - __3.__ In case the swap fails we can refund our funds on the source chain
1482
+
1483
+ - __a.__ Refund with a signer
1484
+ ```typescript
1485
+ if(!swapSuccessful) {
1486
+ await swap.refund(solanaSigner);
1487
+ return;
1488
+ }
1489
+ ```
1490
+
1491
+ - __b.__ Or get the transactions & [sign and send transaction manually](#manually-signing-smart-chain-transactions)
1492
+ ```typescript
1493
+ if(!swapSuccessful) {
1494
+ const txsRefund = await swap.txsRefund();
1495
+ //Sign and send these...
1496
+ ...
1497
+ }
1498
+ ```
1499
+
1500
+ </details>
1501
+
1502
+ ### Getting state of the swap
1503
+
1504
+ You can get the current state of the swap with:
1505
+
1506
+ ```typescript
1507
+ const state = swap.getState();
1508
+ ```
1509
+
1510
+ You can also set a listener to listen for swap state changes:
1511
+
1512
+ ```typescript
1513
+ swap.events.on("swapState", swap => {
1514
+ const newState = swap.getState();
1515
+ });
1516
+ ```
1517
+
1518
+ For the meaning of the states please refer to the "Swap state" section under each swap type.
1519
+
1520
+ ### Swap size limits
1521
+
1522
+ Swap sizes are limited by the LPs you are connected to, they are advertised in BTC terms by LPs during handshake
1523
+
1524
+ ```typescript
1525
+ const swapLimits = swapper.getSwapLimits(srcToken, dstToken);
1526
+ const inputMin = swapLimits.input.min;
1527
+ const inputMax = swapLimits.input.max;
1528
+ const outputMin = swapLimits.output.min;
1529
+ const outputMax = swapLimits.output.max;
1530
+ ```
1531
+
1532
+ NOTE: swap limits denominated in BTC are retrieved from the LPs during initial handshake, however limits in other tokens are only returned when getting a quote fails due to amount being too low or too high. For example if you want to get swap limits for the BTC -> SOL swap, the input limits will be immediately available, while the output limits will only get populated once a quote request fails due to amount being too low or high.
1533
+
1534
+ ```typescript
1535
+ let swapLimits = swapper.getSwapLimits(Tokens.BITCOIN.BTC, Tokens.SOLANA.SOL);
1536
+ let inputMin = swapLimits.input.min; //Immediately available
1537
+ let inputMax = swapLimits.input.max; //Immediately available
1538
+ let outputMin = swapLimits.output.min; //Not available from the get-go
1539
+ let outputMax = swapLimits.output.max; //Not available from the get-go
1540
+
1541
+ //You can also listen to swap limit changes (optional)
1542
+ swapper.on("swapLimitsChanged", () => {
1543
+ //New limits available with swapper.getSwapLimits(srcToken, dstToken)
1544
+ //Useful in e.g. a react application where you want to dynamically set min/max swappable amount
1545
+ })
1546
+
1547
+ //Try to swap really small amount of SOL with exactOut swap
1548
+ try {
1549
+ const swap = await swapper.swap(
1550
+ Tokens.BITCOIN.BTC, //Swap from BTC
1551
+ Tokens.SOLANA.SOL, //Into specified destination token
1552
+ 1n, //1 lamport = 0.000000001 SOL
1553
+ false, //Whether we define an input or output amount
1554
+ undefined, //Source address for the swap, not used for swaps from BTC
1555
+ solanaSigner.getAddress() //Destination address
1556
+ );
1557
+ } catch (e) {
1558
+ //Fails with OutOfBoundsError
1559
+ }
1560
+
1561
+ swapLimits = swapper.getSwapLimits(Tokens.BITCOIN.BTC, Tokens.SOLANA.SOL);
1562
+ inputMin = swapLimits.input.min; //Immediately available
1563
+ inputMax = swapLimits.input.max; //Immediately available
1564
+ outputMin = swapLimits.output.min; //Now available due to failed quote
1565
+ outputMax = swapLimits.output.max; //Now available due to failed quote
1566
+ ```
1567
+
1568
+ ### Stored swaps
1569
+
1570
+ #### Get swap by ID
1571
+
1572
+ You can retrieve a swap by it's id, you can get an ID of the swap with
1573
+
1574
+ ```typescript
1575
+ const swapId = swap.getId();
1576
+ ```
1577
+
1578
+ And then later retrieve it from the storage
1579
+
1580
+ ```typescript
1581
+ import {isSwapType} from "@atomiqlabs/sdk";
1582
+
1583
+ //Use this to obtain a correctly typed swap, returns `undefined` if the type of the
1584
+ // underlying swap is not as requested, `swapType` uses the SwapType enum
1585
+ const typedSwap = await swapper.getTypedSwapById(swapId, chainId, swapType);
1586
+
1587
+ //This returns just a base type `ISwap`, so you have to do typecasting yourself, useful
1588
+ // if you don't know which type of the swap to expect
1589
+ const swap = await swapper.getSwapById(swapId);
1590
+ //You can later narrow this down with the `isSwapType()` typeguard
1591
+ if(isSwapType(swap, swapType)) {
1592
+ //You now have a properly narrowed down type of the swap here
1593
+ }
1594
+ ```
1595
+
1596
+ #### Get refundable swaps
1597
+ You can refund the swaps in one of two cases:
1598
+ * In case intermediary is non-cooperative and goes offline, you can claim the funds from the swap contract back after some time.
1599
+ * In case intermediary tried to pay but was unsuccessful, so he sent you signed message with which you can refund now without waiting.
1600
+
1601
+ This call can be checked on every startup and periodically every few minutes.
1602
+ ```typescript
1603
+ //Get refundable swaps and refund them
1604
+ const refundableSolanaSwaps = await swapper.getRefundableSwaps("SOLANA", solanaSigner.getAddress());
1605
+ for(let swap of refundableSolanaSwaps) await swap.refund(solanaSigner);
1606
+ const refundableStarknetSwaps = await swapper.getRefundableSwaps("STARKNET", starknetSigner.getAddress());
1607
+ for(let swap of refundableStarknetSwaps) await swap.refund(starknetSigner);
1608
+ ```
1609
+
1610
+ #### Get claimable swaps
1611
+ Returns swaps that are ready to be claimed by the client, this can happen if client closes the application when a swap is in-progress and the swap is concluded while the client is offline.
1612
+
1613
+ ```typescript
1614
+ //Get the swaps
1615
+ const claimableSolanaSwaps = await swapper.getClaimableSwaps("SOLANA", solanaSigner.getAddress());
1616
+ //Claim all the claimable swaps
1617
+ for(let swap of claimableSolanaSwaps) {
1618
+ await swap.claim(solanaSigner);
1619
+ }
1620
+ //Get the swaps
1621
+ const claimableStarknetSwaps = await swapper.getClaimableSwaps("STARKNET", starknetSigner.getAddress());
1622
+ //Claim all the claimable swaps
1623
+ for(let swap of claimableStarknetSwaps) {
1624
+ await swap.claim(starknetSigner);
1625
+ }
1626
+ ```
1627
+
1628
+ ### Helpers
1629
+
1630
+ #### Getting wallet balances
1631
+
1632
+ The SDK also contains helper functions for getting the maximum spendable balance of wallets
1633
+
1634
+ ```typescript
1635
+ //Spendable balance of the starknet wallet address (discounting transaction fees)
1636
+ const strkBalance = await swapper.Utils.getSpendableBalance(starknetSigner, Tokens.STARKNET.STRK);
1637
+ //Spendable balance of the solana wallet address (discounting transaction fees)
1638
+ const solBalance = await swapper.Utils.getSpendableBalance(solanaSigner, Tokens.SOLANA.SOL);
1639
+ //Spendable balance of the bitcoin wallet - here we also need to specify the destination chain (as there are different swap protocols available with different on-chain footprints)
1640
+ const {balance: btcBalance, feeRate: btcFeeRate} = await swapper.Utils.getBitcoinSpendableBalance(bitcoinWalletAddress, "SOLANA");
1641
+ ```
1642
+
1643
+ #### Unified address parser
1644
+
1645
+ A common way for parsing all address formats supported by the SDK, automatically recognizes:
1646
+ - Bitcoin on-chain L1 address formats (p2pkh, p2wpkh, p2wsh, p2wsh, p2tr)
1647
+ - [BIP-21](https://en.bitcoin.it/wiki/BIP_0021) bitcoin payment URI
1648
+ - BOLT11 lightning network invoices
1649
+ - [LUD-6](https://github.com/lnurl/luds/blob/luds/06.md) LNURL-pay links
1650
+ - [LUD-3](https://github.com/lnurl/luds/blob/luds/03.md) LNURL-withdraw links
1651
+ - [LUD-16](https://github.com/lnurl/luds/blob/luds/16.md) Lightning static internet identifiers
1652
+ - Smart chain addresses (Solana, Starknet, etc.)
1653
+
1654
+ ```typescript
1655
+ const res = await swapper.Utils.parseAddress(address);
1656
+ switch(res.type) {
1657
+ case "BITCOIN":
1658
+ //Bitcoin on-chain L1 address or BIP-21 URI scheme with amount
1659
+ const btcAmount = res.amount;
1660
+ break;
1661
+ case "LIGHTNING":
1662
+ //BOLT11 lightning network invoice with pre-set amount
1663
+ const lnAmount = res.amount;
1664
+ break;
1665
+ case "LNURL":
1666
+ //LNURL payment or withdrawal link
1667
+ if(isLNURLWithdraw(res.lnurl)) {
1668
+ //LNURL-withdraw allowing withdrawals over the lightning network
1669
+ const lnurlWithdrawData: LNURLWithdraw = res.lnurl;
1670
+ const minWithdrawable = res.min; //Minimum payment amount
1671
+ const maxWithdrawable = res.max; //Maximum payment amount
1672
+ const fixedAmount = res.amount; //If res.min===res.max, an fixed amount is returned instead
1673
+ //Should show a UI allowing the user to choose an amount he wishes to withdraw
1674
+ }
1675
+ if(isLNURLPay(res.lnurl)) {
1676
+ //LNURL-pay or static lightning internet identifier allowing repeated payments over the lightning network
1677
+ const lnurlPayData: LNURLPay = res.lnurl;
1678
+ const minPayable = res.min; //Minimum payment amount
1679
+ const maxPayable = res.max; //Maximum payment amount
1680
+ const fixedAmount = res.amount; //If res.min===res.max, an fixed amount is returned instead
1681
+ const icon: (string | null) = res.lnurl.icon; //URL encoded icon that should be displayed on the UI
1682
+ const shortDescription: (string | null) = res.lnurl.shortDescription; //Short description of the payment
1683
+ const longDescription: (string | null) = res.lnurl.longDescription; //Long description of the payment
1684
+ const maxCommentLength: (number | 0) = res.lnurl.commentMaxLength; //Maximum allowed length of the payment message/comment (0 means no comment allowed)
1685
+ //Should show a UI displaying the icon, short description, long description, allowing the user to choose an amount he wishes to pay and possibly also a comment
1686
+ }
1687
+ break;
1688
+ default:
1689
+ //Addresses for smart chains
1690
+ break;
1691
+ }
1692
+ ```
1693
+
1694
+ ### Manually signing smart chain transactions
1695
+
1696
+ You can also sign the transactions on smart chain side (Solana, Starknet, etc.) of the SDK externally by a separate wallet. Each function which executes any transaction has its txs(action) counterpart, e.g.:
1697
+ - commit() -> txsCommit()
1698
+ - claim() -> txsClaim()
1699
+ - commitAndClaim -> txsCommitAndClaim()
1700
+ - refund() -> txsRefund()
1701
+
1702
+ After sending the transactions, you also need to make sure the SDK has enough time to receive an event notification of the transaction being executed, for this you have the waitTill(action) functions, e.g.:
1703
+
1704
+ - commit() -> waitTillCommited()
1705
+ - claim() -> waitTillClaimed()
1706
+ - commitAndClaim -> waitTillClaimed()
1707
+ - refund() -> waitTillRefunded()
1708
+
1709
+ ```typescript
1710
+ //Example for Solana
1711
+ const txns = await swap.txsCommit(); //Also works with txsClaim, txsRefund, txCommitAndClaim
1712
+ txns.forEach(val => if(val.signers.length>0) { val.tx.sign(...val.signers) });
1713
+ const signedTransactions = await solanaSigner.wallet.signAllTransactions(txns.map(val => val.tx));
1714
+ for(let tx of signedTransactions) {
1715
+ const res = await solanaRpc.sendRawTransaction(tx.serialize());
1716
+ await solanaRpc.confirmTransaction(res);
1717
+ }
1718
+ await swap.waitTillCommited(); //Or other relevant waitTillClaimed, waitTillRefunded
1719
+
1720
+ //Example for Starknet
1721
+ const txns = await swap.txsCommit(); //Also works with txsClaim, txsRefund, txCommitAndClaim
1722
+ for(let tx of txns) {
1723
+ if(tx.type==="INVOKE") await starknetSigner.account.execute(tx.tx, tx.details);
1724
+ if(tx.type==="DEPLOY_ACCOUNT") await starknetSigner.account.deployAccount(tx.tx, tx.details);
1725
+ }
1726
+ await swap.waitTillCommited(); //Or other relevant waitTillClaimed, waitTillRefunded
1727
+
1728
+ //Example for EVM
1729
+ const txns = await swap.txsCommit(); //Also works with txsClaim, txsRefund, txCommitAndClaim
1730
+ for(let tx of txns) {
1731
+ await evmSigner.account.sendTransaction(tx);
1732
+ }
1733
+ await swap.waitTillCommited(); //Or other relevant waitTillClaimed, waitTillRefunded
1734
+ ```
1735
+
1736
+ ### Additional swapper options
1737
+
1738
+ You can further customize the swapper instance with these options, you can:
1739
+ - adjust the maximum accepted pricing difference from the LPs
1740
+ - use custom mempool.space instance
1741
+ - use custom pricing API
1742
+ - use own LP node for swaps
1743
+ - adjust HTTP request timeouts
1744
+ - add parameters to be sent with each LP request
1745
+
1746
+ ```typescript
1747
+ const swapper = Factory.newSwapper({
1748
+ ...
1749
+ //Additional optional options
1750
+ pricingFeeDifferencePPM: 20000n, //Maximum allowed pricing difference for quote (between swap & market price) in ppm (parts per million) (20000 == 2%)
1751
+ mempoolApi: new MempoolApi("<url to custom mempool.space instance>"), //Set the SDK to use a custom mempool.space instance instead of the public one
1752
+ getPriceFn: (tickers: string[], abortSignal?: AbortSignal) => customPricingApi.getUsdPriceForTickers(tickers) //Overrides the default pricing API engine with a custom price getter
1753
+
1754
+ intermediaryUrl: "<url to custom LP node>",
1755
+ registryUrl: "<url to custom LP node registry>",
1756
+
1757
+ getRequestTimeout: 10000, //Timeout in milliseconds for GET requests
1758
+ postRequestTimeout: 10000, //Timeout in milliseconds for POST requests
1759
+ defaultAdditionalParameters: {lpData: "Pls give gud price"}, //Additional request data sent to LPs
1760
+
1761
+ defaultTrustedIntermediaryUrl: "<url to custom LP node>" //LP node/intermediary to use for trusted gas swaps
1762
+ });
1763
+ ```