@xyo-network/chain-bridge 1.19.18 → 1.20.0
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/config/getTestGateway.d.ts +4 -0
- package/dist/node/config/getTestGateway.d.ts.map +1 -0
- package/dist/node/config/index.d.ts +1 -1
- package/dist/node/config/index.d.ts.map +1 -1
- package/dist/node/index.mjs +700 -506
- package/dist/node/index.mjs.map +1 -1
- package/dist/node/modules/index.d.ts +0 -1
- package/dist/node/modules/index.d.ts.map +1 -1
- package/dist/node/queue/flowProducer.d.ts.map +1 -1
- package/dist/node/queue/flows/createEthToXl1BridgeJob.d.ts +10 -0
- package/dist/node/queue/flows/createEthToXl1BridgeJob.d.ts.map +1 -0
- package/dist/node/queue/flows/createXl1ToEthBridgeJob.d.ts.map +1 -1
- package/dist/node/queue/flows/index.d.ts +1 -0
- package/dist/node/queue/flows/index.d.ts.map +1 -1
- package/dist/node/queue/getXl1ToEthQueueJobs.d.ts +20 -0
- package/dist/node/queue/getXl1ToEthQueueJobs.d.ts.map +1 -0
- package/dist/node/queue/getXl1ToEthQueues.d.ts +14 -0
- package/dist/node/queue/getXl1ToEthQueues.d.ts.map +1 -0
- package/dist/node/queue/index.d.ts +3 -0
- package/dist/node/queue/index.d.ts.map +1 -1
- package/dist/node/queue/prefix.d.ts +2 -0
- package/dist/node/queue/prefix.d.ts.map +1 -0
- package/dist/node/queue/workers/EthToXl1BridgeParent.d.ts +8 -0
- package/dist/node/queue/workers/EthToXl1BridgeParent.d.ts.map +1 -0
- package/dist/node/queue/workers/EthTransactionMonitor.d.ts +2 -0
- package/dist/node/queue/workers/EthTransactionMonitor.d.ts.map +1 -1
- package/dist/node/queue/workers/EthTransactionPreparation.d.ts +4 -2
- package/dist/node/queue/workers/EthTransactionPreparation.d.ts.map +1 -1
- package/dist/node/queue/workers/EthTransactionSubmission.d.ts +2 -0
- package/dist/node/queue/workers/EthTransactionSubmission.d.ts.map +1 -1
- package/dist/node/queue/workers/EthTransactionSubmissionStorage.d.ts +13 -0
- package/dist/node/queue/workers/EthTransactionSubmissionStorage.d.ts.map +1 -0
- package/dist/node/queue/workers/Xl1ToEthBridgeParent.d.ts +6 -1
- package/dist/node/queue/workers/Xl1ToEthBridgeParent.d.ts.map +1 -1
- package/dist/node/queue/workers/Xl1TransactionMonitor.d.ts +4 -0
- package/dist/node/queue/workers/Xl1TransactionMonitor.d.ts.map +1 -1
- package/dist/node/queue/workers/Xl1TransactionPreparation.d.ts +2 -0
- package/dist/node/queue/workers/Xl1TransactionPreparation.d.ts.map +1 -1
- package/dist/node/queue/workers/Xl1TransactionSubmission.d.ts +2 -0
- package/dist/node/queue/workers/Xl1TransactionSubmission.d.ts.map +1 -1
- package/dist/node/queue/workers/Xl1TransactionSubmissionStorage.d.ts +13 -0
- package/dist/node/queue/workers/Xl1TransactionSubmissionStorage.d.ts.map +1 -0
- package/dist/node/queue/workers/createWorkers.d.ts.map +1 -1
- package/dist/node/queue/workers/index.d.ts +3 -0
- package/dist/node/queue/workers/index.d.ts.map +1 -1
- package/dist/node/queue/workers/util/index.d.ts +0 -3
- package/dist/node/queue/workers/util/index.d.ts.map +1 -1
- package/dist/node/server/index.d.ts +2 -0
- package/dist/node/server/index.d.ts.map +1 -1
- package/dist/node/server/routes/bridge/routeDefinitions/routes/bridgeToRemote.d.ts.map +1 -1
- package/dist/node/server/routes/bridge/routeDefinitions/routes/bridgeToRemoteEstimate.d.ts +1 -1
- package/dist/node/server/routes/bridge/routeDefinitions/routes/bridgeToRemoteStatus.d.ts.map +1 -1
- package/dist/node/server/server.d.ts.map +1 -1
- package/dist/node/services/IBridgeServiceCollection.d.ts +1 -1
- package/dist/node/services/IBridgeServiceCollection.d.ts.map +1 -1
- package/dist/node/services/TxState.d.ts +0 -7
- package/dist/node/services/TxState.d.ts.map +1 -1
- package/dist/node/util/index.d.ts +0 -3
- package/dist/node/util/index.d.ts.map +1 -1
- package/dist/node/validation/AsyncLogger.d.ts.map +1 -0
- package/dist/node/validation/index.d.ts +7 -0
- package/dist/node/validation/index.d.ts.map +1 -0
- package/dist/node/validation/validateBridgeEstimate.d.ts.map +1 -0
- package/dist/node/validation/validateBridgeEstimateExact.d.ts.map +1 -0
- package/dist/node/validation/validateBridgeTransaction.d.ts.map +1 -0
- package/dist/node/validation/validateSufficientLiquiditySourceAllowance.d.ts.map +1 -0
- package/dist/node/validation/validateSufficientLiquiditySourceBalance.d.ts.map +1 -0
- package/dist/node/validation/validateSufficientRunnerEthBalanceForGas.d.ts.map +1 -0
- package/dist/node/validation/validateSufficientXL1SourceAddressBalance.d.ts +15 -0
- package/dist/node/validation/validateSufficientXL1SourceAddressBalance.d.ts.map +1 -0
- package/package.json +30 -30
- package/src/config/getTestGateway.ts +24 -0
- package/src/config/index.ts +1 -1
- package/src/modules/index.ts +0 -1
- package/src/queue/flowProducer.ts +5 -1
- package/src/queue/flows/createEthToXl1BridgeJob.ts +71 -0
- package/src/queue/flows/createXl1ToEthBridgeJob.ts +48 -20
- package/src/queue/flows/index.ts +1 -0
- package/src/queue/getXl1ToEthQueueJobs.ts +57 -0
- package/src/queue/getXl1ToEthQueues.ts +39 -0
- package/src/queue/index.ts +3 -0
- package/src/queue/prefix.ts +1 -0
- package/src/queue/workers/EthToXl1BridgeParent.ts +40 -0
- package/src/queue/workers/EthTransactionMonitor.ts +6 -2
- package/src/queue/workers/EthTransactionPreparation.ts +9 -5
- package/src/queue/workers/EthTransactionSubmission.ts +4 -12
- package/src/queue/workers/EthTransactionSubmissionStorage.ts +76 -0
- package/src/queue/workers/Xl1ToEthBridgeParent.ts +8 -3
- package/src/queue/workers/Xl1TransactionMonitor.ts +13 -9
- package/src/queue/workers/Xl1TransactionPreparation.ts +6 -2
- package/src/queue/workers/Xl1TransactionSubmission.ts +8 -9
- package/src/queue/workers/Xl1TransactionSubmissionStorage.ts +77 -0
- package/src/queue/workers/createWorkers.ts +10 -4
- package/src/queue/workers/index.ts +3 -0
- package/src/queue/workers/util/index.ts +0 -3
- package/src/server/index.ts +3 -2
- package/src/server/routes/bridge/routeDefinitions/routes/bridgeToRemote.ts +11 -1
- package/src/server/routes/bridge/routeDefinitions/routes/bridgeToRemoteStatus.ts +27 -101
- package/src/server/server.ts +1 -0
- package/src/services/IBridgeServiceCollection.ts +1 -1
- package/src/services/TxState.ts +0 -18
- package/src/util/index.ts +0 -3
- package/src/validation/index.ts +6 -0
- package/src/{util → validation}/validateBridgeEstimate.ts +1 -1
- package/src/{util → validation}/validateBridgeEstimateExact.ts +1 -1
- package/src/{util → validation}/validateBridgeTransaction.ts +1 -2
- package/src/validation/validateSufficientXL1SourceAddressBalance.ts +39 -0
- package/dist/node/config/getGateway.d.ts +0 -4
- package/dist/node/config/getGateway.d.ts.map +0 -1
- package/dist/node/modules/XL1TransactionCompletionMonitorSentinel/XL1TransactionCompletionMonitorSentinel.d.ts +0 -60
- package/dist/node/modules/XL1TransactionCompletionMonitorSentinel/XL1TransactionCompletionMonitorSentinel.d.ts.map +0 -1
- package/dist/node/modules/XL1TransactionCompletionMonitorSentinel/index.d.ts +0 -2
- package/dist/node/modules/XL1TransactionCompletionMonitorSentinel/index.d.ts.map +0 -1
- package/dist/node/queue/workers/util/AsyncLogger.d.ts.map +0 -1
- package/dist/node/queue/workers/util/validateSufficientLiquiditySourceAllowance.d.ts.map +0 -1
- package/dist/node/queue/workers/util/validateSufficientLiquiditySourceBalance.d.ts.map +0 -1
- package/dist/node/queue/workers/util/validateSufficientRunnerEthBalanceForGas.d.ts.map +0 -1
- package/dist/node/util/validateBridgeEstimate.d.ts.map +0 -1
- package/dist/node/util/validateBridgeEstimateExact.d.ts.map +0 -1
- package/dist/node/util/validateBridgeTransaction.d.ts.map +0 -1
- package/src/config/getGateway.ts +0 -23
- package/src/modules/XL1TransactionCompletionMonitorSentinel/XL1TransactionCompletionMonitorSentinel.ts +0 -165
- package/src/modules/XL1TransactionCompletionMonitorSentinel/index.ts +0 -1
- /package/dist/node/{queue/workers/util → validation}/AsyncLogger.d.ts +0 -0
- /package/dist/node/{util → validation}/validateBridgeEstimate.d.ts +0 -0
- /package/dist/node/{util → validation}/validateBridgeEstimateExact.d.ts +0 -0
- /package/dist/node/{util → validation}/validateBridgeTransaction.d.ts +0 -0
- /package/dist/node/{queue/workers/util → validation}/validateSufficientLiquiditySourceAllowance.d.ts +0 -0
- /package/dist/node/{queue/workers/util → validation}/validateSufficientLiquiditySourceBalance.d.ts +0 -0
- /package/dist/node/{queue/workers/util → validation}/validateSufficientRunnerEthBalanceForGas.d.ts +0 -0
- /package/src/{queue/workers/util → validation}/AsyncLogger.ts +0 -0
- /package/src/{queue/workers/util → validation}/validateSufficientLiquiditySourceAllowance.ts +0 -0
- /package/src/{queue/workers/util → validation}/validateSufficientLiquiditySourceBalance.ts +0 -0
- /package/src/{queue/workers/util → validation}/validateSufficientRunnerEthBalanceForGas.ts +0 -0
package/dist/node/index.mjs
CHANGED
|
@@ -31,28 +31,33 @@ var getConnection = /* @__PURE__ */ __name((config) => {
|
|
|
31
31
|
// src/queue/flowProducer.ts
|
|
32
32
|
import { isDefined as isDefined2 } from "@xylabs/sdk-js";
|
|
33
33
|
import { FlowProducer } from "bullmq";
|
|
34
|
+
|
|
35
|
+
// src/queue/prefix.ts
|
|
36
|
+
var prefix = "xl1-bridge";
|
|
37
|
+
|
|
38
|
+
// src/queue/flowProducer.ts
|
|
34
39
|
var flowProducer;
|
|
35
40
|
var getFlowProducer = /* @__PURE__ */ __name((connection2, telemetry2) => {
|
|
36
41
|
if (isDefined2(flowProducer)) return flowProducer;
|
|
37
42
|
flowProducer = new FlowProducer({
|
|
38
43
|
connection: connection2,
|
|
39
|
-
telemetry: telemetry2
|
|
44
|
+
telemetry: telemetry2,
|
|
45
|
+
prefix
|
|
40
46
|
});
|
|
41
47
|
return flowProducer;
|
|
42
48
|
}, "getFlowProducer");
|
|
43
49
|
|
|
44
|
-
// src/queue/flows/createXl1ToEthBridgeJob.ts
|
|
45
|
-
import { PayloadBuilder as PayloadBuilder8 } from "@xyo-network/sdk-js";
|
|
46
|
-
|
|
47
50
|
// src/queue/workers/createWorkers.ts
|
|
48
51
|
var createWorkers = /* @__PURE__ */ __name((connection2, telemetry2, services) => {
|
|
52
|
+
EthTransactionMonitor.createWorker(connection2, telemetry2, services);
|
|
53
|
+
EthTransactionPreparation.createWorker(connection2, telemetry2, services);
|
|
54
|
+
EthTransactionSubmission.createWorker(connection2, telemetry2, services);
|
|
55
|
+
EthTransactionSubmissionStorage.createWorker(connection2, telemetry2, services);
|
|
49
56
|
Xl1ToEthBridgeParent.createWorker(connection2, telemetry2);
|
|
57
|
+
Xl1TransactionMonitor.createWorker(connection2, telemetry2, services);
|
|
50
58
|
Xl1TransactionPreparation.createWorker(connection2, telemetry2, services);
|
|
51
59
|
Xl1TransactionSubmission.createWorker(connection2, telemetry2, services);
|
|
52
|
-
|
|
53
|
-
EthTransactionPreparation.createWorker(connection2, telemetry2, services);
|
|
54
|
-
EthTransactionSubmission.createWorker(connection2, telemetry2, services);
|
|
55
|
-
EthTransactionMonitor.createWorker(connection2, telemetry2, services);
|
|
60
|
+
Xl1TransactionSubmissionStorage.createWorker(connection2, telemetry2, services);
|
|
56
61
|
}, "createWorkers");
|
|
57
62
|
|
|
58
63
|
// src/queue/workers/EthTransactionMonitor.ts
|
|
@@ -81,7 +86,8 @@ var createWorker = /* @__PURE__ */ __name((connection2, telemetry2, services) =>
|
|
|
81
86
|
};
|
|
82
87
|
}, {
|
|
83
88
|
connection: connection2,
|
|
84
|
-
telemetry: telemetry2
|
|
89
|
+
telemetry: telemetry2,
|
|
90
|
+
prefix
|
|
85
91
|
});
|
|
86
92
|
worker.on("failed", (job, err) => {
|
|
87
93
|
console.error(`[${name}] Job ${job?.id} failed:`, err.message);
|
|
@@ -97,42 +103,268 @@ var EthTransactionMonitor = {
|
|
|
97
103
|
};
|
|
98
104
|
|
|
99
105
|
// src/queue/workers/EthTransactionPreparation.ts
|
|
100
|
-
import { assertEx as
|
|
101
|
-
import { PayloadBuilder as
|
|
102
|
-
import { isBridgeIntent as
|
|
106
|
+
import { assertEx as assertEx11, hexToBigInt as hexToBigInt6 } from "@xylabs/sdk-js";
|
|
107
|
+
import { PayloadBuilder as PayloadBuilder5 } from "@xyo-network/sdk-js";
|
|
108
|
+
import { isBridgeIntent as isBridgeIntent3 } from "@xyo-network/xl1-sdk";
|
|
103
109
|
import { Worker as Worker2 } from "bullmq";
|
|
104
110
|
import { getAddress } from "ethers";
|
|
105
111
|
|
|
106
|
-
// src/
|
|
107
|
-
import {
|
|
112
|
+
// src/validation/validateBridgeEstimateExact.ts
|
|
113
|
+
import { isUndefined as isUndefined2 } from "@xylabs/sdk-js";
|
|
114
|
+
import { PayloadBuilder as PayloadBuilder3 } from "@xyo-network/sdk-js";
|
|
115
|
+
|
|
116
|
+
// src/util/calculateBridgeFees.ts
|
|
117
|
+
import { hexToBigInt, toHex } from "@xylabs/sdk-js";
|
|
118
|
+
var calculateBridgeFees = /* @__PURE__ */ __name((srcAmount, feeStructure) => {
|
|
119
|
+
const { feeFixed, feeRateBasisPoints } = feeStructure;
|
|
120
|
+
const srcAmountBigInt = hexToBigInt(srcAmount);
|
|
121
|
+
const feeFixedBigInt = hexToBigInt(feeFixed);
|
|
122
|
+
const feeVariableBigInt = srcAmountBigInt * BigInt(feeRateBasisPoints) / 10000n;
|
|
123
|
+
const feeVariable = toHex(feeVariableBigInt);
|
|
124
|
+
const feeTotalBigInt = feeFixedBigInt + feeVariableBigInt;
|
|
125
|
+
const destAmountBigInt = srcAmountBigInt > feeTotalBigInt ? srcAmountBigInt - feeTotalBigInt : 0n;
|
|
126
|
+
const destAmount = toHex(destAmountBigInt);
|
|
127
|
+
return {
|
|
128
|
+
feeFixed,
|
|
129
|
+
feeVariable,
|
|
130
|
+
srcAmount
|
|
131
|
+
};
|
|
132
|
+
}, "calculateBridgeFees");
|
|
133
|
+
|
|
134
|
+
// src/util/createBridgeTransfer.ts
|
|
135
|
+
import { hexToBigInt as hexToBigInt2 } from "@xylabs/sdk-js";
|
|
136
|
+
import { createTransferPayload } from "@xyo-network/xl1-sdk";
|
|
137
|
+
var createBridgeTransfer = /* @__PURE__ */ __name((sender, srcAmount, escrowAddress, feesAddress, context) => {
|
|
138
|
+
const { feeFixed, feeVariable } = context;
|
|
139
|
+
const escrowAmount = hexToBigInt2(srcAmount);
|
|
140
|
+
const feesAmount = hexToBigInt2(feeFixed) + hexToBigInt2(feeVariable);
|
|
141
|
+
const transfers = escrowAddress === feesAddress ? {
|
|
142
|
+
[feesAddress]: escrowAmount + feesAmount
|
|
143
|
+
} : {
|
|
144
|
+
[escrowAddress]: escrowAmount,
|
|
145
|
+
[feesAddress]: feesAmount
|
|
146
|
+
};
|
|
147
|
+
const transfer = createTransferPayload(sender, transfers, context);
|
|
148
|
+
return transfer;
|
|
149
|
+
}, "createBridgeTransfer");
|
|
150
|
+
|
|
151
|
+
// src/util/generateBridgeEstimate.ts
|
|
152
|
+
import { toAddress } from "@xylabs/sdk-js";
|
|
108
153
|
import { PayloadBuilder as PayloadBuilder2 } from "@xyo-network/sdk-js";
|
|
109
|
-
import {
|
|
110
|
-
|
|
111
|
-
const xl1Transaction = assertEx2(tx[0], () => "No corresponding XL1 transaction found");
|
|
112
|
-
const bridgeIntent = assertEx2(tx[1].find(isBridgeIntent), () => "No bridge intent found");
|
|
113
|
-
const srcAddress = toEthAddress(bridgeIntent.srcAddress);
|
|
114
|
-
const destAddress = toEthAddress(bridgeIntent.destAddress);
|
|
115
|
-
const amount = hexToBigInt(bridgeIntent.destAmount);
|
|
116
|
-
const nonce = hexToBigInt(await PayloadBuilder2.hash(xl1Transaction));
|
|
117
|
-
const bridgeTx = await bridge.connect(wallet).bridgeFromRemote(srcAddress, destAddress, amount, nonce);
|
|
118
|
-
const receipt = await bridgeTx.wait(1);
|
|
119
|
-
return receipt?.hash;
|
|
120
|
-
}, "submitEthTransaction");
|
|
154
|
+
import { BridgeIntentSchema } from "@xyo-network/xl1-sdk";
|
|
155
|
+
import { v4 } from "uuid";
|
|
121
156
|
|
|
122
|
-
// src/
|
|
123
|
-
import {
|
|
124
|
-
var
|
|
125
|
-
const
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
}, "submitXl1Transaction");
|
|
157
|
+
// src/config/asChainId.ts
|
|
158
|
+
import { asHex } from "@xylabs/sdk-js";
|
|
159
|
+
var asChainId = /* @__PURE__ */ __name((value) => {
|
|
160
|
+
const chainId = asHex(value);
|
|
161
|
+
return chainId;
|
|
162
|
+
}, "asChainId");
|
|
129
163
|
|
|
130
|
-
// src/
|
|
131
|
-
import {
|
|
132
|
-
|
|
164
|
+
// src/config/asToken.ts
|
|
165
|
+
import { asAddress } from "@xylabs/sdk-js";
|
|
166
|
+
var asToken = /* @__PURE__ */ __name((value) => {
|
|
167
|
+
const token = asAddress(value);
|
|
168
|
+
return token;
|
|
169
|
+
}, "asToken");
|
|
170
|
+
|
|
171
|
+
// src/config/getBridgeEscrowAddress.ts
|
|
172
|
+
import { asAddress as asAddress2, assertEx as assertEx2 } from "@xylabs/sdk-js";
|
|
173
|
+
var tryGetBridgeEscrowAddress = /* @__PURE__ */ __name((config) => {
|
|
174
|
+
const address = asAddress2(config.escrowAddress);
|
|
175
|
+
return address;
|
|
176
|
+
}, "tryGetBridgeEscrowAddress");
|
|
177
|
+
|
|
178
|
+
// src/config/getBridgeFeesAddress.ts
|
|
179
|
+
import { asAddress as asAddress3, assertEx as assertEx3 } from "@xylabs/sdk-js";
|
|
180
|
+
var tryGetBridgeFeesAddress = /* @__PURE__ */ __name((config) => {
|
|
181
|
+
const address = asAddress3(config.feesAddress);
|
|
182
|
+
return address;
|
|
183
|
+
}, "tryGetBridgeFeesAddress");
|
|
184
|
+
|
|
185
|
+
// src/config/getFeeStructure.ts
|
|
186
|
+
var getFeeStructure = /* @__PURE__ */ __name((config) => {
|
|
187
|
+
const { feeFixed, feeRateBasisPoints } = config;
|
|
188
|
+
return {
|
|
189
|
+
feeFixed,
|
|
190
|
+
feeRateBasisPoints
|
|
191
|
+
};
|
|
192
|
+
}, "getFeeStructure");
|
|
193
|
+
|
|
194
|
+
// src/config/getMaxBridgeAmount.ts
|
|
195
|
+
var getMaxBridgeAmount = /* @__PURE__ */ __name((config) => {
|
|
196
|
+
const { maxBridgeAmount } = config;
|
|
197
|
+
return maxBridgeAmount;
|
|
198
|
+
}, "getMaxBridgeAmount");
|
|
199
|
+
|
|
200
|
+
// src/config/getMinBridgeAmount.ts
|
|
201
|
+
var getMinBridgeAmount = /* @__PURE__ */ __name((config) => {
|
|
202
|
+
const { minBridgeAmount } = config;
|
|
203
|
+
return minBridgeAmount;
|
|
204
|
+
}, "getMinBridgeAmount");
|
|
205
|
+
|
|
206
|
+
// src/config/getRemoteChainId.ts
|
|
207
|
+
import { assertEx as assertEx4 } from "@xylabs/sdk-js";
|
|
208
|
+
var getRemoteChainId = /* @__PURE__ */ __name((config) => {
|
|
209
|
+
const remoteChainId = assertEx4(asChainId(config.remoteChainId), () => "Invalid remote chain ID in config");
|
|
210
|
+
return remoteChainId;
|
|
211
|
+
}, "getRemoteChainId");
|
|
212
|
+
|
|
213
|
+
// src/config/getRemoteTokenAddress.ts
|
|
214
|
+
import { assertEx as assertEx5 } from "@xylabs/sdk-js";
|
|
215
|
+
var getRemoteTokenAddress = /* @__PURE__ */ __name((config) => {
|
|
216
|
+
const token = asToken(config.remoteTokenAddress);
|
|
217
|
+
return assertEx5(token, () => "Remote token address is not defined in bridge configuration");
|
|
218
|
+
}, "getRemoteTokenAddress");
|
|
219
|
+
|
|
220
|
+
// src/config/getBridgeWalletAccount.ts
|
|
221
|
+
import { isDefined as isDefined3, isUndefined } from "@xylabs/sdk-js";
|
|
222
|
+
import { HDWallet } from "@xyo-network/sdk-js";
|
|
223
|
+
import { ADDRESS_INDEX, generateXyoBaseWalletFromPhrase } from "@xyo-network/xl1-sdk";
|
|
224
|
+
var accountServiceSingleton;
|
|
225
|
+
var getBridgeWalletAccount = /* @__PURE__ */ __name(async (config) => {
|
|
226
|
+
if (accountServiceSingleton) return accountServiceSingleton;
|
|
227
|
+
let walletPhrase = config.mnemonic;
|
|
228
|
+
if (isUndefined(walletPhrase)) {
|
|
229
|
+
console.log("[Bridge] No wallet mnemonic specified!");
|
|
230
|
+
const randomMnemonic = HDWallet.generateMnemonic();
|
|
231
|
+
console.log(`[Bridge] Using randomly generated mnemonic:
|
|
232
|
+
|
|
233
|
+
${randomMnemonic}
|
|
234
|
+
|
|
235
|
+
`);
|
|
236
|
+
walletPhrase = randomMnemonic;
|
|
237
|
+
}
|
|
238
|
+
const wallet = await generateXyoBaseWalletFromPhrase(walletPhrase);
|
|
239
|
+
const account = await wallet.derivePath(ADDRESS_INDEX.XYO);
|
|
240
|
+
accountServiceSingleton = account;
|
|
241
|
+
return accountServiceSingleton;
|
|
242
|
+
}, "getBridgeWalletAccount");
|
|
243
|
+
|
|
244
|
+
// src/config/getTransferAddresses.ts
|
|
245
|
+
var getTransferAddresses = /* @__PURE__ */ __name(async (config) => {
|
|
246
|
+
const escrowAddress = tryGetBridgeEscrowAddress(config) ?? (await getBridgeWalletAccount(config)).address;
|
|
247
|
+
const feesAddress = tryGetBridgeFeesAddress(config) ?? (await getBridgeWalletAccount(config)).address;
|
|
248
|
+
return {
|
|
249
|
+
escrowAddress,
|
|
250
|
+
feesAddress
|
|
251
|
+
};
|
|
252
|
+
}, "getTransferAddresses");
|
|
253
|
+
|
|
254
|
+
// src/config/getXl1ChainId.ts
|
|
255
|
+
import { assertEx as assertEx6, isDefined as isDefined4 } from "@xylabs/sdk-js";
|
|
256
|
+
var getXl1ChainId = /* @__PURE__ */ __name((config) => {
|
|
257
|
+
const xl1ChainId = config.xl1ChainId;
|
|
258
|
+
if (isDefined4(xl1ChainId)) {
|
|
259
|
+
return assertEx6(asChainId(xl1ChainId), () => "Invalid xl1ChainId in bridge config");
|
|
260
|
+
}
|
|
261
|
+
return assertEx6(asChainId(config.chain.id), () => "Invalid chain.id in config");
|
|
262
|
+
}, "getXl1ChainId");
|
|
263
|
+
|
|
264
|
+
// src/config/getXl1TokenAddress.ts
|
|
265
|
+
import { isDefined as isDefined5 } from "@xylabs/sdk-js";
|
|
266
|
+
var getXl1TokenAddress = /* @__PURE__ */ __name((config) => {
|
|
267
|
+
const token = asToken(config.xl1TokenAddress);
|
|
268
|
+
if (isDefined5(token)) return token;
|
|
269
|
+
return getXl1ChainId(config);
|
|
270
|
+
}, "getXl1TokenAddress");
|
|
271
|
+
|
|
272
|
+
// src/config/getBridgeSettings.ts
|
|
273
|
+
var getBridgeSettings = /* @__PURE__ */ __name(async (config) => {
|
|
274
|
+
const { feeFixed, feeRateBasisPoints } = getFeeStructure(config);
|
|
275
|
+
const { feesAddress, escrowAddress } = await getTransferAddresses(config);
|
|
276
|
+
const maxBridgeAmount = getMaxBridgeAmount(config);
|
|
277
|
+
const minBridgeAmount = getMinBridgeAmount(config);
|
|
278
|
+
const remoteChainId = getRemoteChainId(config);
|
|
279
|
+
const remoteTokenAddress = getRemoteTokenAddress(config);
|
|
280
|
+
const xl1TokenAddress = getXl1TokenAddress(config);
|
|
281
|
+
const xl1ChainId = getXl1ChainId(config);
|
|
282
|
+
return {
|
|
283
|
+
feeFixed,
|
|
284
|
+
feeRateBasisPoints,
|
|
285
|
+
feesAddress,
|
|
286
|
+
escrowAddress,
|
|
287
|
+
maxBridgeAmount,
|
|
288
|
+
minBridgeAmount,
|
|
289
|
+
remoteChainId,
|
|
290
|
+
remoteTokenAddress,
|
|
291
|
+
xl1TokenAddress,
|
|
292
|
+
xl1ChainId
|
|
293
|
+
};
|
|
294
|
+
}, "getBridgeSettings");
|
|
295
|
+
|
|
296
|
+
// src/util/generateBridgeEstimate.ts
|
|
297
|
+
var generateBridgeEstimate = /* @__PURE__ */ __name(async (srcAddress, srcAmount, destAddress, config, nonceOverride) => {
|
|
298
|
+
const { escrowAddress, feeFixed, feeRateBasisPoints, feesAddress, remoteChainId, remoteTokenAddress, xl1ChainId, xl1TokenAddress } = await getBridgeSettings(config);
|
|
299
|
+
const sender = toAddress(srcAddress);
|
|
300
|
+
const fees = calculateBridgeFees(srcAmount, {
|
|
301
|
+
feeFixed,
|
|
302
|
+
feeRateBasisPoints
|
|
303
|
+
});
|
|
304
|
+
const nonce = nonceOverride ?? v4();
|
|
305
|
+
const bridgeIntentFields = {
|
|
306
|
+
// Source
|
|
307
|
+
src: xl1ChainId,
|
|
308
|
+
srcAddress: sender,
|
|
309
|
+
srcAmount,
|
|
310
|
+
srcToken: xl1TokenAddress,
|
|
311
|
+
// Destination
|
|
312
|
+
dest: remoteChainId,
|
|
313
|
+
destAddress,
|
|
314
|
+
destAmount: srcAmount,
|
|
315
|
+
destToken: remoteTokenAddress,
|
|
316
|
+
nonce
|
|
317
|
+
};
|
|
318
|
+
const bridgeIntent = new PayloadBuilder2({
|
|
319
|
+
schema: BridgeIntentSchema
|
|
320
|
+
}).fields(bridgeIntentFields).build();
|
|
321
|
+
const transfer = createBridgeTransfer(sender, srcAmount, escrowAddress, feesAddress, fees);
|
|
322
|
+
return [
|
|
323
|
+
bridgeIntent,
|
|
324
|
+
transfer
|
|
325
|
+
];
|
|
326
|
+
}, "generateBridgeEstimate");
|
|
327
|
+
|
|
328
|
+
// src/validation/validateBridgeEstimateExact.ts
|
|
329
|
+
var validateBridgeEstimateExact = /* @__PURE__ */ __name(async (intent, transfer, config) => {
|
|
330
|
+
const { srcAddress, srcAmount, destAddress } = intent;
|
|
331
|
+
const [calculatedIntent, calculatedTransfer] = await generateBridgeEstimate(srcAddress, srcAmount, destAddress, config);
|
|
332
|
+
if (isUndefined2(calculatedIntent) || isUndefined2(calculatedTransfer)) return false;
|
|
333
|
+
const { nonce: expectedIntentNonce, ...expectedIntentStatic } = calculatedIntent;
|
|
334
|
+
const { nonce: actualIntentNonce, ...actualIntentStatic } = intent;
|
|
335
|
+
if (await PayloadBuilder3.dataHash(expectedIntentStatic) !== await PayloadBuilder3.dataHash(actualIntentStatic)) return false;
|
|
336
|
+
const { epoch: expectedTransferEpoch, ...expectedTransferStatic } = calculatedTransfer;
|
|
337
|
+
const { epoch: actualTransferEpoch, ...actualTransferStatic } = transfer;
|
|
338
|
+
if (await PayloadBuilder3.dataHash(expectedTransferStatic) !== await PayloadBuilder3.dataHash(actualTransferStatic)) return false;
|
|
339
|
+
return true;
|
|
340
|
+
}, "validateBridgeEstimateExact");
|
|
341
|
+
|
|
342
|
+
// src/validation/validateBridgeTransaction.ts
|
|
343
|
+
import { asAddress as asAddress4, isDefined as isDefined6 } from "@xylabs/sdk-js";
|
|
344
|
+
import { addressesContains, BoundWitnessValidator, payloadHashesContainsAll } from "@xyo-network/boundwitness-validator";
|
|
345
|
+
import { PayloadBuilder as PayloadBuilder4 } from "@xyo-network/sdk-js";
|
|
346
|
+
var validateBridgeTransaction = /* @__PURE__ */ __name(async (signedTxBw, intent, transfer, config) => {
|
|
347
|
+
const { srcAddress } = intent;
|
|
348
|
+
const chainId = getXl1ChainId(config);
|
|
349
|
+
if (signedTxBw.chain !== chainId) return false;
|
|
350
|
+
const errors = await new BoundWitnessValidator(signedTxBw).validate();
|
|
351
|
+
if (isDefined6(errors) && errors.length > 0) return false;
|
|
352
|
+
const sender = asAddress4(srcAddress, true);
|
|
353
|
+
if (!addressesContains(signedTxBw, sender)) return false;
|
|
354
|
+
const hashes = await PayloadBuilder4.hashes([
|
|
355
|
+
intent,
|
|
356
|
+
transfer
|
|
357
|
+
]);
|
|
358
|
+
if (!payloadHashesContainsAll(signedTxBw, hashes)) return false;
|
|
359
|
+
return true;
|
|
360
|
+
}, "validateBridgeTransaction");
|
|
361
|
+
|
|
362
|
+
// src/validation/validateSufficientLiquiditySourceAllowance.ts
|
|
363
|
+
import { assertEx as assertEx7, hexToBigInt as hexToBigInt3 } from "@xylabs/sdk-js";
|
|
364
|
+
import { isBridgeIntent } from "@xyo-network/xl1-sdk";
|
|
133
365
|
var validateSufficientLiquiditySourceAllowance = /* @__PURE__ */ __name(async (tx, bridgeableToken, bridge, logger) => {
|
|
134
|
-
const bridgeIntent =
|
|
135
|
-
const amount =
|
|
366
|
+
const bridgeIntent = assertEx7(tx[1].find(isBridgeIntent), () => "No bridge intent found");
|
|
367
|
+
const amount = hexToBigInt3(bridgeIntent.destAmount);
|
|
136
368
|
const liquiditySourceAddress = await bridge.liquiditySource();
|
|
137
369
|
const bridgeAddress = await bridge.getAddress();
|
|
138
370
|
const remainingAllowance = await bridgeableToken.allowance(liquiditySourceAddress, bridgeAddress);
|
|
@@ -140,23 +372,23 @@ var validateSufficientLiquiditySourceAllowance = /* @__PURE__ */ __name(async (t
|
|
|
140
372
|
return remainingAllowance >= amount;
|
|
141
373
|
}, "validateSufficientLiquiditySourceAllowance");
|
|
142
374
|
|
|
143
|
-
// src/
|
|
144
|
-
import { assertEx as
|
|
145
|
-
import { isBridgeIntent as
|
|
375
|
+
// src/validation/validateSufficientLiquiditySourceBalance.ts
|
|
376
|
+
import { assertEx as assertEx8, hexToBigInt as hexToBigInt4 } from "@xylabs/sdk-js";
|
|
377
|
+
import { isBridgeIntent as isBridgeIntent2 } from "@xyo-network/xl1-sdk";
|
|
146
378
|
var validateSufficientLiquiditySourceBalance = /* @__PURE__ */ __name(async (tx, bridgeableToken, bridge, logger) => {
|
|
147
|
-
const bridgeIntent =
|
|
148
|
-
const amount =
|
|
379
|
+
const bridgeIntent = assertEx8(tx[1].find(isBridgeIntent2), () => "No bridge intent found");
|
|
380
|
+
const amount = hexToBigInt4(bridgeIntent.destAmount);
|
|
149
381
|
const liquiditySourceAddress = await bridge.liquiditySource();
|
|
150
382
|
const balance = await bridgeableToken.balanceOf(liquiditySourceAddress);
|
|
151
383
|
await logger?.log(`Remaining balance: ${balance.toString()}`);
|
|
152
384
|
return balance >= amount;
|
|
153
385
|
}, "validateSufficientLiquiditySourceBalance");
|
|
154
386
|
|
|
155
|
-
// src/
|
|
156
|
-
import { assertEx as
|
|
387
|
+
// src/validation/validateSufficientRunnerEthBalanceForGas.ts
|
|
388
|
+
import { assertEx as assertEx9 } from "@xylabs/sdk-js";
|
|
157
389
|
var DEFAULT_GAS_BUFFER_BPS = 2000n;
|
|
158
390
|
var validateSufficientRunnerEthBalanceForGas = /* @__PURE__ */ __name(async (preparedTx, wallet, logger, bufferBps = DEFAULT_GAS_BUFFER_BPS) => {
|
|
159
|
-
const provider =
|
|
391
|
+
const provider = assertEx9(wallet.provider, () => "Wallet provider is not defined");
|
|
160
392
|
const feeData = await provider.getFeeData();
|
|
161
393
|
const perGas = feeData.maxFeePerGas ?? feeData.gasPrice;
|
|
162
394
|
if (perGas == null) {
|
|
@@ -176,17 +408,30 @@ var validateSufficientRunnerEthBalanceForGas = /* @__PURE__ */ __name(async (pre
|
|
|
176
408
|
return balance >= required;
|
|
177
409
|
}, "validateSufficientRunnerEthBalanceForGas");
|
|
178
410
|
|
|
411
|
+
// src/validation/validateSufficientXL1SourceAddressBalance.ts
|
|
412
|
+
import { asAddress as asAddress5, assertEx as assertEx10, hexToBigInt as hexToBigInt5 } from "@xylabs/sdk-js";
|
|
413
|
+
var validateSufficientXL1SourceAddressBalance = /* @__PURE__ */ __name(async (bridgeIntent, gateway, config, logger) => {
|
|
414
|
+
const viewer = assertEx10(gateway.connection.viewer, () => "Gateway connection does not have a viewer");
|
|
415
|
+
const { srcAddress, srcAmount, destAddress } = bridgeIntent;
|
|
416
|
+
const srcAddressBranded = asAddress5(srcAddress, () => `Invalid source address in bridge intent: ${srcAddress}`);
|
|
417
|
+
const [_, calculatedTransfer] = await generateBridgeEstimate(srcAddress, srcAmount, destAddress, config);
|
|
418
|
+
const totalAmount = Object.values(calculatedTransfer.transfers).reduce((acc, transfer) => acc + hexToBigInt5(transfer), 0n);
|
|
419
|
+
const accountBalance = await viewer.account.balance.accountBalance(srcAddressBranded);
|
|
420
|
+
await logger?.log(`Account balance for ${srcAddressBranded}: ${accountBalance.toString()}`);
|
|
421
|
+
return accountBalance >= totalAmount;
|
|
422
|
+
}, "validateSufficientXL1SourceAddressBalance");
|
|
423
|
+
|
|
179
424
|
// src/queue/workers/EthTransactionPreparation.ts
|
|
180
425
|
var name2 = "Prepare ETH Transaction";
|
|
181
426
|
var queueName2 = "eth-tx-prepare";
|
|
182
427
|
var createWorker2 = /* @__PURE__ */ __name((connection2, telemetry2, services) => {
|
|
183
|
-
const bridge =
|
|
184
|
-
const bridgeableToken =
|
|
185
|
-
const stateMap =
|
|
186
|
-
const wallet =
|
|
428
|
+
const bridge = assertEx11(services?.bridge, () => "bridge service not provided");
|
|
429
|
+
const bridgeableToken = assertEx11(services?.bridgeableToken, () => "bridgeableToken service not provided");
|
|
430
|
+
const stateMap = assertEx11(services?.ethTxStateMap, () => "ethTxStateMap service not provided");
|
|
431
|
+
const wallet = assertEx11(services?.wallet, () => "wallet service not provided");
|
|
187
432
|
const worker = new Worker2(queueName2, async (job) => {
|
|
188
433
|
const { tx } = job.data;
|
|
189
|
-
const hash = await
|
|
434
|
+
const hash = await PayloadBuilder5.hash(tx[0]);
|
|
190
435
|
await job.log(`[${hash}] preparing ETH transaction`);
|
|
191
436
|
await job.log(`[${hash}] validating liquiditySource has sufficient allowance`);
|
|
192
437
|
if (!await validateSufficientLiquiditySourceAllowance(tx, bridgeableToken, bridge, job)) {
|
|
@@ -199,11 +444,11 @@ var createWorker2 = /* @__PURE__ */ __name((connection2, telemetry2, services) =
|
|
|
199
444
|
}
|
|
200
445
|
await job.log(`[${hash}] validated liquiditySource has sufficient balance`);
|
|
201
446
|
await job.log(`[${hash}] building ETH transaction`);
|
|
202
|
-
const bridgeIntent =
|
|
203
|
-
const amount =
|
|
447
|
+
const bridgeIntent = assertEx11(tx[1].find(isBridgeIntent3), () => "No bridge intent found");
|
|
448
|
+
const amount = hexToBigInt6(bridgeIntent.destAmount);
|
|
204
449
|
const srcAddress = getAddress(bridgeIntent.srcAddress);
|
|
205
450
|
const destAddress = getAddress(bridgeIntent.destAddress);
|
|
206
|
-
const nonce =
|
|
451
|
+
const nonce = hexToBigInt6(await PayloadBuilder5.hash(tx[0]));
|
|
207
452
|
const preparedTx = await bridge.getFunction("bridgeFromRemote").populateTransaction(srcAddress, destAddress, amount, nonce);
|
|
208
453
|
await job.log(`[${hash}] built ETH transaction`);
|
|
209
454
|
await job.log(`[${hash}] validating tx runner has sufficient ETH for gas`);
|
|
@@ -220,7 +465,8 @@ var createWorker2 = /* @__PURE__ */ __name((connection2, telemetry2, services) =
|
|
|
220
465
|
return {};
|
|
221
466
|
}, {
|
|
222
467
|
connection: connection2,
|
|
223
|
-
telemetry: telemetry2
|
|
468
|
+
telemetry: telemetry2,
|
|
469
|
+
prefix
|
|
224
470
|
});
|
|
225
471
|
worker.on("failed", (job, err) => {
|
|
226
472
|
console.error(`[${name2}] Job ${job?.id} failed:`, err.message);
|
|
@@ -236,41 +482,64 @@ var EthTransactionPreparation = {
|
|
|
236
482
|
};
|
|
237
483
|
|
|
238
484
|
// src/queue/workers/EthTransactionSubmission.ts
|
|
239
|
-
import { assertEx as
|
|
240
|
-
import { PayloadBuilder as
|
|
485
|
+
import { assertEx as assertEx13, isDefined as isDefined7 } from "@xylabs/sdk-js";
|
|
486
|
+
import { PayloadBuilder as PayloadBuilder7 } from "@xyo-network/sdk-js";
|
|
241
487
|
import { Worker as Worker3 } from "bullmq";
|
|
488
|
+
|
|
489
|
+
// src/queue/workers/util/submitEthTransaction.ts
|
|
490
|
+
import { assertEx as assertEx12, hexToBigInt as hexToBigInt7, toEthAddress } from "@xylabs/sdk-js";
|
|
491
|
+
import { PayloadBuilder as PayloadBuilder6 } from "@xyo-network/sdk-js";
|
|
492
|
+
import { isBridgeIntent as isBridgeIntent4 } from "@xyo-network/xl1-sdk";
|
|
493
|
+
var submitEthTransaction = /* @__PURE__ */ __name(async (tx, bridgeableToken, bridge, wallet) => {
|
|
494
|
+
const xl1Transaction = assertEx12(tx[0], () => "No corresponding XL1 transaction found");
|
|
495
|
+
const bridgeIntent = assertEx12(tx[1].find(isBridgeIntent4), () => "No bridge intent found");
|
|
496
|
+
const srcAddress = toEthAddress(bridgeIntent.srcAddress);
|
|
497
|
+
const destAddress = toEthAddress(bridgeIntent.destAddress);
|
|
498
|
+
const amount = hexToBigInt7(bridgeIntent.destAmount);
|
|
499
|
+
const nonce = hexToBigInt7(await PayloadBuilder6.hash(xl1Transaction));
|
|
500
|
+
const bridgeTx = await bridge.connect(wallet).bridgeFromRemote(srcAddress, destAddress, amount, nonce);
|
|
501
|
+
const receipt = await bridgeTx.wait(1);
|
|
502
|
+
return receipt?.hash;
|
|
503
|
+
}, "submitEthTransaction");
|
|
504
|
+
|
|
505
|
+
// src/queue/workers/util/submitXl1Transaction.ts
|
|
506
|
+
import { isAllowedBlockPayload } from "@xyo-network/xl1-sdk";
|
|
507
|
+
var submitXl1Transaction = /* @__PURE__ */ __name(async (preparedTx, gateway) => {
|
|
508
|
+
const offChainPayloads = preparedTx[1].filter((p) => !isAllowedBlockPayload(p));
|
|
509
|
+
const result = await gateway.addTransactionToChain(preparedTx, offChainPayloads);
|
|
510
|
+
return result;
|
|
511
|
+
}, "submitXl1Transaction");
|
|
512
|
+
|
|
513
|
+
// src/queue/workers/EthTransactionSubmission.ts
|
|
242
514
|
var name3 = "Submit ETH Transaction";
|
|
243
515
|
var queueName3 = "eth-tx-submit";
|
|
244
516
|
var createWorker3 = /* @__PURE__ */ __name((connection2, telemetry2, services) => {
|
|
245
|
-
const bridge =
|
|
246
|
-
const bridgeableToken =
|
|
247
|
-
const wallet =
|
|
248
|
-
const stateMap =
|
|
517
|
+
const bridge = assertEx13(services?.bridge, () => "bridge service not provided");
|
|
518
|
+
const bridgeableToken = assertEx13(services?.bridgeableToken, () => "bridgeableToken service not provided");
|
|
519
|
+
const wallet = assertEx13(services?.wallet, () => "wallet service not provided");
|
|
520
|
+
const stateMap = assertEx13(services?.ethTxStateMap, () => "ethTxStateMap service not provided");
|
|
249
521
|
const worker = new Worker3(queueName3, async (job) => {
|
|
250
522
|
const { tx } = job.data;
|
|
251
|
-
const hash = await
|
|
252
|
-
const state =
|
|
523
|
+
const hash = await PayloadBuilder7.hash(tx[0]);
|
|
524
|
+
const state = assertEx13(await stateMap.get(hash), () => `[${hash}] state not found`);
|
|
253
525
|
const { submissionHash: existingSubmissionHash } = state;
|
|
254
|
-
if (
|
|
526
|
+
if (isDefined7(existingSubmissionHash)) {
|
|
255
527
|
await job.log(`[${hash}] Tx already submitted with submission response hash ${existingSubmissionHash}`);
|
|
256
528
|
return {
|
|
257
529
|
submissionHash: existingSubmissionHash
|
|
258
530
|
};
|
|
259
531
|
}
|
|
260
532
|
await job.log(`[${hash}] Submitting ETH tx`);
|
|
261
|
-
const submissionHash =
|
|
533
|
+
const submissionHash = assertEx13(await submitEthTransaction(tx, bridgeableToken, bridge, wallet), () => `[${hash}] submissionHash not found in receipt`);
|
|
262
534
|
await job.log(`[${hash}] Submitted ETH tx and received submission response hash ${submissionHash}`);
|
|
263
|
-
await job.log(`[${hash}] Storing ETH submissionHash`);
|
|
264
|
-
state.submissionHash = submissionHash;
|
|
265
|
-
await stateMap.set(hash, state);
|
|
266
|
-
await job.log(`[${hash}] Stored ETH submissionHash`);
|
|
267
535
|
return {
|
|
268
536
|
submissionHash
|
|
269
537
|
};
|
|
270
538
|
}, {
|
|
271
539
|
connection: connection2,
|
|
272
540
|
telemetry: telemetry2,
|
|
273
|
-
concurrency: 1
|
|
541
|
+
concurrency: 1,
|
|
542
|
+
prefix
|
|
274
543
|
});
|
|
275
544
|
worker.on("failed", (job, err) => {
|
|
276
545
|
console.error(`[${name3}] Job ${job?.id} failed:`, err.message);
|
|
@@ -285,18 +554,41 @@ var EthTransactionSubmission = {
|
|
|
285
554
|
queueName: queueName3
|
|
286
555
|
};
|
|
287
556
|
|
|
288
|
-
// src/queue/workers/
|
|
557
|
+
// src/queue/workers/EthTransactionSubmissionStorage.ts
|
|
558
|
+
import { assertEx as assertEx14, isDefined as isDefined8 } from "@xylabs/sdk-js";
|
|
559
|
+
import { PayloadBuilder as PayloadBuilder8 } from "@xyo-network/sdk-js";
|
|
289
560
|
import { Worker as Worker4 } from "bullmq";
|
|
290
|
-
var name4 = "
|
|
291
|
-
var queueName4 = "
|
|
292
|
-
var createWorker4 = /* @__PURE__ */ __name((connection2, telemetry2) => {
|
|
561
|
+
var name4 = "Store ETH Transaction Submission";
|
|
562
|
+
var queueName4 = "eth-tx-store-submission";
|
|
563
|
+
var createWorker4 = /* @__PURE__ */ __name((connection2, telemetry2, services) => {
|
|
564
|
+
const stateMap = assertEx14(services?.ethTxStateMap, () => "ethTxStateMap service not provided");
|
|
293
565
|
const worker = new Worker4(queueName4, async (job) => {
|
|
294
|
-
|
|
295
|
-
await
|
|
296
|
-
|
|
566
|
+
const { tx } = job.data;
|
|
567
|
+
const hash = await PayloadBuilder8.hash(tx[0]);
|
|
568
|
+
const state = assertEx14(await stateMap.get(hash), () => `[${hash}] state not found`);
|
|
569
|
+
const { submissionHash: existingSubmissionHash } = state;
|
|
570
|
+
if (isDefined8(existingSubmissionHash)) {
|
|
571
|
+
await job.log(`[${hash}] submissionHash already stored as ${existingSubmissionHash}`);
|
|
572
|
+
return {
|
|
573
|
+
submissionHash: existingSubmissionHash
|
|
574
|
+
};
|
|
575
|
+
}
|
|
576
|
+
const childrenValues = await job.getChildrenValues();
|
|
577
|
+
const jobKey = `${prefix}:${EthTransactionSubmission.queueName}:${hash}`;
|
|
578
|
+
const childValues = childrenValues?.[jobKey];
|
|
579
|
+
const submissionHash = childValues?.submissionHash;
|
|
580
|
+
const resolvedSubmissionHash = assertEx14(submissionHash, () => `[${hash}] child submissionHash not found in children values`);
|
|
581
|
+
await job.log(`[${hash}] Storing ETH submissionHash`);
|
|
582
|
+
state.submissionHash = resolvedSubmissionHash;
|
|
583
|
+
await stateMap.set(hash, state);
|
|
584
|
+
await job.log(`[${hash}] Stored ETH submissionHash`);
|
|
585
|
+
return {
|
|
586
|
+
submissionHash: resolvedSubmissionHash
|
|
587
|
+
};
|
|
297
588
|
}, {
|
|
298
589
|
connection: connection2,
|
|
299
|
-
telemetry: telemetry2
|
|
590
|
+
telemetry: telemetry2,
|
|
591
|
+
prefix
|
|
300
592
|
});
|
|
301
593
|
worker.on("failed", (job, err) => {
|
|
302
594
|
console.error(`[${name4}] Job ${job?.id} failed:`, err.message);
|
|
@@ -305,34 +597,62 @@ var createWorker4 = /* @__PURE__ */ __name((connection2, telemetry2) => {
|
|
|
305
597
|
console.error(`[${name4}] Worker error:`, err);
|
|
306
598
|
});
|
|
307
599
|
}, "createWorker");
|
|
308
|
-
var
|
|
600
|
+
var EthTransactionSubmissionStorage = {
|
|
309
601
|
createWorker: createWorker4,
|
|
310
602
|
name: name4,
|
|
311
603
|
queueName: queueName4
|
|
312
604
|
};
|
|
313
605
|
|
|
314
|
-
// src/queue/workers/
|
|
315
|
-
import {
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
var
|
|
319
|
-
var queueName5 = "xl1-tx-monitor";
|
|
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");
|
|
606
|
+
// src/queue/workers/Xl1ToEthBridgeParent.ts
|
|
607
|
+
import { Worker as Worker5 } from "bullmq";
|
|
608
|
+
var name5 = "Bridge XL1 to Ethereum";
|
|
609
|
+
var queueName5 = "xl1-to-eth-bridge";
|
|
610
|
+
var createWorker5 = /* @__PURE__ */ __name((connection2, telemetry2) => {
|
|
323
611
|
const worker = new Worker5(queueName5, async (job) => {
|
|
612
|
+
await job.log(`[${job.name}] start`);
|
|
613
|
+
await job.log(`[${job.name}] done`);
|
|
614
|
+
return {};
|
|
615
|
+
}, {
|
|
616
|
+
connection: connection2,
|
|
617
|
+
telemetry: telemetry2,
|
|
618
|
+
prefix
|
|
619
|
+
});
|
|
620
|
+
worker.on("failed", (job, err) => {
|
|
621
|
+
console.error(`[${name5}] Job ${job?.id} failed:`, err.message);
|
|
622
|
+
});
|
|
623
|
+
worker.on("error", (err) => {
|
|
624
|
+
console.error(`[${name5}] Worker error:`, err);
|
|
625
|
+
});
|
|
626
|
+
}, "createWorker");
|
|
627
|
+
var Xl1ToEthBridgeParent = {
|
|
628
|
+
createWorker: createWorker5,
|
|
629
|
+
name: name5,
|
|
630
|
+
queueName: queueName5
|
|
631
|
+
};
|
|
632
|
+
|
|
633
|
+
// src/queue/workers/Xl1TransactionMonitor.ts
|
|
634
|
+
import { assertEx as assertEx15, isDefined as isDefined9, isNull } from "@xylabs/sdk-js";
|
|
635
|
+
import { PayloadBuilder as PayloadBuilder9 } from "@xyo-network/sdk-js";
|
|
636
|
+
import { UnrecoverableError, Worker as Worker6 } from "bullmq";
|
|
637
|
+
var name6 = "Monitor Submitted XL1 Transaction";
|
|
638
|
+
var queueName6 = "xl1-tx-monitor";
|
|
639
|
+
var createWorker6 = /* @__PURE__ */ __name((connection2, telemetry2, services) => {
|
|
640
|
+
const gateway = assertEx15(services?.gateway, () => "gateway service not provided");
|
|
641
|
+
const stateMap = assertEx15(services?.xl1TxStateMap, () => "xl1TxStateMap service not provided");
|
|
642
|
+
const viewer = assertEx15(gateway.connection.viewer, () => "viewer not defined on gateway");
|
|
643
|
+
const worker = new Worker6(queueName6, async (job) => {
|
|
324
644
|
const { tx } = job.data;
|
|
325
|
-
const hash = await
|
|
326
|
-
const
|
|
327
|
-
const
|
|
328
|
-
const submissionHash = assertEx8(state?.submissionHash, () => `[${hash}] submissionHash not found`);
|
|
645
|
+
const hash = await PayloadBuilder9.hash(tx[0]);
|
|
646
|
+
const state = assertEx15(await stateMap.get(hash), () => `[${hash}] state not found`);
|
|
647
|
+
const submissionHash = assertEx15(state.submissionHash, () => `[${hash}] submissionHash not found`);
|
|
329
648
|
await job.log(`[${hash}] Checking for XL1 transaction inclusion on chain`);
|
|
330
|
-
const foundTx = await viewer.
|
|
331
|
-
if (
|
|
649
|
+
const foundTx = await viewer.transaction.byHash(submissionHash);
|
|
650
|
+
if (isDefined9(foundTx) && !isNull(foundTx)) {
|
|
332
651
|
await job.log(`[${hash}] Found transaction on chain`);
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
652
|
+
const submissionHash2 = await PayloadBuilder9.hash(foundTx[0]);
|
|
653
|
+
return {
|
|
654
|
+
submissionHash: submissionHash2
|
|
655
|
+
};
|
|
336
656
|
}
|
|
337
657
|
const currentBlockNumber = await viewer.currentBlockNumber();
|
|
338
658
|
if (tx[0].exp < currentBlockNumber) {
|
|
@@ -343,32 +663,33 @@ var createWorker5 = /* @__PURE__ */ __name((connection2, telemetry2, services) =
|
|
|
343
663
|
throw new Error(`[${hash}] Transaction not yet included`);
|
|
344
664
|
}, {
|
|
345
665
|
connection: connection2,
|
|
346
|
-
telemetry: telemetry2
|
|
666
|
+
telemetry: telemetry2,
|
|
667
|
+
prefix
|
|
347
668
|
});
|
|
348
669
|
worker.on("failed", (job, err) => {
|
|
349
|
-
console.error(`[${
|
|
670
|
+
console.error(`[${name6}] Job ${job?.id} failed:`, err.message);
|
|
350
671
|
});
|
|
351
672
|
worker.on("error", (err) => {
|
|
352
|
-
console.error(`[${
|
|
673
|
+
console.error(`[${name6}] Worker error:`, err);
|
|
353
674
|
});
|
|
354
675
|
}, "createWorker");
|
|
355
676
|
var Xl1TransactionMonitor = {
|
|
356
|
-
createWorker:
|
|
357
|
-
name:
|
|
358
|
-
queueName:
|
|
677
|
+
createWorker: createWorker6,
|
|
678
|
+
name: name6,
|
|
679
|
+
queueName: queueName6
|
|
359
680
|
};
|
|
360
681
|
|
|
361
682
|
// src/queue/workers/Xl1TransactionPreparation.ts
|
|
362
|
-
import { assertEx as
|
|
363
|
-
import { PayloadBuilder as
|
|
364
|
-
import { Worker as
|
|
365
|
-
var
|
|
366
|
-
var
|
|
367
|
-
var
|
|
368
|
-
const stateMap =
|
|
369
|
-
const worker = new
|
|
683
|
+
import { assertEx as assertEx16 } from "@xylabs/sdk-js";
|
|
684
|
+
import { PayloadBuilder as PayloadBuilder10 } from "@xyo-network/sdk-js";
|
|
685
|
+
import { Worker as Worker7 } from "bullmq";
|
|
686
|
+
var name7 = "Prepare XL1 Transaction";
|
|
687
|
+
var queueName7 = "xl1-tx-prepare";
|
|
688
|
+
var createWorker7 = /* @__PURE__ */ __name((connection2, telemetry2, services) => {
|
|
689
|
+
const stateMap = assertEx16(services?.xl1TxStateMap, () => "xl1TxStateMap service not provided");
|
|
690
|
+
const worker = new Worker7(queueName7, async (job) => {
|
|
370
691
|
const { tx } = job.data;
|
|
371
|
-
const hash = await
|
|
692
|
+
const hash = await PayloadBuilder10.hash(tx[0]);
|
|
372
693
|
await job.log(`[${hash}] preparing XL1 transaction`);
|
|
373
694
|
const preparedTx = tx;
|
|
374
695
|
await job.log(`[${hash}] storing XL1 preparedTx`);
|
|
@@ -382,37 +703,38 @@ var createWorker6 = /* @__PURE__ */ __name((connection2, telemetry2, services) =
|
|
|
382
703
|
};
|
|
383
704
|
}, {
|
|
384
705
|
connection: connection2,
|
|
385
|
-
telemetry: telemetry2
|
|
706
|
+
telemetry: telemetry2,
|
|
707
|
+
prefix
|
|
386
708
|
});
|
|
387
709
|
worker.on("failed", (job, err) => {
|
|
388
|
-
console.error(`[${
|
|
710
|
+
console.error(`[${name7}] Job ${job?.id} failed:`, err.message);
|
|
389
711
|
});
|
|
390
712
|
worker.on("error", (err) => {
|
|
391
|
-
console.error(`[${
|
|
713
|
+
console.error(`[${name7}] Worker error:`, err);
|
|
392
714
|
});
|
|
393
715
|
}, "createWorker");
|
|
394
716
|
var Xl1TransactionPreparation = {
|
|
395
|
-
createWorker:
|
|
396
|
-
name:
|
|
397
|
-
queueName:
|
|
717
|
+
createWorker: createWorker7,
|
|
718
|
+
name: name7,
|
|
719
|
+
queueName: queueName7
|
|
398
720
|
};
|
|
399
721
|
|
|
400
722
|
// src/queue/workers/Xl1TransactionSubmission.ts
|
|
401
|
-
import { assertEx as
|
|
402
|
-
import { PayloadBuilder as
|
|
403
|
-
import { Worker as
|
|
404
|
-
var
|
|
405
|
-
var
|
|
406
|
-
var
|
|
407
|
-
const gateway =
|
|
408
|
-
const stateMap =
|
|
409
|
-
const worker = new
|
|
723
|
+
import { assertEx as assertEx17, isDefined as isDefined10 } from "@xylabs/sdk-js";
|
|
724
|
+
import { PayloadBuilder as PayloadBuilder11 } from "@xyo-network/sdk-js";
|
|
725
|
+
import { Worker as Worker8 } from "bullmq";
|
|
726
|
+
var name8 = "Submit XL1 Transaction";
|
|
727
|
+
var queueName8 = "xl1-tx-submit";
|
|
728
|
+
var createWorker8 = /* @__PURE__ */ __name((connection2, telemetry2, services) => {
|
|
729
|
+
const gateway = assertEx17(services?.gateway, () => "gateway service not provided");
|
|
730
|
+
const stateMap = assertEx17(services?.xl1TxStateMap, () => "xl1TxStateMap service not provided");
|
|
731
|
+
const worker = new Worker8(queueName8, async (job) => {
|
|
410
732
|
const { tx } = job.data;
|
|
411
|
-
const hash = await
|
|
412
|
-
const state =
|
|
413
|
-
const preparedTx =
|
|
733
|
+
const hash = await PayloadBuilder11.hash(tx[0]);
|
|
734
|
+
const state = assertEx17(await stateMap.get(hash), () => `[${hash}] state not found`);
|
|
735
|
+
const preparedTx = assertEx17(state?.preparedTx, () => `[${hash}] preparedTx not found`);
|
|
414
736
|
const { submissionHash: existingSubmissionHash } = state;
|
|
415
|
-
if (
|
|
737
|
+
if (isDefined10(existingSubmissionHash)) {
|
|
416
738
|
await job.log(`[${hash}] Tx already submitted with submission response hash ${existingSubmissionHash}`);
|
|
417
739
|
return {
|
|
418
740
|
submissionHash: existingSubmissionHash
|
|
@@ -421,34 +743,82 @@ var createWorker7 = /* @__PURE__ */ __name((connection2, telemetry2, services) =
|
|
|
421
743
|
await job.log(`[${hash}] Submitting XL1 tx`);
|
|
422
744
|
const [submissionHash] = await submitXl1Transaction(preparedTx, gateway);
|
|
423
745
|
await job.log(`[${hash}] Submitted XL1 tx`);
|
|
746
|
+
return {
|
|
747
|
+
submissionHash
|
|
748
|
+
};
|
|
749
|
+
}, {
|
|
750
|
+
connection: connection2,
|
|
751
|
+
telemetry: telemetry2,
|
|
752
|
+
prefix
|
|
753
|
+
});
|
|
754
|
+
worker.on("failed", (job, err) => {
|
|
755
|
+
console.error(`[${name8}] Job ${job?.id} failed:`, err.message);
|
|
756
|
+
});
|
|
757
|
+
worker.on("error", (err) => {
|
|
758
|
+
console.error(`[${name8}] Worker error:`, err);
|
|
759
|
+
});
|
|
760
|
+
}, "createWorker");
|
|
761
|
+
var Xl1TransactionSubmission = {
|
|
762
|
+
createWorker: createWorker8,
|
|
763
|
+
name: name8,
|
|
764
|
+
queueName: queueName8
|
|
765
|
+
};
|
|
766
|
+
|
|
767
|
+
// src/queue/workers/Xl1TransactionSubmissionStorage.ts
|
|
768
|
+
import { assertEx as assertEx18, isDefined as isDefined11 } from "@xylabs/sdk-js";
|
|
769
|
+
import { PayloadBuilder as PayloadBuilder12 } from "@xyo-network/sdk-js";
|
|
770
|
+
import { Worker as Worker9 } from "bullmq";
|
|
771
|
+
var name9 = "Store XL1 Transaction Submission";
|
|
772
|
+
var queueName9 = "xl1-tx-store-submission";
|
|
773
|
+
var createWorker9 = /* @__PURE__ */ __name((connection2, telemetry2, services) => {
|
|
774
|
+
const stateMap = assertEx18(services?.xl1TxStateMap, () => "xl1TxStateMap service not provided");
|
|
775
|
+
const worker = new Worker9(queueName9, async (job) => {
|
|
776
|
+
const { tx } = job.data;
|
|
777
|
+
const hash = await PayloadBuilder12.hash(tx[0]);
|
|
778
|
+
const state = assertEx18(await stateMap.get(hash), () => `[${hash}] state not found`);
|
|
779
|
+
const { submissionHash: existingSubmissionHash } = state;
|
|
780
|
+
if (isDefined11(existingSubmissionHash)) {
|
|
781
|
+
await job.log(`[${hash}] submissionHash already stored as ${existingSubmissionHash}`);
|
|
782
|
+
return {
|
|
783
|
+
submissionHash: existingSubmissionHash
|
|
784
|
+
};
|
|
785
|
+
}
|
|
786
|
+
const childrenValues = await job.getChildrenValues();
|
|
787
|
+
const jobKey = `${prefix}:${Xl1TransactionSubmission.queueName}:${hash}`;
|
|
788
|
+
const childValues = childrenValues?.[jobKey];
|
|
789
|
+
const submissionHash = childValues?.submissionHash;
|
|
790
|
+
const resolvedSubmissionHash = assertEx18(submissionHash, () => `[${hash}] child submissionHash not found in children values`);
|
|
424
791
|
await job.log(`[${hash}] Storing XL1 submissionHash`);
|
|
425
|
-
state.submissionHash =
|
|
792
|
+
state.submissionHash = resolvedSubmissionHash;
|
|
426
793
|
await stateMap.set(hash, state);
|
|
427
794
|
await job.log(`[${hash}] Stored XL1 submissionHash`);
|
|
428
795
|
return {
|
|
429
|
-
submissionHash
|
|
796
|
+
submissionHash: resolvedSubmissionHash
|
|
430
797
|
};
|
|
431
798
|
}, {
|
|
432
799
|
connection: connection2,
|
|
433
|
-
telemetry: telemetry2
|
|
800
|
+
telemetry: telemetry2,
|
|
801
|
+
prefix
|
|
434
802
|
});
|
|
435
803
|
worker.on("failed", (job, err) => {
|
|
436
|
-
console.error(`[${
|
|
804
|
+
console.error(`[${name9}] Job ${job?.id} failed:`, err.message);
|
|
437
805
|
});
|
|
438
806
|
worker.on("error", (err) => {
|
|
439
|
-
console.error(`[${
|
|
807
|
+
console.error(`[${name9}] Worker error:`, err);
|
|
440
808
|
});
|
|
441
809
|
}, "createWorker");
|
|
442
|
-
var
|
|
443
|
-
createWorker:
|
|
444
|
-
name:
|
|
445
|
-
queueName:
|
|
810
|
+
var Xl1TransactionSubmissionStorage = {
|
|
811
|
+
createWorker: createWorker9,
|
|
812
|
+
name: name9,
|
|
813
|
+
queueName: queueName9
|
|
446
814
|
};
|
|
447
815
|
|
|
448
816
|
// src/queue/flows/createXl1ToEthBridgeJob.ts
|
|
817
|
+
import { PayloadBuilder as PayloadBuilder13 } from "@xyo-network/sdk-js";
|
|
449
818
|
var createXl1ToEthBridgeJob = /* @__PURE__ */ __name(async (flowProducer2, tx) => {
|
|
450
|
-
const jobId = await
|
|
819
|
+
const jobId = await PayloadBuilder13.hash(tx[0]);
|
|
451
820
|
const flow = await flowProducer2.add({
|
|
821
|
+
// Step 0 (runs first as parent job)
|
|
452
822
|
name: Xl1ToEthBridgeParent.name,
|
|
453
823
|
queueName: Xl1ToEthBridgeParent.queueName,
|
|
454
824
|
data: {
|
|
@@ -459,7 +829,7 @@ var createXl1ToEthBridgeJob = /* @__PURE__ */ __name(async (flowProducer2, tx) =
|
|
|
459
829
|
},
|
|
460
830
|
children: [
|
|
461
831
|
{
|
|
462
|
-
// Step
|
|
832
|
+
// Step 8
|
|
463
833
|
name: EthTransactionMonitor.name,
|
|
464
834
|
queueName: EthTransactionMonitor.queueName,
|
|
465
835
|
data: {
|
|
@@ -475,17 +845,25 @@ var createXl1ToEthBridgeJob = /* @__PURE__ */ __name(async (flowProducer2, tx) =
|
|
|
475
845
|
},
|
|
476
846
|
children: [
|
|
477
847
|
{
|
|
478
|
-
// Step
|
|
479
|
-
name:
|
|
480
|
-
queueName:
|
|
848
|
+
// Step 7
|
|
849
|
+
name: EthTransactionSubmissionStorage.name,
|
|
850
|
+
queueName: EthTransactionSubmissionStorage.queueName,
|
|
481
851
|
data: {
|
|
482
852
|
tx
|
|
483
853
|
},
|
|
854
|
+
opts: {
|
|
855
|
+
jobId,
|
|
856
|
+
attempts: 60,
|
|
857
|
+
backoff: {
|
|
858
|
+
type: "fixed",
|
|
859
|
+
delay: 5e3
|
|
860
|
+
}
|
|
861
|
+
},
|
|
484
862
|
children: [
|
|
485
863
|
{
|
|
486
|
-
// Step
|
|
487
|
-
name:
|
|
488
|
-
queueName:
|
|
864
|
+
// Step 6
|
|
865
|
+
name: EthTransactionSubmission.name,
|
|
866
|
+
queueName: EthTransactionSubmission.queueName,
|
|
489
867
|
data: {
|
|
490
868
|
tx
|
|
491
869
|
},
|
|
@@ -494,9 +872,9 @@ var createXl1ToEthBridgeJob = /* @__PURE__ */ __name(async (flowProducer2, tx) =
|
|
|
494
872
|
},
|
|
495
873
|
children: [
|
|
496
874
|
{
|
|
497
|
-
// Step
|
|
498
|
-
name:
|
|
499
|
-
queueName:
|
|
875
|
+
// Step 5
|
|
876
|
+
name: EthTransactionPreparation.name,
|
|
877
|
+
queueName: EthTransactionPreparation.queueName,
|
|
500
878
|
data: {
|
|
501
879
|
tx
|
|
502
880
|
},
|
|
@@ -510,26 +888,67 @@ var createXl1ToEthBridgeJob = /* @__PURE__ */ __name(async (flowProducer2, tx) =
|
|
|
510
888
|
},
|
|
511
889
|
children: [
|
|
512
890
|
{
|
|
513
|
-
// Step
|
|
514
|
-
name:
|
|
515
|
-
queueName:
|
|
891
|
+
// Step 4
|
|
892
|
+
name: Xl1TransactionMonitor.name,
|
|
893
|
+
queueName: Xl1TransactionMonitor.queueName,
|
|
516
894
|
data: {
|
|
517
895
|
tx
|
|
518
896
|
},
|
|
519
897
|
opts: {
|
|
520
|
-
jobId
|
|
898
|
+
jobId,
|
|
899
|
+
attempts: 60,
|
|
900
|
+
backoff: {
|
|
901
|
+
type: "fixed",
|
|
902
|
+
delay: 5e3
|
|
903
|
+
}
|
|
521
904
|
},
|
|
522
905
|
children: [
|
|
523
906
|
{
|
|
524
|
-
// Step
|
|
525
|
-
name:
|
|
526
|
-
queueName:
|
|
907
|
+
// Step 3
|
|
908
|
+
name: Xl1TransactionSubmissionStorage.name,
|
|
909
|
+
queueName: Xl1TransactionSubmissionStorage.queueName,
|
|
527
910
|
data: {
|
|
528
911
|
tx
|
|
529
912
|
},
|
|
530
913
|
opts: {
|
|
531
|
-
jobId
|
|
532
|
-
|
|
914
|
+
jobId,
|
|
915
|
+
attempts: 60,
|
|
916
|
+
backoff: {
|
|
917
|
+
type: "fixed",
|
|
918
|
+
delay: 5e3
|
|
919
|
+
}
|
|
920
|
+
},
|
|
921
|
+
children: [
|
|
922
|
+
{
|
|
923
|
+
// Step 2
|
|
924
|
+
name: Xl1TransactionSubmission.name,
|
|
925
|
+
queueName: Xl1TransactionSubmission.queueName,
|
|
926
|
+
data: {
|
|
927
|
+
tx
|
|
928
|
+
},
|
|
929
|
+
opts: {
|
|
930
|
+
jobId
|
|
931
|
+
},
|
|
932
|
+
children: [
|
|
933
|
+
{
|
|
934
|
+
// Step 1 (runs first as deepest child)
|
|
935
|
+
name: Xl1TransactionPreparation.name,
|
|
936
|
+
queueName: Xl1TransactionPreparation.queueName,
|
|
937
|
+
data: {
|
|
938
|
+
tx
|
|
939
|
+
},
|
|
940
|
+
opts: {
|
|
941
|
+
jobId,
|
|
942
|
+
attempts: 60,
|
|
943
|
+
backoff: {
|
|
944
|
+
type: "fixed",
|
|
945
|
+
delay: 5e3
|
|
946
|
+
}
|
|
947
|
+
}
|
|
948
|
+
}
|
|
949
|
+
]
|
|
950
|
+
}
|
|
951
|
+
]
|
|
533
952
|
}
|
|
534
953
|
]
|
|
535
954
|
}
|
|
@@ -546,15 +965,82 @@ var createXl1ToEthBridgeJob = /* @__PURE__ */ __name(async (flowProducer2, tx) =
|
|
|
546
965
|
return flow;
|
|
547
966
|
}, "createXl1ToEthBridgeJob");
|
|
548
967
|
|
|
968
|
+
// src/queue/getXl1ToEthQueueJobs.ts
|
|
969
|
+
var getStatusQueueJobs = /* @__PURE__ */ __name(async (queues, jobId) => {
|
|
970
|
+
const [ethTransactionMonitorJob, ethTransactionPreparationJob, ethTransactionSubmissionJob, xl1ToEthBridgeParentJob, xl1TransactionMonitorJob, xl1TransactionPreparationJob, xl1TransactionSubmissionJob, xl1TransactionSubmissionStorageJob] = await Promise.all([
|
|
971
|
+
queues.ethTransactionMonitor.getJob(jobId),
|
|
972
|
+
queues.ethTransactionPreparation.getJob(jobId),
|
|
973
|
+
queues.ethTransactionSubmission.getJob(jobId),
|
|
974
|
+
queues.xl1ToEthBridgeParent.getJob(jobId),
|
|
975
|
+
queues.xl1TransactionMonitor.getJob(jobId),
|
|
976
|
+
queues.xl1TransactionPreparation.getJob(jobId),
|
|
977
|
+
queues.xl1TransactionSubmission.getJob(jobId),
|
|
978
|
+
queues.xl1TransactionSubmissionStorage.getJob(jobId)
|
|
979
|
+
]);
|
|
980
|
+
return {
|
|
981
|
+
ethTransactionMonitorJob,
|
|
982
|
+
ethTransactionPreparationJob,
|
|
983
|
+
ethTransactionSubmissionJob,
|
|
984
|
+
xl1ToEthBridgeParentJob,
|
|
985
|
+
xl1TransactionMonitorJob,
|
|
986
|
+
xl1TransactionPreparationJob,
|
|
987
|
+
xl1TransactionSubmissionStorageJob,
|
|
988
|
+
xl1TransactionSubmissionJob
|
|
989
|
+
};
|
|
990
|
+
}, "getStatusQueueJobs");
|
|
991
|
+
|
|
992
|
+
// src/queue/getXl1ToEthQueues.ts
|
|
993
|
+
import { Queue } from "bullmq";
|
|
994
|
+
var xl1ToEthQueues;
|
|
995
|
+
var getXl1ToEthQueues = /* @__PURE__ */ __name((config) => {
|
|
996
|
+
if (xl1ToEthQueues) return xl1ToEthQueues;
|
|
997
|
+
const connection2 = getConnection(config);
|
|
998
|
+
xl1ToEthQueues = {
|
|
999
|
+
ethTransactionMonitor: new Queue(EthTransactionMonitor.queueName, {
|
|
1000
|
+
connection: connection2,
|
|
1001
|
+
prefix
|
|
1002
|
+
}),
|
|
1003
|
+
ethTransactionPreparation: new Queue(EthTransactionPreparation.queueName, {
|
|
1004
|
+
connection: connection2,
|
|
1005
|
+
prefix
|
|
1006
|
+
}),
|
|
1007
|
+
ethTransactionSubmission: new Queue(EthTransactionSubmission.queueName, {
|
|
1008
|
+
connection: connection2,
|
|
1009
|
+
prefix
|
|
1010
|
+
}),
|
|
1011
|
+
xl1ToEthBridgeParent: new Queue(Xl1ToEthBridgeParent.queueName, {
|
|
1012
|
+
connection: connection2,
|
|
1013
|
+
prefix
|
|
1014
|
+
}),
|
|
1015
|
+
xl1TransactionMonitor: new Queue(Xl1TransactionMonitor.queueName, {
|
|
1016
|
+
connection: connection2,
|
|
1017
|
+
prefix
|
|
1018
|
+
}),
|
|
1019
|
+
xl1TransactionPreparation: new Queue(Xl1TransactionPreparation.queueName, {
|
|
1020
|
+
connection: connection2,
|
|
1021
|
+
prefix
|
|
1022
|
+
}),
|
|
1023
|
+
xl1TransactionSubmission: new Queue(Xl1TransactionSubmission.queueName, {
|
|
1024
|
+
connection: connection2,
|
|
1025
|
+
prefix
|
|
1026
|
+
}),
|
|
1027
|
+
xl1TransactionSubmissionStorage: new Queue(Xl1TransactionSubmissionStorage.queueName, {
|
|
1028
|
+
connection: connection2,
|
|
1029
|
+
prefix
|
|
1030
|
+
})
|
|
1031
|
+
};
|
|
1032
|
+
return xl1ToEthQueues;
|
|
1033
|
+
}, "getXl1ToEthQueues");
|
|
1034
|
+
|
|
549
1035
|
// src/queue/telemetry.ts
|
|
550
|
-
import { isDefined as
|
|
1036
|
+
import { isDefined as isDefined12 } from "@xylabs/sdk-js";
|
|
551
1037
|
import { BullMQOtel } from "bullmq-otel";
|
|
552
1038
|
var telemetry;
|
|
553
1039
|
var options = {
|
|
554
1040
|
enableMetrics: true
|
|
555
1041
|
};
|
|
556
1042
|
var getTelemetry = /* @__PURE__ */ __name(() => {
|
|
557
|
-
if (
|
|
1043
|
+
if (isDefined12(telemetry)) return telemetry;
|
|
558
1044
|
telemetry = new BullMQOtel(options);
|
|
559
1045
|
return telemetry;
|
|
560
1046
|
}, "getTelemetry");
|
|
@@ -585,147 +1071,6 @@ var addInstrumentation = /* @__PURE__ */ __name(() => {
|
|
|
585
1071
|
// src/server/routes/bridge/routeDefinitions/routes/bridgeConfig.ts
|
|
586
1072
|
import { requestHandlerValidator } from "@xylabs/express";
|
|
587
1073
|
import { BridgeSettingsZod } from "@xyo-network/chain-orchestration";
|
|
588
|
-
|
|
589
|
-
// src/config/asChainId.ts
|
|
590
|
-
import { asHex } from "@xylabs/sdk-js";
|
|
591
|
-
var asChainId = /* @__PURE__ */ __name((value) => {
|
|
592
|
-
const chainId = asHex(value);
|
|
593
|
-
return chainId;
|
|
594
|
-
}, "asChainId");
|
|
595
|
-
|
|
596
|
-
// src/config/asToken.ts
|
|
597
|
-
import { asAddress } from "@xylabs/sdk-js";
|
|
598
|
-
var asToken = /* @__PURE__ */ __name((value) => {
|
|
599
|
-
const token = asAddress(value);
|
|
600
|
-
return token;
|
|
601
|
-
}, "asToken");
|
|
602
|
-
|
|
603
|
-
// src/config/getBridgeEscrowAddress.ts
|
|
604
|
-
import { asAddress as asAddress2, assertEx as assertEx11 } from "@xylabs/sdk-js";
|
|
605
|
-
var tryGetBridgeEscrowAddress = /* @__PURE__ */ __name((config) => {
|
|
606
|
-
const address = asAddress2(config.escrowAddress);
|
|
607
|
-
return address;
|
|
608
|
-
}, "tryGetBridgeEscrowAddress");
|
|
609
|
-
|
|
610
|
-
// src/config/getBridgeFeesAddress.ts
|
|
611
|
-
import { asAddress as asAddress3, assertEx as assertEx12 } from "@xylabs/sdk-js";
|
|
612
|
-
var tryGetBridgeFeesAddress = /* @__PURE__ */ __name((config) => {
|
|
613
|
-
const address = asAddress3(config.feesAddress);
|
|
614
|
-
return address;
|
|
615
|
-
}, "tryGetBridgeFeesAddress");
|
|
616
|
-
|
|
617
|
-
// src/config/getFeeStructure.ts
|
|
618
|
-
var getFeeStructure = /* @__PURE__ */ __name((config) => {
|
|
619
|
-
const { feeFixed, feeRateBasisPoints } = config;
|
|
620
|
-
return {
|
|
621
|
-
feeFixed,
|
|
622
|
-
feeRateBasisPoints
|
|
623
|
-
};
|
|
624
|
-
}, "getFeeStructure");
|
|
625
|
-
|
|
626
|
-
// src/config/getMaxBridgeAmount.ts
|
|
627
|
-
var getMaxBridgeAmount = /* @__PURE__ */ __name((config) => {
|
|
628
|
-
const { maxBridgeAmount } = config;
|
|
629
|
-
return maxBridgeAmount;
|
|
630
|
-
}, "getMaxBridgeAmount");
|
|
631
|
-
|
|
632
|
-
// src/config/getMinBridgeAmount.ts
|
|
633
|
-
var getMinBridgeAmount = /* @__PURE__ */ __name((config) => {
|
|
634
|
-
const { minBridgeAmount } = config;
|
|
635
|
-
return minBridgeAmount;
|
|
636
|
-
}, "getMinBridgeAmount");
|
|
637
|
-
|
|
638
|
-
// src/config/getRemoteChainId.ts
|
|
639
|
-
import { assertEx as assertEx13 } from "@xylabs/sdk-js";
|
|
640
|
-
var getRemoteChainId = /* @__PURE__ */ __name((config) => {
|
|
641
|
-
const remoteChainId = assertEx13(asChainId(config.remoteChainId), () => "Invalid remote chain ID in config");
|
|
642
|
-
return remoteChainId;
|
|
643
|
-
}, "getRemoteChainId");
|
|
644
|
-
|
|
645
|
-
// src/config/getRemoteTokenAddress.ts
|
|
646
|
-
import { assertEx as assertEx14 } from "@xylabs/sdk-js";
|
|
647
|
-
var getRemoteTokenAddress = /* @__PURE__ */ __name((config) => {
|
|
648
|
-
const token = asToken(config.remoteTokenAddress);
|
|
649
|
-
return assertEx14(token, () => "Remote token address is not defined in bridge configuration");
|
|
650
|
-
}, "getRemoteTokenAddress");
|
|
651
|
-
|
|
652
|
-
// src/config/getBridgeWalletAccount.ts
|
|
653
|
-
import { isDefined as isDefined7, isUndefined } from "@xylabs/sdk-js";
|
|
654
|
-
import { HDWallet } from "@xyo-network/sdk-js";
|
|
655
|
-
import { ADDRESS_INDEX, generateXyoBaseWalletFromPhrase } from "@xyo-network/xl1-sdk";
|
|
656
|
-
var accountServiceSingleton;
|
|
657
|
-
var getBridgeWalletAccount = /* @__PURE__ */ __name(async (config) => {
|
|
658
|
-
if (accountServiceSingleton) return accountServiceSingleton;
|
|
659
|
-
let walletPhrase = config.mnemonic;
|
|
660
|
-
if (isUndefined(walletPhrase)) {
|
|
661
|
-
console.log("[Bridge] No wallet mnemonic specified!");
|
|
662
|
-
const randomMnemonic = HDWallet.generateMnemonic();
|
|
663
|
-
console.log(`[Bridge] Using randomly generated mnemonic:
|
|
664
|
-
|
|
665
|
-
${randomMnemonic}
|
|
666
|
-
|
|
667
|
-
`);
|
|
668
|
-
walletPhrase = randomMnemonic;
|
|
669
|
-
}
|
|
670
|
-
const wallet = await generateXyoBaseWalletFromPhrase(walletPhrase);
|
|
671
|
-
const account = await wallet.derivePath(ADDRESS_INDEX.XYO);
|
|
672
|
-
accountServiceSingleton = account;
|
|
673
|
-
return accountServiceSingleton;
|
|
674
|
-
}, "getBridgeWalletAccount");
|
|
675
|
-
|
|
676
|
-
// src/config/getTransferAddresses.ts
|
|
677
|
-
var getTransferAddresses = /* @__PURE__ */ __name(async (config) => {
|
|
678
|
-
const escrowAddress = tryGetBridgeEscrowAddress(config) ?? (await getBridgeWalletAccount(config)).address;
|
|
679
|
-
const feesAddress = tryGetBridgeFeesAddress(config) ?? (await getBridgeWalletAccount(config)).address;
|
|
680
|
-
return {
|
|
681
|
-
escrowAddress,
|
|
682
|
-
feesAddress
|
|
683
|
-
};
|
|
684
|
-
}, "getTransferAddresses");
|
|
685
|
-
|
|
686
|
-
// src/config/getXl1ChainId.ts
|
|
687
|
-
import { assertEx as assertEx15, isDefined as isDefined8 } from "@xylabs/sdk-js";
|
|
688
|
-
var getXl1ChainId = /* @__PURE__ */ __name((config) => {
|
|
689
|
-
const xl1ChainId = config.xl1ChainId;
|
|
690
|
-
if (isDefined8(xl1ChainId)) {
|
|
691
|
-
return assertEx15(asChainId(xl1ChainId), () => "Invalid xl1ChainId in bridge config");
|
|
692
|
-
}
|
|
693
|
-
return assertEx15(asChainId(config.chain.id), () => "Invalid chain.id in config");
|
|
694
|
-
}, "getXl1ChainId");
|
|
695
|
-
|
|
696
|
-
// src/config/getXl1TokenAddress.ts
|
|
697
|
-
import { isDefined as isDefined9 } from "@xylabs/sdk-js";
|
|
698
|
-
var getXl1TokenAddress = /* @__PURE__ */ __name((config) => {
|
|
699
|
-
const token = asToken(config.xl1TokenAddress);
|
|
700
|
-
if (isDefined9(token)) return token;
|
|
701
|
-
return getXl1ChainId(config);
|
|
702
|
-
}, "getXl1TokenAddress");
|
|
703
|
-
|
|
704
|
-
// src/config/getBridgeSettings.ts
|
|
705
|
-
var getBridgeSettings = /* @__PURE__ */ __name(async (config) => {
|
|
706
|
-
const { feeFixed, feeRateBasisPoints } = getFeeStructure(config);
|
|
707
|
-
const { feesAddress, escrowAddress } = await getTransferAddresses(config);
|
|
708
|
-
const maxBridgeAmount = getMaxBridgeAmount(config);
|
|
709
|
-
const minBridgeAmount = getMinBridgeAmount(config);
|
|
710
|
-
const remoteChainId = getRemoteChainId(config);
|
|
711
|
-
const remoteTokenAddress = getRemoteTokenAddress(config);
|
|
712
|
-
const xl1TokenAddress = getXl1TokenAddress(config);
|
|
713
|
-
const xl1ChainId = getXl1ChainId(config);
|
|
714
|
-
return {
|
|
715
|
-
feeFixed,
|
|
716
|
-
feeRateBasisPoints,
|
|
717
|
-
feesAddress,
|
|
718
|
-
escrowAddress,
|
|
719
|
-
maxBridgeAmount,
|
|
720
|
-
minBridgeAmount,
|
|
721
|
-
remoteChainId,
|
|
722
|
-
remoteTokenAddress,
|
|
723
|
-
xl1TokenAddress,
|
|
724
|
-
xl1ChainId
|
|
725
|
-
};
|
|
726
|
-
}, "getBridgeSettings");
|
|
727
|
-
|
|
728
|
-
// src/server/routes/bridge/routeDefinitions/routes/bridgeConfig.ts
|
|
729
1074
|
var BridgeConfigResponseZod = BridgeSettingsZod;
|
|
730
1075
|
var validateRequest = requestHandlerValidator({
|
|
731
1076
|
response: BridgeConfigResponseZod
|
|
@@ -755,18 +1100,18 @@ var makeBridgeConfigRoute = /* @__PURE__ */ __name((config) => {
|
|
|
755
1100
|
|
|
756
1101
|
// src/server/routes/bridge/routeDefinitions/routes/bridgeFromRemoteStatus.ts
|
|
757
1102
|
import { requestHandlerValidator as requestHandlerValidator2 } from "@xylabs/express";
|
|
758
|
-
import { toAddress, toHex } from "@xylabs/sdk-js";
|
|
1103
|
+
import { toAddress as toAddress2, toHex as toHex2 } from "@xylabs/sdk-js";
|
|
759
1104
|
import { PayloadZodStrictOfSchema } from "@xyo-network/sdk-js";
|
|
760
1105
|
import { BridgeDestinationObservationFieldsZod, BridgeDestinationObservationSchema } from "@xyo-network/xl1-sdk";
|
|
761
1106
|
import { z } from "zod";
|
|
762
1107
|
|
|
763
1108
|
// src/server/routes/bridge/routeDefinitions/pathParams/ChainIdPathParam.ts
|
|
764
|
-
import { asHex as asHex2, HexZod, isUndefined as
|
|
1109
|
+
import { asHex as asHex2, HexZod, isUndefined as isUndefined3 } from "@xylabs/sdk-js";
|
|
765
1110
|
var getRemoteChainIdZod = /* @__PURE__ */ __name((config) => {
|
|
766
1111
|
const remoteChainId = getRemoteChainId(config);
|
|
767
1112
|
return HexZod.superRefine((val, ctx) => {
|
|
768
1113
|
const chainId = asHex2(val);
|
|
769
|
-
if (
|
|
1114
|
+
if (isUndefined3(chainId)) {
|
|
770
1115
|
ctx.addIssue("Not a valid chain id");
|
|
771
1116
|
return;
|
|
772
1117
|
}
|
|
@@ -800,14 +1145,14 @@ var makeBridgeFromRemoteStatusRoute = /* @__PURE__ */ __name((config) => {
|
|
|
800
1145
|
const observation = {
|
|
801
1146
|
schema: BridgeDestinationObservationSchema,
|
|
802
1147
|
dest: xl1ChainId,
|
|
803
|
-
destAddress:
|
|
804
|
-
destAmount:
|
|
1148
|
+
destAddress: toAddress2("0xabc"),
|
|
1149
|
+
destAmount: toHex2("0x100"),
|
|
805
1150
|
destToken: xl1TokenAddress,
|
|
806
1151
|
src: remoteChainId,
|
|
807
|
-
srcAddress:
|
|
808
|
-
srcAmount:
|
|
1152
|
+
srcAddress: toAddress2("0x123"),
|
|
1153
|
+
srcAmount: toHex2("0x200"),
|
|
809
1154
|
srcToken: remoteTokenAddress,
|
|
810
|
-
destConfirmation:
|
|
1155
|
+
destConfirmation: toHex2("0x9999")
|
|
811
1156
|
};
|
|
812
1157
|
res.json(observation);
|
|
813
1158
|
})
|
|
@@ -816,118 +1161,9 @@ var makeBridgeFromRemoteStatusRoute = /* @__PURE__ */ __name((config) => {
|
|
|
816
1161
|
|
|
817
1162
|
// src/server/routes/bridge/routeDefinitions/routes/bridgeToRemote.ts
|
|
818
1163
|
import { requestHandlerValidator as requestHandlerValidator3 } from "@xylabs/express";
|
|
819
|
-
import { PayloadBuilder as
|
|
1164
|
+
import { PayloadBuilder as PayloadBuilder14, PayloadZodLooseOfSchema, PayloadZodStrictOfSchema as PayloadZodStrictOfSchema2 } from "@xyo-network/sdk-js";
|
|
820
1165
|
import { BridgeIntentFieldsZod, BridgeIntentSchema as BridgeIntentSchema2, BridgeSourceObservationFieldsZod, BridgeSourceObservationSchema, SignedTransactionBoundWitnessZod, TransferZod } from "@xyo-network/xl1-sdk";
|
|
821
1166
|
import { z as z2 } from "zod";
|
|
822
|
-
|
|
823
|
-
// src/util/calculateBridgeFees.ts
|
|
824
|
-
import { hexToBigInt as hexToBigInt5, toHex as toHex2 } from "@xylabs/sdk-js";
|
|
825
|
-
var calculateBridgeFees = /* @__PURE__ */ __name((srcAmount, feeStructure) => {
|
|
826
|
-
const { feeFixed, feeRateBasisPoints } = feeStructure;
|
|
827
|
-
const srcAmountBigInt = hexToBigInt5(srcAmount);
|
|
828
|
-
const feeFixedBigInt = hexToBigInt5(feeFixed);
|
|
829
|
-
const feeVariableBigInt = srcAmountBigInt * BigInt(feeRateBasisPoints) / 10000n;
|
|
830
|
-
const feeVariable = toHex2(feeVariableBigInt);
|
|
831
|
-
const feeTotalBigInt = feeFixedBigInt + feeVariableBigInt;
|
|
832
|
-
const destAmountBigInt = srcAmountBigInt > feeTotalBigInt ? srcAmountBigInt - feeTotalBigInt : 0n;
|
|
833
|
-
const destAmount = toHex2(destAmountBigInt);
|
|
834
|
-
return {
|
|
835
|
-
feeFixed,
|
|
836
|
-
feeVariable,
|
|
837
|
-
srcAmount
|
|
838
|
-
};
|
|
839
|
-
}, "calculateBridgeFees");
|
|
840
|
-
|
|
841
|
-
// src/util/createBridgeTransfer.ts
|
|
842
|
-
import { hexToBigInt as hexToBigInt6 } from "@xylabs/sdk-js";
|
|
843
|
-
import { createTransferPayload } from "@xyo-network/xl1-sdk";
|
|
844
|
-
var createBridgeTransfer = /* @__PURE__ */ __name((sender, srcAmount, escrowAddress, feesAddress, context) => {
|
|
845
|
-
const { feeFixed, feeVariable } = context;
|
|
846
|
-
const escrowAmount = hexToBigInt6(srcAmount);
|
|
847
|
-
const feesAmount = hexToBigInt6(feeFixed) + hexToBigInt6(feeVariable);
|
|
848
|
-
const transfers = escrowAddress === feesAddress ? {
|
|
849
|
-
[feesAddress]: escrowAmount + feesAmount
|
|
850
|
-
} : {
|
|
851
|
-
[escrowAddress]: escrowAmount,
|
|
852
|
-
[feesAddress]: feesAmount
|
|
853
|
-
};
|
|
854
|
-
const transfer = createTransferPayload(sender, transfers, context);
|
|
855
|
-
return transfer;
|
|
856
|
-
}, "createBridgeTransfer");
|
|
857
|
-
|
|
858
|
-
// src/util/generateBridgeEstimate.ts
|
|
859
|
-
import { toAddress as toAddress2 } from "@xylabs/sdk-js";
|
|
860
|
-
import { PayloadBuilder as PayloadBuilder9 } from "@xyo-network/sdk-js";
|
|
861
|
-
import { BridgeIntentSchema } from "@xyo-network/xl1-sdk";
|
|
862
|
-
import { v4 } from "uuid";
|
|
863
|
-
var generateBridgeEstimate = /* @__PURE__ */ __name(async (srcAddress, srcAmount, destAddress, config, nonceOverride) => {
|
|
864
|
-
const { escrowAddress, feeFixed, feeRateBasisPoints, feesAddress, remoteChainId, remoteTokenAddress, xl1ChainId, xl1TokenAddress } = await getBridgeSettings(config);
|
|
865
|
-
const sender = toAddress2(srcAddress);
|
|
866
|
-
const fees = calculateBridgeFees(srcAmount, {
|
|
867
|
-
feeFixed,
|
|
868
|
-
feeRateBasisPoints
|
|
869
|
-
});
|
|
870
|
-
const nonce = nonceOverride ?? v4();
|
|
871
|
-
const bridgeIntentFields = {
|
|
872
|
-
// Source
|
|
873
|
-
src: xl1ChainId,
|
|
874
|
-
srcAddress: sender,
|
|
875
|
-
srcAmount,
|
|
876
|
-
srcToken: xl1TokenAddress,
|
|
877
|
-
// Destination
|
|
878
|
-
dest: remoteChainId,
|
|
879
|
-
destAddress,
|
|
880
|
-
destAmount: srcAmount,
|
|
881
|
-
destToken: remoteTokenAddress,
|
|
882
|
-
nonce
|
|
883
|
-
};
|
|
884
|
-
const bridgeIntent = new PayloadBuilder9({
|
|
885
|
-
schema: BridgeIntentSchema
|
|
886
|
-
}).fields(bridgeIntentFields).build();
|
|
887
|
-
const transfer = createBridgeTransfer(sender, srcAmount, escrowAddress, feesAddress, fees);
|
|
888
|
-
return [
|
|
889
|
-
bridgeIntent,
|
|
890
|
-
transfer
|
|
891
|
-
];
|
|
892
|
-
}, "generateBridgeEstimate");
|
|
893
|
-
|
|
894
|
-
// src/util/validateBridgeEstimateExact.ts
|
|
895
|
-
import { isUndefined as isUndefined3 } from "@xylabs/sdk-js";
|
|
896
|
-
import { PayloadBuilder as PayloadBuilder10 } from "@xyo-network/sdk-js";
|
|
897
|
-
var validateBridgeEstimateExact = /* @__PURE__ */ __name(async (intent, transfer, config) => {
|
|
898
|
-
const { srcAddress, srcAmount, destAddress } = intent;
|
|
899
|
-
const [calculatedIntent, calculatedTransfer] = await generateBridgeEstimate(srcAddress, srcAmount, destAddress, config);
|
|
900
|
-
if (isUndefined3(calculatedIntent) || isUndefined3(calculatedTransfer)) return false;
|
|
901
|
-
const { nonce: expectedIntentNonce, ...expectedIntentStatic } = calculatedIntent;
|
|
902
|
-
const { nonce: actualIntentNonce, ...actualIntentStatic } = intent;
|
|
903
|
-
if (await PayloadBuilder10.dataHash(expectedIntentStatic) !== await PayloadBuilder10.dataHash(actualIntentStatic)) return false;
|
|
904
|
-
const { epoch: expectedTransferEpoch, ...expectedTransferStatic } = calculatedTransfer;
|
|
905
|
-
const { epoch: actualTransferEpoch, ...actualTransferStatic } = transfer;
|
|
906
|
-
if (await PayloadBuilder10.dataHash(expectedTransferStatic) !== await PayloadBuilder10.dataHash(actualTransferStatic)) return false;
|
|
907
|
-
return true;
|
|
908
|
-
}, "validateBridgeEstimateExact");
|
|
909
|
-
|
|
910
|
-
// src/util/validateBridgeTransaction.ts
|
|
911
|
-
import { asAddress as asAddress4, isDefined as isDefined10 } from "@xylabs/sdk-js";
|
|
912
|
-
import { addressesContains, BoundWitnessValidator, payloadHashesContainsAll } from "@xyo-network/boundwitness-validator";
|
|
913
|
-
import { PayloadBuilder as PayloadBuilder11 } from "@xyo-network/sdk-js";
|
|
914
|
-
var validateBridgeTransaction = /* @__PURE__ */ __name(async (signedTxBw, intent, transfer, config) => {
|
|
915
|
-
const { srcAddress } = intent;
|
|
916
|
-
const chainId = getXl1ChainId(config);
|
|
917
|
-
if (signedTxBw.chain !== chainId) return false;
|
|
918
|
-
const errors = await new BoundWitnessValidator(signedTxBw).validate();
|
|
919
|
-
if (isDefined10(errors) && errors.length > 0) return false;
|
|
920
|
-
const sender = asAddress4(srcAddress, true);
|
|
921
|
-
if (!addressesContains(signedTxBw, sender)) return false;
|
|
922
|
-
const hashes = await PayloadBuilder11.hashes([
|
|
923
|
-
intent,
|
|
924
|
-
transfer
|
|
925
|
-
]);
|
|
926
|
-
if (!payloadHashesContainsAll(signedTxBw, hashes)) return false;
|
|
927
|
-
return true;
|
|
928
|
-
}, "validateBridgeTransaction");
|
|
929
|
-
|
|
930
|
-
// src/server/routes/bridge/routeDefinitions/routes/bridgeToRemote.ts
|
|
931
1167
|
var BridgeToRemoteBodyZod = z2.tuple([
|
|
932
1168
|
SignedTransactionBoundWitnessZod,
|
|
933
1169
|
PayloadZodLooseOfSchema(BridgeIntentSchema2).extend(BridgeIntentFieldsZod.shape),
|
|
@@ -949,6 +1185,7 @@ var makeBridgeToRemoteRoute = /* @__PURE__ */ __name((config) => {
|
|
|
949
1185
|
handlers: validateRequest2(async (req, res) => {
|
|
950
1186
|
const [signedTxBw, bridgeIntent, transfer] = req.body;
|
|
951
1187
|
const { flowProducer: flowProducer2 } = req.app;
|
|
1188
|
+
const { gateway } = req.app.services;
|
|
952
1189
|
const transactionValid = await validateBridgeTransaction(signedTxBw, bridgeIntent, transfer, config);
|
|
953
1190
|
if (!transactionValid) {
|
|
954
1191
|
res.status(400).send();
|
|
@@ -959,6 +1196,11 @@ var makeBridgeToRemoteRoute = /* @__PURE__ */ __name((config) => {
|
|
|
959
1196
|
res.status(400).send();
|
|
960
1197
|
return;
|
|
961
1198
|
}
|
|
1199
|
+
const sufficientBalance = await validateSufficientXL1SourceAddressBalance(bridgeIntent, gateway, config);
|
|
1200
|
+
if (!sufficientBalance) {
|
|
1201
|
+
res.status(400).send();
|
|
1202
|
+
return;
|
|
1203
|
+
}
|
|
962
1204
|
const singedHydratedTransaction = [
|
|
963
1205
|
signedTxBw,
|
|
964
1206
|
[
|
|
@@ -967,14 +1209,14 @@ var makeBridgeToRemoteRoute = /* @__PURE__ */ __name((config) => {
|
|
|
967
1209
|
]
|
|
968
1210
|
];
|
|
969
1211
|
await createXl1ToEthBridgeJob(flowProducer2, singedHydratedTransaction);
|
|
970
|
-
const srcConfirmation = await
|
|
1212
|
+
const srcConfirmation = await PayloadBuilder14.hash(signedTxBw);
|
|
971
1213
|
const bridgeCommonFieldsZod = z2.object({}).extend(BridgeSourceObservationFieldsZod.shape);
|
|
972
1214
|
const bridgeCommonFields = bridgeCommonFieldsZod.parse(bridgeIntent);
|
|
973
1215
|
const bridgeObservationFields = {
|
|
974
1216
|
...bridgeCommonFields,
|
|
975
1217
|
srcConfirmation
|
|
976
1218
|
};
|
|
977
|
-
const bridgeObservation = new
|
|
1219
|
+
const bridgeObservation = new PayloadBuilder14({
|
|
978
1220
|
schema: BridgeSourceObservationSchema
|
|
979
1221
|
}).fields(bridgeObservationFields).build();
|
|
980
1222
|
res.json(bridgeObservation);
|
|
@@ -984,7 +1226,7 @@ var makeBridgeToRemoteRoute = /* @__PURE__ */ __name((config) => {
|
|
|
984
1226
|
|
|
985
1227
|
// src/server/routes/bridge/routeDefinitions/routes/bridgeToRemoteEstimate.ts
|
|
986
1228
|
import { requestHandlerValidator as requestHandlerValidator4 } from "@xylabs/express";
|
|
987
|
-
import { assertEx as
|
|
1229
|
+
import { assertEx as assertEx19, toAddress as toAddress3 } from "@xylabs/sdk-js";
|
|
988
1230
|
import { PayloadZodStrictOfSchema as PayloadZodStrictOfSchema3 } from "@xyo-network/sdk-js";
|
|
989
1231
|
import { BridgeIntentFieldsZod as BridgeIntentFieldsZod2, BridgeIntentSchema as BridgeIntentSchema3, buildUnsignedTransaction, toXL1BlockNumber, TransactionBoundWitnessZod, TransferZod as TransferZod2 } from "@xyo-network/xl1-sdk";
|
|
990
1232
|
import { z as z3 } from "zod";
|
|
@@ -1015,7 +1257,7 @@ var makeBridgeToRemoteEstimateRoute = /* @__PURE__ */ __name((config, gateway) =
|
|
|
1015
1257
|
const { srcAddress, srcAmount, destAddress } = req.body;
|
|
1016
1258
|
const [bridgeIntent, transfer] = await generateBridgeEstimate(srcAddress, srcAmount, destAddress, config);
|
|
1017
1259
|
const sender = toAddress3(srcAddress);
|
|
1018
|
-
const viewer =
|
|
1260
|
+
const viewer = assertEx19(gateway.connection.viewer, () => new Error("Viewer not available on gateway connection"));
|
|
1019
1261
|
const currentBlockNumber = await viewer.currentBlockNumber();
|
|
1020
1262
|
const nbf = toXL1BlockNumber(currentBlockNumber, true);
|
|
1021
1263
|
const exp = toXL1BlockNumber(currentBlockNumber + 1e3, true);
|
|
@@ -1035,10 +1277,9 @@ var makeBridgeToRemoteEstimateRoute = /* @__PURE__ */ __name((config, gateway) =
|
|
|
1035
1277
|
|
|
1036
1278
|
// src/server/routes/bridge/routeDefinitions/routes/bridgeToRemoteStatus.ts
|
|
1037
1279
|
import { requestHandlerValidator as requestHandlerValidator5 } from "@xylabs/express";
|
|
1038
|
-
import { asHex as asHex3, isDefined as
|
|
1039
|
-
import { PayloadBuilder as
|
|
1280
|
+
import { asHex as asHex3, isDefined as isDefined13 } from "@xylabs/sdk-js";
|
|
1281
|
+
import { PayloadBuilder as PayloadBuilder15, PayloadZodStrictOfSchema as PayloadZodStrictOfSchema4 } from "@xyo-network/sdk-js";
|
|
1040
1282
|
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";
|
|
1042
1283
|
import { z as z4 } from "zod";
|
|
1043
1284
|
var BridgeIntentResponseZod = PayloadZodStrictOfSchema4(BridgeIntentSchema4).extend(BridgeIntentFieldsZod3.shape);
|
|
1044
1285
|
var BridgeSourceResponseZod = PayloadZodStrictOfSchema4(BridgeSourceObservationSchema2).extend(BridgeSourceObservationFieldsZod2.shape);
|
|
@@ -1058,55 +1299,6 @@ var BridgeToRemoteStatusResponseZod = z4.union([
|
|
|
1058
1299
|
BridgeDestinationResponseZod
|
|
1059
1300
|
])
|
|
1060
1301
|
]);
|
|
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");
|
|
1110
1302
|
var makeBridgeToRemoteStatusRoute = /* @__PURE__ */ __name((config) => {
|
|
1111
1303
|
const params = z4.object({
|
|
1112
1304
|
chainId: getRemoteChainIdZod(config),
|
|
@@ -1122,41 +1314,42 @@ var makeBridgeToRemoteStatusRoute = /* @__PURE__ */ __name((config) => {
|
|
|
1122
1314
|
handlers: validateRequest2(async (req, res) => {
|
|
1123
1315
|
const jobId = req.params.nonce;
|
|
1124
1316
|
const result = [];
|
|
1125
|
-
const queues =
|
|
1317
|
+
const queues = getXl1ToEthQueues(config);
|
|
1126
1318
|
const statusQueueJobs = await getStatusQueueJobs(queues, jobId);
|
|
1127
|
-
const tx =
|
|
1319
|
+
const tx = statusQueueJobs.xl1ToEthBridgeParentJob?.data?.tx;
|
|
1128
1320
|
if (!tx) return res.sendStatus(404);
|
|
1129
1321
|
const bridgeIntent = tx[1].find(isBridgeIntent5);
|
|
1130
1322
|
if (!bridgeIntent) return res.sendStatus(404);
|
|
1131
|
-
result[0] = asBridgeIntent(
|
|
1323
|
+
result[0] = asBridgeIntent(PayloadBuilder15.omitMeta(bridgeIntent));
|
|
1132
1324
|
const { xl1TransactionMonitorJob } = statusQueueJobs;
|
|
1133
1325
|
const xl1MonitorState = xl1TransactionMonitorJob ? await xl1TransactionMonitorJob.getState() : void 0;
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1326
|
+
if (xl1MonitorState === "completed") {
|
|
1327
|
+
const srcConfirmation = xl1TransactionMonitorJob?.returnvalue?.submissionHash;
|
|
1328
|
+
if (isDefined13(srcConfirmation)) {
|
|
1329
|
+
const schema = BridgeSourceObservationSchema2;
|
|
1330
|
+
const bridgeSourceObservationFields = BridgeSourceObservationFieldsZod2.parse(bridgeIntent);
|
|
1331
|
+
const observation = {
|
|
1332
|
+
schema,
|
|
1333
|
+
...bridgeSourceObservationFields,
|
|
1334
|
+
srcConfirmation
|
|
1335
|
+
};
|
|
1336
|
+
result[1] = observation;
|
|
1337
|
+
}
|
|
1144
1338
|
}
|
|
1145
1339
|
const { ethTransactionMonitorJob } = statusQueueJobs;
|
|
1146
1340
|
const ethMonitorState = ethTransactionMonitorJob ? await ethTransactionMonitorJob.getState() : void 0;
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
}
|
|
1159
|
-
result[2] = observation;
|
|
1341
|
+
if (ethMonitorState === "completed") {
|
|
1342
|
+
const destConfirmation = asHex3(ethTransactionMonitorJob?.returnvalue?.submissionHash);
|
|
1343
|
+
if (isDefined13(destConfirmation)) {
|
|
1344
|
+
const schema = BridgeDestinationObservationSchema2;
|
|
1345
|
+
const bridgeDestinationObservationFields = BridgeDestinationObservationFieldsZod2.parse(bridgeIntent);
|
|
1346
|
+
const observation = {
|
|
1347
|
+
schema,
|
|
1348
|
+
...bridgeDestinationObservationFields,
|
|
1349
|
+
destConfirmation
|
|
1350
|
+
};
|
|
1351
|
+
result[2] = observation;
|
|
1352
|
+
}
|
|
1160
1353
|
}
|
|
1161
1354
|
res.json(result);
|
|
1162
1355
|
})
|
|
@@ -1209,7 +1402,7 @@ var getApp = /* @__PURE__ */ __name((config, gateway) => {
|
|
|
1209
1402
|
}, "getApp");
|
|
1210
1403
|
|
|
1211
1404
|
// src/services/getServices.ts
|
|
1212
|
-
import { assertEx as
|
|
1405
|
+
import { assertEx as assertEx20, isDefined as isDefined14 } from "@xylabs/sdk-js";
|
|
1213
1406
|
import { initEvmProvider } from "@xyo-network/chain-orchestration";
|
|
1214
1407
|
import { HDWallet as HDWallet2 } from "@xyo-network/sdk-js";
|
|
1215
1408
|
import { BridgeableToken__factory, LiquidityPoolBridge__factory } from "@xyo-network/typechain";
|
|
@@ -1254,12 +1447,12 @@ var getServices = /* @__PURE__ */ __name(async (context, gateway) => {
|
|
|
1254
1447
|
const xl1TxStateMap = await getIterableMap(config, "liquidity_bridge_xl1_to_eth_xl1_tx_state");
|
|
1255
1448
|
const provider = await initEvmProvider(context);
|
|
1256
1449
|
const { remoteBridgeContractAddress, remoteChainWalletPrivateKey, remoteTokenAddress, mnemonic } = config;
|
|
1257
|
-
const account =
|
|
1450
|
+
const account = isDefined14(mnemonic) ? await HDWallet2.fromPhrase(mnemonic) : await HDWallet2.random();
|
|
1258
1451
|
const wallet = new Wallet(remoteChainWalletPrivateKey, provider);
|
|
1259
1452
|
const bridgeableToken = BridgeableToken__factory.connect(getAddress2(remoteTokenAddress), wallet);
|
|
1260
1453
|
const bridge = LiquidityPoolBridge__factory.connect(getAddress2(remoteBridgeContractAddress), wallet);
|
|
1261
1454
|
const bridgeOwner = await bridge.owner();
|
|
1262
|
-
|
|
1455
|
+
assertEx20(bridgeOwner.toLowerCase() === wallet.address.toLowerCase(), () => "Wallet is not the owner of the bridge contract");
|
|
1263
1456
|
return {
|
|
1264
1457
|
account,
|
|
1265
1458
|
bridge,
|
|
@@ -1286,6 +1479,7 @@ var getServer = /* @__PURE__ */ __name(async (context, gateway) => {
|
|
|
1286
1479
|
const { port } = config;
|
|
1287
1480
|
const app = getApp(config, gateway);
|
|
1288
1481
|
const services = await getServices(context, gateway);
|
|
1482
|
+
app.services = services;
|
|
1289
1483
|
addWorkers(config, services);
|
|
1290
1484
|
const server = app.listen(port, hostname, () => logger?.log(`[Bridge] Server listening at http://${hostname}:${port}`));
|
|
1291
1485
|
server.setTimeout(2e4);
|