@atomiqlabs/sdk 5.0.0-dev.6 → 5.0.0-dev.7
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 +676 -300
- package/dist/SmartChainAssets.d.ts +10 -0
- package/dist/SmartChainAssets.js +10 -0
- package/dist/SwapperFactory.js +3 -0
- package/package.json +4 -4
- package/src/SmartChainAssets.ts +10 -0
- package/src/SwapperFactory.ts +3 -0
package/README.md
CHANGED
|
@@ -170,7 +170,7 @@ const evmWallet = new EVMSigner(wallet, wallet.address);
|
|
|
170
170
|
|
|
171
171
|
### Initialization
|
|
172
172
|
|
|
173
|
-
Initialize the swapper
|
|
173
|
+
Initialize the swapper, this should be done once when your app starts. Checks existing in-progress swaps and does initial LP discovery
|
|
174
174
|
|
|
175
175
|
```typescript
|
|
176
176
|
await swapper.init();
|
|
@@ -186,12 +186,6 @@ To make it easier to do swaps between bitcoin and a specific chain we can extrac
|
|
|
186
186
|
const solanaSwapper = swapper.withChain<"SOLANA">("SOLANA");
|
|
187
187
|
```
|
|
188
188
|
|
|
189
|
-
or also with signer
|
|
190
|
-
|
|
191
|
-
```typescript
|
|
192
|
-
const starknetSwapperWithSigner = swapper.withChain<"STARKNET">("STARKNET").withSigner(signer);
|
|
193
|
-
```
|
|
194
|
-
|
|
195
189
|
### Bitcoin on-chain swaps
|
|
196
190
|
|
|
197
191
|
#### Swap Smart chain -> Bitcoin on-chain
|
|
@@ -199,18 +193,14 @@ const starknetSwapperWithSigner = swapper.withChain<"STARKNET">("STARKNET").with
|
|
|
199
193
|
Getting swap quote
|
|
200
194
|
|
|
201
195
|
```typescript
|
|
202
|
-
const _exactIn = false; //exactIn = false, so we specify the output amount
|
|
203
|
-
const _amount = 10000n; //Amount in BTC base units - sats (10000 sats = 0.0001 BTC)
|
|
204
|
-
const _address = "bc1qtw67hj77rt8zrkkg3jgngutu0yfgt9czjwusxt"; //BTC address of the recipient
|
|
205
|
-
|
|
206
196
|
//Create the swap: swapping SOL to Bitcoin on-chain, receiving _amount of satoshis (smallest unit of bitcoin) to _address
|
|
207
197
|
const swap = await swapper.swap(
|
|
208
198
|
Tokens.SOLANA.SOL, //From specified source token
|
|
209
199
|
Tokens.BITCOIN.BTC, //Swap to BTC
|
|
210
|
-
|
|
211
|
-
|
|
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
|
|
212
202
|
solanaSigner.getAddress(), //Source address and smart chain signer
|
|
213
|
-
|
|
203
|
+
"bc1qtw67hj77rt8zrkkg3jgngutu0yfgt9czjwusxt" //BTC address of the recipient
|
|
214
204
|
);
|
|
215
205
|
|
|
216
206
|
//Get the amount required to pay and fee
|
|
@@ -229,30 +219,80 @@ const marketPrice = swap.getPriceInfo().marketPrice; //Current market price
|
|
|
229
219
|
const difference = swap.getPriceInfo().difference; //Difference between the swap price & current market price
|
|
230
220
|
```
|
|
231
221
|
|
|
232
|
-
|
|
222
|
+
Executing the swap (simple)
|
|
233
223
|
|
|
234
224
|
```typescript
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
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
|
+
);
|
|
242
239
|
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
const result: boolean = await swap.waitForPayment();
|
|
246
|
-
if(!result) {
|
|
240
|
+
//Refund in case of failure
|
|
241
|
+
if(!swapSuccessful) {
|
|
247
242
|
//Swap failed, money can be refunded
|
|
248
|
-
await swap.refund();
|
|
243
|
+
await swap.refund(solanaSigner);
|
|
249
244
|
} else {
|
|
250
|
-
//Swap successful
|
|
251
|
-
const bitcoinTxId = swap.getBitcoinTxId();
|
|
245
|
+
//Swap successful!
|
|
252
246
|
}
|
|
253
247
|
```
|
|
254
248
|
|
|
255
|
-
|
|
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>
|
|
256
296
|
|
|
257
297
|
- ToBTCSwapState.REFUNDED = -3
|
|
258
298
|
- Swap failed and was successfully refunded
|
|
@@ -271,6 +311,8 @@ if(!result) {
|
|
|
271
311
|
- ToBTCSwapState.REFUNDABLE = 4
|
|
272
312
|
- Swap was initiated but counterparty failed to process it, the user can now refund his funds
|
|
273
313
|
|
|
314
|
+
</details>
|
|
315
|
+
|
|
274
316
|
#### Swap Bitcoin on-chain -> Solana
|
|
275
317
|
|
|
276
318
|
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.
|
|
@@ -278,15 +320,12 @@ NOTE: Solana uses an old swap protocol for Bitcoin on-chain -> Solana swaps, the
|
|
|
278
320
|
Getting swap quote
|
|
279
321
|
|
|
280
322
|
```typescript
|
|
281
|
-
const _exactIn = true; //exactIn = true, so we specify the input amount
|
|
282
|
-
const _amount = fromHumanReadableString("0.0001", Tokens.BITCOIN.BTC); //Amount in BTC base units - sats, we can also use a utility function here
|
|
283
|
-
|
|
284
323
|
//Create the swap: swapping _amount of satoshis of Bitcoin on-chain to SOL
|
|
285
324
|
const swap = await swapper.swap(
|
|
286
325
|
Tokens.BITCOIN.BTC, //Swap from BTC
|
|
287
326
|
Tokens.SOLANA.SOL, //Into specified destination token
|
|
288
|
-
|
|
289
|
-
|
|
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
|
|
290
329
|
undefined, //Source address for the swap, not used for swaps from BTC
|
|
291
330
|
solanaSigner.getAddress() //Destination address
|
|
292
331
|
);
|
|
@@ -312,67 +351,123 @@ const marketPrice = swap.getPriceInfo().marketPrice; //Current market price
|
|
|
312
351
|
const difference = swap.getPriceInfo().difference; //Difference between the swap price & current market price
|
|
313
352
|
```
|
|
314
353
|
|
|
315
|
-
|
|
354
|
+
Executing the swap (simple)
|
|
316
355
|
|
|
317
356
|
```typescript
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
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
|
+
);
|
|
335
387
|
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
for(let signIdx of signInputs) {
|
|
340
|
-
psbt.signIdx(..., signIdx); //Or pass it to external signer
|
|
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);
|
|
341
391
|
}
|
|
342
|
-
const bitcoinTxId = await swap.submitPsbt(psbt);
|
|
343
392
|
```
|
|
344
393
|
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
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
|
+
```
|
|
365
466
|
|
|
366
|
-
|
|
367
|
-
try {
|
|
368
|
-
await swap.waitTillClaimed(timeoutSignal(30*1000));
|
|
369
|
-
} catch (e) {
|
|
370
|
-
//Claim ourselves when automatic claim doesn't happen in 30 seconds
|
|
371
|
-
await swap.claim(solanaSigner);
|
|
372
|
-
}
|
|
373
|
-
```
|
|
467
|
+
</details>
|
|
374
468
|
|
|
375
|
-
|
|
469
|
+
<details>
|
|
470
|
+
<summary>Swap states</summary>
|
|
376
471
|
|
|
377
472
|
- FromBTCSwapState.EXPIRED = -3
|
|
378
473
|
- Bitcoin swap address expired
|
|
@@ -389,6 +484,7 @@ try {
|
|
|
389
484
|
- FromBTCSwapState.CLAIM_CLAIMED = 3
|
|
390
485
|
- Swap funds are claimed to the user's wallet
|
|
391
486
|
|
|
487
|
+
</details>
|
|
392
488
|
|
|
393
489
|
#### Swap Bitcoin on-chain -> Starknet/EVM
|
|
394
490
|
|
|
@@ -397,15 +493,12 @@ NOTE: Starknet & EVM uses a new swap protocol for Bitcoin on-chain -> Smart chai
|
|
|
397
493
|
Getting swap quote
|
|
398
494
|
|
|
399
495
|
```typescript
|
|
400
|
-
const _exactIn = true; //exactIn = true, so we specify the input amount
|
|
401
|
-
const _amount = fromHumanReadableString("0.0001", Tokens.BITCOIN.BTC); //Amount in BTC base units - sats, we can also use a utility function here
|
|
402
|
-
|
|
403
496
|
//Create the swap: swapping _amount of satoshis of Bitcoin on-chain to SOL
|
|
404
497
|
const swap = await swapper.swap(
|
|
405
498
|
Tokens.BITCOIN.BTC, //Swap from BTC
|
|
406
499
|
Tokens.STARKNET.STRK, //Into specified destination token
|
|
407
|
-
|
|
408
|
-
|
|
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
|
|
409
502
|
undefined, //Source address for the swap, not used for swaps from BTC
|
|
410
503
|
starknetSigner.getAddress(), //Destination address
|
|
411
504
|
{
|
|
@@ -429,62 +522,109 @@ const marketPrice = swap.getPriceInfo().marketPrice; //Current market price
|
|
|
429
522
|
const difference = swap.getPriceInfo().difference; //Difference between the swap price & current market price
|
|
430
523
|
```
|
|
431
524
|
|
|
432
|
-
|
|
525
|
+
Executing the swap (simple)
|
|
433
526
|
|
|
434
527
|
```typescript
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
}
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
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
|
+
);
|
|
444
554
|
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
//Make sure the second input's sequence (index 1) is as specified in the in1sequence variable
|
|
450
|
-
psbt.updateInput(1, {sequence: in1sequence});
|
|
451
|
-
//Sign the PSBT, sign every input except the first one
|
|
452
|
-
for(let i=1;i<psbt.inputsLength; i++) psbt.signIdx(..., i); //Or pass it to external signer
|
|
453
|
-
//Submit the signed PSBT
|
|
454
|
-
const bitcoinTxId = await swap.submitPsbt(psbt);
|
|
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);
|
|
558
|
+
}
|
|
455
559
|
```
|
|
456
560
|
|
|
457
|
-
Waiting for swap execution
|
|
458
561
|
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
);
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
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
|
+
```
|
|
477
623
|
|
|
478
|
-
|
|
479
|
-
try {
|
|
480
|
-
await swap.waitTillClaimedOrFronted(timeoutSignal(30*1000));
|
|
481
|
-
} catch (e) {
|
|
482
|
-
//Claim ourselves when automatic claim doesn't happen in 30 seconds
|
|
483
|
-
await swap.claim(starknetSigner);
|
|
484
|
-
}
|
|
485
|
-
```
|
|
624
|
+
</details>
|
|
486
625
|
|
|
487
|
-
|
|
626
|
+
<details>
|
|
627
|
+
<summary>Swap states</summary>
|
|
488
628
|
|
|
489
629
|
- SpvFromBTCSwapState.CLOSED = -5
|
|
490
630
|
- Catastrophic failure during swap, shall never happen
|
|
@@ -510,6 +650,8 @@ try {
|
|
|
510
650
|
- Bitcoin swap transaction is confirmed
|
|
511
651
|
- SpvFromBTCSwapState.CLAIM_CLAIMED = 6
|
|
512
652
|
- Swap funds are claimed to the user's wallet
|
|
653
|
+
-
|
|
654
|
+
</details>
|
|
513
655
|
|
|
514
656
|
### Bitcoin lightning network swaps
|
|
515
657
|
|
|
@@ -518,17 +660,15 @@ try {
|
|
|
518
660
|
Getting swap quote
|
|
519
661
|
|
|
520
662
|
```typescript
|
|
521
|
-
//Destination lightning network invoice, amount needs to be part of the invoice!
|
|
522
|
-
const _lightningInvoice = "lnbc10u1pj2q0g9pp5ejs6m677m39cznpzum7muruvh50ys93ln82p4j9ks2luqm56xxlshp52r2anlhddfa9ex9vpw9gstxujff8a0p8s3pzvua930js0kwfea6scqzzsxqyz5vqsp5073zskc5qfgp7lre0t6s8uexxxey80ax564hsjklfwfjq2ew0ewq9qyyssqvzmgs6f8mvuwgfa9uqxhtza07qem4yfhn9wwlpskccmuwplsqmh8pdy6c42kqdu8p73kky9lsnl40qha5396d8lpgn90y27ltfc5rfqqq59cya";
|
|
523
|
-
|
|
524
663
|
//Create the swap: swapping SOL to Bitcoin lightning
|
|
525
664
|
const swap = await swapper.swap(
|
|
526
665
|
Tokens.SOLANA.SOL, //From specified source token
|
|
527
666
|
Tokens.BITCOIN.BTCLN, //Swap to BTC-LN
|
|
528
667
|
undefined, //Amount is specified in the lightning network invoice!
|
|
529
|
-
|
|
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!
|
|
530
669
|
solanaSigner.getAddress(), //Source address and smart chain signer
|
|
531
|
-
|
|
670
|
+
//Destination lightning network invoice, amount needs to be part of the invoice!
|
|
671
|
+
"lnbc10u1pj2q0g9pp5ejs6m677m39cznpzum7muruvh50ys93ln82p4j9ks2luqm56xxlshp52r2anlhddfa9ex9vpw9gstxujff8a0p8s3pzvua930js0kwfea6scqzzsxqyz5vqsp5073zskc5qfgp7lre0t6s8uexxxey80ax564hsjklfwfjq2ew0ewq9qyyssqvzmgs6f8mvuwgfa9uqxhtza07qem4yfhn9wwlpskccmuwplsqmh8pdy6c42kqdu8p73kky9lsnl40qha5396d8lpgn90y27ltfc5rfqqq59cya"
|
|
532
672
|
);
|
|
533
673
|
|
|
534
674
|
//Get the amount required to pay and fee
|
|
@@ -547,30 +687,80 @@ const marketPrice = swap.getPriceInfo().marketPrice; //Current market price
|
|
|
547
687
|
const difference = swap.getPriceInfo().difference; //Difference between the swap price & current market price
|
|
548
688
|
```
|
|
549
689
|
|
|
550
|
-
|
|
690
|
+
Executing the swap (simple)
|
|
551
691
|
|
|
552
692
|
```typescript
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
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
|
+
);
|
|
560
707
|
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
//Swap failed, money can be refunded
|
|
566
|
-
await swap.refund(solanaSigner);
|
|
708
|
+
//Refund in case of failure
|
|
709
|
+
if(!swapSuccessful) {
|
|
710
|
+
//Swap failed, money can be refunded
|
|
711
|
+
await swap.refund(solanaSigner);
|
|
567
712
|
} else {
|
|
568
|
-
|
|
569
|
-
const lightningSecret = swap.getSecret();
|
|
713
|
+
//Swap successful!
|
|
570
714
|
}
|
|
571
715
|
```
|
|
572
716
|
|
|
573
|
-
|
|
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>
|
|
574
764
|
|
|
575
765
|
- ToBTCSwapState.REFUNDED = -3
|
|
576
766
|
- Swap failed and was successfully refunded
|
|
@@ -589,6 +779,8 @@ if(!result) {
|
|
|
589
779
|
- ToBTCSwapState.REFUNDABLE = 4
|
|
590
780
|
- Swap was initiated but counterparty failed to process it, the user can now refund his funds
|
|
591
781
|
|
|
782
|
+
</details>
|
|
783
|
+
|
|
592
784
|
#### Swap Bitcoin lightning network -> Solana
|
|
593
785
|
|
|
594
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.
|
|
@@ -596,14 +788,11 @@ NOTE: Solana uses an old swap protocol for Bitcoin lightning network -> Solana s
|
|
|
596
788
|
Getting swap quote
|
|
597
789
|
|
|
598
790
|
```typescript
|
|
599
|
-
const _exactIn = true; //exactIn = true, so we specify the input amount
|
|
600
|
-
const _amount = 10000n; //Amount in BTC base units - sats
|
|
601
|
-
|
|
602
791
|
const swap = await swapper.swap(
|
|
603
792
|
Tokens.BITCOIN.BTCLN, //Swap from BTC-LN
|
|
604
793
|
Tokens.SOLANA.SOL, //Into specified destination token
|
|
605
|
-
|
|
606
|
-
|
|
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
|
|
607
796
|
undefined, //Source address for the swap, not used for swaps from BTC-LN
|
|
608
797
|
signer.getAddress() //Destination address
|
|
609
798
|
);
|
|
@@ -632,40 +821,72 @@ const marketPrice = swap.getPriceInfo().marketPrice; //Current market price
|
|
|
632
821
|
const difference = swap.getPriceInfo().difference; //Difference between the swap price & current market price
|
|
633
822
|
```
|
|
634
823
|
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
Wait for the payment to be received
|
|
824
|
+
Executing the swap (simple)
|
|
638
825
|
|
|
639
826
|
```typescript
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
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
|
+
);
|
|
646
851
|
```
|
|
647
852
|
|
|
648
|
-
|
|
853
|
+
<details>
|
|
854
|
+
<summary>Manual swap execution (advanced)</summary>
|
|
649
855
|
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
}
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
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
|
+
```
|
|
665
876
|
|
|
666
|
-
|
|
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
|
+
```
|
|
667
885
|
|
|
668
|
-
|
|
886
|
+
</details>
|
|
887
|
+
|
|
888
|
+
<details>
|
|
889
|
+
<summary>Swap states</summary>
|
|
669
890
|
|
|
670
891
|
- FromBTCLNSwapState.FAILED = -4
|
|
671
892
|
- If the claiming of the funds was initiated, but never concluded, the user will get his lightning network payment refunded
|
|
@@ -684,20 +905,18 @@ or [sign and send transactions manually](#manually-signing-smart-chain-transacti
|
|
|
684
905
|
- FromBTCLNSwapState.CLAIM_CLAIMED = 3
|
|
685
906
|
- Funds were successfully claimed & lightning network secret pre-image revealed, so the lightning network payment will settle now
|
|
686
907
|
|
|
908
|
+
</details>
|
|
687
909
|
|
|
688
910
|
#### Swap Bitcoin lightning network -> Starknet/EVM
|
|
689
911
|
|
|
690
912
|
Getting swap quote
|
|
691
913
|
|
|
692
914
|
```typescript
|
|
693
|
-
const _exactIn = true; //exactIn = true, so we specify the input amount
|
|
694
|
-
const _amount = 10000n; //Amount in BTC base units - sats
|
|
695
|
-
|
|
696
915
|
const swap = await swapper.swap(
|
|
697
916
|
Tokens.BITCOIN.BTCLN, //Swap from BTC-LN
|
|
698
917
|
Tokens.STARKNET.STRK, //Into specified destination token
|
|
699
|
-
|
|
700
|
-
|
|
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
|
|
701
920
|
undefined, //Source address for the swap, not used for swaps from BTC-LN
|
|
702
921
|
signer.getAddress(), //Destination address
|
|
703
922
|
{
|
|
@@ -726,28 +945,78 @@ const marketPrice = swap.getPriceInfo().marketPrice; //Current market price
|
|
|
726
945
|
const difference = swap.getPriceInfo().difference; //Difference between the swap price & current market price
|
|
727
946
|
```
|
|
728
947
|
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
Wait for the payment to be received and settle the swap.
|
|
948
|
+
Executing the swap (simple)
|
|
732
949
|
|
|
733
950
|
```typescript
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
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
|
+
);
|
|
740
968
|
|
|
741
|
-
//
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
} catch (e) {
|
|
745
|
-
//Claim ourselves when automatic claim doesn't happen in 30 seconds
|
|
746
|
-
await swap.claim(starknetSigner);
|
|
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);
|
|
747
972
|
}
|
|
748
973
|
```
|
|
749
974
|
|
|
750
|
-
|
|
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>
|
|
751
1020
|
|
|
752
1021
|
- FromBTCLNAutoSwapState.FAILED = -4
|
|
753
1022
|
- If the claiming of the funds was initiated, but never concluded, the user will get his lightning network payment refunded
|
|
@@ -766,6 +1035,8 @@ try {
|
|
|
766
1035
|
- FromBTCLNAutoSwapState.CLAIM_CLAIMED = 3
|
|
767
1036
|
- Funds were successfully claimed & lightning network secret pre-image revealed, so the lightning network payment will settle now
|
|
768
1037
|
|
|
1038
|
+
</details>
|
|
1039
|
+
|
|
769
1040
|
### LNURLs & readable lightning identifiers
|
|
770
1041
|
|
|
771
1042
|
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)
|
|
@@ -798,18 +1069,15 @@ LNURLs & lightning identifiers:
|
|
|
798
1069
|
Getting swap quote
|
|
799
1070
|
|
|
800
1071
|
```typescript
|
|
801
|
-
const _lnurlOrIdentifier: string = "lnurl1dp68gurn8ghj7ampd3kx2ar0veekzar0wd5xjtnrdakj7tnhv4kxctttdehhwm30d3h82unvwqhkx6rfvdjx2ctvxyesuk0a27"; //Destination LNURL-pay or readable identifier
|
|
802
|
-
const _exactIn = false; //exactIn = false, so we specify the output amount
|
|
803
|
-
const _amount: bigint = 10000n; //Amount of satoshis to send (1 BTC = 100 000 000 satoshis)
|
|
804
|
-
|
|
805
1072
|
//Create the swap: swapping SOL to Bitcoin lightning
|
|
806
1073
|
const swap = await swapper.swap(
|
|
807
1074
|
Tokens.SOLANA.SOL, //From specified source token
|
|
808
1075
|
Tokens.BITCOIN.BTCLN, //Swap to BTC-LN
|
|
809
|
-
|
|
810
|
-
|
|
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
|
|
811
1078
|
solanaSigner.getAddress(), //Source address and smart chain signer
|
|
812
|
-
|
|
1079
|
+
//Destination LNURL-pay or readable identifier
|
|
1080
|
+
"lnurl1dp68gurn8ghj7ampd3kx2ar0veekzar0wd5xjtnrdakj7tnhv4kxctttdehhwm30d3h82unvwqhkx6rfvdjx2ctvxyesuk0a27",
|
|
813
1081
|
{
|
|
814
1082
|
comment: "Hello world" //For LNURL-pay we can also pass a comment to the recipient
|
|
815
1083
|
}
|
|
@@ -831,36 +1099,89 @@ const marketPrice = swap.getPriceInfo().marketPrice; //Current market price
|
|
|
831
1099
|
const difference = swap.getPriceInfo().difference; //Difference between the swap price & current market price
|
|
832
1100
|
```
|
|
833
1101
|
|
|
834
|
-
|
|
1102
|
+
|
|
1103
|
+
Executing the swap (simple)
|
|
835
1104
|
|
|
836
1105
|
```typescript
|
|
837
|
-
|
|
838
|
-
|
|
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
|
+
}
|
|
839
1138
|
```
|
|
840
1139
|
|
|
841
|
-
|
|
1140
|
+
<details>
|
|
1141
|
+
<summary>Manual swap execution (advanced)</summary>
|
|
842
1142
|
|
|
843
|
-
|
|
1143
|
+
- __1.__ Initiate the swap on the smart-chain side
|
|
844
1144
|
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
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;
|
|
861
1172
|
}
|
|
862
|
-
|
|
863
|
-
|
|
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
|
+
...
|
|
1181
|
+
}
|
|
1182
|
+
```
|
|
1183
|
+
|
|
1184
|
+
</details>
|
|
864
1185
|
|
|
865
1186
|
#### Swap Bitcoin lightning network -> Solana
|
|
866
1187
|
|
|
@@ -869,16 +1190,13 @@ NOTE: Solana uses an old swap protocol for Bitcoin lightning network -> Solana s
|
|
|
869
1190
|
Getting swap quote
|
|
870
1191
|
|
|
871
1192
|
```typescript
|
|
872
|
-
const _lnurl: string = "lnurl1dp68gurn8ghj7ampd3kx2ar0veekzar0wd5xjtnrdakj7tnhv4kxctttdehhwm30d3h82unvwqhkx6rfvdjx2ctvxyesuk0a27"; //Destination LNURL-pay or readable identifier
|
|
873
|
-
const _exactIn = true; //exactIn = true, so we specify the input amount
|
|
874
|
-
const _amount = 10000n; //Amount in BTC base units - sats
|
|
875
|
-
|
|
876
1193
|
const swap = await swapper.swap(
|
|
877
1194
|
Tokens.BITCOIN.BTCLN, //Swap from BTC-LN
|
|
878
1195
|
Tokens.SOLANA.SOL, //Into specified destination token
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
1196
|
+
10000n,
|
|
1197
|
+
SwapAmountType.EXACT_IN, //EXACT_IN, so we specify the input amount
|
|
1198
|
+
//Source LNURL-withdraw link
|
|
1199
|
+
"lnurl1dp68gurn8ghj7ampd3kx2ar0veekzar0wd5xjtnrdakj7tnhv4kxctttdehhwm30d3h82unvwqhkx6rfvdjx2ctvxyesuk0a27",
|
|
882
1200
|
signer.getAddress(), //Destination address
|
|
883
1201
|
);
|
|
884
1202
|
|
|
@@ -901,52 +1219,71 @@ const marketPrice = swap.getPriceInfo().marketPrice; //Current market price
|
|
|
901
1219
|
const difference = swap.getPriceInfo().difference; //Difference between the swap price & current market price
|
|
902
1220
|
```
|
|
903
1221
|
|
|
904
|
-
|
|
1222
|
+
Executing the swap (simple)
|
|
905
1223
|
|
|
906
1224
|
```typescript
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
//
|
|
911
|
-
|
|
912
|
-
|
|
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
|
+
);
|
|
913
1243
|
```
|
|
914
1244
|
|
|
915
|
-
|
|
1245
|
+
<details>
|
|
1246
|
+
<summary>Manual swap execution (advanced)</summary>
|
|
916
1247
|
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
//
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
```
|
|
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
|
+
```
|
|
932
1263
|
|
|
933
|
-
|
|
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>
|
|
934
1274
|
|
|
935
1275
|
#### Swap Bitcoin lightning network -> Starknet/EVM
|
|
936
1276
|
|
|
937
1277
|
Getting swap quote
|
|
938
1278
|
|
|
939
1279
|
```typescript
|
|
940
|
-
const _lnurl: string = "lnurl1dp68gurn8ghj7ampd3kx2ar0veekzar0wd5xjtnrdakj7tnhv4kxctttdehhwm30d3h82unvwqhkx6rfvdjx2ctvxyesuk0a27"; //Destination LNURL-pay or readable identifier
|
|
941
|
-
const _exactIn = true; //exactIn = true, so we specify the input amount
|
|
942
|
-
const _amount = 10000n; //Amount in BTC base units - sats
|
|
943
|
-
|
|
944
1280
|
const swap = await swapper.swap(
|
|
945
1281
|
Tokens.BITCOIN.BTCLN, //Swap from BTC-LN
|
|
946
1282
|
Tokens.STARKNET.STRK, //Into specified destination token
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
1283
|
+
10000n,
|
|
1284
|
+
SwapAmountType.EXACT_IN, //EXACT_IN, so we specify the input amount
|
|
1285
|
+
//Source LNURL-withdraw link
|
|
1286
|
+
"lnurl1dp68gurn8ghj7ampd3kx2ar0veekzar0wd5xjtnrdakj7tnhv4kxctttdehhwm30d3h82unvwqhkx6rfvdjx2ctvxyesuk0a27",
|
|
950
1287
|
signer.getAddress(), //Destination address
|
|
951
1288
|
{
|
|
952
1289
|
gasAmount: 1_000_000_000_000_000_000n //We can also request a gas drop on the destination chain (here requesting 1 STRK)
|
|
@@ -969,25 +1306,66 @@ const marketPrice = swap.getPriceInfo().marketPrice; //Current market price
|
|
|
969
1306
|
const difference = swap.getPriceInfo().difference; //Difference between the swap price & current market price
|
|
970
1307
|
```
|
|
971
1308
|
|
|
972
|
-
|
|
1309
|
+
|
|
1310
|
+
Executing the swap (simple)
|
|
973
1311
|
|
|
974
1312
|
```typescript
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
}
|
|
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
|
+
}
|
|
1322
|
+
}
|
|
1323
|
+
);
|
|
981
1324
|
|
|
982
|
-
//
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
} catch (e) {
|
|
986
|
-
//Claim ourselves when automatic claim doesn't happen in 30 seconds
|
|
987
|
-
await swap.claim(starknetSigner);
|
|
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);
|
|
988
1328
|
}
|
|
989
1329
|
```
|
|
990
1330
|
|
|
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>
|
|
1368
|
+
|
|
991
1369
|
### Getting state of the swap
|
|
992
1370
|
|
|
993
1371
|
You can get the current state of the swap with:
|
|
@@ -1092,14 +1470,12 @@ Returns swaps that are ready to be claimed by the client, this can happen if cli
|
|
|
1092
1470
|
const claimableSolanaSwaps = await solanaSwapper.getClaimableSwaps("SOLANA", solanaSigner.getAddress());
|
|
1093
1471
|
//Claim all the claimable swaps
|
|
1094
1472
|
for(let swap of claimableSolanaSwaps) {
|
|
1095
|
-
if(swap.canCommit()) await swap.commit(solanaSigner); //This is for Bitcoin (lightning) -> Smart chain swaps, where commit & claim procedure might be needed
|
|
1096
1473
|
await swap.claim(solanaSigner);
|
|
1097
1474
|
}
|
|
1098
1475
|
//Get the swaps
|
|
1099
1476
|
const claimableStarknetSwaps = await solanaSwapper.getClaimableSwaps("STARKNET", starknetSigner.getAddress());
|
|
1100
1477
|
//Claim all the claimable swaps
|
|
1101
1478
|
for(let swap of claimableStarknetSwaps) {
|
|
1102
|
-
if(swap.canCommit()) await swap.commit(starknetSigner); //This is for Bitcoin (lightning) -> Smart chain swaps, where commit & claim procedure might be needed
|
|
1103
1479
|
await swap.claim(starknetSigner);
|
|
1104
1480
|
}
|
|
1105
1481
|
```
|
|
@@ -1188,7 +1564,7 @@ After sending the transactions, you also need to make sure the SDK has enough ti
|
|
|
1188
1564
|
```typescript
|
|
1189
1565
|
//Example for Solana
|
|
1190
1566
|
const txns = await swap.txsCommit(); //Also works with txsClaim, txsRefund, txCommitAndClaim
|
|
1191
|
-
txns.forEach(val => val.tx.sign(...val.signers));
|
|
1567
|
+
txns.forEach(val => if(val.signers.length>0) { val.tx.sign(...val.signers) });
|
|
1192
1568
|
const signedTransactions = await solanaSigner.wallet.signAllTransactions(txns.map(val => val.tx));
|
|
1193
1569
|
for(let tx of signedTransactions) {
|
|
1194
1570
|
const res = await solanaRpc.sendRawTransaction(tx.serialize());
|