@atomiqlabs/sdk 8.4.4 → 8.5.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 +8 -8
- package/dist/enums/SwapSide.d.ts +15 -0
- package/dist/enums/SwapSide.js +19 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/intermediaries/apis/IntermediaryAPI.d.ts +2 -2
- package/dist/intermediaries/apis/IntermediaryAPI.js +2 -2
- package/dist/storage/UnifiedSwapStorage.d.ts +2 -0
- package/dist/swapper/Swapper.d.ts +27 -21
- package/dist/swapper/Swapper.js +19 -26
- package/dist/swapper/SwapperWithChain.d.ts +14 -18
- package/dist/swapper/SwapperWithChain.js +2 -2
- package/dist/swapper/SwapperWithSigner.d.ts +9 -13
- package/dist/swaps/IBTCWalletSwap.d.ts +1 -1
- package/dist/swaps/ISwap.js +2 -0
- package/dist/swaps/ISwapWithGasDrop.d.ts +1 -1
- package/dist/swaps/ISwapWrapper.d.ts +12 -12
- package/dist/swaps/ISwapWrapper.js +22 -14
- package/dist/swaps/escrow_swaps/IEscrowSelfInitSwap.d.ts +3 -3
- package/dist/swaps/escrow_swaps/frombtc/IFromBTCSelfInitSwap.d.ts +8 -8
- package/dist/swaps/escrow_swaps/frombtc/ln/FromBTCLNSwap.d.ts +5 -5
- package/dist/swaps/escrow_swaps/frombtc/ln/FromBTCLNWrapper.d.ts +23 -2
- package/dist/swaps/escrow_swaps/frombtc/ln/FromBTCLNWrapper.js +20 -17
- package/dist/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoSwap.d.ts +4 -4
- package/dist/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoWrapper.d.ts +44 -3
- package/dist/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoWrapper.js +9 -14
- package/dist/swaps/escrow_swaps/frombtc/onchain/FromBTCSwap.d.ts +3 -3
- package/dist/swaps/escrow_swaps/frombtc/onchain/FromBTCWrapper.d.ts +20 -2
- package/dist/swaps/escrow_swaps/frombtc/onchain/FromBTCWrapper.js +15 -8
- package/dist/swaps/escrow_swaps/tobtc/IToBTCSwap.d.ts +7 -7
- package/dist/swaps/escrow_swaps/tobtc/ln/ToBTCLNSwap.d.ts +1 -1
- package/dist/swaps/escrow_swaps/tobtc/ln/ToBTCLNWrapper.d.ts +52 -6
- package/dist/swaps/escrow_swaps/tobtc/ln/ToBTCLNWrapper.js +20 -30
- package/dist/swaps/escrow_swaps/tobtc/onchain/ToBTCSwap.d.ts +1 -1
- package/dist/swaps/escrow_swaps/tobtc/onchain/ToBTCWrapper.d.ts +6 -0
- package/dist/swaps/spv_swaps/SpvFromBTCSwap.d.ts +6 -6
- package/dist/swaps/spv_swaps/SpvFromBTCWrapper.d.ts +32 -1
- package/dist/swaps/spv_swaps/SpvFromBTCWrapper.js +8 -5
- package/dist/swaps/trusted/ln/LnForGasSwap.d.ts +3 -3
- package/dist/swaps/trusted/onchain/OnchainForGasSwap.d.ts +4 -4
- package/dist/types/Token.d.ts +65 -25
- package/dist/types/Token.js +28 -13
- package/dist/types/TokenAmount.d.ts +2 -2
- package/dist/types/fees/Fee.d.ts +3 -3
- package/dist/utils/Utils.d.ts +1 -0
- package/dist/utils/Utils.js +17 -1
- package/package.json +1 -1
- package/src/enums/SwapSide.ts +16 -0
- package/src/index.ts +1 -0
- package/src/intermediaries/apis/IntermediaryAPI.ts +4 -4
- package/src/storage/UnifiedSwapStorage.ts +2 -0
- package/src/swapper/Swapper.ts +46 -37
- package/src/swapper/SwapperWithChain.ts +15 -10
- package/src/swapper/SwapperWithSigner.ts +8 -3
- package/src/swaps/IBTCWalletSwap.ts +1 -1
- package/src/swaps/ISwap.ts +2 -0
- package/src/swaps/ISwapWithGasDrop.ts +1 -1
- package/src/swaps/ISwapWrapper.ts +24 -23
- package/src/swaps/escrow_swaps/IEscrowSelfInitSwap.ts +3 -3
- package/src/swaps/escrow_swaps/frombtc/IFromBTCSelfInitSwap.ts +8 -8
- package/src/swaps/escrow_swaps/frombtc/ln/FromBTCLNSwap.ts +5 -5
- package/src/swaps/escrow_swaps/frombtc/ln/FromBTCLNWrapper.ts +48 -22
- package/src/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoSwap.ts +4 -4
- package/src/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoWrapper.ts +56 -20
- package/src/swaps/escrow_swaps/frombtc/onchain/FromBTCSwap.ts +3 -3
- package/src/swaps/escrow_swaps/frombtc/onchain/FromBTCWrapper.ts +57 -22
- package/src/swaps/escrow_swaps/tobtc/IToBTCSwap.ts +7 -7
- package/src/swaps/escrow_swaps/tobtc/ln/ToBTCLNSwap.ts +1 -1
- package/src/swaps/escrow_swaps/tobtc/ln/ToBTCLNWrapper.ts +80 -37
- package/src/swaps/escrow_swaps/tobtc/onchain/ToBTCSwap.ts +1 -1
- package/src/swaps/escrow_swaps/tobtc/onchain/ToBTCWrapper.ts +12 -3
- package/src/swaps/spv_swaps/SpvFromBTCSwap.ts +6 -6
- package/src/swaps/spv_swaps/SpvFromBTCWrapper.ts +53 -11
- package/src/swaps/trusted/ln/LnForGasSwap.ts +3 -3
- package/src/swaps/trusted/onchain/OnchainForGasSwap.ts +4 -4
- package/src/types/Token.ts +98 -32
- package/src/types/TokenAmount.ts +5 -7
- package/src/types/fees/Fee.ts +3 -3
- package/src/utils/Utils.ts +18 -2
|
@@ -10,6 +10,8 @@ import {UnifiedSwapStorage} from "../storage/UnifiedSwapStorage";
|
|
|
10
10
|
import {SCToken} from "../types/Token";
|
|
11
11
|
import {getLogger} from "../utils/Logger";
|
|
12
12
|
import {PriceInfoType} from "../types/PriceInfoType";
|
|
13
|
+
import {fromHumanReadableString} from "../utils/TokenUtils";
|
|
14
|
+
import {UserError} from "../errors/UserError";
|
|
13
15
|
|
|
14
16
|
/**
|
|
15
17
|
* Options for swap wrapper configuration
|
|
@@ -26,15 +28,9 @@ export type ISwapWrapperOptions = {
|
|
|
26
28
|
*
|
|
27
29
|
* @category Swaps/Base
|
|
28
30
|
*/
|
|
29
|
-
export type WrapperCtorTokens<T extends
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
chains: {[chainId in ChainIds<T>]?: {
|
|
33
|
-
address: string,
|
|
34
|
-
decimals: number,
|
|
35
|
-
displayDecimals?: number
|
|
36
|
-
}}
|
|
37
|
-
}[];
|
|
31
|
+
export type WrapperCtorTokens<T extends ChainType = ChainType> = {
|
|
32
|
+
[tokenAddress: string]: SCToken<T["ChainId"]>
|
|
33
|
+
};
|
|
38
34
|
|
|
39
35
|
/**
|
|
40
36
|
* Type definition linking wrapper and swap types
|
|
@@ -164,22 +160,27 @@ export abstract class ISwapWrapper<
|
|
|
164
160
|
this._prices = prices;
|
|
165
161
|
this.events = events || new EventEmitter();
|
|
166
162
|
this._options = options;
|
|
167
|
-
this._tokens =
|
|
168
|
-
for(let tokenData of tokens) {
|
|
169
|
-
const chainData = tokenData.chains[chainIdentifier];
|
|
170
|
-
if(chainData==null) continue;
|
|
171
|
-
this._tokens[chainData.address] = {
|
|
172
|
-
chain: "SC",
|
|
173
|
-
chainId: this.chainIdentifier,
|
|
174
|
-
address: chainData.address,
|
|
175
|
-
decimals: chainData.decimals,
|
|
176
|
-
ticker: tokenData.ticker,
|
|
177
|
-
name: tokenData.name,
|
|
178
|
-
displayDecimals: chainData.displayDecimals
|
|
179
|
-
};
|
|
180
|
-
}
|
|
163
|
+
this._tokens = tokens;
|
|
181
164
|
}
|
|
182
165
|
|
|
166
|
+
/**
|
|
167
|
+
* Parses the provided gas amount from its `string` or `bigint` representation to `bigint` base units.
|
|
168
|
+
*
|
|
169
|
+
* Defaults to `0n` if no gasAmount is provided
|
|
170
|
+
*
|
|
171
|
+
* @param gasAmount
|
|
172
|
+
* @internal
|
|
173
|
+
*/
|
|
174
|
+
protected parseGasAmount(gasAmount?: string | bigint): bigint {
|
|
175
|
+
let result: bigint | undefined | null;
|
|
176
|
+
if(typeof(gasAmount)==="string") {
|
|
177
|
+
result = fromHumanReadableString(gasAmount, this._getNativeToken());
|
|
178
|
+
if(result==null) throw new UserError("Invalid `gasAmount` option provided, not a numerical string!");
|
|
179
|
+
} else {
|
|
180
|
+
result = gasAmount;
|
|
181
|
+
}
|
|
182
|
+
return result ?? 0n;
|
|
183
|
+
}
|
|
183
184
|
|
|
184
185
|
/**
|
|
185
186
|
* Pre-fetches swap price for a given swap
|
|
@@ -112,7 +112,7 @@ export abstract class IEscrowSelfInitSwap<
|
|
|
112
112
|
/**
|
|
113
113
|
* Returns the transaction fee paid on the smart chain side to initiate the escrow
|
|
114
114
|
*/
|
|
115
|
-
async getSmartChainNetworkFee(): Promise<TokenAmount<
|
|
115
|
+
async getSmartChainNetworkFee(): Promise<TokenAmount<SCToken<T["ChainId"]>, true>> {
|
|
116
116
|
const swapContract: T["Contract"] = this.wrapper._contract;
|
|
117
117
|
return toTokenAmount(
|
|
118
118
|
await (
|
|
@@ -131,8 +131,8 @@ export abstract class IEscrowSelfInitSwap<
|
|
|
131
131
|
*/
|
|
132
132
|
abstract hasEnoughForTxFees(): Promise<{
|
|
133
133
|
enoughBalance: boolean,
|
|
134
|
-
balance: TokenAmount<
|
|
135
|
-
required: TokenAmount<
|
|
134
|
+
balance: TokenAmount<SCToken<T["ChainId"]>, true>,
|
|
135
|
+
required: TokenAmount<SCToken<T["ChainId"]>, true>
|
|
136
136
|
}>;
|
|
137
137
|
|
|
138
138
|
|
|
@@ -169,19 +169,19 @@ export abstract class IFromBTCSelfInitSwap<
|
|
|
169
169
|
/**
|
|
170
170
|
* @inheritDoc
|
|
171
171
|
*/
|
|
172
|
-
getOutput(): TokenAmount<
|
|
172
|
+
getOutput(): TokenAmount<SCToken<T["ChainId"]>, true> {
|
|
173
173
|
return toTokenAmount(this.getSwapData().getAmount(), this.wrapper._tokens[this.getSwapData().getToken()], this.wrapper._prices, this.pricingInfo);
|
|
174
174
|
}
|
|
175
175
|
|
|
176
176
|
/**
|
|
177
177
|
* @inheritDoc
|
|
178
178
|
*/
|
|
179
|
-
abstract getInput(): TokenAmount<
|
|
179
|
+
abstract getInput(): TokenAmount<BtcToken>;
|
|
180
180
|
|
|
181
181
|
/**
|
|
182
182
|
* @inheritDoc
|
|
183
183
|
*/
|
|
184
|
-
getInputWithoutFee(): TokenAmount<
|
|
184
|
+
getInputWithoutFee(): TokenAmount<BtcToken> {
|
|
185
185
|
const input = this.getInput();
|
|
186
186
|
if(input.rawAmount==null) return toTokenAmount(null, this.inputToken, this.wrapper._prices, this.pricingInfo);
|
|
187
187
|
return toTokenAmount(input.rawAmount - this.swapFeeBtc, this.inputToken, this.wrapper._prices, this.pricingInfo);
|
|
@@ -192,8 +192,8 @@ export abstract class IFromBTCSelfInitSwap<
|
|
|
192
192
|
*/
|
|
193
193
|
async hasEnoughForTxFees(): Promise<{
|
|
194
194
|
enoughBalance: boolean,
|
|
195
|
-
balance: TokenAmount<
|
|
196
|
-
required: TokenAmount<
|
|
195
|
+
balance: TokenAmount<SCToken<T["ChainId"]>, true>,
|
|
196
|
+
required: TokenAmount<SCToken<T["ChainId"]>, true>
|
|
197
197
|
}> {
|
|
198
198
|
const [balance, commitFee] = await Promise.all([
|
|
199
199
|
this.wrapper._contract.getBalance(this._getInitiator(), this.wrapper._chain.getNativeCurrencyAddress(), false),
|
|
@@ -212,7 +212,7 @@ export abstract class IFromBTCSelfInitSwap<
|
|
|
212
212
|
* to act as a security deposit that can be taken by the intermediary (LP) if the user doesn't go through
|
|
213
213
|
* with the swap
|
|
214
214
|
*/
|
|
215
|
-
getSecurityDeposit(): TokenAmount<
|
|
215
|
+
getSecurityDeposit(): TokenAmount<SCToken<T["ChainId"]>, true> {
|
|
216
216
|
return toTokenAmount(this.getSwapData().getSecurityDeposit(), this.wrapper._getNativeToken(), this.wrapper._prices, this.pricingInfo);
|
|
217
217
|
}
|
|
218
218
|
|
|
@@ -221,7 +221,7 @@ export abstract class IFromBTCSelfInitSwap<
|
|
|
221
221
|
* This covers the security deposit and the watchtower fee (if applicable), it is calculated a maximum of those
|
|
222
222
|
* two values.
|
|
223
223
|
*/
|
|
224
|
-
getTotalDeposit(): TokenAmount<
|
|
224
|
+
getTotalDeposit(): TokenAmount<SCToken<T["ChainId"]>, true> {
|
|
225
225
|
return toTokenAmount(this.getSwapData().getTotalDeposit(), this.wrapper._getNativeToken(), this.wrapper._prices, this.pricingInfo);
|
|
226
226
|
}
|
|
227
227
|
|
|
@@ -273,7 +273,7 @@ export abstract class IFromBTCSelfInitSwap<
|
|
|
273
273
|
* Returns the transaction fee required for the claim transaction to settle the escrow on the destination
|
|
274
274
|
* smart chain
|
|
275
275
|
*/
|
|
276
|
-
async getClaimNetworkFee(): Promise<TokenAmount<
|
|
276
|
+
async getClaimNetworkFee(): Promise<TokenAmount<SCToken<T["ChainId"]>, true>> {
|
|
277
277
|
const swapContract: T["Contract"] = this.wrapper._contract;
|
|
278
278
|
return toTokenAmount(
|
|
279
279
|
await swapContract.getClaimFee(this._getInitiator(), this.getSwapData()),
|
|
@@ -448,7 +448,7 @@ export class FromBTCLNSwap<T extends ChainType = ChainType>
|
|
|
448
448
|
/**
|
|
449
449
|
* @inheritDoc
|
|
450
450
|
*/
|
|
451
|
-
getInput(): TokenAmount<
|
|
451
|
+
getInput(): TokenAmount<BtcToken<true>> {
|
|
452
452
|
if(this.pr==null || !this.pr.toLowerCase().startsWith("ln"))
|
|
453
453
|
return toTokenAmount(null, this.inputToken, this.wrapper._prices, this.pricingInfo);
|
|
454
454
|
|
|
@@ -461,7 +461,7 @@ export class FromBTCLNSwap<T extends ChainType = ChainType>
|
|
|
461
461
|
/**
|
|
462
462
|
* @inheritDoc
|
|
463
463
|
*/
|
|
464
|
-
getSmartChainNetworkFee(): Promise<TokenAmount<
|
|
464
|
+
getSmartChainNetworkFee(): Promise<TokenAmount<SCToken<T["ChainId"]>, true>> {
|
|
465
465
|
return this.getCommitAndClaimNetworkFee();
|
|
466
466
|
}
|
|
467
467
|
|
|
@@ -470,8 +470,8 @@ export class FromBTCLNSwap<T extends ChainType = ChainType>
|
|
|
470
470
|
*/
|
|
471
471
|
async hasEnoughForTxFees(): Promise<{
|
|
472
472
|
enoughBalance: boolean,
|
|
473
|
-
balance: TokenAmount<
|
|
474
|
-
required: TokenAmount<
|
|
473
|
+
balance: TokenAmount<SCToken<T["ChainId"]>, true>,
|
|
474
|
+
required: TokenAmount<SCToken<T["ChainId"]>, true>
|
|
475
475
|
}> {
|
|
476
476
|
const [balance, feeRate] = await Promise.all([
|
|
477
477
|
this.wrapper._contract.getBalance(this._getInitiator(), this.wrapper._chain.getNativeCurrencyAddress(), false),
|
|
@@ -1082,7 +1082,7 @@ export class FromBTCLNSwap<T extends ChainType = ChainType>
|
|
|
1082
1082
|
* Estimated transaction fee for commit & claim transactions combined, required
|
|
1083
1083
|
* to settle the swap on the smart chain destination side.
|
|
1084
1084
|
*/
|
|
1085
|
-
async getCommitAndClaimNetworkFee(): Promise<TokenAmount<
|
|
1085
|
+
async getCommitAndClaimNetworkFee(): Promise<TokenAmount<SCToken<T["ChainId"]>, true>> {
|
|
1086
1086
|
const swapContract: T["Contract"] = this.wrapper._contract;
|
|
1087
1087
|
const feeRate = this.feeRate ?? await swapContract.getInitFeeRate(
|
|
1088
1088
|
this.getSwapData().getOfferer(),
|
|
@@ -13,7 +13,7 @@ import {UserError} from "../../../../errors/UserError";
|
|
|
13
13
|
import {IntermediaryError} from "../../../../errors/IntermediaryError";
|
|
14
14
|
import {SwapType} from "../../../../enums/SwapType";
|
|
15
15
|
import {
|
|
16
|
-
extendAbortController,
|
|
16
|
+
extendAbortController, parseHashValueExact32Bytes,
|
|
17
17
|
throwIfUndefined
|
|
18
18
|
} from "../../../../utils/Utils";
|
|
19
19
|
import {FromBTCLNResponseType, IntermediaryAPI} from "../../../../intermediaries/apis/IntermediaryAPI";
|
|
@@ -33,9 +33,30 @@ import {AllOptional} from "../../../../utils/TypeUtils";
|
|
|
33
33
|
import {sha256} from "@noble/hashes/sha2";
|
|
34
34
|
|
|
35
35
|
export type FromBTCLNOptions = {
|
|
36
|
-
|
|
36
|
+
/**
|
|
37
|
+
* Instead of letting the SDK generate the preimage/paymentHash pair internally you can pass your computed
|
|
38
|
+
* paymentHash here, this will create the swap with the provided payment hash. Note that you would then
|
|
39
|
+
* have to reveal the preimage by passing it to the {@link FromBTCLNSwap.claim} or {@link FromBTCLNSwap.txsClaim}
|
|
40
|
+
* functions
|
|
41
|
+
*
|
|
42
|
+
* Accepts both, a {@link Buffer} and a hexadecimal `string`
|
|
43
|
+
*/
|
|
44
|
+
paymentHash?: Buffer | string,
|
|
45
|
+
/**
|
|
46
|
+
* Optional description to use for the swap lightning network invoice, keep the invoice length below 500 characters
|
|
47
|
+
*/
|
|
37
48
|
description?: string,
|
|
38
|
-
|
|
49
|
+
/**
|
|
50
|
+
* Optional description hash to use for the lightning network invoice, useful when returning the invoice as part of
|
|
51
|
+
* an LNURL-pay service endpoint.
|
|
52
|
+
*
|
|
53
|
+
* Accepts both, a {@link Buffer} and a hexadecimal `string`
|
|
54
|
+
*/
|
|
55
|
+
descriptionHash?: Buffer | string,
|
|
56
|
+
/**
|
|
57
|
+
* A flag to skip checking whether the lightning network node of the LP has enough channel liquidity to facilitate
|
|
58
|
+
* the swap.
|
|
59
|
+
*/
|
|
39
60
|
unsafeSkipLnNodeCheck?: boolean
|
|
40
61
|
};
|
|
41
62
|
|
|
@@ -179,7 +200,10 @@ export class FromBTCLNWrapper<
|
|
|
179
200
|
resp: FromBTCLNResponseType,
|
|
180
201
|
amountData: AmountData,
|
|
181
202
|
lp: Intermediary,
|
|
182
|
-
options:
|
|
203
|
+
options: {
|
|
204
|
+
descriptionHash?: Buffer,
|
|
205
|
+
description?: string
|
|
206
|
+
},
|
|
183
207
|
decodedPr: PaymentRequestObject & {tagsObject: TagsObject},
|
|
184
208
|
paymentHash: Buffer
|
|
185
209
|
): void {
|
|
@@ -238,22 +262,20 @@ export class FromBTCLNWrapper<
|
|
|
238
262
|
}[] {
|
|
239
263
|
if(!this.isInitialized) throw new Error("Not initialized, call init() first!");
|
|
240
264
|
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
if(options.descriptionHash!=null && options.descriptionHash.length!==32)
|
|
248
|
-
throw new UserError("Invalid description hash length");
|
|
265
|
+
const _options = {
|
|
266
|
+
paymentHash: parseHashValueExact32Bytes(options?.paymentHash, "payment hash"),
|
|
267
|
+
description: options?.description,
|
|
268
|
+
descriptionHash: parseHashValueExact32Bytes(options?.descriptionHash, "description hash"),
|
|
269
|
+
unsafeSkipLnNodeCheck: options?.unsafeSkipLnNodeCheck ?? this._options.unsafeSkipLnNodeCheck
|
|
270
|
+
};
|
|
249
271
|
|
|
250
|
-
if(
|
|
272
|
+
if(_options.description!=null && Buffer.byteLength(_options.description, "utf8") > 500)
|
|
251
273
|
throw new UserError("Invalid description length");
|
|
252
274
|
|
|
253
275
|
let secret: Buffer | undefined;
|
|
254
276
|
let paymentHash: Buffer;
|
|
255
|
-
if(
|
|
256
|
-
paymentHash =
|
|
277
|
+
if(_options.paymentHash!=null) {
|
|
278
|
+
paymentHash = _options.paymentHash;
|
|
257
279
|
} else {
|
|
258
280
|
({secret, paymentHash} = this.getSecretAndHash());
|
|
259
281
|
}
|
|
@@ -286,8 +308,8 @@ export class FromBTCLNWrapper<
|
|
|
286
308
|
amount: amountData.amount,
|
|
287
309
|
claimer: recipient,
|
|
288
310
|
token: amountData.token.toString(),
|
|
289
|
-
description:
|
|
290
|
-
descriptionHash:
|
|
311
|
+
description: _options.description,
|
|
312
|
+
descriptionHash: _options.descriptionHash,
|
|
291
313
|
exactOut: !amountData.exactIn,
|
|
292
314
|
feeRate: throwIfUndefined(_preFetches.feeRatePromise),
|
|
293
315
|
additionalParams
|
|
@@ -296,7 +318,7 @@ export class FromBTCLNWrapper<
|
|
|
296
318
|
);
|
|
297
319
|
|
|
298
320
|
return {
|
|
299
|
-
lnCapacityPromise:
|
|
321
|
+
lnCapacityPromise: _options.unsafeSkipLnNodeCheck ? null : this.preFetchLnCapacity(lnPublicKey),
|
|
300
322
|
resp: await response
|
|
301
323
|
};
|
|
302
324
|
}, undefined, RequestError, abortController.signal);
|
|
@@ -307,7 +329,7 @@ export class FromBTCLNWrapper<
|
|
|
307
329
|
const amountIn = (BigInt(decodedPr.millisatoshis) + 999n) / 1000n;
|
|
308
330
|
|
|
309
331
|
try {
|
|
310
|
-
this.verifyReturnedData(resp, amountData, lp,
|
|
332
|
+
this.verifyReturnedData(resp, amountData, lp, _options, decodedPr, paymentHash);
|
|
311
333
|
const [pricingInfo] = await Promise.all([
|
|
312
334
|
this.verifyReturnedPrice(
|
|
313
335
|
lp.services[SwapType.FROM_BTCLN], false, amountIn, resp.total,
|
|
@@ -374,8 +396,12 @@ export class FromBTCLNWrapper<
|
|
|
374
396
|
}[]> {
|
|
375
397
|
if(!this.isInitialized) throw new Error("Not initialized, call init() first!");
|
|
376
398
|
|
|
377
|
-
|
|
378
|
-
|
|
399
|
+
const _options = {
|
|
400
|
+
paymentHash: parseHashValueExact32Bytes(options?.paymentHash, "payment hash"),
|
|
401
|
+
description: options?.description,
|
|
402
|
+
descriptionHash: parseHashValueExact32Bytes(options?.descriptionHash, "description hash"),
|
|
403
|
+
unsafeSkipLnNodeCheck: options?.unsafeSkipLnNodeCheck ?? this._options.unsafeSkipLnNodeCheck
|
|
404
|
+
};
|
|
379
405
|
|
|
380
406
|
const abortController = extendAbortController(abortSignal);
|
|
381
407
|
const preFetches = {
|
|
@@ -408,7 +434,7 @@ export class FromBTCLNWrapper<
|
|
|
408
434
|
if((amount * 105n / 100n) > max) throw new UserError("Amount more than LNURL-withdraw maximum");
|
|
409
435
|
}
|
|
410
436
|
|
|
411
|
-
return this.create(recipient, amountData, lps,
|
|
437
|
+
return this.create(recipient, amountData, lps, _options, additionalParams, abortSignal, preFetches).map(data => {
|
|
412
438
|
return {
|
|
413
439
|
quote: data.quote.then(quote => {
|
|
414
440
|
quote._setLNURLData(
|
|
@@ -589,14 +589,14 @@ export class FromBTCLNAutoSwap<T extends ChainType = ChainType>
|
|
|
589
589
|
/**
|
|
590
590
|
* @inheritDoc
|
|
591
591
|
*/
|
|
592
|
-
getInput(): TokenAmount<
|
|
592
|
+
getInput(): TokenAmount<BtcToken<true>> {
|
|
593
593
|
return toTokenAmount(this.getLightningInvoiceSats(), this.inputToken, this.wrapper._prices, this.pricingInfo);
|
|
594
594
|
}
|
|
595
595
|
|
|
596
596
|
/**
|
|
597
597
|
* @inheritDoc
|
|
598
598
|
*/
|
|
599
|
-
getInputWithoutFee(): TokenAmount<
|
|
599
|
+
getInputWithoutFee(): TokenAmount<BtcToken<true>> {
|
|
600
600
|
return toTokenAmount(this.getInputAmountWithoutFee(), this.inputToken, this.wrapper._prices, this.pricingInfo);
|
|
601
601
|
}
|
|
602
602
|
|
|
@@ -610,14 +610,14 @@ export class FromBTCLNAutoSwap<T extends ChainType = ChainType>
|
|
|
610
610
|
/**
|
|
611
611
|
* @inheritDoc
|
|
612
612
|
*/
|
|
613
|
-
getOutput(): TokenAmount<
|
|
613
|
+
getOutput(): TokenAmount<SCToken<T["ChainId"]>, true> {
|
|
614
614
|
return toTokenAmount(this.getSwapData().getAmount(), this.wrapper._tokens[this.getSwapData().getToken()], this.wrapper._prices, this.pricingInfo);
|
|
615
615
|
}
|
|
616
616
|
|
|
617
617
|
/**
|
|
618
618
|
* @inheritDoc
|
|
619
619
|
*/
|
|
620
|
-
getGasDropOutput(): TokenAmount<
|
|
620
|
+
getGasDropOutput(): TokenAmount<SCToken<T["ChainId"]>, true> {
|
|
621
621
|
return toTokenAmount(
|
|
622
622
|
this.getSwapData().getSecurityDeposit() - this.getSwapData().getClaimerBounty(),
|
|
623
623
|
this.wrapper._tokens[this.getSwapData().getDepositToken()], this.wrapper._prices, this.gasPricingInfo
|
|
@@ -12,7 +12,7 @@ import {UserError} from "../../../../errors/UserError";
|
|
|
12
12
|
import {IntermediaryError} from "../../../../errors/IntermediaryError";
|
|
13
13
|
import {SwapType} from "../../../../enums/SwapType";
|
|
14
14
|
import {
|
|
15
|
-
extendAbortController,
|
|
15
|
+
extendAbortController, parseHashValueExact32Bytes,
|
|
16
16
|
randomBytes,
|
|
17
17
|
throwIfUndefined
|
|
18
18
|
} from "../../../../utils/Utils";
|
|
@@ -35,14 +35,56 @@ import {LNURLWithdrawParamsWithUrl} from "../../../../types/lnurl/LNURLWithdraw"
|
|
|
35
35
|
import {tryWithRetries} from "../../../../utils/RetryUtils";
|
|
36
36
|
import {AllOptional} from "../../../../utils/TypeUtils";
|
|
37
37
|
import {sha256} from "@noble/hashes/sha2";
|
|
38
|
+
import {fromHumanReadableString} from "../../../../utils/TokenUtils";
|
|
38
39
|
|
|
39
40
|
export type FromBTCLNAutoOptions = {
|
|
40
|
-
|
|
41
|
+
/**
|
|
42
|
+
* Instead of letting the SDK generate the preimage/paymentHash pair internally you can pass your computed
|
|
43
|
+
* paymentHash here, this will create the swap with the provided payment hash. Note that swaps created this way
|
|
44
|
+
* won't settle automatically (as the SDK is missing the preimage). Once the HTLC towards the user is created in
|
|
45
|
+
* the {@link FromBTCLNAutoSwapState.CLAIM_COMMITED} state, you should pass the secret preimage manually in the
|
|
46
|
+
* {@link FromBTCLNAutoSwap.waitTillClaimed}, {@link FromBTCLNAutoSwap.claim} or {@link FromBTCLNAutoSwap.txsClaim}
|
|
47
|
+
* functions.
|
|
48
|
+
*
|
|
49
|
+
* Accepts both, a {@link Buffer} and a hexadecimal `string`
|
|
50
|
+
*/
|
|
51
|
+
paymentHash?: Buffer | string,
|
|
52
|
+
/**
|
|
53
|
+
* Optional description to use for the swap lightning network invoice, keep the invoice length below 500 characters
|
|
54
|
+
*/
|
|
41
55
|
description?: string,
|
|
42
|
-
|
|
56
|
+
/**
|
|
57
|
+
* Optional description hash to use for the lightning network invoice, useful when returning the invoice as part of
|
|
58
|
+
* an LNURL-pay service endpoint.
|
|
59
|
+
*
|
|
60
|
+
* Accepts both, a {@link Buffer} and a hexadecimal `string`
|
|
61
|
+
*/
|
|
62
|
+
descriptionHash?: Buffer | string,
|
|
63
|
+
/**
|
|
64
|
+
* Optional additional native token to receive as an output of the swap (e.g. STRK on Starknet or cBTC on Citrea).
|
|
65
|
+
* When passed as a `bigint` it is specified in base units of the token and in `string` it is the human readable
|
|
66
|
+
* decimal format.
|
|
67
|
+
*/
|
|
68
|
+
gasAmount?: bigint | string,
|
|
69
|
+
/**
|
|
70
|
+
* A flag to skip checking whether the lightning network node of the LP has enough channel liquidity to facilitate
|
|
71
|
+
* the swap.
|
|
72
|
+
*/
|
|
43
73
|
unsafeSkipLnNodeCheck?: boolean,
|
|
44
|
-
|
|
74
|
+
/**
|
|
75
|
+
* A flag to attach 0 watchtower fee to the swap, this would make the settlement unattractive for the watchtowers
|
|
76
|
+
* and therefore automatic settlement for such swaps will not be possible, you will have to settle manually
|
|
77
|
+
* with {@link FromBTCLNSwap.claim} or {@link FromBTCLNSwap.txsClaim} functions.
|
|
78
|
+
*/
|
|
45
79
|
unsafeZeroWatchtowerFee?: boolean,
|
|
80
|
+
/**
|
|
81
|
+
* A safety factor to use when estimating the watchtower fee to attach to the swap (this has to cover the gas fee
|
|
82
|
+
* of watchtowers settling the swap). A higher multiple here would mean that a swap is more attractive for
|
|
83
|
+
* watchtowers to settle automatically.
|
|
84
|
+
*
|
|
85
|
+
* Uses a `1.25` multiple by default (i.e. the current network fee is multiplied by 1.25 and then used to estimate
|
|
86
|
+
* the settlement gas fee cost)
|
|
87
|
+
*/
|
|
46
88
|
feeSafetyFactor?: number
|
|
47
89
|
};
|
|
48
90
|
|
|
@@ -326,26 +368,21 @@ export class FromBTCLNAutoWrapper<
|
|
|
326
368
|
if(!this.isInitialized) throw new Error("Not initialized, call init() first!");
|
|
327
369
|
|
|
328
370
|
const _options = {
|
|
329
|
-
paymentHash: options?.paymentHash,
|
|
371
|
+
paymentHash: parseHashValueExact32Bytes(options?.paymentHash, "payment hash"),
|
|
330
372
|
unsafeSkipLnNodeCheck: options?.unsafeSkipLnNodeCheck ?? this._options.unsafeSkipLnNodeCheck,
|
|
331
|
-
gasAmount: options?.gasAmount
|
|
373
|
+
gasAmount: this.parseGasAmount(options?.gasAmount),
|
|
332
374
|
feeSafetyFactor: options?.feeSafetyFactor ?? 1.25, //No need to add much of a margin, since the claim should happen rather soon
|
|
333
375
|
unsafeZeroWatchtowerFee: options?.unsafeZeroWatchtowerFee ?? false,
|
|
334
376
|
description: options?.description,
|
|
335
|
-
descriptionHash: options?.descriptionHash
|
|
377
|
+
descriptionHash: parseHashValueExact32Bytes(options?.descriptionHash, "description hash")
|
|
336
378
|
};
|
|
337
379
|
|
|
338
|
-
if(
|
|
339
|
-
throw new UserError("
|
|
340
|
-
|
|
341
|
-
if(_options.descriptionHash!=null && _options.descriptionHash.length!==32)
|
|
342
|
-
throw new UserError("Invalid description hash length");
|
|
380
|
+
if(amountData.token===this._chain.getNativeCurrencyAddress() && _options.gasAmount!==0n)
|
|
381
|
+
throw new UserError("Cannot specify `gasAmount` for swaps to a native token!");
|
|
343
382
|
|
|
344
383
|
if(_options.description!=null && Buffer.byteLength(_options.description, "utf8") > 500)
|
|
345
384
|
throw new UserError("Invalid description length");
|
|
346
385
|
|
|
347
|
-
if(preFetches==null) preFetches = {};
|
|
348
|
-
|
|
349
386
|
let secret: Buffer | undefined;
|
|
350
387
|
let paymentHash: Buffer;
|
|
351
388
|
if(_options?.paymentHash!=null) {
|
|
@@ -358,6 +395,8 @@ export class FromBTCLNAutoWrapper<
|
|
|
358
395
|
const nativeTokenAddress = this._chain.getNativeCurrencyAddress();
|
|
359
396
|
|
|
360
397
|
const _abortController = extendAbortController(abortSignal);
|
|
398
|
+
|
|
399
|
+
preFetches ??= {};
|
|
361
400
|
const _preFetches = {
|
|
362
401
|
pricePrefetchPromise: preFetches?.pricePrefetchPromise ?? this.preFetchPrice(amountData, _abortController.signal),
|
|
363
402
|
usdPricePrefetchPromise: preFetches?.usdPricePrefetchPromise ?? this.preFetchUsdPrice(_abortController.signal),
|
|
@@ -497,18 +536,15 @@ export class FromBTCLNAutoWrapper<
|
|
|
497
536
|
if(!this.isInitialized) throw new Error("Not initialized, call init() first!");
|
|
498
537
|
|
|
499
538
|
const _options = {
|
|
500
|
-
paymentHash: options?.paymentHash,
|
|
539
|
+
paymentHash: parseHashValueExact32Bytes(options?.paymentHash, "payment hash"),
|
|
501
540
|
unsafeSkipLnNodeCheck: options?.unsafeSkipLnNodeCheck ?? this._options.unsafeSkipLnNodeCheck,
|
|
502
|
-
gasAmount: options?.gasAmount
|
|
541
|
+
gasAmount: this.parseGasAmount(options?.gasAmount),
|
|
503
542
|
feeSafetyFactor: options?.feeSafetyFactor ?? 1.25, //No need to add much of a margin, since the claim should happen rather soon
|
|
504
543
|
unsafeZeroWatchtowerFee: options?.unsafeZeroWatchtowerFee ?? false,
|
|
505
544
|
description: options?.description,
|
|
506
|
-
descriptionHash: options?.descriptionHash
|
|
545
|
+
descriptionHash: parseHashValueExact32Bytes(options?.descriptionHash, "description hash")
|
|
507
546
|
};
|
|
508
547
|
|
|
509
|
-
if(_options.paymentHash!=null && _options.paymentHash.length!==32)
|
|
510
|
-
throw new UserError("Invalid payment hash length, must be exactly 32 bytes!");
|
|
511
|
-
|
|
512
548
|
const abortController = extendAbortController(abortSignal);
|
|
513
549
|
const preFetches = {
|
|
514
550
|
pricePrefetchPromise: this.preFetchPrice(amountData, abortController.signal),
|
|
@@ -356,7 +356,7 @@ export class FromBTCSwap<T extends ChainType = ChainType>
|
|
|
356
356
|
/**
|
|
357
357
|
* @inheritDoc
|
|
358
358
|
*/
|
|
359
|
-
getInput(): TokenAmount<
|
|
359
|
+
getInput(): TokenAmount<BtcToken<false>> {
|
|
360
360
|
return toTokenAmount(this.amount ?? null, this.inputToken, this.wrapper._prices);
|
|
361
361
|
}
|
|
362
362
|
|
|
@@ -365,7 +365,7 @@ export class FromBTCSwap<T extends ChainType = ChainType>
|
|
|
365
365
|
* this amount is pre-funded by the user on the destination chain when the swap escrow
|
|
366
366
|
* is initiated. For total pre-funded deposit amount see {@link getTotalDeposit}.
|
|
367
367
|
*/
|
|
368
|
-
getClaimerBounty(): TokenAmount<
|
|
368
|
+
getClaimerBounty(): TokenAmount<SCToken<T["ChainId"]>, true> {
|
|
369
369
|
return toTokenAmount(this._data.getClaimerBounty(), this.wrapper._tokens[this._data.getDepositToken()], this.wrapper._prices);
|
|
370
370
|
}
|
|
371
371
|
|
|
@@ -661,7 +661,7 @@ export class FromBTCSwap<T extends ChainType = ChainType>
|
|
|
661
661
|
/**
|
|
662
662
|
* @inheritDoc
|
|
663
663
|
*/
|
|
664
|
-
async estimateBitcoinFee(_bitcoinWallet: IBitcoinWallet | MinimalBitcoinWalletInterface, feeRate?: number): Promise<TokenAmount<
|
|
664
|
+
async estimateBitcoinFee(_bitcoinWallet: IBitcoinWallet | MinimalBitcoinWalletInterface, feeRate?: number): Promise<TokenAmount<BtcToken<false>, true> | null> {
|
|
665
665
|
if(this.address==null || this.amount==null) return null;
|
|
666
666
|
const bitcoinWallet: IBitcoinWallet = toBitcoinWallet(_bitcoinWallet, this.wrapper._btcRpc, this.wrapper._options.bitcoinNetwork);
|
|
667
667
|
const txFee = await bitcoinWallet.getTransactionFee(this.address, this.amount, feeRate);
|