@atomiqlabs/sdk 6.0.1 → 7.0.0
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 +818 -274
- package/dist/SmartChainAssets.d.ts +30 -0
- package/dist/SmartChainAssets.js +30 -0
- package/dist/SwapperFactory.d.ts +3 -1
- package/dist/SwapperFactory.js +12 -2
- package/package.json +4 -3
- package/src/SmartChainAssets.ts +30 -0
- package/src/SwapperFactory.ts +16 -2
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
|
|
9
|
+
npm install @atomiqlabs/sdk@next
|
|
10
10
|
```
|
|
11
11
|
|
|
12
12
|
## Installing chain-specific connectors
|
|
@@ -14,8 +14,9 @@ npm install @atomiqlabs/sdk
|
|
|
14
14
|
You can install only the chain-specific connectors that your project requires
|
|
15
15
|
|
|
16
16
|
```
|
|
17
|
-
npm install @atomiqlabs/chain-solana
|
|
18
|
-
npm install @atomiqlabs/chain-starknet
|
|
17
|
+
npm install @atomiqlabs/chain-solana@next
|
|
18
|
+
npm install @atomiqlabs/chain-starknet@next
|
|
19
|
+
npm install @atomiqlabs/chain-evm@next
|
|
19
20
|
```
|
|
20
21
|
|
|
21
22
|
## How to use?
|
|
@@ -26,11 +27,13 @@ npm install @atomiqlabs/chain-starknet
|
|
|
26
27
|
- Swaps:
|
|
27
28
|
- [Smart Chain -> BTC L1](#swap-smart-chain---bitcoin-on-chain)
|
|
28
29
|
- [BTC L1 -> Solana (Old swap protocol)](#swap-bitcoin-on-chain---solana)
|
|
29
|
-
- [BTC L1 -> Starknet (New swap protocol)](#swap-bitcoin-on-chain---
|
|
30
|
+
- [BTC L1 -> Starknet/EVM (New swap protocol)](#swap-bitcoin-on-chain---starknetevm)
|
|
30
31
|
- [Smart Chain -> BTC Lightning network L2](#swap-smart-chain---bitcoin-lightning-network)
|
|
31
32
|
- [Smart Chain -> BTC Lightning network L2 (LNURL-pay)](#swap-smart-chain---bitcoin-lightning-network-1)
|
|
32
|
-
- [BTC Lightning network L2 ->
|
|
33
|
-
- [BTC Lightning network L2 (
|
|
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)
|
|
34
37
|
- [Swap states](#getting-state-of-the-swap)
|
|
35
38
|
- [Swap size limits](#swap-size-limits)
|
|
36
39
|
- [Stored swaps](#stored-swaps)
|
|
@@ -48,7 +51,8 @@ Set Solana & Starknet RPC URL to use
|
|
|
48
51
|
|
|
49
52
|
```typescript
|
|
50
53
|
const solanaRpc = "https://api.mainnet-beta.solana.com";
|
|
51
|
-
const starknetRpc = "https://starknet-mainnet.public.blastapi.io/rpc/
|
|
54
|
+
const starknetRpc = "https://starknet-mainnet.public.blastapi.io/rpc/v0_8";
|
|
55
|
+
const citreaRpc = "https://rpc.testnet.citrea.xyz";
|
|
52
56
|
```
|
|
53
57
|
|
|
54
58
|
Create swapper factory, here we can pick and choose which chains we want to have supported in the SDK, ensure the "as const" keyword is used such that the typescript compiler can properly infer the types.
|
|
@@ -56,9 +60,10 @@ Create swapper factory, here we can pick and choose which chains we want to have
|
|
|
56
60
|
```typescript
|
|
57
61
|
import {SolanaInitializer, SolanaInitializerType} from "@atomiqlabs/chain-solana";
|
|
58
62
|
import {StarknetInitializer, StarknetInitializerType} from "@atomiqlabs/chain-starknet";
|
|
63
|
+
import {CitreaInitializer, CitreaInitializerType} from "@atomiqlabs/chain-evm";
|
|
59
64
|
import {SwapperFactory} from "@atomiqlabs/sdk";
|
|
60
65
|
|
|
61
|
-
const Factory = new SwapperFactory<[SolanaInitializerType, StarknetInitializerType]>([SolanaInitializer, StarknetInitializer] as const);
|
|
66
|
+
const Factory = new SwapperFactory<[SolanaInitializerType, StarknetInitializerType, CitreaInitializerType]>([SolanaInitializer, StarknetInitializer, CitreaInitializer] as const);
|
|
62
67
|
const Tokens = Factory.Tokens; //Get the supported tokens for all the specified chains.
|
|
63
68
|
```
|
|
64
69
|
|
|
@@ -75,7 +80,10 @@ const swapper = Factory.newSwapper({
|
|
|
75
80
|
rpcUrl: solanaRpc //You can also pass Connection object here
|
|
76
81
|
},
|
|
77
82
|
STARKNET: {
|
|
78
|
-
rpcUrl: starknetRpc //You can also pass Provider object here
|
|
83
|
+
rpcUrl: starknetRpc //You can also pass Provider object here
|
|
84
|
+
},
|
|
85
|
+
CITREA: {
|
|
86
|
+
rpcUrl: citreaRpc, //You can also pass JsonApiProvider object here
|
|
79
87
|
}
|
|
80
88
|
},
|
|
81
89
|
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)
|
|
@@ -89,7 +97,7 @@ if you want to use custom pricing api, mempool.space RPC url, or tune HTTP reque
|
|
|
89
97
|
For NodeJS we need to use sqlite storage, for that we first need to install the sqlite storage adaptor
|
|
90
98
|
|
|
91
99
|
```
|
|
92
|
-
npm install @atomiqlabs/storage-sqlite
|
|
100
|
+
npm install @atomiqlabs/storage-sqlite@next
|
|
93
101
|
```
|
|
94
102
|
|
|
95
103
|
Then use pass it in the newSwapper function
|
|
@@ -105,6 +113,9 @@ const swapper = Factory.newSwapper({
|
|
|
105
113
|
},
|
|
106
114
|
STARKNET: {
|
|
107
115
|
rpcUrl: starknetRpc //You can also pass Provider object here
|
|
116
|
+
},
|
|
117
|
+
CITREA: {
|
|
118
|
+
rpcUrl: citreaRpc, //You can also pass JsonApiProvider object here
|
|
108
119
|
}
|
|
109
120
|
},
|
|
110
121
|
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)
|
|
@@ -131,7 +142,7 @@ import {WalletAccount} from "starknet";
|
|
|
131
142
|
import {StarknetSigner} from "@atomiqlabs/chain-starknet";
|
|
132
143
|
//Browser, using get-starknet
|
|
133
144
|
const swo = await connect();
|
|
134
|
-
const wallet = new
|
|
145
|
+
const wallet = new StarknetBrowserSigner(new WalletAccount(starknetRpc, swo.wallet));
|
|
135
146
|
```
|
|
136
147
|
|
|
137
148
|
or
|
|
@@ -144,14 +155,22 @@ const solanaSigner = new SolanaSigner(new SolanaKeypairWallet(Keypair.fromSecret
|
|
|
144
155
|
```
|
|
145
156
|
|
|
146
157
|
```typescript
|
|
147
|
-
import {
|
|
158
|
+
import {StarknetSigner, StarknetKeypairWallet} from "@atomiqlabs/chain-starknet";
|
|
148
159
|
//Creating Starknet signer from private key
|
|
149
160
|
const starknetSigner = new StarknetSigner(new StarknetKeypairWallet(starknetRpc, starknetKey));
|
|
150
161
|
```
|
|
151
162
|
|
|
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
|
+
|
|
152
171
|
### Initialization
|
|
153
172
|
|
|
154
|
-
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
|
|
155
174
|
|
|
156
175
|
```typescript
|
|
157
176
|
await swapper.init();
|
|
@@ -167,12 +186,6 @@ To make it easier to do swaps between bitcoin and a specific chain we can extrac
|
|
|
167
186
|
const solanaSwapper = swapper.withChain<"SOLANA">("SOLANA");
|
|
168
187
|
```
|
|
169
188
|
|
|
170
|
-
or also with signer
|
|
171
|
-
|
|
172
|
-
```typescript
|
|
173
|
-
const starknetSwapperWithSigner = swapper.withChain<"STARKNET">("STARKNET").withSigner(signer);
|
|
174
|
-
```
|
|
175
|
-
|
|
176
189
|
### Bitcoin on-chain swaps
|
|
177
190
|
|
|
178
191
|
#### Swap Smart chain -> Bitcoin on-chain
|
|
@@ -180,18 +193,14 @@ const starknetSwapperWithSigner = swapper.withChain<"STARKNET">("STARKNET").with
|
|
|
180
193
|
Getting swap quote
|
|
181
194
|
|
|
182
195
|
```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
|
-
|
|
187
196
|
//Create the swap: swapping SOL to Bitcoin on-chain, receiving _amount of satoshis (smallest unit of bitcoin) to _address
|
|
188
197
|
const swap = await swapper.swap(
|
|
189
198
|
Tokens.SOLANA.SOL, //From specified source token
|
|
190
199
|
Tokens.BITCOIN.BTC, //Swap to BTC
|
|
191
|
-
|
|
192
|
-
|
|
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
|
|
193
202
|
solanaSigner.getAddress(), //Source address and smart chain signer
|
|
194
|
-
|
|
203
|
+
"bc1qtw67hj77rt8zrkkg3jgngutu0yfgt9czjwusxt" //BTC address of the recipient
|
|
195
204
|
);
|
|
196
205
|
|
|
197
206
|
//Get the amount required to pay and fee
|
|
@@ -210,30 +219,80 @@ const marketPrice = swap.getPriceInfo().marketPrice; //Current market price
|
|
|
210
219
|
const difference = swap.getPriceInfo().difference; //Difference between the swap price & current market price
|
|
211
220
|
```
|
|
212
221
|
|
|
213
|
-
|
|
222
|
+
Executing the swap (simple)
|
|
214
223
|
|
|
215
224
|
```typescript
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
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
|
+
);
|
|
223
239
|
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
const result: boolean = await swap.waitForPayment();
|
|
227
|
-
if(!result) {
|
|
240
|
+
//Refund in case of failure
|
|
241
|
+
if(!swapSuccessful) {
|
|
228
242
|
//Swap failed, money can be refunded
|
|
229
|
-
await swap.refund();
|
|
243
|
+
await swap.refund(solanaSigner);
|
|
230
244
|
} else {
|
|
231
|
-
//Swap successful
|
|
232
|
-
const bitcoinTxId = swap.getBitcoinTxId();
|
|
245
|
+
//Swap successful!
|
|
233
246
|
}
|
|
234
247
|
```
|
|
235
248
|
|
|
236
|
-
|
|
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>
|
|
237
296
|
|
|
238
297
|
- ToBTCSwapState.REFUNDED = -3
|
|
239
298
|
- Swap failed and was successfully refunded
|
|
@@ -252,6 +311,8 @@ if(!result) {
|
|
|
252
311
|
- ToBTCSwapState.REFUNDABLE = 4
|
|
253
312
|
- Swap was initiated but counterparty failed to process it, the user can now refund his funds
|
|
254
313
|
|
|
314
|
+
</details>
|
|
315
|
+
|
|
255
316
|
#### Swap Bitcoin on-chain -> Solana
|
|
256
317
|
|
|
257
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.
|
|
@@ -259,15 +320,12 @@ NOTE: Solana uses an old swap protocol for Bitcoin on-chain -> Solana swaps, the
|
|
|
259
320
|
Getting swap quote
|
|
260
321
|
|
|
261
322
|
```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
|
-
|
|
265
323
|
//Create the swap: swapping _amount of satoshis of Bitcoin on-chain to SOL
|
|
266
324
|
const swap = await swapper.swap(
|
|
267
325
|
Tokens.BITCOIN.BTC, //Swap from BTC
|
|
268
326
|
Tokens.SOLANA.SOL, //Into specified destination token
|
|
269
|
-
|
|
270
|
-
|
|
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
|
|
271
329
|
undefined, //Source address for the swap, not used for swaps from BTC
|
|
272
330
|
solanaSigner.getAddress() //Destination address
|
|
273
331
|
);
|
|
@@ -293,67 +351,123 @@ const marketPrice = swap.getPriceInfo().marketPrice; //Current market price
|
|
|
293
351
|
const difference = swap.getPriceInfo().difference; //Difference between the swap price & current market price
|
|
294
352
|
```
|
|
295
353
|
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
```typescript
|
|
299
|
-
//Initiate the swap on the destination chain (Solana) by opening up the bitcoin swap address
|
|
300
|
-
await swap.commit(solanaSigner);
|
|
301
|
-
```
|
|
302
|
-
|
|
303
|
-
or [sign and send transaction manually](#manually-signing-smart-chain-transactions)
|
|
304
|
-
|
|
305
|
-
Sending bitcoin
|
|
354
|
+
Executing the swap (simple)
|
|
306
355
|
|
|
307
356
|
```typescript
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
//
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
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
|
+
);
|
|
316
387
|
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
for(let signIdx of signInputs) {
|
|
321
|
-
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);
|
|
322
391
|
}
|
|
323
|
-
const bitcoinTxId = await swap.submitPsbt(psbt);
|
|
324
392
|
```
|
|
325
393
|
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
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
|
+
```
|
|
346
466
|
|
|
347
|
-
|
|
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
|
-
```
|
|
467
|
+
</details>
|
|
355
468
|
|
|
356
|
-
|
|
469
|
+
<details>
|
|
470
|
+
<summary>Swap states</summary>
|
|
357
471
|
|
|
358
472
|
- FromBTCSwapState.EXPIRED = -3
|
|
359
473
|
- Bitcoin swap address expired
|
|
@@ -370,23 +484,21 @@ try {
|
|
|
370
484
|
- FromBTCSwapState.CLAIM_CLAIMED = 3
|
|
371
485
|
- Swap funds are claimed to the user's wallet
|
|
372
486
|
|
|
487
|
+
</details>
|
|
373
488
|
|
|
374
|
-
#### Swap Bitcoin on-chain -> Starknet
|
|
489
|
+
#### Swap Bitcoin on-chain -> Starknet/EVM
|
|
375
490
|
|
|
376
|
-
NOTE: Starknet uses a new swap protocol for Bitcoin on-chain ->
|
|
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!
|
|
377
492
|
|
|
378
493
|
Getting swap quote
|
|
379
494
|
|
|
380
495
|
```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
|
-
|
|
384
496
|
//Create the swap: swapping _amount of satoshis of Bitcoin on-chain to SOL
|
|
385
497
|
const swap = await swapper.swap(
|
|
386
498
|
Tokens.BITCOIN.BTC, //Swap from BTC
|
|
387
499
|
Tokens.STARKNET.STRK, //Into specified destination token
|
|
388
|
-
|
|
389
|
-
|
|
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
|
|
390
502
|
undefined, //Source address for the swap, not used for swaps from BTC
|
|
391
503
|
starknetSigner.getAddress(), //Destination address
|
|
392
504
|
{
|
|
@@ -410,62 +522,109 @@ const marketPrice = swap.getPriceInfo().marketPrice; //Current market price
|
|
|
410
522
|
const difference = swap.getPriceInfo().difference; //Difference between the swap price & current market price
|
|
411
523
|
```
|
|
412
524
|
|
|
413
|
-
|
|
525
|
+
Executing the swap (simple)
|
|
414
526
|
|
|
415
527
|
```typescript
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
}
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
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
|
+
);
|
|
425
554
|
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
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);
|
|
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
|
+
}
|
|
436
559
|
```
|
|
437
560
|
|
|
438
|
-
Waiting for swap execution
|
|
439
561
|
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
);
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
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
|
+
```
|
|
458
623
|
|
|
459
|
-
|
|
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
|
-
```
|
|
624
|
+
</details>
|
|
467
625
|
|
|
468
|
-
|
|
626
|
+
<details>
|
|
627
|
+
<summary>Swap states</summary>
|
|
469
628
|
|
|
470
629
|
- SpvFromBTCSwapState.CLOSED = -5
|
|
471
630
|
- Catastrophic failure during swap, shall never happen
|
|
@@ -491,6 +650,8 @@ try {
|
|
|
491
650
|
- Bitcoin swap transaction is confirmed
|
|
492
651
|
- SpvFromBTCSwapState.CLAIM_CLAIMED = 6
|
|
493
652
|
- Swap funds are claimed to the user's wallet
|
|
653
|
+
-
|
|
654
|
+
</details>
|
|
494
655
|
|
|
495
656
|
### Bitcoin lightning network swaps
|
|
496
657
|
|
|
@@ -499,17 +660,15 @@ try {
|
|
|
499
660
|
Getting swap quote
|
|
500
661
|
|
|
501
662
|
```typescript
|
|
502
|
-
//Destination lightning network invoice, amount needs to be part of the invoice!
|
|
503
|
-
const _lightningInvoice = "lnbc10u1pj2q0g9pp5ejs6m677m39cznpzum7muruvh50ys93ln82p4j9ks2luqm56xxlshp52r2anlhddfa9ex9vpw9gstxujff8a0p8s3pzvua930js0kwfea6scqzzsxqyz5vqsp5073zskc5qfgp7lre0t6s8uexxxey80ax564hsjklfwfjq2ew0ewq9qyyssqvzmgs6f8mvuwgfa9uqxhtza07qem4yfhn9wwlpskccmuwplsqmh8pdy6c42kqdu8p73kky9lsnl40qha5396d8lpgn90y27ltfc5rfqqq59cya";
|
|
504
|
-
|
|
505
663
|
//Create the swap: swapping SOL to Bitcoin lightning
|
|
506
664
|
const swap = await swapper.swap(
|
|
507
665
|
Tokens.SOLANA.SOL, //From specified source token
|
|
508
666
|
Tokens.BITCOIN.BTCLN, //Swap to BTC-LN
|
|
509
667
|
undefined, //Amount is specified in the lightning network invoice!
|
|
510
|
-
|
|
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!
|
|
511
669
|
solanaSigner.getAddress(), //Source address and smart chain signer
|
|
512
|
-
|
|
670
|
+
//Destination lightning network invoice, amount needs to be part of the invoice!
|
|
671
|
+
"lnbc10u1pj2q0g9pp5ejs6m677m39cznpzum7muruvh50ys93ln82p4j9ks2luqm56xxlshp52r2anlhddfa9ex9vpw9gstxujff8a0p8s3pzvua930js0kwfea6scqzzsxqyz5vqsp5073zskc5qfgp7lre0t6s8uexxxey80ax564hsjklfwfjq2ew0ewq9qyyssqvzmgs6f8mvuwgfa9uqxhtza07qem4yfhn9wwlpskccmuwplsqmh8pdy6c42kqdu8p73kky9lsnl40qha5396d8lpgn90y27ltfc5rfqqq59cya"
|
|
513
672
|
);
|
|
514
673
|
|
|
515
674
|
//Get the amount required to pay and fee
|
|
@@ -528,30 +687,80 @@ const marketPrice = swap.getPriceInfo().marketPrice; //Current market price
|
|
|
528
687
|
const difference = swap.getPriceInfo().difference; //Difference between the swap price & current market price
|
|
529
688
|
```
|
|
530
689
|
|
|
531
|
-
|
|
690
|
+
Executing the swap (simple)
|
|
532
691
|
|
|
533
692
|
```typescript
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
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
|
+
);
|
|
541
707
|
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
//Swap failed, money can be refunded
|
|
547
|
-
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);
|
|
548
712
|
} else {
|
|
549
|
-
|
|
550
|
-
const lightningSecret = swap.getSecret();
|
|
713
|
+
//Swap successful!
|
|
551
714
|
}
|
|
552
715
|
```
|
|
553
716
|
|
|
554
|
-
|
|
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>
|
|
555
764
|
|
|
556
765
|
- ToBTCSwapState.REFUNDED = -3
|
|
557
766
|
- Swap failed and was successfully refunded
|
|
@@ -570,19 +779,20 @@ if(!result) {
|
|
|
570
779
|
- ToBTCSwapState.REFUNDABLE = 4
|
|
571
780
|
- Swap was initiated but counterparty failed to process it, the user can now refund his funds
|
|
572
781
|
|
|
573
|
-
|
|
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.
|
|
574
787
|
|
|
575
788
|
Getting swap quote
|
|
576
789
|
|
|
577
790
|
```typescript
|
|
578
|
-
const _exactIn = true; //exactIn = true, so we specify the input amount
|
|
579
|
-
const _amount = 10000n; //Amount in BTC base units - sats
|
|
580
|
-
|
|
581
791
|
const swap = await swapper.swap(
|
|
582
792
|
Tokens.BITCOIN.BTCLN, //Swap from BTC-LN
|
|
583
|
-
Tokens.
|
|
584
|
-
|
|
585
|
-
|
|
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
|
|
586
796
|
undefined, //Source address for the swap, not used for swaps from BTC-LN
|
|
587
797
|
signer.getAddress() //Destination address
|
|
588
798
|
);
|
|
@@ -611,40 +821,72 @@ const marketPrice = swap.getPriceInfo().marketPrice; //Current market price
|
|
|
611
821
|
const difference = swap.getPriceInfo().difference; //Difference between the swap price & current market price
|
|
612
822
|
```
|
|
613
823
|
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
Wait for the payment to be received
|
|
824
|
+
Executing the swap (simple)
|
|
617
825
|
|
|
618
826
|
```typescript
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
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
|
+
);
|
|
625
851
|
```
|
|
626
852
|
|
|
627
|
-
|
|
853
|
+
<details>
|
|
854
|
+
<summary>Manual swap execution (advanced)</summary>
|
|
628
855
|
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
}
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
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
|
+
```
|
|
876
|
+
|
|
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
|
+
```
|
|
644
885
|
|
|
645
|
-
|
|
886
|
+
</details>
|
|
646
887
|
|
|
647
|
-
|
|
888
|
+
<details>
|
|
889
|
+
<summary>Swap states</summary>
|
|
648
890
|
|
|
649
891
|
- FromBTCLNSwapState.FAILED = -4
|
|
650
892
|
- If the claiming of the funds was initiated, but never concluded, the user will get his lightning network payment refunded
|
|
@@ -663,6 +905,138 @@ or [sign and send transactions manually](#manually-signing-smart-chain-transacti
|
|
|
663
905
|
- FromBTCLNSwapState.CLAIM_CLAIMED = 3
|
|
664
906
|
- Funds were successfully claimed & lightning network secret pre-image revealed, so the lightning network payment will settle now
|
|
665
907
|
|
|
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
|
+
|
|
666
1040
|
### LNURLs & readable lightning identifiers
|
|
667
1041
|
|
|
668
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)
|
|
@@ -695,18 +1069,15 @@ LNURLs & lightning identifiers:
|
|
|
695
1069
|
Getting swap quote
|
|
696
1070
|
|
|
697
1071
|
```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
|
-
|
|
702
1072
|
//Create the swap: swapping SOL to Bitcoin lightning
|
|
703
1073
|
const swap = await swapper.swap(
|
|
704
1074
|
Tokens.SOLANA.SOL, //From specified source token
|
|
705
1075
|
Tokens.BITCOIN.BTCLN, //Swap to BTC-LN
|
|
706
|
-
|
|
707
|
-
|
|
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
|
|
708
1078
|
solanaSigner.getAddress(), //Source address and smart chain signer
|
|
709
|
-
|
|
1079
|
+
//Destination LNURL-pay or readable identifier
|
|
1080
|
+
"lnurl1dp68gurn8ghj7ampd3kx2ar0veekzar0wd5xjtnrdakj7tnhv4kxctttdehhwm30d3h82unvwqhkx6rfvdjx2ctvxyesuk0a27",
|
|
710
1081
|
{
|
|
711
1082
|
comment: "Hello world" //For LNURL-pay we can also pass a comment to the recipient
|
|
712
1083
|
}
|
|
@@ -728,53 +1099,105 @@ const marketPrice = swap.getPriceInfo().marketPrice; //Current market price
|
|
|
728
1099
|
const difference = swap.getPriceInfo().difference; //Difference between the swap price & current market price
|
|
729
1100
|
```
|
|
730
1101
|
|
|
731
|
-
|
|
1102
|
+
|
|
1103
|
+
Executing the swap (simple)
|
|
732
1104
|
|
|
733
1105
|
```typescript
|
|
734
|
-
|
|
735
|
-
|
|
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
|
+
}
|
|
736
1138
|
```
|
|
737
1139
|
|
|
738
|
-
|
|
1140
|
+
<details>
|
|
1141
|
+
<summary>Manual swap execution (advanced)</summary>
|
|
739
1142
|
|
|
740
|
-
|
|
1143
|
+
- __1.__ Initiate the swap on the smart-chain side
|
|
741
1144
|
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
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;
|
|
758
1172
|
}
|
|
759
|
-
|
|
760
|
-
|
|
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>
|
|
1185
|
+
|
|
1186
|
+
#### Swap Bitcoin lightning network -> Solana
|
|
761
1187
|
|
|
762
|
-
|
|
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.
|
|
763
1189
|
|
|
764
1190
|
Getting swap quote
|
|
765
1191
|
|
|
766
1192
|
```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
|
-
|
|
771
1193
|
const swap = await swapper.swap(
|
|
772
1194
|
Tokens.BITCOIN.BTCLN, //Swap from BTC-LN
|
|
773
|
-
Tokens.
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
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
|
|
778
1201
|
);
|
|
779
1202
|
|
|
780
1203
|
//Get the amount required to pay and fee
|
|
@@ -796,36 +1219,152 @@ const marketPrice = swap.getPriceInfo().marketPrice; //Current market price
|
|
|
796
1219
|
const difference = swap.getPriceInfo().difference; //Difference between the swap price & current market price
|
|
797
1220
|
```
|
|
798
1221
|
|
|
799
|
-
|
|
1222
|
+
Executing the swap (simple)
|
|
800
1223
|
|
|
801
1224
|
```typescript
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
//
|
|
806
|
-
|
|
807
|
-
|
|
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
|
+
);
|
|
808
1243
|
```
|
|
809
1244
|
|
|
810
|
-
|
|
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
|
|
811
1278
|
|
|
812
1279
|
```typescript
|
|
813
|
-
|
|
814
|
-
//
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
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
|
|
1307
|
+
```
|
|
1308
|
+
|
|
1309
|
+
|
|
1310
|
+
Executing the swap (simple)
|
|
1311
|
+
|
|
1312
|
+
```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
|
+
}
|
|
822
1322
|
}
|
|
823
|
-
|
|
824
|
-
|
|
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);
|
|
825
1328
|
}
|
|
826
1329
|
```
|
|
827
1330
|
|
|
828
|
-
|
|
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>
|
|
829
1368
|
|
|
830
1369
|
### Getting state of the swap
|
|
831
1370
|
|
|
@@ -931,14 +1470,12 @@ Returns swaps that are ready to be claimed by the client, this can happen if cli
|
|
|
931
1470
|
const claimableSolanaSwaps = await solanaSwapper.getClaimableSwaps("SOLANA", solanaSigner.getAddress());
|
|
932
1471
|
//Claim all the claimable swaps
|
|
933
1472
|
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
|
|
935
1473
|
await swap.claim(solanaSigner);
|
|
936
1474
|
}
|
|
937
1475
|
//Get the swaps
|
|
938
1476
|
const claimableStarknetSwaps = await solanaSwapper.getClaimableSwaps("STARKNET", starknetSigner.getAddress());
|
|
939
1477
|
//Claim all the claimable swaps
|
|
940
1478
|
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
|
|
942
1479
|
await swap.claim(starknetSigner);
|
|
943
1480
|
}
|
|
944
1481
|
```
|
|
@@ -1027,7 +1564,7 @@ After sending the transactions, you also need to make sure the SDK has enough ti
|
|
|
1027
1564
|
```typescript
|
|
1028
1565
|
//Example for Solana
|
|
1029
1566
|
const txns = await swap.txsCommit(); //Also works with txsClaim, txsRefund, txCommitAndClaim
|
|
1030
|
-
txns.forEach(val => val.tx.sign(...val.signers));
|
|
1567
|
+
txns.forEach(val => if(val.signers.length>0) { val.tx.sign(...val.signers) });
|
|
1031
1568
|
const signedTransactions = await solanaSigner.wallet.signAllTransactions(txns.map(val => val.tx));
|
|
1032
1569
|
for(let tx of signedTransactions) {
|
|
1033
1570
|
const res = await solanaRpc.sendRawTransaction(tx.serialize());
|
|
@@ -1042,6 +1579,13 @@ for(let tx of txns) {
|
|
|
1042
1579
|
if(tx.type==="DEPLOY_ACCOUNT") await starknetSigner.account.deployAccount(tx.tx, tx.details);
|
|
1043
1580
|
}
|
|
1044
1581
|
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
|
|
1045
1589
|
```
|
|
1046
1590
|
|
|
1047
1591
|
### Additional swapper options
|