@atomiqlabs/sdk 8.6.0 → 8.6.3
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/http/paramcoders/ParamDecoder.js +9 -4
- package/dist/http/paramcoders/ParamEncoder.js +6 -1
- package/dist/intermediaries/IntermediaryDiscovery.js +4 -3
- package/dist/storage/UnifiedSwapStorage.js +13 -8
- package/dist/swapper/Swapper.d.ts +1 -12
- package/dist/swapper/Swapper.js +31 -28
- package/dist/swapper/SwapperFactory.d.ts +1 -0
- package/dist/swapper/SwapperFactory.js +9 -4
- package/dist/swaps/ISwap.d.ts +8 -0
- package/dist/swaps/ISwap.js +8 -0
- package/dist/swaps/ISwapWrapper.d.ts +23 -1
- package/dist/swaps/ISwapWrapper.js +88 -28
- package/dist/swaps/escrow_swaps/IEscrowSwapWrapper.js +4 -1
- package/dist/swaps/escrow_swaps/frombtc/IFromBTCSelfInitSwap.d.ts +2 -2
- package/dist/swaps/escrow_swaps/frombtc/IFromBTCSelfInitSwap.js +1 -1
- package/dist/swaps/escrow_swaps/frombtc/ln/FromBTCLNSwap.d.ts +2 -2
- package/dist/swaps/escrow_swaps/frombtc/ln/FromBTCLNSwap.js +16 -6
- package/dist/swaps/escrow_swaps/frombtc/ln/FromBTCLNWrapper.js +8 -2
- package/dist/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoSwap.d.ts +1 -1
- package/dist/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoSwap.js +14 -4
- package/dist/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoWrapper.js +8 -6
- package/dist/swaps/escrow_swaps/frombtc/onchain/FromBTCSwap.d.ts +2 -1
- package/dist/swaps/escrow_swaps/frombtc/onchain/FromBTCSwap.js +7 -5
- package/dist/swaps/escrow_swaps/frombtc/onchain/FromBTCWrapper.js +8 -2
- package/dist/swaps/escrow_swaps/tobtc/IToBTCSwap.js +1 -1
- package/dist/swaps/escrow_swaps/tobtc/IToBTCWrapper.js +0 -6
- package/dist/swaps/escrow_swaps/tobtc/ln/ToBTCLNWrapper.js +8 -3
- package/dist/swaps/escrow_swaps/tobtc/onchain/ToBTCWrapper.js +8 -2
- package/dist/swaps/spv_swaps/SpvFromBTCSwap.d.ts +1 -0
- package/dist/swaps/spv_swaps/SpvFromBTCSwap.js +3 -2
- package/dist/swaps/spv_swaps/SpvFromBTCWrapper.js +1 -3
- package/dist/swaps/trusted/ln/LnForGasWrapper.js +0 -1
- package/dist/swaps/trusted/onchain/OnchainForGasWrapper.js +0 -1
- package/dist/utils/RetryUtils.d.ts +2 -1
- package/dist/utils/RetryUtils.js +3 -2
- package/package.json +1 -1
- package/src/http/paramcoders/ParamDecoder.ts +8 -4
- package/src/http/paramcoders/ParamEncoder.ts +5 -1
- package/src/intermediaries/IntermediaryDiscovery.ts +6 -4
- package/src/storage/UnifiedSwapStorage.ts +13 -8
- package/src/swapper/Swapper.ts +35 -28
- package/src/swapper/SwapperFactory.ts +12 -6
- package/src/swaps/ISwap.ts +8 -0
- package/src/swaps/ISwapWrapper.ts +104 -28
- package/src/swaps/escrow_swaps/IEscrowSwapWrapper.ts +5 -1
- package/src/swaps/escrow_swaps/frombtc/IFromBTCSelfInitSwap.ts +3 -3
- package/src/swaps/escrow_swaps/frombtc/ln/FromBTCLNSwap.ts +17 -8
- package/src/swaps/escrow_swaps/frombtc/ln/FromBTCLNWrapper.ts +8 -3
- package/src/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoSwap.ts +13 -5
- package/src/swaps/escrow_swaps/frombtc/ln_auto/FromBTCLNAutoWrapper.ts +8 -7
- package/src/swaps/escrow_swaps/frombtc/onchain/FromBTCSwap.ts +9 -5
- package/src/swaps/escrow_swaps/frombtc/onchain/FromBTCWrapper.ts +7 -2
- package/src/swaps/escrow_swaps/tobtc/IToBTCSwap.ts +1 -1
- package/src/swaps/escrow_swaps/tobtc/IToBTCWrapper.ts +0 -3
- package/src/swaps/escrow_swaps/tobtc/ln/ToBTCLNWrapper.ts +7 -3
- package/src/swaps/escrow_swaps/tobtc/onchain/ToBTCWrapper.ts +7 -2
- package/src/swaps/spv_swaps/SpvFromBTCSwap.ts +5 -2
- package/src/swaps/spv_swaps/SpvFromBTCWrapper.ts +1 -3
- package/src/swaps/trusted/ln/LnForGasWrapper.ts +0 -1
- package/src/swaps/trusted/onchain/OnchainForGasWrapper.ts +0 -1
- package/src/utils/RetryUtils.ts +11 -4
|
@@ -227,7 +227,7 @@ class SpvFromBTCSwap extends ISwap_1.ISwap {
|
|
|
227
227
|
*/
|
|
228
228
|
upgradeVersion() {
|
|
229
229
|
if (this.version === 1) {
|
|
230
|
-
this.posted = this.initiated;
|
|
230
|
+
this.posted = this.initiated && this._data != null;
|
|
231
231
|
this.version = 2;
|
|
232
232
|
}
|
|
233
233
|
}
|
|
@@ -1244,6 +1244,7 @@ class SpvFromBTCSwap extends ISwap_1.ISwap {
|
|
|
1244
1244
|
if (this._data?.btcTx == null)
|
|
1245
1245
|
return false;
|
|
1246
1246
|
//Check if bitcoin payment was confirmed
|
|
1247
|
+
this.btcTxLastChecked = Date.now();
|
|
1247
1248
|
const res = await this.getBitcoinPayment();
|
|
1248
1249
|
if (res == null) {
|
|
1249
1250
|
//Check inputs double-spent
|
|
@@ -1379,7 +1380,7 @@ class SpvFromBTCSwap extends ISwap_1.ISwap {
|
|
|
1379
1380
|
return true;
|
|
1380
1381
|
}
|
|
1381
1382
|
}
|
|
1382
|
-
if (
|
|
1383
|
+
if (this.btcTxLastChecked == null || Date.now() - this.btcTxLastChecked > 120000) {
|
|
1383
1384
|
if (this._state === SpvFromBTCSwapState.POSTED ||
|
|
1384
1385
|
this._state === SpvFromBTCSwapState.BROADCASTED) {
|
|
1385
1386
|
try {
|
|
@@ -39,6 +39,7 @@ class SpvFromBTCWrapper extends ISwapWrapper_1.ISwapWrapper {
|
|
|
39
39
|
*/
|
|
40
40
|
constructor(chainIdentifier, unifiedStorage, unifiedChainEvents, chain, contract, prices, tokens, spvWithdrawalDataDeserializer, btcRelay, synchronizer, btcRpc, options, events) {
|
|
41
41
|
super(chainIdentifier, unifiedStorage, unifiedChainEvents, chain, prices, tokens, {
|
|
42
|
+
...options,
|
|
42
43
|
bitcoinNetwork: options?.bitcoinNetwork ?? utils_1.TEST_NETWORK,
|
|
43
44
|
maxConfirmations: options?.maxConfirmations ?? 6,
|
|
44
45
|
bitcoinBlocktime: options?.bitcoinBlocktime ?? 10 * 60,
|
|
@@ -89,7 +90,6 @@ class SpvFromBTCWrapper extends ISwapWrapper_1.ISwapWrapper {
|
|
|
89
90
|
swap._state === SpvFromBTCSwap_1.SpvFromBTCSwapState.BROADCASTED || swap._state === SpvFromBTCSwap_1.SpvFromBTCSwapState.DECLINED ||
|
|
90
91
|
swap._state === SpvFromBTCSwap_1.SpvFromBTCSwapState.QUOTE_SOFT_EXPIRED || swap._state === SpvFromBTCSwap_1.SpvFromBTCSwapState.BTC_TX_CONFIRMED) {
|
|
91
92
|
swap._state = SpvFromBTCSwap_1.SpvFromBTCSwapState.FRONTED;
|
|
92
|
-
swap._frontTxId = event.meta?.txId;
|
|
93
93
|
await swap._setBitcoinTxId(event.btcTxId).catch(e => {
|
|
94
94
|
this.logger.warn("processEventFront(): Failed to set bitcoin txId: ", e);
|
|
95
95
|
});
|
|
@@ -103,7 +103,6 @@ class SpvFromBTCWrapper extends ISwapWrapper_1.ISwapWrapper {
|
|
|
103
103
|
swap._state === SpvFromBTCSwap_1.SpvFromBTCSwapState.QUOTE_SOFT_EXPIRED || swap._state === SpvFromBTCSwap_1.SpvFromBTCSwapState.FRONTED ||
|
|
104
104
|
swap._state === SpvFromBTCSwap_1.SpvFromBTCSwapState.BTC_TX_CONFIRMED) {
|
|
105
105
|
swap._state = SpvFromBTCSwap_1.SpvFromBTCSwapState.CLAIMED;
|
|
106
|
-
swap._claimTxId = event.meta?.txId;
|
|
107
106
|
await swap._setBitcoinTxId(event.btcTxId).catch(e => {
|
|
108
107
|
this.logger.warn("processEventClaim(): Failed to set bitcoin txId: ", e);
|
|
109
108
|
});
|
|
@@ -506,7 +505,6 @@ class SpvFromBTCWrapper extends ISwapWrapper_1.ISwapWrapper {
|
|
|
506
505
|
genesisSmartChainBlockHeight: await (0, Utils_1.throwIfUndefined)(finalizedBlockHeightPrefetchPromise, "Finalize block height promise failed!")
|
|
507
506
|
};
|
|
508
507
|
const quote = new SpvFromBTCSwap_1.SpvFromBTCSwap(this, swapInit);
|
|
509
|
-
await quote._save();
|
|
510
508
|
return quote;
|
|
511
509
|
}
|
|
512
510
|
catch (e) {
|
|
@@ -10,6 +10,7 @@ type Constructor<T = any> = new (...args: any[]) => T;
|
|
|
10
10
|
* @param retryPolicy.exponential Whether to use exponentially increasing delays
|
|
11
11
|
* @param errorAllowed A callback for determining whether a given error is allowed, and we should therefore not retry
|
|
12
12
|
* @param abortSignal
|
|
13
|
+
* @param failureLogLevel
|
|
13
14
|
* @returns Result of the action executing callback
|
|
14
15
|
* @category Utilities
|
|
15
16
|
*/
|
|
@@ -17,5 +18,5 @@ export declare function tryWithRetries<T>(func: (retryCount: number) => Promise<
|
|
|
17
18
|
maxRetries?: number;
|
|
18
19
|
delay?: number;
|
|
19
20
|
exponential?: boolean;
|
|
20
|
-
}, errorAllowed?: ((e: any) => boolean) | Constructor<Error> | Constructor<Error>[], abortSignal?: AbortSignal): Promise<T>;
|
|
21
|
+
}, errorAllowed?: ((e: any) => boolean) | Constructor<Error> | Constructor<Error>[], abortSignal?: AbortSignal, failureLogLevel?: "debug" | "info" | "warn" | "error"): Promise<T>;
|
|
21
22
|
export {};
|
package/dist/utils/RetryUtils.js
CHANGED
|
@@ -36,10 +36,11 @@ function checkError(e, errorAllowed) {
|
|
|
36
36
|
* @param retryPolicy.exponential Whether to use exponentially increasing delays
|
|
37
37
|
* @param errorAllowed A callback for determining whether a given error is allowed, and we should therefore not retry
|
|
38
38
|
* @param abortSignal
|
|
39
|
+
* @param failureLogLevel
|
|
39
40
|
* @returns Result of the action executing callback
|
|
40
41
|
* @category Utilities
|
|
41
42
|
*/
|
|
42
|
-
async function tryWithRetries(func, retryPolicy, errorAllowed, abortSignal) {
|
|
43
|
+
async function tryWithRetries(func, retryPolicy, errorAllowed, abortSignal, failureLogLevel = "warn") {
|
|
43
44
|
retryPolicy = retryPolicy || {};
|
|
44
45
|
retryPolicy.maxRetries = retryPolicy.maxRetries || 5;
|
|
45
46
|
retryPolicy.delay = retryPolicy.delay || 500;
|
|
@@ -53,7 +54,7 @@ async function tryWithRetries(func, retryPolicy, errorAllowed, abortSignal) {
|
|
|
53
54
|
if (errorAllowed != null && checkError(e, errorAllowed))
|
|
54
55
|
throw e;
|
|
55
56
|
err = e;
|
|
56
|
-
logger
|
|
57
|
+
logger[failureLogLevel]("tryWithRetries(): Error on try number: " + i, e);
|
|
57
58
|
}
|
|
58
59
|
if (abortSignal != null && abortSignal.aborted)
|
|
59
60
|
throw (abortSignal.reason || new Error("Aborted"));
|
package/package.json
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import {IParamReader} from "./IParamReader";
|
|
2
2
|
import {Buffer} from "buffer";
|
|
3
3
|
|
|
4
|
+
function ensureBuffer(input: any): Buffer {
|
|
5
|
+
if(input instanceof Buffer) return input;
|
|
6
|
+
return Buffer.from(input);
|
|
7
|
+
}
|
|
4
8
|
|
|
5
9
|
export class ParamDecoder implements IParamReader {
|
|
6
10
|
|
|
@@ -56,8 +60,8 @@ export class ParamDecoder implements IParamReader {
|
|
|
56
60
|
this.frameHeader = leavesBuffer;
|
|
57
61
|
leavesBuffer = null;
|
|
58
62
|
} else {
|
|
59
|
-
this.frameHeader = leavesBuffer.subarray(0, 4);
|
|
60
|
-
leavesBuffer = leavesBuffer.subarray(4);
|
|
63
|
+
this.frameHeader = ensureBuffer(leavesBuffer.subarray(0, 4));
|
|
64
|
+
leavesBuffer = ensureBuffer(leavesBuffer.subarray(4));
|
|
61
65
|
}
|
|
62
66
|
} else if(this.frameHeader.length<4) {
|
|
63
67
|
const requiredLen = 4-this.frameHeader.length;
|
|
@@ -66,13 +70,13 @@ export class ParamDecoder implements IParamReader {
|
|
|
66
70
|
leavesBuffer = null;
|
|
67
71
|
} else {
|
|
68
72
|
this.frameHeader = Buffer.concat([this.frameHeader, leavesBuffer.subarray(0, requiredLen)]);
|
|
69
|
-
leavesBuffer = leavesBuffer.subarray(requiredLen);
|
|
73
|
+
leavesBuffer = ensureBuffer(leavesBuffer.subarray(requiredLen));
|
|
70
74
|
}
|
|
71
75
|
}
|
|
72
76
|
if(leavesBuffer==null) continue;
|
|
73
77
|
if(this.frameHeader==null || this.frameHeader.length<4) continue;
|
|
74
78
|
|
|
75
|
-
const frameLength = this.frameHeader.readUint32LE();
|
|
79
|
+
const frameLength = this.frameHeader.readUint32LE!=null ? this.frameHeader.readUint32LE() : this.frameHeader.readUInt32LE();
|
|
76
80
|
const requiredLen = frameLength-this.frameDataLength;
|
|
77
81
|
|
|
78
82
|
if(leavesBuffer.length<=requiredLen) {
|
|
@@ -19,7 +19,11 @@ export class ParamEncoder {
|
|
|
19
19
|
const serialized: Buffer = Buffer.from(JSON.stringify(data));
|
|
20
20
|
|
|
21
21
|
const frameLengthBuffer = Buffer.alloc(4);
|
|
22
|
-
frameLengthBuffer.writeUint32LE
|
|
22
|
+
if(frameLengthBuffer.writeUint32LE!=null) {
|
|
23
|
+
frameLengthBuffer.writeUint32LE(serialized.length);
|
|
24
|
+
} else {
|
|
25
|
+
frameLengthBuffer.writeUInt32LE(serialized.length);
|
|
26
|
+
}
|
|
23
27
|
|
|
24
28
|
return this.writeFN(Buffer.concat([
|
|
25
29
|
frameLengthBuffer,
|
|
@@ -241,7 +241,8 @@ export class IntermediaryDiscovery extends EventEmitter {
|
|
|
241
241
|
() => IntermediaryAPI.getIntermediaryInfo(url, this.httpRequestTimeout, abortSignal),
|
|
242
242
|
{maxRetries: 3, delay: 100, exponential: true},
|
|
243
243
|
undefined,
|
|
244
|
-
abortSignal
|
|
244
|
+
abortSignal,
|
|
245
|
+
"debug"
|
|
245
246
|
);
|
|
246
247
|
abortSignal?.throwIfAborted();
|
|
247
248
|
|
|
@@ -255,7 +256,7 @@ export class IntermediaryDiscovery extends EventEmitter {
|
|
|
255
256
|
await this.swapContracts[chain].isValidDataSignature(Buffer.from(response.envelope), signature, address);
|
|
256
257
|
addresses[chain] = address;
|
|
257
258
|
} catch (e) {
|
|
258
|
-
logger.warn("Failed to verify "+chain+" signature for intermediary: "+url);
|
|
259
|
+
logger.warn("getNodeInfo(): Failed to verify "+chain+" signature for intermediary: "+url);
|
|
259
260
|
}
|
|
260
261
|
})());
|
|
261
262
|
}
|
|
@@ -303,8 +304,9 @@ export class IntermediaryDiscovery extends EventEmitter {
|
|
|
303
304
|
services[swapHandlerTypeToSwapType(key as SwapHandlerType)] = nodeInfo.info.services[key as SwapHandlerType];
|
|
304
305
|
}
|
|
305
306
|
return new Intermediary(url, nodeInfo.addresses, services);
|
|
306
|
-
} catch (e) {
|
|
307
|
-
logger.warn("fetchIntermediaries():
|
|
307
|
+
} catch (e: any) {
|
|
308
|
+
logger.warn("fetchIntermediaries(): Intermediary "+url+` is unreachable due to ${e.name ?? e.message} error, skipping...`);
|
|
309
|
+
logger.debug("fetchIntermediaries(): Error contacting intermediary "+url+": ", e);
|
|
308
310
|
return null;
|
|
309
311
|
}
|
|
310
312
|
}
|
|
@@ -89,6 +89,7 @@ export class UnifiedSwapStorage<T extends ChainType> {
|
|
|
89
89
|
}
|
|
90
90
|
const value = reviver(rawObj);
|
|
91
91
|
if(value==null) return;
|
|
92
|
+
value._persisted = true;
|
|
92
93
|
if(!this.noWeakRefMap) this.weakRefCache.set(rawObj.id, new WeakRef<ISwap<T>>(value));
|
|
93
94
|
result.push(value);
|
|
94
95
|
});
|
|
@@ -101,36 +102,40 @@ export class UnifiedSwapStorage<T extends ChainType> {
|
|
|
101
102
|
*
|
|
102
103
|
* @param value Swap to save
|
|
103
104
|
*/
|
|
104
|
-
save<S extends ISwap<T>>(value: S): Promise<void> {
|
|
105
|
+
async save<S extends ISwap<T>>(value: S): Promise<void> {
|
|
105
106
|
if(!this.noWeakRefMap) this.weakRefCache.set(value.getId(), new WeakRef<ISwap<T>>(value));
|
|
106
|
-
|
|
107
|
+
await this.storage.save(value.serialize());
|
|
108
|
+
value._persisted = true;
|
|
107
109
|
}
|
|
108
110
|
|
|
109
111
|
/**
|
|
110
112
|
* Saves multiple swaps to storage in a batch operation
|
|
111
113
|
* @param values Array of swaps to save
|
|
112
114
|
*/
|
|
113
|
-
saveAll<S extends ISwap<T>>(values: S[]): Promise<void> {
|
|
115
|
+
async saveAll<S extends ISwap<T>>(values: S[]): Promise<void> {
|
|
114
116
|
if(!this.noWeakRefMap) values.forEach(value => this.weakRefCache.set(value.getId(), new WeakRef<ISwap<T>>(value)));
|
|
115
|
-
|
|
117
|
+
await this.storage.saveAll(values.map(obj => obj.serialize()));
|
|
118
|
+
values.forEach(value => value._persisted = true);
|
|
116
119
|
}
|
|
117
120
|
|
|
118
121
|
/**
|
|
119
122
|
* Removes a swap from storage
|
|
120
123
|
* @param value Swap to remove
|
|
121
124
|
*/
|
|
122
|
-
remove<S extends ISwap<T>>(value: S): Promise<void> {
|
|
125
|
+
async remove<S extends ISwap<T>>(value: S): Promise<void> {
|
|
123
126
|
if(!this.noWeakRefMap) this.weakRefCache.delete(value.getId());
|
|
124
|
-
|
|
127
|
+
await this.storage.remove(value.serialize());
|
|
128
|
+
value._persisted = false;
|
|
125
129
|
}
|
|
126
130
|
|
|
127
131
|
/**
|
|
128
132
|
* Removes multiple swaps from storage in a batch operation
|
|
129
133
|
* @param values Array of swaps to remove
|
|
130
134
|
*/
|
|
131
|
-
removeAll<S extends ISwap<T>>(values: S[]): Promise<void> {
|
|
135
|
+
async removeAll<S extends ISwap<T>>(values: S[]): Promise<void> {
|
|
132
136
|
if(!this.noWeakRefMap) values.forEach(value => this.weakRefCache.delete(value.getId()));
|
|
133
|
-
|
|
137
|
+
await this.storage.removeAll(values.map(obj => obj.serialize()));
|
|
138
|
+
values.forEach(value => value._persisted = false);
|
|
134
139
|
}
|
|
135
140
|
|
|
136
141
|
}
|
package/src/swapper/Swapper.ts
CHANGED
|
@@ -316,7 +316,7 @@ export class Swapper<T extends MultiChain> extends EventEmitter<{
|
|
|
316
316
|
bitcoinSynchronizer: (btcRelay: BtcRelay<any, any, any>) => RelaySynchronizer<any, any, any>,
|
|
317
317
|
chainsData: CtorMultiChainData<T>,
|
|
318
318
|
pricing: ISwapPrice<T>,
|
|
319
|
-
tokens:
|
|
319
|
+
tokens: SCToken[],
|
|
320
320
|
messenger: Messenger,
|
|
321
321
|
options?: SwapperOptions
|
|
322
322
|
) {
|
|
@@ -347,22 +347,10 @@ export class Swapper<T extends MultiChain> extends EventEmitter<{
|
|
|
347
347
|
this._tokens = {};
|
|
348
348
|
this._tokensByTicker = {};
|
|
349
349
|
for(let tokenData of tokens) {
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
this._tokens[chainId][chainData.address] = this._tokensByTicker[chainId][tokenData.ticker] = {
|
|
355
|
-
chain: "SC",
|
|
356
|
-
chainId,
|
|
357
|
-
ticker: tokenData.ticker,
|
|
358
|
-
name: tokenData.name,
|
|
359
|
-
decimals: chainData.decimals,
|
|
360
|
-
displayDecimals: chainData.displayDecimals,
|
|
361
|
-
address: chainData.address,
|
|
362
|
-
equals: (other: Token) => other.chainId===chainId && other.ticker===tokenData.ticker && other.address===chainData.address,
|
|
363
|
-
toString: () => `${chainId}-${tokenData.ticker}`
|
|
364
|
-
}
|
|
365
|
-
}
|
|
350
|
+
const chainId = tokenData.chainId;
|
|
351
|
+
this._tokens[chainId] ??= {};
|
|
352
|
+
this._tokensByTicker[chainId] ??= {};
|
|
353
|
+
this._tokens[chainId][tokenData.address] = this._tokensByTicker[chainId][tokenData.ticker] = tokenData;
|
|
366
354
|
}
|
|
367
355
|
|
|
368
356
|
this.swapStateListener = (swap: ISwap) => {
|
|
@@ -395,6 +383,7 @@ export class Swapper<T extends MultiChain> extends EventEmitter<{
|
|
|
395
383
|
{
|
|
396
384
|
getRequestTimeout: this.options.getRequestTimeout,
|
|
397
385
|
postRequestTimeout: this.options.postRequestTimeout,
|
|
386
|
+
saveUninitializedSwaps: this.options.saveUninitializedSwaps,
|
|
398
387
|
}
|
|
399
388
|
);
|
|
400
389
|
wrappers[SwapType.TO_BTC] = new ToBTCWrapper<T[InputKey]>(
|
|
@@ -410,6 +399,7 @@ export class Swapper<T extends MultiChain> extends EventEmitter<{
|
|
|
410
399
|
{
|
|
411
400
|
getRequestTimeout: this.options.getRequestTimeout,
|
|
412
401
|
postRequestTimeout: this.options.postRequestTimeout,
|
|
402
|
+
saveUninitializedSwaps: this.options.saveUninitializedSwaps,
|
|
413
403
|
bitcoinNetwork: this._btcNetwork
|
|
414
404
|
}
|
|
415
405
|
);
|
|
@@ -426,6 +416,7 @@ export class Swapper<T extends MultiChain> extends EventEmitter<{
|
|
|
426
416
|
{
|
|
427
417
|
getRequestTimeout: this.options.getRequestTimeout,
|
|
428
418
|
postRequestTimeout: this.options.postRequestTimeout,
|
|
419
|
+
saveUninitializedSwaps: this.options.saveUninitializedSwaps,
|
|
429
420
|
unsafeSkipLnNodeCheck: this.bitcoinNetwork===BitcoinNetwork.TESTNET4 || this.bitcoinNetwork===BitcoinNetwork.REGTEST
|
|
430
421
|
}
|
|
431
422
|
);
|
|
@@ -444,6 +435,7 @@ export class Swapper<T extends MultiChain> extends EventEmitter<{
|
|
|
444
435
|
{
|
|
445
436
|
getRequestTimeout: this.options.getRequestTimeout,
|
|
446
437
|
postRequestTimeout: this.options.postRequestTimeout,
|
|
438
|
+
saveUninitializedSwaps: this.options.saveUninitializedSwaps,
|
|
447
439
|
bitcoinNetwork: this._btcNetwork
|
|
448
440
|
}
|
|
449
441
|
);
|
|
@@ -456,7 +448,8 @@ export class Swapper<T extends MultiChain> extends EventEmitter<{
|
|
|
456
448
|
this._tokens[chainId],
|
|
457
449
|
{
|
|
458
450
|
getRequestTimeout: this.options.getRequestTimeout,
|
|
459
|
-
postRequestTimeout: this.options.postRequestTimeout
|
|
451
|
+
postRequestTimeout: this.options.postRequestTimeout,
|
|
452
|
+
saveUninitializedSwaps: this.options.saveUninitializedSwaps,
|
|
460
453
|
}
|
|
461
454
|
);
|
|
462
455
|
wrappers[SwapType.TRUSTED_FROM_BTC] = new OnchainForGasWrapper<T[InputKey]>(
|
|
@@ -470,6 +463,7 @@ export class Swapper<T extends MultiChain> extends EventEmitter<{
|
|
|
470
463
|
{
|
|
471
464
|
getRequestTimeout: this.options.getRequestTimeout,
|
|
472
465
|
postRequestTimeout: this.options.postRequestTimeout,
|
|
466
|
+
saveUninitializedSwaps: this.options.saveUninitializedSwaps,
|
|
473
467
|
bitcoinNetwork: this._btcNetwork
|
|
474
468
|
}
|
|
475
469
|
);
|
|
@@ -490,6 +484,7 @@ export class Swapper<T extends MultiChain> extends EventEmitter<{
|
|
|
490
484
|
{
|
|
491
485
|
getRequestTimeout: this.options.getRequestTimeout,
|
|
492
486
|
postRequestTimeout: this.options.postRequestTimeout,
|
|
487
|
+
saveUninitializedSwaps: this.options.saveUninitializedSwaps,
|
|
493
488
|
bitcoinNetwork: this._btcNetwork
|
|
494
489
|
}
|
|
495
490
|
);
|
|
@@ -510,6 +505,7 @@ export class Swapper<T extends MultiChain> extends EventEmitter<{
|
|
|
510
505
|
{
|
|
511
506
|
getRequestTimeout: this.options.getRequestTimeout,
|
|
512
507
|
postRequestTimeout: this.options.postRequestTimeout,
|
|
508
|
+
saveUninitializedSwaps: this.options.saveUninitializedSwaps,
|
|
513
509
|
unsafeSkipLnNodeCheck: this.bitcoinNetwork===BitcoinNetwork.TESTNET4 || this.bitcoinNetwork===BitcoinNetwork.REGTEST
|
|
514
510
|
}
|
|
515
511
|
);
|
|
@@ -557,7 +553,7 @@ export class Swapper<T extends MultiChain> extends EventEmitter<{
|
|
|
557
553
|
}
|
|
558
554
|
|
|
559
555
|
private async _init(): Promise<void> {
|
|
560
|
-
this.logger.debug("init(): Initializing swapper
|
|
556
|
+
this.logger.debug("init(): Initializing swapper...");
|
|
561
557
|
|
|
562
558
|
const abortController = new AbortController();
|
|
563
559
|
|
|
@@ -598,12 +594,19 @@ export class Swapper<T extends MultiChain> extends EventEmitter<{
|
|
|
598
594
|
for(let chainIdentifier in this._chains) {
|
|
599
595
|
chainPromises.push((async() => {
|
|
600
596
|
const {
|
|
597
|
+
chainInterface,
|
|
601
598
|
swapContract,
|
|
602
599
|
unifiedChainEvents,
|
|
603
600
|
unifiedSwapStorage,
|
|
604
601
|
wrappers,
|
|
605
602
|
reviver
|
|
606
603
|
} = this._chains[chainIdentifier];
|
|
604
|
+
|
|
605
|
+
const _chainInterface: any = chainInterface;
|
|
606
|
+
if(_chainInterface.verifyNetwork!=null) {
|
|
607
|
+
await _chainInterface.verifyNetwork(this.bitcoinNetwork);
|
|
608
|
+
}
|
|
609
|
+
|
|
607
610
|
await swapContract.start();
|
|
608
611
|
this.logger.debug("init(): Intialized swap contract: "+chainIdentifier);
|
|
609
612
|
|
|
@@ -659,7 +662,10 @@ export class Swapper<T extends MultiChain> extends EventEmitter<{
|
|
|
659
662
|
*/
|
|
660
663
|
async init(): Promise<void> {
|
|
661
664
|
if(this.initialized) return;
|
|
662
|
-
if(this.initPromise!=null)
|
|
665
|
+
if(this.initPromise!=null) {
|
|
666
|
+
await this.initPromise;
|
|
667
|
+
return;
|
|
668
|
+
}
|
|
663
669
|
|
|
664
670
|
try {
|
|
665
671
|
const promise = this._init();
|
|
@@ -856,10 +862,7 @@ export class Swapper<T extends MultiChain> extends EventEmitter<{
|
|
|
856
862
|
if(swapLimitsChanged) this.emit("swapLimitsChanged");
|
|
857
863
|
|
|
858
864
|
const quote = quotes[0].quote;
|
|
859
|
-
|
|
860
|
-
quote._setInitiated();
|
|
861
|
-
await quote._save();
|
|
862
|
-
}
|
|
865
|
+
await quote._save();
|
|
863
866
|
return quote;
|
|
864
867
|
} catch (e) {
|
|
865
868
|
if(swapLimitsChanged) this.emit("swapLimitsChanged");
|
|
@@ -1334,13 +1337,15 @@ export class Swapper<T extends MultiChain> extends EventEmitter<{
|
|
|
1334
1337
|
* @param trustedIntermediaryOrUrl URL or Intermediary object of the trusted intermediary to use, otherwise uses default
|
|
1335
1338
|
* @throws {Error} If no trusted intermediary specified
|
|
1336
1339
|
*/
|
|
1337
|
-
createTrustedLNForGasSwap<C extends ChainIds<T>>(chainIdentifier: C, recipient: string, amount: bigint, trustedIntermediaryOrUrl?: Intermediary | string): Promise<LnForGasSwap<T[C]>> {
|
|
1340
|
+
async createTrustedLNForGasSwap<C extends ChainIds<T>>(chainIdentifier: C, recipient: string, amount: bigint, trustedIntermediaryOrUrl?: Intermediary | string): Promise<LnForGasSwap<T[C]>> {
|
|
1338
1341
|
if(this._chains[chainIdentifier]==null) throw new Error("Invalid chain identifier! Unknown chain: "+chainIdentifier);
|
|
1339
1342
|
if(!this._chains[chainIdentifier].chainInterface.isValidAddress(recipient, true)) throw new Error("Invalid "+chainIdentifier+" address");
|
|
1340
1343
|
recipient = this._chains[chainIdentifier].chainInterface.normalizeAddress(recipient);
|
|
1341
1344
|
const useUrl = trustedIntermediaryOrUrl ?? this.defaultTrustedIntermediary ?? this.options.defaultTrustedIntermediaryUrl;
|
|
1342
1345
|
if(useUrl==null) throw new Error("No trusted intermediary specified!");
|
|
1343
|
-
|
|
1346
|
+
const swap = await this._chains[chainIdentifier as C].wrappers[SwapType.TRUSTED_FROM_BTCLN].create(recipient, amount, useUrl);
|
|
1347
|
+
await swap._save();
|
|
1348
|
+
return swap;
|
|
1344
1349
|
}
|
|
1345
1350
|
|
|
1346
1351
|
/**
|
|
@@ -1353,7 +1358,7 @@ export class Swapper<T extends MultiChain> extends EventEmitter<{
|
|
|
1353
1358
|
* @param trustedIntermediaryOrUrl URL or Intermediary object of the trusted intermediary to use, otherwise uses default
|
|
1354
1359
|
* @throws {Error} If no trusted intermediary specified
|
|
1355
1360
|
*/
|
|
1356
|
-
createTrustedOnchainForGasSwap<C extends ChainIds<T>>(
|
|
1361
|
+
async createTrustedOnchainForGasSwap<C extends ChainIds<T>>(
|
|
1357
1362
|
chainIdentifier: C, recipient: string,
|
|
1358
1363
|
amount: bigint, refundAddress?: string,
|
|
1359
1364
|
trustedIntermediaryOrUrl?: Intermediary | string
|
|
@@ -1363,7 +1368,9 @@ export class Swapper<T extends MultiChain> extends EventEmitter<{
|
|
|
1363
1368
|
recipient = this._chains[chainIdentifier].chainInterface.normalizeAddress(recipient);
|
|
1364
1369
|
const useUrl = trustedIntermediaryOrUrl ?? this.defaultTrustedIntermediary ?? this.options.defaultTrustedIntermediaryUrl;
|
|
1365
1370
|
if(useUrl==null) throw new Error("No trusted intermediary specified!");
|
|
1366
|
-
|
|
1371
|
+
const swap = await this._chains[chainIdentifier as C].wrappers[SwapType.TRUSTED_FROM_BTC].create(recipient, amount, useUrl, refundAddress);
|
|
1372
|
+
await swap._save();
|
|
1373
|
+
return swap;
|
|
1367
1374
|
}
|
|
1368
1375
|
|
|
1369
1376
|
/**
|
|
@@ -9,7 +9,7 @@ import {SmartChainAssets, SmartChainAssetTickers} from "../SmartChainAssets";
|
|
|
9
9
|
import {NostrMessenger} from "@atomiqlabs/messenger-nostr";
|
|
10
10
|
import {Swapper, SwapperOptions} from "./Swapper";
|
|
11
11
|
import {CustomPriceProvider} from "../prices/providers/CustomPriceProvider";
|
|
12
|
-
import {BitcoinTokens, BtcToken, SCToken} from "../types/Token";
|
|
12
|
+
import {BitcoinTokens, BtcToken, SCToken, Token} from "../types/Token";
|
|
13
13
|
import {SwapType} from "../enums/SwapType";
|
|
14
14
|
import {SwapTypeMapping} from "../utils/SwapUtils";
|
|
15
15
|
import {RedundantSwapPrice, RedundantSwapPriceAssets} from "../prices/RedundantSwapPrice";
|
|
@@ -191,6 +191,8 @@ export class SwapperFactory<T extends readonly ChainInitializer<any, ChainType,
|
|
|
191
191
|
*/
|
|
192
192
|
TokenResolver: TypedTokenResolvers<T> = {} as any;
|
|
193
193
|
|
|
194
|
+
private smartChainTokens: SCToken[] = [];
|
|
195
|
+
|
|
194
196
|
constructor(readonly initializers: T) {
|
|
195
197
|
this.initializers = initializers;
|
|
196
198
|
initializers.forEach(initializer => {
|
|
@@ -200,15 +202,19 @@ export class SwapperFactory<T extends readonly ChainInitializer<any, ChainType,
|
|
|
200
202
|
|
|
201
203
|
for(let ticker in initializer.tokens) {
|
|
202
204
|
const assetData = initializer.tokens[ticker] as any;
|
|
203
|
-
|
|
205
|
+
const token: SCToken = {
|
|
204
206
|
chain: "SC",
|
|
205
207
|
chainId: initializer.chainId,
|
|
206
|
-
|
|
208
|
+
ticker,
|
|
207
209
|
name: SmartChainAssets[ticker as SmartChainAssetTickers]?.name ?? ticker,
|
|
208
210
|
decimals: assetData.decimals,
|
|
209
211
|
displayDecimals: assetData.displayDecimals,
|
|
210
|
-
|
|
211
|
-
|
|
212
|
+
address: assetData.address,
|
|
213
|
+
equals: (other: Token) => other.chainId===initializer.chainId && other.ticker===ticker && other.address===assetData.address,
|
|
214
|
+
toString: () => `${initializer.chainId}-${ticker}`
|
|
215
|
+
};
|
|
216
|
+
this.smartChainTokens.push(token);
|
|
217
|
+
tokens[ticker] = addressMap[assetData.address] = token;
|
|
212
218
|
}
|
|
213
219
|
|
|
214
220
|
this.TokenResolver[initializer.chainId as keyof TypedTokenResolvers<T>] = {
|
|
@@ -280,7 +286,7 @@ export class SwapperFactory<T extends readonly ChainInitializer<any, ChainType,
|
|
|
280
286
|
(btcRelay: BtcRelay<any, any, any>) => new MempoolBtcRelaySynchronizer(btcRelay, bitcoinRpc),
|
|
281
287
|
chains as any,
|
|
282
288
|
swapPricing,
|
|
283
|
-
|
|
289
|
+
this.smartChainTokens,
|
|
284
290
|
options.messenger,
|
|
285
291
|
options
|
|
286
292
|
);
|
package/src/swaps/ISwap.ts
CHANGED
|
@@ -132,6 +132,14 @@ export abstract class ISwap<
|
|
|
132
132
|
* @internal
|
|
133
133
|
*/
|
|
134
134
|
_randomNonce: string;
|
|
135
|
+
/**
|
|
136
|
+
* Whether the swap is saved in the persistent storage or not.
|
|
137
|
+
*
|
|
138
|
+
* @remarks This field itself is not persisted but is instead derived during runtime
|
|
139
|
+
*
|
|
140
|
+
* @internal
|
|
141
|
+
*/
|
|
142
|
+
_persisted: boolean = false;
|
|
135
143
|
|
|
136
144
|
|
|
137
145
|
/**
|