@atomiqlabs/sdk 5.0.0-dev.7 → 6.0.1

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.
package/README.md CHANGED
@@ -6,7 +6,7 @@ Example SDK integration in NodeJS available [here](https://github.com/atomiqlabs
6
6
 
7
7
  ## Installation
8
8
  ```
9
- npm install @atomiqlabs/sdk@dev
9
+ npm install @atomiqlabs/sdk
10
10
  ```
11
11
 
12
12
  ## Installing chain-specific connectors
@@ -14,9 +14,8 @@ npm install @atomiqlabs/sdk@dev
14
14
  You can install only the chain-specific connectors that your project requires
15
15
 
16
16
  ```
17
- npm install @atomiqlabs/chain-solana@dev
18
- npm install @atomiqlabs/chain-starknet@dev
19
- npm install @atomiqlabs/chain-evm@dev
17
+ npm install @atomiqlabs/chain-solana
18
+ npm install @atomiqlabs/chain-starknet
20
19
  ```
21
20
 
22
21
  ## How to use?
@@ -27,13 +26,11 @@ npm install @atomiqlabs/chain-evm@dev
27
26
  - Swaps:
28
27
  - [Smart Chain -> BTC L1](#swap-smart-chain---bitcoin-on-chain)
29
28
  - [BTC L1 -> Solana (Old swap protocol)](#swap-bitcoin-on-chain---solana)
30
- - [BTC L1 -> Starknet/EVM (New swap protocol)](#swap-bitcoin-on-chain---starknetevm)
29
+ - [BTC L1 -> Starknet (New swap protocol)](#swap-bitcoin-on-chain---starknet)
31
30
  - [Smart Chain -> BTC Lightning network L2](#swap-smart-chain---bitcoin-lightning-network)
32
31
  - [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)
32
+ - [BTC Lightning network L2 -> Smart Chain](#swap-bitcoin-lightning-network---smart-chain)
33
+ - [BTC Lightning network L2 (LNURL-withdraw) -> Smart Chain](#swap-bitcoin-lightning-network---smart-chain-1)
37
34
  - [Swap states](#getting-state-of-the-swap)
38
35
  - [Swap size limits](#swap-size-limits)
39
36
  - [Stored swaps](#stored-swaps)
@@ -51,8 +48,7 @@ Set Solana & Starknet RPC URL to use
51
48
 
52
49
  ```typescript
53
50
  const solanaRpc = "https://api.mainnet-beta.solana.com";
54
- const starknetRpc = "https://starknet-mainnet.public.blastapi.io/rpc/v0_8";
55
- const citreaRpc = "https://rpc.testnet.citrea.xyz";
51
+ const starknetRpc = "https://starknet-mainnet.public.blastapi.io/rpc/v0_7";
56
52
  ```
57
53
 
58
54
  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.
@@ -60,10 +56,9 @@ Create swapper factory, here we can pick and choose which chains we want to have
60
56
  ```typescript
61
57
  import {SolanaInitializer, SolanaInitializerType} from "@atomiqlabs/chain-solana";
62
58
  import {StarknetInitializer, StarknetInitializerType} from "@atomiqlabs/chain-starknet";
63
- import {CitreaInitializer, CitreaInitializerType} from "@atomiqlabs/chain-evm";
64
59
  import {SwapperFactory} from "@atomiqlabs/sdk";
65
60
 
66
- const Factory = new SwapperFactory<[SolanaInitializerType, StarknetInitializerType, CitreaInitializerType]>([SolanaInitializer, StarknetInitializer, CitreaInitializer] as const);
61
+ const Factory = new SwapperFactory<[SolanaInitializerType, StarknetInitializerType]>([SolanaInitializer, StarknetInitializer] as const);
67
62
  const Tokens = Factory.Tokens; //Get the supported tokens for all the specified chains.
68
63
  ```
69
64
 
@@ -80,10 +75,7 @@ const swapper = Factory.newSwapper({
80
75
  rpcUrl: solanaRpc //You can also pass Connection object here
81
76
  },
82
77
  STARKNET: {
83
- rpcUrl: starknetRpc //You can also pass Provider object here
84
- },
85
- CITREA: {
86
- rpcUrl: citreaRpc, //You can also pass JsonApiProvider object here
78
+ rpcUrl: starknetRpc //You can also pass Provider object here
87
79
  }
88
80
  },
89
81
  bitcoinNetwork: BitcoinNetwork.TESTNET //or BitcoinNetwork.MAINNET, BitcoinNetwork.TESTNET4 - this also sets the network to use for Solana (solana devnet for bitcoin testnet) & Starknet (sepolia for bitcoin testnet)
@@ -113,9 +105,6 @@ const swapper = Factory.newSwapper({
113
105
  },
114
106
  STARKNET: {
115
107
  rpcUrl: starknetRpc //You can also pass Provider object here
116
- },
117
- CITREA: {
118
- rpcUrl: citreaRpc, //You can also pass JsonApiProvider object here
119
108
  }
120
109
  },
121
110
  bitcoinNetwork: BitcoinNetwork.TESTNET, //or BitcoinNetwork.MAINNET - this also sets the network to use for Solana (solana devnet for bitcoin testnet) & Starknet (sepolia for bitcoin testnet)
@@ -155,22 +144,14 @@ const solanaSigner = new SolanaSigner(new SolanaKeypairWallet(Keypair.fromSecret
155
144
  ```
156
145
 
157
146
  ```typescript
158
- import {StarknetSigner, StarknetKeypairWallet} from "@atomiqlabs/chain-starknet";
147
+ import {SolanaKeypairWallet, SolanaSigner} from "@atomiqlabs/chain-solana";
159
148
  //Creating Starknet signer from private key
160
149
  const starknetSigner = new StarknetSigner(new StarknetKeypairWallet(starknetRpc, starknetKey));
161
150
  ```
162
151
 
163
- ```typescript
164
- import {BaseWallet, SigningKey} from "ethers";
165
- import {EVMSigner} from "@atomiqlabs/chain-evm";
166
- //Creating EVM signer from private key
167
- const wallet = new BaseWallet(new SigningKey(evmKey));
168
- const evmWallet = new EVMSigner(wallet, wallet.address);
169
- ```
170
-
171
152
  ### Initialization
172
153
 
173
- Initialize the swapper, this should be done once when your app starts. Checks existing in-progress swaps and does initial LP discovery
154
+ Initialize the swapper
174
155
 
175
156
  ```typescript
176
157
  await swapper.init();
@@ -186,6 +167,12 @@ To make it easier to do swaps between bitcoin and a specific chain we can extrac
186
167
  const solanaSwapper = swapper.withChain<"SOLANA">("SOLANA");
187
168
  ```
188
169
 
170
+ or also with signer
171
+
172
+ ```typescript
173
+ const starknetSwapperWithSigner = swapper.withChain<"STARKNET">("STARKNET").withSigner(signer);
174
+ ```
175
+
189
176
  ### Bitcoin on-chain swaps
190
177
 
191
178
  #### Swap Smart chain -> Bitcoin on-chain
@@ -193,14 +180,18 @@ const solanaSwapper = swapper.withChain<"SOLANA">("SOLANA");
193
180
  Getting swap quote
194
181
 
195
182
  ```typescript
183
+ const _exactIn = false; //exactIn = false, so we specify the output amount
184
+ const _amount = 10000n; //Amount in BTC base units - sats (10000 sats = 0.0001 BTC)
185
+ const _address = "bc1qtw67hj77rt8zrkkg3jgngutu0yfgt9czjwusxt"; //BTC address of the recipient
186
+
196
187
  //Create the swap: swapping SOL to Bitcoin on-chain, receiving _amount of satoshis (smallest unit of bitcoin) to _address
197
188
  const swap = await swapper.swap(
198
189
  Tokens.SOLANA.SOL, //From specified source token
199
190
  Tokens.BITCOIN.BTC, //Swap to BTC
200
- "0.0001", //Amount can be either passed in base units as bigint or in decimal format as string
201
- SwapAmountType.EXACT_OUT, //EXACT_OUT, so we specify the output amount
191
+ _amount,
192
+ _exactIn,
202
193
  solanaSigner.getAddress(), //Source address and smart chain signer
203
- "bc1qtw67hj77rt8zrkkg3jgngutu0yfgt9czjwusxt" //BTC address of the recipient
194
+ _address //Destination of the swap
204
195
  );
205
196
 
206
197
  //Get the amount required to pay and fee
@@ -219,80 +210,30 @@ const marketPrice = swap.getPriceInfo().marketPrice; //Current market price
219
210
  const difference = swap.getPriceInfo().difference; //Difference between the swap price & current market price
220
211
  ```
221
212
 
222
- Executing the swap (simple)
213
+ Initiating the swap
223
214
 
224
215
  ```typescript
225
- const swapSuccessful = await swap.execute(
226
- solanaSigner,
227
- { //Callbacks
228
- onSourceTransactionSent: (txId: string) => {
229
- //Transaction on the source chain was sent
230
- },
231
- onSourceTransactionConfirmed: (txId: string) => {
232
- //Transaction on the source chain was confirmed
233
- },
234
- onSwapSettled: (destinationTxId: string) => {
235
- //Bitcoin transaction on the destination chain was sent and swap settled
236
- }
237
- }
238
- );
216
+ //Initiate and pay for the swap
217
+ await swap.commit(solanaSigner);
218
+ ```
219
+
220
+ or [sign and send transaction manually](#manually-signing-smart-chain-transactions)
239
221
 
240
- //Refund in case of failure
241
- if(!swapSuccessful) {
222
+ Wait for the swap to execute, refund in case of failure
223
+
224
+ ```typescript
225
+ //Wait for the swap to conclude
226
+ const result: boolean = await swap.waitForPayment();
227
+ if(!result) {
242
228
  //Swap failed, money can be refunded
243
- await swap.refund(solanaSigner);
229
+ await swap.refund();
244
230
  } else {
245
- //Swap successful!
231
+ //Swap successful, we can get the bitcoin txId
232
+ const bitcoinTxId = swap.getBitcoinTxId();
246
233
  }
247
234
  ```
248
235
 
249
- <details>
250
- <summary>Manual swap execution (advanced)</summary>
251
-
252
- - __1.__ Initiate the swap on the smart-chain side
253
-
254
- - __a.__ Commit with a signer
255
- ```typescript
256
- await swap.commit(solanaSigner);
257
- ```
258
-
259
- - __b.__ Or get the transactions & [sign and send transaction manually](#manually-signing-smart-chain-transactions)
260
- ```typescript
261
- const txsCommit = await swap.txsCommit();
262
- //Sign and send these...
263
- ...
264
- //Important to wait till SDK processes the swap initialization
265
- await swap.waitTillCommited();
266
- ```
267
-
268
- - __2.__ Wait for the swap to execute and for the payment to be sent
269
- ```typescript
270
- const swapSuccessful = await swap.waitForPayment();
271
- ```
272
-
273
- - __3.__ In case the swap fails we can refund our funds on the source chain
274
-
275
- - __a.__ Refund with a signer
276
- ```typescript
277
- if(!swapSuccessful) {
278
- await swap.refund(solanaSigner);
279
- return;
280
- }
281
- ```
282
-
283
- - __b.__ Or get the transactions & [sign and send transaction manually](#manually-signing-smart-chain-transactions)
284
- ```typescript
285
- if(!swapSuccessful) {
286
- const txsRefund = await swap.txsRefund();
287
- //Sign and send these...
288
- ...
289
- }
290
- ```
291
-
292
- </details>
293
-
294
- <details>
295
- <summary>Swap states</summary>
236
+ ##### Swap states
296
237
 
297
238
  - ToBTCSwapState.REFUNDED = -3
298
239
  - Swap failed and was successfully refunded
@@ -311,8 +252,6 @@ if(!swapSuccessful) {
311
252
  - ToBTCSwapState.REFUNDABLE = 4
312
253
  - Swap was initiated but counterparty failed to process it, the user can now refund his funds
313
254
 
314
- </details>
315
-
316
255
  #### Swap Bitcoin on-chain -> Solana
317
256
 
318
257
  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.
@@ -320,12 +259,15 @@ NOTE: Solana uses an old swap protocol for Bitcoin on-chain -> Solana swaps, the
320
259
  Getting swap quote
321
260
 
322
261
  ```typescript
262
+ const _exactIn = true; //exactIn = true, so we specify the input amount
263
+ const _amount = fromHumanReadableString("0.0001", Tokens.BITCOIN.BTC); //Amount in BTC base units - sats, we can also use a utility function here
264
+
323
265
  //Create the swap: swapping _amount of satoshis of Bitcoin on-chain to SOL
324
266
  const swap = await swapper.swap(
325
267
  Tokens.BITCOIN.BTC, //Swap from BTC
326
268
  Tokens.SOLANA.SOL, //Into specified destination token
327
- "0.0001", //Amount can be either passed in base units as bigint or in decimal format as string
328
- SwapAmountType.EXACT_IN, //EXACT_IN, so we specify the input amount
269
+ _amount,
270
+ _exactIn, //Whether we define an input or output amount
329
271
  undefined, //Source address for the swap, not used for swaps from BTC
330
272
  solanaSigner.getAddress() //Destination address
331
273
  );
@@ -351,123 +293,67 @@ const marketPrice = swap.getPriceInfo().marketPrice; //Current market price
351
293
  const difference = swap.getPriceInfo().difference; //Difference between the swap price & current market price
352
294
  ```
353
295
 
354
- Executing the swap (simple)
296
+ Initiating the swap
355
297
 
356
298
  ```typescript
357
- const automaticSettlementSuccess = await swap.execute(
358
- solanaSigner,
359
- { //Bitcoin wallet, you can also pass null/undefined and send the bitcoin transaction from an external wallet
360
- address: "bc1pscnrk588hdj79mwccucu06007mj5np2jurwfwp5mvhkjldzyphzqyk62m5",
361
- publicKey: "03a2d8b728935f61d5bcba0cfb09c2c443c483b5c31ebd180e1833f37344bd34ba",
362
- signPsbt: (psbt: {psbt, psbtHex: string, psbtBase64: string}, signInputs: number[]) => {
363
- //Sign the PSBT with the bitcoin wallet
364
- ...
365
- //Return the signed PSBT in the hex or base64 format!
366
- return "<signed PSBT>";
367
- }
368
- },
369
- { //Callbacks
370
- onDestinationCommitSent: (swapAddressOpeningTxId: string) => {
371
- //Swap address opening transaction sent on the destination chain
372
- },
373
- onSourceTransactionSent: (txId: string) => {
374
- //Bitcoin transaction sent on the source
375
- },
376
- onSourceTransactionConfirmationStatus: (txId: string, confirmations: number, targetConfirmations: number, txEtaMs: number) => {
377
- //Bitcoin transaction confirmation status updates
378
- },
379
- onSourceTransactionConfirmed: (txId: string) => {
380
- //Bitcoin transaction confirmed
381
- },
382
- onSwapSettled: (destinationTxId: string) => {
383
- //Swap settled on the destination
384
- }
385
- }
386
- );
299
+ //Initiate the swap on the destination chain (Solana) by opening up the bitcoin swap address
300
+ await swap.commit(solanaSigner);
301
+ ```
387
302
 
388
- //In case the automatic swap settlement fails, we can settle it manually using the wallet of the destination chain
389
- if(!automaticSettlementSuccess) {
390
- await swap.claim(solanaSigner);
303
+ or [sign and send transaction manually](#manually-signing-smart-chain-transactions)
304
+
305
+ Sending bitcoin
306
+
307
+ ```typescript
308
+ //Get the bitcoin address
309
+ const receivingAddressOnBitcoin = swap.getAddress();
310
+ //Get the QR code data (contains the address and amount)
311
+ const qrCodeData = swap.getHyperlink(); //Data that can be displayed in the form of QR code
312
+ //Send the exact amount of BTC to the provided address
313
+ ```
314
+
315
+ or get a psbt and sign it
316
+
317
+ ```typescript
318
+ //Or obtain the funded PSBT (input already added) - ready for signing
319
+ const {psbt, signInputs} = await swap.getFundedPsbt({address: "", publicKey: ""});
320
+ for(let signIdx of signInputs) {
321
+ psbt.signIdx(..., signIdx); //Or pass it to external signer
391
322
  }
323
+ const bitcoinTxId = await swap.submitPsbt(psbt);
392
324
  ```
393
325
 
394
- <details>
395
- <summary>Manual swap execution (advanced)</summary>
396
-
397
- - __1.__ Initiate the swap on the destination chain (Solana) by opening up the bitcoin swap address
398
-
399
- - __a.__ Commit using signer
400
- ```typescript
401
- await swap.commit(solanaWallet);
402
- ```
403
-
404
- - __b.__ Or get the transactions & [sign and send transaction manually](#manually-signing-smart-chain-transactions)
405
- ```typescript
406
- const txsCommit = await swap.txsCommit();
407
- //Sign and send these...
408
- ...
409
- //Important to wait till SDK processes the swap initialization
410
- await swap.waitTillCommited();
411
- ```
412
-
413
- - __2.__ Send bitcoin transaction
414
-
415
- - __a.__ Get funded PSBT and sign it
416
- ```typescript
417
- const {psbt, psbtHex, psbtBase64, signInputs} = await swap.getFundedPsbt({
418
- address: "bc1pscnrk588hdj79mwccucu06007mj5np2jurwfwp5mvhkjldzyphzqyk62m5",
419
- publicKey: "03a2d8b728935f61d5bcba0cfb09c2c443c483b5c31ebd180e1833f37344bd34ba"
420
- });
421
- //Sign the psbt
422
- const signedPsbt = ...; //Can be hex or base64 encoded
423
- const bitcoinTxId = await swap.submitPsbt(signedPsbt);
424
- ```
425
-
426
- - __b.__ Get the bitcoin address or deeplink and send from external wallet
427
- ```typescript
428
- //It is imporant to send the EXACT amount, sending different amount will lead to loss of funds!
429
- const btcSwapAddress = swap.getAddress();
430
- const btcDeepLink = swap.getHyperlink();
431
- ```
432
-
433
- - __3.__ Wait for the bitcoin on-chain transaction to confirm
434
- ```typescript
435
- await swap.waitForBitcoinTransaction(
436
- (txId, confirmations, targetConfirmations, txEtaMs) => {
437
- //Bitcoin transaction confirmation status callback
438
- }
439
- );
440
- ```
441
-
442
- - __4.__ Wait for the automatic settlement of the swap
443
- ```typescript
444
- const automaticSettlementSuccess = await swap.waitTillClaimed(30);
445
- ```
446
-
447
- - __5.__ In case the automatic swap settlement fails, we can settle it manually using the wallet of the destination chain
448
-
449
- - __a.__ Claim with a signer
450
- ```typescript
451
- if(!automaticSettlementSuccess) {
452
- await swap.claim(solanaSigner);
453
- }
454
- ```
455
-
456
- - __b.__ Or get the transactions & [sign and send transaction manually](#manually-signing-smart-chain-transactions)
457
- ```typescript
458
- if(!automaticSettlementSuccess) {}
459
- const txsClaim = await swap.txsClaim();
460
- //Sign and send these...
461
- ...
462
- //Important to wait till SDK processes the swap initialization
463
- await swap.waitTillCommited();
464
- }
465
- ```
326
+ Waiting for swap execution
466
327
 
467
- </details>
328
+ ```typescript
329
+ try {
330
+ //Wait for the payment to arrive
331
+ await swap.waitForBitcoinTransaction(
332
+ null, null,
333
+ (
334
+ txId: string, //Transaction ID of the received bitcoin transaction
335
+ confirmations: number, //Current confirmations of the transaction
336
+ targetConfirmations: number, //Required confirmations
337
+ transactionETAms: number //Estimated in time (in milliseconds) until when the transaction will receive required amount of confirmations
338
+ ) => {
339
+ //Callback for transaction updates
340
+ }
341
+ );
342
+ } catch(e) {
343
+ //Error occurred while waiting for payment, this is most likely due to network errors
344
+ return;
345
+ }
346
+
347
+ //Swap should get automatically claimed by the watchtowers, if not we can call swap.claim() ourselves
348
+ try {
349
+ await swap.waitTillClaimed(timeoutSignal(30*1000));
350
+ } catch (e) {
351
+ //Claim ourselves when automatic claim doesn't happen in 30 seconds
352
+ await swap.claim(solanaSigner);
353
+ }
354
+ ```
468
355
 
469
- <details>
470
- <summary>Swap states</summary>
356
+ ##### Swap states
471
357
 
472
358
  - FromBTCSwapState.EXPIRED = -3
473
359
  - Bitcoin swap address expired
@@ -484,21 +370,23 @@ if(!automaticSettlementSuccess) {
484
370
  - FromBTCSwapState.CLAIM_CLAIMED = 3
485
371
  - Swap funds are claimed to the user's wallet
486
372
 
487
- </details>
488
373
 
489
- #### Swap Bitcoin on-chain -> Starknet/EVM
374
+ #### Swap Bitcoin on-chain -> Starknet
490
375
 
491
- 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!
376
+ NOTE: Starknet uses a new swap protocol for Bitcoin on-chain -> Solana swaps, the flow here is different from the one for Solana!
492
377
 
493
378
  Getting swap quote
494
379
 
495
380
  ```typescript
381
+ const _exactIn = true; //exactIn = true, so we specify the input amount
382
+ const _amount = fromHumanReadableString("0.0001", Tokens.BITCOIN.BTC); //Amount in BTC base units - sats, we can also use a utility function here
383
+
496
384
  //Create the swap: swapping _amount of satoshis of Bitcoin on-chain to SOL
497
385
  const swap = await swapper.swap(
498
386
  Tokens.BITCOIN.BTC, //Swap from BTC
499
387
  Tokens.STARKNET.STRK, //Into specified destination token
500
- "0.0001", //Amount can be either passed in base units as bigint or in decimal format as string
501
- SwapAmountType.EXACT_IN, //EXACT_IN, so we specify the input amount
388
+ _amount,
389
+ _exactIn, //Whether we define an input or output amount
502
390
  undefined, //Source address for the swap, not used for swaps from BTC
503
391
  starknetSigner.getAddress(), //Destination address
504
392
  {
@@ -522,109 +410,62 @@ const marketPrice = swap.getPriceInfo().marketPrice; //Current market price
522
410
  const difference = swap.getPriceInfo().difference; //Difference between the swap price & current market price
523
411
  ```
524
412
 
525
- Executing the swap (simple)
413
+ Initiating the swap
526
414
 
527
415
  ```typescript
528
- const automaticSettlementSuccess = await swap.execute(
529
- { //Bitcoin wallet
530
- address: "bc1pscnrk588hdj79mwccucu06007mj5np2jurwfwp5mvhkjldzyphzqyk62m5",
531
- publicKey: "03a2d8b728935f61d5bcba0cfb09c2c443c483b5c31ebd180e1833f37344bd34ba",
532
- signPsbt: (psbt: {psbt, psbtHex: string, psbtBase64: string}, signInputs: number[]) => {
533
- //Sign the PSBT with the bitcoin wallet
534
- ...
535
- //Return the signed PSBT in the hex or base64 format!
536
- return "<signed PSBT>";
537
- }
538
- },
539
- { //Callbacks
540
- onSourceTransactionSent: (txId: string) => {
541
- //Bitcoin transaction sent on the source
542
- },
543
- onSourceTransactionConfirmationStatus: (txId: string, confirmations: number, targetConfirmations: number, txEtaMs: number) => {
544
- //Bitcoin transaction confirmation status updates
545
- },
546
- onSourceTransactionConfirmed: (txId: string) => {
547
- //Bitcoin transaction confirmed
548
- },
549
- onSwapSettled: (destinationTxId: string) => {
550
- //Swap settled on the destination
551
- }
552
- }
553
- );
554
-
555
- //In case the automatic swap settlement fails, we can settle it manually using the wallet of the destination chain
556
- if(!automaticSettlementSuccess) {
557
- await swap.claim(starknetWallet);
416
+ //Obtain the funded PSBT (input already added) - ready for signing
417
+ const {psbt, signInputs} = await swap.getFundedPsbt({address: "", publicKey: ""});
418
+ for(let signIdx of signInputs) {
419
+ psbt.signIdx(..., signIdx); //Or pass it to external signer
558
420
  }
421
+ const bitcoinTxId = await swap.submitPsbt(psbt);
559
422
  ```
560
423
 
424
+ or get raw PSBT and add inputs manually
561
425
 
562
- <details>
563
- <summary>Manual swap execution (advanced)</summary>
564
-
565
- - __1.__ Send bitcoin transaction
566
-
567
- - __a.__ Get funded PSBT and sign it
568
- ```typescript
569
- const {psbt, psbtHex, psbtBase64, signInputs} = await swap.getFundedPsbt({
570
- address: "bc1pscnrk588hdj79mwccucu06007mj5np2jurwfwp5mvhkjldzyphzqyk62m5",
571
- publicKey: "03a2d8b728935f61d5bcba0cfb09c2c443c483b5c31ebd180e1833f37344bd34ba"
572
- });
573
- //Sign the psbt
574
- const signedPsbt = ...; //Can be hex or base64 encoded
575
- const bitcoinTxId = await swap.submitPsbt(signedPsbt);
576
- ```
577
-
578
- - __b.__ Or obtain raw PSBT to which inputs still need to be added
579
- ```typescript
580
- const {psbt, psbtHex, psbtBase64, in1sequence} = await swap.getPsbt();
581
- psbt.addInput(...);
582
- //Make sure the second input's sequence (index 1) is as specified in the in1sequence variable
583
- psbt.updateInput(1, {sequence: in1sequence});
584
- //Sign the PSBT, sign every input except the first one
585
- for(let i=1;i<psbt.inputsLength; i++) psbt.signIdx(..., i); //Or pass it to external signer
586
- //Submit the signed PSBT, can be the Transaction object, or hex/base64 serialized
587
- const bitcoinTxId = await swap.submitPsbt(psbt);
588
- ```
589
-
590
- - __2.__ Wait for the bitcoin on-chain transaction to confirm
591
- ```typescript
592
- await swap.waitForBitcoinTransaction(
593
- (txId, confirmations, targetConfirmations, txEtaMs) => {
594
- //Bitcoin transaction confirmation status callback
595
- }
596
- );
597
- ```
598
-
599
- - __3.__ Wait for the automatic settlement of the swap
600
- ```typescript
601
- const automaticSettlementSuccess = await swap.waitTillClaimed(60);
602
- ```
603
-
604
- - __4.__ In case the automatic swap settlement fails, we can settle it manually using the wallet of the destination chain
605
-
606
- - __a.__ Claim with a signer
607
- ```typescript
608
- if(!automaticSettlementSuccess) {
609
- await swap.claim(starknetSigner);
610
- }
611
- ```
612
-
613
- - __b.__ Or get the transactions & [sign and send transaction manually](#manually-signing-smart-chain-transactions)
614
- ```typescript
615
- if(!automaticSettlementSuccess) {}
616
- const txsClaim = await swap.txsClaim();
617
- //Sign and send these...
618
- ...
619
- //Important to wait till SDK processes the swap initialization
620
- await swap.waitTillCommited();
621
- }
622
- ```
426
+ ```typescript
427
+ //Or obtain raw PSBT to which inputs still need to be added
428
+ const {psbt, in1sequence} = await swap.getPsbt();
429
+ psbt.addInput(...);
430
+ //Make sure the second input's sequence (index 1) is as specified in the in1sequence variable
431
+ psbt.updateInput(1, {sequence: in1sequence});
432
+ //Sign the PSBT, sign every input except the first one
433
+ for(let i=1;i<psbt.inputsLength; i++) psbt.signIdx(..., i); //Or pass it to external signer
434
+ //Submit the signed PSBT
435
+ const bitcoinTxId = await swap.submitPsbt(psbt);
436
+ ```
623
437
 
624
- </details>
438
+ Waiting for swap execution
625
439
 
626
- <details>
627
- <summary>Swap states</summary>
440
+ ```typescript
441
+ try {
442
+ //Wait for the payment to arrive
443
+ await swap.waitForBitcoinTransaction(
444
+ null, null,
445
+ (
446
+ txId: string, //Transaction ID of the received bitcoin transaction
447
+ confirmations: number, //Current confirmations of the transaction
448
+ targetConfirmations: number, //Required confirmations
449
+ transactionETAms: number //Estimated in time (in milliseconds) until when the transaction will receive required amount of confirmations
450
+ ) => {
451
+ //Callback for transaction updates
452
+ }
453
+ );
454
+ } catch(e) {
455
+ //Error occurred while waiting for payment, this is most likely due to network errors
456
+ return;
457
+ }
458
+
459
+ //Swap should get automatically claimed by the watchtowers, if not we can call swap.claim() ourselves
460
+ try {
461
+ await swap.waitTillClaimedOrFronted(timeoutSignal(30*1000));
462
+ } catch (e) {
463
+ //Claim ourselves when automatic claim doesn't happen in 30 seconds
464
+ await swap.claim(starknetSigner);
465
+ }
466
+ ```
467
+
468
+ ##### Swap states
628
469
 
629
470
  - SpvFromBTCSwapState.CLOSED = -5
630
471
  - Catastrophic failure during swap, shall never happen
@@ -650,8 +491,6 @@ if(!automaticSettlementSuccess) {
650
491
  - Bitcoin swap transaction is confirmed
651
492
  - SpvFromBTCSwapState.CLAIM_CLAIMED = 6
652
493
  - Swap funds are claimed to the user's wallet
653
- -
654
- </details>
655
494
 
656
495
  ### Bitcoin lightning network swaps
657
496
 
@@ -660,15 +499,17 @@ if(!automaticSettlementSuccess) {
660
499
  Getting swap quote
661
500
 
662
501
  ```typescript
502
+ //Destination lightning network invoice, amount needs to be part of the invoice!
503
+ const _lightningInvoice = "lnbc10u1pj2q0g9pp5ejs6m677m39cznpzum7muruvh50ys93ln82p4j9ks2luqm56xxlshp52r2anlhddfa9ex9vpw9gstxujff8a0p8s3pzvua930js0kwfea6scqzzsxqyz5vqsp5073zskc5qfgp7lre0t6s8uexxxey80ax564hsjklfwfjq2ew0ewq9qyyssqvzmgs6f8mvuwgfa9uqxhtza07qem4yfhn9wwlpskccmuwplsqmh8pdy6c42kqdu8p73kky9lsnl40qha5396d8lpgn90y27ltfc5rfqqq59cya";
504
+
663
505
  //Create the swap: swapping SOL to Bitcoin lightning
664
506
  const swap = await swapper.swap(
665
507
  Tokens.SOLANA.SOL, //From specified source token
666
508
  Tokens.BITCOIN.BTCLN, //Swap to BTC-LN
667
509
  undefined, //Amount is specified in the lightning network invoice!
668
- 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!
510
+ false, //Make sure we use exactIn=false for swaps to BTC-LN, if you want to use exactIn=true and set an amount, use LNURL-pay!
669
511
  solanaSigner.getAddress(), //Source address and smart chain signer
670
- //Destination lightning network invoice, amount needs to be part of the invoice!
671
- "lnbc10u1pj2q0g9pp5ejs6m677m39cznpzum7muruvh50ys93ln82p4j9ks2luqm56xxlshp52r2anlhddfa9ex9vpw9gstxujff8a0p8s3pzvua930js0kwfea6scqzzsxqyz5vqsp5073zskc5qfgp7lre0t6s8uexxxey80ax564hsjklfwfjq2ew0ewq9qyyssqvzmgs6f8mvuwgfa9uqxhtza07qem4yfhn9wwlpskccmuwplsqmh8pdy6c42kqdu8p73kky9lsnl40qha5396d8lpgn90y27ltfc5rfqqq59cya"
512
+ _lightningInvoice //Destination of the swap
672
513
  );
673
514
 
674
515
  //Get the amount required to pay and fee
@@ -687,80 +528,30 @@ const marketPrice = swap.getPriceInfo().marketPrice; //Current market price
687
528
  const difference = swap.getPriceInfo().difference; //Difference between the swap price & current market price
688
529
  ```
689
530
 
690
- Executing the swap (simple)
531
+ Initiating the swap
691
532
 
692
533
  ```typescript
693
- const swapSuccessful = await swap.execute(
694
- solanaSigner,
695
- { //Callbacks
696
- onSourceTransactionSent: (txId: string) => {
697
- //Transaction on the source chain was sent
698
- },
699
- onSourceTransactionConfirmed: (txId: string) => {
700
- //Transaction on the source chain was confirmed
701
- },
702
- onSwapSettled: (destinationTxId: string) => {
703
- //Lightning payment on the destination chain was sent and swap settled
704
- }
705
- }
706
- );
534
+ //Initiate and pay for the swap
535
+ await swap.commit(solanaSigner);
536
+ ```
707
537
 
708
- //Refund in case of failure
709
- if(!swapSuccessful) {
710
- //Swap failed, money can be refunded
711
- await swap.refund(solanaSigner);
538
+ or [sign and send transaction manually](#manually-signing-smart-chain-transactions)
539
+
540
+ Wait for the swap to execute, refund in case of failure
541
+
542
+ ```typescript
543
+ //Wait for the swap to conclude
544
+ const result: boolean = await swap.waitForPayment();
545
+ if(!result) {
546
+ //Swap failed, money can be refunded
547
+ await swap.refund(solanaSigner);
712
548
  } else {
713
- //Swap successful!
549
+ //Swap successful, we can get the lightning payment secret pre-image, which acts as a proof of payment
550
+ const lightningSecret = swap.getSecret();
714
551
  }
715
552
  ```
716
553
 
717
- <details>
718
- <summary>Manual swap execution (advanced)</summary>
719
-
720
- - __1.__ Initiate the swap on the smart-chain side
721
-
722
- - __a.__ Commit with a signer
723
- ```typescript
724
- await swap.commit(solanaSigner);
725
- ```
726
-
727
- - __b.__ Or get the transactions & [sign and send transaction manually](#manually-signing-smart-chain-transactions)
728
- ```typescript
729
- const txsCommit = await swap.txsCommit();
730
- //Sign and send these...
731
- ...
732
- //Important to wait till SDK processes the swap initialization
733
- await swap.waitTillCommited();
734
- ```
735
-
736
- - __2.__ Wait for the swap to execute and for the payment to be sent
737
- ```typescript
738
- const swapSuccessful = await swap.waitForPayment();
739
- ```
740
-
741
- - __3.__ In case the swap fails we can refund our funds on the source chain
742
-
743
- - __a.__ Refund with a signer
744
- ```typescript
745
- if(!swapSuccessful) {
746
- await swap.refund(solanaSigner);
747
- return;
748
- }
749
- ```
750
-
751
- - __b.__ Or get the transactions & [sign and send transaction manually](#manually-signing-smart-chain-transactions)
752
- ```typescript
753
- if(!swapSuccessful) {
754
- const txsRefund = await swap.txsRefund();
755
- //Sign and send these...
756
- ...
757
- }
758
- ```
759
-
760
- </details>
761
-
762
- <details>
763
- <summary>Swap states</summary>
554
+ ##### Swap states
764
555
 
765
556
  - ToBTCSwapState.REFUNDED = -3
766
557
  - Swap failed and was successfully refunded
@@ -779,20 +570,19 @@ if(!swapSuccessful) {
779
570
  - ToBTCSwapState.REFUNDABLE = 4
780
571
  - Swap was initiated but counterparty failed to process it, the user can now refund his funds
781
572
 
782
- </details>
783
-
784
- #### Swap Bitcoin lightning network -> Solana
785
-
786
- 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.
573
+ #### Swap Bitcoin lightning network -> Smart chain
787
574
 
788
575
  Getting swap quote
789
576
 
790
577
  ```typescript
578
+ const _exactIn = true; //exactIn = true, so we specify the input amount
579
+ const _amount = 10000n; //Amount in BTC base units - sats
580
+
791
581
  const swap = await swapper.swap(
792
582
  Tokens.BITCOIN.BTCLN, //Swap from BTC-LN
793
- Tokens.SOLANA.SOL, //Into specified destination token
794
- 10000n, //Amount can be either passed in base units as bigint or in decimal format as string
795
- SwapAmountType.EXACT_IN, //SwapAmountType.EXACT_IN, so we specify the input amount
583
+ Tokens.STARKNET.STRK, //Into specified destination token
584
+ _amount,
585
+ _exactIn, //Whether we define an input or output amount
796
586
  undefined, //Source address for the swap, not used for swaps from BTC-LN
797
587
  signer.getAddress() //Destination address
798
588
  );
@@ -821,72 +611,40 @@ const marketPrice = swap.getPriceInfo().marketPrice; //Current market price
821
611
  const difference = swap.getPriceInfo().difference; //Difference between the swap price & current market price
822
612
  ```
823
613
 
824
- Executing the swap (simple)
614
+ Pay the displayed lightning network invoice from an external wallet
615
+
616
+ Wait for the payment to be received
825
617
 
826
618
  ```typescript
827
- await swap.execute(
828
- solanaSigner,
829
- { //Lightning network wallet, you can also pass null/undefined and pay the LN invoice from an external wallet
830
- payInvoice: (bolt11PaymentRequest: string) => {
831
- //Here you would usually call the WebLN or NWC to execute the payment, it's completely fine if the
832
- // promise here would block till the payment is settled
833
- return Promise.resolve("");
834
- }
835
- },
836
- { //Callbacks
837
- onSourceTransactionReceived: (sourceLnPaymentHash: string) => {
838
- //Lightning network payment received by the LP
839
- },
840
- onDestinationCommitSent: (destinationCommitTxId: string) => {
841
- //HTLC initialization transaction sent on the destination chain
842
- },
843
- onDestinationClaimSent: (destinationClaimTxId: string) => {
844
- //HTLC claim transaction sent on the destination chain
845
- },
846
- onSwapSettled: (destinationClaimTxId: string) => {
847
- //Swap settled and funds received on destination
848
- }
849
- }
850
- );
619
+ //Start listening to incoming lightning network payment
620
+ const success = await swap.waitForPayment();
621
+ if(!success) {
622
+ //Lightning network payment not received in time and quote expired!
623
+ return;
624
+ }
851
625
  ```
852
626
 
853
- <details>
854
- <summary>Manual swap execution (advanced)</summary>
855
-
856
- - __1.__ Pay the LN invoice from a lightning network wallet
857
- ```typescript
858
- const lightningInvoice = swap.getAddress();
859
- ```
860
-
861
- - __2.__ Start listening to incoming lightning network payment
862
- ```typescript
863
- const success = await swap.waitForPayment();
864
- if(!success) {
865
- //Lightning network payment not received in time and quote expired
866
- return;
867
- }
868
- ```
869
-
870
- - __3.__ Claim the swap at the destination
871
-
872
- - __a.__ Commit & claim with signer
873
- ```typescript
874
- await swap.commitAndClaim(solanaSigner);
875
- ```
627
+ Claim the funds on the destination smart chains, this settles the swap and lightning network payment
876
628
 
877
- - __b.__ Or get the transactions & [sign and send transaction manually](#manually-signing-smart-chain-transactions)
878
- ```typescript
879
- const txsCommitAndClaim = await swap.txsCommitAndClaim();
880
- //Take EXTRA care to make sure transaction are sent sequentially and in order - always wait
881
- // for prior transaction confirmation before sending the next one
882
- //Sign and send these...
883
- ...
884
- ```
629
+ ```typescript
630
+ try {
631
+ //Claim the swap funds - this will initiate 2 transactions
632
+ if(swap.canCommitAndClaimInOneShot()) {
633
+ //Some chains (e.g. Solana) support signing multiple transactions in one flow
634
+ await swap.commitAndClaim(solanaSigner);
635
+ } else {
636
+ //Other chains (e.g. Starknet) don't support signing multiple transaction in one flow, therefore you need to sign one-by-one
637
+ await swap.commit(starknetSigner);
638
+ await swap.claim(starknetSigner);
639
+ }
640
+ } catch(e) {
641
+ //Error occurred while waiting for payment
642
+ }
643
+ ```
885
644
 
886
- </details>
645
+ or [sign and send transactions manually](#manually-signing-smart-chain-transactions)
887
646
 
888
- <details>
889
- <summary>Swap states</summary>
647
+ ##### Swap states
890
648
 
891
649
  - FromBTCLNSwapState.FAILED = -4
892
650
  - If the claiming of the funds was initiated, but never concluded, the user will get his lightning network payment refunded
@@ -905,138 +663,6 @@ await swap.execute(
905
663
  - FromBTCLNSwapState.CLAIM_CLAIMED = 3
906
664
  - Funds were successfully claimed & lightning network secret pre-image revealed, so the lightning network payment will settle now
907
665
 
908
- </details>
909
-
910
- #### Swap Bitcoin lightning network -> Starknet/EVM
911
-
912
- Getting swap quote
913
-
914
- ```typescript
915
- const swap = await swapper.swap(
916
- Tokens.BITCOIN.BTCLN, //Swap from BTC-LN
917
- Tokens.STARKNET.STRK, //Into specified destination token
918
- 10000n, //Amount can be either passed in base units as bigint or in decimal format as string
919
- SwapAmountType.EXACT_IN, //SwapAmountType.EXACT_IN, so we specify the input amount
920
- undefined, //Source address for the swap, not used for swaps from BTC-LN
921
- signer.getAddress(), //Destination address
922
- {
923
- gasAmount: 1_000_000_000_000_000_000n //We can also request a gas drop on the destination chain (here requesting 1 STRK)
924
- }
925
- );
926
-
927
- //Get the bitcoin lightning network invoice (the invoice contains pre-entered amount)
928
- const receivingLightningInvoice: string = swap.getAddress();
929
- //Get the URI hyperlink (contains the lightning network invoice) which can be displayed also as QR code
930
- const qrCodeData: string = swap.getHyperlink();
931
-
932
- //Get the amount required to pay and fee
933
- const input: string = swap.getInputWithoutFee().toString(); //Input amount excluding fees
934
- const fee: string = swap.getFee().amountInSrcToken.toString(); //Fees paid on the output
935
- const inputWithFees: string = swap.getInput().toString(); //Total amount paid including fees
936
-
937
- const output: string = swap.getOutput().toString(); //Total output amount
938
-
939
- //Get swap expiration time
940
- const expiry: number = swap.getQuoteExpiry(); //Expiration time of the swap quote in UNIX milliseconds, swap needs to be initiated before this time
941
-
942
- //Get pricing info
943
- const swapPrice = swap.getPriceInfo().swapPrice; //Price of the current swap (excluding fees)
944
- const marketPrice = swap.getPriceInfo().marketPrice; //Current market price
945
- const difference = swap.getPriceInfo().difference; //Difference between the swap price & current market price
946
- ```
947
-
948
- Executing the swap (simple)
949
-
950
- ```typescript
951
- const automaticSettlementSuccess = await swap.execute(
952
- { //Lightning network wallet, you can also pass null/undefined and pay the LN invoice from an external wallet
953
- payInvoice: (bolt11PaymentRequest: string) => {
954
- //Here you would usually call the WebLN or NWC to execute the payment, it's completely fine if the
955
- // promise here would block till the payment is settled
956
- return Promise.resolve("");
957
- }
958
- },
959
- { //Callbacks
960
- onSourceTransactionReceived: (sourceLnPaymentHash: string) => {
961
- //Lightning network payment received by the LP
962
- },
963
- onSwapSettled: (destinationClaimTxId: string) => {
964
- //Swap settled and funds received on destination
965
- }
966
- }
967
- );
968
-
969
- //In case the automatic swap settlement fails, we can settle it manually using the wallet of the destination chain
970
- if(!automaticSettlementSuccess) {
971
- await swap.claim(starknetSigner);
972
- }
973
- ```
974
-
975
-
976
- <details>
977
- <summary>Manual swap execution (advanced)</summary>
978
-
979
- - __1.__ Pay the LN invoice from a lightning network wallet
980
- ```typescript
981
- const lightningInvoice = swap.getAddress();
982
- ```
983
-
984
- - __2.__ Start listening to incoming lightning network payment
985
- ```typescript
986
- const success = await swap.waitForPayment();
987
- if(!success) {
988
- //Lightning network payment not received in time and quote expired
989
- return;
990
- }
991
- ```
992
-
993
- - __3.__ Wait for the swap to be automatically settled
994
- ```typescript
995
- const automaticSettlementSuccess = await swap.waitTillClaimed(60);
996
- ```
997
-
998
- - __4.__ In case the automatic swap settlement fails, we can settle it manually using the wallet of the destination chain
999
-
1000
- - __a.__ Claim with signer
1001
- ```typescript
1002
- if(!automaticSettlementSuccess) {
1003
- await swap.claim(starknetSigner);
1004
- }
1005
- ```
1006
-
1007
- - __b.__ Or get the transactions & [sign and send transaction manually](#manually-signing-smart-chain-transactions)
1008
- ```typescript
1009
- if(!automaticSettlementSuccess) {
1010
- const txsClaim = await swap.txsClaim();
1011
- //Sign and send these...
1012
- ...
1013
- }
1014
- ```
1015
-
1016
- </details>
1017
-
1018
- <details>
1019
- <summary>Swap states</summary>
1020
-
1021
- - FromBTCLNAutoSwapState.FAILED = -4
1022
- - If the claiming of the funds was initiated, but never concluded, the user will get his lightning network payment refunded
1023
- - FromBTCLNAutoSwapState.QUOTE_EXPIRED = -3
1024
- - Swap quote expired and cannot be executed anymore
1025
- - FromBTCLNAutoSwapState.QUOTE_SOFT_EXPIRED = -2
1026
- - Swap quote soft-expired (i.e. the quote probably expired, but if there is already an initialization transaction sent it might still succeed)
1027
- - FromBTCLNAutoSwapState.EXPIRED = -1
1028
- - Lightning network invoice expired, meaning the swap is expired
1029
- - FromBTCLNAutoSwapState.PR_CREATED = 0
1030
- - Swap is created, the user should now pay the provided lightning network invoice
1031
- - FromBTCLNAutoSwapState.PR_PAID = 1
1032
- - Lightning network invoice payment was received (but cannot be settled by the counterparty yet)
1033
- - FromBTCLNAutoSwapState.CLAIM_COMMITED = 2
1034
- - A swap HTLC was offered by the LP to the user
1035
- - FromBTCLNAutoSwapState.CLAIM_CLAIMED = 3
1036
- - Funds were successfully claimed & lightning network secret pre-image revealed, so the lightning network payment will settle now
1037
-
1038
- </details>
1039
-
1040
666
  ### LNURLs & readable lightning identifiers
1041
667
 
1042
668
  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)
@@ -1069,15 +695,18 @@ LNURLs & lightning identifiers:
1069
695
  Getting swap quote
1070
696
 
1071
697
  ```typescript
698
+ const _lnurlOrIdentifier: string = "lnurl1dp68gurn8ghj7ampd3kx2ar0veekzar0wd5xjtnrdakj7tnhv4kxctttdehhwm30d3h82unvwqhkx6rfvdjx2ctvxyesuk0a27"; //Destination LNURL-pay or readable identifier
699
+ const _exactIn = false; //exactIn = false, so we specify the output amount
700
+ const _amount: bigint = 10000n; //Amount of satoshis to send (1 BTC = 100 000 000 satoshis)
701
+
1072
702
  //Create the swap: swapping SOL to Bitcoin lightning
1073
703
  const swap = await swapper.swap(
1074
704
  Tokens.SOLANA.SOL, //From specified source token
1075
705
  Tokens.BITCOIN.BTCLN, //Swap to BTC-LN
1076
- 10000n, //Now we can specify an amount for a lightning network payment!
1077
- SwapAmountType.EXACT_OUT, //We can also use exactIn=true here and set an amount in input token
706
+ _amount, //Now we can specify an amount for a lightning network payment!
707
+ _exactIn, //We can also use exactIn=true here and set an amount in input token
1078
708
  solanaSigner.getAddress(), //Source address and smart chain signer
1079
- //Destination LNURL-pay or readable identifier
1080
- "lnurl1dp68gurn8ghj7ampd3kx2ar0veekzar0wd5xjtnrdakj7tnhv4kxctttdehhwm30d3h82unvwqhkx6rfvdjx2ctvxyesuk0a27",
709
+ _lnurlOrIdentifier, //Destination of the swap
1081
710
  {
1082
711
  comment: "Hello world" //For LNURL-pay we can also pass a comment to the recipient
1083
712
  }
@@ -1099,105 +728,53 @@ const marketPrice = swap.getPriceInfo().marketPrice; //Current market price
1099
728
  const difference = swap.getPriceInfo().difference; //Difference between the swap price & current market price
1100
729
  ```
1101
730
 
1102
-
1103
- Executing the swap (simple)
731
+ Initiating the swap
1104
732
 
1105
733
  ```typescript
1106
- const swapSuccessful = await swap.execute(
1107
- solanaSigner,
1108
- { //Callbacks
1109
- onSourceTransactionSent: (txId: string) => {
1110
- //Transaction on the source chain was sent
1111
- },
1112
- onSourceTransactionConfirmed: (txId: string) => {
1113
- //Transaction on the source chain was confirmed
1114
- },
1115
- onSwapSettled: (destinationTxId: string) => {
1116
- //Lightning payment on the destination chain was sent and swap settled
1117
- }
1118
- }
1119
- );
1120
-
1121
- //Refund in case of failure
1122
- if(!swapSuccessful) {
1123
- //Swap failed, money can be refunded
1124
- await swap.refund(solanaSigner);
1125
- return;
1126
- }
1127
-
1128
- //Swap successful!
1129
- const lightningSecret = swap.getSecret();
1130
- //In case the LNURL contained a success action, we can read it now and display it to user
1131
- if(swap.hasSuccessAction()) {
1132
- //Contains a success action that should displayed to the user
1133
- const successMessage = swap.getSuccessAction();
1134
- const description: string = successMessage.description; //Description of the message
1135
- const text: (string | null) = successMessage.text; //Main text of the message
1136
- const url: (string | null) = successMessage.url; //URL link which should be displayed
1137
- }
734
+ //Initiate and pay for the swap
735
+ await swap.commit(solanaSigner);
1138
736
  ```
1139
737
 
1140
- <details>
1141
- <summary>Manual swap execution (advanced)</summary>
738
+ or [sign and send transaction manually](#manually-signing-smart-chain-transactions)
1142
739
 
1143
- - __1.__ Initiate the swap on the smart-chain side
740
+ Wait for the swap to execute, refund in case of failure
1144
741
 
1145
- - __a.__ Commit with a signer
1146
- ```typescript
1147
- await swap.commit(solanaSigner);
1148
- ```
1149
-
1150
- - __b.__ Or get the transactions & [sign and send transaction manually](#manually-signing-smart-chain-transactions)
1151
- ```typescript
1152
- const txsCommit = await swap.txsCommit();
1153
- //Sign and send these...
1154
- ...
1155
- //Important to wait till SDK processes the swap initialization
1156
- await swap.waitTillCommited();
1157
- ```
1158
-
1159
- - __2.__ Wait for the swap to execute and for the payment to be sent
1160
-
1161
- ```typescript
1162
- const swapSuccessful = await swap.waitForPayment();
1163
- ```
1164
-
1165
- - __3.__ In case the swap fails we can refund our funds on the source chain
1166
-
1167
- - __a.__ Refund with a signer
1168
- ```typescript
1169
- if(!swapSuccessful) {
1170
- await swap.refund(solanaSigner);
1171
- return;
1172
- }
1173
- ```
1174
-
1175
- - __b.__ Or get the transactions & [sign and send transaction manually](#manually-signing-smart-chain-transactions)
1176
- ```typescript
1177
- if(!swapSuccessful) {
1178
- const txsRefund = await swap.txsRefund();
1179
- //Sign and send these...
1180
- ...
742
+ ```typescript
743
+ //Wait for the swap to conclude
744
+ const result: boolean = await swap.waitForPayment();
745
+ if(!result) {
746
+ //Swap failed, money can be refunded
747
+ await swap.refund(solanaSigner);
748
+ } else {
749
+ //Swap successful, we can get the lightning payment secret pre-image, which acts as a proof of payment
750
+ const lightningSecret = swap.getSecret();
751
+ //In case the LNURL contained a success action, we can read it now and display it to user
752
+ if(swap.hasSuccessAction()) {
753
+ //Contains a success action that should displayed to the user
754
+ const successMessage = swap.getSuccessAction();
755
+ const description: string = successMessage.description; //Description of the message
756
+ const text: (string | null) = successMessage.text; //Main text of the message
757
+ const url: (string | null) = successMessage.url; //URL link which should be displayed
1181
758
  }
1182
- ```
1183
-
1184
- </details>
1185
-
1186
- #### Swap Bitcoin lightning network -> Solana
759
+ }
760
+ ```
1187
761
 
1188
- 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.
762
+ #### Swap Bitcoin lightning network -> Smart chain
1189
763
 
1190
764
  Getting swap quote
1191
765
 
1192
766
  ```typescript
767
+ const _lnurl: string = "lnurl1dp68gurn8ghj7ampd3kx2ar0veekzar0wd5xjtnrdakj7tnhv4kxctttdehhwm30d3h82unvwqhkx6rfvdjx2ctvxyesuk0a27"; //Destination LNURL-pay or readable identifier
768
+ const _exactIn = true; //exactIn = true, so we specify the input amount
769
+ const _amount = 10000n; //Amount in BTC base units - sats
770
+
1193
771
  const swap = await swapper.swap(
1194
772
  Tokens.BITCOIN.BTCLN, //Swap from BTC-LN
1195
- Tokens.SOLANA.SOL, //Into specified destination token
1196
- 10000n,
1197
- SwapAmountType.EXACT_IN, //EXACT_IN, so we specify the input amount
1198
- //Source LNURL-withdraw link
1199
- "lnurl1dp68gurn8ghj7ampd3kx2ar0veekzar0wd5xjtnrdakj7tnhv4kxctttdehhwm30d3h82unvwqhkx6rfvdjx2ctvxyesuk0a27",
1200
- signer.getAddress(), //Destination address
773
+ Tokens.STARKNET.STRK, //Into specified destination token
774
+ _amount,
775
+ _exactIn, //Whether we define an input or output amount
776
+ _lnurl, //Source LNURL for the swap
777
+ signer.getAddress() //Destination address
1201
778
  );
1202
779
 
1203
780
  //Get the amount required to pay and fee
@@ -1219,152 +796,36 @@ const marketPrice = swap.getPriceInfo().marketPrice; //Current market price
1219
796
  const difference = swap.getPriceInfo().difference; //Difference between the swap price & current market price
1220
797
  ```
1221
798
 
1222
- Executing the swap (simple)
1223
-
1224
- ```typescript
1225
- await swap.execute(
1226
- solanaSigner,
1227
- undefined, //No need to specify a wallet, we are sourcing the fund from LNURL-withdraw link
1228
- { //Callbacks
1229
- onSourceTransactionReceived: (sourceLnPaymentHash: string) => {
1230
- //Lightning network payment received by the LP
1231
- },
1232
- onDestinationCommitSent: (destinationCommitTxId: string) => {
1233
- //HTLC initialization transaction sent on the destination chain
1234
- },
1235
- onDestinationClaimSent: (destinationClaimTxId: string) => {
1236
- //HTLC claim transaction sent on the destination chain
1237
- },
1238
- onSwapSettled: (destinationClaimTxId: string) => {
1239
- //Swap settled and funds received on destination
1240
- }
1241
- }
1242
- );
1243
- ```
1244
-
1245
- <details>
1246
- <summary>Manual swap execution (advanced)</summary>
1247
-
1248
- - __1.__ Start listening to incoming lightning network payment (this also requests the payment from LNURL-withdraw service)
1249
- ```typescript
1250
- const success = await swap.waitForPayment();
1251
- if(!success) {
1252
- //Lightning network payment not received in time and quote expired
1253
- return;
1254
- }
1255
- ```
1256
-
1257
- - __2.__ Claim the swap at the destination
1258
-
1259
- - __a.__ Commit & claim with signer
1260
- ```typescript
1261
- await swap.commitAndClaim(solanaSigner);
1262
- ```
1263
-
1264
- - __b.__ Or get the transactions & [sign and send transaction manually](#manually-signing-smart-chain-transactions)
1265
- ```typescript
1266
- const txsCommitAndClaim = await swap.txsCommitAndClaim();
1267
- //Take EXTRA care to make sure transaction are sent sequentially and in order - always wait
1268
- // for prior transaction confirmation before sending the next one
1269
- //Sign and send these...
1270
- ...
1271
- ```
1272
-
1273
- </details>
1274
-
1275
- #### Swap Bitcoin lightning network -> Starknet/EVM
1276
-
1277
- Getting swap quote
799
+ Wait for the payment to be received
1278
800
 
1279
801
  ```typescript
1280
- const swap = await swapper.swap(
1281
- Tokens.BITCOIN.BTCLN, //Swap from BTC-LN
1282
- Tokens.STARKNET.STRK, //Into specified destination token
1283
- 10000n,
1284
- SwapAmountType.EXACT_IN, //EXACT_IN, so we specify the input amount
1285
- //Source LNURL-withdraw link
1286
- "lnurl1dp68gurn8ghj7ampd3kx2ar0veekzar0wd5xjtnrdakj7tnhv4kxctttdehhwm30d3h82unvwqhkx6rfvdjx2ctvxyesuk0a27",
1287
- signer.getAddress(), //Destination address
1288
- {
1289
- gasAmount: 1_000_000_000_000_000_000n //We can also request a gas drop on the destination chain (here requesting 1 STRK)
1290
- }
1291
- );
1292
-
1293
- //Get the amount required to pay and fee
1294
- const input: string = swap.getInputWithoutFee().toString(); //Input amount excluding fees
1295
- const fee: string = swap.getFee().amountInSrcToken.toString(); //Fees paid on the output
1296
- const inputWithFees: string = swap.getInput().toString(); //Total amount paid including fees
1297
-
1298
- const output: string = swap.getOutput().toString(); //Total output amount
1299
-
1300
- //Get swap expiration time
1301
- const expiry: number = swap.getQuoteExpiry(); //Expiration time of the swap quote in UNIX milliseconds, swap needs to be initiated before this time
1302
-
1303
- //Get pricing info
1304
- const swapPrice = swap.getPriceInfo().swapPrice; //Price of the current swap (excluding fees)
1305
- const marketPrice = swap.getPriceInfo().marketPrice; //Current market price
1306
- const difference = swap.getPriceInfo().difference; //Difference between the swap price & current market price
802
+ //Start listening to incoming lightning network payment
803
+ const success = await swap.waitForPayment();
804
+ if(!success) {
805
+ //Lightning network payment not received in time and quote expired!
806
+ return;
807
+ }
1307
808
  ```
1308
809
 
1309
-
1310
- Executing the swap (simple)
810
+ Claim the funds on the destination smart chains, this settles the swap and lightning network payment
1311
811
 
1312
812
  ```typescript
1313
- const automaticSettlementSuccess = await swap.execute(
1314
- undefined, //No need to specify a wallet, we are sourcing the funds from LNURL-withdraw link
1315
- { //Callbacks
1316
- onSourceTransactionReceived: (sourceLnPaymentHash: string) => {
1317
- //Lightning network payment received by the LP
1318
- },
1319
- onSwapSettled: (destinationClaimTxId: string) => {
1320
- //Swap settled and funds received on destination
1321
- }
813
+ try {
814
+ //Claim the swap funds - this will initiate 2 transactions
815
+ if(swap.canCommitAndClaimInOneShot()) {
816
+ //Some chains (e.g. Solana) support signing multiple transactions in one flow
817
+ await swap.commitAndClaim(solanaSigner);
818
+ } else {
819
+ //Other chains (e.g. Starknet) don't support signing multiple transaction in one flow, therefore you need to sign one-by-one
820
+ await swap.commit(starknetSigner);
821
+ await swap.claim(starknetSigner);
1322
822
  }
1323
- );
1324
-
1325
- //In case the automatic swap settlement fails, we can settle it manually using the wallet of the destination chain
1326
- if(!automaticSettlementSuccess) {
1327
- await swap.claim(starknetSigner);
823
+ } catch(e) {
824
+ //Error occurred while waiting for payment
1328
825
  }
1329
826
  ```
1330
827
 
1331
-
1332
- <details>
1333
- <summary>Manual swap execution (advanced)</summary>
1334
-
1335
- - __1.__ Start listening to incoming lightning network payment (this also requests the payment from LNURL-withdraw service)
1336
- ```typescript
1337
- const success = await swap.waitForPayment();
1338
- if(!success) {
1339
- //Lightning network payment not received in time and quote expired
1340
- return;
1341
- }
1342
- ```
1343
-
1344
- - __2.__ Wait for the swap to be automatically settled
1345
- ```typescript
1346
- const automaticSettlementSuccess = await swap.waitTillClaimed(60);
1347
- ```
1348
-
1349
- - __3.__ In case the automatic swap settlement fails, we can settle it manually using the wallet of the destination chain
1350
-
1351
- - __a.__ Claim with signer
1352
- ```typescript
1353
- if(!automaticSettlementSuccess) {
1354
- await swap.claim(starknetSigner);
1355
- }
1356
- ```
1357
-
1358
- - __b.__ Or get the transactions & [sign and send transaction manually](#manually-signing-smart-chain-transactions)
1359
- ```typescript
1360
- if(!automaticSettlementSuccess) {
1361
- const txsClaim = await swap.txsClaim();
1362
- //Sign and send these...
1363
- ...
1364
- }
1365
- ```
1366
-
1367
- </details>
828
+ or [sign and send transactions manually](#manually-signing-smart-chain-transactions)
1368
829
 
1369
830
  ### Getting state of the swap
1370
831
 
@@ -1470,12 +931,14 @@ Returns swaps that are ready to be claimed by the client, this can happen if cli
1470
931
  const claimableSolanaSwaps = await solanaSwapper.getClaimableSwaps("SOLANA", solanaSigner.getAddress());
1471
932
  //Claim all the claimable swaps
1472
933
  for(let swap of claimableSolanaSwaps) {
934
+ if(swap.canCommit()) await swap.commit(solanaSigner); //This is for Bitcoin (lightning) -> Smart chain swaps, where commit & claim procedure might be needed
1473
935
  await swap.claim(solanaSigner);
1474
936
  }
1475
937
  //Get the swaps
1476
938
  const claimableStarknetSwaps = await solanaSwapper.getClaimableSwaps("STARKNET", starknetSigner.getAddress());
1477
939
  //Claim all the claimable swaps
1478
940
  for(let swap of claimableStarknetSwaps) {
941
+ if(swap.canCommit()) await swap.commit(starknetSigner); //This is for Bitcoin (lightning) -> Smart chain swaps, where commit & claim procedure might be needed
1479
942
  await swap.claim(starknetSigner);
1480
943
  }
1481
944
  ```
@@ -1564,7 +1027,7 @@ After sending the transactions, you also need to make sure the SDK has enough ti
1564
1027
  ```typescript
1565
1028
  //Example for Solana
1566
1029
  const txns = await swap.txsCommit(); //Also works with txsClaim, txsRefund, txCommitAndClaim
1567
- txns.forEach(val => if(val.signers.length>0) { val.tx.sign(...val.signers) });
1030
+ txns.forEach(val => val.tx.sign(...val.signers));
1568
1031
  const signedTransactions = await solanaSigner.wallet.signAllTransactions(txns.map(val => val.tx));
1569
1032
  for(let tx of signedTransactions) {
1570
1033
  const res = await solanaRpc.sendRawTransaction(tx.serialize());
@@ -1579,13 +1042,6 @@ for(let tx of txns) {
1579
1042
  if(tx.type==="DEPLOY_ACCOUNT") await starknetSigner.account.deployAccount(tx.tx, tx.details);
1580
1043
  }
1581
1044
  await swap.waitTillCommited(); //Or other relevant waitTillClaimed, waitTillRefunded
1582
-
1583
- //Example for EVM
1584
- const txns = await swap.txsCommit(); //Also works with txsClaim, txsRefund, txCommitAndClaim
1585
- for(let tx of txns) {
1586
- await evmSigner.account.sendTransaction(tx);
1587
- }
1588
- await swap.waitTillCommited(); //Or other relevant waitTillClaimed, waitTillRefunded
1589
1045
  ```
1590
1046
 
1591
1047
  ### Additional swapper options