@xyo-network/chain-bridge 1.17.2 → 1.17.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/node/config/asChainId.d.ts +3 -0
- package/dist/node/config/asChainId.d.ts.map +1 -0
- package/dist/node/config/asToken.d.ts +3 -0
- package/dist/node/config/asToken.d.ts.map +1 -0
- package/dist/node/config/getBridgeEscrowAddress.d.ts +5 -0
- package/dist/node/config/getBridgeEscrowAddress.d.ts.map +1 -0
- package/dist/node/config/getBridgeFeesAddress.d.ts +5 -0
- package/dist/node/config/getBridgeFeesAddress.d.ts.map +1 -0
- package/dist/node/config/getBridgeSettings.d.ts +3 -0
- package/dist/node/config/getBridgeSettings.d.ts.map +1 -0
- package/dist/node/config/getBridgeWalletAccount.d.ts +6 -0
- package/dist/node/config/getBridgeWalletAccount.d.ts.map +1 -0
- package/dist/node/config/getFeeStructure.d.ts +4 -0
- package/dist/node/config/getFeeStructure.d.ts.map +1 -0
- package/dist/node/config/getGateway.d.ts +3 -0
- package/dist/node/config/getGateway.d.ts.map +1 -0
- package/dist/node/config/getMaxBridgeAmount.d.ts +4 -0
- package/dist/node/config/getMaxBridgeAmount.d.ts.map +1 -0
- package/dist/node/config/getMinBridgeAmount.d.ts +4 -0
- package/dist/node/config/getMinBridgeAmount.d.ts.map +1 -0
- package/dist/node/config/getRemoteChainId.d.ts +4 -0
- package/dist/node/config/getRemoteChainId.d.ts.map +1 -0
- package/dist/node/config/getRemoteTokenAddress.d.ts +4 -0
- package/dist/node/config/getRemoteTokenAddress.d.ts.map +1 -0
- package/dist/node/config/getTransferAddresses.d.ts +8 -0
- package/dist/node/config/getTransferAddresses.d.ts.map +1 -0
- package/dist/node/config/getXl1ChainId.d.ts +4 -0
- package/dist/node/config/getXl1ChainId.d.ts.map +1 -0
- package/dist/node/config/getXl1TokenAddress.d.ts +4 -0
- package/dist/node/config/getXl1TokenAddress.d.ts.map +1 -0
- package/dist/node/config/index.d.ts +16 -0
- package/dist/node/config/index.d.ts.map +1 -0
- package/dist/node/index.mjs +1133 -206
- package/dist/node/index.mjs.map +1 -1
- package/dist/node/interface/service/Observer/LiquidityPoolBridgeObserver/LiquidityPoolBridgeObserver.d.ts.map +1 -1
- package/dist/node/manifest/getLocator.d.ts.map +1 -1
- package/dist/node/manifest/public/index.d.ts +0 -4
- package/dist/node/manifest/public/index.d.ts.map +1 -1
- package/dist/node/modules/EVMLiquidityBridgeTransactionCompletionMonitorSentinel/EVMLiquidityBridgeTransactionCompletionMonitorSentinel.d.ts +77 -0
- package/dist/node/modules/EVMLiquidityBridgeTransactionCompletionMonitorSentinel/EVMLiquidityBridgeTransactionCompletionMonitorSentinel.d.ts.map +1 -0
- package/dist/node/modules/EVMLiquidityBridgeTransactionCompletionMonitorSentinel/index.d.ts +2 -0
- package/dist/node/modules/EVMLiquidityBridgeTransactionCompletionMonitorSentinel/index.d.ts.map +1 -0
- package/dist/node/modules/XL1TransactionCompletionMonitorSentinel/XL1TransactionCompletionMonitorSentinel.d.ts +56 -0
- package/dist/node/modules/XL1TransactionCompletionMonitorSentinel/XL1TransactionCompletionMonitorSentinel.d.ts.map +1 -0
- package/dist/node/modules/XL1TransactionCompletionMonitorSentinel/index.d.ts +2 -0
- package/dist/node/modules/XL1TransactionCompletionMonitorSentinel/index.d.ts.map +1 -0
- package/dist/node/modules/index.d.ts +2 -1
- package/dist/node/modules/index.d.ts.map +1 -1
- package/dist/node/server/app.d.ts +3 -1
- package/dist/node/server/app.d.ts.map +1 -1
- package/dist/node/server/routes/addRoutes.d.ts +2 -1
- package/dist/node/server/routes/addRoutes.d.ts.map +1 -1
- package/dist/node/server/routes/bridge/addBridgeRoutes.d.ts +2 -1
- package/dist/node/server/routes/bridge/addBridgeRoutes.d.ts.map +1 -1
- package/dist/node/server/routes/bridge/routeDefinitions/getRouteDefinitions.d.ts +2 -1
- package/dist/node/server/routes/bridge/routeDefinitions/getRouteDefinitions.d.ts.map +1 -1
- package/dist/node/server/routes/bridge/routeDefinitions/pathParams/ChainIdPathParam.d.ts +2 -1
- package/dist/node/server/routes/bridge/routeDefinitions/pathParams/ChainIdPathParam.d.ts.map +1 -1
- package/dist/node/server/routes/bridge/routeDefinitions/routes/bridgeConfig.d.ts +4 -0
- package/dist/node/server/routes/bridge/routeDefinitions/routes/bridgeConfig.d.ts.map +1 -0
- package/dist/node/server/routes/bridge/routeDefinitions/routes/bridgeFromRemoteStatus.d.ts +2 -1
- package/dist/node/server/routes/bridge/routeDefinitions/routes/bridgeFromRemoteStatus.d.ts.map +1 -1
- package/dist/node/server/routes/bridge/routeDefinitions/routes/bridgeToRemote.d.ts +2 -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 +2 -1
- package/dist/node/server/routes/bridge/routeDefinitions/routes/bridgeToRemoteEstimate.d.ts.map +1 -1
- package/dist/node/server/routes/bridge/routeDefinitions/routes/bridgeToRemoteStatus.d.ts +2 -1
- package/dist/node/server/routes/bridge/routeDefinitions/routes/bridgeToRemoteStatus.d.ts.map +1 -1
- package/dist/node/server/routes/bridge/routeDefinitions/routes/index.d.ts +1 -0
- package/dist/node/server/routes/bridge/routeDefinitions/routes/index.d.ts.map +1 -1
- package/dist/node/server/routes/index.d.ts +0 -2
- package/dist/node/server/routes/index.d.ts.map +1 -1
- package/dist/node/server/server.d.ts +1 -1
- package/dist/node/server/server.d.ts.map +1 -1
- package/dist/node/util/calculateBridgeFees.d.ts +10 -0
- package/dist/node/util/calculateBridgeFees.d.ts.map +1 -0
- package/dist/node/util/generateBridgeEstimate.d.ts +5 -0
- package/dist/node/util/generateBridgeEstimate.d.ts.map +1 -0
- package/dist/node/util/index.d.ts +5 -0
- package/dist/node/util/index.d.ts.map +1 -0
- package/dist/node/util/validateBridgeEstimate.d.ts +13 -0
- package/dist/node/util/validateBridgeEstimate.d.ts.map +1 -0
- package/dist/node/util/validateBridgeEstimateExact.d.ts +12 -0
- package/dist/node/util/validateBridgeEstimateExact.d.ts.map +1 -0
- package/package.json +29 -14
- package/src/config/asChainId.ts +7 -0
- package/src/config/asToken.ts +7 -0
- package/src/config/getBridgeEscrowAddress.ts +13 -0
- package/src/config/getBridgeFeesAddress.ts +13 -0
- package/src/config/getBridgeSettings.ts +24 -0
- package/src/config/getBridgeWalletAccount.ts +34 -0
- package/src/config/getFeeStructure.ts +8 -0
- package/src/config/getGateway.ts +19 -0
- package/src/config/getMaxBridgeAmount.ts +7 -0
- package/src/config/getMinBridgeAmount.ts +7 -0
- package/src/config/getRemoteChainId.ts +10 -0
- package/src/config/getRemoteTokenAddress.ts +10 -0
- package/src/config/getTransferAddresses.ts +17 -0
- package/src/config/getXl1ChainId.ts +13 -0
- package/src/config/getXl1TokenAddress.ts +12 -0
- package/src/config/index.ts +15 -0
- package/src/interface/service/Observer/LiquidityPoolBridgeObserver/LiquidityPoolBridgeObserver.ts +1 -2
- package/src/manifest/getLocator.ts +97 -34
- package/src/manifest/public/Ethereum.json +24 -64
- package/src/manifest/public/XL1.json +24 -64
- package/src/manifest/public/index.ts +0 -6
- package/src/modules/EVMLiquidityBridgeTransactionCompletionMonitorSentinel/EVMLiquidityBridgeTransactionCompletionMonitorSentinel.ts +234 -0
- package/src/modules/EVMLiquidityBridgeTransactionCompletionMonitorSentinel/index.ts +1 -0
- package/src/modules/XL1TransactionCompletionMonitorSentinel/XL1TransactionCompletionMonitorSentinel.ts +166 -0
- package/src/modules/XL1TransactionCompletionMonitorSentinel/index.ts +1 -0
- package/src/modules/index.ts +2 -1
- package/src/server/app.ts +5 -4
- package/src/server/routes/addRoutes.ts +3 -2
- package/src/server/routes/bridge/addBridgeRoutes.ts +3 -2
- package/src/server/routes/bridge/routeDefinitions/getRouteDefinitions.ts +8 -6
- package/src/server/routes/bridge/routeDefinitions/pathParams/ChainIdPathParam.ts +16 -13
- package/src/server/routes/bridge/routeDefinitions/routes/bridgeConfig.ts +43 -0
- package/src/server/routes/bridge/routeDefinitions/routes/bridgeFromRemoteStatus.ts +40 -37
- package/src/server/routes/bridge/routeDefinitions/routes/bridgeToRemote.ts +74 -45
- package/src/server/routes/bridge/routeDefinitions/routes/bridgeToRemoteEstimate.ts +48 -75
- package/src/server/routes/bridge/routeDefinitions/routes/bridgeToRemoteStatus.ts +95 -47
- package/src/server/routes/bridge/routeDefinitions/routes/index.ts +1 -0
- package/src/server/routes/index.ts +0 -2
- package/src/server/server.ts +37 -31
- package/src/util/calculateBridgeFees.ts +39 -0
- package/src/util/generateBridgeEstimate.ts +64 -0
- package/src/util/index.ts +4 -0
- package/src/util/validateBridgeEstimate.ts +60 -0
- package/src/util/validateBridgeEstimateExact.ts +34 -0
- package/dist/node/modules/XL1toEvmBridgeSentinel/XL1toEvmBridgeSentinel.d.ts +0 -47
- package/dist/node/modules/XL1toEvmBridgeSentinel/XL1toEvmBridgeSentinel.d.ts.map +0 -1
- package/dist/node/modules/XL1toEvmBridgeSentinel/index.d.ts +0 -2
- package/dist/node/modules/XL1toEvmBridgeSentinel/index.d.ts.map +0 -1
- package/dist/node/server/routes/address/AddressPathParams.d.ts +0 -4
- package/dist/node/server/routes/address/AddressPathParams.d.ts.map +0 -1
- package/dist/node/server/routes/address/addNodeRoutes.d.ts +0 -3
- package/dist/node/server/routes/address/addNodeRoutes.d.ts.map +0 -1
- package/dist/node/server/routes/address/get/get.d.ts +0 -4
- package/dist/node/server/routes/address/get/get.d.ts.map +0 -1
- package/dist/node/server/routes/address/get/index.d.ts +0 -2
- package/dist/node/server/routes/address/get/index.d.ts.map +0 -1
- package/dist/node/server/routes/address/index.d.ts +0 -2
- package/dist/node/server/routes/address/index.d.ts.map +0 -1
- package/dist/node/server/routes/address/post/getQueryConfig.d.ts +0 -6
- package/dist/node/server/routes/address/post/getQueryConfig.d.ts.map +0 -1
- package/dist/node/server/routes/address/post/index.d.ts +0 -2
- package/dist/node/server/routes/address/post/index.d.ts.map +0 -1
- package/dist/node/server/routes/address/post/post.d.ts +0 -8
- package/dist/node/server/routes/address/post/post.d.ts.map +0 -1
- package/src/manifest/public/Chain.json +0 -32
- package/src/modules/XL1toEvmBridgeSentinel/XL1toEvmBridgeSentinel.ts +0 -156
- package/src/modules/XL1toEvmBridgeSentinel/index.ts +0 -1
- package/src/server/routes/address/AddressPathParams.ts +0 -3
- package/src/server/routes/address/addNodeRoutes.ts +0 -21
- package/src/server/routes/address/get/get.ts +0 -30
- package/src/server/routes/address/get/index.ts +0 -1
- package/src/server/routes/address/index.ts +0 -1
- package/src/server/routes/address/post/getQueryConfig.ts +0 -23
- package/src/server/routes/address/post/index.ts +0 -1
- package/src/server/routes/address/post/post.ts +0 -77
package/dist/node/index.mjs
CHANGED
|
@@ -21,243 +21,573 @@ var addInstrumentation = /* @__PURE__ */ __name(() => {
|
|
|
21
21
|
});
|
|
22
22
|
}, "addInstrumentation");
|
|
23
23
|
|
|
24
|
-
// src/server/routes/bridge/routeDefinitions/routes/
|
|
24
|
+
// src/server/routes/bridge/routeDefinitions/routes/bridgeConfig.ts
|
|
25
25
|
import { requestHandlerValidator } from "@xylabs/express";
|
|
26
|
-
import {
|
|
26
|
+
import { BridgeSettingsZod } from "@xyo-network/xl1-protocol-sdk";
|
|
27
|
+
|
|
28
|
+
// src/config/asChainId.ts
|
|
29
|
+
import { asHex } from "@xylabs/sdk-js";
|
|
30
|
+
var asChainId = /* @__PURE__ */ __name((value) => {
|
|
31
|
+
const chainId = asHex(value);
|
|
32
|
+
return chainId;
|
|
33
|
+
}, "asChainId");
|
|
34
|
+
|
|
35
|
+
// src/config/asToken.ts
|
|
36
|
+
import { asAddress } from "@xylabs/sdk-js";
|
|
37
|
+
var asToken = /* @__PURE__ */ __name((value) => {
|
|
38
|
+
const token = asAddress(value);
|
|
39
|
+
return token;
|
|
40
|
+
}, "asToken");
|
|
41
|
+
|
|
42
|
+
// src/config/getBridgeEscrowAddress.ts
|
|
43
|
+
import { asAddress as asAddress2, assertEx } from "@xylabs/sdk-js";
|
|
44
|
+
var tryGetBridgeEscrowAddress = /* @__PURE__ */ __name((config) => {
|
|
45
|
+
const address = asAddress2(config.bridge.escrowAddress);
|
|
46
|
+
return address;
|
|
47
|
+
}, "tryGetBridgeEscrowAddress");
|
|
48
|
+
|
|
49
|
+
// src/config/getBridgeFeesAddress.ts
|
|
50
|
+
import { asAddress as asAddress3, assertEx as assertEx2 } from "@xylabs/sdk-js";
|
|
51
|
+
var tryGetBridgeFeesAddress = /* @__PURE__ */ __name((config) => {
|
|
52
|
+
const address = asAddress3(config.bridge.feesAddress);
|
|
53
|
+
return address;
|
|
54
|
+
}, "tryGetBridgeFeesAddress");
|
|
55
|
+
|
|
56
|
+
// src/config/getFeeStructure.ts
|
|
57
|
+
var getFeeStructure = /* @__PURE__ */ __name((config) => {
|
|
58
|
+
const { feeFixed, feeRateBasisPoints } = config.bridge;
|
|
59
|
+
return {
|
|
60
|
+
feeFixed,
|
|
61
|
+
feeRateBasisPoints
|
|
62
|
+
};
|
|
63
|
+
}, "getFeeStructure");
|
|
64
|
+
|
|
65
|
+
// src/config/getMaxBridgeAmount.ts
|
|
66
|
+
var getMaxBridgeAmount = /* @__PURE__ */ __name((config) => {
|
|
67
|
+
const { maxBridgeAmount } = config.bridge;
|
|
68
|
+
return maxBridgeAmount;
|
|
69
|
+
}, "getMaxBridgeAmount");
|
|
70
|
+
|
|
71
|
+
// src/config/getMinBridgeAmount.ts
|
|
72
|
+
var getMinBridgeAmount = /* @__PURE__ */ __name((config) => {
|
|
73
|
+
const { minBridgeAmount } = config.bridge;
|
|
74
|
+
return minBridgeAmount;
|
|
75
|
+
}, "getMinBridgeAmount");
|
|
76
|
+
|
|
77
|
+
// src/config/getRemoteChainId.ts
|
|
78
|
+
import { assertEx as assertEx3 } from "@xylabs/sdk-js";
|
|
79
|
+
var getRemoteChainId = /* @__PURE__ */ __name((config) => {
|
|
80
|
+
const remoteChainId = assertEx3(asChainId(config.bridge.remoteChainId), () => "Invalid remote chain ID in config");
|
|
81
|
+
return remoteChainId;
|
|
82
|
+
}, "getRemoteChainId");
|
|
83
|
+
|
|
84
|
+
// src/config/getRemoteTokenAddress.ts
|
|
85
|
+
import { assertEx as assertEx4 } from "@xylabs/sdk-js";
|
|
86
|
+
var getRemoteTokenAddress = /* @__PURE__ */ __name((config) => {
|
|
87
|
+
const token = asToken(config.bridge.remoteTokenAddress);
|
|
88
|
+
return assertEx4(token, () => "Remote token address is not defined in bridge configuration");
|
|
89
|
+
}, "getRemoteTokenAddress");
|
|
90
|
+
|
|
91
|
+
// src/config/getBridgeWalletAccount.ts
|
|
92
|
+
import { isDefined, isUndefined } from "@xylabs/sdk-js";
|
|
93
|
+
import { HDWallet } from "@xyo-network/wallet";
|
|
94
|
+
import { ADDRESS_INDEX, generateXyoBaseWalletFromPhrase } from "@xyo-network/xl1-protocol-sdk";
|
|
95
|
+
var accountServiceSingleton;
|
|
96
|
+
var getBridgeWalletAccount = /* @__PURE__ */ __name(async (config) => {
|
|
97
|
+
if (accountServiceSingleton) return accountServiceSingleton;
|
|
98
|
+
let walletPhrase = config.bridge.mnemonic;
|
|
99
|
+
if (isUndefined(walletPhrase)) {
|
|
100
|
+
console.log("[Bridge] No wallet mnemonic specified!");
|
|
101
|
+
const randomMnemonic = HDWallet.generateMnemonic();
|
|
102
|
+
console.log(`[Bridge] Using randomly generated mnemonic:
|
|
103
|
+
|
|
104
|
+
${randomMnemonic}
|
|
105
|
+
|
|
106
|
+
`);
|
|
107
|
+
walletPhrase = randomMnemonic;
|
|
108
|
+
}
|
|
109
|
+
const wallet = await generateXyoBaseWalletFromPhrase(walletPhrase);
|
|
110
|
+
const account = await wallet.derivePath(ADDRESS_INDEX.XYO);
|
|
111
|
+
accountServiceSingleton = account;
|
|
112
|
+
return accountServiceSingleton;
|
|
113
|
+
}, "getBridgeWalletAccount");
|
|
114
|
+
|
|
115
|
+
// src/config/getTransferAddresses.ts
|
|
116
|
+
var getTransferAddresses = /* @__PURE__ */ __name(async (config) => {
|
|
117
|
+
const escrowAddress = tryGetBridgeEscrowAddress(config) ?? (await getBridgeWalletAccount(config)).address;
|
|
118
|
+
const feesAddress = tryGetBridgeFeesAddress(config) ?? (await getBridgeWalletAccount(config)).address;
|
|
119
|
+
return {
|
|
120
|
+
escrowAddress,
|
|
121
|
+
feesAddress
|
|
122
|
+
};
|
|
123
|
+
}, "getTransferAddresses");
|
|
124
|
+
|
|
125
|
+
// src/config/getXl1ChainId.ts
|
|
126
|
+
import { assertEx as assertEx5, isDefined as isDefined2 } from "@xylabs/sdk-js";
|
|
127
|
+
var getXl1ChainId = /* @__PURE__ */ __name((config) => {
|
|
128
|
+
const xl1ChainId = config.bridge.xl1ChainId;
|
|
129
|
+
if (isDefined2(xl1ChainId)) {
|
|
130
|
+
return assertEx5(asChainId(xl1ChainId), () => "Invalid xl1ChainId in bridge config");
|
|
131
|
+
}
|
|
132
|
+
return assertEx5(asChainId(config.chain.id), () => "Invalid chain.id in config");
|
|
133
|
+
}, "getXl1ChainId");
|
|
134
|
+
|
|
135
|
+
// src/config/getXl1TokenAddress.ts
|
|
136
|
+
import { isDefined as isDefined3 } from "@xylabs/sdk-js";
|
|
137
|
+
var getXl1TokenAddress = /* @__PURE__ */ __name((config) => {
|
|
138
|
+
const token = asToken(config.bridge.xl1TokenAddress);
|
|
139
|
+
if (isDefined3(token)) return token;
|
|
140
|
+
return getXl1ChainId(config);
|
|
141
|
+
}, "getXl1TokenAddress");
|
|
142
|
+
|
|
143
|
+
// src/config/getBridgeSettings.ts
|
|
144
|
+
var getBridgeSettings = /* @__PURE__ */ __name(async (config) => {
|
|
145
|
+
const { feeFixed, feeRateBasisPoints } = getFeeStructure(config);
|
|
146
|
+
const { feesAddress, escrowAddress } = await getTransferAddresses(config);
|
|
147
|
+
const maxBridgeAmount = getMaxBridgeAmount(config);
|
|
148
|
+
const minBridgeAmount = getMinBridgeAmount(config);
|
|
149
|
+
const remoteChainId = getRemoteChainId(config);
|
|
150
|
+
const remoteTokenAddress = getRemoteTokenAddress(config);
|
|
151
|
+
const xl1TokenAddress = getXl1TokenAddress(config);
|
|
152
|
+
const xl1ChainId = getXl1ChainId(config);
|
|
153
|
+
return {
|
|
154
|
+
feeFixed,
|
|
155
|
+
feeRateBasisPoints,
|
|
156
|
+
feesAddress,
|
|
157
|
+
escrowAddress,
|
|
158
|
+
maxBridgeAmount,
|
|
159
|
+
minBridgeAmount,
|
|
160
|
+
remoteChainId,
|
|
161
|
+
remoteTokenAddress,
|
|
162
|
+
xl1TokenAddress,
|
|
163
|
+
xl1ChainId
|
|
164
|
+
};
|
|
165
|
+
}, "getBridgeSettings");
|
|
166
|
+
|
|
167
|
+
// src/config/getGateway.ts
|
|
168
|
+
import { isDefined as isDefined4 } from "@xylabs/sdk-js";
|
|
169
|
+
import { HDWallet as HDWallet2 } from "@xyo-network/wallet";
|
|
170
|
+
import { SimpleXyoGatewayRunner, SimpleXyoSigner } from "@xyo-network/xl1-protocol-sdk";
|
|
171
|
+
import { HttpRpcXyoConnection } from "@xyo-network/xl1-rpc";
|
|
172
|
+
var gatewayInstance;
|
|
173
|
+
var getGateway = /* @__PURE__ */ __name(async (config) => {
|
|
174
|
+
if (isDefined4(gatewayInstance)) return gatewayInstance;
|
|
175
|
+
const { mnemonic, chainRpcApiUrl: endpoint } = config.bridge;
|
|
176
|
+
const walletPromise = isDefined4(mnemonic) ? HDWallet2.fromPhrase(mnemonic) : HDWallet2.random();
|
|
177
|
+
const account = await walletPromise;
|
|
178
|
+
const signer = new SimpleXyoSigner(account);
|
|
179
|
+
const connection = new HttpRpcXyoConnection({
|
|
180
|
+
endpoint
|
|
181
|
+
});
|
|
182
|
+
gatewayInstance = new SimpleXyoGatewayRunner(connection, signer);
|
|
183
|
+
return gatewayInstance;
|
|
184
|
+
}, "getGateway");
|
|
185
|
+
|
|
186
|
+
// src/server/routes/bridge/routeDefinitions/routes/bridgeConfig.ts
|
|
187
|
+
var response = BridgeSettingsZod;
|
|
188
|
+
var validateRequest = requestHandlerValidator({
|
|
189
|
+
response
|
|
190
|
+
});
|
|
191
|
+
var makeBridgeConfigRoute = /* @__PURE__ */ __name((config) => {
|
|
192
|
+
return {
|
|
193
|
+
method: "get",
|
|
194
|
+
path: "/bridge/chains/:chainId/config",
|
|
195
|
+
handlers: validateRequest(async (_, res) => {
|
|
196
|
+
const { escrowAddress, feeFixed, feeRateBasisPoints, feesAddress, maxBridgeAmount, minBridgeAmount, remoteChainId, remoteTokenAddress, xl1ChainId, xl1TokenAddress } = await getBridgeSettings(config);
|
|
197
|
+
const sanitizedConfig = {
|
|
198
|
+
escrowAddress,
|
|
199
|
+
feeFixed,
|
|
200
|
+
feeRateBasisPoints,
|
|
201
|
+
feesAddress,
|
|
202
|
+
maxBridgeAmount,
|
|
203
|
+
minBridgeAmount,
|
|
204
|
+
remoteChainId,
|
|
205
|
+
remoteTokenAddress,
|
|
206
|
+
xl1ChainId,
|
|
207
|
+
xl1TokenAddress
|
|
208
|
+
};
|
|
209
|
+
res.json(sanitizedConfig);
|
|
210
|
+
})
|
|
211
|
+
};
|
|
212
|
+
}, "makeBridgeConfigRoute");
|
|
213
|
+
|
|
214
|
+
// src/server/routes/bridge/routeDefinitions/routes/bridgeFromRemoteStatus.ts
|
|
215
|
+
import { requestHandlerValidator as requestHandlerValidator2 } from "@xylabs/express";
|
|
216
|
+
import { toAddress, toHex } from "@xylabs/sdk-js";
|
|
27
217
|
import { PayloadZodStrictOfSchema } from "@xyo-network/payload-model";
|
|
28
218
|
import { BridgeDestinationObservationFieldsZod, BridgeDestinationObservationSchema } from "@xyo-network/xl1-protocol";
|
|
29
219
|
import { z } from "zod";
|
|
30
220
|
|
|
31
221
|
// src/server/routes/bridge/routeDefinitions/pathParams/ChainIdPathParam.ts
|
|
32
|
-
import {
|
|
33
|
-
var
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
222
|
+
import { asHex as asHex2, HexZod, isUndefined as isUndefined2 } from "@xylabs/sdk-js";
|
|
223
|
+
var getRemoteChainIdZod = /* @__PURE__ */ __name((config) => {
|
|
224
|
+
const remoteChainId = getRemoteChainId(config);
|
|
225
|
+
return HexZod.superRefine((val, ctx) => {
|
|
226
|
+
const chainId = asHex2(val);
|
|
227
|
+
if (isUndefined2(chainId)) {
|
|
228
|
+
ctx.addIssue("Not a valid chain id");
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
if (chainId !== remoteChainId) {
|
|
232
|
+
ctx.addIssue(`Only ${remoteChainId} is supported`);
|
|
233
|
+
}
|
|
37
234
|
});
|
|
38
|
-
|
|
39
|
-
const suppliedChainId = toAddress(chainIdHex);
|
|
40
|
-
if (isUndefined(suppliedChainId)) return false;
|
|
41
|
-
return suppliedChainId === remoteChainId;
|
|
42
|
-
}, {
|
|
43
|
-
message: `Only ${remoteChainId} is supported`
|
|
44
|
-
});
|
|
235
|
+
}, "getRemoteChainIdZod");
|
|
45
236
|
|
|
46
237
|
// src/server/routes/bridge/routeDefinitions/routes/bridgeFromRemoteStatus.ts
|
|
47
|
-
var
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
}
|
|
238
|
+
var makeBridgeFromRemoteStatusRoute = /* @__PURE__ */ __name((config) => {
|
|
239
|
+
const params = z.object({
|
|
240
|
+
chainId: getRemoteChainIdZod(config),
|
|
241
|
+
nonce: z.string().nonempty()
|
|
242
|
+
});
|
|
243
|
+
const response2 = PayloadZodStrictOfSchema(BridgeDestinationObservationSchema).extend(BridgeDestinationObservationFieldsZod.shape);
|
|
244
|
+
const validateRequest2 = requestHandlerValidator2({
|
|
245
|
+
params,
|
|
246
|
+
response: response2
|
|
247
|
+
});
|
|
248
|
+
return {
|
|
249
|
+
method: "get",
|
|
250
|
+
path: "/bridge/chains/:chainId/bridgeFromRemote/status/:nonce",
|
|
251
|
+
handlers: validateRequest2(async (req, res) => {
|
|
252
|
+
const { remoteChainId, remoteTokenAddress, xl1ChainId, xl1TokenAddress } = await getBridgeSettings(config);
|
|
253
|
+
const rand = await Promise.resolve(Math.random());
|
|
254
|
+
const found = rand > 0.5;
|
|
255
|
+
if (!found) return res.sendStatus(404);
|
|
256
|
+
const confirmed = rand > 0.8;
|
|
257
|
+
if (!confirmed) return res.sendStatus(204);
|
|
258
|
+
const observation = {
|
|
259
|
+
schema: BridgeDestinationObservationSchema,
|
|
260
|
+
dest: xl1ChainId,
|
|
261
|
+
destAddress: toAddress("0xabc"),
|
|
262
|
+
destAmount: toHex("0x100"),
|
|
263
|
+
destToken: xl1TokenAddress,
|
|
264
|
+
src: remoteChainId,
|
|
265
|
+
srcAddress: toAddress("0x123"),
|
|
266
|
+
srcAmount: toHex("0x200"),
|
|
267
|
+
srcToken: remoteTokenAddress,
|
|
268
|
+
destConfirmation: toHex("0x9999")
|
|
269
|
+
};
|
|
270
|
+
res.json(observation);
|
|
271
|
+
})
|
|
272
|
+
};
|
|
273
|
+
}, "makeBridgeFromRemoteStatusRoute");
|
|
81
274
|
|
|
82
275
|
// src/server/routes/bridge/routeDefinitions/routes/bridgeToRemote.ts
|
|
83
|
-
import { requestHandlerValidator as
|
|
84
|
-
import {
|
|
85
|
-
import { PayloadBuilder } from "@xyo-network/payload-builder";
|
|
86
|
-
import {
|
|
87
|
-
import {
|
|
276
|
+
import { requestHandlerValidator as requestHandlerValidator3 } from "@xylabs/express";
|
|
277
|
+
import { assertEx as assertEx6 } from "@xylabs/sdk-js";
|
|
278
|
+
import { PayloadBuilder as PayloadBuilder3 } from "@xyo-network/payload-builder";
|
|
279
|
+
import { PayloadZodStrictOfSchema as PayloadZodStrictOfSchema2 } from "@xyo-network/payload-model";
|
|
280
|
+
import { asSentinelInstance } from "@xyo-network/sentinel-model";
|
|
281
|
+
import { BridgeIntentFieldsZod, BridgeIntentSchema as BridgeIntentSchema2, BridgeSourceObservationFieldsZod, BridgeSourceObservationSchema, SignedTransactionBoundWitnessZod, TransferZod } from "@xyo-network/xl1-protocol";
|
|
282
|
+
import { flattenHydratedTransaction } from "@xyo-network/xl1-protocol-sdk";
|
|
88
283
|
import { z as z2 } from "zod";
|
|
89
|
-
var params2 = z2.object({
|
|
90
|
-
chainId: ChainIdPathParam
|
|
91
|
-
});
|
|
92
|
-
var body = z2.tuple([
|
|
93
|
-
// TODO: TransactionBoundWitness
|
|
94
|
-
PayloadZodStrictOfSchema2(BridgeIntentSchema).extend(BridgeIntentFieldsZod.shape),
|
|
95
|
-
PayloadZodLooseOfSchema(TransferSchema)
|
|
96
|
-
]);
|
|
97
|
-
var response2 = PayloadZodStrictOfSchema2(BridgeSourceObservationSchema).extend(BridgeSourceObservationFieldsZod.shape);
|
|
98
|
-
var validateRequest2 = requestHandlerValidator2({
|
|
99
|
-
params: params2,
|
|
100
|
-
body,
|
|
101
|
-
response: response2
|
|
102
|
-
});
|
|
103
|
-
var bridgeToRemote = {
|
|
104
|
-
method: "post",
|
|
105
|
-
path: "/bridge/chains/:chainId/bridgeToRemote",
|
|
106
|
-
handlers: validateRequest2(async (req, res) => {
|
|
107
|
-
const { body: body3 } = req;
|
|
108
|
-
const [bridgeIntent] = body3;
|
|
109
|
-
const srcConfirmation = await Promise.resolve(asHash("0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef"));
|
|
110
|
-
const bridgeCommonFieldsZod = z2.object({}).extend(BridgeSourceObservationFieldsZod.shape);
|
|
111
|
-
const bridgeCommonFields = bridgeCommonFieldsZod.parse(bridgeIntent);
|
|
112
|
-
const bridgeObservationFields = {
|
|
113
|
-
...bridgeCommonFields,
|
|
114
|
-
srcConfirmation
|
|
115
|
-
};
|
|
116
|
-
const bridgeObservation = new PayloadBuilder({
|
|
117
|
-
schema: BridgeSourceObservationSchema
|
|
118
|
-
}).fields(bridgeObservationFields).build();
|
|
119
|
-
res.json(bridgeObservation);
|
|
120
|
-
})
|
|
121
|
-
};
|
|
122
284
|
|
|
123
|
-
// src/
|
|
124
|
-
import {
|
|
125
|
-
|
|
285
|
+
// src/util/calculateBridgeFees.ts
|
|
286
|
+
import { hexToBigInt, toHex as toHex2 } from "@xylabs/sdk-js";
|
|
287
|
+
var calculateBridgeFees = /* @__PURE__ */ __name((srcAmount, feeStructure) => {
|
|
288
|
+
const { feeFixed, feeRateBasisPoints } = feeStructure;
|
|
289
|
+
const srcAmountBigInt = hexToBigInt(srcAmount);
|
|
290
|
+
const feeFixedBigInt = hexToBigInt(feeFixed);
|
|
291
|
+
const feeVariableBigInt = srcAmountBigInt * BigInt(feeRateBasisPoints) / 10000n;
|
|
292
|
+
const feeVariable = toHex2(feeVariableBigInt);
|
|
293
|
+
const feeTotalBigInt = feeFixedBigInt + feeVariableBigInt;
|
|
294
|
+
const destAmountBigInt = srcAmountBigInt > feeTotalBigInt ? srcAmountBigInt - feeTotalBigInt : 0n;
|
|
295
|
+
const destAmount = toHex2(destAmountBigInt);
|
|
296
|
+
return {
|
|
297
|
+
destAmount,
|
|
298
|
+
feeFixed,
|
|
299
|
+
feeVariable
|
|
300
|
+
};
|
|
301
|
+
}, "calculateBridgeFees");
|
|
302
|
+
|
|
303
|
+
// src/util/generateBridgeEstimate.ts
|
|
304
|
+
import { hexToBigInt as hexToBigInt2, toAddress as toAddress2 } from "@xylabs/sdk-js";
|
|
126
305
|
import { createTransferPayload } from "@xyo-network/chain-protocol";
|
|
127
|
-
import { PayloadBuilder
|
|
128
|
-
import {
|
|
129
|
-
import { BridgeIntentFieldsZod as BridgeIntentFieldsZod2, BridgeIntentSchema as BridgeIntentSchema2, TransferSchema as TransferSchema2 } from "@xyo-network/xl1-protocol";
|
|
306
|
+
import { PayloadBuilder } from "@xyo-network/payload-builder";
|
|
307
|
+
import { BridgeIntentSchema } from "@xyo-network/xl1-protocol";
|
|
130
308
|
import { v4 } from "uuid";
|
|
309
|
+
var generateBridgeEstimate = /* @__PURE__ */ __name(async (srcAddress, srcAmount, destAddress, config, nonceOverride) => {
|
|
310
|
+
const { escrowAddress, feeFixed, feeRateBasisPoints, feesAddress, remoteChainId, remoteTokenAddress, xl1ChainId, xl1TokenAddress } = await getBridgeSettings(config);
|
|
311
|
+
const sender = toAddress2(srcAddress);
|
|
312
|
+
const fees = calculateBridgeFees(srcAmount, {
|
|
313
|
+
feeFixed,
|
|
314
|
+
feeRateBasisPoints
|
|
315
|
+
});
|
|
316
|
+
const { destAmount, feeFixed: feeFixedAmount, feeVariable } = fees;
|
|
317
|
+
const nonce = nonceOverride ?? v4();
|
|
318
|
+
const bridgeIntentFields = {
|
|
319
|
+
// Source
|
|
320
|
+
src: xl1ChainId,
|
|
321
|
+
srcAddress: sender,
|
|
322
|
+
srcAmount,
|
|
323
|
+
srcToken: xl1TokenAddress,
|
|
324
|
+
// Destination
|
|
325
|
+
dest: remoteChainId,
|
|
326
|
+
destAddress,
|
|
327
|
+
destAmount,
|
|
328
|
+
destToken: remoteTokenAddress,
|
|
329
|
+
nonce
|
|
330
|
+
};
|
|
331
|
+
const bridgeIntent = new PayloadBuilder({
|
|
332
|
+
schema: BridgeIntentSchema
|
|
333
|
+
}).fields(bridgeIntentFields).build();
|
|
334
|
+
const context = {
|
|
335
|
+
destAmount,
|
|
336
|
+
feeFixed: feeFixedAmount,
|
|
337
|
+
feeVariable
|
|
338
|
+
};
|
|
339
|
+
const transfer = createTransferPayload(sender, {
|
|
340
|
+
[escrowAddress]: hexToBigInt2(destAmount),
|
|
341
|
+
[feesAddress]: hexToBigInt2(feeFixedAmount) + hexToBigInt2(feeVariable)
|
|
342
|
+
}, context);
|
|
343
|
+
return [
|
|
344
|
+
bridgeIntent,
|
|
345
|
+
transfer
|
|
346
|
+
];
|
|
347
|
+
}, "generateBridgeEstimate");
|
|
348
|
+
|
|
349
|
+
// src/util/validateBridgeEstimateExact.ts
|
|
350
|
+
import { isUndefined as isUndefined3 } from "@xylabs/sdk-js";
|
|
351
|
+
import { PayloadBuilder as PayloadBuilder2 } from "@xyo-network/payload-builder";
|
|
352
|
+
var validateBridgeEstimateExact = /* @__PURE__ */ __name(async (intent, transfer, config) => {
|
|
353
|
+
const { srcAddress, srcAmount, destAddress } = intent;
|
|
354
|
+
const [calculatedIntent, calculatedTransfer] = await generateBridgeEstimate(srcAddress, srcAmount, destAddress, config);
|
|
355
|
+
if (isUndefined3(calculatedIntent) || isUndefined3(calculatedTransfer)) return false;
|
|
356
|
+
const { nonce: expectedIntentNonce, ...expectedIntentStatic } = calculatedIntent;
|
|
357
|
+
const { nonce: actualIntentNonce, ...actualIntentStatic } = intent;
|
|
358
|
+
if (await PayloadBuilder2.dataHash(expectedIntentStatic) !== await PayloadBuilder2.dataHash(actualIntentStatic)) return false;
|
|
359
|
+
const { epoch: expectedTransferEpoch, ...expectedTransferStatic } = calculatedTransfer;
|
|
360
|
+
const { epoch: actualTransferEpoch, ...actualTransferStatic } = transfer;
|
|
361
|
+
if (await PayloadBuilder2.dataHash(expectedTransferStatic) !== await PayloadBuilder2.dataHash(actualTransferStatic)) return false;
|
|
362
|
+
return true;
|
|
363
|
+
}, "validateBridgeEstimateExact");
|
|
364
|
+
|
|
365
|
+
// src/server/routes/bridge/routeDefinitions/routes/bridgeToRemote.ts
|
|
366
|
+
var makeBridgeToRemoteRoute = /* @__PURE__ */ __name((config) => {
|
|
367
|
+
const params = z2.object({
|
|
368
|
+
chainId: getRemoteChainIdZod(config)
|
|
369
|
+
});
|
|
370
|
+
const body = z2.tuple([
|
|
371
|
+
SignedTransactionBoundWitnessZod,
|
|
372
|
+
PayloadZodStrictOfSchema2(BridgeIntentSchema2).extend(BridgeIntentFieldsZod.shape),
|
|
373
|
+
TransferZod
|
|
374
|
+
]);
|
|
375
|
+
const response2 = PayloadZodStrictOfSchema2(BridgeSourceObservationSchema).extend(BridgeSourceObservationFieldsZod.shape);
|
|
376
|
+
const validateRequest2 = requestHandlerValidator3({
|
|
377
|
+
params,
|
|
378
|
+
body,
|
|
379
|
+
response: response2
|
|
380
|
+
});
|
|
381
|
+
return {
|
|
382
|
+
method: "post",
|
|
383
|
+
path: "/bridge/chains/:chainId/bridgeToRemote",
|
|
384
|
+
handlers: validateRequest2(async (req, res) => {
|
|
385
|
+
const [signedTxBw, bridgeIntent, transfer] = req.body;
|
|
386
|
+
const { srcAddress } = bridgeIntent;
|
|
387
|
+
const { node } = req.app;
|
|
388
|
+
const estimateValid = await validateBridgeEstimateExact(bridgeIntent, transfer, config);
|
|
389
|
+
if (!estimateValid) {
|
|
390
|
+
res.status(400).send();
|
|
391
|
+
return;
|
|
392
|
+
}
|
|
393
|
+
const mod = await node.resolve("XL1BridgeIntentTransactionCompletionMonitorSentinel");
|
|
394
|
+
const sentinel = assertEx6(asSentinelInstance(mod), () => "Error resolving XL1BridgeIntentTransactionCompletionMonitorSentinel");
|
|
395
|
+
const singedHydratedTransaction = [
|
|
396
|
+
signedTxBw,
|
|
397
|
+
[
|
|
398
|
+
transfer,
|
|
399
|
+
bridgeIntent
|
|
400
|
+
]
|
|
401
|
+
];
|
|
402
|
+
const observation = await sentinel.report(flattenHydratedTransaction(singedHydratedTransaction));
|
|
403
|
+
if (observation.length === 0) {
|
|
404
|
+
console.error("Error submitting bridge intent transaction to sentinel");
|
|
405
|
+
res.status(500).send();
|
|
406
|
+
return;
|
|
407
|
+
}
|
|
408
|
+
const srcConfirmation = await PayloadBuilder3.hash(signedTxBw);
|
|
409
|
+
const bridgeCommonFieldsZod = z2.object({}).extend(BridgeSourceObservationFieldsZod.shape);
|
|
410
|
+
const bridgeCommonFields = bridgeCommonFieldsZod.parse(bridgeIntent);
|
|
411
|
+
const bridgeObservationFields = {
|
|
412
|
+
...bridgeCommonFields,
|
|
413
|
+
srcConfirmation
|
|
414
|
+
};
|
|
415
|
+
const bridgeObservation = new PayloadBuilder3({
|
|
416
|
+
schema: BridgeSourceObservationSchema
|
|
417
|
+
}).fields(bridgeObservationFields).build();
|
|
418
|
+
res.json(bridgeObservation);
|
|
419
|
+
})
|
|
420
|
+
};
|
|
421
|
+
}, "makeBridgeToRemoteRoute");
|
|
422
|
+
|
|
423
|
+
// src/server/routes/bridge/routeDefinitions/routes/bridgeToRemoteEstimate.ts
|
|
424
|
+
import { requestHandlerValidator as requestHandlerValidator4 } from "@xylabs/express";
|
|
425
|
+
import { assertEx as assertEx7, toAddress as toAddress3 } from "@xylabs/sdk-js";
|
|
426
|
+
import { PayloadZodLooseOfSchema, PayloadZodStrictOfSchema as PayloadZodStrictOfSchema3 } from "@xyo-network/payload-model";
|
|
427
|
+
import { BridgeIntentFieldsZod as BridgeIntentFieldsZod2, BridgeIntentSchema as BridgeIntentSchema3, toXL1BlockNumber, TransactionBoundWitnessZod, TransferSchema } from "@xyo-network/xl1-protocol";
|
|
428
|
+
import { buildUnsignedTransaction } from "@xyo-network/xl1-protocol-sdk";
|
|
131
429
|
import { z as z3 } from "zod";
|
|
132
|
-
var
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
destAmount,
|
|
178
|
-
destToken: bridgeableTokenContract,
|
|
179
|
-
nonce
|
|
180
|
-
};
|
|
181
|
-
const bridgeIntent = new PayloadBuilder2({
|
|
182
|
-
schema: BridgeIntentSchema2
|
|
183
|
-
}).fields(bridgeIntentFields).build();
|
|
184
|
-
const transfer = createTransferPayload(sender, {
|
|
185
|
-
[bridgeEscrowAddress]: destAmountBigInt,
|
|
186
|
-
[bridgeFeesAddress]: feeAmount
|
|
187
|
-
});
|
|
188
|
-
res.json([
|
|
189
|
-
bridgeIntent,
|
|
190
|
-
transfer
|
|
191
|
-
]);
|
|
192
|
-
})
|
|
193
|
-
};
|
|
430
|
+
var makeBridgeToRemoteEstimateRoute = /* @__PURE__ */ __name((config) => {
|
|
431
|
+
const params = z3.object({
|
|
432
|
+
chainId: getRemoteChainIdZod(config)
|
|
433
|
+
});
|
|
434
|
+
const body = BridgeIntentFieldsZod2.pick({
|
|
435
|
+
destAddress: true,
|
|
436
|
+
srcAddress: true,
|
|
437
|
+
srcAmount: true
|
|
438
|
+
});
|
|
439
|
+
const response2 = z3.tuple([
|
|
440
|
+
TransactionBoundWitnessZod,
|
|
441
|
+
PayloadZodStrictOfSchema3(BridgeIntentSchema3).extend(BridgeIntentFieldsZod2.shape),
|
|
442
|
+
PayloadZodLooseOfSchema(TransferSchema)
|
|
443
|
+
]);
|
|
444
|
+
const validateRequest2 = requestHandlerValidator4({
|
|
445
|
+
params,
|
|
446
|
+
body,
|
|
447
|
+
response: response2
|
|
448
|
+
});
|
|
449
|
+
return {
|
|
450
|
+
method: "post",
|
|
451
|
+
path: "/bridge/chains/:chainId/bridgeToRemote/estimate",
|
|
452
|
+
handlers: validateRequest2(async (req, res) => {
|
|
453
|
+
const xl1ChainId = getXl1ChainId(config);
|
|
454
|
+
const { srcAddress, srcAmount, destAddress } = req.body;
|
|
455
|
+
const [bridgeIntent, transfer] = await generateBridgeEstimate(srcAddress, srcAmount, destAddress, config);
|
|
456
|
+
const sender = toAddress3(srcAddress);
|
|
457
|
+
const gateway = await getGateway(config);
|
|
458
|
+
const viewer = assertEx7(gateway.connectionInstance.viewer, () => new Error("Viewer not available on gateway connection"));
|
|
459
|
+
const currentBlockNumber = await viewer.currentBlockNumber();
|
|
460
|
+
const nbf = toXL1BlockNumber(currentBlockNumber, true);
|
|
461
|
+
const exp = toXL1BlockNumber(currentBlockNumber + 1e3, true);
|
|
462
|
+
const [txBw] = await buildUnsignedTransaction(xl1ChainId, [
|
|
463
|
+
transfer
|
|
464
|
+
], [
|
|
465
|
+
bridgeIntent
|
|
466
|
+
], nbf, exp, sender);
|
|
467
|
+
res.json([
|
|
468
|
+
txBw,
|
|
469
|
+
bridgeIntent,
|
|
470
|
+
transfer
|
|
471
|
+
]);
|
|
472
|
+
})
|
|
473
|
+
};
|
|
474
|
+
}, "makeBridgeToRemoteEstimateRoute");
|
|
194
475
|
|
|
195
476
|
// src/server/routes/bridge/routeDefinitions/routes/bridgeToRemoteStatus.ts
|
|
196
|
-
import { requestHandlerValidator as
|
|
197
|
-
import {
|
|
477
|
+
import { requestHandlerValidator as requestHandlerValidator5 } from "@xylabs/express";
|
|
478
|
+
import { asAddress as asAddress4, asHex as asHex3, toHex as toHex3 } from "@xylabs/sdk-js";
|
|
198
479
|
import { PayloadZodStrictOfSchema as PayloadZodStrictOfSchema4 } from "@xyo-network/payload-model";
|
|
199
|
-
import { BridgeDestinationObservationFieldsZod as BridgeDestinationObservationFieldsZod2, BridgeDestinationObservationSchema as BridgeDestinationObservationSchema2 } from "@xyo-network/xl1-protocol";
|
|
480
|
+
import { BridgeDestinationObservationFieldsZod as BridgeDestinationObservationFieldsZod2, BridgeDestinationObservationSchema as BridgeDestinationObservationSchema2, BridgeIntentFieldsZod as BridgeIntentFieldsZod3, BridgeIntentSchema as BridgeIntentSchema4, BridgeSourceObservationFieldsZod as BridgeSourceObservationFieldsZod2, BridgeSourceObservationSchema as BridgeSourceObservationSchema2 } from "@xyo-network/xl1-protocol";
|
|
200
481
|
import { z as z4 } from "zod";
|
|
201
|
-
var
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
res
|
|
233
|
-
|
|
234
|
-
};
|
|
482
|
+
var makeBridgeToRemoteStatusRoute = /* @__PURE__ */ __name((config) => {
|
|
483
|
+
const params = z4.object({
|
|
484
|
+
chainId: getRemoteChainIdZod(config),
|
|
485
|
+
nonce: z4.string().nonempty()
|
|
486
|
+
});
|
|
487
|
+
const query = z4.object({
|
|
488
|
+
mockStatus: z4.coerce.number().default(0)
|
|
489
|
+
});
|
|
490
|
+
const response2 = z4.union([
|
|
491
|
+
z4.tuple([]),
|
|
492
|
+
z4.tuple([
|
|
493
|
+
PayloadZodStrictOfSchema4(BridgeIntentSchema4).extend(BridgeIntentFieldsZod3.shape)
|
|
494
|
+
]),
|
|
495
|
+
z4.tuple([
|
|
496
|
+
PayloadZodStrictOfSchema4(BridgeIntentSchema4).extend(BridgeIntentFieldsZod3.shape),
|
|
497
|
+
PayloadZodStrictOfSchema4(BridgeSourceObservationSchema2).extend(BridgeSourceObservationFieldsZod2.shape)
|
|
498
|
+
]),
|
|
499
|
+
z4.tuple([
|
|
500
|
+
PayloadZodStrictOfSchema4(BridgeIntentSchema4).extend(BridgeIntentFieldsZod3.shape),
|
|
501
|
+
PayloadZodStrictOfSchema4(BridgeSourceObservationSchema2).extend(BridgeSourceObservationFieldsZod2.shape),
|
|
502
|
+
PayloadZodStrictOfSchema4(BridgeDestinationObservationSchema2).extend(BridgeDestinationObservationFieldsZod2.shape)
|
|
503
|
+
])
|
|
504
|
+
]);
|
|
505
|
+
const validateRequest2 = requestHandlerValidator5({
|
|
506
|
+
params,
|
|
507
|
+
query,
|
|
508
|
+
response: response2
|
|
509
|
+
});
|
|
510
|
+
return {
|
|
511
|
+
method: "get",
|
|
512
|
+
path: "/bridge/chains/:chainId/bridgeToRemote/status/:nonce",
|
|
513
|
+
handlers: validateRequest2(async (req, res) => {
|
|
514
|
+
const { chainId } = req.params;
|
|
515
|
+
const { mockStatus = 0 } = req.query;
|
|
516
|
+
const result = [];
|
|
517
|
+
const { remoteTokenAddress, xl1ChainId, xl1TokenAddress } = await getBridgeSettings(config);
|
|
518
|
+
const src = xl1ChainId;
|
|
519
|
+
const srcAddress = asAddress4("2222222222222222222222222222222222222222", true);
|
|
520
|
+
const srcAmount = asHex3("0x200", true);
|
|
521
|
+
const srcToken = xl1TokenAddress;
|
|
522
|
+
const dest = chainId;
|
|
523
|
+
const destAddress = asAddress4("3333333333333333333333333333333333333333", true);
|
|
524
|
+
const destAmount = asHex3("0x100", true);
|
|
525
|
+
const destToken = remoteTokenAddress;
|
|
526
|
+
if (mockStatus === 0) return res.sendStatus(404);
|
|
527
|
+
if (mockStatus > 0) {
|
|
528
|
+
const [observation] = await generateBridgeEstimate(srcAddress, srcAmount, destAddress, config, req.params.nonce);
|
|
529
|
+
result[0] = observation;
|
|
530
|
+
}
|
|
531
|
+
if (mockStatus > 1) {
|
|
532
|
+
const observation = {
|
|
533
|
+
schema: BridgeSourceObservationSchema2,
|
|
534
|
+
dest,
|
|
535
|
+
destAddress,
|
|
536
|
+
destAmount,
|
|
537
|
+
destToken,
|
|
538
|
+
src,
|
|
539
|
+
srcAddress,
|
|
540
|
+
srcAmount,
|
|
541
|
+
srcToken
|
|
542
|
+
};
|
|
543
|
+
result[1] = observation;
|
|
544
|
+
}
|
|
545
|
+
if (mockStatus > 2) {
|
|
546
|
+
const observation = {
|
|
547
|
+
schema: BridgeDestinationObservationSchema2,
|
|
548
|
+
dest,
|
|
549
|
+
destAddress,
|
|
550
|
+
destAmount,
|
|
551
|
+
destToken,
|
|
552
|
+
src,
|
|
553
|
+
srcAddress,
|
|
554
|
+
srcAmount,
|
|
555
|
+
srcToken,
|
|
556
|
+
destConfirmation: toHex3("0x9999")
|
|
557
|
+
};
|
|
558
|
+
result[2] = observation;
|
|
559
|
+
}
|
|
560
|
+
res.json(result);
|
|
561
|
+
})
|
|
562
|
+
};
|
|
563
|
+
}, "makeBridgeToRemoteStatusRoute");
|
|
235
564
|
|
|
236
565
|
// src/server/routes/bridge/routeDefinitions/getRouteDefinitions.ts
|
|
237
|
-
var getRouteDefinitions = /* @__PURE__ */ __name(() => {
|
|
566
|
+
var getRouteDefinitions = /* @__PURE__ */ __name((config) => {
|
|
238
567
|
return [
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
568
|
+
makeBridgeConfigRoute(config),
|
|
569
|
+
makeBridgeToRemoteEstimateRoute(config),
|
|
570
|
+
makeBridgeToRemoteRoute(config),
|
|
571
|
+
makeBridgeToRemoteStatusRoute(config),
|
|
572
|
+
makeBridgeFromRemoteStatusRoute(config)
|
|
243
573
|
];
|
|
244
574
|
}, "getRouteDefinitions");
|
|
245
575
|
|
|
246
576
|
// src/server/routes/bridge/addBridgeRoutes.ts
|
|
247
|
-
var addBridgeRoutes = /* @__PURE__ */ __name((app) => {
|
|
248
|
-
const routeDefinitions = getRouteDefinitions();
|
|
577
|
+
var addBridgeRoutes = /* @__PURE__ */ __name((app, config) => {
|
|
578
|
+
const routeDefinitions = getRouteDefinitions(config);
|
|
249
579
|
for (const definition of routeDefinitions) {
|
|
250
580
|
app[definition.method](definition.path, definition.handlers);
|
|
251
581
|
}
|
|
252
582
|
}, "addBridgeRoutes");
|
|
253
583
|
|
|
254
584
|
// src/server/routes/addRoutes.ts
|
|
255
|
-
var addRoutes = /* @__PURE__ */ __name((app) => {
|
|
256
|
-
addBridgeRoutes(app);
|
|
585
|
+
var addRoutes = /* @__PURE__ */ __name((app, config) => {
|
|
586
|
+
addBridgeRoutes(app, config);
|
|
257
587
|
}, "addRoutes");
|
|
258
588
|
|
|
259
589
|
// src/server/app.ts
|
|
260
|
-
var getApp = /* @__PURE__ */ __name(() => {
|
|
590
|
+
var getApp = /* @__PURE__ */ __name((node, config) => {
|
|
261
591
|
addInstrumentation();
|
|
262
592
|
const app = express();
|
|
263
593
|
app.set("etag", false);
|
|
@@ -271,18 +601,615 @@ var getApp = /* @__PURE__ */ __name(() => {
|
|
|
271
601
|
disableExpressDefaultPoweredByHeader(app);
|
|
272
602
|
app.use(customPoweredByHeader);
|
|
273
603
|
disableCaseSensitiveRouting(app);
|
|
274
|
-
|
|
604
|
+
app.node = node;
|
|
605
|
+
addRoutes(app, config);
|
|
275
606
|
app.use(standardErrors);
|
|
276
607
|
return app;
|
|
277
608
|
}, "getApp");
|
|
278
609
|
|
|
610
|
+
// src/server/server.ts
|
|
611
|
+
import { assertEx as assertEx11, isDefined as isDefined8, isString } from "@xylabs/sdk-js";
|
|
612
|
+
import { boot } from "@xyo-network/bios";
|
|
613
|
+
import { HDWallet as HDWallet4 } from "@xyo-network/wallet";
|
|
614
|
+
|
|
615
|
+
// src/manifest/getLocator.ts
|
|
616
|
+
import { BaseMongoSdk } from "@xylabs/mongo";
|
|
617
|
+
import { assertEx as assertEx10, isDefined as isDefined7 } from "@xylabs/sdk-js";
|
|
618
|
+
import { MemoryArchivist } from "@xyo-network/archivist-memory";
|
|
619
|
+
import { MongoDBArchivistV2 } from "@xyo-network/archivist-mongodb";
|
|
620
|
+
import { ViewArchivist } from "@xyo-network/archivist-view";
|
|
621
|
+
import { mapToMapType, MongoMap } from "@xyo-network/chain-protocol";
|
|
622
|
+
import { initEvmProvider } from "@xyo-network/chain-services";
|
|
623
|
+
import { initTelemetry } from "@xyo-network/chain-telemetry";
|
|
624
|
+
import { AbstractModule, LoggerModuleStatusReporter } from "@xyo-network/module-abstract";
|
|
625
|
+
import { ModuleFactoryLocator } from "@xyo-network/module-factory-locator";
|
|
626
|
+
import { MemorySentinel } from "@xyo-network/sentinel-memory";
|
|
627
|
+
import { HDWallet as HDWallet3 } from "@xyo-network/wallet";
|
|
628
|
+
import { hasMongoConfig, SimpleXyoGatewayRunner as SimpleXyoGatewayRunner2, SimpleXyoSigner as SimpleXyoSigner2 } from "@xyo-network/xl1-protocol-sdk";
|
|
629
|
+
import { HttpRpcXyoConnection as HttpRpcXyoConnection2 } from "@xyo-network/xl1-rpc";
|
|
630
|
+
|
|
631
|
+
// src/modules/EVMLiquidityBridgeTransactionCompletionMonitorSentinel/EVMLiquidityBridgeTransactionCompletionMonitorSentinel.ts
|
|
632
|
+
import { asAddress as asAddress5, asHex as asHex4, assertEx as assertEx8, delay, hexFromBigInt, hexToBigInt as hexToBigInt3, isDefined as isDefined5, isUndefined as isUndefined4 } from "@xylabs/sdk-js";
|
|
633
|
+
import { PayloadBuilder as PayloadBuilder4 } from "@xyo-network/payload-builder";
|
|
634
|
+
import { AbstractSentinel } from "@xyo-network/sentinel-abstract";
|
|
635
|
+
import { LiquidityPoolBridge__factory } from "@xyo-network/typechain";
|
|
636
|
+
import { BridgeDestinationObservationSchema as BridgeDestinationObservationSchema3, isBridgeIntent } from "@xyo-network/xl1-protocol";
|
|
637
|
+
import { flattenHydratedTransaction as flattenHydratedTransaction2, flattenHydratedTransactions, tryUnflattenHydratedTransaction } from "@xyo-network/xl1-protocol-sdk";
|
|
638
|
+
import { Mutex } from "async-mutex";
|
|
639
|
+
import { getAddress } from "ethers/address";
|
|
640
|
+
import { Wallet } from "ethers/wallet";
|
|
641
|
+
var EVMLiquidityBridgeTransactionCompletionMonitorSentinelConfigSchema = "network.xyo.sentinel.chain.evm.liquidity.bridge.transaction.completion.monitor.config";
|
|
642
|
+
var defaultJobCheckIntervalMs = 15e3;
|
|
643
|
+
var EVMLiquidityBridgeTransactionCompletionMonitorSentinel = class extends AbstractSentinel {
|
|
644
|
+
static {
|
|
645
|
+
__name(this, "EVMLiquidityBridgeTransactionCompletionMonitorSentinel");
|
|
646
|
+
}
|
|
647
|
+
static configSchemas = [
|
|
648
|
+
EVMLiquidityBridgeTransactionCompletionMonitorSentinelConfigSchema
|
|
649
|
+
];
|
|
650
|
+
static defaultConfigSchema = EVMLiquidityBridgeTransactionCompletionMonitorSentinelConfigSchema;
|
|
651
|
+
_attemptsCounter;
|
|
652
|
+
_bridge;
|
|
653
|
+
_bridgeChainId;
|
|
654
|
+
_bridgeRemoteChainId;
|
|
655
|
+
_bridgeTokenAddress;
|
|
656
|
+
_checkCounter;
|
|
657
|
+
_errorCounter;
|
|
658
|
+
_reportMutex = new Mutex();
|
|
659
|
+
_successCounter;
|
|
660
|
+
_wallet;
|
|
661
|
+
get bridge() {
|
|
662
|
+
return assertEx8(this._bridge, () => new Error("Bridge contract not initialized"));
|
|
663
|
+
}
|
|
664
|
+
get completedTransactions() {
|
|
665
|
+
return assertEx8(this.params.completedTransactions, () => "Completed transactions map is not defined");
|
|
666
|
+
}
|
|
667
|
+
get jobCheckInterval() {
|
|
668
|
+
return isDefined5(this.config.jobCheckInterval) ? this.config.jobCheckInterval : defaultJobCheckIntervalMs;
|
|
669
|
+
}
|
|
670
|
+
get pendingTransactions() {
|
|
671
|
+
return assertEx8(this.params.pendingTransactions, () => "Pending transactions map is not defined");
|
|
672
|
+
}
|
|
673
|
+
get wallet() {
|
|
674
|
+
return assertEx8(this._wallet, () => "wallet is required");
|
|
675
|
+
}
|
|
676
|
+
async createHandler() {
|
|
677
|
+
await super.createHandler();
|
|
678
|
+
this._attemptsCounter = this.meter?.createCounter("evm_liquidity_bridge_transaction_completion_monitor_sentinel_attempts_total", {
|
|
679
|
+
description: "Number of attempts"
|
|
680
|
+
});
|
|
681
|
+
this._checkCounter = this.meter?.createCounter("evm_liquidity_bridge_transaction_completion_monitor_sentinel_check_total", {
|
|
682
|
+
description: "Number of checks"
|
|
683
|
+
});
|
|
684
|
+
this._successCounter = this.meter?.createCounter("evm_liquidity_bridge_transaction_completion_monitor_sentinel_success_total", {
|
|
685
|
+
description: "Number of successes"
|
|
686
|
+
});
|
|
687
|
+
this._errorCounter = this.meter?.createCounter("evm_liquidity_bridge_transaction_completion_monitor_sentinel_errors_total", {
|
|
688
|
+
description: "Number of errors"
|
|
689
|
+
});
|
|
690
|
+
const { provider, bridgeAddress } = this.params;
|
|
691
|
+
const key = assertEx8(this.account?.private?.hex, () => new Error("Account private key is required"));
|
|
692
|
+
this._wallet = new Wallet(key, provider);
|
|
693
|
+
this._bridge = LiquidityPoolBridge__factory.connect(getAddress(bridgeAddress), this._wallet);
|
|
694
|
+
const network = await provider.getNetwork();
|
|
695
|
+
this._bridgeChainId = assertEx8(hexFromBigInt(network.chainId), () => new Error("Failed to parse bridgeChainId"));
|
|
696
|
+
const tokenAddress = await this.bridge.token();
|
|
697
|
+
this._bridgeTokenAddress = asAddress5(tokenAddress, true);
|
|
698
|
+
const bridgeRemoteChain = await this.bridge.remoteChain();
|
|
699
|
+
this._bridgeRemoteChainId = asHex4(bridgeRemoteChain);
|
|
700
|
+
}
|
|
701
|
+
async reportHandler(payloads) {
|
|
702
|
+
if (isDefined5(payloads) && payloads.length > 0) {
|
|
703
|
+
const signedHydratedTransaction = tryUnflattenHydratedTransaction(payloads);
|
|
704
|
+
if (isDefined5(signedHydratedTransaction)) {
|
|
705
|
+
const txHash = await PayloadBuilder4.hash(signedHydratedTransaction[0]);
|
|
706
|
+
this.logger?.info(`Adding transaction ${signedHydratedTransaction[0]} with hash ${txHash} to pending transactions for monitoring`);
|
|
707
|
+
await this.pendingTransactions.set(txHash, signedHydratedTransaction);
|
|
708
|
+
return flattenHydratedTransaction2(signedHydratedTransaction);
|
|
709
|
+
}
|
|
710
|
+
return [];
|
|
711
|
+
} else {
|
|
712
|
+
if (this._reportMutex.isLocked()) {
|
|
713
|
+
this.logger?.debug(`EVMLiquidityBridgeTransactionCompletionMonitorSentinel [${this.id}] is already running, skipping report [${Date.now()}]`);
|
|
714
|
+
return [];
|
|
715
|
+
}
|
|
716
|
+
return await this._reportMutex.runExclusive(async () => {
|
|
717
|
+
const response2 = [];
|
|
718
|
+
if (isUndefined4(payloads) || payloads.length === 0) {
|
|
719
|
+
await this.processAllTransactions();
|
|
720
|
+
}
|
|
721
|
+
return response2;
|
|
722
|
+
});
|
|
723
|
+
}
|
|
724
|
+
}
|
|
725
|
+
async processAllTransactions() {
|
|
726
|
+
const results = [];
|
|
727
|
+
for await (const [hash, signedHydratedTransaction] of this.pendingTransactions) {
|
|
728
|
+
const result = await this.processTransaction([
|
|
729
|
+
hash,
|
|
730
|
+
signedHydratedTransaction
|
|
731
|
+
]);
|
|
732
|
+
if (isDefined5(result)) results.push(result[1]);
|
|
733
|
+
await delay(this.jobCheckInterval);
|
|
734
|
+
}
|
|
735
|
+
return flattenHydratedTransactions(results);
|
|
736
|
+
}
|
|
737
|
+
async processTransaction([hash, signedHydratedTransaction]) {
|
|
738
|
+
this.logger?.info(`Checking for transaction ${signedHydratedTransaction[0]} with hash ${hash}`);
|
|
739
|
+
try {
|
|
740
|
+
let ret = void 0;
|
|
741
|
+
this._checkCounter?.add(1);
|
|
742
|
+
const bridgeIntents = signedHydratedTransaction[1].filter(isBridgeIntent);
|
|
743
|
+
if (bridgeIntents.length !== 1) {
|
|
744
|
+
await this.pendingTransactions.delete(hash);
|
|
745
|
+
return ret;
|
|
746
|
+
}
|
|
747
|
+
const bridgeIntent = bridgeIntents[0];
|
|
748
|
+
this._attemptsCounter?.add(1);
|
|
749
|
+
const bridgeDestinationObservation = await this.relayBridgeIntentSync(bridgeIntent);
|
|
750
|
+
await this.completedTransactions.set(hash, bridgeDestinationObservation);
|
|
751
|
+
await this.pendingTransactions.delete(hash);
|
|
752
|
+
this._successCounter?.add(1);
|
|
753
|
+
return ret;
|
|
754
|
+
} catch (error) {
|
|
755
|
+
this._errorCounter?.add(1);
|
|
756
|
+
this.logger?.error(`Error checking for transaction ${signedHydratedTransaction[0]} with hash ${hash}:`, error);
|
|
757
|
+
}
|
|
758
|
+
}
|
|
759
|
+
/**
|
|
760
|
+
* Relays a given BridgeIntent.
|
|
761
|
+
* @param bridgeIntent The BridgeIntent to relay
|
|
762
|
+
* @returns Relays the intent in a blocking manner, returning the resulting BridgeDestinationObservation if successful
|
|
763
|
+
*/
|
|
764
|
+
async relayBridgeIntentSync(bridgeIntent) {
|
|
765
|
+
const amount = hexToBigInt3(bridgeIntent.destAmount);
|
|
766
|
+
const nonce = await this.wallet.getNonce();
|
|
767
|
+
const srcAddress = getAddress(bridgeIntent.srcAddress);
|
|
768
|
+
const destAddress = getAddress(bridgeIntent.destAddress);
|
|
769
|
+
const tx = await this.bridge.bridgeFromRemote(srcAddress, destAddress, amount, {
|
|
770
|
+
nonce
|
|
771
|
+
});
|
|
772
|
+
const confirmation = await tx.wait();
|
|
773
|
+
const transactionResponse = await confirmation?.getTransaction();
|
|
774
|
+
const destConfirmation = asHex4(transactionResponse?.hash ?? "", true);
|
|
775
|
+
const { schema, ...rest } = bridgeIntent;
|
|
776
|
+
const result = new PayloadBuilder4({
|
|
777
|
+
schema: BridgeDestinationObservationSchema3
|
|
778
|
+
}).fields({
|
|
779
|
+
...rest,
|
|
780
|
+
destConfirmation
|
|
781
|
+
}).build();
|
|
782
|
+
return result;
|
|
783
|
+
}
|
|
784
|
+
};
|
|
785
|
+
|
|
786
|
+
// src/modules/XL1TransactionCompletionMonitorSentinel/XL1TransactionCompletionMonitorSentinel.ts
|
|
787
|
+
import { assertEx as assertEx9, delay as delay2, isDefined as isDefined6, isNull, isUndefined as isUndefined5 } from "@xylabs/sdk-js";
|
|
788
|
+
import { PayloadBuilder as PayloadBuilder5 } from "@xyo-network/payload-builder";
|
|
789
|
+
import { AbstractSentinel as AbstractSentinel2 } from "@xyo-network/sentinel-abstract";
|
|
790
|
+
import { flattenHydratedTransaction as flattenHydratedTransaction3, flattenHydratedTransactions as flattenHydratedTransactions2, tryUnflattenHydratedTransaction as tryUnflattenHydratedTransaction2 } from "@xyo-network/xl1-protocol-sdk";
|
|
791
|
+
import { Mutex as Mutex2 } from "async-mutex";
|
|
792
|
+
var XL1TransactionCompletionMonitorSentinelConfigSchema = "network.xyo.sentinel.chain.transaction.completion.monitor.config";
|
|
793
|
+
var defaultJobCheckIntervalMs2 = 15e3;
|
|
794
|
+
var XL1TransactionCompletionMonitorSentinel = class extends AbstractSentinel2 {
|
|
795
|
+
static {
|
|
796
|
+
__name(this, "XL1TransactionCompletionMonitorSentinel");
|
|
797
|
+
}
|
|
798
|
+
static configSchemas = [
|
|
799
|
+
XL1TransactionCompletionMonitorSentinelConfigSchema
|
|
800
|
+
];
|
|
801
|
+
static defaultConfigSchema = XL1TransactionCompletionMonitorSentinelConfigSchema;
|
|
802
|
+
_attemptsCounter;
|
|
803
|
+
_checkCounter;
|
|
804
|
+
_errorCounter;
|
|
805
|
+
_reportMutex = new Mutex2();
|
|
806
|
+
_successCounter;
|
|
807
|
+
get completedTransactions() {
|
|
808
|
+
return assertEx9(this.params.completedTransactions, () => "Completed transactions map is not defined");
|
|
809
|
+
}
|
|
810
|
+
get jobCheckInterval() {
|
|
811
|
+
return isDefined6(this.config.jobCheckInterval) ? this.config.jobCheckInterval : defaultJobCheckIntervalMs2;
|
|
812
|
+
}
|
|
813
|
+
get pendingTransactions() {
|
|
814
|
+
return assertEx9(this.params.pendingTransactions, () => "Pending transactions map is not defined");
|
|
815
|
+
}
|
|
816
|
+
get viewer() {
|
|
817
|
+
return assertEx9(this.params.viewer, () => "Viewer is not defined in params");
|
|
818
|
+
}
|
|
819
|
+
async createHandler() {
|
|
820
|
+
await super.createHandler();
|
|
821
|
+
this._attemptsCounter = this.meter?.createCounter("xl1_transaction_completion_monitor_sentinel_attempts_total", {
|
|
822
|
+
description: "Number of attempts"
|
|
823
|
+
});
|
|
824
|
+
this._checkCounter = this.meter?.createCounter("xl1_transaction_completion_monitor_sentinel_check_total", {
|
|
825
|
+
description: "Number of checks"
|
|
826
|
+
});
|
|
827
|
+
this._successCounter = this.meter?.createCounter("xl1_transaction_completion_monitor_sentinel_success_total", {
|
|
828
|
+
description: "Number of successes"
|
|
829
|
+
});
|
|
830
|
+
this._errorCounter = this.meter?.createCounter("xl1_transaction_completion_monitor_sentinel_errors_total", {
|
|
831
|
+
description: "Number of errors"
|
|
832
|
+
});
|
|
833
|
+
}
|
|
834
|
+
async reportHandler(payloads) {
|
|
835
|
+
if (isDefined6(payloads) && payloads.length > 0) {
|
|
836
|
+
const signedHydratedTransaction = tryUnflattenHydratedTransaction2(payloads);
|
|
837
|
+
if (isDefined6(signedHydratedTransaction)) {
|
|
838
|
+
const txHash = await PayloadBuilder5.hash(signedHydratedTransaction[0]);
|
|
839
|
+
this.logger?.info(`Adding transaction ${signedHydratedTransaction[0]} with hash ${txHash} to pending transactions for monitoring`);
|
|
840
|
+
await this.pendingTransactions.set(txHash, signedHydratedTransaction);
|
|
841
|
+
return flattenHydratedTransaction3(signedHydratedTransaction);
|
|
842
|
+
}
|
|
843
|
+
return [];
|
|
844
|
+
} else {
|
|
845
|
+
if (this._reportMutex.isLocked()) {
|
|
846
|
+
this.logger?.debug(`XL1TransactionCompletionMonitorSentinel [${this.id}] is already running, skipping report [${Date.now()}]`);
|
|
847
|
+
return [];
|
|
848
|
+
}
|
|
849
|
+
return await this._reportMutex.runExclusive(async () => {
|
|
850
|
+
const response2 = [];
|
|
851
|
+
if (isUndefined5(payloads) || payloads.length === 0) {
|
|
852
|
+
await this.processAllTransactions();
|
|
853
|
+
}
|
|
854
|
+
return response2;
|
|
855
|
+
});
|
|
856
|
+
}
|
|
857
|
+
}
|
|
858
|
+
async processAllTransactions() {
|
|
859
|
+
const results = [];
|
|
860
|
+
for await (const [hash, signedHydratedTransaction] of this.pendingTransactions) {
|
|
861
|
+
const result = await this.processTransaction([
|
|
862
|
+
hash,
|
|
863
|
+
signedHydratedTransaction
|
|
864
|
+
]);
|
|
865
|
+
if (isDefined6(result)) results.push(result[1]);
|
|
866
|
+
await delay2(this.jobCheckInterval);
|
|
867
|
+
}
|
|
868
|
+
return flattenHydratedTransactions2(results);
|
|
869
|
+
}
|
|
870
|
+
async processTransaction([hash, signedHydratedTransaction]) {
|
|
871
|
+
this.logger?.info(`Checking for transaction ${signedHydratedTransaction[0]} with hash ${hash}`);
|
|
872
|
+
try {
|
|
873
|
+
let ret = void 0;
|
|
874
|
+
this._checkCounter?.add(1);
|
|
875
|
+
this._attemptsCounter?.add(1);
|
|
876
|
+
const tx = await this.viewer.transactionByHash(hash);
|
|
877
|
+
if (isDefined6(tx) && !isNull(tx)) {
|
|
878
|
+
await this.completedTransactions.set(hash, signedHydratedTransaction);
|
|
879
|
+
this.logger?.info(`Found transaction ${signedHydratedTransaction[0]} with hash ${hash}`);
|
|
880
|
+
this.logger?.info(`Removing completed transaction ${signedHydratedTransaction[0]} with hash ${hash}`);
|
|
881
|
+
await this.pendingTransactions.delete(hash);
|
|
882
|
+
ret = [
|
|
883
|
+
hash,
|
|
884
|
+
signedHydratedTransaction
|
|
885
|
+
];
|
|
886
|
+
} else {
|
|
887
|
+
const currentBlockNumber = await this.viewer.currentBlockNumber();
|
|
888
|
+
if (signedHydratedTransaction[0].exp < currentBlockNumber) {
|
|
889
|
+
this.logger?.info(`Removing expired transaction ${signedHydratedTransaction[0]} with hash ${hash}`);
|
|
890
|
+
await this.pendingTransactions.delete(hash);
|
|
891
|
+
}
|
|
892
|
+
}
|
|
893
|
+
this._successCounter?.add(1);
|
|
894
|
+
return ret;
|
|
895
|
+
} catch (error) {
|
|
896
|
+
this._errorCounter?.add(1);
|
|
897
|
+
this.logger?.error(`Error checking for transaction ${signedHydratedTransaction[0]} with hash ${hash}:`, error);
|
|
898
|
+
}
|
|
899
|
+
}
|
|
900
|
+
};
|
|
901
|
+
|
|
902
|
+
// src/manifest/getLocator.ts
|
|
903
|
+
var getLocator = /* @__PURE__ */ __name(async (context) => {
|
|
904
|
+
const { config, logger } = context;
|
|
905
|
+
const { otlpEndpoint } = config.telemetry?.otel ?? {};
|
|
906
|
+
const { path: endpoint = "/metrics", port = 9468 } = config.telemetry?.metrics?.scrape ?? {};
|
|
907
|
+
const { traceProvider, meterProvider } = await initTelemetry({
|
|
908
|
+
attributes: {
|
|
909
|
+
serviceName: "xl1-bridge",
|
|
910
|
+
serviceVersion: "1.0.0"
|
|
911
|
+
},
|
|
912
|
+
otlpEndpoint,
|
|
913
|
+
metricsConfig: {
|
|
914
|
+
endpoint,
|
|
915
|
+
port
|
|
916
|
+
}
|
|
917
|
+
});
|
|
918
|
+
if (isDefined7(logger)) AbstractModule.defaultLogger = logger;
|
|
919
|
+
const statusReporter = logger ? new LoggerModuleStatusReporter(logger) : void 0;
|
|
920
|
+
const locator = new ModuleFactoryLocator();
|
|
921
|
+
const mongoConfig = config.storage?.mongo;
|
|
922
|
+
if (hasMongoConfig(mongoConfig)) {
|
|
923
|
+
const { connectionString: dbConnectionString, database: dbName, domain: dbDomain, password: dbPassword, username: dbUserName } = mongoConfig;
|
|
924
|
+
const payloadSdkConfig = {
|
|
925
|
+
dbConnectionString,
|
|
926
|
+
dbDomain,
|
|
927
|
+
dbName,
|
|
928
|
+
dbPassword,
|
|
929
|
+
dbUserName
|
|
930
|
+
};
|
|
931
|
+
const params = {
|
|
932
|
+
meterProvider,
|
|
933
|
+
payloadSdkConfig,
|
|
934
|
+
statusReporter,
|
|
935
|
+
traceProvider
|
|
936
|
+
};
|
|
937
|
+
locator.register(MongoDBArchivistV2.factory(params), void 0, true);
|
|
938
|
+
}
|
|
939
|
+
locator.register(MemoryArchivist.factory({
|
|
940
|
+
traceProvider,
|
|
941
|
+
meterProvider,
|
|
942
|
+
statusReporter
|
|
943
|
+
}));
|
|
944
|
+
locator.register(MemorySentinel.factory({
|
|
945
|
+
traceProvider,
|
|
946
|
+
meterProvider,
|
|
947
|
+
statusReporter
|
|
948
|
+
}));
|
|
949
|
+
locator.register(ViewArchivist.factory({
|
|
950
|
+
traceProvider,
|
|
951
|
+
meterProvider,
|
|
952
|
+
statusReporter
|
|
953
|
+
}));
|
|
954
|
+
const gateway = await getGateway2(config);
|
|
955
|
+
const viewer = assertEx10(gateway.connectionInstance.viewer, () => "Gateway viewer is not defined");
|
|
956
|
+
const pendingXl1ToEthXl1BridgeIntentTransactions = await getIterableMap(config, "liquidity_bridge_xl1_to_eth_xl1_pending");
|
|
957
|
+
const completedXl1ToEthXl1BridgeIntentTransactions = await getIterableMap(config, "liquidity_bridge_xl1_to_eth_xl1_completed");
|
|
958
|
+
const xl1TransactionCompletionMonitorSentinelParams = {
|
|
959
|
+
completedTransactions: completedXl1ToEthXl1BridgeIntentTransactions,
|
|
960
|
+
config: {
|
|
961
|
+
schema: XL1TransactionCompletionMonitorSentinelConfigSchema
|
|
962
|
+
},
|
|
963
|
+
meterProvider,
|
|
964
|
+
pendingTransactions: pendingXl1ToEthXl1BridgeIntentTransactions,
|
|
965
|
+
statusReporter,
|
|
966
|
+
traceProvider,
|
|
967
|
+
viewer
|
|
968
|
+
};
|
|
969
|
+
locator.register(XL1TransactionCompletionMonitorSentinel.factory(xl1TransactionCompletionMonitorSentinelParams));
|
|
970
|
+
const completedEthXl1BridgeTransactions = await getIterableMap(config, "liquidity_bridge_eth_xl1_bridge_completed");
|
|
971
|
+
const provider = await initEvmProvider({
|
|
972
|
+
config
|
|
973
|
+
});
|
|
974
|
+
const bridgeAddress = config.bridge.remoteBridgeContractAddress;
|
|
975
|
+
const evmLiquidityBridgeTransactionCompletionMonitorSentinelParams = {
|
|
976
|
+
bridgeAddress,
|
|
977
|
+
completedTransactions: completedEthXl1BridgeTransactions,
|
|
978
|
+
config: {
|
|
979
|
+
schema: EVMLiquidityBridgeTransactionCompletionMonitorSentinelConfigSchema
|
|
980
|
+
},
|
|
981
|
+
meterProvider,
|
|
982
|
+
pendingTransactions: completedXl1ToEthXl1BridgeIntentTransactions,
|
|
983
|
+
provider,
|
|
984
|
+
statusReporter,
|
|
985
|
+
traceProvider
|
|
986
|
+
};
|
|
987
|
+
locator.register(EVMLiquidityBridgeTransactionCompletionMonitorSentinel.factory(evmLiquidityBridgeTransactionCompletionMonitorSentinelParams));
|
|
988
|
+
return locator;
|
|
989
|
+
}, "getLocator");
|
|
990
|
+
var getGateway2 = /* @__PURE__ */ __name(async (config) => {
|
|
991
|
+
const { mnemonic, chainRpcApiUrl: endpoint } = config.bridge;
|
|
992
|
+
const walletPromise = isDefined7(mnemonic) ? HDWallet3.fromPhrase(mnemonic) : HDWallet3.random();
|
|
993
|
+
const account = await walletPromise;
|
|
994
|
+
const signer = new SimpleXyoSigner2(account);
|
|
995
|
+
const connection = new HttpRpcXyoConnection2({
|
|
996
|
+
endpoint
|
|
997
|
+
});
|
|
998
|
+
const gateway = new SimpleXyoGatewayRunner2(connection, signer);
|
|
999
|
+
return gateway;
|
|
1000
|
+
}, "getGateway");
|
|
1001
|
+
var getIterableMap = /* @__PURE__ */ __name(async (config, collection) => {
|
|
1002
|
+
const mongoConfig = config.storage?.mongo;
|
|
1003
|
+
if (hasMongoConfig(mongoConfig)) {
|
|
1004
|
+
const { connectionString: dbConnectionString, database: dbName, domain: dbDomain, password: dbPassword, username: dbUserName } = mongoConfig;
|
|
1005
|
+
const payloadSdkConfig = {
|
|
1006
|
+
dbConnectionString,
|
|
1007
|
+
dbDomain,
|
|
1008
|
+
dbName,
|
|
1009
|
+
dbPassword,
|
|
1010
|
+
dbUserName
|
|
1011
|
+
};
|
|
1012
|
+
const sdkBalanceSummaryMap = new BaseMongoSdk({
|
|
1013
|
+
...payloadSdkConfig,
|
|
1014
|
+
collection
|
|
1015
|
+
});
|
|
1016
|
+
const result = await MongoMap.create({
|
|
1017
|
+
sdk: sdkBalanceSummaryMap,
|
|
1018
|
+
getCache: {
|
|
1019
|
+
enabled: true,
|
|
1020
|
+
maxEntries: 5e3
|
|
1021
|
+
}
|
|
1022
|
+
});
|
|
1023
|
+
return result;
|
|
1024
|
+
} else {
|
|
1025
|
+
return mapToMapType(/* @__PURE__ */ new Map());
|
|
1026
|
+
}
|
|
1027
|
+
}, "getIterableMap");
|
|
1028
|
+
|
|
1029
|
+
// src/manifest/getNode.ts
|
|
1030
|
+
import { ManifestWrapper } from "@xyo-network/manifest-wrapper";
|
|
1031
|
+
|
|
1032
|
+
// src/manifest/node.json
|
|
1033
|
+
var node_default = {
|
|
1034
|
+
$schema: "https://raw.githubusercontent.com/XYOracleNetwork/sdk-xyo-client-js/main/packages/manifest/src/schema.json",
|
|
1035
|
+
nodes: [
|
|
1036
|
+
{
|
|
1037
|
+
config: {
|
|
1038
|
+
accountPath: "44'/60'/1",
|
|
1039
|
+
name: "XYOEthereumBridge",
|
|
1040
|
+
schema: "network.xyo.node.config"
|
|
1041
|
+
},
|
|
1042
|
+
modules: {
|
|
1043
|
+
private: [],
|
|
1044
|
+
public: []
|
|
1045
|
+
}
|
|
1046
|
+
}
|
|
1047
|
+
],
|
|
1048
|
+
schema: "network.xyo.manifest"
|
|
1049
|
+
};
|
|
1050
|
+
|
|
1051
|
+
// src/manifest/nodeManifest.ts
|
|
1052
|
+
var NodeManifest = node_default;
|
|
1053
|
+
|
|
1054
|
+
// src/manifest/private/index.ts
|
|
1055
|
+
var PrivateChildManifests = [];
|
|
1056
|
+
|
|
1057
|
+
// src/manifest/public/XL1.json
|
|
1058
|
+
var XL1_default = {
|
|
1059
|
+
$schema: "https://raw.githubusercontent.com/XYOracleNetwork/sdk-xyo-client-js/main/packages/manifest/src/schema.json",
|
|
1060
|
+
nodes: [
|
|
1061
|
+
{
|
|
1062
|
+
config: {
|
|
1063
|
+
accountPath: "2",
|
|
1064
|
+
name: "XL1",
|
|
1065
|
+
schema: "network.xyo.node.config"
|
|
1066
|
+
},
|
|
1067
|
+
modules: {
|
|
1068
|
+
private: [
|
|
1069
|
+
{
|
|
1070
|
+
config: {
|
|
1071
|
+
accountPath: "1/1'/1'",
|
|
1072
|
+
automations: [
|
|
1073
|
+
{
|
|
1074
|
+
frequency: 6e4,
|
|
1075
|
+
frequencyUnits: "millis",
|
|
1076
|
+
schema: "network.xyo.automation.interval",
|
|
1077
|
+
type: "interval"
|
|
1078
|
+
}
|
|
1079
|
+
],
|
|
1080
|
+
name: "XL1BridgeIntentTransactionCompletionMonitorSentinelIntervalSentinel",
|
|
1081
|
+
schema: "network.xyo.sentinel.config",
|
|
1082
|
+
synchronous: true,
|
|
1083
|
+
tasks: [
|
|
1084
|
+
{
|
|
1085
|
+
mod: "XL1BridgeIntentTransactionCompletionMonitorSentinel",
|
|
1086
|
+
endPoint: "report"
|
|
1087
|
+
}
|
|
1088
|
+
]
|
|
1089
|
+
}
|
|
1090
|
+
}
|
|
1091
|
+
],
|
|
1092
|
+
public: [
|
|
1093
|
+
{
|
|
1094
|
+
config: {
|
|
1095
|
+
accountPath: "1/1/1",
|
|
1096
|
+
name: "XL1BridgeIntentTransactionCompletionMonitorSentinel",
|
|
1097
|
+
schema: "network.xyo.sentinel.chain.transaction.completion.monitor.config"
|
|
1098
|
+
}
|
|
1099
|
+
}
|
|
1100
|
+
]
|
|
1101
|
+
}
|
|
1102
|
+
}
|
|
1103
|
+
],
|
|
1104
|
+
schema: "network.xyo.manifest"
|
|
1105
|
+
};
|
|
1106
|
+
|
|
1107
|
+
// src/manifest/public/Ethereum.json
|
|
1108
|
+
var Ethereum_default = {
|
|
1109
|
+
$schema: "https://raw.githubusercontent.com/XYOracleNetwork/sdk-xyo-client-js/main/packages/manifest/src/schema.json",
|
|
1110
|
+
nodes: [
|
|
1111
|
+
{
|
|
1112
|
+
config: {
|
|
1113
|
+
accountPath: "3",
|
|
1114
|
+
name: "Ethereum",
|
|
1115
|
+
schema: "network.xyo.node.config"
|
|
1116
|
+
},
|
|
1117
|
+
modules: {
|
|
1118
|
+
private: [
|
|
1119
|
+
{
|
|
1120
|
+
config: {
|
|
1121
|
+
accountPath: "1/1'/1'",
|
|
1122
|
+
automations: [
|
|
1123
|
+
{
|
|
1124
|
+
frequency: 6e4,
|
|
1125
|
+
frequencyUnits: "millis",
|
|
1126
|
+
schema: "network.xyo.automation.interval",
|
|
1127
|
+
type: "interval"
|
|
1128
|
+
}
|
|
1129
|
+
],
|
|
1130
|
+
name: "EVMLiquidityBridgeTransactionCompletionMonitorSentinelIntervalSentinel",
|
|
1131
|
+
schema: "network.xyo.sentinel.config",
|
|
1132
|
+
synchronous: true,
|
|
1133
|
+
tasks: [
|
|
1134
|
+
{
|
|
1135
|
+
mod: "EVMLiquidityBridgeTransactionCompletionMonitorSentinel",
|
|
1136
|
+
endPoint: "report"
|
|
1137
|
+
}
|
|
1138
|
+
]
|
|
1139
|
+
}
|
|
1140
|
+
}
|
|
1141
|
+
],
|
|
1142
|
+
public: [
|
|
1143
|
+
{
|
|
1144
|
+
config: {
|
|
1145
|
+
accountPath: "1/1/1",
|
|
1146
|
+
name: "EVMLiquidityBridgeTransactionCompletionMonitorSentinel",
|
|
1147
|
+
schema: "network.xyo.sentinel.chain.evm.liquidity.bridge.transaction.completion.monitor.config"
|
|
1148
|
+
}
|
|
1149
|
+
}
|
|
1150
|
+
]
|
|
1151
|
+
}
|
|
1152
|
+
}
|
|
1153
|
+
],
|
|
1154
|
+
schema: "network.xyo.manifest"
|
|
1155
|
+
};
|
|
1156
|
+
|
|
1157
|
+
// src/manifest/public/index.ts
|
|
1158
|
+
var XL1NodeManifest = XL1_default;
|
|
1159
|
+
var EthereumNodeManifest = Ethereum_default;
|
|
1160
|
+
var PublicChildManifests = [
|
|
1161
|
+
...XL1NodeManifest.nodes,
|
|
1162
|
+
...EthereumNodeManifest.nodes
|
|
1163
|
+
];
|
|
1164
|
+
|
|
1165
|
+
// src/manifest/getNode.ts
|
|
1166
|
+
var getNode = /* @__PURE__ */ __name(async (context) => {
|
|
1167
|
+
const { wallet } = context;
|
|
1168
|
+
const locator = await getLocator(context);
|
|
1169
|
+
const wrapper = new ManifestWrapper(NodeManifest, wallet, locator, PublicChildManifests, PrivateChildManifests);
|
|
1170
|
+
const [node, ...childNodes] = await wrapper.loadNodes();
|
|
1171
|
+
if (childNodes?.length > 0) {
|
|
1172
|
+
await Promise.all(childNodes.map((childNode) => node.register(childNode)));
|
|
1173
|
+
await Promise.all(childNodes.map((childNode) => node.attach(childNode.address, true)));
|
|
1174
|
+
}
|
|
1175
|
+
return node;
|
|
1176
|
+
}, "getNode");
|
|
1177
|
+
|
|
279
1178
|
// src/server/server.ts
|
|
280
1179
|
var hostname = "::";
|
|
1180
|
+
var getSeedPhrase = /* @__PURE__ */ __name(async (bios, config, logger) => {
|
|
1181
|
+
const storedSeedPhrase = await bios.seedPhraseStore.get("os");
|
|
1182
|
+
logger?.debug(`[Bridge] Stored mnemonic: ${storedSeedPhrase}`);
|
|
1183
|
+
const { mnemonic } = config.api;
|
|
1184
|
+
if (isString(storedSeedPhrase) && isString(mnemonic)) {
|
|
1185
|
+
logger?.warn("[Bridge] Stored mnemonic does not match supplied. Updating stored mnemonic to supplied.");
|
|
1186
|
+
await bios.seedPhraseStore.set("os", mnemonic);
|
|
1187
|
+
} else {
|
|
1188
|
+
let seedPhrase;
|
|
1189
|
+
if (isString(mnemonic)) {
|
|
1190
|
+
seedPhrase = mnemonic;
|
|
1191
|
+
} else {
|
|
1192
|
+
seedPhrase = HDWallet4.generateMnemonic();
|
|
1193
|
+
logger?.log("[Bridge] No mnemonic provided, using random mnemonic. This is not recommended for production use.");
|
|
1194
|
+
logger?.log(`[Bridge] Mnemonic: ${seedPhrase}`);
|
|
1195
|
+
}
|
|
1196
|
+
await bios.seedPhraseStore.set("os", seedPhrase);
|
|
1197
|
+
}
|
|
1198
|
+
return assertEx11(await bios.seedPhraseStore.get("os"), () => "Unable to acquire mnemonic from bios");
|
|
1199
|
+
}, "getSeedPhrase");
|
|
281
1200
|
var getServer = /* @__PURE__ */ __name(async (context) => {
|
|
282
|
-
const { logger } = context;
|
|
283
|
-
const { port } =
|
|
284
|
-
await
|
|
285
|
-
const
|
|
1201
|
+
const { logger, config } = context;
|
|
1202
|
+
const { port, mnemonic } = config.bridge;
|
|
1203
|
+
const bios = await boot();
|
|
1204
|
+
const seedPhrase = isDefined8(mnemonic) ? mnemonic : await getSeedPhrase(bios, config, logger);
|
|
1205
|
+
const wallet = await HDWallet4.fromPhrase(seedPhrase);
|
|
1206
|
+
const nodeContext = {
|
|
1207
|
+
wallet,
|
|
1208
|
+
logger,
|
|
1209
|
+
config
|
|
1210
|
+
};
|
|
1211
|
+
const node = context.node ?? await getNode(nodeContext);
|
|
1212
|
+
const app = getApp(node, config);
|
|
286
1213
|
const server = app.listen(port, hostname, () => logger?.log(`[Bridge] Server listening at http://${hostname}:${port}`));
|
|
287
1214
|
server.setTimeout(2e4);
|
|
288
1215
|
return server;
|