@atomiqlabs/sdk 8.6.4 → 8.6.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/prices/abstract/ISwapPrice.d.ts +4 -2
- package/dist/prices/abstract/ISwapPrice.js +18 -6
- package/dist/swaps/ISwap.js +10 -5
- package/dist/swaps/ISwapWrapper.d.ts +1 -0
- package/dist/swaps/ISwapWrapper.js +2 -2
- package/dist/swaps/escrow_swaps/frombtc/ln/FromBTCLNWrapper.js +3 -2
- package/dist/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoSwap.js +1 -1
- package/dist/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoWrapper.js +2 -2
- package/dist/swaps/escrow_swaps/frombtc/onchain/FromBTCWrapper.js +3 -2
- package/dist/swaps/escrow_swaps/tobtc/ln/ToBTCLNWrapper.js +4 -4
- package/dist/swaps/escrow_swaps/tobtc/onchain/ToBTCWrapper.js +4 -4
- package/dist/swaps/spv_swaps/SpvFromBTCSwap.js +1 -1
- package/dist/swaps/spv_swaps/SpvFromBTCWrapper.js +2 -2
- package/dist/swaps/trusted/ln/LnForGasWrapper.js +1 -1
- package/dist/swaps/trusted/onchain/OnchainForGasWrapper.js +1 -1
- package/package.json +1 -1
- package/src/prices/abstract/ISwapPrice.ts +19 -6
- package/src/swaps/ISwap.ts +17 -6
- package/src/swaps/ISwapWrapper.ts +4 -3
- package/src/swaps/escrow_swaps/frombtc/ln/FromBTCLNWrapper.ts +4 -2
- package/src/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoSwap.ts +4 -1
- package/src/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoWrapper.ts +2 -2
- package/src/swaps/escrow_swaps/frombtc/onchain/FromBTCWrapper.ts +4 -2
- package/src/swaps/escrow_swaps/tobtc/ln/ToBTCLNWrapper.ts +6 -6
- package/src/swaps/escrow_swaps/tobtc/onchain/ToBTCWrapper.ts +5 -5
- package/src/swaps/spv_swaps/SpvFromBTCSwap.ts +4 -1
- package/src/swaps/spv_swaps/SpvFromBTCWrapper.ts +2 -2
- package/src/swaps/trusted/ln/LnForGasWrapper.ts +1 -1
- package/src/swaps/trusted/onchain/OnchainForGasWrapper.ts +1 -1
|
@@ -64,8 +64,9 @@ export declare abstract class ISwapPrice<T extends MultiChain = MultiChain> {
|
|
|
64
64
|
* @param tokenAddress Token address to be paid
|
|
65
65
|
* @param abortSignal
|
|
66
66
|
* @param preFetchedPrice An optional price pre-fetched with {@link preFetchPrice}
|
|
67
|
+
* @param realSwapFeeSats
|
|
67
68
|
*/
|
|
68
|
-
isValidAmountSend<C extends ChainIds<T>>(chainIdentifier: C, amountSats: bigint, satsBaseFee: bigint, feePPM: bigint, paidToken: bigint, tokenAddress: string, abortSignal?: AbortSignal, preFetchedPrice?: bigint | null): Promise<PriceInfoType>;
|
|
69
|
+
isValidAmountSend<C extends ChainIds<T>>(chainIdentifier: C, amountSats: bigint, satsBaseFee: bigint, feePPM: bigint, paidToken: bigint, tokenAddress: string, abortSignal?: AbortSignal, preFetchedPrice?: bigint | null, realSwapFeeSats?: bigint): Promise<PriceInfoType>;
|
|
69
70
|
/**
|
|
70
71
|
* Recomputes pricing info without fetching the current price
|
|
71
72
|
*
|
|
@@ -88,8 +89,9 @@ export declare abstract class ISwapPrice<T extends MultiChain = MultiChain> {
|
|
|
88
89
|
* @param tokenAddress Token address to be received
|
|
89
90
|
* @param abortSignal
|
|
90
91
|
* @param preFetchedPrice An optional price pre-fetched with {@link preFetchPrice}
|
|
92
|
+
* @param realSwapFeeSats
|
|
91
93
|
*/
|
|
92
|
-
isValidAmountReceive<C extends ChainIds<T>>(chainIdentifier: C, amountSats: bigint, satsBaseFee: bigint, feePPM: bigint, receiveToken: bigint, tokenAddress: string, abortSignal?: AbortSignal, preFetchedPrice?: bigint | null): Promise<PriceInfoType>;
|
|
94
|
+
isValidAmountReceive<C extends ChainIds<T>>(chainIdentifier: C, amountSats: bigint, satsBaseFee: bigint, feePPM: bigint, receiveToken: bigint, tokenAddress: string, abortSignal?: AbortSignal, preFetchedPrice?: bigint | null, realSwapFeeSats?: bigint): Promise<PriceInfoType>;
|
|
93
95
|
/**
|
|
94
96
|
* Pre-fetches the pricing data for a given token, such that further calls to {@link isValidAmountReceive} or
|
|
95
97
|
* {@link isValidAmountSend} are quicker and don't need to wait for the price fetch
|
|
@@ -59,10 +59,14 @@ class ISwapPrice {
|
|
|
59
59
|
* @param tokenAddress Token address to be paid
|
|
60
60
|
* @param abortSignal
|
|
61
61
|
* @param preFetchedPrice An optional price pre-fetched with {@link preFetchPrice}
|
|
62
|
+
* @param realSwapFeeSats
|
|
62
63
|
*/
|
|
63
|
-
async isValidAmountSend(chainIdentifier, amountSats, satsBaseFee, feePPM, paidToken, tokenAddress, abortSignal, preFetchedPrice) {
|
|
64
|
-
|
|
65
|
-
|
|
64
|
+
async isValidAmountSend(chainIdentifier, amountSats, satsBaseFee, feePPM, paidToken, tokenAddress, abortSignal, preFetchedPrice, realSwapFeeSats) {
|
|
65
|
+
if (realSwapFeeSats != undefined && realSwapFeeSats < 0)
|
|
66
|
+
throw new Error("Invalid swap fee! Swap fee cannot be negative!");
|
|
67
|
+
const totalSats = realSwapFeeSats != undefined
|
|
68
|
+
? amountSats + realSwapFeeSats
|
|
69
|
+
: (amountSats * (1000000n + feePPM) / 1000000n) + satsBaseFee;
|
|
66
70
|
const totalUSats = totalSats * 1000000n;
|
|
67
71
|
const swapPriceUSatPerToken = totalUSats * (10n ** BigInt(this.getDecimalsThrowing(chainIdentifier, tokenAddress))) / paidToken;
|
|
68
72
|
if (this.shouldIgnore(chainIdentifier, tokenAddress))
|
|
@@ -122,10 +126,18 @@ class ISwapPrice {
|
|
|
122
126
|
* @param tokenAddress Token address to be received
|
|
123
127
|
* @param abortSignal
|
|
124
128
|
* @param preFetchedPrice An optional price pre-fetched with {@link preFetchPrice}
|
|
129
|
+
* @param realSwapFeeSats
|
|
125
130
|
*/
|
|
126
|
-
async isValidAmountReceive(chainIdentifier, amountSats, satsBaseFee, feePPM, receiveToken, tokenAddress, abortSignal, preFetchedPrice) {
|
|
127
|
-
|
|
128
|
-
|
|
131
|
+
async isValidAmountReceive(chainIdentifier, amountSats, satsBaseFee, feePPM, receiveToken, tokenAddress, abortSignal, preFetchedPrice, realSwapFeeSats) {
|
|
132
|
+
if (realSwapFeeSats != undefined) {
|
|
133
|
+
if (realSwapFeeSats >= amountSats)
|
|
134
|
+
throw new Error("Invalid swap fee! Larger than or equal to total output amount!");
|
|
135
|
+
if (realSwapFeeSats < 0)
|
|
136
|
+
throw new Error("Invalid swap fee! Must be non-negative!");
|
|
137
|
+
}
|
|
138
|
+
const totalSats = realSwapFeeSats != undefined
|
|
139
|
+
? amountSats - realSwapFeeSats
|
|
140
|
+
: (amountSats * (1000000n - feePPM) / 1000000n) - satsBaseFee;
|
|
129
141
|
const totalUSats = totalSats * 1000000n;
|
|
130
142
|
const swapPriceUSatPerToken = totalUSats * (10n ** BigInt(this.getDecimalsThrowing(chainIdentifier, tokenAddress))) / receiveToken;
|
|
131
143
|
if (this.shouldIgnore(chainIdentifier, tokenAddress))
|
package/dist/swaps/ISwap.js
CHANGED
|
@@ -164,16 +164,21 @@ class ISwap {
|
|
|
164
164
|
if (this.pricingInfo == null)
|
|
165
165
|
return;
|
|
166
166
|
const priceUsdPerBtc = this.pricingInfo.realPriceUsdPerBitcoin;
|
|
167
|
-
const input = this.getInput();
|
|
168
167
|
const output = this.getOutput();
|
|
169
|
-
if (
|
|
168
|
+
if (output.isUnknown)
|
|
170
169
|
return;
|
|
171
|
-
if ((0, Token_1.isSCToken)(
|
|
172
|
-
|
|
170
|
+
if ((0, Token_1.isSCToken)(this.getInputToken()) && this.getDirection() === SwapDirection_1.SwapDirection.TO_BTC) {
|
|
171
|
+
const input = this.getInputWithoutFee();
|
|
172
|
+
if (input.isUnknown)
|
|
173
|
+
return;
|
|
174
|
+
this.pricingInfo = await this.wrapper._prices.isValidAmountSend(this.chainIdentifier, output.rawAmount, this.pricingInfo.satsBaseFee, this.pricingInfo.feePPM, input.rawAmount + this.swapFee, input.token.address, undefined, undefined, this.swapFeeBtc);
|
|
173
175
|
this.pricingInfo.realPriceUsdPerBitcoin = priceUsdPerBtc;
|
|
174
176
|
}
|
|
175
177
|
else if ((0, Token_1.isSCToken)(output.token) && this.getDirection() === SwapDirection_1.SwapDirection.FROM_BTC) {
|
|
176
|
-
|
|
178
|
+
const input = this.getInput();
|
|
179
|
+
if (input.isUnknown)
|
|
180
|
+
return;
|
|
181
|
+
this.pricingInfo = await this.wrapper._prices.isValidAmountReceive(this.chainIdentifier, input.rawAmount, this.pricingInfo.satsBaseFee, this.pricingInfo.feePPM, output.rawAmount, output.token.address, undefined, undefined, this.swapFeeBtc);
|
|
177
182
|
this.pricingInfo.realPriceUsdPerBitcoin = priceUsdPerBtc;
|
|
178
183
|
}
|
|
179
184
|
}
|
|
@@ -194,6 +194,7 @@ export declare abstract class ISwapWrapper<T extends ChainType, D extends SwapTy
|
|
|
194
194
|
swapFeePPM: number;
|
|
195
195
|
}, send: boolean, amountSats: bigint, amountToken: bigint, token: string, feeData: {
|
|
196
196
|
networkFee?: bigint;
|
|
197
|
+
swapFeeBtc?: bigint;
|
|
197
198
|
}, pricePrefetchPromise?: Promise<bigint | undefined>, usdPricePrefetchPromise?: Promise<number | undefined>, abortSignal?: AbortSignal): Promise<PriceInfoType>;
|
|
198
199
|
/**
|
|
199
200
|
* Processes a single smart chain on-chain event
|
|
@@ -114,8 +114,8 @@ class ISwapWrapper {
|
|
|
114
114
|
amountToken = amountToken - feeData.networkFee;
|
|
115
115
|
const [isValidAmount, usdPrice] = await Promise.all([
|
|
116
116
|
send ?
|
|
117
|
-
this._prices.isValidAmountSend(this.chainIdentifier, amountSats, swapBaseFee, swapFeePPM, amountToken, token, abortSignal, await pricePrefetchPromise) :
|
|
118
|
-
this._prices.isValidAmountReceive(this.chainIdentifier, amountSats, swapBaseFee, swapFeePPM, amountToken, token, abortSignal, await pricePrefetchPromise),
|
|
117
|
+
this._prices.isValidAmountSend(this.chainIdentifier, amountSats, swapBaseFee, swapFeePPM, amountToken, token, abortSignal, await pricePrefetchPromise, feeData.swapFeeBtc) :
|
|
118
|
+
this._prices.isValidAmountReceive(this.chainIdentifier, amountSats, swapBaseFee, swapFeePPM, amountToken, token, abortSignal, await pricePrefetchPromise, feeData.swapFeeBtc),
|
|
119
119
|
usdPricePrefetchPromise.then(value => {
|
|
120
120
|
if (value != null)
|
|
121
121
|
return value;
|
|
@@ -217,10 +217,11 @@ class FromBTCLNWrapper extends IFromBTCLNWrapper_1.IFromBTCLNWrapper {
|
|
|
217
217
|
if (decodedPr.timeExpireDate == null)
|
|
218
218
|
throw new IntermediaryError_1.IntermediaryError("Invalid returned swap invoice, no expiry date field");
|
|
219
219
|
const amountIn = (BigInt(decodedPr.millisatoshis) + 999n) / 1000n;
|
|
220
|
+
const swapFeeBtc = resp.swapFee * amountIn / (resp.total - resp.swapFee);
|
|
220
221
|
try {
|
|
221
222
|
this.verifyReturnedData(resp, amountData, lp, _options, decodedPr, paymentHash);
|
|
222
223
|
const [pricingInfo] = await Promise.all([
|
|
223
|
-
this.verifyReturnedPrice(lp.services[SwapType_1.SwapType.FROM_BTCLN], false, amountIn, resp.total, amountData.token, {}, _preFetches.pricePrefetchPromise, _preFetches.usdPricePrefetchPromise, abortController.signal),
|
|
224
|
+
this.verifyReturnedPrice(lp.services[SwapType_1.SwapType.FROM_BTCLN], false, amountIn, resp.total, amountData.token, { swapFeeBtc }, _preFetches.pricePrefetchPromise, _preFetches.usdPricePrefetchPromise, abortController.signal),
|
|
224
225
|
this.verifyIntermediaryLiquidity(resp.total, (0, Utils_1.throwIfUndefined)(liquidityPromise)),
|
|
225
226
|
lnCapacityPromise != null ? this.verifyLnNodeCapacity(lp, decodedPr, lnCapacityPromise, abortController.signal) : Promise.resolve()
|
|
226
227
|
]);
|
|
@@ -229,7 +230,7 @@ class FromBTCLNWrapper extends IFromBTCLNWrapper_1.IFromBTCLNWrapper {
|
|
|
229
230
|
url: lp.url,
|
|
230
231
|
expiry: decodedPr.timeExpireDate * 1000,
|
|
231
232
|
swapFee: resp.swapFee,
|
|
232
|
-
swapFeeBtc
|
|
233
|
+
swapFeeBtc,
|
|
233
234
|
feeRate: (await _preFetches.feeRatePromise),
|
|
234
235
|
initialSwapData: await this._contract.createSwapData(base_1.ChainSwapType.HTLC, lp.getAddress(this.chainIdentifier), recipient, amountData.token, resp.total, claimHash.toString("hex"), this.getRandomSequence(), BigInt(Math.floor(Date.now() / 1000)), false, true, resp.securityDeposit, 0n, nativeTokenAddress),
|
|
235
236
|
pr: resp.pr,
|
|
@@ -206,7 +206,7 @@ class FromBTCLNAutoSwap extends IEscrowSwap_1.IEscrowSwap {
|
|
|
206
206
|
if (this.pricingInfo == null || this.btcAmountSwap == null)
|
|
207
207
|
return;
|
|
208
208
|
const usdPricePerBtc = this.pricingInfo.realPriceUsdPerBitcoin;
|
|
209
|
-
this.pricingInfo = await this.wrapper._prices.isValidAmountReceive(this.chainIdentifier, this.btcAmountSwap, this.pricingInfo.satsBaseFee, this.pricingInfo.feePPM, this.getOutputAmountWithoutFee(), this.getSwapData().getToken());
|
|
209
|
+
this.pricingInfo = await this.wrapper._prices.isValidAmountReceive(this.chainIdentifier, this.btcAmountSwap, this.pricingInfo.satsBaseFee, this.pricingInfo.feePPM, this.getOutputAmountWithoutFee(), this.getSwapData().getToken(), undefined, undefined, this.swapFeeBtc);
|
|
210
210
|
this.pricingInfo.realPriceUsdPerBitcoin = usdPricePerBtc;
|
|
211
211
|
}
|
|
212
212
|
//////////////////////////////
|
|
@@ -295,9 +295,9 @@ class FromBTCLNAutoWrapper extends IFromBTCLNWrapper_1.IFromBTCLNWrapper {
|
|
|
295
295
|
try {
|
|
296
296
|
this.verifyReturnedData(resp, amountData, lp, _options, decodedPr, paymentHash, claimerBounty);
|
|
297
297
|
const [pricingInfo, gasPricingInfo] = await Promise.all([
|
|
298
|
-
this.verifyReturnedPrice(lp.services[SwapType_1.SwapType.FROM_BTCLN_AUTO], false, resp.btcAmountSwap, resp.total, amountData.token, {}, _preFetches.pricePrefetchPromise, _preFetches.usdPricePrefetchPromise, abortController.signal),
|
|
298
|
+
this.verifyReturnedPrice(lp.services[SwapType_1.SwapType.FROM_BTCLN_AUTO], false, resp.btcAmountSwap, resp.total, amountData.token, { swapFeeBtc: resp.swapFeeBtc }, _preFetches.pricePrefetchPromise, _preFetches.usdPricePrefetchPromise, abortController.signal),
|
|
299
299
|
_options.gasAmount === 0n ? Promise.resolve(undefined) : this.verifyReturnedPrice({ ...lp.services[SwapType_1.SwapType.FROM_BTCLN_AUTO], swapBaseFee: 0 }, //Base fee should be charged only on the amount, not on gas
|
|
300
|
-
false, resp.btcAmountGas, resp.totalGas + resp.claimerBounty, nativeTokenAddress, {}, _preFetches.gasTokenPricePrefetchPromise, _preFetches.usdPricePrefetchPromise, abortController.signal),
|
|
300
|
+
false, resp.btcAmountGas, resp.totalGas + resp.claimerBounty, nativeTokenAddress, { swapFeeBtc: resp.gasSwapFeeBtc }, _preFetches.gasTokenPricePrefetchPromise, _preFetches.usdPricePrefetchPromise, abortController.signal),
|
|
301
301
|
this.verifyIntermediaryLiquidity(resp.total, (0, Utils_1.throwIfUndefined)(liquidityPromise)),
|
|
302
302
|
_options.unsafeSkipLnNodeCheck ? Promise.resolve() : this.verifyLnNodeCapacity(lp, decodedPr, lnCapacityPromise, abortController.signal)
|
|
303
303
|
]);
|
|
@@ -309,10 +309,11 @@ class FromBTCWrapper extends IFromBTCWrapper_1.IFromBTCWrapper {
|
|
|
309
309
|
}, undefined, e => e instanceof RequestError_1.RequestError, abortController.signal);
|
|
310
310
|
const data = new this._swapDataDeserializer(resp.data);
|
|
311
311
|
data.setClaimer(recipient);
|
|
312
|
+
const swapFeeBtc = resp.swapFee * resp.amount / (data.getAmount() - resp.swapFee);
|
|
312
313
|
this.verifyReturnedData(recipient, resp, amountData, lp, _options, data, sequence, (await claimerBountyPrefetchPromise), nativeTokenAddress);
|
|
313
314
|
const [pricingInfo, signatureExpiry] = await Promise.all([
|
|
314
315
|
//Get intermediary's liquidity
|
|
315
|
-
this.verifyReturnedPrice(lp.services[SwapType_1.SwapType.FROM_BTC], false, resp.amount, resp.total, amountData.token, {}, pricePrefetchPromise, usdPricePrefetchPromise, abortController.signal),
|
|
316
|
+
this.verifyReturnedPrice(lp.services[SwapType_1.SwapType.FROM_BTC], false, resp.amount, resp.total, amountData.token, { swapFeeBtc }, pricePrefetchPromise, usdPricePrefetchPromise, abortController.signal),
|
|
316
317
|
this.verifyReturnedSignature(recipient, data, resp, feeRatePromise, signDataPromise, abortController.signal),
|
|
317
318
|
this.verifyIntermediaryLiquidity(data.getAmount(), (0, Utils_1.throwIfUndefined)(liquidityPromise)),
|
|
318
319
|
]);
|
|
@@ -321,7 +322,7 @@ class FromBTCWrapper extends IFromBTCWrapper_1.IFromBTCWrapper {
|
|
|
321
322
|
url: lp.url,
|
|
322
323
|
expiry: signatureExpiry,
|
|
323
324
|
swapFee: resp.swapFee,
|
|
324
|
-
swapFeeBtc
|
|
325
|
+
swapFeeBtc,
|
|
325
326
|
feeRate: (await feeRatePromise),
|
|
326
327
|
signatureData: resp,
|
|
327
328
|
data,
|
|
@@ -179,15 +179,15 @@ class ToBTCLNWrapper extends IToBTCWrapper_1.IToBTCWrapper {
|
|
|
179
179
|
const data = new this._swapDataDeserializer(resp.data);
|
|
180
180
|
data.setOfferer(signer);
|
|
181
181
|
await this.verifyReturnedData(signer, resp, parsedPr, amountData.token, lp, calculatedOptions, data);
|
|
182
|
+
const swapFeeBtc = resp.swapFee * amountOut / (data.getAmount() - totalFee);
|
|
182
183
|
const [pricingInfo, signatureExpiry, reputation] = await Promise.all([
|
|
183
|
-
this.verifyReturnedPrice(lp.services[SwapType_1.SwapType.TO_BTCLN], true, amountOut, data.getAmount(), amountData.token, { networkFee: resp.maxFee }, preFetches.pricePreFetchPromise, preFetches.usdPricePrefetchPromise, abortController.signal),
|
|
184
|
+
this.verifyReturnedPrice(lp.services[SwapType_1.SwapType.TO_BTCLN], true, amountOut, data.getAmount(), amountData.token, { networkFee: resp.maxFee, swapFeeBtc }, preFetches.pricePreFetchPromise, preFetches.usdPricePrefetchPromise, abortController.signal),
|
|
184
185
|
this.verifyReturnedSignature(signer, data, resp, preFetches.feeRatePromise, signDataPromise, abortController.signal),
|
|
185
186
|
reputationPromise
|
|
186
187
|
]);
|
|
187
188
|
abortController.signal.throwIfAborted();
|
|
188
189
|
if (reputation != null)
|
|
189
190
|
lp.reputation[amountData.token.toString()] = reputation;
|
|
190
|
-
const swapFeeBtc = resp.swapFee * amountOut / (data.getAmount() - totalFee);
|
|
191
191
|
const quote = new ToBTCLNSwap_1.ToBTCLNSwap(this, {
|
|
192
192
|
pricingInfo,
|
|
193
193
|
url: lp.url,
|
|
@@ -328,15 +328,15 @@ class ToBTCLNWrapper extends IToBTCWrapper_1.IToBTCWrapper {
|
|
|
328
328
|
const data = new this._swapDataDeserializer(resp.data);
|
|
329
329
|
data.setOfferer(signer);
|
|
330
330
|
await this.verifyReturnedData(signer, resp, parsedInvoice, amountData.token, lp, calculatedOptions, data, amountData.amount);
|
|
331
|
+
const swapFeeBtc = resp.swapFee * amountOut / (data.getAmount() - totalFee);
|
|
331
332
|
const [pricingInfo, signatureExpiry, reputation] = await Promise.all([
|
|
332
|
-
this.verifyReturnedPrice(lp.services[SwapType_1.SwapType.TO_BTCLN], true, prepareResp.amount, data.getAmount(), amountData.token, { networkFee: resp.maxFee }, preFetches.pricePreFetchPromise, preFetches.usdPricePrefetchPromise, abortSignal),
|
|
333
|
+
this.verifyReturnedPrice(lp.services[SwapType_1.SwapType.TO_BTCLN], true, prepareResp.amount, data.getAmount(), amountData.token, { networkFee: resp.maxFee, swapFeeBtc }, preFetches.pricePreFetchPromise, preFetches.usdPricePrefetchPromise, abortSignal),
|
|
333
334
|
this.verifyReturnedSignature(signer, data, resp, preFetches.feeRatePromise, signDataPromise, abortController.signal),
|
|
334
335
|
reputationPromise
|
|
335
336
|
]);
|
|
336
337
|
abortController.signal.throwIfAborted();
|
|
337
338
|
if (reputation != null)
|
|
338
339
|
lp.reputation[amountData.token.toString()] = reputation;
|
|
339
|
-
const swapFeeBtc = resp.swapFee * amountOut / (data.getAmount() - totalFee);
|
|
340
340
|
const quote = new ToBTCLNSwap_1.ToBTCLNSwap(this, {
|
|
341
341
|
pricingInfo,
|
|
342
342
|
url: lp.url,
|
|
@@ -194,18 +194,18 @@ class ToBTCWrapper extends IToBTCWrapper_1.IToBTCWrapper {
|
|
|
194
194
|
let hash = _hash ?? this._contract.getHashForOnchain(outputScript, resp.amount, _options.confirmations, nonce).toString("hex");
|
|
195
195
|
const data = new this._swapDataDeserializer(resp.data);
|
|
196
196
|
data.setOfferer(signer);
|
|
197
|
+
const inputWithoutFees = data.getAmount() - resp.swapFee - resp.networkFee;
|
|
198
|
+
const swapFeeBtc = resp.swapFee * resp.amount / inputWithoutFees;
|
|
199
|
+
const networkFeeBtc = resp.networkFee * resp.amount / inputWithoutFees;
|
|
197
200
|
this.verifyReturnedData(signer, resp, amountData, lp, _options, data, hash);
|
|
198
201
|
const [pricingInfo, signatureExpiry, reputation] = await Promise.all([
|
|
199
|
-
this.verifyReturnedPrice(lp.services[SwapType_1.SwapType.TO_BTC], true, resp.amount, data.getAmount(), amountData.token, resp, pricePreFetchPromise, usdPricePrefetchPromise, abortController.signal),
|
|
202
|
+
this.verifyReturnedPrice(lp.services[SwapType_1.SwapType.TO_BTC], true, resp.amount, data.getAmount(), amountData.token, { networkFee: resp.networkFee, swapFeeBtc }, pricePreFetchPromise, usdPricePrefetchPromise, abortController.signal),
|
|
200
203
|
this.verifyReturnedSignature(signer, data, resp, feeRatePromise, signDataPromise, abortController.signal),
|
|
201
204
|
reputationPromise
|
|
202
205
|
]);
|
|
203
206
|
abortController.signal.throwIfAborted();
|
|
204
207
|
if (reputation != null)
|
|
205
208
|
lp.reputation[amountData.token.toString()] = reputation;
|
|
206
|
-
const inputWithoutFees = data.getAmount() - resp.swapFee - resp.networkFee;
|
|
207
|
-
const swapFeeBtc = resp.swapFee * resp.amount / inputWithoutFees;
|
|
208
|
-
const networkFeeBtc = resp.networkFee * resp.amount / inputWithoutFees;
|
|
209
209
|
const quote = new ToBTCSwap_1.ToBTCSwap(this, {
|
|
210
210
|
pricingInfo,
|
|
211
211
|
url: lp.url,
|
|
@@ -254,7 +254,7 @@ class SpvFromBTCSwap extends ISwap_1.ISwap {
|
|
|
254
254
|
if (this.pricingInfo == null)
|
|
255
255
|
return;
|
|
256
256
|
const usdPricePerBtc = this.pricingInfo.realPriceUsdPerBitcoin;
|
|
257
|
-
this.pricingInfo = await this.wrapper._prices.isValidAmountReceive(this.chainIdentifier, this.btcAmountSwap, this.pricingInfo.satsBaseFee, this.pricingInfo.feePPM, this.getOutputWithoutFee().rawAmount, this.outputSwapToken);
|
|
257
|
+
this.pricingInfo = await this.wrapper._prices.isValidAmountReceive(this.chainIdentifier, this.btcAmountSwap, this.pricingInfo.satsBaseFee, this.pricingInfo.feePPM, this.getOutputWithoutFee().rawAmount, this.outputSwapToken, undefined, undefined, this.swapFeeBtc);
|
|
258
258
|
this.pricingInfo.realPriceUsdPerBitcoin = usdPricePerBtc;
|
|
259
259
|
}
|
|
260
260
|
//////////////////////////////
|
|
@@ -466,9 +466,9 @@ class SpvFromBTCWrapper extends ISwapWrapper_1.ISwapWrapper {
|
|
|
466
466
|
this.logger.debug("create(" + lp.url + "): LP response: ", resp);
|
|
467
467
|
const callerFeeShare = (await callerFeePrefetchPromise);
|
|
468
468
|
const [pricingInfo, gasPricingInfo, { vault, vaultUtxoValue }] = await Promise.all([
|
|
469
|
-
this.verifyReturnedPrice(lp.services[SwapType_1.SwapType.SPV_VAULT_FROM_BTC], false, resp.btcAmountSwap, resp.total * (100000n + callerFeeShare) / 100000n, amountData.token, {}, pricePrefetchPromise, usdPricePrefetchPromise, abortController.signal),
|
|
469
|
+
this.verifyReturnedPrice(lp.services[SwapType_1.SwapType.SPV_VAULT_FROM_BTC], false, resp.btcAmountSwap, resp.total * (100000n + callerFeeShare) / 100000n, amountData.token, { swapFeeBtc: resp.swapFeeBtc }, pricePrefetchPromise, usdPricePrefetchPromise, abortController.signal),
|
|
470
470
|
_options.gasAmount === 0n ? Promise.resolve(undefined) : this.verifyReturnedPrice({ ...lp.services[SwapType_1.SwapType.SPV_VAULT_FROM_BTC], swapBaseFee: 0 }, //Base fee should be charged only on the amount, not on gas
|
|
471
|
-
false, resp.btcAmountGas, resp.totalGas * (100000n + callerFeeShare) / 100000n, nativeTokenAddress, {}, gasTokenPricePrefetchPromise, usdPricePrefetchPromise, abortController.signal),
|
|
471
|
+
false, resp.btcAmountGas, resp.totalGas * (100000n + callerFeeShare) / 100000n, nativeTokenAddress, { swapFeeBtc: resp.gasSwapFeeBtc }, gasTokenPricePrefetchPromise, usdPricePrefetchPromise, abortController.signal),
|
|
472
472
|
this.verifyReturnedData(resp, amountData, lp, _options, callerFeeShare, bitcoinFeeRatePromise, abortController.signal)
|
|
473
473
|
]);
|
|
474
474
|
const swapInit = {
|
|
@@ -62,7 +62,7 @@ class LnForGasWrapper extends ISwapWrapper_1.ISwapWrapper {
|
|
|
62
62
|
throw new IntermediaryError_1.IntermediaryError("Invalid total returned");
|
|
63
63
|
const pricingInfo = await this.verifyReturnedPrice(typeof (lpOrUrl) === "string" || lpOrUrl.services[SwapType_1.SwapType.TRUSTED_FROM_BTCLN] == null ?
|
|
64
64
|
{ swapFeePPM: 10000, swapBaseFee: 10 } :
|
|
65
|
-
lpOrUrl.services[SwapType_1.SwapType.TRUSTED_FROM_BTCLN], false, amountIn, amount, token, {});
|
|
65
|
+
lpOrUrl.services[SwapType_1.SwapType.TRUSTED_FROM_BTCLN], false, amountIn, amount, token, { swapFeeBtc: resp.swapFeeSats });
|
|
66
66
|
const quoteInit = {
|
|
67
67
|
pr: resp.pr,
|
|
68
68
|
outputAmount: resp.total,
|
|
@@ -69,7 +69,7 @@ class OnchainForGasWrapper extends ISwapWrapper_1.ISwapWrapper {
|
|
|
69
69
|
throw new IntermediaryError_1.IntermediaryError("Invalid total returned");
|
|
70
70
|
const pricingInfo = await this.verifyReturnedPrice(typeof (lpOrUrl) === "string" || lpOrUrl.services[SwapType_1.SwapType.TRUSTED_FROM_BTC] == null ?
|
|
71
71
|
{ swapFeePPM: 10000, swapBaseFee: 10 } :
|
|
72
|
-
lpOrUrl.services[SwapType_1.SwapType.TRUSTED_FROM_BTC], false, resp.amountSats, amount, this._chain.getNativeCurrencyAddress(), {});
|
|
72
|
+
lpOrUrl.services[SwapType_1.SwapType.TRUSTED_FROM_BTC], false, resp.amountSats, amount, this._chain.getNativeCurrencyAddress(), { swapFeeBtc: resp.swapFeeSats });
|
|
73
73
|
const quote = new OnchainForGasSwap_1.OnchainForGasSwap(this, {
|
|
74
74
|
paymentHash: resp.paymentHash,
|
|
75
75
|
sequence: resp.sequence,
|
package/package.json
CHANGED
|
@@ -100,6 +100,7 @@ export abstract class ISwapPrice<T extends MultiChain = MultiChain> {
|
|
|
100
100
|
* @param tokenAddress Token address to be paid
|
|
101
101
|
* @param abortSignal
|
|
102
102
|
* @param preFetchedPrice An optional price pre-fetched with {@link preFetchPrice}
|
|
103
|
+
* @param realSwapFeeSats
|
|
103
104
|
*/
|
|
104
105
|
public async isValidAmountSend<C extends ChainIds<T>>(
|
|
105
106
|
chainIdentifier: C,
|
|
@@ -109,11 +110,15 @@ export abstract class ISwapPrice<T extends MultiChain = MultiChain> {
|
|
|
109
110
|
paidToken: bigint,
|
|
110
111
|
tokenAddress: string,
|
|
111
112
|
abortSignal?: AbortSignal,
|
|
112
|
-
preFetchedPrice?: bigint | null
|
|
113
|
+
preFetchedPrice?: bigint | null,
|
|
114
|
+
realSwapFeeSats?: bigint
|
|
113
115
|
): Promise<PriceInfoType> {
|
|
114
|
-
|
|
115
|
-
|
|
116
|
+
if(realSwapFeeSats!=undefined && realSwapFeeSats<0) throw new Error("Invalid swap fee! Swap fee cannot be negative!");
|
|
117
|
+
const totalSats = realSwapFeeSats!=undefined
|
|
118
|
+
? amountSats + realSwapFeeSats
|
|
119
|
+
: (amountSats * (1000000n + feePPM) / 1000000n) + satsBaseFee;
|
|
116
120
|
const totalUSats = totalSats * 1000000n;
|
|
121
|
+
|
|
117
122
|
const swapPriceUSatPerToken = totalUSats * (10n ** BigInt(this.getDecimalsThrowing(chainIdentifier, tokenAddress))) / paidToken;
|
|
118
123
|
|
|
119
124
|
if(this.shouldIgnore(chainIdentifier, tokenAddress)) return {
|
|
@@ -185,6 +190,7 @@ export abstract class ISwapPrice<T extends MultiChain = MultiChain> {
|
|
|
185
190
|
* @param tokenAddress Token address to be received
|
|
186
191
|
* @param abortSignal
|
|
187
192
|
* @param preFetchedPrice An optional price pre-fetched with {@link preFetchPrice}
|
|
193
|
+
* @param realSwapFeeSats
|
|
188
194
|
*/
|
|
189
195
|
public async isValidAmountReceive<C extends ChainIds<T>>(
|
|
190
196
|
chainIdentifier: C,
|
|
@@ -194,11 +200,18 @@ export abstract class ISwapPrice<T extends MultiChain = MultiChain> {
|
|
|
194
200
|
receiveToken: bigint,
|
|
195
201
|
tokenAddress: string,
|
|
196
202
|
abortSignal?: AbortSignal,
|
|
197
|
-
preFetchedPrice?: bigint | null
|
|
203
|
+
preFetchedPrice?: bigint | null,
|
|
204
|
+
realSwapFeeSats?: bigint
|
|
198
205
|
): Promise<PriceInfoType> {
|
|
199
|
-
|
|
200
|
-
|
|
206
|
+
if(realSwapFeeSats!=undefined) {
|
|
207
|
+
if(realSwapFeeSats>=amountSats) throw new Error("Invalid swap fee! Larger than or equal to total output amount!");
|
|
208
|
+
if(realSwapFeeSats<0) throw new Error("Invalid swap fee! Must be non-negative!");
|
|
209
|
+
}
|
|
210
|
+
const totalSats = realSwapFeeSats!=undefined
|
|
211
|
+
? amountSats - realSwapFeeSats
|
|
212
|
+
: (amountSats * (1000000n - feePPM) / 1000000n) - satsBaseFee;
|
|
201
213
|
const totalUSats = totalSats * 1000000n;
|
|
214
|
+
|
|
202
215
|
const swapPriceUSatPerToken = totalUSats * (10n ** BigInt(this.getDecimalsThrowing(chainIdentifier, tokenAddress))) / receiveToken;
|
|
203
216
|
|
|
204
217
|
if(this.shouldIgnore(chainIdentifier, tokenAddress)) return {
|
package/src/swaps/ISwap.ts
CHANGED
|
@@ -315,28 +315,39 @@ export abstract class ISwap<
|
|
|
315
315
|
public async refreshPriceData(): Promise<void> {
|
|
316
316
|
if(this.pricingInfo==null) return;
|
|
317
317
|
const priceUsdPerBtc = this.pricingInfo.realPriceUsdPerBitcoin;
|
|
318
|
-
const input = this.getInput();
|
|
319
318
|
const output = this.getOutput();
|
|
320
|
-
if(
|
|
319
|
+
if(output.isUnknown) return;
|
|
320
|
+
|
|
321
|
+
if(isSCToken(this.getInputToken()) && this.getDirection()===SwapDirection.TO_BTC) {
|
|
322
|
+
const input = this.getInputWithoutFee();
|
|
323
|
+
if(input.isUnknown) return;
|
|
321
324
|
|
|
322
|
-
if(isSCToken(input.token) && this.getDirection()===SwapDirection.TO_BTC) {
|
|
323
325
|
this.pricingInfo = await this.wrapper._prices.isValidAmountSend(
|
|
324
326
|
this.chainIdentifier,
|
|
325
327
|
output.rawAmount!,
|
|
326
328
|
this.pricingInfo.satsBaseFee,
|
|
327
329
|
this.pricingInfo.feePPM,
|
|
328
|
-
input.rawAmount
|
|
329
|
-
input.token.address
|
|
330
|
+
input.rawAmount! + this.swapFee,
|
|
331
|
+
input.token.address,
|
|
332
|
+
undefined,
|
|
333
|
+
undefined,
|
|
334
|
+
this.swapFeeBtc
|
|
330
335
|
);
|
|
331
336
|
this.pricingInfo.realPriceUsdPerBitcoin = priceUsdPerBtc;
|
|
332
337
|
} else if(isSCToken(output.token) && this.getDirection()===SwapDirection.FROM_BTC) {
|
|
338
|
+
const input = this.getInput();
|
|
339
|
+
if(input.isUnknown) return;
|
|
340
|
+
|
|
333
341
|
this.pricingInfo = await this.wrapper._prices.isValidAmountReceive(
|
|
334
342
|
this.chainIdentifier,
|
|
335
343
|
input.rawAmount!,
|
|
336
344
|
this.pricingInfo.satsBaseFee,
|
|
337
345
|
this.pricingInfo.feePPM,
|
|
338
346
|
output.rawAmount!,
|
|
339
|
-
output.token.address
|
|
347
|
+
output.token.address,
|
|
348
|
+
undefined,
|
|
349
|
+
undefined,
|
|
350
|
+
this.swapFeeBtc
|
|
340
351
|
);
|
|
341
352
|
this.pricingInfo.realPriceUsdPerBitcoin = priceUsdPerBtc;
|
|
342
353
|
}
|
|
@@ -259,7 +259,8 @@ export abstract class ISwapWrapper<
|
|
|
259
259
|
amountToken: bigint,
|
|
260
260
|
token: string,
|
|
261
261
|
feeData: {
|
|
262
|
-
networkFee?: bigint
|
|
262
|
+
networkFee?: bigint,
|
|
263
|
+
swapFeeBtc?: bigint
|
|
263
264
|
},
|
|
264
265
|
pricePrefetchPromise: Promise<bigint | undefined> = Promise.resolve(undefined),
|
|
265
266
|
usdPricePrefetchPromise: Promise<number | undefined> = Promise.resolve(undefined),
|
|
@@ -271,8 +272,8 @@ export abstract class ISwapWrapper<
|
|
|
271
272
|
|
|
272
273
|
const [isValidAmount, usdPrice] = await Promise.all([
|
|
273
274
|
send ?
|
|
274
|
-
this._prices.isValidAmountSend(this.chainIdentifier, amountSats, swapBaseFee, swapFeePPM, amountToken, token, abortSignal, await pricePrefetchPromise) :
|
|
275
|
-
this._prices.isValidAmountReceive(this.chainIdentifier, amountSats, swapBaseFee, swapFeePPM, amountToken, token, abortSignal, await pricePrefetchPromise),
|
|
275
|
+
this._prices.isValidAmountSend(this.chainIdentifier, amountSats, swapBaseFee, swapFeePPM, amountToken, token, abortSignal, await pricePrefetchPromise, feeData.swapFeeBtc) :
|
|
276
|
+
this._prices.isValidAmountReceive(this.chainIdentifier, amountSats, swapBaseFee, swapFeePPM, amountToken, token, abortSignal, await pricePrefetchPromise, feeData.swapFeeBtc),
|
|
276
277
|
usdPricePrefetchPromise.then(value => {
|
|
277
278
|
if(value!=null) return value;
|
|
278
279
|
return this._prices.preFetchUsdPrice(abortSignal);
|
|
@@ -334,12 +334,14 @@ export class FromBTCLNWrapper<
|
|
|
334
334
|
if(decodedPr.timeExpireDate==null) throw new IntermediaryError("Invalid returned swap invoice, no expiry date field");
|
|
335
335
|
const amountIn = (BigInt(decodedPr.millisatoshis) + 999n) / 1000n;
|
|
336
336
|
|
|
337
|
+
const swapFeeBtc = resp.swapFee * amountIn / (resp.total - resp.swapFee);
|
|
338
|
+
|
|
337
339
|
try {
|
|
338
340
|
this.verifyReturnedData(resp, amountData, lp, _options, decodedPr, paymentHash);
|
|
339
341
|
const [pricingInfo] = await Promise.all([
|
|
340
342
|
this.verifyReturnedPrice(
|
|
341
343
|
lp.services[SwapType.FROM_BTCLN], false, amountIn, resp.total,
|
|
342
|
-
amountData.token, {}, _preFetches.pricePrefetchPromise, _preFetches.usdPricePrefetchPromise, abortController.signal
|
|
344
|
+
amountData.token, {swapFeeBtc}, _preFetches.pricePrefetchPromise, _preFetches.usdPricePrefetchPromise, abortController.signal
|
|
343
345
|
),
|
|
344
346
|
this.verifyIntermediaryLiquidity(resp.total, throwIfUndefined(liquidityPromise)),
|
|
345
347
|
lnCapacityPromise!=null ? this.verifyLnNodeCapacity(lp, decodedPr, lnCapacityPromise, abortController.signal) : Promise.resolve()
|
|
@@ -350,7 +352,7 @@ export class FromBTCLNWrapper<
|
|
|
350
352
|
url: lp.url,
|
|
351
353
|
expiry: decodedPr.timeExpireDate*1000,
|
|
352
354
|
swapFee: resp.swapFee,
|
|
353
|
-
swapFeeBtc
|
|
355
|
+
swapFeeBtc,
|
|
354
356
|
feeRate: (await _preFetches.feeRatePromise)!,
|
|
355
357
|
initialSwapData: await this._contract.createSwapData(
|
|
356
358
|
ChainSwapType.HTLC, lp.getAddress(this.chainIdentifier), recipient, amountData.token,
|
|
@@ -309,7 +309,10 @@ export class FromBTCLNAutoSwap<T extends ChainType = ChainType>
|
|
|
309
309
|
this.pricingInfo.satsBaseFee,
|
|
310
310
|
this.pricingInfo.feePPM,
|
|
311
311
|
this.getOutputAmountWithoutFee(),
|
|
312
|
-
this.getSwapData().getToken()
|
|
312
|
+
this.getSwapData().getToken(),
|
|
313
|
+
undefined,
|
|
314
|
+
undefined,
|
|
315
|
+
this.swapFeeBtc
|
|
313
316
|
);
|
|
314
317
|
this.pricingInfo.realPriceUsdPerBitcoin = usdPricePerBtc;
|
|
315
318
|
}
|
|
@@ -457,13 +457,13 @@ export class FromBTCLNAutoWrapper<
|
|
|
457
457
|
lp.services[SwapType.FROM_BTCLN_AUTO],
|
|
458
458
|
false, resp.btcAmountSwap,
|
|
459
459
|
resp.total,
|
|
460
|
-
amountData.token, {}, _preFetches.pricePrefetchPromise, _preFetches.usdPricePrefetchPromise, abortController.signal
|
|
460
|
+
amountData.token, {swapFeeBtc: resp.swapFeeBtc}, _preFetches.pricePrefetchPromise, _preFetches.usdPricePrefetchPromise, abortController.signal
|
|
461
461
|
),
|
|
462
462
|
_options.gasAmount===0n ? Promise.resolve(undefined) : this.verifyReturnedPrice(
|
|
463
463
|
{...lp.services[SwapType.FROM_BTCLN_AUTO], swapBaseFee: 0}, //Base fee should be charged only on the amount, not on gas
|
|
464
464
|
false, resp.btcAmountGas,
|
|
465
465
|
resp.totalGas + resp.claimerBounty,
|
|
466
|
-
nativeTokenAddress, {}, _preFetches.gasTokenPricePrefetchPromise, _preFetches.usdPricePrefetchPromise, abortController.signal
|
|
466
|
+
nativeTokenAddress, {swapFeeBtc: resp.gasSwapFeeBtc}, _preFetches.gasTokenPricePrefetchPromise, _preFetches.usdPricePrefetchPromise, abortController.signal
|
|
467
467
|
),
|
|
468
468
|
this.verifyIntermediaryLiquidity(resp.total, throwIfUndefined(liquidityPromise)),
|
|
469
469
|
_options.unsafeSkipLnNodeCheck ? Promise.resolve() : this.verifyLnNodeCapacity(lp, decodedPr, lnCapacityPromise, abortController.signal)
|
|
@@ -487,12 +487,14 @@ export class FromBTCWrapper<
|
|
|
487
487
|
const data: T["Data"] = new this._swapDataDeserializer(resp.data);
|
|
488
488
|
data.setClaimer(recipient);
|
|
489
489
|
|
|
490
|
+
const swapFeeBtc = resp.swapFee * resp.amount / (data.getAmount() - resp.swapFee);
|
|
491
|
+
|
|
490
492
|
this.verifyReturnedData(recipient, resp, amountData, lp, _options, data, sequence, (await claimerBountyPrefetchPromise)!, nativeTokenAddress);
|
|
491
493
|
const [pricingInfo, signatureExpiry] = await Promise.all([
|
|
492
494
|
//Get intermediary's liquidity
|
|
493
495
|
this.verifyReturnedPrice(
|
|
494
496
|
lp.services[SwapType.FROM_BTC], false, resp.amount, resp.total,
|
|
495
|
-
amountData.token, {}, pricePrefetchPromise, usdPricePrefetchPromise, abortController.signal
|
|
497
|
+
amountData.token, {swapFeeBtc}, pricePrefetchPromise, usdPricePrefetchPromise, abortController.signal
|
|
496
498
|
),
|
|
497
499
|
this.verifyReturnedSignature(recipient, data, resp, feeRatePromise, signDataPromise, abortController.signal),
|
|
498
500
|
this.verifyIntermediaryLiquidity(data.getAmount(), throwIfUndefined(liquidityPromise)),
|
|
@@ -503,7 +505,7 @@ export class FromBTCWrapper<
|
|
|
503
505
|
url: lp.url,
|
|
504
506
|
expiry: signatureExpiry,
|
|
505
507
|
swapFee: resp.swapFee,
|
|
506
|
-
swapFeeBtc
|
|
508
|
+
swapFeeBtc,
|
|
507
509
|
feeRate: (await feeRatePromise)!,
|
|
508
510
|
signatureData: resp,
|
|
509
511
|
data,
|
|
@@ -309,10 +309,12 @@ export class ToBTCLNWrapper<T extends ChainType> extends IToBTCWrapper<T, ToBTCL
|
|
|
309
309
|
|
|
310
310
|
await this.verifyReturnedData(signer, resp, parsedPr, amountData.token, lp, calculatedOptions, data);
|
|
311
311
|
|
|
312
|
+
const swapFeeBtc = resp.swapFee * amountOut / (data.getAmount() - totalFee);
|
|
313
|
+
|
|
312
314
|
const [pricingInfo, signatureExpiry, reputation] = await Promise.all([
|
|
313
315
|
this.verifyReturnedPrice(
|
|
314
316
|
lp.services[SwapType.TO_BTCLN], true, amountOut, data.getAmount(),
|
|
315
|
-
amountData.token, {networkFee: resp.maxFee},
|
|
317
|
+
amountData.token, {networkFee: resp.maxFee, swapFeeBtc},
|
|
316
318
|
preFetches.pricePreFetchPromise, preFetches.usdPricePrefetchPromise, abortController.signal
|
|
317
319
|
),
|
|
318
320
|
this.verifyReturnedSignature(
|
|
@@ -324,8 +326,6 @@ export class ToBTCLNWrapper<T extends ChainType> extends IToBTCWrapper<T, ToBTCL
|
|
|
324
326
|
|
|
325
327
|
if(reputation!=null) lp.reputation[amountData.token.toString()] = reputation;
|
|
326
328
|
|
|
327
|
-
const swapFeeBtc = resp.swapFee * amountOut / (data.getAmount() - totalFee);
|
|
328
|
-
|
|
329
329
|
const quote = new ToBTCLNSwap<T>(this, {
|
|
330
330
|
pricingInfo,
|
|
331
331
|
url: lp.url,
|
|
@@ -512,10 +512,12 @@ export class ToBTCLNWrapper<T extends ChainType> extends IToBTCWrapper<T, ToBTCL
|
|
|
512
512
|
|
|
513
513
|
await this.verifyReturnedData(signer, resp, parsedInvoice, amountData.token, lp, calculatedOptions, data, amountData.amount);
|
|
514
514
|
|
|
515
|
+
const swapFeeBtc = resp.swapFee * amountOut / (data.getAmount() - totalFee);
|
|
516
|
+
|
|
515
517
|
const [pricingInfo, signatureExpiry, reputation] = await Promise.all([
|
|
516
518
|
this.verifyReturnedPrice(
|
|
517
519
|
lp.services[SwapType.TO_BTCLN], true, prepareResp.amount, data.getAmount(),
|
|
518
|
-
amountData.token, {networkFee: resp.maxFee},
|
|
520
|
+
amountData.token, {networkFee: resp.maxFee, swapFeeBtc},
|
|
519
521
|
preFetches.pricePreFetchPromise, preFetches.usdPricePrefetchPromise, abortSignal
|
|
520
522
|
),
|
|
521
523
|
this.verifyReturnedSignature(
|
|
@@ -527,8 +529,6 @@ export class ToBTCLNWrapper<T extends ChainType> extends IToBTCWrapper<T, ToBTCL
|
|
|
527
529
|
|
|
528
530
|
if(reputation!=null) lp.reputation[amountData.token.toString()] = reputation;
|
|
529
531
|
|
|
530
|
-
const swapFeeBtc = resp.swapFee * amountOut / (data.getAmount() - totalFee);
|
|
531
|
-
|
|
532
532
|
const quote = new ToBTCLNSwap<T>(this, {
|
|
533
533
|
pricingInfo,
|
|
534
534
|
url: lp.url,
|
|
@@ -289,11 +289,15 @@ export class ToBTCWrapper<T extends ChainType> extends IToBTCWrapper<T, ToBTCDef
|
|
|
289
289
|
const data: T["Data"] = new this._swapDataDeserializer(resp.data);
|
|
290
290
|
data.setOfferer(signer);
|
|
291
291
|
|
|
292
|
+
const inputWithoutFees = data.getAmount() - resp.swapFee - resp.networkFee;
|
|
293
|
+
const swapFeeBtc = resp.swapFee * resp.amount / inputWithoutFees;
|
|
294
|
+
const networkFeeBtc = resp.networkFee * resp.amount / inputWithoutFees;
|
|
295
|
+
|
|
292
296
|
this.verifyReturnedData(signer, resp, amountData, lp, _options, data, hash);
|
|
293
297
|
const [pricingInfo, signatureExpiry, reputation] = await Promise.all([
|
|
294
298
|
this.verifyReturnedPrice(
|
|
295
299
|
lp.services[SwapType.TO_BTC], true, resp.amount, data.getAmount(),
|
|
296
|
-
amountData.token, resp, pricePreFetchPromise, usdPricePrefetchPromise, abortController.signal
|
|
300
|
+
amountData.token, {networkFee: resp.networkFee, swapFeeBtc}, pricePreFetchPromise, usdPricePrefetchPromise, abortController.signal
|
|
297
301
|
),
|
|
298
302
|
this.verifyReturnedSignature(signer, data, resp, feeRatePromise, signDataPromise, abortController.signal),
|
|
299
303
|
reputationPromise
|
|
@@ -302,10 +306,6 @@ export class ToBTCWrapper<T extends ChainType> extends IToBTCWrapper<T, ToBTCDef
|
|
|
302
306
|
|
|
303
307
|
if(reputation!=null) lp.reputation[amountData.token.toString()] = reputation;
|
|
304
308
|
|
|
305
|
-
const inputWithoutFees = data.getAmount() - resp.swapFee - resp.networkFee;
|
|
306
|
-
const swapFeeBtc = resp.swapFee * resp.amount / inputWithoutFees;
|
|
307
|
-
const networkFeeBtc = resp.networkFee * resp.amount / inputWithoutFees
|
|
308
|
-
|
|
309
309
|
const quote = new ToBTCSwap<T>(this, {
|
|
310
310
|
pricingInfo,
|
|
311
311
|
url: lp.url,
|
|
@@ -398,7 +398,10 @@ export class SpvFromBTCSwap<T extends ChainType>
|
|
|
398
398
|
this.pricingInfo.satsBaseFee,
|
|
399
399
|
this.pricingInfo.feePPM,
|
|
400
400
|
this.getOutputWithoutFee().rawAmount,
|
|
401
|
-
this.outputSwapToken
|
|
401
|
+
this.outputSwapToken,
|
|
402
|
+
undefined,
|
|
403
|
+
undefined,
|
|
404
|
+
this.swapFeeBtc
|
|
402
405
|
);
|
|
403
406
|
this.pricingInfo.realPriceUsdPerBitcoin = usdPricePerBtc;
|
|
404
407
|
}
|
|
@@ -652,13 +652,13 @@ export class SpvFromBTCWrapper<
|
|
|
652
652
|
lp.services[SwapType.SPV_VAULT_FROM_BTC],
|
|
653
653
|
false, resp.btcAmountSwap,
|
|
654
654
|
resp.total * (100_000n + callerFeeShare) / 100_000n,
|
|
655
|
-
amountData.token, {}, pricePrefetchPromise, usdPricePrefetchPromise, abortController.signal
|
|
655
|
+
amountData.token, {swapFeeBtc: resp.swapFeeBtc}, pricePrefetchPromise, usdPricePrefetchPromise, abortController.signal
|
|
656
656
|
),
|
|
657
657
|
_options.gasAmount===0n ? Promise.resolve(undefined) : this.verifyReturnedPrice(
|
|
658
658
|
{...lp.services[SwapType.SPV_VAULT_FROM_BTC], swapBaseFee: 0}, //Base fee should be charged only on the amount, not on gas
|
|
659
659
|
false, resp.btcAmountGas,
|
|
660
660
|
resp.totalGas * (100_000n + callerFeeShare) / 100_000n,
|
|
661
|
-
nativeTokenAddress, {}, gasTokenPricePrefetchPromise, usdPricePrefetchPromise, abortController.signal
|
|
661
|
+
nativeTokenAddress, {swapFeeBtc: resp.gasSwapFeeBtc}, gasTokenPricePrefetchPromise, usdPricePrefetchPromise, abortController.signal
|
|
662
662
|
),
|
|
663
663
|
this.verifyReturnedData(resp, amountData, lp, _options, callerFeeShare, bitcoinFeeRatePromise, abortController.signal)
|
|
664
664
|
]);
|
|
@@ -68,7 +68,7 @@ export class LnForGasWrapper<T extends ChainType> extends ISwapWrapper<T, LnForG
|
|
|
68
68
|
{swapFeePPM: 10000, swapBaseFee: 10} :
|
|
69
69
|
lpOrUrl.services[SwapType.TRUSTED_FROM_BTCLN],
|
|
70
70
|
false, amountIn,
|
|
71
|
-
amount, token, {}
|
|
71
|
+
amount, token, {swapFeeBtc: resp.swapFeeSats}
|
|
72
72
|
);
|
|
73
73
|
|
|
74
74
|
const quoteInit: LnForGasSwapInit = {
|
|
@@ -105,7 +105,7 @@ export class OnchainForGasWrapper<T extends ChainType> extends ISwapWrapper<T, O
|
|
|
105
105
|
{swapFeePPM: 10000, swapBaseFee: 10} :
|
|
106
106
|
lpOrUrl.services[SwapType.TRUSTED_FROM_BTC],
|
|
107
107
|
false, resp.amountSats,
|
|
108
|
-
amount, this._chain.getNativeCurrencyAddress(), {}
|
|
108
|
+
amount, this._chain.getNativeCurrencyAddress(), {swapFeeBtc: resp.swapFeeSats}
|
|
109
109
|
);
|
|
110
110
|
|
|
111
111
|
const quote = new OnchainForGasSwap(this, {
|