@atomiqlabs/lp-lib 13.0.0 → 14.0.0-dev.10
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/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/plugins/IPlugin.d.ts +2 -2
- package/dist/plugins/PluginManager.d.ts +2 -2
- package/dist/storagemanager/IntermediaryStorageManager.d.ts +1 -0
- package/dist/storagemanager/IntermediaryStorageManager.js +9 -2
- package/dist/storagemanager/StorageManager.d.ts +1 -0
- package/dist/storagemanager/StorageManager.js +9 -2
- package/dist/swaps/SwapHandler.d.ts +4 -7
- package/dist/swaps/SwapHandler.js +4 -7
- package/dist/swaps/assertions/FromBtcAmountAssertions.d.ts +2 -2
- package/dist/swaps/escrow/EscrowHandlerSwap.js +2 -2
- package/dist/swaps/escrow/FromBtcBaseSwapHandler.d.ts +2 -1
- package/dist/swaps/escrow/FromBtcBaseSwapHandler.js +8 -5
- package/dist/swaps/escrow/frombtcln_abstract/FromBtcLnSwapAbs.d.ts +1 -0
- package/dist/swaps/escrow/frombtcln_abstract/FromBtcLnSwapAbs.js +3 -0
- package/dist/swaps/escrow/frombtcln_autoinit/FromBtcLnAuto.d.ts +104 -0
- package/dist/swaps/escrow/frombtcln_autoinit/FromBtcLnAuto.js +629 -0
- package/dist/swaps/escrow/frombtcln_autoinit/FromBtcLnAutoSwap.d.ts +55 -0
- package/dist/swaps/escrow/frombtcln_autoinit/FromBtcLnAutoSwap.js +120 -0
- package/dist/swaps/escrow/tobtc_abstract/ToBtcAbs.js +6 -2
- package/dist/swaps/escrow/tobtcln_abstract/ToBtcLnAbs.js +6 -2
- package/dist/swaps/spv_vault_swap/SpvVaultSwapHandler.js +4 -2
- package/dist/swaps/spv_vault_swap/SpvVaults.d.ts +1 -6
- package/dist/swaps/spv_vault_swap/SpvVaults.js +2 -7
- package/dist/swaps/trusted/frombtc_trusted/FromBtcTrusted.js +1 -1
- package/dist/swaps/trusted/frombtcln_trusted/FromBtcLnTrusted.js +3 -4
- package/dist/utils/Utils.d.ts +7 -7
- package/dist/utils/Utils.js +12 -11
- package/dist/utils/paramcoders/server/ServerParamDecoder.js +8 -6
- package/package.json +2 -2
- package/src/index.ts +2 -0
- package/src/plugins/IPlugin.ts +2 -2
- package/src/plugins/PluginManager.ts +2 -2
- package/src/storagemanager/IntermediaryStorageManager.ts +11 -2
- package/src/storagemanager/StorageManager.ts +12 -2
- package/src/swaps/SwapHandler.ts +5 -8
- package/src/swaps/assertions/FromBtcAmountAssertions.ts +3 -3
- package/src/swaps/escrow/EscrowHandler.ts +3 -3
- package/src/swaps/escrow/EscrowHandlerSwap.ts +2 -2
- package/src/swaps/escrow/FromBtcBaseSwapHandler.ts +8 -5
- package/src/swaps/escrow/frombtcln_abstract/FromBtcLnSwapAbs.ts +4 -0
- package/src/swaps/escrow/frombtcln_autoinit/FromBtcLnAuto.ts +789 -0
- package/src/swaps/escrow/frombtcln_autoinit/FromBtcLnAutoSwap.ts +196 -0
- package/src/swaps/escrow/tobtc_abstract/ToBtcAbs.ts +7 -4
- package/src/swaps/escrow/tobtcln_abstract/ToBtcLnAbs.ts +7 -4
- package/src/swaps/spv_vault_swap/SpvVaultSwapHandler.ts +4 -2
- package/src/swaps/spv_vault_swap/SpvVaults.ts +3 -8
- package/src/swaps/trusted/frombtc_trusted/FromBtcTrusted.ts +1 -1
- package/src/swaps/trusted/frombtcln_trusted/FromBtcLnTrusted.ts +3 -5
- package/src/utils/Utils.ts +19 -17
- package/src/utils/paramcoders/server/ServerParamDecoder.ts +9 -6
- package/dist/wallets/ISpvVaultWallet.d.ts +0 -42
- package/dist/wallets/ISpvVaultWallet.js +0 -2
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
import {SwapData} from "@atomiqlabs/base";
|
|
2
|
+
import {SwapHandlerType} from "../../../index";
|
|
3
|
+
import {FromBtcBaseSwap} from "../FromBtcBaseSwap";
|
|
4
|
+
import {deserializeBN, serializeBN} from "../../../utils/Utils";
|
|
5
|
+
|
|
6
|
+
export enum FromBtcLnAutoSwapState {
|
|
7
|
+
REFUNDED = -2,
|
|
8
|
+
CANCELED = -1,
|
|
9
|
+
CREATED = 0,
|
|
10
|
+
RECEIVED = 1,
|
|
11
|
+
TXS_SENT = 2,
|
|
12
|
+
COMMITED = 3,
|
|
13
|
+
CLAIMED = 4,
|
|
14
|
+
SETTLED = 5,
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export class FromBtcLnAutoSwap<T extends SwapData = SwapData> extends FromBtcBaseSwap<T, FromBtcLnAutoSwapState> {
|
|
18
|
+
|
|
19
|
+
readonly pr: string;
|
|
20
|
+
readonly lnPaymentHash: string;
|
|
21
|
+
readonly claimHash: string;
|
|
22
|
+
|
|
23
|
+
readonly claimer: string;
|
|
24
|
+
|
|
25
|
+
readonly token: string;
|
|
26
|
+
readonly gasToken: string;
|
|
27
|
+
readonly amountToken: bigint;
|
|
28
|
+
readonly amountGasToken: bigint;
|
|
29
|
+
|
|
30
|
+
readonly tokenSwapFee: bigint;
|
|
31
|
+
readonly tokenSwapFeeInToken: bigint;
|
|
32
|
+
readonly gasSwapFee: bigint;
|
|
33
|
+
readonly gasSwapFeeInToken: bigint;
|
|
34
|
+
|
|
35
|
+
readonly claimerBounty: bigint;
|
|
36
|
+
|
|
37
|
+
secret: string;
|
|
38
|
+
|
|
39
|
+
constructor(
|
|
40
|
+
chainIdentifier: string,
|
|
41
|
+
pr: string,
|
|
42
|
+
lnPaymentHash: string,
|
|
43
|
+
claimHash: string,
|
|
44
|
+
amountMtokens: bigint,
|
|
45
|
+
|
|
46
|
+
claimer: string,
|
|
47
|
+
token: string,
|
|
48
|
+
gasToken: string,
|
|
49
|
+
amountToken: bigint,
|
|
50
|
+
amountGasToken: bigint,
|
|
51
|
+
|
|
52
|
+
tokenSwapFee: bigint,
|
|
53
|
+
tokenSwapFeeInToken: bigint,
|
|
54
|
+
gasSwapFee: bigint,
|
|
55
|
+
gasSwapFeeInToken: bigint,
|
|
56
|
+
|
|
57
|
+
claimerBounty: bigint
|
|
58
|
+
);
|
|
59
|
+
constructor(obj: any);
|
|
60
|
+
|
|
61
|
+
constructor(
|
|
62
|
+
chainIdOrObj: string | any,
|
|
63
|
+
pr?: string,
|
|
64
|
+
lnPaymentHash?: string,
|
|
65
|
+
claimHash?: string,
|
|
66
|
+
amountMtokens?: bigint,
|
|
67
|
+
|
|
68
|
+
claimer?: string,
|
|
69
|
+
token?: string,
|
|
70
|
+
gasToken?: string,
|
|
71
|
+
amountToken?: bigint,
|
|
72
|
+
amountGasToken?: bigint,
|
|
73
|
+
|
|
74
|
+
tokenSwapFee?: bigint,
|
|
75
|
+
tokenSwapFeeInToken?: bigint,
|
|
76
|
+
gasSwapFee?: bigint,
|
|
77
|
+
gasSwapFeeInToken?: bigint,
|
|
78
|
+
|
|
79
|
+
claimerBounty?: bigint
|
|
80
|
+
) {
|
|
81
|
+
if(typeof(chainIdOrObj)==="string") {
|
|
82
|
+
super(chainIdOrObj, (amountMtokens + 999n) / 1000n, tokenSwapFee + gasSwapFee, tokenSwapFeeInToken);
|
|
83
|
+
this.state = FromBtcLnAutoSwapState.CREATED;
|
|
84
|
+
this.pr = pr;
|
|
85
|
+
this.lnPaymentHash = lnPaymentHash;
|
|
86
|
+
this.claimHash = claimHash;
|
|
87
|
+
this.claimer = claimer;
|
|
88
|
+
this.token = token;
|
|
89
|
+
this.gasToken = gasToken;
|
|
90
|
+
this.amountToken = amountToken;
|
|
91
|
+
this.amountGasToken = amountGasToken;
|
|
92
|
+
this.tokenSwapFee = tokenSwapFee;
|
|
93
|
+
this.tokenSwapFeeInToken = tokenSwapFeeInToken;
|
|
94
|
+
this.gasSwapFee = gasSwapFee;
|
|
95
|
+
this.gasSwapFeeInToken = gasSwapFeeInToken;
|
|
96
|
+
this.claimerBounty = claimerBounty;
|
|
97
|
+
} else {
|
|
98
|
+
super(chainIdOrObj);
|
|
99
|
+
this.pr = chainIdOrObj.pr;
|
|
100
|
+
this.lnPaymentHash = chainIdOrObj.lnPaymentHash;
|
|
101
|
+
this.claimHash = chainIdOrObj.claimHash;
|
|
102
|
+
this.claimer = chainIdOrObj.claimer;
|
|
103
|
+
this.token = chainIdOrObj.token;
|
|
104
|
+
this.gasToken = chainIdOrObj.gasToken;
|
|
105
|
+
this.amountToken = deserializeBN(chainIdOrObj.amountToken);
|
|
106
|
+
this.amountGasToken = deserializeBN(chainIdOrObj.amountGasToken);
|
|
107
|
+
this.tokenSwapFee = deserializeBN(chainIdOrObj.tokenSwapFee);
|
|
108
|
+
this.tokenSwapFeeInToken = deserializeBN(chainIdOrObj.tokenSwapFeeInToken);
|
|
109
|
+
this.gasSwapFee = deserializeBN(chainIdOrObj.gasSwapFee);
|
|
110
|
+
this.gasSwapFeeInToken = deserializeBN(chainIdOrObj.gasSwapFeeInToken);
|
|
111
|
+
this.claimerBounty = deserializeBN(chainIdOrObj.claimerBounty);
|
|
112
|
+
this.secret = chainIdOrObj.secret;
|
|
113
|
+
}
|
|
114
|
+
this.type = SwapHandlerType.FROM_BTCLN;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
serialize(): any {
|
|
118
|
+
const partialSerialized = super.serialize();
|
|
119
|
+
partialSerialized.pr = this.pr;
|
|
120
|
+
partialSerialized.secret = this.secret;
|
|
121
|
+
partialSerialized.lnPaymentHash = this.lnPaymentHash;
|
|
122
|
+
partialSerialized.claimHash = this.claimHash;
|
|
123
|
+
partialSerialized.claimer = this.claimer;
|
|
124
|
+
partialSerialized.token = this.token;
|
|
125
|
+
partialSerialized.gasToken = this.gasToken;
|
|
126
|
+
partialSerialized.amountToken = serializeBN(this.amountToken);
|
|
127
|
+
partialSerialized.amountGasToken = serializeBN(this.amountGasToken);
|
|
128
|
+
partialSerialized.tokenSwapFee = serializeBN(this.tokenSwapFee);
|
|
129
|
+
partialSerialized.tokenSwapFeeInToken = serializeBN(this.tokenSwapFeeInToken);
|
|
130
|
+
partialSerialized.gasSwapFee = serializeBN(this.gasSwapFee);
|
|
131
|
+
partialSerialized.gasSwapFeeInToken = serializeBN(this.gasSwapFeeInToken);
|
|
132
|
+
partialSerialized.claimerBounty = serializeBN(this.claimerBounty);
|
|
133
|
+
return partialSerialized;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
getClaimHash(): string {
|
|
137
|
+
return this.claimHash;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
getIdentifierHash(): string {
|
|
141
|
+
return this.lnPaymentHash;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
getOutputGasAmount(): bigint {
|
|
145
|
+
return this.amountGasToken;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
getOutputAmount(): bigint {
|
|
149
|
+
return this.amountToken;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
getTotalOutputAmount(): bigint {
|
|
153
|
+
return this.amountToken;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
getTotalOutputGasAmount(): bigint {
|
|
157
|
+
return this.amountGasToken + this.claimerBounty;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
getSequence(): bigint {
|
|
161
|
+
return 0n;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
getSwapFee(): { inInputToken: bigint; inOutputToken: bigint } {
|
|
165
|
+
return {inInputToken: this.swapFee, inOutputToken: this.swapFeeInToken};
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
getTokenSwapFee(): { inInputToken: bigint; inOutputToken: bigint } {
|
|
169
|
+
return {inInputToken: this.tokenSwapFee, inOutputToken: this.tokenSwapFeeInToken};
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
getGasSwapFee(): { inInputToken: bigint; inOutputToken: bigint } {
|
|
173
|
+
return {inInputToken: this.gasSwapFee, inOutputToken: this.gasSwapFeeInToken};
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
getToken(): string {
|
|
177
|
+
return this.token;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
getGasToken(): string {
|
|
181
|
+
return this.gasToken;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
isInitiated(): boolean {
|
|
185
|
+
return this.state!==FromBtcLnAutoSwapState.CREATED;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
isFailed(): boolean {
|
|
189
|
+
return this.state===FromBtcLnAutoSwapState.CANCELED || this.state===FromBtcLnAutoSwapState.REFUNDED;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
isSuccess(): boolean {
|
|
193
|
+
return this.state===FromBtcLnAutoSwapState.SETTLED;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
}
|
|
@@ -8,10 +8,9 @@ import {
|
|
|
8
8
|
ClaimEvent,
|
|
9
9
|
InitializeEvent,
|
|
10
10
|
RefundEvent,
|
|
11
|
-
SwapCommitStatus,
|
|
12
11
|
SwapData,
|
|
13
12
|
BitcoinRpc,
|
|
14
|
-
BtcBlock, BigIntBufferUtils
|
|
13
|
+
BtcBlock, BigIntBufferUtils, SwapCommitStateType
|
|
15
14
|
} from "@atomiqlabs/base";
|
|
16
15
|
import {expressHandlerWrapper, getAbortController, HEX_REGEX, isDefinedRuntimeError} from "../../../utils/Utils";
|
|
17
16
|
import {PluginManager} from "../../../plugins/PluginManager";
|
|
@@ -169,13 +168,17 @@ export class ToBtcAbs extends ToBtcBaseSwapHandler<ToBtcSwapAbs, ToBtcSwapState>
|
|
|
169
168
|
const isCommited = await swapContract.isCommited(swap.data);
|
|
170
169
|
if(!isCommited) {
|
|
171
170
|
const status = await swapContract.getCommitStatus(signer.getAddress(), swap.data);
|
|
172
|
-
if(status===
|
|
171
|
+
if(status.type===SwapCommitStateType.PAID) {
|
|
173
172
|
this.swapLogger.info(swap, "processPastSwap(state=BTC_SENT): swap claimed (detected from processPastSwap), address: "+swap.address);
|
|
174
173
|
this.unsubscribePayment(swap);
|
|
174
|
+
swap.txIds ??= {};
|
|
175
|
+
swap.txIds.claim = await status.getClaimTxId();
|
|
175
176
|
await this.removeSwapData(swap, ToBtcSwapState.CLAIMED);
|
|
176
|
-
} else if(status===
|
|
177
|
+
} else if(status.type===SwapCommitStateType.EXPIRED) {
|
|
177
178
|
this.swapLogger.warn(swap, "processPastSwap(state=BTC_SENT): swap expired, but bitcoin was probably already sent, txId: "+swap.txId+" address: "+swap.address);
|
|
178
179
|
this.unsubscribePayment(swap);
|
|
180
|
+
swap.txIds ??= {};
|
|
181
|
+
swap.txIds.refund = status.getRefundTxId==null ? null : await status.getRefundTxId();
|
|
179
182
|
await this.removeSwapData(swap, ToBtcSwapState.REFUNDED);
|
|
180
183
|
}
|
|
181
184
|
return;
|
|
@@ -7,8 +7,7 @@ import {
|
|
|
7
7
|
ChainSwapType,
|
|
8
8
|
ClaimEvent,
|
|
9
9
|
InitializeEvent,
|
|
10
|
-
RefundEvent,
|
|
11
|
-
SwapCommitStatus,
|
|
10
|
+
RefundEvent, SwapCommitStateType,
|
|
12
11
|
SwapData
|
|
13
12
|
} from "@atomiqlabs/base";
|
|
14
13
|
import {expressHandlerWrapper, getAbortController, HEX_REGEX, isDefinedRuntimeError} from "../../../utils/Utils";
|
|
@@ -218,12 +217,16 @@ export class ToBtcLnAbs extends ToBtcBaseSwapHandler<ToBtcLnSwapAbs, ToBtcLnSwap
|
|
|
218
217
|
const isCommited = await swapContract.isCommited(swap.data);
|
|
219
218
|
if(!isCommited) {
|
|
220
219
|
const status = await swapContract.getCommitStatus(signer.getAddress(), swap.data);
|
|
221
|
-
if(status===
|
|
220
|
+
if(status?.type===SwapCommitStateType.PAID) {
|
|
222
221
|
//This is alright, we got the money
|
|
222
|
+
swap.txIds ??= {};
|
|
223
|
+
swap.txIds.claim = await status.getClaimTxId();
|
|
223
224
|
await this.removeSwapData(swap, ToBtcLnSwapState.CLAIMED);
|
|
224
225
|
return true;
|
|
225
|
-
} else if(status===
|
|
226
|
+
} else if(status?.type===SwapCommitStateType.EXPIRED) {
|
|
226
227
|
//This means the user was able to refund before we were able to claim, no good
|
|
228
|
+
swap.txIds ??= {};
|
|
229
|
+
swap.txIds.refund = status.getRefundTxId==null ? null : await status.getRefundTxId();
|
|
227
230
|
await this.removeSwapData(swap, ToBtcLnSwapState.REFUNDED);
|
|
228
231
|
}
|
|
229
232
|
this.swapLogger.warn(swap, "processPaymentResult(): tried to claim but escrow doesn't exist anymore,"+
|
|
@@ -496,7 +496,7 @@ export class SpvVaultSwapHandler extends SwapHandler<SpvVaultSwap, SpvVaultSwapS
|
|
|
496
496
|
}
|
|
497
497
|
|
|
498
498
|
if(
|
|
499
|
-
data.
|
|
499
|
+
!data.isRecipient(swap.recipient) ||
|
|
500
500
|
data.callerFeeRate!==swap.callerFeeShare ||
|
|
501
501
|
data.frontingFeeRate!==swap.frontingFeeShare ||
|
|
502
502
|
data.executionFeeRate!==swap.executionFeeShare ||
|
|
@@ -506,7 +506,9 @@ export class SpvVaultSwapHandler extends SwapHandler<SpvVaultSwap, SpvVaultSwapS
|
|
|
506
506
|
data.btcTx.outs[0].value!==VAULT_DUST_AMOUNT ||
|
|
507
507
|
!Buffer.from(data.btcTx.outs[0].scriptPubKey.hex, "hex").equals(this.bitcoin.toOutputScript(swap.vaultAddress)) ||
|
|
508
508
|
BigInt(data.btcTx.outs[2].value)!==swap.amountBtc ||
|
|
509
|
-
!Buffer.from(data.btcTx.outs[2].scriptPubKey.hex, "hex").equals(this.bitcoin.toOutputScript(swap.btcAddress))
|
|
509
|
+
!Buffer.from(data.btcTx.outs[2].scriptPubKey.hex, "hex").equals(this.bitcoin.toOutputScript(swap.btcAddress)) ||
|
|
510
|
+
(data.btcTx.locktime > 0 && data.btcTx.locktime < 500_000_000) ||
|
|
511
|
+
data.btcTx.locktime > Math.floor(Date.now()/1000) - 1_000_000
|
|
510
512
|
) {
|
|
511
513
|
this.swapLogger.error(swap, "REST: /postQuote: Invalid psbt data submitted, raw psbt hex: ", parsedBody.psbtHex);
|
|
512
514
|
throw {
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
SpvVaultOpenEvent, SpvWithdrawalTransactionData
|
|
9
9
|
} from "@atomiqlabs/base";
|
|
10
10
|
import {SpvVaultSwap} from "./SpvVaultSwap";
|
|
11
|
-
import {bigIntSorter} from "../../utils/Utils";
|
|
11
|
+
import {bigIntSorter, getLogger} from "../../utils/Utils";
|
|
12
12
|
import {PluginManager} from "../../plugins/PluginManager";
|
|
13
13
|
import {IBitcoinWallet} from "../../wallets/IBitcoinWallet";
|
|
14
14
|
import {ISpvVaultSigner} from "../../wallets/ISpvVaultSigner";
|
|
@@ -30,12 +30,7 @@ export class SpvVaults {
|
|
|
30
30
|
readonly config: {vaultsCheckInterval: number, maxUnclaimedWithdrawals?: number};
|
|
31
31
|
readonly getChain: (chainId: string) => ChainData
|
|
32
32
|
|
|
33
|
-
readonly logger =
|
|
34
|
-
debug: (msg: string, ...args: any) => console.debug("SpvVaults: "+msg, ...args),
|
|
35
|
-
info: (msg: string, ...args: any) => console.info("SpvVaults: "+msg, ...args),
|
|
36
|
-
warn: (msg: string, ...args: any) => console.warn("SpvVaults: "+msg, ...args),
|
|
37
|
-
error: (msg: string, ...args: any) => console.error("SpvVaults: "+msg, ...args)
|
|
38
|
-
};
|
|
33
|
+
readonly logger = getLogger("SpvVaults: ");
|
|
39
34
|
|
|
40
35
|
constructor(
|
|
41
36
|
vaultStorage: IStorageManager<SpvVault>,
|
|
@@ -428,7 +423,7 @@ export class SpvVaults {
|
|
|
428
423
|
async startVaultsWatchdog() {
|
|
429
424
|
let rerun: () => Promise<void>;
|
|
430
425
|
rerun = async () => {
|
|
431
|
-
await this.checkVaults().catch( e =>
|
|
426
|
+
await this.checkVaults().catch( e => this.logger.error("startVaultsWatchdog(): Error when periodically checking SPV vaults: ", e));
|
|
432
427
|
setTimeout(rerun, this.config.vaultsCheckInterval);
|
|
433
428
|
};
|
|
434
429
|
await rerun();
|
|
@@ -713,7 +713,7 @@ export class FromBtcTrusted extends SwapHandler<FromBtcTrustedSwap, FromBtcTrust
|
|
|
713
713
|
private async startDoubleSpendWatchdog() {
|
|
714
714
|
let rerun: () => Promise<void>;
|
|
715
715
|
rerun = async () => {
|
|
716
|
-
await this.checkDoubleSpends().catch( e =>
|
|
716
|
+
await this.checkDoubleSpends().catch( e => this.logger.error("startDoubleSpendWatchdog(): Error when checking double spends: ", e));
|
|
717
717
|
setTimeout(rerun, this.config.doubleSpendCheckInterval);
|
|
718
718
|
};
|
|
719
719
|
await rerun();
|
|
@@ -90,7 +90,7 @@ export class FromBtcLnTrusted extends SwapHandler<FromBtcLnTrustedSwap, FromBtcL
|
|
|
90
90
|
this.lightning.waitForInvoice(hash, abortController.signal).then(invoice => {
|
|
91
91
|
this.swapLogger.debug(invoiceData, "subscribeToInvoice(): invoice_updated: ", invoice);
|
|
92
92
|
if(invoice.status!=="held") return;
|
|
93
|
-
this.htlcReceived(invoiceData, invoice).catch(e =>
|
|
93
|
+
this.htlcReceived(invoiceData, invoice).catch(e => this.swapLogger.error(invoiceData, "subscribeToInvoice(): Error calling htlcReceived(): ", e));
|
|
94
94
|
this.activeSubscriptions.delete(hash);
|
|
95
95
|
});
|
|
96
96
|
|
|
@@ -117,7 +117,7 @@ export class FromBtcLnTrusted extends SwapHandler<FromBtcLnTrustedSwap, FromBtcL
|
|
|
117
117
|
await this.htlcReceived(swap, invoice);
|
|
118
118
|
//Result is either FromBtcLnTrustedSwapState.RECEIVED or FromBtcLnTrustedSwapState.CANCELED
|
|
119
119
|
} catch (e) {
|
|
120
|
-
|
|
120
|
+
this.swapLogger.error(swap, "processPastSwap(): Error calling htlcReceived(): ", e);
|
|
121
121
|
}
|
|
122
122
|
return false;
|
|
123
123
|
case "confirmed":
|
|
@@ -226,7 +226,7 @@ export class FromBtcLnTrusted extends SwapHandler<FromBtcLnTrustedSwap, FromBtcL
|
|
|
226
226
|
await invoiceData.setState(FromBtcLnTrustedSwapState.SENT);
|
|
227
227
|
await this.storageManager.saveData(invoice.id, null, invoiceData);
|
|
228
228
|
}
|
|
229
|
-
}).catch(e =>
|
|
229
|
+
}).catch(e => this.swapLogger.error(invoiceData, "htlcReceived(): Error sending transfer txns", e));
|
|
230
230
|
|
|
231
231
|
if(result==null) {
|
|
232
232
|
//Cancel invoice
|
|
@@ -459,8 +459,6 @@ export class FromBtcLnTrusted extends SwapHandler<FromBtcLnTrustedSwap, FromBtcL
|
|
|
459
459
|
metadata.times.invoiceCreated = Date.now();
|
|
460
460
|
metadata.invoiceResponse = {...hodlInvoice};
|
|
461
461
|
|
|
462
|
-
console.log("[From BTC-LN: REST.CreateInvoice] hodl invoice created: ", hodlInvoice);
|
|
463
|
-
|
|
464
462
|
const createdSwap = new FromBtcLnTrustedSwap(
|
|
465
463
|
chainIdentifier,
|
|
466
464
|
hodlInvoice.request,
|
package/src/utils/Utils.ts
CHANGED
|
@@ -1,6 +1,22 @@
|
|
|
1
1
|
import {Request, Response} from "express";
|
|
2
2
|
import {ServerParamEncoder} from "./paramcoders/server/ServerParamEncoder";
|
|
3
3
|
|
|
4
|
+
export type LoggerType = {
|
|
5
|
+
debug: (msg: string, ...args: any[]) => void,
|
|
6
|
+
info: (msg: string, ...args: any[]) => void,
|
|
7
|
+
warn: (msg: string, ...args: any[]) => void,
|
|
8
|
+
error: (msg: string, ...args: any[]) => void
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export function getLogger(prefix: string | (() => string)): LoggerType {
|
|
12
|
+
return {
|
|
13
|
+
debug: (msg, ...args) => global.atomiqLogLevel >= 3 && console.debug((typeof(prefix)==="function" ? prefix() : prefix)+msg, ...args),
|
|
14
|
+
info: (msg, ...args) => global.atomiqLogLevel >= 2 && console.info((typeof(prefix)==="function" ? prefix() : prefix)+msg, ...args),
|
|
15
|
+
warn: (msg, ...args) => (global.atomiqLogLevel==null || global.atomiqLogLevel >= 1) && console.warn((typeof(prefix)==="function" ? prefix() : prefix)+msg, ...args),
|
|
16
|
+
error: (msg, ...args) => (global.atomiqLogLevel==null || global.atomiqLogLevel >= 0) && console.error((typeof(prefix)==="function" ? prefix() : prefix)+msg, ...args)
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
|
|
4
20
|
export type DefinedRuntimeError = {
|
|
5
21
|
code: number;
|
|
6
22
|
msg?: string;
|
|
@@ -17,6 +33,8 @@ export function isDefinedRuntimeError(obj: any): obj is DefinedRuntimeError {
|
|
|
17
33
|
return false;
|
|
18
34
|
}
|
|
19
35
|
|
|
36
|
+
const expressHandlerWrapperLogger = getLogger("ExpressHandlerWrapper: ");
|
|
37
|
+
|
|
20
38
|
export function expressHandlerWrapper(func: (
|
|
21
39
|
req: Request,
|
|
22
40
|
res: Response
|
|
@@ -32,7 +50,7 @@ export function expressHandlerWrapper(func: (
|
|
|
32
50
|
try {
|
|
33
51
|
await func(req, res);
|
|
34
52
|
} catch (e) {
|
|
35
|
-
|
|
53
|
+
expressHandlerWrapperLogger.error("Error in called function "+req.path+": ", e);
|
|
36
54
|
let statusCode = 500;
|
|
37
55
|
const obj: {code: number, msg: string, data?: any} = {
|
|
38
56
|
code: 0,
|
|
@@ -56,22 +74,6 @@ export function expressHandlerWrapper(func: (
|
|
|
56
74
|
}
|
|
57
75
|
}
|
|
58
76
|
|
|
59
|
-
export type LoggerType = {
|
|
60
|
-
debug: (msg: string, ...args: any[]) => void,
|
|
61
|
-
info: (msg: string, ...args: any[]) => void,
|
|
62
|
-
warn: (msg: string, ...args: any[]) => void,
|
|
63
|
-
error: (msg: string, ...args: any[]) => void
|
|
64
|
-
};
|
|
65
|
-
|
|
66
|
-
export function getLogger(prefix: string): LoggerType {
|
|
67
|
-
return {
|
|
68
|
-
debug: (msg, ...args) => console.debug(prefix+msg, ...args),
|
|
69
|
-
info: (msg, ...args) => console.info(prefix+msg, ...args),
|
|
70
|
-
warn: (msg, ...args) => console.warn(prefix+msg, ...args),
|
|
71
|
-
error: (msg, ...args) => console.error(prefix+msg, ...args)
|
|
72
|
-
};
|
|
73
|
-
}
|
|
74
|
-
|
|
75
77
|
export const HEX_REGEX = /[0-9a-fA-F]+/;
|
|
76
78
|
|
|
77
79
|
export function serializeBN(bn: bigint | null): string | null {
|
|
@@ -3,6 +3,7 @@ import {RequestSchema, verifySchema} from "../SchemaVerifier";
|
|
|
3
3
|
import {ParamDecoder} from "../ParamDecoder";
|
|
4
4
|
import {ServerParamEncoder} from "./ServerParamEncoder";
|
|
5
5
|
import {IParamReader} from "../IParamReader";
|
|
6
|
+
import {getLogger} from "../../Utils";
|
|
6
7
|
|
|
7
8
|
export class RequestTimeoutError extends Error {
|
|
8
9
|
|
|
@@ -24,6 +25,8 @@ export class RequestParsingError extends Error {
|
|
|
24
25
|
|
|
25
26
|
}
|
|
26
27
|
|
|
28
|
+
const logger = getLogger("ServerParamDecoder: ");
|
|
29
|
+
|
|
27
30
|
export const serverParamDecoder = (timeoutMillis: number) => (req: Request, res: Response, next: () => void) => {
|
|
28
31
|
|
|
29
32
|
let timeout;
|
|
@@ -50,14 +53,14 @@ export const serverParamDecoder = (timeoutMillis: number) => (req: Request, res:
|
|
|
50
53
|
(req as any).paramReader = paramReader;
|
|
51
54
|
next();
|
|
52
55
|
} catch (e) {
|
|
53
|
-
|
|
56
|
+
logger.error("error reading legacy (non-streaming) http request", e);
|
|
54
57
|
req.destroy(new RequestParsingError());
|
|
55
58
|
res.destroy(new RequestParsingError());
|
|
56
59
|
}
|
|
57
60
|
clearTimeout(timeout);
|
|
58
61
|
});
|
|
59
62
|
req.on("error", (e) => {
|
|
60
|
-
|
|
63
|
+
logger.error("error reading legacy (non-streaming) http request",e);
|
|
61
64
|
});
|
|
62
65
|
|
|
63
66
|
timeout = setTimeout(() => {
|
|
@@ -74,7 +77,7 @@ export const serverParamDecoder = (timeoutMillis: number) => (req: Request, res:
|
|
|
74
77
|
try {
|
|
75
78
|
decoder.onData(data);
|
|
76
79
|
} catch (e) {
|
|
77
|
-
|
|
80
|
+
logger.error("error reading streaming http request: on(\"data\")", e);
|
|
78
81
|
req.destroy(new RequestParsingError());
|
|
79
82
|
res.destroy(new RequestParsingError());
|
|
80
83
|
}
|
|
@@ -83,7 +86,7 @@ export const serverParamDecoder = (timeoutMillis: number) => (req: Request, res:
|
|
|
83
86
|
try {
|
|
84
87
|
decoder.onEnd();
|
|
85
88
|
} catch (e) {
|
|
86
|
-
|
|
89
|
+
logger.error("error reading streaming http request: on(\"end\")", e);
|
|
87
90
|
req.destroy(new RequestParsingError());
|
|
88
91
|
res.destroy(new RequestParsingError());
|
|
89
92
|
}
|
|
@@ -93,7 +96,7 @@ export const serverParamDecoder = (timeoutMillis: number) => (req: Request, res:
|
|
|
93
96
|
try {
|
|
94
97
|
decoder.onError(e);
|
|
95
98
|
} catch(e) {
|
|
96
|
-
|
|
99
|
+
logger.error("error reading streaming http request: on(\"error\")", e);
|
|
97
100
|
}
|
|
98
101
|
});
|
|
99
102
|
|
|
@@ -101,7 +104,7 @@ export const serverParamDecoder = (timeoutMillis: number) => (req: Request, res:
|
|
|
101
104
|
try {
|
|
102
105
|
decoder.onEnd();
|
|
103
106
|
} catch(e) {
|
|
104
|
-
|
|
107
|
+
logger.error("error reading streaming http request: timeout", e);
|
|
105
108
|
}
|
|
106
109
|
req.destroy(new RequestTimeoutError());
|
|
107
110
|
res.destroy(new RequestTimeoutError());
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
/// <reference types="node" />
|
|
2
|
-
import { Command } from "@atomiqlabs/server-base";
|
|
3
|
-
import { Transaction } from "@scure/btc-signer";
|
|
4
|
-
export type BitcoinUtxo = {
|
|
5
|
-
address: string;
|
|
6
|
-
type: "p2wpkh" | "p2sh-p2wpkh" | "p2tr";
|
|
7
|
-
confirmations: number;
|
|
8
|
-
outputScript: Buffer;
|
|
9
|
-
value: number;
|
|
10
|
-
txId: string;
|
|
11
|
-
vout: number;
|
|
12
|
-
};
|
|
13
|
-
export type SignPsbtResponse = {
|
|
14
|
-
psbt: Transaction;
|
|
15
|
-
tx: Transaction;
|
|
16
|
-
raw: string;
|
|
17
|
-
txId: string;
|
|
18
|
-
networkFee: number;
|
|
19
|
-
};
|
|
20
|
-
export interface ISpvVaultSigner {
|
|
21
|
-
init(): Promise<void>;
|
|
22
|
-
isReady(): boolean;
|
|
23
|
-
getStatus(): string;
|
|
24
|
-
getStatusInfo(): Promise<Record<string, string>>;
|
|
25
|
-
getCommands(): Command<any>[];
|
|
26
|
-
getAddressType(): "p2wpkh" | "p2sh-p2wpkh" | "p2tr";
|
|
27
|
-
/**
|
|
28
|
-
* Returns an unused address suitable for receiving
|
|
29
|
-
*/
|
|
30
|
-
getAddress(vaultId: bigint): Promise<string>;
|
|
31
|
-
signPsbt(vaultId: bigint, psbt: Transaction): Promise<SignPsbtResponse>;
|
|
32
|
-
sendRawTransaction(tx: string): Promise<void>;
|
|
33
|
-
getSignedTransaction(destination: string, amount: number, feeRate?: number, nonce?: bigint, maxAllowedFeeRate?: number): Promise<SignPsbtResponse>;
|
|
34
|
-
estimateFee(destination: string, amount: number, feeRate?: number, feeRateMultiplier?: number): Promise<{
|
|
35
|
-
satsPerVbyte: number;
|
|
36
|
-
networkFee: number;
|
|
37
|
-
}>;
|
|
38
|
-
drainAll(destination: string | Buffer, inputs: Omit<BitcoinUtxo, "address">[], feeRate?: number): Promise<SignPsbtResponse>;
|
|
39
|
-
burnAll(inputs: Omit<BitcoinUtxo, "address">[]): Promise<SignPsbtResponse>;
|
|
40
|
-
getBlockheight(): Promise<number>;
|
|
41
|
-
getFeeRate(): Promise<number>;
|
|
42
|
-
}
|