@atomiqlabs/chain-evm 2.1.12 → 2.1.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +75 -0
- package/dist/chains/EVMOptions.d.ts +66 -0
- package/dist/chains/EVMOptions.js +2 -0
- package/dist/chains/alpen/AlpenInitializer.d.ts +3 -30
- package/dist/chains/alpen/AlpenInitializer.js +3 -3
- package/dist/chains/botanix/BotanixInitializer.d.ts +3 -30
- package/dist/chains/botanix/BotanixInitializer.js +3 -3
- package/dist/chains/citrea/CitreaBtcRelay.d.ts +5 -0
- package/dist/chains/citrea/CitreaBtcRelay.js +7 -2
- package/dist/chains/citrea/CitreaFees.d.ts +3 -5
- package/dist/chains/citrea/CitreaFees.js +3 -5
- package/dist/chains/citrea/CitreaInitializer.d.ts +3 -29
- package/dist/chains/citrea/CitreaInitializer.js +3 -3
- package/dist/chains/citrea/CitreaSpvVaultContract.d.ts +5 -0
- package/dist/chains/citrea/CitreaSpvVaultContract.js +7 -2
- package/dist/chains/citrea/CitreaSwapContract.d.ts +7 -2
- package/dist/chains/citrea/CitreaSwapContract.js +10 -5
- package/dist/chains/citrea/CitreaTokens.d.ts +5 -0
- package/dist/chains/citrea/CitreaTokens.js +5 -0
- package/dist/chains/goat/GoatInitializer.d.ts +3 -30
- package/dist/chains/goat/GoatInitializer.js +3 -3
- package/dist/evm/btcrelay/EVMBtcRelay.d.ts +41 -10
- package/dist/evm/btcrelay/EVMBtcRelay.js +50 -18
- package/dist/evm/btcrelay/headers/EVMBtcHeader.d.ts +53 -7
- package/dist/evm/btcrelay/headers/EVMBtcHeader.js +43 -5
- package/dist/evm/btcrelay/headers/EVMBtcStoredHeader.d.ts +53 -8
- package/dist/evm/btcrelay/headers/EVMBtcStoredHeader.js +41 -1
- package/dist/evm/chain/EVMChainInterface.d.ts +57 -2
- package/dist/evm/chain/EVMChainInterface.js +7 -7
- package/dist/evm/chain/EVMModule.d.ts +5 -0
- package/dist/evm/chain/EVMModule.js +6 -1
- package/dist/evm/chain/modules/EVMBlocks.d.ts +7 -0
- package/dist/evm/chain/modules/EVMBlocks.js +2 -0
- package/dist/evm/chain/modules/EVMEvents.js +19 -19
- package/dist/evm/chain/modules/EVMFees.d.ts +41 -5
- package/dist/evm/chain/modules/EVMFees.js +24 -5
- package/dist/evm/chain/modules/EVMTokens.d.ts +1 -1
- package/dist/evm/chain/modules/EVMTokens.js +1 -1
- package/dist/evm/chain/modules/EVMTransactions.d.ts +20 -2
- package/dist/evm/chain/modules/EVMTransactions.js +11 -8
- package/dist/evm/contract/EVMContractBase.d.ts +28 -10
- package/dist/evm/contract/EVMContractBase.js +9 -18
- package/dist/evm/contract/EVMContractModule.d.ts +5 -0
- package/dist/evm/contract/EVMContractModule.js +5 -0
- package/dist/evm/contract/modules/EVMContractEvents.d.ts +7 -1
- package/dist/evm/contract/modules/EVMContractEvents.js +23 -3
- package/dist/evm/events/EVMChainEvents.d.ts +8 -0
- package/dist/evm/events/EVMChainEvents.js +8 -0
- package/dist/evm/events/EVMChainEventsBrowser.d.ts +87 -19
- package/dist/evm/events/EVMChainEventsBrowser.js +53 -18
- package/dist/evm/providers/JsonRpcProviderWithRetries.d.ts +9 -0
- package/dist/evm/providers/JsonRpcProviderWithRetries.js +9 -0
- package/dist/evm/providers/ReconnectingWebSocketProvider.d.ts +5 -0
- package/dist/evm/providers/ReconnectingWebSocketProvider.js +5 -0
- package/dist/evm/providers/WebSocketProviderWithRetries.d.ts +9 -0
- package/dist/evm/providers/WebSocketProviderWithRetries.js +9 -0
- package/dist/evm/spv_swap/EVMSpvVaultContract.d.ts +46 -21
- package/dist/evm/spv_swap/EVMSpvVaultContract.js +61 -23
- package/dist/evm/spv_swap/EVMSpvVaultData.d.ts +57 -2
- package/dist/evm/spv_swap/EVMSpvVaultData.js +57 -2
- package/dist/evm/spv_swap/EVMSpvWithdrawalData.d.ts +12 -0
- package/dist/evm/spv_swap/EVMSpvWithdrawalData.js +12 -0
- package/dist/evm/swaps/EVMSwapContract.d.ts +58 -13
- package/dist/evm/swaps/EVMSwapContract.js +81 -54
- package/dist/evm/swaps/EVMSwapData.d.ts +27 -6
- package/dist/evm/swaps/EVMSwapData.js +26 -0
- package/dist/evm/swaps/EVMSwapModule.d.ts +5 -0
- package/dist/evm/swaps/EVMSwapModule.js +5 -0
- package/dist/evm/swaps/handlers/IHandler.d.ts +5 -0
- package/dist/evm/swaps/handlers/claim/ClaimHandlers.d.ts +15 -0
- package/dist/evm/swaps/handlers/claim/ClaimHandlers.js +5 -0
- package/dist/evm/swaps/handlers/claim/btc/BitcoinNoncedOutputClaimHandler.d.ts +5 -0
- package/dist/evm/swaps/handlers/claim/btc/BitcoinOutputClaimHandler.d.ts +10 -0
- package/dist/evm/swaps/handlers/claim/btc/BitcoinTxIdClaimHandler.d.ts +5 -0
- package/dist/evm/swaps/handlers/claim/btc/IBitcoinClaimHandler.d.ts +15 -0
- package/dist/evm/swaps/handlers/claim/btc/IBitcoinClaimHandler.js +7 -2
- package/dist/evm/swaps/modules/EVMLpVault.d.ts +5 -0
- package/dist/evm/swaps/modules/EVMLpVault.js +9 -4
- package/dist/evm/swaps/modules/EVMSwapClaim.d.ts +7 -2
- package/dist/evm/swaps/modules/EVMSwapClaim.js +11 -6
- package/dist/evm/swaps/modules/EVMSwapInit.d.ts +10 -0
- package/dist/evm/swaps/modules/EVMSwapInit.js +11 -6
- package/dist/evm/swaps/modules/EVMSwapRefund.d.ts +5 -0
- package/dist/evm/swaps/modules/EVMSwapRefund.js +9 -4
- package/dist/evm/wallet/EVMBrowserSigner.d.ts +22 -2
- package/dist/evm/wallet/EVMBrowserSigner.js +40 -2
- package/dist/evm/wallet/EVMPersistentSigner.d.ts +13 -2
- package/dist/evm/wallet/EVMPersistentSigner.js +13 -1
- package/dist/evm/wallet/EVMSigner.d.ts +30 -1
- package/dist/evm/wallet/EVMSigner.js +34 -1
- package/dist/index.d.ts +71 -0
- package/dist/index.js +70 -0
- package/dist/node/index.d.ts +10 -0
- package/dist/node/index.js +15 -0
- package/dist/utils/Utils.d.ts +50 -0
- package/dist/utils/Utils.js +45 -0
- package/node/index.d.ts +1 -0
- package/node/index.js +3 -0
- package/package.json +4 -3
- package/src/chains/EVMOptions.ts +70 -0
- package/src/chains/alpen/AlpenInitializer.ts +5 -27
- package/src/chains/botanix/BotanixChainType.ts +5 -5
- package/src/chains/botanix/BotanixInitializer.ts +5 -27
- package/src/chains/citrea/CitreaBtcRelay.ts +8 -3
- package/src/chains/citrea/CitreaFees.ts +3 -6
- package/src/chains/citrea/CitreaInitializer.ts +5 -27
- package/src/chains/citrea/CitreaSpvVaultContract.ts +7 -2
- package/src/chains/citrea/CitreaSwapContract.ts +11 -6
- package/src/chains/citrea/CitreaTokens.ts +6 -1
- package/src/chains/goat/GoatChainType.ts +5 -5
- package/src/chains/goat/GoatInitializer.ts +3 -25
- package/src/evm/btcrelay/EVMBtcRelay.ts +54 -22
- package/src/evm/btcrelay/headers/EVMBtcHeader.ts +60 -13
- package/src/evm/btcrelay/headers/EVMBtcStoredHeader.ts +55 -10
- package/src/evm/chain/EVMChainInterface.ts +66 -14
- package/src/evm/chain/EVMModule.ts +6 -1
- package/src/evm/chain/modules/EVMBlocks.ts +7 -0
- package/src/evm/chain/modules/EVMEvents.ts +19 -19
- package/src/evm/chain/modules/EVMFees.ts +41 -5
- package/src/evm/chain/modules/EVMTokens.ts +1 -1
- package/src/evm/chain/modules/EVMTransactions.ts +27 -8
- package/src/evm/contract/EVMContractBase.ts +29 -24
- package/src/evm/contract/EVMContractModule.ts +5 -0
- package/src/evm/contract/modules/EVMContractEvents.ts +27 -8
- package/src/evm/events/EVMChainEvents.ts +8 -0
- package/src/evm/events/EVMChainEventsBrowser.ts +103 -29
- package/src/evm/providers/JsonRpcProviderWithRetries.ts +10 -1
- package/src/evm/providers/ReconnectingWebSocketProvider.ts +6 -1
- package/src/evm/providers/WebSocketProviderWithRetries.ts +10 -1
- package/src/evm/spv_swap/EVMSpvVaultContract.ts +72 -32
- package/src/evm/spv_swap/EVMSpvVaultData.ts +57 -2
- package/src/evm/spv_swap/EVMSpvWithdrawalData.ts +12 -0
- package/src/evm/swaps/EVMSwapContract.ts +108 -63
- package/src/evm/swaps/EVMSwapData.ts +27 -1
- package/src/evm/swaps/EVMSwapModule.ts +5 -0
- package/src/evm/swaps/handlers/IHandler.ts +5 -0
- package/src/evm/swaps/handlers/claim/ClaimHandlers.ts +15 -0
- package/src/evm/swaps/handlers/claim/btc/BitcoinNoncedOutputClaimHandler.ts +5 -0
- package/src/evm/swaps/handlers/claim/btc/BitcoinOutputClaimHandler.ts +10 -0
- package/src/evm/swaps/handlers/claim/btc/BitcoinTxIdClaimHandler.ts +5 -0
- package/src/evm/swaps/handlers/claim/btc/IBitcoinClaimHandler.ts +17 -2
- package/src/evm/swaps/modules/EVMLpVault.ts +10 -5
- package/src/evm/swaps/modules/EVMSwapClaim.ts +12 -7
- package/src/evm/swaps/modules/EVMSwapInit.ts +17 -7
- package/src/evm/swaps/modules/EVMSwapRefund.ts +9 -4
- package/src/evm/wallet/EVMBrowserSigner.ts +44 -5
- package/src/evm/wallet/EVMPersistentSigner.ts +14 -2
- package/src/evm/wallet/EVMSigner.ts +37 -1
- package/src/index.ts +72 -0
- package/src/node/index.ts +10 -0
- package/src/utils/Utils.ts +50 -1
|
@@ -39,16 +39,28 @@ function decodeUtxo(utxo: string): {txHash: string, vout: bigint} {
|
|
|
39
39
|
}
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
+
/**
|
|
43
|
+
* Packs vault owner and vault id into compact `owner+vaultId` event key format.
|
|
44
|
+
*
|
|
45
|
+
* @category Swaps
|
|
46
|
+
*/
|
|
42
47
|
export function packOwnerAndVaultId(owner: string, vaultId: bigint): string {
|
|
43
48
|
if(owner.length!==42) throw new Error("Invalid owner address");
|
|
44
49
|
return owner.toLowerCase() + BigIntBufferUtils.toBuffer(vaultId, "be", 12).toString("hex");
|
|
45
50
|
}
|
|
46
51
|
|
|
52
|
+
/**
|
|
53
|
+
* Unpacks compact `owner+vaultId` event key format into owner and vault id.
|
|
54
|
+
*
|
|
55
|
+
* @category Swaps
|
|
56
|
+
*/
|
|
47
57
|
export function unpackOwnerAndVaultId(data: string): [string, bigint] {
|
|
48
58
|
return [getAddress(data.substring(0, 42)), BigInt("0x"+data.substring(42, 66))];
|
|
49
59
|
}
|
|
50
60
|
|
|
51
61
|
/**
|
|
62
|
+
* EVM SPV vault (UTXO-controlled vault) contract representation.
|
|
63
|
+
*
|
|
52
64
|
* @category Swaps
|
|
53
65
|
*/
|
|
54
66
|
export class EVMSpvVaultContract<ChainId extends string>
|
|
@@ -61,7 +73,7 @@ export class EVMSpvVaultContract<ChainId extends string>
|
|
|
61
73
|
EVMSpvVaultData
|
|
62
74
|
>
|
|
63
75
|
{
|
|
64
|
-
|
|
76
|
+
private static readonly GasCosts = {
|
|
65
77
|
DEPOSIT_BASE: 15_000 + 21_000,
|
|
66
78
|
DEPOSIT_ERC20: 40_000,
|
|
67
79
|
|
|
@@ -79,12 +91,12 @@ export class EVMSpvVaultContract<ChainId extends string>
|
|
|
79
91
|
};
|
|
80
92
|
|
|
81
93
|
readonly chainId: ChainId;
|
|
94
|
+
public readonly claimTimeout: number = 180;
|
|
82
95
|
|
|
83
|
-
readonly btcRelay: EVMBtcRelay<any>;
|
|
84
|
-
readonly bitcoinRpc: BitcoinRpc<any>;
|
|
85
|
-
readonly claimTimeout: number = 180;
|
|
96
|
+
private readonly btcRelay: EVMBtcRelay<any>;
|
|
97
|
+
private readonly bitcoinRpc: BitcoinRpc<any>;
|
|
86
98
|
|
|
87
|
-
readonly logger = getLogger("EVMSpvVaultContract: ");
|
|
99
|
+
private readonly logger = getLogger("EVMSpvVaultContract: ");
|
|
88
100
|
|
|
89
101
|
constructor(
|
|
90
102
|
chainInterface: EVMChainInterface<ChainId>,
|
|
@@ -100,20 +112,20 @@ export class EVMSpvVaultContract<ChainId extends string>
|
|
|
100
112
|
}
|
|
101
113
|
|
|
102
114
|
//Transactions
|
|
103
|
-
|
|
115
|
+
private async Open(signer: string, vault: EVMSpvVaultData, feeRate: string): Promise<TransactionRequest> {
|
|
104
116
|
const {txHash, vout} = decodeUtxo(vault.getUtxo());
|
|
105
117
|
|
|
106
118
|
const tokens = vault.getTokenData();
|
|
107
119
|
if(tokens.length!==2) throw new Error("Must specify exactly 2 tokens for vault!");
|
|
108
120
|
|
|
109
|
-
const tx = await this.contract.open.populateTransaction(vault.vaultId, vault.
|
|
121
|
+
const tx = await this.contract.open.populateTransaction(vault.vaultId, vault._getVaultParamsStruct(), txHash, vout);
|
|
110
122
|
tx.from = signer;
|
|
111
123
|
EVMFees.applyFeeRate(tx, EVMSpvVaultContract.GasCosts.OPEN, feeRate);
|
|
112
124
|
|
|
113
125
|
return tx;
|
|
114
126
|
}
|
|
115
127
|
|
|
116
|
-
|
|
128
|
+
private async Deposit(signer: string, vault: EVMSpvVaultData, rawAmounts: bigint[], feeRate: string): Promise<TransactionRequest> {
|
|
117
129
|
let totalGas = EVMSpvVaultContract.GasCosts.DEPOSIT_BASE;
|
|
118
130
|
let value = 0n;
|
|
119
131
|
if(vault.token0.token.toLowerCase()===this.Chain.getNativeCurrencyAddress().toLowerCase()) {
|
|
@@ -129,7 +141,7 @@ export class EVMSpvVaultContract<ChainId extends string>
|
|
|
129
141
|
}
|
|
130
142
|
|
|
131
143
|
const tx = await this.contract.deposit.populateTransaction(
|
|
132
|
-
vault.owner, vault.vaultId, vault.
|
|
144
|
+
vault.owner, vault.vaultId, vault._getVaultParamsStruct(),
|
|
133
145
|
rawAmounts[0], rawAmounts[1] ?? 0n, { value }
|
|
134
146
|
);
|
|
135
147
|
tx.from = signer;
|
|
@@ -138,7 +150,7 @@ export class EVMSpvVaultContract<ChainId extends string>
|
|
|
138
150
|
return tx;
|
|
139
151
|
}
|
|
140
152
|
|
|
141
|
-
|
|
153
|
+
private async Front(
|
|
142
154
|
signer: string, vault: EVMSpvVaultData, data: EVMSpvWithdrawalData, withdrawalSequence: number, feeRate: string
|
|
143
155
|
): Promise<TransactionRequest> {
|
|
144
156
|
let value = 0n;
|
|
@@ -149,7 +161,7 @@ export class EVMSpvVaultContract<ChainId extends string>
|
|
|
149
161
|
value += (frontingAmount[1] ?? 0n) * vault.token1.multiplier;
|
|
150
162
|
|
|
151
163
|
const tx = await this.contract.front.populateTransaction(
|
|
152
|
-
vault.owner, vault.vaultId, vault.
|
|
164
|
+
vault.owner, vault.vaultId, vault._getVaultParamsStruct(),
|
|
153
165
|
withdrawalSequence, data.getTxHash(), data.serializeToStruct(),
|
|
154
166
|
{ value }
|
|
155
167
|
);
|
|
@@ -159,12 +171,12 @@ export class EVMSpvVaultContract<ChainId extends string>
|
|
|
159
171
|
return tx;
|
|
160
172
|
}
|
|
161
173
|
|
|
162
|
-
|
|
174
|
+
private async Claim(
|
|
163
175
|
signer: string, vault: EVMSpvVaultData, data: EVMSpvWithdrawalData,
|
|
164
176
|
blockheader: EVMBtcStoredHeader, merkle: Buffer[], position: number, feeRate: string
|
|
165
177
|
): Promise<TransactionRequest> {
|
|
166
178
|
const tx = await this.contract.claim.populateTransaction(
|
|
167
|
-
vault.owner, vault.vaultId, vault.
|
|
179
|
+
vault.owner, vault.vaultId, vault._getVaultParamsStruct(), "0x"+data.btcTx.hex,
|
|
168
180
|
blockheader.serializeToStruct(), merkle, position
|
|
169
181
|
)
|
|
170
182
|
|
|
@@ -191,7 +203,7 @@ export class EVMSpvVaultContract<ChainId extends string>
|
|
|
191
203
|
if(tokenData.length!==2) throw new Error("Must specify 2 tokens in tokenData!");
|
|
192
204
|
|
|
193
205
|
const vaultParams = {
|
|
194
|
-
btcRelayContract: this.btcRelay.
|
|
206
|
+
btcRelayContract: this.btcRelay._contractAddress,
|
|
195
207
|
token0: tokenData[0].token,
|
|
196
208
|
token1: tokenData[1].token,
|
|
197
209
|
token0Multiplier: tokenData[0].multiplier,
|
|
@@ -239,7 +251,7 @@ export class EVMSpvVaultContract<ChainId extends string>
|
|
|
239
251
|
promises.push(this.getFronterAddress(owner, vaultId, withdrawal).then(val => {
|
|
240
252
|
result[withdrawal.getTxId()] = val;
|
|
241
253
|
}));
|
|
242
|
-
if(promises.length>=this.Chain.
|
|
254
|
+
if(promises.length>=this.Chain._config.maxParallelCalls) {
|
|
243
255
|
await Promise.all(promises);
|
|
244
256
|
promises = [];
|
|
245
257
|
}
|
|
@@ -260,7 +272,7 @@ export class EVMSpvVaultContract<ChainId extends string>
|
|
|
260
272
|
|
|
261
273
|
const vaultParams = await this.vaultParamsCache.getOrComputeAsync(vaultState.spvVaultParametersCommitment, async () => {
|
|
262
274
|
const blockheight = Number(vaultState.openBlockheight);
|
|
263
|
-
const events = await this.
|
|
275
|
+
const events = await this._Events.getContractBlockEvents(
|
|
264
276
|
["Opened"],
|
|
265
277
|
[
|
|
266
278
|
"0x"+owner.substring(2).padStart(64, "0"),
|
|
@@ -277,7 +289,7 @@ export class EVMSpvVaultContract<ChainId extends string>
|
|
|
277
289
|
return foundEvent.args.params;
|
|
278
290
|
});
|
|
279
291
|
|
|
280
|
-
if(vaultParams.btcRelayContract.toLowerCase()!==this.btcRelay.
|
|
292
|
+
if(vaultParams.btcRelayContract.toLowerCase()!==this.btcRelay._contractAddress.toLowerCase()) return null;
|
|
281
293
|
|
|
282
294
|
return new EVMSpvVaultData(owner, vaultId, vaultState, vaultParams);
|
|
283
295
|
}
|
|
@@ -294,7 +306,7 @@ export class EVMSpvVaultContract<ChainId extends string>
|
|
|
294
306
|
result[owner] ??= {};
|
|
295
307
|
result[owner][vaultId.toString(10)] = val;
|
|
296
308
|
}));
|
|
297
|
-
if(promises.length>=this.Chain.
|
|
309
|
+
if(promises.length>=this.Chain._config.maxParallelCalls) {
|
|
298
310
|
await Promise.all(promises);
|
|
299
311
|
promises = [];
|
|
300
312
|
}
|
|
@@ -325,7 +337,7 @@ export class EVMSpvVaultContract<ChainId extends string>
|
|
|
325
337
|
result[owner] ??= {};
|
|
326
338
|
result[owner][vaultId.toString(10)] = val;
|
|
327
339
|
}));
|
|
328
|
-
if(promises.length>=this.Chain.
|
|
340
|
+
if(promises.length>=this.Chain._config.maxParallelCalls) {
|
|
329
341
|
await Promise.all(promises);
|
|
330
342
|
promises = [];
|
|
331
343
|
}
|
|
@@ -339,7 +351,7 @@ export class EVMSpvVaultContract<ChainId extends string>
|
|
|
339
351
|
*/
|
|
340
352
|
async getAllVaults(owner?: string): Promise<EVMSpvVaultData[]> {
|
|
341
353
|
const openedVaults = new Map<string, SpvVaultParametersStructOutput>();
|
|
342
|
-
await this.
|
|
354
|
+
await this._Events.findInContractEventsForward(
|
|
343
355
|
["Opened", "Closed"],
|
|
344
356
|
owner==null ? null : [
|
|
345
357
|
"0x"+owner.substring(2).padStart(64, "0")
|
|
@@ -358,7 +370,7 @@ export class EVMSpvVaultContract<ChainId extends string>
|
|
|
358
370
|
const vaults: EVMSpvVaultData[] = [];
|
|
359
371
|
let promises: Promise<void>[] = [];
|
|
360
372
|
for(let [identifier, vaultParams] of openedVaults.entries()) {
|
|
361
|
-
if(vaultParams.btcRelayContract.toLowerCase()!==this.btcRelay.
|
|
373
|
+
if(vaultParams.btcRelayContract.toLowerCase()!==this.btcRelay._contractAddress.toLowerCase()) continue;
|
|
362
374
|
|
|
363
375
|
const [owner, vaultIdStr] = identifier.split(":");
|
|
364
376
|
|
|
@@ -368,7 +380,7 @@ export class EVMSpvVaultContract<ChainId extends string>
|
|
|
368
380
|
}
|
|
369
381
|
}))
|
|
370
382
|
|
|
371
|
-
if(promises.length>=this.Chain.
|
|
383
|
+
if(promises.length>=this.Chain._config.maxParallelCalls) {
|
|
372
384
|
await Promise.all(promises);
|
|
373
385
|
promises = [];
|
|
374
386
|
}
|
|
@@ -444,14 +456,14 @@ export class EVMSpvVaultContract<ChainId extends string>
|
|
|
444
456
|
|
|
445
457
|
let result: SpvWithdrawalState | null;
|
|
446
458
|
if(scStartHeight==null) {
|
|
447
|
-
result = await this.
|
|
459
|
+
result = await this._Events.findInContractEvents(
|
|
448
460
|
events, keys,
|
|
449
461
|
async (event) => {
|
|
450
462
|
return this.parseWithdrawalEvent(event);
|
|
451
463
|
}
|
|
452
464
|
);
|
|
453
465
|
} else {
|
|
454
|
-
result = await this.
|
|
466
|
+
result = await this._Events.findInContractEventsForward(
|
|
455
467
|
events, keys,
|
|
456
468
|
async (event) => {
|
|
457
469
|
const result = this.parseWithdrawalEvent(event);
|
|
@@ -481,8 +493,8 @@ export class EVMSpvVaultContract<ChainId extends string>
|
|
|
481
493
|
|
|
482
494
|
const events: ["Fronted", "Claimed", "Closed"] = ["Fronted", "Claimed", "Closed"];
|
|
483
495
|
|
|
484
|
-
for(let i=0;i<withdrawalTxs.length;i+=this.Chain.
|
|
485
|
-
const checkWithdrawalTxs = withdrawalTxs.slice(i, i+this.Chain.
|
|
496
|
+
for(let i=0;i<withdrawalTxs.length;i+=this.Chain._config.maxLogTopics) {
|
|
497
|
+
const checkWithdrawalTxs = withdrawalTxs.slice(i, i+this.Chain._config.maxLogTopics);
|
|
486
498
|
const checkWithdrawalTxsMap = new Map(checkWithdrawalTxs.map(val => [val.withdrawal.getTxId() as string, val.withdrawal]));
|
|
487
499
|
|
|
488
500
|
let scStartHeight = null;
|
|
@@ -497,7 +509,7 @@ export class EVMSpvVaultContract<ChainId extends string>
|
|
|
497
509
|
const keys = [null, null, checkWithdrawalTxs.map(withdrawal => hexlify(Buffer.from(withdrawal.withdrawal.getTxId(), "hex").reverse()))];
|
|
498
510
|
|
|
499
511
|
if(scStartHeight==null) {
|
|
500
|
-
await this.
|
|
512
|
+
await this._Events.findInContractEvents(
|
|
501
513
|
events, keys,
|
|
502
514
|
async (event) => {
|
|
503
515
|
const _event = event as TypedEventLog<SpvVaultManager["filters"]["Fronted" | "Claimed" | "Closed"]>;
|
|
@@ -514,7 +526,7 @@ export class EVMSpvVaultContract<ChainId extends string>
|
|
|
514
526
|
}
|
|
515
527
|
);
|
|
516
528
|
} else {
|
|
517
|
-
await this.
|
|
529
|
+
await this._Events.findInContractEventsForward(
|
|
518
530
|
events, keys,
|
|
519
531
|
async (event) => {
|
|
520
532
|
const _event = event as TypedEventLog<SpvVaultManager["filters"]["Fronted" | "Claimed" | "Closed"]>;
|
|
@@ -560,7 +572,7 @@ export class EVMSpvVaultContract<ChainId extends string>
|
|
|
560
572
|
const {height: latestBlockheight} = await this.Chain.getFinalizedBlock();
|
|
561
573
|
const withdrawals: { [btcTxId: string]: SpvWithdrawalClaimedState | SpvWithdrawalFrontedState } = {};
|
|
562
574
|
|
|
563
|
-
await this.
|
|
575
|
+
await this._Events.findInContractEventsForward(
|
|
564
576
|
["Claimed", "Fronted"],
|
|
565
577
|
[null, recipient],
|
|
566
578
|
async (_event) => {
|
|
@@ -591,6 +603,12 @@ export class EVMSpvVaultContract<ChainId extends string>
|
|
|
591
603
|
fromOpReturnData(data: Buffer): { recipient: string; rawAmounts: bigint[]; executionHash?: string } {
|
|
592
604
|
return EVMSpvVaultContract.fromOpReturnData(data);
|
|
593
605
|
}
|
|
606
|
+
|
|
607
|
+
/**
|
|
608
|
+
* Parses withdrawal params from OP_RETURN data.
|
|
609
|
+
*
|
|
610
|
+
* @param data Data as specified in the OP_RETURN output of the transaction
|
|
611
|
+
*/
|
|
594
612
|
static fromOpReturnData(data: Buffer): { recipient: string; rawAmounts: bigint[]; executionHash?: string } {
|
|
595
613
|
let rawAmount0: bigint = 0n;
|
|
596
614
|
let rawAmount1: bigint = 0n;
|
|
@@ -623,6 +641,14 @@ export class EVMSpvVaultContract<ChainId extends string>
|
|
|
623
641
|
toOpReturnData(recipient: string, rawAmounts: bigint[], executionHash?: string): Buffer {
|
|
624
642
|
return EVMSpvVaultContract.toOpReturnData(recipient, rawAmounts, executionHash);
|
|
625
643
|
}
|
|
644
|
+
|
|
645
|
+
/**
|
|
646
|
+
* Serializes withdrawal params to OP_RETURN data.
|
|
647
|
+
*
|
|
648
|
+
* @param recipient Recipient of the withdrawn tokens
|
|
649
|
+
* @param rawAmounts Raw amount of tokens to withdraw
|
|
650
|
+
* @param executionHash Optional execution hash of the actions to execute
|
|
651
|
+
*/
|
|
626
652
|
static toOpReturnData(recipient: string, rawAmounts: bigint[], executionHash?: string): Buffer {
|
|
627
653
|
if(!EVMAddresses.isValidAddress(recipient)) throw new Error("Invalid recipient specified");
|
|
628
654
|
if(rawAmounts.length < 1) throw new Error("At least 1 amount needs to be specified");
|
|
@@ -769,7 +795,7 @@ export class EVMSpvVaultContract<ChainId extends string>
|
|
|
769
795
|
}
|
|
770
796
|
|
|
771
797
|
const requiredApprovalTxns = await Promise.all(
|
|
772
|
-
Object.keys(requiredApprovals).map(token => this.Chain.Tokens.checkAndGetApproveTx(signer, token, requiredApprovals[token], this.
|
|
798
|
+
Object.keys(requiredApprovals).map(token => this.Chain.Tokens.checkAndGetApproveTx(signer, token, requiredApprovals[token], this._contractAddress, feeRate))
|
|
773
799
|
);
|
|
774
800
|
requiredApprovalTxns.forEach(tx => tx!=null && txs.push(tx));
|
|
775
801
|
|
|
@@ -813,7 +839,7 @@ export class EVMSpvVaultContract<ChainId extends string>
|
|
|
813
839
|
}
|
|
814
840
|
|
|
815
841
|
const requiredApprovalTxns = await Promise.all(
|
|
816
|
-
Object.keys(requiredApprovals).map(token => this.Chain.Tokens.checkAndGetApproveTx(signer, token, requiredApprovals[token], this.
|
|
842
|
+
Object.keys(requiredApprovals).map(token => this.Chain.Tokens.checkAndGetApproveTx(signer, token, requiredApprovals[token], this._contractAddress, feeRate))
|
|
817
843
|
);
|
|
818
844
|
requiredApprovalTxns.forEach(tx => tx!=null && txs.push(tx));
|
|
819
845
|
|
|
@@ -841,6 +867,13 @@ export class EVMSpvVaultContract<ChainId extends string>
|
|
|
841
867
|
return [tx];
|
|
842
868
|
}
|
|
843
869
|
|
|
870
|
+
/**
|
|
871
|
+
* Returns an estimated gas amount for a claim transaction.
|
|
872
|
+
*
|
|
873
|
+
* @param signer Signer address executing the claim
|
|
874
|
+
* @param vault Vault data used to determine transfer paths
|
|
875
|
+
* @param data Parsed withdrawal data
|
|
876
|
+
*/
|
|
844
877
|
getClaimGas(signer: string, vault?: EVMSpvVaultData, data?: EVMSpvWithdrawalData): number {
|
|
845
878
|
let totalGas = EVMSpvVaultContract.GasCosts.CLAIM_BASE;
|
|
846
879
|
|
|
@@ -863,6 +896,13 @@ export class EVMSpvVaultContract<ChainId extends string>
|
|
|
863
896
|
return totalGas;
|
|
864
897
|
}
|
|
865
898
|
|
|
899
|
+
/**
|
|
900
|
+
* Returns an estimated gas amount for a front-liquidity transaction.
|
|
901
|
+
*
|
|
902
|
+
* @param signer Signer address executing the front action
|
|
903
|
+
* @param vault Vault data used to determine transfer paths
|
|
904
|
+
* @param data Parsed withdrawal data
|
|
905
|
+
*/
|
|
866
906
|
getFrontGas(signer: string, vault: EVMSpvVaultData, data?: EVMSpvWithdrawalData): number {
|
|
867
907
|
let totalGas = EVMSpvVaultContract.GasCosts.FRONT_BASE;
|
|
868
908
|
|
|
@@ -891,7 +931,7 @@ export class EVMSpvVaultContract<ChainId extends string>
|
|
|
891
931
|
* @inheritDoc
|
|
892
932
|
*/
|
|
893
933
|
async getFrontFee(signer: string, vault?: EVMSpvVaultData, withdrawalData?: EVMSpvWithdrawalData, feeRate?: string): Promise<bigint> {
|
|
894
|
-
vault ??= EVMSpvVaultData.
|
|
934
|
+
vault ??= EVMSpvVaultData._randomVault();
|
|
895
935
|
feeRate ??= await this.Chain.Fees.getFeeRate();
|
|
896
936
|
let totalFee = EVMFees.getGasFee(this.getFrontGas(signer, vault, withdrawalData), feeRate);
|
|
897
937
|
if(withdrawalData==null || (withdrawalData.rawAmounts[0]!=null && withdrawalData.rawAmounts[0]>0n)) {
|
|
@@ -16,6 +16,11 @@ import {AbiCoder, keccak256} from "ethers";
|
|
|
16
16
|
import {EVMAddresses} from "../chain/modules/EVMAddresses";
|
|
17
17
|
import type {AddressLike, BigNumberish, BytesLike} from "ethers/lib.esm";
|
|
18
18
|
|
|
19
|
+
/**
|
|
20
|
+
* Computes the vault parameter commitment hash used by the on-chain SPV vault state.
|
|
21
|
+
*
|
|
22
|
+
* @category Swaps
|
|
23
|
+
*/
|
|
19
24
|
export function getVaultParamsCommitment(vaultParams: SpvVaultParametersStruct) {
|
|
20
25
|
return keccak256(AbiCoder.defaultAbiCoder().encode(
|
|
21
26
|
["address", "address", "address", "uint192", "uint192", "uint256"],
|
|
@@ -23,12 +28,19 @@ export function getVaultParamsCommitment(vaultParams: SpvVaultParametersStruct)
|
|
|
23
28
|
));
|
|
24
29
|
}
|
|
25
30
|
|
|
31
|
+
/**
|
|
32
|
+
* Decodes UTXO reference (`txid:vout`) from the on-chain SPV vault state struct.
|
|
33
|
+
*
|
|
34
|
+
* @category Swaps
|
|
35
|
+
*/
|
|
26
36
|
export function getVaultUtxoFromState(state: SpvVaultStateStruct): string {
|
|
27
37
|
const txHash = Buffer.from(hexlify(state.utxoTxHash).substring(2), "hex");
|
|
28
38
|
return txHash.reverse().toString("hex")+":"+BigInt(state.utxoVout).toString(10);
|
|
29
39
|
}
|
|
30
40
|
|
|
31
41
|
/**
|
|
42
|
+
* Represents the state of the EVM SPV vault (UTXO-controlled vault).
|
|
43
|
+
*
|
|
32
44
|
* @category Swaps
|
|
33
45
|
*/
|
|
34
46
|
export class EVMSpvVaultData extends SpvVaultData<EVMSpvWithdrawalData> {
|
|
@@ -102,6 +114,9 @@ export class EVMSpvVaultData extends SpvVaultData<EVMSpvWithdrawalData> {
|
|
|
102
114
|
}
|
|
103
115
|
}
|
|
104
116
|
|
|
117
|
+
/**
|
|
118
|
+
* @inheritDoc
|
|
119
|
+
*/
|
|
105
120
|
getBalances(): SpvVaultTokenBalance[] {
|
|
106
121
|
return [
|
|
107
122
|
{...this.token0, scaledAmount: this.token0.rawAmount * this.token0.multiplier},
|
|
@@ -109,34 +124,58 @@ export class EVMSpvVaultData extends SpvVaultData<EVMSpvWithdrawalData> {
|
|
|
109
124
|
];
|
|
110
125
|
}
|
|
111
126
|
|
|
127
|
+
/**
|
|
128
|
+
* @inheritDoc
|
|
129
|
+
*/
|
|
112
130
|
getConfirmations(): number {
|
|
113
131
|
return this.confirmations;
|
|
114
132
|
}
|
|
115
133
|
|
|
134
|
+
/**
|
|
135
|
+
* @inheritDoc
|
|
136
|
+
*/
|
|
116
137
|
getOwner(): string {
|
|
117
138
|
return this.owner;
|
|
118
139
|
}
|
|
119
140
|
|
|
141
|
+
/**
|
|
142
|
+
* @inheritDoc
|
|
143
|
+
*/
|
|
120
144
|
getTokenData(): SpvVaultTokenData[] {
|
|
121
145
|
return [this.token0, this.token1];
|
|
122
146
|
}
|
|
123
147
|
|
|
148
|
+
/**
|
|
149
|
+
* @inheritDoc
|
|
150
|
+
*/
|
|
124
151
|
getUtxo(): string {
|
|
125
152
|
return this.isOpened() ? this.utxo : this.initialUtxo!;
|
|
126
153
|
}
|
|
127
154
|
|
|
155
|
+
/**
|
|
156
|
+
* @inheritDoc
|
|
157
|
+
*/
|
|
128
158
|
getVaultId(): bigint {
|
|
129
159
|
return this.vaultId;
|
|
130
160
|
}
|
|
131
161
|
|
|
162
|
+
/**
|
|
163
|
+
* @inheritDoc
|
|
164
|
+
*/
|
|
132
165
|
getWithdrawalCount(): number {
|
|
133
166
|
return this.withdrawCount;
|
|
134
167
|
}
|
|
135
168
|
|
|
169
|
+
/**
|
|
170
|
+
* @inheritDoc
|
|
171
|
+
*/
|
|
136
172
|
isOpened(): boolean {
|
|
137
173
|
return this.utxo!=="0000000000000000000000000000000000000000000000000000000000000000:0";
|
|
138
174
|
}
|
|
139
175
|
|
|
176
|
+
/**
|
|
177
|
+
* @inheritDoc
|
|
178
|
+
*/
|
|
140
179
|
serialize(): any {
|
|
141
180
|
return {
|
|
142
181
|
type: "EVM",
|
|
@@ -161,6 +200,9 @@ export class EVMSpvVaultData extends SpvVaultData<EVMSpvWithdrawalData> {
|
|
|
161
200
|
}
|
|
162
201
|
}
|
|
163
202
|
|
|
203
|
+
/**
|
|
204
|
+
* @inheritDoc
|
|
205
|
+
*/
|
|
164
206
|
updateState(withdrawalTxOrEvent: SpvVaultClaimEvent | SpvVaultCloseEvent | SpvVaultOpenEvent | SpvVaultDepositEvent | EVMSpvWithdrawalData): void {
|
|
165
207
|
if(withdrawalTxOrEvent instanceof SpvVaultClaimEvent) {
|
|
166
208
|
if(withdrawalTxOrEvent.withdrawCount <= this.withdrawCount) return;
|
|
@@ -194,11 +236,19 @@ export class EVMSpvVaultData extends SpvVaultData<EVMSpvWithdrawalData> {
|
|
|
194
236
|
}
|
|
195
237
|
}
|
|
196
238
|
|
|
239
|
+
/**
|
|
240
|
+
* @inheritDoc
|
|
241
|
+
*/
|
|
197
242
|
getDepositCount(): number {
|
|
198
243
|
return this.depositCount;
|
|
199
244
|
}
|
|
200
245
|
|
|
201
|
-
|
|
246
|
+
/**
|
|
247
|
+
* Serializes this spv vault data to a struct object which can be passed to the ether.js functions
|
|
248
|
+
*
|
|
249
|
+
* @internal
|
|
250
|
+
*/
|
|
251
|
+
_getVaultParamsStruct(): SpvVaultParametersStruct {
|
|
202
252
|
return {
|
|
203
253
|
btcRelayContract: this.relayContract,
|
|
204
254
|
token0: this.token0.token,
|
|
@@ -209,7 +259,12 @@ export class EVMSpvVaultData extends SpvVaultData<EVMSpvWithdrawalData> {
|
|
|
209
259
|
}
|
|
210
260
|
}
|
|
211
261
|
|
|
212
|
-
|
|
262
|
+
/**
|
|
263
|
+
* Returns a dummy random vault that can be used for e.g. fee estimation
|
|
264
|
+
*
|
|
265
|
+
* @internal
|
|
266
|
+
*/
|
|
267
|
+
static _randomVault(): EVMSpvVaultData {
|
|
213
268
|
const spvVaultParams = {
|
|
214
269
|
btcRelayContract: EVMAddresses.randomAddress(),
|
|
215
270
|
token0: EVMAddresses.randomAddress(),
|
|
@@ -5,6 +5,9 @@ import {BitcoinVaultTransactionDataStruct} from "./SpvVaultContractTypechain";
|
|
|
5
5
|
import {AbiCoder, keccak256, ZeroHash} from "ethers";
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
|
+
* Represents parsed withdrawal data used for claiming assets from the EVM SPV vault
|
|
9
|
+
* (UTXO-controlled vault).
|
|
10
|
+
*
|
|
8
11
|
* @category Swaps
|
|
9
12
|
*/
|
|
10
13
|
export class EVMSpvWithdrawalData extends SpvWithdrawalTransactionData {
|
|
@@ -43,10 +46,16 @@ export class EVMSpvWithdrawalData extends SpvWithdrawalTransactionData {
|
|
|
43
46
|
)).substring(2);
|
|
44
47
|
}
|
|
45
48
|
|
|
49
|
+
/**
|
|
50
|
+
* @inheritDoc
|
|
51
|
+
*/
|
|
46
52
|
getTxHash(): string {
|
|
47
53
|
return "0x"+Buffer.from(this.btcTx.txid, "hex").reverse().toString("hex");
|
|
48
54
|
}
|
|
49
55
|
|
|
56
|
+
/**
|
|
57
|
+
* @inheritDoc
|
|
58
|
+
*/
|
|
50
59
|
getFrontingAmount(): bigint[] {
|
|
51
60
|
return [this.rawAmounts[0] + this.getExecutionFee()[0], this.rawAmounts[1]];
|
|
52
61
|
}
|
|
@@ -61,6 +70,9 @@ export class EVMSpvWithdrawalData extends SpvWithdrawalTransactionData {
|
|
|
61
70
|
};
|
|
62
71
|
}
|
|
63
72
|
|
|
73
|
+
/**
|
|
74
|
+
* Serializes the withdrawal data to the EVM contract struct representation.
|
|
75
|
+
*/
|
|
64
76
|
serializeToStruct(): BitcoinVaultTransactionDataStruct {
|
|
65
77
|
const callerFee = this.getCallerFee();
|
|
66
78
|
const frontingFee = this.getFrontingFee();
|