@atomiqlabs/base 13.0.4 → 13.1.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/btc/lightning/LightningNetworkApi.d.ts +23 -0
- package/dist/btc/lightning/LightningNetworkApi.js +2 -0
- package/dist/btc/rpc/BitcoinRpc.d.ts +6 -0
- package/dist/btc/rpc/BitcoinRpcWithAddressIndex.d.ts +112 -0
- package/dist/btc/rpc/BitcoinRpcWithAddressIndex.js +2 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +6 -0
- package/dist/storage/VoidStorageManager.d.ts +33 -0
- package/dist/storage/VoidStorageManager.js +42 -0
- package/dist/utils/Logger.d.ts +17 -0
- package/dist/utils/Logger.js +17 -0
- package/dist/utils/RetryUtils.d.ts +23 -0
- package/dist/utils/RetryUtils.js +68 -0
- package/dist/utils/TimeoutUtils.d.ts +19 -0
- package/dist/utils/TimeoutUtils.js +57 -0
- package/package.json +1 -1
- package/src/btc/lightning/LightningNetworkApi.ts +27 -0
- package/src/btc/rpc/BitcoinRpc.ts +7 -0
- package/src/btc/rpc/BitcoinRpcWithAddressIndex.ts +138 -0
- package/src/index.ts +6 -0
- package/src/storage/VoidStorageManager.ts +42 -0
- package/src/utils/Logger.ts +25 -0
- package/src/utils/RetryUtils.ts +73 -0
- package/src/utils/TimeoutUtils.ts +52 -0
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A type defining total capacity of a given lightning network node
|
|
3
|
+
*
|
|
4
|
+
* @category Bitcoin
|
|
5
|
+
*/
|
|
6
|
+
export type LNNodeLiquidity = {
|
|
7
|
+
publicKey: string;
|
|
8
|
+
capacity: bigint;
|
|
9
|
+
numChannels: number;
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* An interface for Lightning API, provides view of the public lightning network data like channel graph
|
|
13
|
+
*
|
|
14
|
+
* @category Bitcoin
|
|
15
|
+
*/
|
|
16
|
+
export interface LightningNetworkApi {
|
|
17
|
+
/**
|
|
18
|
+
* Returns the lightning network's node liquidity as identified by an identity public key
|
|
19
|
+
*
|
|
20
|
+
* @param pubkey
|
|
21
|
+
*/
|
|
22
|
+
getLNNodeLiquidity(pubkey: string): Promise<LNNodeLiquidity | null>;
|
|
23
|
+
}
|
|
@@ -226,4 +226,10 @@ export interface BitcoinRpc<T extends BtcBlock> {
|
|
|
226
226
|
fee: number;
|
|
227
227
|
feeRate: number;
|
|
228
228
|
}>;
|
|
229
|
+
/**
|
|
230
|
+
* Parses a bitcoin address from the passed output script in hexadecimal format
|
|
231
|
+
*
|
|
232
|
+
* @param outputScriptHex
|
|
233
|
+
*/
|
|
234
|
+
outputScriptToAddress?(outputScriptHex: string): Promise<string>;
|
|
229
235
|
}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { Buffer } from "buffer";
|
|
3
|
+
import { BitcoinRpc, BtcTx } from "./BitcoinRpc";
|
|
4
|
+
import { BtcBlock } from "../../btcrelay/types/BtcBlock";
|
|
5
|
+
/**
|
|
6
|
+
* A type defining a bitcoin transaction with its blockheight and optional input addresses populated
|
|
7
|
+
*
|
|
8
|
+
* @category Bitcoin
|
|
9
|
+
*/
|
|
10
|
+
export type BtcTxWithBlockheight = BtcTx & {
|
|
11
|
+
blockheight?: number;
|
|
12
|
+
inputAddresses?: string[];
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* A type defining a single UTXO belonging to an address
|
|
16
|
+
*
|
|
17
|
+
* @category Bitcoin
|
|
18
|
+
*/
|
|
19
|
+
export type BtcAddressUtxo = {
|
|
20
|
+
txid: string;
|
|
21
|
+
vout: number;
|
|
22
|
+
confirmed: boolean;
|
|
23
|
+
block_height: number;
|
|
24
|
+
block_hash: string;
|
|
25
|
+
block_time: number;
|
|
26
|
+
value: bigint;
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* An extended interface for Bitcoin, that allows querying balances and UTXOs of any address + other utilities
|
|
30
|
+
*
|
|
31
|
+
* @category Bitcoin
|
|
32
|
+
*/
|
|
33
|
+
export interface BitcoinRpcWithAddressIndex<T extends BtcBlock> extends BitcoinRpc<T> {
|
|
34
|
+
/**
|
|
35
|
+
* Returns the current fee rate required for submitted bitcoin transactions in sats/vB
|
|
36
|
+
*/
|
|
37
|
+
getFeeRate(): Promise<number>;
|
|
38
|
+
/**
|
|
39
|
+
* Returns confirmed & unconfirmed balances for a given wallet address
|
|
40
|
+
*
|
|
41
|
+
* @param address
|
|
42
|
+
*/
|
|
43
|
+
getAddressBalances(address: string): Promise<{
|
|
44
|
+
confirmedBalance: bigint;
|
|
45
|
+
unconfirmedBalance: bigint;
|
|
46
|
+
}>;
|
|
47
|
+
/**
|
|
48
|
+
* Returns UTXOs owned by the given wallet address
|
|
49
|
+
* @param address
|
|
50
|
+
*/
|
|
51
|
+
getAddressUTXOs(address: string): Promise<BtcAddressUtxo[]>;
|
|
52
|
+
/**
|
|
53
|
+
* Returns CPFP (children-pay-for-parent) data for a given transaction, or null if transaction is not found
|
|
54
|
+
* or already confirmed
|
|
55
|
+
*
|
|
56
|
+
* @param txId
|
|
57
|
+
*/
|
|
58
|
+
getCPFPData(txId: string): Promise<{
|
|
59
|
+
effectiveFeePerVsize: number;
|
|
60
|
+
adjustedVsize: number;
|
|
61
|
+
} | null>;
|
|
62
|
+
/**
|
|
63
|
+
* @inheritDoc
|
|
64
|
+
*/
|
|
65
|
+
getTransaction(txId: string): Promise<BtcTxWithBlockheight | null>;
|
|
66
|
+
/**
|
|
67
|
+
* Awaits till the given transaction gets confirmed
|
|
68
|
+
*
|
|
69
|
+
* @param txId Transaction ID to monitor
|
|
70
|
+
* @param requiredConfirmations Required number of confirmations
|
|
71
|
+
* @param stateUpdateCbk Optional update callback called with the current status of the bitcoin transaction
|
|
72
|
+
* @param abortSignal
|
|
73
|
+
* @param intervalSeconds How often to poll
|
|
74
|
+
*/
|
|
75
|
+
waitForTransaction(txId: string, requiredConfirmations: number, stateUpdateCbk?: (btcTx?: BtcTxWithBlockheight, txEtaMS?: number) => void, abortSignal?: AbortSignal, intervalSeconds?: number): Promise<BtcTxWithBlockheight>;
|
|
76
|
+
/**
|
|
77
|
+
* Returns an estimate after which time the tx will confirm with the required amount of confirmations,
|
|
78
|
+
* confirmationDelay of -1 means the transaction won't confirm in the near future
|
|
79
|
+
*
|
|
80
|
+
* @param tx
|
|
81
|
+
* @param requiredConfirmations
|
|
82
|
+
*
|
|
83
|
+
* @returns estimated confirmation delay, -1 if the transaction won't confirm in the near future, null if the
|
|
84
|
+
* transaction was replaced or was confirmed in the meantime
|
|
85
|
+
*/
|
|
86
|
+
getConfirmationDelay(tx: BtcTx, requiredConfirmations: number): Promise<number | null>;
|
|
87
|
+
/**
|
|
88
|
+
* Checks if an address received the transaction with the required txoHash, returns info about that
|
|
89
|
+
* specific transaction if found, or null if not found
|
|
90
|
+
*
|
|
91
|
+
* @param address Address that should receive the transaction
|
|
92
|
+
* @param txoHash Required output txoHash
|
|
93
|
+
*/
|
|
94
|
+
checkAddressTxos(address: string, txoHash: Buffer): Promise<{
|
|
95
|
+
tx: Omit<BtcTxWithBlockheight, "hex" | "raw">;
|
|
96
|
+
vout: number;
|
|
97
|
+
} | null>;
|
|
98
|
+
/**
|
|
99
|
+
* Waits till the address receives a transaction containing a specific txoHash
|
|
100
|
+
*
|
|
101
|
+
* @param address Address that should receive the transaction
|
|
102
|
+
* @param txoHash Required output txoHash
|
|
103
|
+
* @param requiredConfirmations Required confirmations of the transaction
|
|
104
|
+
* @param stateUpdateCbk Callback for transaction state updates
|
|
105
|
+
* @param abortSignal Abort signal
|
|
106
|
+
* @param intervalSeconds How often to check new transaction
|
|
107
|
+
*/
|
|
108
|
+
waitForAddressTxo(address: string, txoHash: Buffer, requiredConfirmations: number, stateUpdateCbk: (btcTx?: Omit<BtcTxWithBlockheight, "hex" | "raw">, vout?: number, txEtaMS?: number) => void, abortSignal?: AbortSignal, intervalSeconds?: number): Promise<{
|
|
109
|
+
tx: Omit<BtcTxWithBlockheight, "hex" | "raw">;
|
|
110
|
+
vout: number;
|
|
111
|
+
}>;
|
|
112
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
export * from "./btcrelay/BtcRelay";
|
|
2
2
|
export * from "./btc/rpc/BitcoinRpc";
|
|
3
|
+
export * from "./btc/rpc/BitcoinRpcWithAddressIndex";
|
|
4
|
+
export * from "./btc/lightning/LightningNetworkApi";
|
|
3
5
|
export * from "./btcrelay/synchronizer/RelaySynchronizer";
|
|
4
6
|
export * from "./btcrelay/types/BtcBlock";
|
|
5
7
|
export * from "./btcrelay/types/BtcHeader";
|
|
@@ -12,6 +14,7 @@ export * from "./events/types/swap/RefundEvent";
|
|
|
12
14
|
export * from "./events/types/swap/SwapEvent";
|
|
13
15
|
export * from "./lockable/Lockable";
|
|
14
16
|
export * from "./storage/IStorageManager";
|
|
17
|
+
export * from "./storage/VoidStorageManager";
|
|
15
18
|
export * from "./storage/StorageObject";
|
|
16
19
|
export * from "./swaps/SwapContract";
|
|
17
20
|
export * from "./swaps/SwapData";
|
|
@@ -24,6 +27,9 @@ export * from "./errors/TransactionRevertedError";
|
|
|
24
27
|
export * from "./chains/ChainType";
|
|
25
28
|
export * from "./chains/ChainData";
|
|
26
29
|
export * from "./utils/BigIntBufferUtils";
|
|
30
|
+
export * from "./utils/Logger";
|
|
31
|
+
export * from "./utils/RetryUtils";
|
|
32
|
+
export * from "./utils/TimeoutUtils";
|
|
27
33
|
export * from "./btc/BitcoinNetwork";
|
|
28
34
|
export * from "./chains/ChainInterface";
|
|
29
35
|
export * from "./spv_swap/SpvVaultContract";
|
package/dist/index.js
CHANGED
|
@@ -16,6 +16,8 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
17
|
__exportStar(require("./btcrelay/BtcRelay"), exports);
|
|
18
18
|
__exportStar(require("./btc/rpc/BitcoinRpc"), exports);
|
|
19
|
+
__exportStar(require("./btc/rpc/BitcoinRpcWithAddressIndex"), exports);
|
|
20
|
+
__exportStar(require("./btc/lightning/LightningNetworkApi"), exports);
|
|
19
21
|
__exportStar(require("./btcrelay/synchronizer/RelaySynchronizer"), exports);
|
|
20
22
|
__exportStar(require("./btcrelay/types/BtcBlock"), exports);
|
|
21
23
|
__exportStar(require("./btcrelay/types/BtcHeader"), exports);
|
|
@@ -28,6 +30,7 @@ __exportStar(require("./events/types/swap/RefundEvent"), exports);
|
|
|
28
30
|
__exportStar(require("./events/types/swap/SwapEvent"), exports);
|
|
29
31
|
__exportStar(require("./lockable/Lockable"), exports);
|
|
30
32
|
__exportStar(require("./storage/IStorageManager"), exports);
|
|
33
|
+
__exportStar(require("./storage/VoidStorageManager"), exports);
|
|
31
34
|
__exportStar(require("./storage/StorageObject"), exports);
|
|
32
35
|
__exportStar(require("./swaps/SwapContract"), exports);
|
|
33
36
|
__exportStar(require("./swaps/SwapData"), exports);
|
|
@@ -40,6 +43,9 @@ __exportStar(require("./errors/TransactionRevertedError"), exports);
|
|
|
40
43
|
__exportStar(require("./chains/ChainType"), exports);
|
|
41
44
|
__exportStar(require("./chains/ChainData"), exports);
|
|
42
45
|
__exportStar(require("./utils/BigIntBufferUtils"), exports);
|
|
46
|
+
__exportStar(require("./utils/Logger"), exports);
|
|
47
|
+
__exportStar(require("./utils/RetryUtils"), exports);
|
|
48
|
+
__exportStar(require("./utils/TimeoutUtils"), exports);
|
|
43
49
|
__exportStar(require("./btc/BitcoinNetwork"), exports);
|
|
44
50
|
__exportStar(require("./chains/ChainInterface"), exports);
|
|
45
51
|
__exportStar(require("./spv_swap/SpvVaultContract"), exports);
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { IStorageManager } from "./IStorageManager";
|
|
2
|
+
/**
|
|
3
|
+
* A dummy storage manager that doesn't store anything, and should be only used as a placeholder
|
|
4
|
+
*
|
|
5
|
+
* @category Storage
|
|
6
|
+
* @internal
|
|
7
|
+
*/
|
|
8
|
+
export declare class VoidStorageManager implements IStorageManager<any> {
|
|
9
|
+
/**
|
|
10
|
+
* @inheritDoc
|
|
11
|
+
*/
|
|
12
|
+
data: {
|
|
13
|
+
[p: string]: any;
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* @inheritDoc
|
|
17
|
+
*/
|
|
18
|
+
init(): Promise<void>;
|
|
19
|
+
/**
|
|
20
|
+
* @inheritDoc
|
|
21
|
+
*/
|
|
22
|
+
loadData(type: {
|
|
23
|
+
new (data: any): any;
|
|
24
|
+
}): Promise<any[]>;
|
|
25
|
+
/**
|
|
26
|
+
* @inheritDoc
|
|
27
|
+
*/
|
|
28
|
+
removeData(hash: string): Promise<void>;
|
|
29
|
+
/**
|
|
30
|
+
* @inheritDoc
|
|
31
|
+
*/
|
|
32
|
+
saveData(hash: string, object: any): Promise<void>;
|
|
33
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.VoidStorageManager = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* A dummy storage manager that doesn't store anything, and should be only used as a placeholder
|
|
6
|
+
*
|
|
7
|
+
* @category Storage
|
|
8
|
+
* @internal
|
|
9
|
+
*/
|
|
10
|
+
class VoidStorageManager {
|
|
11
|
+
constructor() {
|
|
12
|
+
/**
|
|
13
|
+
* @inheritDoc
|
|
14
|
+
*/
|
|
15
|
+
this.data = {};
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* @inheritDoc
|
|
19
|
+
*/
|
|
20
|
+
init() {
|
|
21
|
+
return Promise.resolve();
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* @inheritDoc
|
|
25
|
+
*/
|
|
26
|
+
loadData(type) {
|
|
27
|
+
return Promise.resolve([]);
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* @inheritDoc
|
|
31
|
+
*/
|
|
32
|
+
removeData(hash) {
|
|
33
|
+
return Promise.resolve();
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* @inheritDoc
|
|
37
|
+
*/
|
|
38
|
+
saveData(hash, object) {
|
|
39
|
+
return Promise.resolve();
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
exports.VoidStorageManager = VoidStorageManager;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type of the logger
|
|
3
|
+
*
|
|
4
|
+
* @internal
|
|
5
|
+
*/
|
|
6
|
+
export type LoggerType = {
|
|
7
|
+
debug: (msg: string, ...args: any[]) => void;
|
|
8
|
+
info: (msg: string, ...args: any[]) => void;
|
|
9
|
+
warn: (msg: string, ...args: any[]) => void;
|
|
10
|
+
error: (msg: string, ...args: any[]) => void;
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Getter function to create a logger instance
|
|
14
|
+
*
|
|
15
|
+
* @internal
|
|
16
|
+
*/
|
|
17
|
+
export declare function getLogger(prefix: string): LoggerType;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getLogger = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Getter function to create a logger instance
|
|
6
|
+
*
|
|
7
|
+
* @internal
|
|
8
|
+
*/
|
|
9
|
+
function getLogger(prefix) {
|
|
10
|
+
return {
|
|
11
|
+
debug: (msg, ...args) => global.atomiqLogLevel >= 3 && console.debug(prefix + msg, ...args),
|
|
12
|
+
info: (msg, ...args) => global.atomiqLogLevel >= 2 && console.info(prefix + msg, ...args),
|
|
13
|
+
warn: (msg, ...args) => (global.atomiqLogLevel == null || global.atomiqLogLevel >= 1) && console.warn(prefix + msg, ...args),
|
|
14
|
+
error: (msg, ...args) => (global.atomiqLogLevel == null || global.atomiqLogLevel >= 0) && console.error(prefix + msg, ...args)
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
exports.getLogger = getLogger;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
type Constructor<T = any> = new (...args: any[]) => T;
|
|
2
|
+
/**
|
|
3
|
+
* Runs the passed function multiple times if it fails
|
|
4
|
+
*
|
|
5
|
+
* @param func A callback for executing the action
|
|
6
|
+
* @param func.retryCount Count of the current retry, starting from 0 for original request and increasing
|
|
7
|
+
* @param retryPolicy Retry policy
|
|
8
|
+
* @param retryPolicy.maxRetries How many retries to attempt in total
|
|
9
|
+
* @param retryPolicy.delay How long should the delay be
|
|
10
|
+
* @param retryPolicy.exponential Whether to use exponentially increasing delays
|
|
11
|
+
* @param errorAllowed A callback for determining whether a given error is allowed, and we should therefore not retry
|
|
12
|
+
* @param abortSignal
|
|
13
|
+
*
|
|
14
|
+
* @returns Result of the action executing callback
|
|
15
|
+
*
|
|
16
|
+
* @internal
|
|
17
|
+
*/
|
|
18
|
+
export declare function tryWithRetries<T>(func: (retryCount: number) => Promise<T>, retryPolicy?: {
|
|
19
|
+
maxRetries?: number;
|
|
20
|
+
delay?: number;
|
|
21
|
+
exponential?: boolean;
|
|
22
|
+
}, errorAllowed?: ((e: any) => boolean) | Constructor<Error> | Constructor<Error>[], abortSignal?: AbortSignal): Promise<T>;
|
|
23
|
+
export {};
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.tryWithRetries = void 0;
|
|
4
|
+
const Logger_1 = require("./Logger");
|
|
5
|
+
const TimeoutUtils_1 = require("./TimeoutUtils");
|
|
6
|
+
const logger = (0, Logger_1.getLogger)("RetryUtils: ");
|
|
7
|
+
function isConstructor(fn) {
|
|
8
|
+
return (typeof fn === 'function' &&
|
|
9
|
+
fn.prototype != null &&
|
|
10
|
+
fn.prototype.constructor === fn);
|
|
11
|
+
}
|
|
12
|
+
function isConstructorArray(fnArr) {
|
|
13
|
+
return Array.isArray(fnArr) && fnArr.every(isConstructor);
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Checks whether the passed error is allowed to pass through
|
|
17
|
+
*
|
|
18
|
+
* @param e Error in question
|
|
19
|
+
* @param errorAllowed Allowed errors as defined as a callback function, specific error type, or an array of error types
|
|
20
|
+
*/
|
|
21
|
+
function checkError(e, errorAllowed) {
|
|
22
|
+
if (isConstructorArray(errorAllowed))
|
|
23
|
+
return errorAllowed.find(error => e instanceof error) != null;
|
|
24
|
+
if (isConstructor(errorAllowed))
|
|
25
|
+
return e instanceof errorAllowed;
|
|
26
|
+
return errorAllowed(e);
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Runs the passed function multiple times if it fails
|
|
30
|
+
*
|
|
31
|
+
* @param func A callback for executing the action
|
|
32
|
+
* @param func.retryCount Count of the current retry, starting from 0 for original request and increasing
|
|
33
|
+
* @param retryPolicy Retry policy
|
|
34
|
+
* @param retryPolicy.maxRetries How many retries to attempt in total
|
|
35
|
+
* @param retryPolicy.delay How long should the delay be
|
|
36
|
+
* @param retryPolicy.exponential Whether to use exponentially increasing delays
|
|
37
|
+
* @param errorAllowed A callback for determining whether a given error is allowed, and we should therefore not retry
|
|
38
|
+
* @param abortSignal
|
|
39
|
+
*
|
|
40
|
+
* @returns Result of the action executing callback
|
|
41
|
+
*
|
|
42
|
+
* @internal
|
|
43
|
+
*/
|
|
44
|
+
async function tryWithRetries(func, retryPolicy, errorAllowed, abortSignal) {
|
|
45
|
+
retryPolicy = retryPolicy || {};
|
|
46
|
+
retryPolicy.maxRetries = retryPolicy.maxRetries || 5;
|
|
47
|
+
retryPolicy.delay = retryPolicy.delay || 500;
|
|
48
|
+
retryPolicy.exponential = retryPolicy.exponential == null ? true : retryPolicy.exponential;
|
|
49
|
+
let err = null;
|
|
50
|
+
for (let i = 0; i < retryPolicy.maxRetries; i++) {
|
|
51
|
+
try {
|
|
52
|
+
return await func(i);
|
|
53
|
+
}
|
|
54
|
+
catch (e) {
|
|
55
|
+
if (errorAllowed != null && checkError(e, errorAllowed))
|
|
56
|
+
throw e;
|
|
57
|
+
err = e;
|
|
58
|
+
logger.warn("tryWithRetries(): Error on try number: " + i, e);
|
|
59
|
+
}
|
|
60
|
+
if (abortSignal != null && abortSignal.aborted)
|
|
61
|
+
throw (abortSignal.reason || new Error("Aborted"));
|
|
62
|
+
if (i !== retryPolicy.maxRetries - 1) {
|
|
63
|
+
await (0, TimeoutUtils_1.timeoutPromise)(retryPolicy.exponential ? retryPolicy.delay * Math.pow(2, i) : retryPolicy.delay, abortSignal);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
throw err;
|
|
67
|
+
}
|
|
68
|
+
exports.tryWithRetries = tryWithRetries;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Returns a promise that resolves after given amount seconds
|
|
3
|
+
*
|
|
4
|
+
* @param timeout how many milliseconds to wait for
|
|
5
|
+
* @param abortSignal
|
|
6
|
+
*
|
|
7
|
+
* @internal
|
|
8
|
+
*/
|
|
9
|
+
export declare function timeoutPromise(timeout: number, abortSignal?: AbortSignal): Promise<void>;
|
|
10
|
+
/**
|
|
11
|
+
* Returns an abort signal that aborts after a specified timeout in milliseconds
|
|
12
|
+
*
|
|
13
|
+
* @param timeout Milliseconds to wait
|
|
14
|
+
* @param abortReason Abort with this abort reason
|
|
15
|
+
* @param abortSignal Abort signal to extend
|
|
16
|
+
*
|
|
17
|
+
* @internal
|
|
18
|
+
*/
|
|
19
|
+
export declare function timeoutSignal(timeout: number, abortReason?: any, abortSignal?: AbortSignal): AbortSignal;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.timeoutSignal = exports.timeoutPromise = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Returns a promise that resolves after given amount seconds
|
|
6
|
+
*
|
|
7
|
+
* @param timeout how many milliseconds to wait for
|
|
8
|
+
* @param abortSignal
|
|
9
|
+
*
|
|
10
|
+
* @internal
|
|
11
|
+
*/
|
|
12
|
+
function timeoutPromise(timeout, abortSignal) {
|
|
13
|
+
return new Promise((resolve, reject) => {
|
|
14
|
+
if (abortSignal != null && abortSignal.aborted) {
|
|
15
|
+
reject(abortSignal.reason);
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
let abortSignalListener;
|
|
19
|
+
let timeoutHandle = setTimeout(() => {
|
|
20
|
+
if (abortSignalListener != null && abortSignal != null)
|
|
21
|
+
abortSignal.removeEventListener("abort", abortSignalListener);
|
|
22
|
+
resolve();
|
|
23
|
+
}, timeout);
|
|
24
|
+
if (abortSignal != null) {
|
|
25
|
+
abortSignal.addEventListener("abort", abortSignalListener = () => {
|
|
26
|
+
if (timeoutHandle != null)
|
|
27
|
+
clearTimeout(timeoutHandle);
|
|
28
|
+
timeoutHandle = null;
|
|
29
|
+
reject(abortSignal.reason);
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
exports.timeoutPromise = timeoutPromise;
|
|
35
|
+
/**
|
|
36
|
+
* Returns an abort signal that aborts after a specified timeout in milliseconds
|
|
37
|
+
*
|
|
38
|
+
* @param timeout Milliseconds to wait
|
|
39
|
+
* @param abortReason Abort with this abort reason
|
|
40
|
+
* @param abortSignal Abort signal to extend
|
|
41
|
+
*
|
|
42
|
+
* @internal
|
|
43
|
+
*/
|
|
44
|
+
function timeoutSignal(timeout, abortReason, abortSignal) {
|
|
45
|
+
if (timeout == null)
|
|
46
|
+
throw new Error("Timeout seconds cannot be null!");
|
|
47
|
+
const abortController = new AbortController();
|
|
48
|
+
const timeoutHandle = setTimeout(() => abortController.abort(abortReason || new Error("Timed out")), timeout);
|
|
49
|
+
if (abortSignal != null) {
|
|
50
|
+
abortSignal.addEventListener("abort", () => {
|
|
51
|
+
clearTimeout(timeoutHandle);
|
|
52
|
+
abortController.abort(abortSignal.reason);
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
return abortController.signal;
|
|
56
|
+
}
|
|
57
|
+
exports.timeoutSignal = timeoutSignal;
|
package/package.json
CHANGED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
|
|
2
|
+
/**
|
|
3
|
+
* A type defining total capacity of a given lightning network node
|
|
4
|
+
*
|
|
5
|
+
* @category Bitcoin
|
|
6
|
+
*/
|
|
7
|
+
export type LNNodeLiquidity = {
|
|
8
|
+
publicKey: string,
|
|
9
|
+
capacity: bigint,
|
|
10
|
+
numChannels: number
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* An interface for Lightning API, provides view of the public lightning network data like channel graph
|
|
15
|
+
*
|
|
16
|
+
* @category Bitcoin
|
|
17
|
+
*/
|
|
18
|
+
export interface LightningNetworkApi {
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Returns the lightning network's node liquidity as identified by an identity public key
|
|
22
|
+
*
|
|
23
|
+
* @param pubkey
|
|
24
|
+
*/
|
|
25
|
+
getLNNodeLiquidity(pubkey: string): Promise<LNNodeLiquidity | null>
|
|
26
|
+
|
|
27
|
+
}
|
|
@@ -242,4 +242,11 @@ export interface BitcoinRpc<T extends BtcBlock> {
|
|
|
242
242
|
*/
|
|
243
243
|
getEffectiveFeeRate(btcTx: BtcTx): Promise<{vsize: number, fee: number, feeRate: number}>;
|
|
244
244
|
|
|
245
|
+
/**
|
|
246
|
+
* Parses a bitcoin address from the passed output script in hexadecimal format
|
|
247
|
+
*
|
|
248
|
+
* @param outputScriptHex
|
|
249
|
+
*/
|
|
250
|
+
outputScriptToAddress?(outputScriptHex: string): Promise<string>;
|
|
251
|
+
|
|
245
252
|
}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import {Buffer} from "buffer";
|
|
2
|
+
import {BitcoinRpc, BtcTx} from "./BitcoinRpc";
|
|
3
|
+
import {BtcBlock} from "../../btcrelay/types/BtcBlock";
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* A type defining a bitcoin transaction with its blockheight and optional input addresses populated
|
|
8
|
+
*
|
|
9
|
+
* @category Bitcoin
|
|
10
|
+
*/
|
|
11
|
+
export type BtcTxWithBlockheight = BtcTx & {
|
|
12
|
+
blockheight?: number,
|
|
13
|
+
inputAddresses?: string[]
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* A type defining a single UTXO belonging to an address
|
|
18
|
+
*
|
|
19
|
+
* @category Bitcoin
|
|
20
|
+
*/
|
|
21
|
+
export type BtcAddressUtxo = {
|
|
22
|
+
txid: string,
|
|
23
|
+
vout: number,
|
|
24
|
+
confirmed: boolean,
|
|
25
|
+
block_height: number,
|
|
26
|
+
block_hash: string,
|
|
27
|
+
block_time: number
|
|
28
|
+
value: bigint
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* An extended interface for Bitcoin, that allows querying balances and UTXOs of any address + other utilities
|
|
33
|
+
*
|
|
34
|
+
* @category Bitcoin
|
|
35
|
+
*/
|
|
36
|
+
export interface BitcoinRpcWithAddressIndex<T extends BtcBlock> extends BitcoinRpc<T> {
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Returns the current fee rate required for submitted bitcoin transactions in sats/vB
|
|
40
|
+
*/
|
|
41
|
+
getFeeRate(): Promise<number>;
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Returns confirmed & unconfirmed balances for a given wallet address
|
|
45
|
+
*
|
|
46
|
+
* @param address
|
|
47
|
+
*/
|
|
48
|
+
getAddressBalances(address: string): Promise<{
|
|
49
|
+
confirmedBalance: bigint,
|
|
50
|
+
unconfirmedBalance: bigint
|
|
51
|
+
}>;
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Returns UTXOs owned by the given wallet address
|
|
55
|
+
* @param address
|
|
56
|
+
*/
|
|
57
|
+
getAddressUTXOs(address: string): Promise<BtcAddressUtxo[]>;
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Returns CPFP (children-pay-for-parent) data for a given transaction, or null if transaction is not found
|
|
61
|
+
* or already confirmed
|
|
62
|
+
*
|
|
63
|
+
* @param txId
|
|
64
|
+
*/
|
|
65
|
+
getCPFPData(txId: string): Promise<{
|
|
66
|
+
effectiveFeePerVsize: number,
|
|
67
|
+
adjustedVsize: number
|
|
68
|
+
} | null>;
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* @inheritDoc
|
|
72
|
+
*/
|
|
73
|
+
getTransaction(txId: string): Promise<BtcTxWithBlockheight | null>;
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Awaits till the given transaction gets confirmed
|
|
77
|
+
*
|
|
78
|
+
* @param txId Transaction ID to monitor
|
|
79
|
+
* @param requiredConfirmations Required number of confirmations
|
|
80
|
+
* @param stateUpdateCbk Optional update callback called with the current status of the bitcoin transaction
|
|
81
|
+
* @param abortSignal
|
|
82
|
+
* @param intervalSeconds How often to poll
|
|
83
|
+
*/
|
|
84
|
+
waitForTransaction(
|
|
85
|
+
txId: string,
|
|
86
|
+
requiredConfirmations: number,
|
|
87
|
+
stateUpdateCbk?: (btcTx?: BtcTxWithBlockheight, txEtaMS?: number) => void,
|
|
88
|
+
abortSignal?: AbortSignal,
|
|
89
|
+
intervalSeconds?: number
|
|
90
|
+
): Promise<BtcTxWithBlockheight>;
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Returns an estimate after which time the tx will confirm with the required amount of confirmations,
|
|
94
|
+
* confirmationDelay of -1 means the transaction won't confirm in the near future
|
|
95
|
+
*
|
|
96
|
+
* @param tx
|
|
97
|
+
* @param requiredConfirmations
|
|
98
|
+
*
|
|
99
|
+
* @returns estimated confirmation delay, -1 if the transaction won't confirm in the near future, null if the
|
|
100
|
+
* transaction was replaced or was confirmed in the meantime
|
|
101
|
+
*/
|
|
102
|
+
getConfirmationDelay(tx: BtcTx, requiredConfirmations: number): Promise<number | null>
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Checks if an address received the transaction with the required txoHash, returns info about that
|
|
106
|
+
* specific transaction if found, or null if not found
|
|
107
|
+
*
|
|
108
|
+
* @param address Address that should receive the transaction
|
|
109
|
+
* @param txoHash Required output txoHash
|
|
110
|
+
*/
|
|
111
|
+
checkAddressTxos(address: string, txoHash: Buffer): Promise<{
|
|
112
|
+
tx: Omit<BtcTxWithBlockheight, "hex" | "raw">,
|
|
113
|
+
vout: number
|
|
114
|
+
} | null>;
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Waits till the address receives a transaction containing a specific txoHash
|
|
118
|
+
*
|
|
119
|
+
* @param address Address that should receive the transaction
|
|
120
|
+
* @param txoHash Required output txoHash
|
|
121
|
+
* @param requiredConfirmations Required confirmations of the transaction
|
|
122
|
+
* @param stateUpdateCbk Callback for transaction state updates
|
|
123
|
+
* @param abortSignal Abort signal
|
|
124
|
+
* @param intervalSeconds How often to check new transaction
|
|
125
|
+
*/
|
|
126
|
+
waitForAddressTxo(
|
|
127
|
+
address: string,
|
|
128
|
+
txoHash: Buffer,
|
|
129
|
+
requiredConfirmations: number,
|
|
130
|
+
stateUpdateCbk: (btcTx?: Omit<BtcTxWithBlockheight, "hex" | "raw">, vout?: number, txEtaMS?: number) => void,
|
|
131
|
+
abortSignal?: AbortSignal,
|
|
132
|
+
intervalSeconds?: number
|
|
133
|
+
): Promise<{
|
|
134
|
+
tx: Omit<BtcTxWithBlockheight, "hex" | "raw">,
|
|
135
|
+
vout: number
|
|
136
|
+
}>;
|
|
137
|
+
|
|
138
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
export * from "./btcrelay/BtcRelay";
|
|
2
2
|
export * from "./btc/rpc/BitcoinRpc";
|
|
3
|
+
export * from "./btc/rpc/BitcoinRpcWithAddressIndex";
|
|
4
|
+
export * from "./btc/lightning/LightningNetworkApi";
|
|
3
5
|
export * from "./btcrelay/synchronizer/RelaySynchronizer";
|
|
4
6
|
export * from "./btcrelay/types/BtcBlock";
|
|
5
7
|
export * from "./btcrelay/types/BtcHeader";
|
|
@@ -12,6 +14,7 @@ export * from "./events/types/swap/RefundEvent";
|
|
|
12
14
|
export * from "./events/types/swap/SwapEvent";
|
|
13
15
|
export * from "./lockable/Lockable";
|
|
14
16
|
export * from "./storage/IStorageManager";
|
|
17
|
+
export * from "./storage/VoidStorageManager";
|
|
15
18
|
export * from "./storage/StorageObject";
|
|
16
19
|
export * from "./swaps/SwapContract";
|
|
17
20
|
export * from "./swaps/SwapData";
|
|
@@ -27,6 +30,9 @@ export * from "./chains/ChainType";
|
|
|
27
30
|
export * from "./chains/ChainData";
|
|
28
31
|
|
|
29
32
|
export * from "./utils/BigIntBufferUtils";
|
|
33
|
+
export * from "./utils/Logger";
|
|
34
|
+
export * from "./utils/RetryUtils";
|
|
35
|
+
export * from "./utils/TimeoutUtils";
|
|
30
36
|
|
|
31
37
|
export * from "./btc/BitcoinNetwork";
|
|
32
38
|
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import {IStorageManager} from "./IStorageManager";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* A dummy storage manager that doesn't store anything, and should be only used as a placeholder
|
|
5
|
+
*
|
|
6
|
+
* @category Storage
|
|
7
|
+
* @internal
|
|
8
|
+
*/
|
|
9
|
+
export class VoidStorageManager implements IStorageManager<any> {
|
|
10
|
+
/**
|
|
11
|
+
* @inheritDoc
|
|
12
|
+
*/
|
|
13
|
+
data: { [p: string]: any } = {};
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* @inheritDoc
|
|
17
|
+
*/
|
|
18
|
+
init(): Promise<void> {
|
|
19
|
+
return Promise.resolve();
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* @inheritDoc
|
|
24
|
+
*/
|
|
25
|
+
loadData(type: { new(data: any): any }): Promise<any[]> {
|
|
26
|
+
return Promise.resolve([]);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* @inheritDoc
|
|
31
|
+
*/
|
|
32
|
+
removeData(hash: string): Promise<void> {
|
|
33
|
+
return Promise.resolve();
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* @inheritDoc
|
|
38
|
+
*/
|
|
39
|
+
saveData(hash: string, object: any): Promise<void> {
|
|
40
|
+
return Promise.resolve();
|
|
41
|
+
}
|
|
42
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type of the logger
|
|
3
|
+
*
|
|
4
|
+
* @internal
|
|
5
|
+
*/
|
|
6
|
+
export type LoggerType = {
|
|
7
|
+
debug: (msg: string, ...args: any[]) => void,
|
|
8
|
+
info: (msg: string, ...args: any[]) => void,
|
|
9
|
+
warn: (msg: string, ...args: any[]) => void,
|
|
10
|
+
error: (msg: string, ...args: any[]) => void
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Getter function to create a logger instance
|
|
15
|
+
*
|
|
16
|
+
* @internal
|
|
17
|
+
*/
|
|
18
|
+
export function getLogger(prefix: string): LoggerType {
|
|
19
|
+
return {
|
|
20
|
+
debug: (msg, ...args) => (global as any).atomiqLogLevel >= 3 && console.debug(prefix + msg, ...args),
|
|
21
|
+
info: (msg, ...args) => (global as any).atomiqLogLevel >= 2 && console.info(prefix + msg, ...args),
|
|
22
|
+
warn: (msg, ...args) => ((global as any).atomiqLogLevel == null || (global as any).atomiqLogLevel >= 1) && console.warn(prefix + msg, ...args),
|
|
23
|
+
error: (msg, ...args) => ((global as any).atomiqLogLevel == null || (global as any).atomiqLogLevel >= 0) && console.error(prefix + msg, ...args)
|
|
24
|
+
};
|
|
25
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import {getLogger} from "./Logger";
|
|
2
|
+
import {timeoutPromise} from "./TimeoutUtils";
|
|
3
|
+
|
|
4
|
+
const logger = getLogger("RetryUtils: ");
|
|
5
|
+
|
|
6
|
+
type Constructor<T = any> = new (...args: any[]) => T;
|
|
7
|
+
|
|
8
|
+
function isConstructor(fn: any): fn is Constructor {
|
|
9
|
+
return (
|
|
10
|
+
typeof fn === 'function' &&
|
|
11
|
+
fn.prototype != null &&
|
|
12
|
+
fn.prototype.constructor === fn
|
|
13
|
+
);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function isConstructorArray(fnArr: any): fnArr is Constructor[] {
|
|
17
|
+
return Array.isArray(fnArr) && fnArr.every(isConstructor);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Checks whether the passed error is allowed to pass through
|
|
22
|
+
*
|
|
23
|
+
* @param e Error in question
|
|
24
|
+
* @param errorAllowed Allowed errors as defined as a callback function, specific error type, or an array of error types
|
|
25
|
+
*/
|
|
26
|
+
function checkError(e: any, errorAllowed: ((e: any) => boolean) | Constructor<Error> | Constructor<Error>[]) {
|
|
27
|
+
if (isConstructorArray(errorAllowed)) return errorAllowed.find(error => e instanceof error) != null;
|
|
28
|
+
if (isConstructor(errorAllowed)) return e instanceof errorAllowed;
|
|
29
|
+
return errorAllowed(e);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Runs the passed function multiple times if it fails
|
|
34
|
+
*
|
|
35
|
+
* @param func A callback for executing the action
|
|
36
|
+
* @param func.retryCount Count of the current retry, starting from 0 for original request and increasing
|
|
37
|
+
* @param retryPolicy Retry policy
|
|
38
|
+
* @param retryPolicy.maxRetries How many retries to attempt in total
|
|
39
|
+
* @param retryPolicy.delay How long should the delay be
|
|
40
|
+
* @param retryPolicy.exponential Whether to use exponentially increasing delays
|
|
41
|
+
* @param errorAllowed A callback for determining whether a given error is allowed, and we should therefore not retry
|
|
42
|
+
* @param abortSignal
|
|
43
|
+
*
|
|
44
|
+
* @returns Result of the action executing callback
|
|
45
|
+
*
|
|
46
|
+
* @internal
|
|
47
|
+
*/
|
|
48
|
+
export async function tryWithRetries<T>(func: (retryCount: number) => Promise<T>, retryPolicy?: {
|
|
49
|
+
maxRetries?: number, delay?: number, exponential?: boolean
|
|
50
|
+
}, errorAllowed?: ((e: any) => boolean) | Constructor<Error> | Constructor<Error>[], abortSignal?: AbortSignal): Promise<T> {
|
|
51
|
+
retryPolicy = retryPolicy || {};
|
|
52
|
+
retryPolicy.maxRetries = retryPolicy.maxRetries || 5;
|
|
53
|
+
retryPolicy.delay = retryPolicy.delay || 500;
|
|
54
|
+
retryPolicy.exponential = retryPolicy.exponential == null ? true : retryPolicy.exponential;
|
|
55
|
+
|
|
56
|
+
let err = null;
|
|
57
|
+
|
|
58
|
+
for (let i = 0; i < retryPolicy.maxRetries; i++) {
|
|
59
|
+
try {
|
|
60
|
+
return await func(i);
|
|
61
|
+
} catch (e) {
|
|
62
|
+
if (errorAllowed != null && checkError(e, errorAllowed)) throw e;
|
|
63
|
+
err = e;
|
|
64
|
+
logger.warn("tryWithRetries(): Error on try number: " + i, e);
|
|
65
|
+
}
|
|
66
|
+
if (abortSignal != null && abortSignal.aborted) throw (abortSignal.reason || new Error("Aborted"));
|
|
67
|
+
if (i !== retryPolicy.maxRetries - 1) {
|
|
68
|
+
await timeoutPromise(retryPolicy.exponential ? retryPolicy.delay * Math.pow(2, i) : retryPolicy.delay, abortSignal);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
throw err;
|
|
73
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Returns a promise that resolves after given amount seconds
|
|
3
|
+
*
|
|
4
|
+
* @param timeout how many milliseconds to wait for
|
|
5
|
+
* @param abortSignal
|
|
6
|
+
*
|
|
7
|
+
* @internal
|
|
8
|
+
*/
|
|
9
|
+
export function timeoutPromise(timeout: number, abortSignal?: AbortSignal): Promise<void> {
|
|
10
|
+
return new Promise<void>((resolve, reject) => {
|
|
11
|
+
if (abortSignal != null && abortSignal.aborted) {
|
|
12
|
+
reject(abortSignal.reason);
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
let abortSignalListener: () => void;
|
|
17
|
+
let timeoutHandle: any | null = setTimeout(() => {
|
|
18
|
+
if (abortSignalListener != null && abortSignal != null) abortSignal.removeEventListener("abort", abortSignalListener);
|
|
19
|
+
resolve();
|
|
20
|
+
}, timeout);
|
|
21
|
+
|
|
22
|
+
if (abortSignal != null) {
|
|
23
|
+
abortSignal.addEventListener("abort", abortSignalListener = () => {
|
|
24
|
+
if (timeoutHandle != null) clearTimeout(timeoutHandle);
|
|
25
|
+
timeoutHandle = null;
|
|
26
|
+
reject(abortSignal.reason);
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Returns an abort signal that aborts after a specified timeout in milliseconds
|
|
34
|
+
*
|
|
35
|
+
* @param timeout Milliseconds to wait
|
|
36
|
+
* @param abortReason Abort with this abort reason
|
|
37
|
+
* @param abortSignal Abort signal to extend
|
|
38
|
+
*
|
|
39
|
+
* @internal
|
|
40
|
+
*/
|
|
41
|
+
export function timeoutSignal(timeout: number, abortReason?: any, abortSignal?: AbortSignal): AbortSignal {
|
|
42
|
+
if (timeout == null) throw new Error("Timeout seconds cannot be null!");
|
|
43
|
+
const abortController = new AbortController();
|
|
44
|
+
const timeoutHandle = setTimeout(() => abortController.abort(abortReason || new Error("Timed out")), timeout);
|
|
45
|
+
if (abortSignal != null) {
|
|
46
|
+
abortSignal.addEventListener("abort", () => {
|
|
47
|
+
clearTimeout(timeoutHandle);
|
|
48
|
+
abortController.abort(abortSignal.reason);
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
return abortController.signal;
|
|
52
|
+
}
|