@xyo-network/chain-bridge 1.19.16 → 1.19.18
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/node/index.mjs +256 -145
- package/dist/node/index.mjs.map +1 -1
- package/dist/node/queue/flowProducer.d.ts +2 -1
- package/dist/node/queue/flowProducer.d.ts.map +1 -1
- package/dist/node/queue/flows/createXl1ToEthBridgeJob.d.ts.map +1 -1
- package/dist/node/queue/index.d.ts +1 -0
- package/dist/node/queue/index.d.ts.map +1 -1
- package/dist/node/queue/telemetry.d.ts +3 -0
- package/dist/node/queue/telemetry.d.ts.map +1 -0
- package/dist/node/queue/workers/EthTransactionMonitor.d.ts +9 -0
- package/dist/node/queue/workers/EthTransactionMonitor.d.ts.map +1 -1
- package/dist/node/queue/workers/EthTransactionPreparation.d.ts +7 -1
- package/dist/node/queue/workers/EthTransactionPreparation.d.ts.map +1 -1
- package/dist/node/queue/workers/EthTransactionSubmission.d.ts +8 -0
- package/dist/node/queue/workers/EthTransactionSubmission.d.ts.map +1 -1
- package/dist/node/queue/workers/WorkerDescription.d.ts +2 -1
- package/dist/node/queue/workers/WorkerDescription.d.ts.map +1 -1
- package/dist/node/queue/workers/Xl1ToEthBridgeParent.d.ts +3 -0
- package/dist/node/queue/workers/Xl1ToEthBridgeParent.d.ts.map +1 -1
- package/dist/node/queue/workers/Xl1TransactionMonitor.d.ts +6 -0
- package/dist/node/queue/workers/Xl1TransactionMonitor.d.ts.map +1 -1
- package/dist/node/queue/workers/Xl1TransactionPreparation.d.ts +7 -0
- package/dist/node/queue/workers/Xl1TransactionPreparation.d.ts.map +1 -1
- package/dist/node/queue/workers/Xl1TransactionSubmission.d.ts +8 -0
- package/dist/node/queue/workers/Xl1TransactionSubmission.d.ts.map +1 -1
- package/dist/node/queue/workers/createWorkers.d.ts +2 -1
- package/dist/node/queue/workers/createWorkers.d.ts.map +1 -1
- package/dist/node/queue/workers/util/AsyncLogger.d.ts +5 -0
- package/dist/node/queue/workers/util/AsyncLogger.d.ts.map +1 -0
- package/dist/node/queue/workers/util/index.d.ts +3 -2
- package/dist/node/queue/workers/util/index.d.ts.map +1 -1
- package/dist/node/queue/workers/util/{validateSufficientAllowance.d.ts → validateSufficientLiquiditySourceAllowance.d.ts} +3 -7
- package/dist/node/queue/workers/util/validateSufficientLiquiditySourceAllowance.d.ts.map +1 -0
- package/dist/node/queue/workers/util/{validateSufficientBalance.d.ts → validateSufficientLiquiditySourceBalance.d.ts} +3 -7
- package/dist/node/queue/workers/util/validateSufficientLiquiditySourceBalance.d.ts.map +1 -0
- package/dist/node/queue/workers/util/validateSufficientRunnerEthBalanceForGas.d.ts +14 -0
- package/dist/node/queue/workers/util/validateSufficientRunnerEthBalanceForGas.d.ts.map +1 -0
- package/dist/node/server/addFlowProducer.d.ts.map +1 -1
- package/dist/node/server/addWorkers.d.ts.map +1 -1
- package/dist/node/server/routes/bridge/routeDefinitions/routes/bridgeToRemoteStatus.d.ts.map +1 -1
- package/dist/node/util/BridgeFees.d.ts +7 -1
- package/dist/node/util/BridgeFees.d.ts.map +1 -1
- package/package.json +30 -35
- package/src/config/getBridgeWalletAccount.ts +1 -1
- package/src/config/getGateway.ts +1 -1
- package/src/queue/flowProducer.ts +3 -2
- package/src/queue/flows/createXl1ToEthBridgeJob.ts +12 -2
- package/src/queue/index.ts +1 -0
- package/src/queue/telemetry.ts +12 -0
- package/src/queue/workers/EthTransactionMonitor.ts +10 -6
- package/src/queue/workers/EthTransactionPreparation.ts +17 -9
- package/src/queue/workers/EthTransactionSubmission.ts +8 -28
- package/src/queue/workers/WorkerDescription.ts +2 -1
- package/src/queue/workers/Xl1ToEthBridgeParent.ts +8 -5
- package/src/queue/workers/Xl1TransactionMonitor.ts +7 -5
- package/src/queue/workers/Xl1TransactionPreparation.ts +7 -7
- package/src/queue/workers/Xl1TransactionSubmission.ts +6 -5
- package/src/queue/workers/createWorkers.ts +9 -8
- package/src/queue/workers/util/AsyncLogger.ts +5 -0
- package/src/queue/workers/util/index.ts +3 -2
- package/src/queue/workers/util/{validateSufficientAllowance.ts → validateSufficientLiquiditySourceAllowance.ts} +3 -6
- package/src/queue/workers/util/{validateSufficientBalance.ts → validateSufficientLiquiditySourceBalance.ts} +3 -6
- package/src/queue/workers/util/validateSufficientRunnerEthBalanceForGas.ts +57 -0
- package/src/server/addFlowProducer.ts +5 -2
- package/src/server/addWorkers.ts +6 -2
- package/src/server/routes/bridge/routeDefinitions/routes/bridgeToRemoteStatus.ts +130 -65
- package/src/services/getServices.ts +1 -1
- package/src/util/BridgeFees.ts +10 -1
- package/dist/node/queue/workers/util/validateSufficientAllowance.d.ts.map +0 -1
- package/dist/node/queue/workers/util/validateSufficientBalance.d.ts.map +0 -1
package/dist/node/index.mjs
CHANGED
|
@@ -32,23 +32,27 @@ var getConnection = /* @__PURE__ */ __name((config) => {
|
|
|
32
32
|
import { isDefined as isDefined2 } from "@xylabs/sdk-js";
|
|
33
33
|
import { FlowProducer } from "bullmq";
|
|
34
34
|
var flowProducer;
|
|
35
|
-
var getFlowProducer = /* @__PURE__ */ __name((connection2) => {
|
|
35
|
+
var getFlowProducer = /* @__PURE__ */ __name((connection2, telemetry2) => {
|
|
36
36
|
if (isDefined2(flowProducer)) return flowProducer;
|
|
37
37
|
flowProducer = new FlowProducer({
|
|
38
|
-
connection: connection2
|
|
38
|
+
connection: connection2,
|
|
39
|
+
telemetry: telemetry2
|
|
39
40
|
});
|
|
40
41
|
return flowProducer;
|
|
41
42
|
}, "getFlowProducer");
|
|
42
43
|
|
|
44
|
+
// src/queue/flows/createXl1ToEthBridgeJob.ts
|
|
45
|
+
import { PayloadBuilder as PayloadBuilder8 } from "@xyo-network/sdk-js";
|
|
46
|
+
|
|
43
47
|
// src/queue/workers/createWorkers.ts
|
|
44
|
-
var createWorkers = /* @__PURE__ */ __name((connection2, services) => {
|
|
45
|
-
Xl1ToEthBridgeParent.createWorker(connection2);
|
|
46
|
-
Xl1TransactionPreparation.createWorker(connection2, services);
|
|
47
|
-
Xl1TransactionSubmission.createWorker(connection2, services);
|
|
48
|
-
Xl1TransactionMonitor.createWorker(connection2, services);
|
|
49
|
-
EthTransactionPreparation.createWorker(connection2, services);
|
|
50
|
-
EthTransactionSubmission.createWorker(connection2, services);
|
|
51
|
-
EthTransactionMonitor.createWorker(connection2, services);
|
|
48
|
+
var createWorkers = /* @__PURE__ */ __name((connection2, telemetry2, services) => {
|
|
49
|
+
Xl1ToEthBridgeParent.createWorker(connection2, telemetry2);
|
|
50
|
+
Xl1TransactionPreparation.createWorker(connection2, telemetry2, services);
|
|
51
|
+
Xl1TransactionSubmission.createWorker(connection2, telemetry2, services);
|
|
52
|
+
Xl1TransactionMonitor.createWorker(connection2, telemetry2, services);
|
|
53
|
+
EthTransactionPreparation.createWorker(connection2, telemetry2, services);
|
|
54
|
+
EthTransactionSubmission.createWorker(connection2, telemetry2, services);
|
|
55
|
+
EthTransactionMonitor.createWorker(connection2, telemetry2, services);
|
|
52
56
|
}, "createWorkers");
|
|
53
57
|
|
|
54
58
|
// src/queue/workers/EthTransactionMonitor.ts
|
|
@@ -57,7 +61,7 @@ import { PayloadBuilder } from "@xyo-network/sdk-js";
|
|
|
57
61
|
import { Worker } from "bullmq";
|
|
58
62
|
var name = "Monitor Submitted ETH Transaction";
|
|
59
63
|
var queueName = "eth-tx-monitor";
|
|
60
|
-
var createWorker = /* @__PURE__ */ __name((connection2, services) => {
|
|
64
|
+
var createWorker = /* @__PURE__ */ __name((connection2, telemetry2, services) => {
|
|
61
65
|
const provider = assertEx(services?.provider, () => "provider service not provided");
|
|
62
66
|
const stateMap = assertEx(services?.ethTxStateMap, () => "ethTxStateMap service not provided");
|
|
63
67
|
const worker = new Worker(queueName, async (job) => {
|
|
@@ -72,10 +76,12 @@ var createWorker = /* @__PURE__ */ __name((connection2, services) => {
|
|
|
72
76
|
await stateMap.set(hash, state);
|
|
73
77
|
return {
|
|
74
78
|
blockHash,
|
|
75
|
-
blockNumber
|
|
79
|
+
blockNumber,
|
|
80
|
+
submissionHash
|
|
76
81
|
};
|
|
77
82
|
}, {
|
|
78
|
-
connection: connection2
|
|
83
|
+
connection: connection2,
|
|
84
|
+
telemetry: telemetry2
|
|
79
85
|
});
|
|
80
86
|
worker.on("failed", (job, err) => {
|
|
81
87
|
console.error(`[${name}] Job ${job?.id} failed:`, err.message);
|
|
@@ -91,7 +97,7 @@ var EthTransactionMonitor = {
|
|
|
91
97
|
};
|
|
92
98
|
|
|
93
99
|
// src/queue/workers/EthTransactionPreparation.ts
|
|
94
|
-
import { assertEx as
|
|
100
|
+
import { assertEx as assertEx6, hexToBigInt as hexToBigInt4 } from "@xylabs/sdk-js";
|
|
95
101
|
import { PayloadBuilder as PayloadBuilder3 } from "@xyo-network/sdk-js";
|
|
96
102
|
import { isBridgeIntent as isBridgeIntent4 } from "@xyo-network/xl1-sdk";
|
|
97
103
|
import { Worker as Worker2 } from "bullmq";
|
|
@@ -121,10 +127,10 @@ var submitXl1Transaction = /* @__PURE__ */ __name(async (preparedTx, gateway) =>
|
|
|
121
127
|
return result;
|
|
122
128
|
}, "submitXl1Transaction");
|
|
123
129
|
|
|
124
|
-
// src/queue/workers/util/
|
|
130
|
+
// src/queue/workers/util/validateSufficientLiquiditySourceAllowance.ts
|
|
125
131
|
import { assertEx as assertEx3, hexToBigInt as hexToBigInt2 } from "@xylabs/sdk-js";
|
|
126
132
|
import { isBridgeIntent as isBridgeIntent2 } from "@xyo-network/xl1-sdk";
|
|
127
|
-
var
|
|
133
|
+
var validateSufficientLiquiditySourceAllowance = /* @__PURE__ */ __name(async (tx, bridgeableToken, bridge, logger) => {
|
|
128
134
|
const bridgeIntent = assertEx3(tx[1].find(isBridgeIntent2), () => "No bridge intent found");
|
|
129
135
|
const amount = hexToBigInt2(bridgeIntent.destAmount);
|
|
130
136
|
const liquiditySourceAddress = await bridge.liquiditySource();
|
|
@@ -132,49 +138,79 @@ var validateSufficientAllowance = /* @__PURE__ */ __name(async (tx, bridgeableTo
|
|
|
132
138
|
const remainingAllowance = await bridgeableToken.allowance(liquiditySourceAddress, bridgeAddress);
|
|
133
139
|
await logger?.log(`Remaining allowance: ${remainingAllowance.toString()}`);
|
|
134
140
|
return remainingAllowance >= amount;
|
|
135
|
-
}, "
|
|
141
|
+
}, "validateSufficientLiquiditySourceAllowance");
|
|
136
142
|
|
|
137
|
-
// src/queue/workers/util/
|
|
143
|
+
// src/queue/workers/util/validateSufficientLiquiditySourceBalance.ts
|
|
138
144
|
import { assertEx as assertEx4, hexToBigInt as hexToBigInt3 } from "@xylabs/sdk-js";
|
|
139
145
|
import { isBridgeIntent as isBridgeIntent3 } from "@xyo-network/xl1-sdk";
|
|
140
|
-
var
|
|
146
|
+
var validateSufficientLiquiditySourceBalance = /* @__PURE__ */ __name(async (tx, bridgeableToken, bridge, logger) => {
|
|
141
147
|
const bridgeIntent = assertEx4(tx[1].find(isBridgeIntent3), () => "No bridge intent found");
|
|
142
148
|
const amount = hexToBigInt3(bridgeIntent.destAmount);
|
|
143
149
|
const liquiditySourceAddress = await bridge.liquiditySource();
|
|
144
150
|
const balance = await bridgeableToken.balanceOf(liquiditySourceAddress);
|
|
145
151
|
await logger?.log(`Remaining balance: ${balance.toString()}`);
|
|
146
152
|
return balance >= amount;
|
|
147
|
-
}, "
|
|
153
|
+
}, "validateSufficientLiquiditySourceBalance");
|
|
154
|
+
|
|
155
|
+
// src/queue/workers/util/validateSufficientRunnerEthBalanceForGas.ts
|
|
156
|
+
import { assertEx as assertEx5 } from "@xylabs/sdk-js";
|
|
157
|
+
var DEFAULT_GAS_BUFFER_BPS = 2000n;
|
|
158
|
+
var validateSufficientRunnerEthBalanceForGas = /* @__PURE__ */ __name(async (preparedTx, wallet, logger, bufferBps = DEFAULT_GAS_BUFFER_BPS) => {
|
|
159
|
+
const provider = assertEx5(wallet.provider, () => "Wallet provider is not defined");
|
|
160
|
+
const feeData = await provider.getFeeData();
|
|
161
|
+
const perGas = feeData.maxFeePerGas ?? feeData.gasPrice;
|
|
162
|
+
if (perGas == null) {
|
|
163
|
+
await logger?.log("[gas] unable to resolve gas price / maxFeePerGas from provider");
|
|
164
|
+
return true;
|
|
165
|
+
}
|
|
166
|
+
const transactionRequest = {
|
|
167
|
+
...preparedTx,
|
|
168
|
+
from: await wallet.getAddress()
|
|
169
|
+
};
|
|
170
|
+
const estGas = await provider.estimateGas(transactionRequest);
|
|
171
|
+
const txValue = preparedTx?.value ?? 0n;
|
|
172
|
+
const baseRequired = estGas * perGas + txValue;
|
|
173
|
+
const required = baseRequired * (10000n + bufferBps) / 10000n;
|
|
174
|
+
const balance = await provider.getBalance(await wallet.getAddress());
|
|
175
|
+
await logger?.log(`[gas] runner=${await wallet.getAddress()} balance=${balance.toString()} estGas=${estGas.toString()} perGas=${perGas.toString()} value=${txValue.toString()} requiredWithBuffer=${required.toString()} bufferBps=${bufferBps.toString()}`);
|
|
176
|
+
return balance >= required;
|
|
177
|
+
}, "validateSufficientRunnerEthBalanceForGas");
|
|
148
178
|
|
|
149
179
|
// src/queue/workers/EthTransactionPreparation.ts
|
|
150
180
|
var name2 = "Prepare ETH Transaction";
|
|
151
181
|
var queueName2 = "eth-tx-prepare";
|
|
152
|
-
var createWorker2 = /* @__PURE__ */ __name((connection2, services) => {
|
|
153
|
-
const bridge =
|
|
154
|
-
const bridgeableToken =
|
|
155
|
-
const stateMap =
|
|
182
|
+
var createWorker2 = /* @__PURE__ */ __name((connection2, telemetry2, services) => {
|
|
183
|
+
const bridge = assertEx6(services?.bridge, () => "bridge service not provided");
|
|
184
|
+
const bridgeableToken = assertEx6(services?.bridgeableToken, () => "bridgeableToken service not provided");
|
|
185
|
+
const stateMap = assertEx6(services?.ethTxStateMap, () => "ethTxStateMap service not provided");
|
|
186
|
+
const wallet = assertEx6(services?.wallet, () => "wallet service not provided");
|
|
156
187
|
const worker = new Worker2(queueName2, async (job) => {
|
|
157
188
|
const { tx } = job.data;
|
|
158
189
|
const hash = await PayloadBuilder3.hash(tx[0]);
|
|
159
190
|
await job.log(`[${hash}] preparing ETH transaction`);
|
|
160
191
|
await job.log(`[${hash}] validating liquiditySource has sufficient allowance`);
|
|
161
|
-
if (!await
|
|
192
|
+
if (!await validateSufficientLiquiditySourceAllowance(tx, bridgeableToken, bridge, job)) {
|
|
162
193
|
throw new Error("Liquidity source does not have sufficient allowance for the bridge to execute the transaction");
|
|
163
194
|
}
|
|
164
195
|
await job.log(`[${hash}] validated liquiditySource has sufficient allowance`);
|
|
165
196
|
await job.log(`[${hash}] validating liquiditySource has sufficient balance`);
|
|
166
|
-
if (!await
|
|
197
|
+
if (!await validateSufficientLiquiditySourceBalance(tx, bridgeableToken, bridge, job)) {
|
|
167
198
|
throw new Error("Liquidity source does not have sufficient balance for the bridge to execute the transaction");
|
|
168
199
|
}
|
|
169
200
|
await job.log(`[${hash}] validated liquiditySource has sufficient balance`);
|
|
170
201
|
await job.log(`[${hash}] building ETH transaction`);
|
|
171
|
-
const bridgeIntent =
|
|
202
|
+
const bridgeIntent = assertEx6(tx[1].find(isBridgeIntent4), () => "No bridge intent found");
|
|
172
203
|
const amount = hexToBigInt4(bridgeIntent.destAmount);
|
|
173
204
|
const srcAddress = getAddress(bridgeIntent.srcAddress);
|
|
174
205
|
const destAddress = getAddress(bridgeIntent.destAddress);
|
|
175
206
|
const nonce = hexToBigInt4(await PayloadBuilder3.hash(tx[0]));
|
|
176
207
|
const preparedTx = await bridge.getFunction("bridgeFromRemote").populateTransaction(srcAddress, destAddress, amount, nonce);
|
|
177
208
|
await job.log(`[${hash}] built ETH transaction`);
|
|
209
|
+
await job.log(`[${hash}] validating tx runner has sufficient ETH for gas`);
|
|
210
|
+
if (!await validateSufficientRunnerEthBalanceForGas(preparedTx, wallet, job)) {
|
|
211
|
+
throw new Error("Transaction runner does not have sufficient ETH to cover estimated gas (with buffer)");
|
|
212
|
+
}
|
|
213
|
+
await job.log(`[${hash}] validated tx runner has sufficient ETH for gas`);
|
|
178
214
|
await job.log(`[${hash}] storing ETH preparedTx`);
|
|
179
215
|
await stateMap.set(hash, {
|
|
180
216
|
preparedTx
|
|
@@ -183,7 +219,8 @@ var createWorker2 = /* @__PURE__ */ __name((connection2, services) => {
|
|
|
183
219
|
await job.log(`[${hash}] prepared ETH transaction`);
|
|
184
220
|
return {};
|
|
185
221
|
}, {
|
|
186
|
-
connection: connection2
|
|
222
|
+
connection: connection2,
|
|
223
|
+
telemetry: telemetry2
|
|
187
224
|
});
|
|
188
225
|
worker.on("failed", (job, err) => {
|
|
189
226
|
console.error(`[${name2}] Job ${job?.id} failed:`, err.message);
|
|
@@ -199,21 +236,20 @@ var EthTransactionPreparation = {
|
|
|
199
236
|
};
|
|
200
237
|
|
|
201
238
|
// src/queue/workers/EthTransactionSubmission.ts
|
|
202
|
-
import { assertEx as
|
|
239
|
+
import { assertEx as assertEx7, isDefined as isDefined3 } from "@xylabs/sdk-js";
|
|
203
240
|
import { PayloadBuilder as PayloadBuilder4 } from "@xyo-network/sdk-js";
|
|
204
241
|
import { Worker as Worker3 } from "bullmq";
|
|
205
242
|
var name3 = "Submit ETH Transaction";
|
|
206
243
|
var queueName3 = "eth-tx-submit";
|
|
207
|
-
var createWorker3 = /* @__PURE__ */ __name((connection2, services) => {
|
|
208
|
-
const bridge =
|
|
209
|
-
const bridgeableToken =
|
|
210
|
-
const wallet =
|
|
211
|
-
const stateMap =
|
|
244
|
+
var createWorker3 = /* @__PURE__ */ __name((connection2, telemetry2, services) => {
|
|
245
|
+
const bridge = assertEx7(services?.bridge, () => "bridge service not provided");
|
|
246
|
+
const bridgeableToken = assertEx7(services?.bridgeableToken, () => "bridgeableToken service not provided");
|
|
247
|
+
const wallet = assertEx7(services?.wallet, () => "wallet service not provided");
|
|
248
|
+
const stateMap = assertEx7(services?.ethTxStateMap, () => "ethTxStateMap service not provided");
|
|
212
249
|
const worker = new Worker3(queueName3, async (job) => {
|
|
213
250
|
const { tx } = job.data;
|
|
214
251
|
const hash = await PayloadBuilder4.hash(tx[0]);
|
|
215
|
-
const state =
|
|
216
|
-
const preparedTx = assertEx6(state?.preparedTx, () => `[${hash}] preparedTx not found`);
|
|
252
|
+
const state = assertEx7(await stateMap.get(hash), () => `[${hash}] state not found`);
|
|
217
253
|
const { submissionHash: existingSubmissionHash } = state;
|
|
218
254
|
if (isDefined3(existingSubmissionHash)) {
|
|
219
255
|
await job.log(`[${hash}] Tx already submitted with submission response hash ${existingSubmissionHash}`);
|
|
@@ -222,7 +258,7 @@ var createWorker3 = /* @__PURE__ */ __name((connection2, services) => {
|
|
|
222
258
|
};
|
|
223
259
|
}
|
|
224
260
|
await job.log(`[${hash}] Submitting ETH tx`);
|
|
225
|
-
const submissionHash =
|
|
261
|
+
const submissionHash = assertEx7(await submitEthTransaction(tx, bridgeableToken, bridge, wallet), () => `[${hash}] submissionHash not found in receipt`);
|
|
226
262
|
await job.log(`[${hash}] Submitted ETH tx and received submission response hash ${submissionHash}`);
|
|
227
263
|
await job.log(`[${hash}] Storing ETH submissionHash`);
|
|
228
264
|
state.submissionHash = submissionHash;
|
|
@@ -233,6 +269,7 @@ var createWorker3 = /* @__PURE__ */ __name((connection2, services) => {
|
|
|
233
269
|
};
|
|
234
270
|
}, {
|
|
235
271
|
connection: connection2,
|
|
272
|
+
telemetry: telemetry2,
|
|
236
273
|
concurrency: 1
|
|
237
274
|
});
|
|
238
275
|
worker.on("failed", (job, err) => {
|
|
@@ -252,15 +289,14 @@ var EthTransactionSubmission = {
|
|
|
252
289
|
import { Worker as Worker4 } from "bullmq";
|
|
253
290
|
var name4 = "Bridge XL1 to Ethereum";
|
|
254
291
|
var queueName4 = "xl1-to-eth-bridge";
|
|
255
|
-
var createWorker4 = /* @__PURE__ */ __name((connection2) => {
|
|
292
|
+
var createWorker4 = /* @__PURE__ */ __name((connection2, telemetry2) => {
|
|
256
293
|
const worker = new Worker4(queueName4, async (job) => {
|
|
257
294
|
await job.log(`[${job.name}] start`);
|
|
258
295
|
await job.log(`[${job.name}] done`);
|
|
259
|
-
return {
|
|
260
|
-
ok: true
|
|
261
|
-
};
|
|
296
|
+
return {};
|
|
262
297
|
}, {
|
|
263
|
-
connection: connection2
|
|
298
|
+
connection: connection2,
|
|
299
|
+
telemetry: telemetry2
|
|
264
300
|
});
|
|
265
301
|
worker.on("failed", (job, err) => {
|
|
266
302
|
console.error(`[${name4}] Job ${job?.id} failed:`, err.message);
|
|
@@ -276,20 +312,20 @@ var Xl1ToEthBridgeParent = {
|
|
|
276
312
|
};
|
|
277
313
|
|
|
278
314
|
// src/queue/workers/Xl1TransactionMonitor.ts
|
|
279
|
-
import { assertEx as
|
|
315
|
+
import { assertEx as assertEx8, isDefined as isDefined4, isNull } from "@xylabs/sdk-js";
|
|
280
316
|
import { PayloadBuilder as PayloadBuilder5 } from "@xyo-network/sdk-js";
|
|
281
317
|
import { UnrecoverableError, Worker as Worker5 } from "bullmq";
|
|
282
318
|
var name5 = "Monitor Submitted XL1 Transaction";
|
|
283
319
|
var queueName5 = "xl1-tx-monitor";
|
|
284
|
-
var createWorker5 = /* @__PURE__ */ __name((connection2, services) => {
|
|
285
|
-
const gateway =
|
|
286
|
-
const stateMap =
|
|
320
|
+
var createWorker5 = /* @__PURE__ */ __name((connection2, telemetry2, services) => {
|
|
321
|
+
const gateway = assertEx8(services?.gateway, () => "gateway service not provided");
|
|
322
|
+
const stateMap = assertEx8(services?.xl1TxStateMap, () => "xl1TxStateMap service not provided");
|
|
287
323
|
const worker = new Worker5(queueName5, async (job) => {
|
|
288
324
|
const { tx } = job.data;
|
|
289
325
|
const hash = await PayloadBuilder5.hash(tx[0]);
|
|
290
|
-
const viewer =
|
|
291
|
-
const state =
|
|
292
|
-
const submissionHash =
|
|
326
|
+
const viewer = assertEx8(gateway.connection.viewer, () => `[${hash}] viewer not defined on gateway`);
|
|
327
|
+
const state = assertEx8(await stateMap.get(hash), () => `[${hash}] state not found`);
|
|
328
|
+
const submissionHash = assertEx8(state?.submissionHash, () => `[${hash}] submissionHash not found`);
|
|
293
329
|
await job.log(`[${hash}] Checking for XL1 transaction inclusion on chain`);
|
|
294
330
|
const foundTx = await viewer.transactionByHash(submissionHash);
|
|
295
331
|
if (isDefined4(foundTx) && !isNull(foundTx)) {
|
|
@@ -306,7 +342,8 @@ var createWorker5 = /* @__PURE__ */ __name((connection2, services) => {
|
|
|
306
342
|
await job.log(`[${hash}] Transaction not yet included, retrying later`);
|
|
307
343
|
throw new Error(`[${hash}] Transaction not yet included`);
|
|
308
344
|
}, {
|
|
309
|
-
connection: connection2
|
|
345
|
+
connection: connection2,
|
|
346
|
+
telemetry: telemetry2
|
|
310
347
|
});
|
|
311
348
|
worker.on("failed", (job, err) => {
|
|
312
349
|
console.error(`[${name5}] Job ${job?.id} failed:`, err.message);
|
|
@@ -322,13 +359,13 @@ var Xl1TransactionMonitor = {
|
|
|
322
359
|
};
|
|
323
360
|
|
|
324
361
|
// src/queue/workers/Xl1TransactionPreparation.ts
|
|
325
|
-
import { assertEx as
|
|
362
|
+
import { assertEx as assertEx9 } from "@xylabs/sdk-js";
|
|
326
363
|
import { PayloadBuilder as PayloadBuilder6 } from "@xyo-network/sdk-js";
|
|
327
364
|
import { Worker as Worker6 } from "bullmq";
|
|
328
365
|
var name6 = "Prepare XL1 Transaction";
|
|
329
366
|
var queueName6 = "xl1-tx-prepare";
|
|
330
|
-
var createWorker6 = /* @__PURE__ */ __name((connection2, services) => {
|
|
331
|
-
const stateMap =
|
|
367
|
+
var createWorker6 = /* @__PURE__ */ __name((connection2, telemetry2, services) => {
|
|
368
|
+
const stateMap = assertEx9(services?.xl1TxStateMap, () => "xl1TxStateMap service not provided");
|
|
332
369
|
const worker = new Worker6(queueName6, async (job) => {
|
|
333
370
|
const { tx } = job.data;
|
|
334
371
|
const hash = await PayloadBuilder6.hash(tx[0]);
|
|
@@ -340,9 +377,12 @@ var createWorker6 = /* @__PURE__ */ __name((connection2, services) => {
|
|
|
340
377
|
});
|
|
341
378
|
await job.log(`[${hash}] stored XL1 preparedTx`);
|
|
342
379
|
await job.log(`[${hash}] prepared XL1 transaction`);
|
|
343
|
-
return {
|
|
380
|
+
return {
|
|
381
|
+
preparedTx
|
|
382
|
+
};
|
|
344
383
|
}, {
|
|
345
|
-
connection: connection2
|
|
384
|
+
connection: connection2,
|
|
385
|
+
telemetry: telemetry2
|
|
346
386
|
});
|
|
347
387
|
worker.on("failed", (job, err) => {
|
|
348
388
|
console.error(`[${name6}] Job ${job?.id} failed:`, err.message);
|
|
@@ -358,19 +398,19 @@ var Xl1TransactionPreparation = {
|
|
|
358
398
|
};
|
|
359
399
|
|
|
360
400
|
// src/queue/workers/Xl1TransactionSubmission.ts
|
|
361
|
-
import { assertEx as
|
|
401
|
+
import { assertEx as assertEx10, isDefined as isDefined5 } from "@xylabs/sdk-js";
|
|
362
402
|
import { PayloadBuilder as PayloadBuilder7 } from "@xyo-network/sdk-js";
|
|
363
403
|
import { Worker as Worker7 } from "bullmq";
|
|
364
404
|
var name7 = "Submit XL1 Transaction";
|
|
365
405
|
var queueName7 = "xl1-tx-submit";
|
|
366
|
-
var createWorker7 = /* @__PURE__ */ __name((connection2, services) => {
|
|
367
|
-
const gateway =
|
|
368
|
-
const stateMap =
|
|
406
|
+
var createWorker7 = /* @__PURE__ */ __name((connection2, telemetry2, services) => {
|
|
407
|
+
const gateway = assertEx10(services?.gateway, () => "gateway service not provided");
|
|
408
|
+
const stateMap = assertEx10(services?.xl1TxStateMap, () => "xl1TxStateMap service not provided");
|
|
369
409
|
const worker = new Worker7(queueName7, async (job) => {
|
|
370
410
|
const { tx } = job.data;
|
|
371
411
|
const hash = await PayloadBuilder7.hash(tx[0]);
|
|
372
|
-
const state =
|
|
373
|
-
const preparedTx =
|
|
412
|
+
const state = assertEx10(await stateMap.get(hash), () => `[${hash}] state not found`);
|
|
413
|
+
const preparedTx = assertEx10(state?.preparedTx, () => `[${hash}] preparedTx not found`);
|
|
374
414
|
const { submissionHash: existingSubmissionHash } = state;
|
|
375
415
|
if (isDefined5(existingSubmissionHash)) {
|
|
376
416
|
await job.log(`[${hash}] Tx already submitted with submission response hash ${existingSubmissionHash}`);
|
|
@@ -389,7 +429,8 @@ var createWorker7 = /* @__PURE__ */ __name((connection2, services) => {
|
|
|
389
429
|
submissionHash
|
|
390
430
|
};
|
|
391
431
|
}, {
|
|
392
|
-
connection: connection2
|
|
432
|
+
connection: connection2,
|
|
433
|
+
telemetry: telemetry2
|
|
393
434
|
});
|
|
394
435
|
worker.on("failed", (job, err) => {
|
|
395
436
|
console.error(`[${name7}] Job ${job?.id} failed:`, err.message);
|
|
@@ -406,12 +447,16 @@ var Xl1TransactionSubmission = {
|
|
|
406
447
|
|
|
407
448
|
// src/queue/flows/createXl1ToEthBridgeJob.ts
|
|
408
449
|
var createXl1ToEthBridgeJob = /* @__PURE__ */ __name(async (flowProducer2, tx) => {
|
|
450
|
+
const jobId = await PayloadBuilder8.hash(tx[0]);
|
|
409
451
|
const flow = await flowProducer2.add({
|
|
410
452
|
name: Xl1ToEthBridgeParent.name,
|
|
411
453
|
queueName: Xl1ToEthBridgeParent.queueName,
|
|
412
454
|
data: {
|
|
413
455
|
tx
|
|
414
456
|
},
|
|
457
|
+
opts: {
|
|
458
|
+
jobId
|
|
459
|
+
},
|
|
415
460
|
children: [
|
|
416
461
|
{
|
|
417
462
|
// Step 6 (runs after child completes)
|
|
@@ -421,6 +466,7 @@ var createXl1ToEthBridgeJob = /* @__PURE__ */ __name(async (flowProducer2, tx) =
|
|
|
421
466
|
tx
|
|
422
467
|
},
|
|
423
468
|
opts: {
|
|
469
|
+
jobId,
|
|
424
470
|
attempts: 60,
|
|
425
471
|
backoff: {
|
|
426
472
|
type: "fixed",
|
|
@@ -443,6 +489,9 @@ var createXl1ToEthBridgeJob = /* @__PURE__ */ __name(async (flowProducer2, tx) =
|
|
|
443
489
|
data: {
|
|
444
490
|
tx
|
|
445
491
|
},
|
|
492
|
+
opts: {
|
|
493
|
+
jobId
|
|
494
|
+
},
|
|
446
495
|
children: [
|
|
447
496
|
{
|
|
448
497
|
// Step 3
|
|
@@ -452,6 +501,7 @@ var createXl1ToEthBridgeJob = /* @__PURE__ */ __name(async (flowProducer2, tx) =
|
|
|
452
501
|
tx
|
|
453
502
|
},
|
|
454
503
|
opts: {
|
|
504
|
+
jobId,
|
|
455
505
|
attempts: 60,
|
|
456
506
|
backoff: {
|
|
457
507
|
type: "fixed",
|
|
@@ -466,6 +516,9 @@ var createXl1ToEthBridgeJob = /* @__PURE__ */ __name(async (flowProducer2, tx) =
|
|
|
466
516
|
data: {
|
|
467
517
|
tx
|
|
468
518
|
},
|
|
519
|
+
opts: {
|
|
520
|
+
jobId
|
|
521
|
+
},
|
|
469
522
|
children: [
|
|
470
523
|
{
|
|
471
524
|
// Step 1 (runs first as deepest child)
|
|
@@ -473,6 +526,9 @@ var createXl1ToEthBridgeJob = /* @__PURE__ */ __name(async (flowProducer2, tx) =
|
|
|
473
526
|
queueName: Xl1TransactionPreparation.queueName,
|
|
474
527
|
data: {
|
|
475
528
|
tx
|
|
529
|
+
},
|
|
530
|
+
opts: {
|
|
531
|
+
jobId
|
|
476
532
|
}
|
|
477
533
|
}
|
|
478
534
|
]
|
|
@@ -490,10 +546,24 @@ var createXl1ToEthBridgeJob = /* @__PURE__ */ __name(async (flowProducer2, tx) =
|
|
|
490
546
|
return flow;
|
|
491
547
|
}, "createXl1ToEthBridgeJob");
|
|
492
548
|
|
|
549
|
+
// src/queue/telemetry.ts
|
|
550
|
+
import { isDefined as isDefined6 } from "@xylabs/sdk-js";
|
|
551
|
+
import { BullMQOtel } from "bullmq-otel";
|
|
552
|
+
var telemetry;
|
|
553
|
+
var options = {
|
|
554
|
+
enableMetrics: true
|
|
555
|
+
};
|
|
556
|
+
var getTelemetry = /* @__PURE__ */ __name(() => {
|
|
557
|
+
if (isDefined6(telemetry)) return telemetry;
|
|
558
|
+
telemetry = new BullMQOtel(options);
|
|
559
|
+
return telemetry;
|
|
560
|
+
}, "getTelemetry");
|
|
561
|
+
|
|
493
562
|
// src/server/addFlowProducer.ts
|
|
494
563
|
var addFlowProducer = /* @__PURE__ */ __name((app, config) => {
|
|
495
564
|
const connection2 = getConnection(config);
|
|
496
|
-
const
|
|
565
|
+
const telemetry2 = getTelemetry();
|
|
566
|
+
const flowProducer2 = getFlowProducer(connection2, telemetry2);
|
|
497
567
|
app.flowProducer = flowProducer2;
|
|
498
568
|
return app;
|
|
499
569
|
}, "addFlowProducer");
|
|
@@ -531,14 +601,14 @@ var asToken = /* @__PURE__ */ __name((value) => {
|
|
|
531
601
|
}, "asToken");
|
|
532
602
|
|
|
533
603
|
// src/config/getBridgeEscrowAddress.ts
|
|
534
|
-
import { asAddress as asAddress2, assertEx as
|
|
604
|
+
import { asAddress as asAddress2, assertEx as assertEx11 } from "@xylabs/sdk-js";
|
|
535
605
|
var tryGetBridgeEscrowAddress = /* @__PURE__ */ __name((config) => {
|
|
536
606
|
const address = asAddress2(config.escrowAddress);
|
|
537
607
|
return address;
|
|
538
608
|
}, "tryGetBridgeEscrowAddress");
|
|
539
609
|
|
|
540
610
|
// src/config/getBridgeFeesAddress.ts
|
|
541
|
-
import { asAddress as asAddress3, assertEx as
|
|
611
|
+
import { asAddress as asAddress3, assertEx as assertEx12 } from "@xylabs/sdk-js";
|
|
542
612
|
var tryGetBridgeFeesAddress = /* @__PURE__ */ __name((config) => {
|
|
543
613
|
const address = asAddress3(config.feesAddress);
|
|
544
614
|
return address;
|
|
@@ -566,22 +636,22 @@ var getMinBridgeAmount = /* @__PURE__ */ __name((config) => {
|
|
|
566
636
|
}, "getMinBridgeAmount");
|
|
567
637
|
|
|
568
638
|
// src/config/getRemoteChainId.ts
|
|
569
|
-
import { assertEx as
|
|
639
|
+
import { assertEx as assertEx13 } from "@xylabs/sdk-js";
|
|
570
640
|
var getRemoteChainId = /* @__PURE__ */ __name((config) => {
|
|
571
|
-
const remoteChainId =
|
|
641
|
+
const remoteChainId = assertEx13(asChainId(config.remoteChainId), () => "Invalid remote chain ID in config");
|
|
572
642
|
return remoteChainId;
|
|
573
643
|
}, "getRemoteChainId");
|
|
574
644
|
|
|
575
645
|
// src/config/getRemoteTokenAddress.ts
|
|
576
|
-
import { assertEx as
|
|
646
|
+
import { assertEx as assertEx14 } from "@xylabs/sdk-js";
|
|
577
647
|
var getRemoteTokenAddress = /* @__PURE__ */ __name((config) => {
|
|
578
648
|
const token = asToken(config.remoteTokenAddress);
|
|
579
|
-
return
|
|
649
|
+
return assertEx14(token, () => "Remote token address is not defined in bridge configuration");
|
|
580
650
|
}, "getRemoteTokenAddress");
|
|
581
651
|
|
|
582
652
|
// src/config/getBridgeWalletAccount.ts
|
|
583
|
-
import { isDefined as
|
|
584
|
-
import { HDWallet } from "@xyo-network/
|
|
653
|
+
import { isDefined as isDefined7, isUndefined } from "@xylabs/sdk-js";
|
|
654
|
+
import { HDWallet } from "@xyo-network/sdk-js";
|
|
585
655
|
import { ADDRESS_INDEX, generateXyoBaseWalletFromPhrase } from "@xyo-network/xl1-sdk";
|
|
586
656
|
var accountServiceSingleton;
|
|
587
657
|
var getBridgeWalletAccount = /* @__PURE__ */ __name(async (config) => {
|
|
@@ -614,20 +684,20 @@ var getTransferAddresses = /* @__PURE__ */ __name(async (config) => {
|
|
|
614
684
|
}, "getTransferAddresses");
|
|
615
685
|
|
|
616
686
|
// src/config/getXl1ChainId.ts
|
|
617
|
-
import { assertEx as
|
|
687
|
+
import { assertEx as assertEx15, isDefined as isDefined8 } from "@xylabs/sdk-js";
|
|
618
688
|
var getXl1ChainId = /* @__PURE__ */ __name((config) => {
|
|
619
689
|
const xl1ChainId = config.xl1ChainId;
|
|
620
|
-
if (
|
|
621
|
-
return
|
|
690
|
+
if (isDefined8(xl1ChainId)) {
|
|
691
|
+
return assertEx15(asChainId(xl1ChainId), () => "Invalid xl1ChainId in bridge config");
|
|
622
692
|
}
|
|
623
|
-
return
|
|
693
|
+
return assertEx15(asChainId(config.chain.id), () => "Invalid chain.id in config");
|
|
624
694
|
}, "getXl1ChainId");
|
|
625
695
|
|
|
626
696
|
// src/config/getXl1TokenAddress.ts
|
|
627
|
-
import { isDefined as
|
|
697
|
+
import { isDefined as isDefined9 } from "@xylabs/sdk-js";
|
|
628
698
|
var getXl1TokenAddress = /* @__PURE__ */ __name((config) => {
|
|
629
699
|
const token = asToken(config.xl1TokenAddress);
|
|
630
|
-
if (
|
|
700
|
+
if (isDefined9(token)) return token;
|
|
631
701
|
return getXl1ChainId(config);
|
|
632
702
|
}, "getXl1TokenAddress");
|
|
633
703
|
|
|
@@ -746,7 +816,7 @@ var makeBridgeFromRemoteStatusRoute = /* @__PURE__ */ __name((config) => {
|
|
|
746
816
|
|
|
747
817
|
// src/server/routes/bridge/routeDefinitions/routes/bridgeToRemote.ts
|
|
748
818
|
import { requestHandlerValidator as requestHandlerValidator3 } from "@xylabs/express";
|
|
749
|
-
import { PayloadBuilder as
|
|
819
|
+
import { PayloadBuilder as PayloadBuilder12, PayloadZodLooseOfSchema, PayloadZodStrictOfSchema as PayloadZodStrictOfSchema2 } from "@xyo-network/sdk-js";
|
|
750
820
|
import { BridgeIntentFieldsZod, BridgeIntentSchema as BridgeIntentSchema2, BridgeSourceObservationFieldsZod, BridgeSourceObservationSchema, SignedTransactionBoundWitnessZod, TransferZod } from "@xyo-network/xl1-sdk";
|
|
751
821
|
import { z as z2 } from "zod";
|
|
752
822
|
|
|
@@ -787,7 +857,7 @@ var createBridgeTransfer = /* @__PURE__ */ __name((sender, srcAmount, escrowAddr
|
|
|
787
857
|
|
|
788
858
|
// src/util/generateBridgeEstimate.ts
|
|
789
859
|
import { toAddress as toAddress2 } from "@xylabs/sdk-js";
|
|
790
|
-
import { PayloadBuilder as
|
|
860
|
+
import { PayloadBuilder as PayloadBuilder9 } from "@xyo-network/sdk-js";
|
|
791
861
|
import { BridgeIntentSchema } from "@xyo-network/xl1-sdk";
|
|
792
862
|
import { v4 } from "uuid";
|
|
793
863
|
var generateBridgeEstimate = /* @__PURE__ */ __name(async (srcAddress, srcAmount, destAddress, config, nonceOverride) => {
|
|
@@ -811,7 +881,7 @@ var generateBridgeEstimate = /* @__PURE__ */ __name(async (srcAddress, srcAmount
|
|
|
811
881
|
destToken: remoteTokenAddress,
|
|
812
882
|
nonce
|
|
813
883
|
};
|
|
814
|
-
const bridgeIntent = new
|
|
884
|
+
const bridgeIntent = new PayloadBuilder9({
|
|
815
885
|
schema: BridgeIntentSchema
|
|
816
886
|
}).fields(bridgeIntentFields).build();
|
|
817
887
|
const transfer = createBridgeTransfer(sender, srcAmount, escrowAddress, feesAddress, fees);
|
|
@@ -823,33 +893,33 @@ var generateBridgeEstimate = /* @__PURE__ */ __name(async (srcAddress, srcAmount
|
|
|
823
893
|
|
|
824
894
|
// src/util/validateBridgeEstimateExact.ts
|
|
825
895
|
import { isUndefined as isUndefined3 } from "@xylabs/sdk-js";
|
|
826
|
-
import { PayloadBuilder as
|
|
896
|
+
import { PayloadBuilder as PayloadBuilder10 } from "@xyo-network/sdk-js";
|
|
827
897
|
var validateBridgeEstimateExact = /* @__PURE__ */ __name(async (intent, transfer, config) => {
|
|
828
898
|
const { srcAddress, srcAmount, destAddress } = intent;
|
|
829
899
|
const [calculatedIntent, calculatedTransfer] = await generateBridgeEstimate(srcAddress, srcAmount, destAddress, config);
|
|
830
900
|
if (isUndefined3(calculatedIntent) || isUndefined3(calculatedTransfer)) return false;
|
|
831
901
|
const { nonce: expectedIntentNonce, ...expectedIntentStatic } = calculatedIntent;
|
|
832
902
|
const { nonce: actualIntentNonce, ...actualIntentStatic } = intent;
|
|
833
|
-
if (await
|
|
903
|
+
if (await PayloadBuilder10.dataHash(expectedIntentStatic) !== await PayloadBuilder10.dataHash(actualIntentStatic)) return false;
|
|
834
904
|
const { epoch: expectedTransferEpoch, ...expectedTransferStatic } = calculatedTransfer;
|
|
835
905
|
const { epoch: actualTransferEpoch, ...actualTransferStatic } = transfer;
|
|
836
|
-
if (await
|
|
906
|
+
if (await PayloadBuilder10.dataHash(expectedTransferStatic) !== await PayloadBuilder10.dataHash(actualTransferStatic)) return false;
|
|
837
907
|
return true;
|
|
838
908
|
}, "validateBridgeEstimateExact");
|
|
839
909
|
|
|
840
910
|
// src/util/validateBridgeTransaction.ts
|
|
841
|
-
import { asAddress as asAddress4, isDefined as
|
|
911
|
+
import { asAddress as asAddress4, isDefined as isDefined10 } from "@xylabs/sdk-js";
|
|
842
912
|
import { addressesContains, BoundWitnessValidator, payloadHashesContainsAll } from "@xyo-network/boundwitness-validator";
|
|
843
|
-
import { PayloadBuilder as
|
|
913
|
+
import { PayloadBuilder as PayloadBuilder11 } from "@xyo-network/sdk-js";
|
|
844
914
|
var validateBridgeTransaction = /* @__PURE__ */ __name(async (signedTxBw, intent, transfer, config) => {
|
|
845
915
|
const { srcAddress } = intent;
|
|
846
916
|
const chainId = getXl1ChainId(config);
|
|
847
917
|
if (signedTxBw.chain !== chainId) return false;
|
|
848
918
|
const errors = await new BoundWitnessValidator(signedTxBw).validate();
|
|
849
|
-
if (
|
|
919
|
+
if (isDefined10(errors) && errors.length > 0) return false;
|
|
850
920
|
const sender = asAddress4(srcAddress, true);
|
|
851
921
|
if (!addressesContains(signedTxBw, sender)) return false;
|
|
852
|
-
const hashes = await
|
|
922
|
+
const hashes = await PayloadBuilder11.hashes([
|
|
853
923
|
intent,
|
|
854
924
|
transfer
|
|
855
925
|
]);
|
|
@@ -897,14 +967,14 @@ var makeBridgeToRemoteRoute = /* @__PURE__ */ __name((config) => {
|
|
|
897
967
|
]
|
|
898
968
|
];
|
|
899
969
|
await createXl1ToEthBridgeJob(flowProducer2, singedHydratedTransaction);
|
|
900
|
-
const srcConfirmation = await
|
|
970
|
+
const srcConfirmation = await PayloadBuilder12.hash(signedTxBw);
|
|
901
971
|
const bridgeCommonFieldsZod = z2.object({}).extend(BridgeSourceObservationFieldsZod.shape);
|
|
902
972
|
const bridgeCommonFields = bridgeCommonFieldsZod.parse(bridgeIntent);
|
|
903
973
|
const bridgeObservationFields = {
|
|
904
974
|
...bridgeCommonFields,
|
|
905
975
|
srcConfirmation
|
|
906
976
|
};
|
|
907
|
-
const bridgeObservation = new
|
|
977
|
+
const bridgeObservation = new PayloadBuilder12({
|
|
908
978
|
schema: BridgeSourceObservationSchema
|
|
909
979
|
}).fields(bridgeObservationFields).build();
|
|
910
980
|
res.json(bridgeObservation);
|
|
@@ -914,7 +984,7 @@ var makeBridgeToRemoteRoute = /* @__PURE__ */ __name((config) => {
|
|
|
914
984
|
|
|
915
985
|
// src/server/routes/bridge/routeDefinitions/routes/bridgeToRemoteEstimate.ts
|
|
916
986
|
import { requestHandlerValidator as requestHandlerValidator4 } from "@xylabs/express";
|
|
917
|
-
import { assertEx as
|
|
987
|
+
import { assertEx as assertEx16, toAddress as toAddress3 } from "@xylabs/sdk-js";
|
|
918
988
|
import { PayloadZodStrictOfSchema as PayloadZodStrictOfSchema3 } from "@xyo-network/sdk-js";
|
|
919
989
|
import { BridgeIntentFieldsZod as BridgeIntentFieldsZod2, BridgeIntentSchema as BridgeIntentSchema3, buildUnsignedTransaction, toXL1BlockNumber, TransactionBoundWitnessZod, TransferZod as TransferZod2 } from "@xyo-network/xl1-sdk";
|
|
920
990
|
import { z as z3 } from "zod";
|
|
@@ -945,7 +1015,7 @@ var makeBridgeToRemoteEstimateRoute = /* @__PURE__ */ __name((config, gateway) =
|
|
|
945
1015
|
const { srcAddress, srcAmount, destAddress } = req.body;
|
|
946
1016
|
const [bridgeIntent, transfer] = await generateBridgeEstimate(srcAddress, srcAmount, destAddress, config);
|
|
947
1017
|
const sender = toAddress3(srcAddress);
|
|
948
|
-
const viewer =
|
|
1018
|
+
const viewer = assertEx16(gateway.connection.viewer, () => new Error("Viewer not available on gateway connection"));
|
|
949
1019
|
const currentBlockNumber = await viewer.currentBlockNumber();
|
|
950
1020
|
const nbf = toXL1BlockNumber(currentBlockNumber, true);
|
|
951
1021
|
const exp = toXL1BlockNumber(currentBlockNumber + 1e3, true);
|
|
@@ -965,86 +1035,126 @@ var makeBridgeToRemoteEstimateRoute = /* @__PURE__ */ __name((config, gateway) =
|
|
|
965
1035
|
|
|
966
1036
|
// src/server/routes/bridge/routeDefinitions/routes/bridgeToRemoteStatus.ts
|
|
967
1037
|
import { requestHandlerValidator as requestHandlerValidator5 } from "@xylabs/express";
|
|
968
|
-
import {
|
|
969
|
-
import { PayloadZodStrictOfSchema as PayloadZodStrictOfSchema4 } from "@xyo-network/sdk-js";
|
|
970
|
-
import { BridgeDestinationObservationFieldsZod as BridgeDestinationObservationFieldsZod2, BridgeDestinationObservationSchema as BridgeDestinationObservationSchema2, BridgeIntentFieldsZod as BridgeIntentFieldsZod3, BridgeIntentSchema as BridgeIntentSchema4, BridgeSourceObservationFieldsZod as BridgeSourceObservationFieldsZod2, BridgeSourceObservationSchema as BridgeSourceObservationSchema2 } from "@xyo-network/xl1-sdk";
|
|
1038
|
+
import { asHex as asHex3, isDefined as isDefined11 } from "@xylabs/sdk-js";
|
|
1039
|
+
import { PayloadBuilder as PayloadBuilder13, PayloadZodStrictOfSchema as PayloadZodStrictOfSchema4 } from "@xyo-network/sdk-js";
|
|
1040
|
+
import { asBridgeIntent, BridgeDestinationObservationFieldsZod as BridgeDestinationObservationFieldsZod2, BridgeDestinationObservationSchema as BridgeDestinationObservationSchema2, BridgeIntentFieldsZod as BridgeIntentFieldsZod3, BridgeIntentSchema as BridgeIntentSchema4, BridgeSourceObservationFieldsZod as BridgeSourceObservationFieldsZod2, BridgeSourceObservationSchema as BridgeSourceObservationSchema2, isBridgeIntent as isBridgeIntent5 } from "@xyo-network/xl1-sdk";
|
|
1041
|
+
import { Queue } from "bullmq";
|
|
971
1042
|
import { z as z4 } from "zod";
|
|
1043
|
+
var BridgeIntentResponseZod = PayloadZodStrictOfSchema4(BridgeIntentSchema4).extend(BridgeIntentFieldsZod3.shape);
|
|
1044
|
+
var BridgeSourceResponseZod = PayloadZodStrictOfSchema4(BridgeSourceObservationSchema2).extend(BridgeSourceObservationFieldsZod2.shape);
|
|
1045
|
+
var BridgeDestinationResponseZod = PayloadZodStrictOfSchema4(BridgeDestinationObservationSchema2).extend(BridgeDestinationObservationFieldsZod2.shape);
|
|
972
1046
|
var BridgeToRemoteStatusResponseZod = z4.union([
|
|
973
1047
|
z4.tuple([]),
|
|
974
1048
|
z4.tuple([
|
|
975
|
-
|
|
1049
|
+
BridgeIntentResponseZod
|
|
976
1050
|
]),
|
|
977
1051
|
z4.tuple([
|
|
978
|
-
|
|
979
|
-
|
|
1052
|
+
BridgeIntentResponseZod,
|
|
1053
|
+
BridgeSourceResponseZod
|
|
980
1054
|
]),
|
|
981
1055
|
z4.tuple([
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
1056
|
+
BridgeIntentResponseZod,
|
|
1057
|
+
BridgeSourceResponseZod,
|
|
1058
|
+
BridgeDestinationResponseZod
|
|
985
1059
|
])
|
|
986
1060
|
]);
|
|
1061
|
+
var statusQueues;
|
|
1062
|
+
var getStatusQueues = /* @__PURE__ */ __name((config) => {
|
|
1063
|
+
if (statusQueues) return statusQueues;
|
|
1064
|
+
const connection2 = getConnection(config);
|
|
1065
|
+
statusQueues = {
|
|
1066
|
+
ethTransactionMonitor: new Queue(EthTransactionMonitor.queueName, {
|
|
1067
|
+
connection: connection2
|
|
1068
|
+
}),
|
|
1069
|
+
ethTransactionPreparation: new Queue(EthTransactionPreparation.queueName, {
|
|
1070
|
+
connection: connection2
|
|
1071
|
+
}),
|
|
1072
|
+
ethTransactionSubmission: new Queue(EthTransactionSubmission.queueName, {
|
|
1073
|
+
connection: connection2
|
|
1074
|
+
}),
|
|
1075
|
+
xl1ToEthBridgeParent: new Queue(Xl1ToEthBridgeParent.queueName, {
|
|
1076
|
+
connection: connection2
|
|
1077
|
+
}),
|
|
1078
|
+
xl1TransactionMonitor: new Queue(Xl1TransactionMonitor.queueName, {
|
|
1079
|
+
connection: connection2
|
|
1080
|
+
}),
|
|
1081
|
+
xl1TransactionPreparation: new Queue(Xl1TransactionPreparation.queueName, {
|
|
1082
|
+
connection: connection2
|
|
1083
|
+
}),
|
|
1084
|
+
xl1TransactionSubmission: new Queue(Xl1TransactionSubmission.queueName, {
|
|
1085
|
+
connection: connection2
|
|
1086
|
+
})
|
|
1087
|
+
};
|
|
1088
|
+
return statusQueues;
|
|
1089
|
+
}, "getStatusQueues");
|
|
1090
|
+
var getStatusQueueJobs = /* @__PURE__ */ __name(async (queues, jobId) => {
|
|
1091
|
+
const [ethTransactionMonitorJob, ethTransactionPreparationJob, ethTransactionSubmissionJob, xl1ToEthBridgeParentJob, xl1TransactionMonitorJob, xl1TransactionPreparationJob, xl1TransactionSubmissionJob] = await Promise.all([
|
|
1092
|
+
queues.ethTransactionMonitor.getJob(jobId),
|
|
1093
|
+
queues.ethTransactionPreparation.getJob(jobId),
|
|
1094
|
+
queues.ethTransactionSubmission.getJob(jobId),
|
|
1095
|
+
queues.xl1ToEthBridgeParent.getJob(jobId),
|
|
1096
|
+
queues.xl1TransactionMonitor.getJob(jobId),
|
|
1097
|
+
queues.xl1TransactionPreparation.getJob(jobId),
|
|
1098
|
+
queues.xl1TransactionSubmission.getJob(jobId)
|
|
1099
|
+
]);
|
|
1100
|
+
return {
|
|
1101
|
+
ethTransactionMonitorJob,
|
|
1102
|
+
ethTransactionPreparationJob,
|
|
1103
|
+
ethTransactionSubmissionJob,
|
|
1104
|
+
xl1ToEthBridgeParentJob,
|
|
1105
|
+
xl1TransactionMonitorJob,
|
|
1106
|
+
xl1TransactionPreparationJob,
|
|
1107
|
+
xl1TransactionSubmissionJob
|
|
1108
|
+
};
|
|
1109
|
+
}, "getStatusQueueJobs");
|
|
987
1110
|
var makeBridgeToRemoteStatusRoute = /* @__PURE__ */ __name((config) => {
|
|
988
1111
|
const params = z4.object({
|
|
989
1112
|
chainId: getRemoteChainIdZod(config),
|
|
990
1113
|
nonce: z4.string().nonempty()
|
|
991
1114
|
});
|
|
992
|
-
const query = z4.object({
|
|
993
|
-
mockStatus: z4.coerce.number().default(0)
|
|
994
|
-
});
|
|
995
1115
|
const validateRequest2 = requestHandlerValidator5({
|
|
996
1116
|
params,
|
|
997
|
-
query,
|
|
998
1117
|
response: BridgeToRemoteStatusResponseZod
|
|
999
1118
|
});
|
|
1000
1119
|
return {
|
|
1001
1120
|
method: "get",
|
|
1002
1121
|
path: "/bridge/chains/:chainId/bridgeToRemote/status/:nonce",
|
|
1003
1122
|
handlers: validateRequest2(async (req, res) => {
|
|
1004
|
-
const
|
|
1005
|
-
const { mockStatus = 0 } = req.query;
|
|
1123
|
+
const jobId = req.params.nonce;
|
|
1006
1124
|
const result = [];
|
|
1007
|
-
const
|
|
1008
|
-
const
|
|
1009
|
-
const
|
|
1010
|
-
|
|
1011
|
-
const
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
const
|
|
1015
|
-
const
|
|
1016
|
-
|
|
1017
|
-
if (
|
|
1018
|
-
const
|
|
1019
|
-
|
|
1020
|
-
}
|
|
1021
|
-
if (mockStatus > 1) {
|
|
1125
|
+
const queues = getStatusQueues(config);
|
|
1126
|
+
const statusQueueJobs = await getStatusQueueJobs(queues, jobId);
|
|
1127
|
+
const tx = Object.values(statusQueueJobs).map((job) => job?.data?.tx).find((tx2) => isDefined11(tx2));
|
|
1128
|
+
if (!tx) return res.sendStatus(404);
|
|
1129
|
+
const bridgeIntent = tx[1].find(isBridgeIntent5);
|
|
1130
|
+
if (!bridgeIntent) return res.sendStatus(404);
|
|
1131
|
+
result[0] = asBridgeIntent(PayloadBuilder13.omitMeta(bridgeIntent));
|
|
1132
|
+
const { xl1TransactionMonitorJob } = statusQueueJobs;
|
|
1133
|
+
const xl1MonitorState = xl1TransactionMonitorJob ? await xl1TransactionMonitorJob.getState() : void 0;
|
|
1134
|
+
const srcConfirmation = asHex3(jobId);
|
|
1135
|
+
if (xl1MonitorState === "completed" && isDefined11(srcConfirmation)) {
|
|
1136
|
+
const bridgeCommonFieldsZod = z4.object({}).extend(BridgeSourceObservationFieldsZod2.shape);
|
|
1137
|
+
const bridgeCommonFields = bridgeCommonFieldsZod.parse(bridgeIntent);
|
|
1022
1138
|
const observation = {
|
|
1023
1139
|
schema: BridgeSourceObservationSchema2,
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
destAmount,
|
|
1027
|
-
destToken,
|
|
1028
|
-
src,
|
|
1029
|
-
srcAddress,
|
|
1030
|
-
srcAmount,
|
|
1031
|
-
srcToken,
|
|
1032
|
-
srcConfirmation: toHex3("0x8888")
|
|
1140
|
+
...bridgeCommonFields,
|
|
1141
|
+
srcConfirmation
|
|
1033
1142
|
};
|
|
1034
1143
|
result[1] = observation;
|
|
1035
1144
|
}
|
|
1036
|
-
|
|
1145
|
+
const { ethTransactionMonitorJob } = statusQueueJobs;
|
|
1146
|
+
const ethMonitorState = ethTransactionMonitorJob ? await ethTransactionMonitorJob.getState() : void 0;
|
|
1147
|
+
const submissionHash = ethTransactionMonitorJob?.returnvalue?.submissionHash;
|
|
1148
|
+
const destConfirmation = asHex3(submissionHash);
|
|
1149
|
+
if (ethMonitorState === "completed" && isDefined11(submissionHash)) {
|
|
1150
|
+
const bridgeDestinationFieldsZod = z4.object({}).extend(BridgeDestinationObservationFieldsZod2.shape);
|
|
1151
|
+
const bridgeDestinationFields = bridgeDestinationFieldsZod.parse({
|
|
1152
|
+
...bridgeIntent,
|
|
1153
|
+
destConfirmation
|
|
1154
|
+
});
|
|
1037
1155
|
const observation = {
|
|
1038
1156
|
schema: BridgeDestinationObservationSchema2,
|
|
1039
|
-
|
|
1040
|
-
destAddress,
|
|
1041
|
-
destAmount,
|
|
1042
|
-
destToken,
|
|
1043
|
-
src,
|
|
1044
|
-
srcAddress,
|
|
1045
|
-
srcAmount,
|
|
1046
|
-
srcToken,
|
|
1047
|
-
destConfirmation: toHex3("0x9999")
|
|
1157
|
+
...bridgeDestinationFields
|
|
1048
1158
|
};
|
|
1049
1159
|
result[2] = observation;
|
|
1050
1160
|
}
|
|
@@ -1099,10 +1209,10 @@ var getApp = /* @__PURE__ */ __name((config, gateway) => {
|
|
|
1099
1209
|
}, "getApp");
|
|
1100
1210
|
|
|
1101
1211
|
// src/services/getServices.ts
|
|
1102
|
-
import { assertEx as
|
|
1212
|
+
import { assertEx as assertEx17, isDefined as isDefined12 } from "@xylabs/sdk-js";
|
|
1103
1213
|
import { initEvmProvider } from "@xyo-network/chain-orchestration";
|
|
1214
|
+
import { HDWallet as HDWallet2 } from "@xyo-network/sdk-js";
|
|
1104
1215
|
import { BridgeableToken__factory, LiquidityPoolBridge__factory } from "@xyo-network/typechain";
|
|
1105
|
-
import { HDWallet as HDWallet2 } from "@xyo-network/wallet";
|
|
1106
1216
|
import { getAddress as getAddress2, Wallet } from "ethers";
|
|
1107
1217
|
|
|
1108
1218
|
// src/services/getIterableMap.ts
|
|
@@ -1144,12 +1254,12 @@ var getServices = /* @__PURE__ */ __name(async (context, gateway) => {
|
|
|
1144
1254
|
const xl1TxStateMap = await getIterableMap(config, "liquidity_bridge_xl1_to_eth_xl1_tx_state");
|
|
1145
1255
|
const provider = await initEvmProvider(context);
|
|
1146
1256
|
const { remoteBridgeContractAddress, remoteChainWalletPrivateKey, remoteTokenAddress, mnemonic } = config;
|
|
1147
|
-
const account =
|
|
1257
|
+
const account = isDefined12(mnemonic) ? await HDWallet2.fromPhrase(mnemonic) : await HDWallet2.random();
|
|
1148
1258
|
const wallet = new Wallet(remoteChainWalletPrivateKey, provider);
|
|
1149
1259
|
const bridgeableToken = BridgeableToken__factory.connect(getAddress2(remoteTokenAddress), wallet);
|
|
1150
1260
|
const bridge = LiquidityPoolBridge__factory.connect(getAddress2(remoteBridgeContractAddress), wallet);
|
|
1151
1261
|
const bridgeOwner = await bridge.owner();
|
|
1152
|
-
|
|
1262
|
+
assertEx17(bridgeOwner.toLowerCase() === wallet.address.toLowerCase(), () => "Wallet is not the owner of the bridge contract");
|
|
1153
1263
|
return {
|
|
1154
1264
|
account,
|
|
1155
1265
|
bridge,
|
|
@@ -1165,7 +1275,8 @@ var getServices = /* @__PURE__ */ __name(async (context, gateway) => {
|
|
|
1165
1275
|
// src/server/addWorkers.ts
|
|
1166
1276
|
var addWorkers = /* @__PURE__ */ __name((config, services) => {
|
|
1167
1277
|
const connection2 = getConnection(config);
|
|
1168
|
-
|
|
1278
|
+
const telemetry2 = getTelemetry();
|
|
1279
|
+
createWorkers(connection2, telemetry2, services);
|
|
1169
1280
|
}, "addWorkers");
|
|
1170
1281
|
|
|
1171
1282
|
// src/server/server.ts
|