@xyo-network/chain-bridge 1.20.28 → 1.21.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.
Files changed (344) hide show
  1. package/dist/node/BridgeActor.d.ts +5 -3
  2. package/dist/node/BridgeActor.d.ts.map +1 -1
  3. package/dist/node/command.d.ts +5 -0
  4. package/dist/node/command.d.ts.map +1 -0
  5. package/dist/node/index.d.ts +3 -1
  6. package/dist/node/index.d.ts.map +1 -1
  7. package/dist/node/index.mjs +1271 -515
  8. package/dist/node/index.mjs.map +1 -1
  9. package/dist/node/run.d.ts +6 -0
  10. package/dist/node/run.d.ts.map +1 -0
  11. package/dist/node/server/addWorkers.d.ts.map +1 -1
  12. package/dist/node/server/routes/bridge/routeDefinitions/routes/bridgeFromRemoteStatus.d.ts +81 -0
  13. package/dist/node/server/routes/bridge/routeDefinitions/routes/bridgeFromRemoteStatus.d.ts.map +1 -1
  14. package/dist/node/server/routes/bridge/routeDefinitions/routes/bridgeToRemoteEstimate.d.ts +2 -2
  15. package/dist/node/server/routes/bridge/routeDefinitions/routes/bridgeToRemoteMaxEstimate.d.ts +2 -2
  16. package/dist/node/server/server.d.ts.map +1 -1
  17. package/dist/node/services/BridgeFulfillmentState.d.ts +54 -0
  18. package/dist/node/services/BridgeFulfillmentState.d.ts.map +1 -0
  19. package/dist/node/services/IBridgeServiceCollection.d.ts +7 -0
  20. package/dist/node/services/IBridgeServiceCollection.d.ts.map +1 -1
  21. package/dist/node/services/evm/asChainId.d.ts.map +1 -0
  22. package/dist/node/services/evm/asToken.d.ts.map +1 -0
  23. package/dist/node/services/evm/getBridgeEscrowAddress.d.ts.map +1 -0
  24. package/dist/node/services/evm/getBridgeFeesAddress.d.ts.map +1 -0
  25. package/dist/node/services/evm/getBridgeSettings.d.ts.map +1 -0
  26. package/dist/node/services/evm/getBridgeWalletAccount.d.ts.map +1 -0
  27. package/dist/node/services/evm/getFeeStructure.d.ts.map +1 -0
  28. package/dist/node/services/evm/getMaxBridgeAmount.d.ts.map +1 -0
  29. package/dist/node/services/evm/getMinBridgeAmount.d.ts.map +1 -0
  30. package/dist/node/services/evm/getRemoteChainId.d.ts.map +1 -0
  31. package/dist/node/services/evm/getRemoteConfirmationDepth.d.ts +4 -0
  32. package/dist/node/services/evm/getRemoteConfirmationDepth.d.ts.map +1 -0
  33. package/dist/node/services/evm/getRemoteTokenAddress.d.ts.map +1 -0
  34. package/dist/node/services/evm/getScannerIntervalMs.d.ts +9 -0
  35. package/dist/node/services/evm/getScannerIntervalMs.d.ts.map +1 -0
  36. package/dist/node/services/evm/getTestGateway.d.ts.map +1 -0
  37. package/dist/node/services/evm/getTransferAddresses.d.ts.map +1 -0
  38. package/dist/node/services/evm/getXl1ChainId.d.ts.map +1 -0
  39. package/dist/node/services/evm/getXl1TokenAddress.d.ts.map +1 -0
  40. package/dist/node/{config → services/evm}/index.d.ts +2 -0
  41. package/dist/node/services/evm/index.d.ts.map +1 -0
  42. package/dist/node/services/getServices.d.ts.map +1 -1
  43. package/dist/node/services/index.d.ts +1 -0
  44. package/dist/node/services/index.d.ts.map +1 -1
  45. package/dist/node/services/interface/index.d.ts.map +1 -0
  46. package/dist/node/services/interface/interface/ChainBridgeRelayInterface.d.ts.map +1 -0
  47. package/dist/node/services/interface/interface/IntentIndexerInterface.d.ts.map +1 -0
  48. package/dist/node/services/interface/interface/LockingProcessorInterface.d.ts.map +1 -0
  49. package/dist/node/services/interface/interface/ObservationIndexerInterface.d.ts.map +1 -0
  50. package/dist/node/services/interface/interface/Params.d.ts.map +1 -0
  51. package/dist/node/services/interface/interface/RelayInterface.d.ts.map +1 -0
  52. package/dist/node/services/interface/interface/index.d.ts.map +1 -0
  53. package/dist/node/services/interface/repository/RepositoryInterface.d.ts.map +1 -0
  54. package/dist/node/services/interface/repository/index.d.ts.map +1 -0
  55. package/dist/node/services/interface/service/Observer/ERC20TransferObserver/ERC20TransferObserver.d.ts.map +1 -0
  56. package/dist/node/services/interface/service/Observer/ERC20TransferObserver/index.d.ts.map +1 -0
  57. package/dist/node/services/interface/service/Observer/LiquidityPoolBridgeObserver/LiquidityPoolBridgeObserver.d.ts.map +1 -0
  58. package/dist/node/services/interface/service/Observer/LiquidityPoolBridgeObserver/index.d.ts.map +1 -0
  59. package/dist/node/services/interface/service/Observer/Observer.d.ts.map +1 -0
  60. package/dist/node/services/interface/service/Observer/index.d.ts.map +1 -0
  61. package/dist/node/services/interface/service/Relay/ChainBridgeRelay/ChainBridgeRelayInterface.d.ts.map +1 -0
  62. package/dist/node/services/interface/service/Relay/ChainBridgeRelay/ChainBridgeRelayService.d.ts.map +1 -0
  63. package/dist/node/services/interface/service/Relay/ChainBridgeRelay/index.d.ts.map +1 -0
  64. package/dist/node/services/interface/service/Relay/LiquidityPoolBridgeRelay/LiquidityPoolBridgeRelay.d.ts.map +1 -0
  65. package/dist/node/services/interface/service/Relay/LiquidityPoolBridgeRelay/index.d.ts.map +1 -0
  66. package/dist/node/services/interface/service/Relay/index.d.ts.map +1 -0
  67. package/dist/node/services/interface/service/index.d.ts.map +1 -0
  68. package/dist/node/services/interface/util/getBridgeIntentIdentifier.d.ts.map +1 -0
  69. package/dist/node/services/interface/util/index.d.ts.map +1 -0
  70. package/dist/node/services/modules/EVMLiquidityBridgeTransactionCompletionMonitorSentinel/EVMLiquidityBridgeTransactionCompletionMonitorSentinel.d.ts.map +1 -0
  71. package/dist/node/services/modules/EVMLiquidityBridgeTransactionCompletionMonitorSentinel/index.d.ts.map +1 -0
  72. package/dist/node/services/modules/index.d.ts.map +1 -0
  73. package/dist/node/services/queue/connection.d.ts.map +1 -0
  74. package/dist/node/services/queue/flowProducer.d.ts.map +1 -0
  75. package/dist/node/services/queue/flows/createEthToXl1BridgeJob/createEthToXl1BridgeJob.d.ts +34 -0
  76. package/dist/node/services/queue/flows/createEthToXl1BridgeJob/createEthToXl1BridgeJob.d.ts.map +1 -0
  77. package/dist/node/services/queue/flows/createEthToXl1BridgeJob/getJobIdForEthToXl1BridgeJob.d.ts +25 -0
  78. package/dist/node/services/queue/flows/createEthToXl1BridgeJob/getJobIdForEthToXl1BridgeJob.d.ts.map +1 -0
  79. package/dist/node/services/queue/flows/createEthToXl1BridgeJob/index.d.ts +3 -0
  80. package/dist/node/services/queue/flows/createEthToXl1BridgeJob/index.d.ts.map +1 -0
  81. package/dist/node/services/queue/flows/createXl1ToEthBridgeJob/createXl1ToEthBridgeJob.d.ts.map +1 -0
  82. package/dist/node/services/queue/flows/createXl1ToEthBridgeJob/getJobIdForXl1ToEthBridgeJob.d.ts.map +1 -0
  83. package/dist/node/services/queue/flows/createXl1ToEthBridgeJob/getXl1ToEthBridgeJob.d.ts.map +1 -0
  84. package/dist/node/services/queue/flows/createXl1ToEthBridgeJob/index.d.ts.map +1 -0
  85. package/dist/node/services/queue/flows/index.d.ts +3 -0
  86. package/dist/node/services/queue/flows/index.d.ts.map +1 -0
  87. package/dist/node/services/queue/getEthToXl1Queues.d.ts +23 -0
  88. package/dist/node/services/queue/getEthToXl1Queues.d.ts.map +1 -0
  89. package/dist/node/services/queue/getXl1ToEthQueueJobs.d.ts.map +1 -0
  90. package/dist/node/services/queue/getXl1ToEthQueues.d.ts.map +1 -0
  91. package/dist/node/{queue → services/queue}/index.d.ts +2 -0
  92. package/dist/node/services/queue/index.d.ts.map +1 -0
  93. package/dist/node/services/queue/prefix.d.ts.map +1 -0
  94. package/dist/node/services/queue/scanner/EvmBridgeCursor.d.ts +6 -0
  95. package/dist/node/services/queue/scanner/EvmBridgeCursor.d.ts.map +1 -0
  96. package/dist/node/services/queue/scanner/EvmBridgeScanner.d.ts +36 -0
  97. package/dist/node/services/queue/scanner/EvmBridgeScanner.d.ts.map +1 -0
  98. package/dist/node/services/queue/scanner/EvmBridgeScannerRunner.d.ts +29 -0
  99. package/dist/node/services/queue/scanner/EvmBridgeScannerRunner.d.ts.map +1 -0
  100. package/dist/node/services/queue/scanner/buildEvmBridgeScannerRunner.d.ts +24 -0
  101. package/dist/node/services/queue/scanner/buildEvmBridgeScannerRunner.d.ts.map +1 -0
  102. package/dist/node/services/queue/scanner/createEnqueueEthToXl1Bridge.d.ts +30 -0
  103. package/dist/node/services/queue/scanner/createEnqueueEthToXl1Bridge.d.ts.map +1 -0
  104. package/dist/node/services/queue/scanner/index.d.ts +6 -0
  105. package/dist/node/services/queue/scanner/index.d.ts.map +1 -0
  106. package/dist/node/services/queue/telemetry.d.ts.map +1 -0
  107. package/dist/node/services/queue/workers/EthEventVerification.d.ts +12 -0
  108. package/dist/node/services/queue/workers/EthEventVerification.d.ts.map +1 -0
  109. package/dist/node/{queue → services/queue}/workers/EthToXl1BridgeParent.d.ts +2 -0
  110. package/dist/node/services/queue/workers/EthToXl1BridgeParent.d.ts.map +1 -0
  111. package/dist/node/services/queue/workers/EthTransactionMonitor.d.ts.map +1 -0
  112. package/dist/node/{queue → services/queue}/workers/EthTransactionPreparation.d.ts +1 -1
  113. package/dist/node/services/queue/workers/EthTransactionPreparation.d.ts.map +1 -0
  114. package/dist/node/{queue → services/queue}/workers/EthTransactionSubmission.d.ts +1 -1
  115. package/dist/node/services/queue/workers/EthTransactionSubmission.d.ts.map +1 -0
  116. package/dist/node/{queue → services/queue}/workers/EthTransactionSubmissionStorage.d.ts +1 -1
  117. package/dist/node/services/queue/workers/EthTransactionSubmissionStorage.d.ts.map +1 -0
  118. package/dist/node/{queue → services/queue}/workers/WorkerDescription.d.ts +1 -1
  119. package/dist/node/services/queue/workers/WorkerDescription.d.ts.map +1 -0
  120. package/dist/node/services/queue/workers/Xl1ReserveTxFulfillment.d.ts +21 -0
  121. package/dist/node/services/queue/workers/Xl1ReserveTxFulfillment.d.ts.map +1 -0
  122. package/dist/node/services/queue/workers/Xl1ToEthBridgeParent.d.ts.map +1 -0
  123. package/dist/node/services/queue/workers/Xl1TransactionJobData.d.ts.map +1 -0
  124. package/dist/node/services/queue/workers/Xl1TransactionMonitor.d.ts.map +1 -0
  125. package/dist/node/services/queue/workers/Xl1TransactionPreparation.d.ts.map +1 -0
  126. package/dist/node/{queue → services/queue}/workers/Xl1TransactionSubmission.d.ts +1 -1
  127. package/dist/node/services/queue/workers/Xl1TransactionSubmission.d.ts.map +1 -0
  128. package/dist/node/{queue → services/queue}/workers/Xl1TransactionSubmissionStorage.d.ts +1 -1
  129. package/dist/node/services/queue/workers/Xl1TransactionSubmissionStorage.d.ts.map +1 -0
  130. package/dist/node/{queue → services/queue}/workers/createWorkers.d.ts +1 -1
  131. package/dist/node/services/queue/workers/createWorkers.d.ts.map +1 -0
  132. package/dist/node/{queue → services/queue}/workers/index.d.ts +2 -0
  133. package/dist/node/services/queue/workers/index.d.ts.map +1 -0
  134. package/dist/node/services/queue/workers/util/buildEthToXl1ReserveTx.d.ts +36 -0
  135. package/dist/node/services/queue/workers/util/buildEthToXl1ReserveTx.d.ts.map +1 -0
  136. package/dist/node/services/queue/workers/util/index.d.ts +6 -0
  137. package/dist/node/services/queue/workers/util/index.d.ts.map +1 -0
  138. package/dist/node/services/queue/workers/util/resolveEvmBlockTagAtDepth.d.ts +16 -0
  139. package/dist/node/services/queue/workers/util/resolveEvmBlockTagAtDepth.d.ts.map +1 -0
  140. package/dist/node/services/queue/workers/util/submitEthTransaction.d.ts.map +1 -0
  141. package/dist/node/services/queue/workers/util/submitXl1Transaction.d.ts.map +1 -0
  142. package/dist/node/services/queue/workers/util/verifyEthBridgeEvent.d.ts +31 -0
  143. package/dist/node/services/queue/workers/util/verifyEthBridgeEvent.d.ts.map +1 -0
  144. package/dist/node/services/util/BridgeFees.d.ts.map +1 -0
  145. package/dist/node/services/util/bridgeFeesAsBigInt.d.ts.map +1 -0
  146. package/dist/node/services/util/calculateBridgeFees.d.ts.map +1 -0
  147. package/dist/node/services/util/calculateMaxBridgeAmount.d.ts.map +1 -0
  148. package/dist/node/services/util/createBridgeTransfer.d.ts.map +1 -0
  149. package/dist/node/services/util/generateBridgeEstimate.d.ts.map +1 -0
  150. package/dist/node/services/util/getConfigFromEnv.d.ts.map +1 -0
  151. package/dist/node/services/util/index.d.ts.map +1 -0
  152. package/dist/node/services/validation/AsyncLogger.d.ts.map +1 -0
  153. package/dist/node/{validation → services/validation}/index.d.ts +1 -0
  154. package/dist/node/services/validation/index.d.ts.map +1 -0
  155. package/dist/node/services/validation/validateBridgeEstimate.d.ts.map +1 -0
  156. package/dist/node/services/validation/validateBridgeEstimateExact.d.ts.map +1 -0
  157. package/dist/node/services/validation/validateBridgeTransaction.d.ts.map +1 -0
  158. package/dist/node/services/validation/validateSufficientLiquiditySourceAllowance.d.ts.map +1 -0
  159. package/dist/node/services/validation/validateSufficientLiquiditySourceBalance.d.ts.map +1 -0
  160. package/dist/node/services/validation/validateSufficientRunnerEthBalanceForGas.d.ts.map +1 -0
  161. package/dist/node/services/validation/validateSufficientXL1SourceAddressBalance.d.ts.map +1 -0
  162. package/dist/node/services/validation/validateSufficientXl1ReserveBalance.d.ts +28 -0
  163. package/dist/node/services/validation/validateSufficientXl1ReserveBalance.d.ts.map +1 -0
  164. package/dist/node/telemetry/createBalanceMonitor.d.ts.map +1 -0
  165. package/dist/node/telemetry/createQueueMetrics.d.ts +20 -0
  166. package/dist/node/telemetry/createQueueMetrics.d.ts.map +1 -0
  167. package/dist/node/telemetry/index.d.ts.map +1 -0
  168. package/package.json +140 -132
  169. package/dist/node/config/asChainId.d.ts.map +0 -1
  170. package/dist/node/config/asToken.d.ts.map +0 -1
  171. package/dist/node/config/getBridgeEscrowAddress.d.ts.map +0 -1
  172. package/dist/node/config/getBridgeFeesAddress.d.ts.map +0 -1
  173. package/dist/node/config/getBridgeSettings.d.ts.map +0 -1
  174. package/dist/node/config/getBridgeWalletAccount.d.ts.map +0 -1
  175. package/dist/node/config/getFeeStructure.d.ts.map +0 -1
  176. package/dist/node/config/getMaxBridgeAmount.d.ts.map +0 -1
  177. package/dist/node/config/getMinBridgeAmount.d.ts.map +0 -1
  178. package/dist/node/config/getRemoteChainId.d.ts.map +0 -1
  179. package/dist/node/config/getRemoteTokenAddress.d.ts.map +0 -1
  180. package/dist/node/config/getTestGateway.d.ts.map +0 -1
  181. package/dist/node/config/getTransferAddresses.d.ts.map +0 -1
  182. package/dist/node/config/getXl1ChainId.d.ts.map +0 -1
  183. package/dist/node/config/getXl1TokenAddress.d.ts.map +0 -1
  184. package/dist/node/config/index.d.ts.map +0 -1
  185. package/dist/node/interface/index.d.ts.map +0 -1
  186. package/dist/node/interface/interface/ChainBridgeRelayInterface.d.ts.map +0 -1
  187. package/dist/node/interface/interface/IntentIndexerInterface.d.ts.map +0 -1
  188. package/dist/node/interface/interface/LockingProcessorInterface.d.ts.map +0 -1
  189. package/dist/node/interface/interface/ObservationIndexerInterface.d.ts.map +0 -1
  190. package/dist/node/interface/interface/Params.d.ts.map +0 -1
  191. package/dist/node/interface/interface/RelayInterface.d.ts.map +0 -1
  192. package/dist/node/interface/interface/index.d.ts.map +0 -1
  193. package/dist/node/interface/repository/RepositoryInterface.d.ts.map +0 -1
  194. package/dist/node/interface/repository/index.d.ts.map +0 -1
  195. package/dist/node/interface/service/Observer/ERC20TransferObserver/ERC20TransferObserver.d.ts.map +0 -1
  196. package/dist/node/interface/service/Observer/ERC20TransferObserver/index.d.ts.map +0 -1
  197. package/dist/node/interface/service/Observer/LiquidityPoolBridgeObserver/LiquidityPoolBridgeObserver.d.ts.map +0 -1
  198. package/dist/node/interface/service/Observer/LiquidityPoolBridgeObserver/index.d.ts.map +0 -1
  199. package/dist/node/interface/service/Observer/Observer.d.ts.map +0 -1
  200. package/dist/node/interface/service/Observer/index.d.ts.map +0 -1
  201. package/dist/node/interface/service/Relay/ChainBridgeRelay/ChainBridgeRelayInterface.d.ts.map +0 -1
  202. package/dist/node/interface/service/Relay/ChainBridgeRelay/ChainBridgeRelayService.d.ts.map +0 -1
  203. package/dist/node/interface/service/Relay/ChainBridgeRelay/index.d.ts.map +0 -1
  204. package/dist/node/interface/service/Relay/LiquidityPoolBridgeRelay/LiquidityPoolBridgeRelay.d.ts.map +0 -1
  205. package/dist/node/interface/service/Relay/LiquidityPoolBridgeRelay/index.d.ts.map +0 -1
  206. package/dist/node/interface/service/Relay/index.d.ts.map +0 -1
  207. package/dist/node/interface/service/index.d.ts.map +0 -1
  208. package/dist/node/interface/util/getBridgeIntentIdentifier.d.ts.map +0 -1
  209. package/dist/node/interface/util/index.d.ts.map +0 -1
  210. package/dist/node/modules/EVMLiquidityBridgeTransactionCompletionMonitorSentinel/EVMLiquidityBridgeTransactionCompletionMonitorSentinel.d.ts.map +0 -1
  211. package/dist/node/modules/EVMLiquidityBridgeTransactionCompletionMonitorSentinel/index.d.ts.map +0 -1
  212. package/dist/node/modules/index.d.ts.map +0 -1
  213. package/dist/node/monitoring/createBalanceMonitor.d.ts.map +0 -1
  214. package/dist/node/monitoring/createQueueMetrics.d.ts +0 -13
  215. package/dist/node/monitoring/createQueueMetrics.d.ts.map +0 -1
  216. package/dist/node/monitoring/index.d.ts.map +0 -1
  217. package/dist/node/queue/connection.d.ts.map +0 -1
  218. package/dist/node/queue/flowProducer.d.ts.map +0 -1
  219. package/dist/node/queue/flows/createEthToXl1BridgeJob.d.ts +0 -10
  220. package/dist/node/queue/flows/createEthToXl1BridgeJob.d.ts.map +0 -1
  221. package/dist/node/queue/flows/createXl1ToEthBridgeJob/createXl1ToEthBridgeJob.d.ts.map +0 -1
  222. package/dist/node/queue/flows/createXl1ToEthBridgeJob/getJobIdForXl1ToEthBridgeJob.d.ts.map +0 -1
  223. package/dist/node/queue/flows/createXl1ToEthBridgeJob/getXl1ToEthBridgeJob.d.ts.map +0 -1
  224. package/dist/node/queue/flows/createXl1ToEthBridgeJob/index.d.ts.map +0 -1
  225. package/dist/node/queue/flows/index.d.ts +0 -3
  226. package/dist/node/queue/flows/index.d.ts.map +0 -1
  227. package/dist/node/queue/getXl1ToEthQueueJobs.d.ts.map +0 -1
  228. package/dist/node/queue/getXl1ToEthQueues.d.ts.map +0 -1
  229. package/dist/node/queue/index.d.ts.map +0 -1
  230. package/dist/node/queue/prefix.d.ts.map +0 -1
  231. package/dist/node/queue/telemetry.d.ts.map +0 -1
  232. package/dist/node/queue/workers/EthToXl1BridgeParent.d.ts.map +0 -1
  233. package/dist/node/queue/workers/EthTransactionMonitor.d.ts.map +0 -1
  234. package/dist/node/queue/workers/EthTransactionPreparation.d.ts.map +0 -1
  235. package/dist/node/queue/workers/EthTransactionSubmission.d.ts.map +0 -1
  236. package/dist/node/queue/workers/EthTransactionSubmissionStorage.d.ts.map +0 -1
  237. package/dist/node/queue/workers/WorkerDescription.d.ts.map +0 -1
  238. package/dist/node/queue/workers/Xl1ToEthBridgeParent.d.ts.map +0 -1
  239. package/dist/node/queue/workers/Xl1TransactionJobData.d.ts.map +0 -1
  240. package/dist/node/queue/workers/Xl1TransactionMonitor.d.ts.map +0 -1
  241. package/dist/node/queue/workers/Xl1TransactionPreparation.d.ts.map +0 -1
  242. package/dist/node/queue/workers/Xl1TransactionSubmission.d.ts.map +0 -1
  243. package/dist/node/queue/workers/Xl1TransactionSubmissionStorage.d.ts.map +0 -1
  244. package/dist/node/queue/workers/createWorkers.d.ts.map +0 -1
  245. package/dist/node/queue/workers/index.d.ts.map +0 -1
  246. package/dist/node/queue/workers/util/index.d.ts +0 -3
  247. package/dist/node/queue/workers/util/index.d.ts.map +0 -1
  248. package/dist/node/queue/workers/util/submitEthTransaction.d.ts.map +0 -1
  249. package/dist/node/queue/workers/util/submitXl1Transaction.d.ts.map +0 -1
  250. package/dist/node/util/BridgeFees.d.ts.map +0 -1
  251. package/dist/node/util/bridgeFeesAsBigInt.d.ts.map +0 -1
  252. package/dist/node/util/calculateBridgeFees.d.ts.map +0 -1
  253. package/dist/node/util/calculateMaxBridgeAmount.d.ts.map +0 -1
  254. package/dist/node/util/createBridgeTransfer.d.ts.map +0 -1
  255. package/dist/node/util/generateBridgeEstimate.d.ts.map +0 -1
  256. package/dist/node/util/getConfigFromEnv.d.ts.map +0 -1
  257. package/dist/node/util/index.d.ts.map +0 -1
  258. package/dist/node/validation/AsyncLogger.d.ts.map +0 -1
  259. package/dist/node/validation/index.d.ts.map +0 -1
  260. package/dist/node/validation/validateBridgeEstimate.d.ts.map +0 -1
  261. package/dist/node/validation/validateBridgeEstimateExact.d.ts.map +0 -1
  262. package/dist/node/validation/validateBridgeTransaction.d.ts.map +0 -1
  263. package/dist/node/validation/validateSufficientLiquiditySourceAllowance.d.ts.map +0 -1
  264. package/dist/node/validation/validateSufficientLiquiditySourceBalance.d.ts.map +0 -1
  265. package/dist/node/validation/validateSufficientRunnerEthBalanceForGas.d.ts.map +0 -1
  266. package/dist/node/validation/validateSufficientXL1SourceAddressBalance.d.ts.map +0 -1
  267. /package/dist/node/{config → services/evm}/asChainId.d.ts +0 -0
  268. /package/dist/node/{config → services/evm}/asToken.d.ts +0 -0
  269. /package/dist/node/{config → services/evm}/getBridgeEscrowAddress.d.ts +0 -0
  270. /package/dist/node/{config → services/evm}/getBridgeFeesAddress.d.ts +0 -0
  271. /package/dist/node/{config → services/evm}/getBridgeSettings.d.ts +0 -0
  272. /package/dist/node/{config → services/evm}/getBridgeWalletAccount.d.ts +0 -0
  273. /package/dist/node/{config → services/evm}/getFeeStructure.d.ts +0 -0
  274. /package/dist/node/{config → services/evm}/getMaxBridgeAmount.d.ts +0 -0
  275. /package/dist/node/{config → services/evm}/getMinBridgeAmount.d.ts +0 -0
  276. /package/dist/node/{config → services/evm}/getRemoteChainId.d.ts +0 -0
  277. /package/dist/node/{config → services/evm}/getRemoteTokenAddress.d.ts +0 -0
  278. /package/dist/node/{config → services/evm}/getTestGateway.d.ts +0 -0
  279. /package/dist/node/{config → services/evm}/getTransferAddresses.d.ts +0 -0
  280. /package/dist/node/{config → services/evm}/getXl1ChainId.d.ts +0 -0
  281. /package/dist/node/{config → services/evm}/getXl1TokenAddress.d.ts +0 -0
  282. /package/dist/node/{interface → services/interface}/index.d.ts +0 -0
  283. /package/dist/node/{interface → services/interface}/interface/ChainBridgeRelayInterface.d.ts +0 -0
  284. /package/dist/node/{interface → services/interface}/interface/IntentIndexerInterface.d.ts +0 -0
  285. /package/dist/node/{interface → services/interface}/interface/LockingProcessorInterface.d.ts +0 -0
  286. /package/dist/node/{interface → services/interface}/interface/ObservationIndexerInterface.d.ts +0 -0
  287. /package/dist/node/{interface → services/interface}/interface/Params.d.ts +0 -0
  288. /package/dist/node/{interface → services/interface}/interface/RelayInterface.d.ts +0 -0
  289. /package/dist/node/{interface → services/interface}/interface/index.d.ts +0 -0
  290. /package/dist/node/{interface → services/interface}/repository/RepositoryInterface.d.ts +0 -0
  291. /package/dist/node/{interface → services/interface}/repository/index.d.ts +0 -0
  292. /package/dist/node/{interface → services/interface}/service/Observer/ERC20TransferObserver/ERC20TransferObserver.d.ts +0 -0
  293. /package/dist/node/{interface → services/interface}/service/Observer/ERC20TransferObserver/index.d.ts +0 -0
  294. /package/dist/node/{interface → services/interface}/service/Observer/LiquidityPoolBridgeObserver/LiquidityPoolBridgeObserver.d.ts +0 -0
  295. /package/dist/node/{interface → services/interface}/service/Observer/LiquidityPoolBridgeObserver/index.d.ts +0 -0
  296. /package/dist/node/{interface → services/interface}/service/Observer/Observer.d.ts +0 -0
  297. /package/dist/node/{interface → services/interface}/service/Observer/index.d.ts +0 -0
  298. /package/dist/node/{interface → services/interface}/service/Relay/ChainBridgeRelay/ChainBridgeRelayInterface.d.ts +0 -0
  299. /package/dist/node/{interface → services/interface}/service/Relay/ChainBridgeRelay/ChainBridgeRelayService.d.ts +0 -0
  300. /package/dist/node/{interface → services/interface}/service/Relay/ChainBridgeRelay/index.d.ts +0 -0
  301. /package/dist/node/{interface → services/interface}/service/Relay/LiquidityPoolBridgeRelay/LiquidityPoolBridgeRelay.d.ts +0 -0
  302. /package/dist/node/{interface → services/interface}/service/Relay/LiquidityPoolBridgeRelay/index.d.ts +0 -0
  303. /package/dist/node/{interface → services/interface}/service/Relay/index.d.ts +0 -0
  304. /package/dist/node/{interface → services/interface}/service/index.d.ts +0 -0
  305. /package/dist/node/{interface → services/interface}/util/getBridgeIntentIdentifier.d.ts +0 -0
  306. /package/dist/node/{interface → services/interface}/util/index.d.ts +0 -0
  307. /package/dist/node/{modules → services/modules}/EVMLiquidityBridgeTransactionCompletionMonitorSentinel/EVMLiquidityBridgeTransactionCompletionMonitorSentinel.d.ts +0 -0
  308. /package/dist/node/{modules → services/modules}/EVMLiquidityBridgeTransactionCompletionMonitorSentinel/index.d.ts +0 -0
  309. /package/dist/node/{modules → services/modules}/index.d.ts +0 -0
  310. /package/dist/node/{queue → services/queue}/connection.d.ts +0 -0
  311. /package/dist/node/{queue → services/queue}/flowProducer.d.ts +0 -0
  312. /package/dist/node/{queue → services/queue}/flows/createXl1ToEthBridgeJob/createXl1ToEthBridgeJob.d.ts +0 -0
  313. /package/dist/node/{queue → services/queue}/flows/createXl1ToEthBridgeJob/getJobIdForXl1ToEthBridgeJob.d.ts +0 -0
  314. /package/dist/node/{queue → services/queue}/flows/createXl1ToEthBridgeJob/getXl1ToEthBridgeJob.d.ts +0 -0
  315. /package/dist/node/{queue → services/queue}/flows/createXl1ToEthBridgeJob/index.d.ts +0 -0
  316. /package/dist/node/{queue → services/queue}/getXl1ToEthQueueJobs.d.ts +0 -0
  317. /package/dist/node/{queue → services/queue}/getXl1ToEthQueues.d.ts +0 -0
  318. /package/dist/node/{queue → services/queue}/prefix.d.ts +0 -0
  319. /package/dist/node/{queue → services/queue}/telemetry.d.ts +0 -0
  320. /package/dist/node/{queue → services/queue}/workers/EthTransactionMonitor.d.ts +0 -0
  321. /package/dist/node/{queue → services/queue}/workers/Xl1ToEthBridgeParent.d.ts +0 -0
  322. /package/dist/node/{queue → services/queue}/workers/Xl1TransactionJobData.d.ts +0 -0
  323. /package/dist/node/{queue → services/queue}/workers/Xl1TransactionMonitor.d.ts +0 -0
  324. /package/dist/node/{queue → services/queue}/workers/Xl1TransactionPreparation.d.ts +0 -0
  325. /package/dist/node/{queue → services/queue}/workers/util/submitEthTransaction.d.ts +0 -0
  326. /package/dist/node/{queue → services/queue}/workers/util/submitXl1Transaction.d.ts +0 -0
  327. /package/dist/node/{util → services/util}/BridgeFees.d.ts +0 -0
  328. /package/dist/node/{util → services/util}/bridgeFeesAsBigInt.d.ts +0 -0
  329. /package/dist/node/{util → services/util}/calculateBridgeFees.d.ts +0 -0
  330. /package/dist/node/{util → services/util}/calculateMaxBridgeAmount.d.ts +0 -0
  331. /package/dist/node/{util → services/util}/createBridgeTransfer.d.ts +0 -0
  332. /package/dist/node/{util → services/util}/generateBridgeEstimate.d.ts +0 -0
  333. /package/dist/node/{util → services/util}/getConfigFromEnv.d.ts +0 -0
  334. /package/dist/node/{util → services/util}/index.d.ts +0 -0
  335. /package/dist/node/{validation → services/validation}/AsyncLogger.d.ts +0 -0
  336. /package/dist/node/{validation → services/validation}/validateBridgeEstimate.d.ts +0 -0
  337. /package/dist/node/{validation → services/validation}/validateBridgeEstimateExact.d.ts +0 -0
  338. /package/dist/node/{validation → services/validation}/validateBridgeTransaction.d.ts +0 -0
  339. /package/dist/node/{validation → services/validation}/validateSufficientLiquiditySourceAllowance.d.ts +0 -0
  340. /package/dist/node/{validation → services/validation}/validateSufficientLiquiditySourceBalance.d.ts +0 -0
  341. /package/dist/node/{validation → services/validation}/validateSufficientRunnerEthBalanceForGas.d.ts +0 -0
  342. /package/dist/node/{validation → services/validation}/validateSufficientXL1SourceAddressBalance.d.ts +0 -0
  343. /package/dist/node/{monitoring → telemetry}/createBalanceMonitor.d.ts +0 -0
  344. /package/dist/node/{monitoring → telemetry}/index.d.ts +0 -0
@@ -3,143 +3,15 @@ var __name = (target, value) => __defProp(target, "name", { value, configurable:
3
3
 
4
4
  // src/BridgeActor.ts
5
5
  import { creatable } from "@xylabs/sdk-js";
6
- import { asBridgeConfigContext } from "@xyo-network/chain-orchestration";
7
- import { ActorV3, XyoGatewayRunnerMoniker } from "@xyo-network/xl1-sdk";
6
+ import { ActorV3, asBridgeConfigContext } from "@xyo-network/chain-orchestration";
7
+ import { XyoGatewayRunnerMoniker, XyoViewerMoniker } from "@xyo-network/xl1-sdk";
8
8
 
9
- // src/monitoring/createBalanceMonitor.ts
10
- var DEFAULT_INTERVAL_MS = 6e4;
11
- var WEI_PER_GWEI = 10n ** 9n;
12
- var TOKEN_DECIMALS = 10n ** 18n;
13
- function createBalanceMonitor(config) {
14
- const { account, bridge, bridgeableToken, gateway, meter, provider, wallet, intervalMs = DEFAULT_INTERVAL_MS } = config;
15
- let timer;
16
- const ethWalletGasBalance = meter.createGauge("bridge_eth_wallet_gas_balance_gwei", {
17
- description: "ETH balance of the bridge runner wallet (in gwei)",
18
- unit: "gwei"
19
- });
20
- const liquidityTokenBalance = meter.createGauge("bridge_eth_liquidity_token_balance", {
21
- description: "ERC-20 token balance of the liquidity source (in whole tokens)",
22
- unit: "tokens"
23
- });
24
- const liquidityTokenAllowance = meter.createGauge("bridge_eth_liquidity_token_allowance", {
25
- description: "ERC-20 token allowance from liquidity source to bridge contract (in whole tokens)",
26
- unit: "tokens"
27
- });
28
- const xl1AccountBalance = meter.createGauge("bridge_xl1_account_balance", {
29
- description: "XL1 native balance of the bridge account (in whole XL1)",
30
- unit: "xl1"
31
- });
32
- const walletAddress = wallet.address;
33
- async function poll() {
34
- try {
35
- const balance = await provider.getBalance(walletAddress);
36
- ethWalletGasBalance.record(Number(balance / WEI_PER_GWEI), {
37
- address: walletAddress
38
- });
39
- } catch (err) {
40
- console.error("[BalanceMonitor] Failed to read ETH wallet gas balance:", err);
41
- }
42
- try {
43
- const liquiditySourceAddress = await bridge.liquiditySource();
44
- const balance = await bridgeableToken.balanceOf(liquiditySourceAddress);
45
- liquidityTokenBalance.record(Number(balance / TOKEN_DECIMALS), {
46
- address: liquiditySourceAddress
47
- });
48
- } catch (err) {
49
- console.error("[BalanceMonitor] Failed to read liquidity source token balance:", err);
50
- }
51
- try {
52
- const liquiditySourceAddress = await bridge.liquiditySource();
53
- const bridgeAddress = await bridge.getAddress();
54
- const allowance = await bridgeableToken.allowance(liquiditySourceAddress, bridgeAddress);
55
- liquidityTokenAllowance.record(Number(allowance / TOKEN_DECIMALS), {
56
- address: liquiditySourceAddress
57
- });
58
- } catch (err) {
59
- console.error("[BalanceMonitor] Failed to read liquidity source token allowance:", err);
60
- }
61
- try {
62
- const viewer = gateway.connection.viewer;
63
- if (viewer) {
64
- const balance = await viewer.account.balance.accountBalance(account.address);
65
- xl1AccountBalance.record(Number(balance / TOKEN_DECIMALS), {
66
- address: account.address.toString()
67
- });
68
- }
69
- } catch (err) {
70
- console.error("[BalanceMonitor] Failed to read XL1 account balance:", err);
71
- }
72
- }
73
- __name(poll, "poll");
74
- return {
75
- start() {
76
- void poll();
77
- timer = setInterval(() => void poll(), intervalMs);
78
- },
79
- stop() {
80
- if (timer) {
81
- clearInterval(timer);
82
- timer = void 0;
83
- }
84
- }
85
- };
86
- }
87
- __name(createBalanceMonitor, "createBalanceMonitor");
88
-
89
- // src/monitoring/createQueueMetrics.ts
90
- var DEFAULT_INTERVAL_MS2 = 3e4;
91
- function createQueueMetrics(config) {
92
- const { meter, queues, intervalMs = DEFAULT_INTERVAL_MS2 } = config;
93
- let timer;
94
- const waitingGauge = meter.createGauge("bridge_queue_waiting", {
95
- description: "Number of waiting jobs in the bridge queue"
96
- });
97
- const activeGauge = meter.createGauge("bridge_queue_active", {
98
- description: "Number of active jobs in the bridge queue"
99
- });
100
- const completedGauge = meter.createGauge("bridge_queue_completed", {
101
- description: "Number of completed jobs in the bridge queue"
102
- });
103
- const failedGauge = meter.createGauge("bridge_queue_failed", {
104
- description: "Number of failed jobs in the bridge queue"
105
- });
106
- const delayedGauge = meter.createGauge("bridge_queue_delayed", {
107
- description: "Number of delayed jobs in the bridge queue"
108
- });
109
- async function poll() {
110
- for (const [name10, queue] of Object.entries(queues)) {
111
- try {
112
- const counts = await queue.getJobCounts("waiting", "active", "completed", "failed", "delayed");
113
- const attrs = {
114
- queue_name: name10
115
- };
116
- waitingGauge.record(counts.waiting ?? 0, attrs);
117
- activeGauge.record(counts.active ?? 0, attrs);
118
- completedGauge.record(counts.completed ?? 0, attrs);
119
- failedGauge.record(counts.failed ?? 0, attrs);
120
- delayedGauge.record(counts.delayed ?? 0, attrs);
121
- } catch (err) {
122
- console.error(`[QueueMetrics] Failed to read job counts for queue ${name10}:`, err);
123
- }
124
- }
125
- }
126
- __name(poll, "poll");
127
- return {
128
- start() {
129
- void poll();
130
- timer = setInterval(() => void poll(), intervalMs);
131
- },
132
- stop() {
133
- if (timer) {
134
- clearInterval(timer);
135
- timer = void 0;
136
- }
137
- }
138
- };
139
- }
140
- __name(createQueueMetrics, "createQueueMetrics");
9
+ // src/server/app.ts
10
+ import { standardErrors } from "@xylabs/express";
11
+ import { sharedMiddleware } from "@xyo-network/chain-orchestration";
12
+ import express from "express";
141
13
 
142
- // src/queue/connection.ts
14
+ // src/services/queue/connection.ts
143
15
  import { isDefined } from "@xylabs/sdk-js";
144
16
  import { Redis } from "ioredis";
145
17
  var connection;
@@ -155,14 +27,14 @@ var getConnection = /* @__PURE__ */ __name((config) => {
155
27
  return connection;
156
28
  }, "getConnection");
157
29
 
158
- // src/queue/flowProducer.ts
30
+ // src/services/queue/flowProducer.ts
159
31
  import { isDefined as isDefined2 } from "@xylabs/sdk-js";
160
32
  import { FlowProducer } from "bullmq";
161
33
 
162
- // src/queue/prefix.ts
34
+ // src/services/queue/prefix.ts
163
35
  var prefix = "xl1-bridge";
164
36
 
165
- // src/queue/flowProducer.ts
37
+ // src/services/queue/flowProducer.ts
166
38
  var flowProducer;
167
39
  var getFlowProducer = /* @__PURE__ */ __name((connection2, telemetry2) => {
168
40
  if (isDefined2(flowProducer)) return flowProducer;
@@ -174,21 +46,210 @@ var getFlowProducer = /* @__PURE__ */ __name((connection2, telemetry2) => {
174
46
  return flowProducer;
175
47
  }, "getFlowProducer");
176
48
 
177
- // src/queue/workers/EthTransactionMonitor.ts
178
- import { assertEx } from "@xylabs/sdk-js";
49
+ // src/services/queue/workers/EthEventVerification.ts
50
+ import { assertEx as assertEx2, isNull } from "@xylabs/sdk-js";
51
+ import { UnrecoverableError, Worker } from "bullmq";
52
+
53
+ // src/services/queue/workers/util/buildEthToXl1ReserveTx.ts
54
+ import { toHex } from "@xylabs/sdk-js";
179
55
  import { PayloadBuilder } from "@xyo-network/sdk-js";
180
- import { Worker } from "bullmq";
181
- var name = "Monitor Submitted ETH Transaction";
182
- var queueName = "eth-tx-monitor";
56
+ import { BridgeIntentSchema, BridgeSourceObservationSchema, buildTransaction, createTransferPayload } from "@xyo-network/xl1-sdk";
57
+ async function buildEthToXl1ReserveTx(options2) {
58
+ const { amount, bridgeAccount, bridgeId, destAddress, evmChainId, evmContractAddress, evmSrcAddress, evmTokenAddress, evmTxHash, exp, nbf, xl1ChainId, xl1TokenAddress } = options2;
59
+ const amountHex = toHex(amount);
60
+ const nonce = `evm:${evmChainId.toLowerCase()}:${evmContractAddress.toLowerCase()}:${bridgeId.toString()}`;
61
+ const transfer = createTransferPayload(bridgeAccount.address, {
62
+ [destAddress]: amount
63
+ });
64
+ const intent = new PayloadBuilder({
65
+ schema: BridgeIntentSchema
66
+ }).fields({
67
+ dest: xl1ChainId,
68
+ destAddress,
69
+ destAmount: amountHex,
70
+ destToken: xl1TokenAddress,
71
+ nonce,
72
+ src: evmChainId,
73
+ srcAddress: evmSrcAddress,
74
+ srcAmount: amountHex,
75
+ srcToken: evmTokenAddress
76
+ }).build();
77
+ const sourceObservation = new PayloadBuilder({
78
+ schema: BridgeSourceObservationSchema
79
+ }).fields({
80
+ dest: xl1ChainId,
81
+ destAddress,
82
+ destAmount: amountHex,
83
+ destToken: xl1TokenAddress,
84
+ src: evmChainId,
85
+ srcAddress: evmSrcAddress,
86
+ srcAmount: amountHex,
87
+ srcConfirmation: evmTxHash,
88
+ srcToken: evmTokenAddress
89
+ }).build();
90
+ return buildTransaction(xl1ChainId, [
91
+ transfer
92
+ ], [
93
+ intent,
94
+ sourceObservation
95
+ ], bridgeAccount, nbf, exp);
96
+ }
97
+ __name(buildEthToXl1ReserveTx, "buildEthToXl1ReserveTx");
98
+
99
+ // src/services/queue/workers/util/resolveEvmBlockTagAtDepth.ts
100
+ async function resolveEvmBlockTagAtDepth(provider, depth) {
101
+ if (depth === "finalized") return "finalized";
102
+ const head = await provider.getBlockNumber();
103
+ return Math.max(head - depth, 0);
104
+ }
105
+ __name(resolveEvmBlockTagAtDepth, "resolveEvmBlockTagAtDepth");
106
+
107
+ // src/services/queue/workers/util/submitEthTransaction.ts
108
+ import { assertEx, hexToBigInt, toEthAddress } from "@xylabs/sdk-js";
109
+ import { PayloadBuilder as PayloadBuilder2 } from "@xyo-network/sdk-js";
110
+ import { isBridgeIntent } from "@xyo-network/xl1-sdk";
111
+ var submitEthTransaction = /* @__PURE__ */ __name(async (tx, offChainPayloads, bridge, wallet) => {
112
+ const xl1Transaction = assertEx(tx[0], () => "No corresponding XL1 transaction found");
113
+ const allPayloads = [
114
+ ...tx[1],
115
+ ...offChainPayloads
116
+ ];
117
+ const bridgeIntent = assertEx(allPayloads.find(isBridgeIntent), () => "No bridge intent found");
118
+ const srcAddress = toEthAddress(bridgeIntent.srcAddress);
119
+ const destAddress = toEthAddress(bridgeIntent.destAddress);
120
+ const amount = hexToBigInt(bridgeIntent.destAmount);
121
+ const nonce = hexToBigInt(await PayloadBuilder2.hash(xl1Transaction));
122
+ const bridgeTx = await bridge.connect(wallet).bridgeFromRemote(srcAddress, destAddress, amount, nonce);
123
+ const receipt = await bridgeTx.wait(1);
124
+ return receipt?.hash;
125
+ }, "submitEthTransaction");
126
+
127
+ // src/services/queue/workers/util/submitXl1Transaction.ts
128
+ var submitXl1Transaction = /* @__PURE__ */ __name(async (preparedTx, offChain = [], gateway) => {
129
+ const result = await gateway.addTransactionToChain(preparedTx, offChain);
130
+ return result;
131
+ }, "submitXl1Transaction");
132
+
133
+ // src/services/queue/workers/util/verifyEthBridgeEvent.ts
134
+ import { asHex, toAddress } from "@xylabs/sdk-js";
135
+ import { ZeroAddress } from "ethers";
136
+ async function verifyEthBridgeEvent(id, bridge, provider, confirmationDepth) {
137
+ const blockTag = await resolveEvmBlockTagAtDepth(provider, confirmationDepth);
138
+ const data = await bridge.bridgesToRemote(id, {
139
+ blockTag
140
+ });
141
+ if (data.srcAddress === ZeroAddress) {
142
+ return null;
143
+ }
144
+ const filter = bridge.filters.BridgedToRemote(id);
145
+ const events = await bridge.queryFilter(filter, 0, blockTag);
146
+ const event = events[0];
147
+ if (event === void 0) {
148
+ return null;
149
+ }
150
+ return {
151
+ amount: data.amount,
152
+ destAddress: toAddress(data.destAddress),
153
+ destToken: toAddress(data.destToken),
154
+ evmTxHash: asHex(event.transactionHash, true),
155
+ srcAddress: toAddress(data.srcAddress)
156
+ };
157
+ }
158
+ __name(verifyEthBridgeEvent, "verifyEthBridgeEvent");
159
+
160
+ // src/services/queue/workers/EthEventVerification.ts
161
+ var name = "Verify ETH Bridge Event at Depth";
162
+ var queueName = "eth-event-verify";
183
163
  var createWorker = /* @__PURE__ */ __name((connection2, telemetry2, services) => {
184
- const provider = assertEx(services?.provider, () => "provider service not provided");
185
- const stateMap = assertEx(services?.ethTxStateMap, () => "ethTxStateMap service not provided");
164
+ const svc = assertEx2(services, () => "services not provided");
165
+ const { bridge, bridgeFulfillmentMap, provider, remoteConfirmationDepth } = svc;
186
166
  const worker = new Worker(queueName, async (job) => {
167
+ const { bridgeId, identity } = job.data;
168
+ const id = BigInt(bridgeId);
169
+ const existing = await bridgeFulfillmentMap.get(identity);
170
+ if (existing?.canonical) {
171
+ await job.log(`[${identity}] canonical already set; verification skipped`);
172
+ return;
173
+ }
174
+ const state = existing ?? {
175
+ identity,
176
+ previousAttempts: []
177
+ };
178
+ if (state.failed) state.failed = void 0;
179
+ await job.log(`[${identity}] verifying BridgedToRemote(${id}) at depth ${remoteConfirmationDepth}`);
180
+ const data = await verifyEthBridgeEvent(id, bridge, provider, remoteConfirmationDepth);
181
+ if (isNull(data)) {
182
+ state.failed = {
183
+ at: Date.now(),
184
+ reason: "non-canonical at confirmation depth \u2014 orphaned by reorg or never reached canonical state"
185
+ };
186
+ await bridgeFulfillmentMap.set(identity, state);
187
+ await job.log(`[${identity}] non-canonical at depth \u2014 marked failed`);
188
+ throw new UnrecoverableError(`[${identity}] bridgesToRemote slot empty at confirmation depth ${remoteConfirmationDepth}`);
189
+ }
190
+ state.canonical = data;
191
+ await bridgeFulfillmentMap.set(identity, state);
192
+ await job.log(`[${identity}] verified: src=${data.srcAddress} dest=${data.destAddress} amount=${data.amount} evmTxHash=${data.evmTxHash}`);
193
+ }, {
194
+ connection: connection2,
195
+ telemetry: telemetry2,
196
+ prefix
197
+ });
198
+ worker.on("failed", (job, err) => {
199
+ console.error(`[${name}] Job ${job?.id} failed:`, err.message);
200
+ });
201
+ worker.on("error", (err) => {
202
+ console.error(`[${name}] Worker error:`, err);
203
+ });
204
+ }, "createWorker");
205
+ var EthEventVerification = {
206
+ createWorker,
207
+ name,
208
+ queueName
209
+ };
210
+
211
+ // src/services/queue/workers/EthToXl1BridgeParent.ts
212
+ import { Worker as Worker2 } from "bullmq";
213
+ var name2 = "Bridge Ethereum to XL1";
214
+ var queueName2 = "eth-to-xl1-bridge";
215
+ var createWorker2 = /* @__PURE__ */ __name((connection2, telemetry2) => {
216
+ const worker = new Worker2(queueName2, async (job) => {
217
+ await job.log(`[${job.name}] start`);
218
+ await job.log(`[${job.name}] done`);
219
+ return {};
220
+ }, {
221
+ connection: connection2,
222
+ telemetry: telemetry2,
223
+ prefix
224
+ });
225
+ worker.on("failed", (job, err) => {
226
+ console.error(`[${name2}] Job ${job?.id} failed:`, err.message);
227
+ });
228
+ worker.on("error", (err) => {
229
+ console.error(`[${name2}] Worker error:`, err);
230
+ });
231
+ }, "createWorker");
232
+ var EthToXl1BridgeParent = {
233
+ createWorker: createWorker2,
234
+ name: name2,
235
+ queueName: queueName2
236
+ };
237
+
238
+ // src/services/queue/workers/EthTransactionMonitor.ts
239
+ import { assertEx as assertEx3 } from "@xylabs/sdk-js";
240
+ import { PayloadBuilder as PayloadBuilder3 } from "@xyo-network/sdk-js";
241
+ import { Worker as Worker3 } from "bullmq";
242
+ var name3 = "Monitor Submitted ETH Transaction";
243
+ var queueName3 = "eth-tx-monitor";
244
+ var createWorker3 = /* @__PURE__ */ __name((connection2, telemetry2, services) => {
245
+ const provider = assertEx3(services?.provider, () => "provider service not provided");
246
+ const stateMap = assertEx3(services?.ethTxStateMap, () => "ethTxStateMap service not provided");
247
+ const worker = new Worker3(queueName3, async (job) => {
187
248
  const { tx } = job.data;
188
- const hash = await PayloadBuilder.hash(tx[0]);
189
- const state = assertEx(await stateMap.get(hash), () => "State not found");
190
- const submissionHash = assertEx(state?.submissionHash, () => "submissionHash not found");
191
- const receipt = assertEx(await provider.getTransactionReceipt(submissionHash), () => "Transaction receipt not found");
249
+ const hash = await PayloadBuilder3.hash(tx[0]);
250
+ const state = assertEx3(await stateMap.get(hash), () => "State not found");
251
+ const submissionHash = assertEx3(state?.submissionHash, () => "submissionHash not found");
252
+ const receipt = assertEx3(await provider.getTransactionReceipt(submissionHash), () => "Transaction receipt not found");
192
253
  await job.log(`[${hash}] confirmed ETH tx ${submissionHash} in block ${receipt.blockNumber}`);
193
254
  const { blockHash, blockNumber } = receipt;
194
255
  state.confirmationHash = blockHash;
@@ -204,58 +265,58 @@ var createWorker = /* @__PURE__ */ __name((connection2, telemetry2, services) =>
204
265
  prefix
205
266
  });
206
267
  worker.on("failed", (job, err) => {
207
- console.error(`[${name}] Job ${job?.id} failed:`, err.message);
268
+ console.error(`[${name3}] Job ${job?.id} failed:`, err.message);
208
269
  });
209
270
  worker.on("error", (err) => {
210
- console.error(`[${name}] Worker error:`, err);
271
+ console.error(`[${name3}] Worker error:`, err);
211
272
  });
212
273
  }, "createWorker");
213
274
  var EthTransactionMonitor = {
214
- createWorker,
215
- name,
216
- queueName
275
+ createWorker: createWorker3,
276
+ name: name3,
277
+ queueName: queueName3
217
278
  };
218
279
 
219
- // src/queue/workers/EthTransactionPreparation.ts
220
- import { assertEx as assertEx11, hexToBigInt as hexToBigInt8 } from "@xylabs/sdk-js";
221
- import { PayloadBuilder as PayloadBuilder5 } from "@xyo-network/sdk-js";
222
- import { isBridgeIntent as isBridgeIntent3 } from "@xyo-network/xl1-sdk";
223
- import { Worker as Worker2 } from "bullmq";
280
+ // src/services/queue/workers/EthTransactionPreparation.ts
281
+ import { assertEx as assertEx14, hexToBigInt as hexToBigInt9 } from "@xylabs/sdk-js";
282
+ import { PayloadBuilder as PayloadBuilder7 } from "@xyo-network/sdk-js";
283
+ import { isBridgeIntent as isBridgeIntent4 } from "@xyo-network/xl1-sdk";
284
+ import { Worker as Worker4 } from "bullmq";
224
285
  import { getAddress } from "ethers";
225
286
 
226
- // src/validation/validateBridgeEstimateExact.ts
227
- import { hexToBigInt as hexToBigInt4, isUndefined } from "@xylabs/sdk-js";
228
- import { PayloadBuilder as PayloadBuilder3 } from "@xyo-network/sdk-js";
287
+ // src/services/validation/validateBridgeEstimateExact.ts
288
+ import { hexToBigInt as hexToBigInt5, isUndefined } from "@xylabs/sdk-js";
289
+ import { PayloadBuilder as PayloadBuilder5 } from "@xyo-network/sdk-js";
229
290
 
230
- // src/config/asChainId.ts
231
- import { asHex } from "@xylabs/sdk-js";
291
+ // src/services/evm/asChainId.ts
292
+ import { asHex as asHex2 } from "@xylabs/sdk-js";
232
293
  var asChainId = /* @__PURE__ */ __name((value) => {
233
- const chainId = asHex(value);
294
+ const chainId = asHex2(value);
234
295
  return chainId;
235
296
  }, "asChainId");
236
297
 
237
- // src/config/asToken.ts
298
+ // src/services/evm/asToken.ts
238
299
  import { asAddress } from "@xylabs/sdk-js";
239
300
  var asToken = /* @__PURE__ */ __name((value) => {
240
301
  const token = asAddress(value);
241
302
  return token;
242
303
  }, "asToken");
243
304
 
244
- // src/config/getBridgeEscrowAddress.ts
245
- import { asAddress as asAddress2, assertEx as assertEx2 } from "@xylabs/sdk-js";
305
+ // src/services/evm/getBridgeEscrowAddress.ts
306
+ import { asAddress as asAddress2, assertEx as assertEx4 } from "@xylabs/sdk-js";
246
307
  var tryGetBridgeEscrowAddress = /* @__PURE__ */ __name((config) => {
247
308
  const address = asAddress2(config.escrowAddress);
248
309
  return address;
249
310
  }, "tryGetBridgeEscrowAddress");
250
311
 
251
- // src/config/getBridgeFeesAddress.ts
252
- import { asAddress as asAddress3, assertEx as assertEx3 } from "@xylabs/sdk-js";
312
+ // src/services/evm/getBridgeFeesAddress.ts
313
+ import { asAddress as asAddress3, assertEx as assertEx5 } from "@xylabs/sdk-js";
253
314
  var tryGetBridgeFeesAddress = /* @__PURE__ */ __name((config) => {
254
315
  const address = asAddress3(config.feesAddress);
255
316
  return address;
256
317
  }, "tryGetBridgeFeesAddress");
257
318
 
258
- // src/config/getFeeStructure.ts
319
+ // src/services/evm/getFeeStructure.ts
259
320
  var getFeeStructure = /* @__PURE__ */ __name((config) => {
260
321
  const { feeFixed, feeRateBasisPoints } = config;
261
322
  return {
@@ -264,33 +325,33 @@ var getFeeStructure = /* @__PURE__ */ __name((config) => {
264
325
  };
265
326
  }, "getFeeStructure");
266
327
 
267
- // src/config/getMaxBridgeAmount.ts
328
+ // src/services/evm/getMaxBridgeAmount.ts
268
329
  var getMaxBridgeAmount = /* @__PURE__ */ __name((config) => {
269
330
  const { maxBridgeAmount } = config;
270
331
  return maxBridgeAmount;
271
332
  }, "getMaxBridgeAmount");
272
333
 
273
- // src/config/getMinBridgeAmount.ts
334
+ // src/services/evm/getMinBridgeAmount.ts
274
335
  var getMinBridgeAmount = /* @__PURE__ */ __name((config) => {
275
336
  const { minBridgeAmount } = config;
276
337
  return minBridgeAmount;
277
338
  }, "getMinBridgeAmount");
278
339
 
279
- // src/config/getRemoteChainId.ts
280
- import { assertEx as assertEx4 } from "@xylabs/sdk-js";
340
+ // src/services/evm/getRemoteChainId.ts
341
+ import { assertEx as assertEx6 } from "@xylabs/sdk-js";
281
342
  var getRemoteChainId = /* @__PURE__ */ __name((config) => {
282
- const remoteChainId = assertEx4(asChainId(config.remoteChainId), () => "Invalid remote chain ID in config");
343
+ const remoteChainId = assertEx6(asChainId(config.remoteChainId), () => "Invalid remote chain ID in config");
283
344
  return remoteChainId;
284
345
  }, "getRemoteChainId");
285
346
 
286
- // src/config/getRemoteTokenAddress.ts
287
- import { assertEx as assertEx5 } from "@xylabs/sdk-js";
347
+ // src/services/evm/getRemoteTokenAddress.ts
348
+ import { assertEx as assertEx7 } from "@xylabs/sdk-js";
288
349
  var getRemoteTokenAddress = /* @__PURE__ */ __name((config) => {
289
350
  const token = asToken(config.remoteTokenAddress);
290
- return assertEx5(token, () => "Remote token address is not defined in bridge configuration");
351
+ return assertEx7(token, () => "Remote token address is not defined in bridge configuration");
291
352
  }, "getRemoteTokenAddress");
292
353
 
293
- // src/config/getBridgeWalletAccount.ts
354
+ // src/services/evm/getBridgeWalletAccount.ts
294
355
  import { isDefined as isDefined3 } from "@xylabs/sdk-js";
295
356
  import { resolveWalletForActor } from "@xyo-network/chain-orchestration";
296
357
  var accountServiceSingleton;
@@ -302,7 +363,7 @@ var getBridgeWalletAccount = /* @__PURE__ */ __name(async (config) => {
302
363
  return accountServiceSingleton;
303
364
  }, "getBridgeWalletAccount");
304
365
 
305
- // src/config/getTransferAddresses.ts
366
+ // src/services/evm/getTransferAddresses.ts
306
367
  var getTransferAddresses = /* @__PURE__ */ __name(async (config) => {
307
368
  const escrowAddress = tryGetBridgeEscrowAddress(config) ?? (await getBridgeWalletAccount(config)).address;
308
369
  const feesAddress = tryGetBridgeFeesAddress(config) ?? (await getBridgeWalletAccount(config)).address;
@@ -312,17 +373,17 @@ var getTransferAddresses = /* @__PURE__ */ __name(async (config) => {
312
373
  };
313
374
  }, "getTransferAddresses");
314
375
 
315
- // src/config/getXl1ChainId.ts
316
- import { assertEx as assertEx6, isDefined as isDefined4 } from "@xylabs/sdk-js";
376
+ // src/services/evm/getXl1ChainId.ts
377
+ import { assertEx as assertEx8, isDefined as isDefined4 } from "@xylabs/sdk-js";
317
378
  var getXl1ChainId = /* @__PURE__ */ __name((config) => {
318
379
  const xl1ChainId = config.xl1ChainId;
319
380
  if (isDefined4(xl1ChainId)) {
320
- return assertEx6(asChainId(xl1ChainId), () => "Invalid xl1ChainId in bridge config");
381
+ return assertEx8(asChainId(xl1ChainId), () => "Invalid xl1ChainId in bridge config");
321
382
  }
322
- return assertEx6(asChainId(config.chain.id), () => "Invalid chain.id in config");
383
+ return assertEx8(asChainId(config.chain.id), () => "Invalid chain.id in config");
323
384
  }, "getXl1ChainId");
324
385
 
325
- // src/config/getXl1TokenAddress.ts
386
+ // src/services/evm/getXl1TokenAddress.ts
326
387
  import { isDefined as isDefined5 } from "@xylabs/sdk-js";
327
388
  var getXl1TokenAddress = /* @__PURE__ */ __name((config) => {
328
389
  const token = asToken(config.xl1TokenAddress);
@@ -330,7 +391,7 @@ var getXl1TokenAddress = /* @__PURE__ */ __name((config) => {
330
391
  return getXl1ChainId(config);
331
392
  }, "getXl1TokenAddress");
332
393
 
333
- // src/config/getBridgeSettings.ts
394
+ // src/services/evm/getBridgeSettings.ts
334
395
  var getBridgeSettings = /* @__PURE__ */ __name(async (config) => {
335
396
  const { feeFixed, feeRateBasisPoints } = getFeeStructure(config);
336
397
  const { feesAddress, escrowAddress } = await getTransferAddresses(config);
@@ -354,13 +415,35 @@ var getBridgeSettings = /* @__PURE__ */ __name(async (config) => {
354
415
  };
355
416
  }, "getBridgeSettings");
356
417
 
357
- // src/util/calculateBridgeFees.ts
358
- import { hexToBigInt, toHex } from "@xylabs/sdk-js";
418
+ // src/services/evm/getRemoteConfirmationDepth.ts
419
+ import { isDefined as isDefined6 } from "@xylabs/sdk-js";
420
+ var HARDHAT_CHAIN_ID = "0x7a69";
421
+ var ETHEREUM_MAINNET_CHAIN_ID = "0x1";
422
+ var FALLBACK_CONFIRMATION_DEPTH = 32;
423
+ var DEFAULT_CONFIRMATION_DEPTH_BY_CHAIN_ID = {
424
+ [HARDHAT_CHAIN_ID]: 0,
425
+ [ETHEREUM_MAINNET_CHAIN_ID]: 32
426
+ };
427
+ function getRemoteConfirmationDepth(config) {
428
+ if (isDefined6(config.remoteConfirmationDepth)) return config.remoteConfirmationDepth;
429
+ const chainId = getRemoteChainId(config).toLowerCase();
430
+ return DEFAULT_CONFIRMATION_DEPTH_BY_CHAIN_ID[chainId] ?? FALLBACK_CONFIRMATION_DEPTH;
431
+ }
432
+ __name(getRemoteConfirmationDepth, "getRemoteConfirmationDepth");
433
+
434
+ // src/services/evm/getScannerIntervalMs.ts
435
+ function getScannerIntervalMs(config) {
436
+ return config.scannerIntervalMs;
437
+ }
438
+ __name(getScannerIntervalMs, "getScannerIntervalMs");
439
+
440
+ // src/services/util/calculateBridgeFees.ts
441
+ import { hexToBigInt as hexToBigInt2, toHex as toHex2 } from "@xylabs/sdk-js";
359
442
  var calculateBridgeFees = /* @__PURE__ */ __name((srcAmount, feeStructure) => {
360
443
  const { feeFixed, feeRateBasisPoints } = feeStructure;
361
- const srcAmountBigInt = hexToBigInt(srcAmount);
444
+ const srcAmountBigInt = hexToBigInt2(srcAmount);
362
445
  const feeVariableBigInt = srcAmountBigInt * BigInt(feeRateBasisPoints) / 10000n;
363
- const feeVariable = toHex(feeVariableBigInt);
446
+ const feeVariable = toHex2(feeVariableBigInt);
364
447
  return {
365
448
  feeFixed,
366
449
  feeVariable,
@@ -368,42 +451,42 @@ var calculateBridgeFees = /* @__PURE__ */ __name((srcAmount, feeStructure) => {
368
451
  };
369
452
  }, "calculateBridgeFees");
370
453
 
371
- // src/util/calculateMaxBridgeAmount.ts
372
- import { hexToBigInt as hexToBigInt2, toHex as toHex2 } from "@xylabs/sdk-js";
454
+ // src/services/util/calculateMaxBridgeAmount.ts
455
+ import { hexToBigInt as hexToBigInt3, toHex as toHex3 } from "@xylabs/sdk-js";
373
456
  var calculateMaxBridgeAmount = /* @__PURE__ */ __name((balance, feeStructure) => {
374
457
  const { feeFixed, feeRateBasisPoints } = feeStructure;
375
- const balanceBigInt = hexToBigInt2(balance);
376
- const feeFixedBigInt = hexToBigInt2(feeFixed);
377
- if (balanceBigInt <= feeFixedBigInt) return toHex2(0n);
458
+ const balanceBigInt = hexToBigInt3(balance);
459
+ const feeFixedBigInt = hexToBigInt3(feeFixed);
460
+ if (balanceBigInt <= feeFixedBigInt) return toHex3(0n);
378
461
  const maxAmount = (balanceBigInt - feeFixedBigInt) * 10000n / (10000n + BigInt(feeRateBasisPoints));
379
- return toHex2(maxAmount);
462
+ return toHex3(maxAmount);
380
463
  }, "calculateMaxBridgeAmount");
381
464
 
382
- // src/util/createBridgeTransfer.ts
383
- import { hexToBigInt as hexToBigInt3 } from "@xylabs/sdk-js";
384
- import { createTransferPayload } from "@xyo-network/xl1-sdk";
465
+ // src/services/util/createBridgeTransfer.ts
466
+ import { hexToBigInt as hexToBigInt4 } from "@xylabs/sdk-js";
467
+ import { createTransferPayload as createTransferPayload2 } from "@xyo-network/xl1-sdk";
385
468
  var createBridgeTransfer = /* @__PURE__ */ __name((sender, srcAmount, escrowAddress, feesAddress, context) => {
386
469
  const { feeFixed, feeVariable } = context;
387
- const escrowAmount = hexToBigInt3(srcAmount);
388
- const feesAmount = hexToBigInt3(feeFixed) + hexToBigInt3(feeVariable);
470
+ const escrowAmount = hexToBigInt4(srcAmount);
471
+ const feesAmount = hexToBigInt4(feeFixed) + hexToBigInt4(feeVariable);
389
472
  const transfers = escrowAddress === feesAddress ? {
390
473
  [feesAddress]: escrowAmount + feesAmount
391
474
  } : {
392
475
  [escrowAddress]: escrowAmount,
393
476
  [feesAddress]: feesAmount
394
477
  };
395
- const transfer = createTransferPayload(sender, transfers, context);
478
+ const transfer = createTransferPayload2(sender, transfers, context);
396
479
  return transfer;
397
480
  }, "createBridgeTransfer");
398
481
 
399
- // src/util/generateBridgeEstimate.ts
400
- import { toAddress } from "@xylabs/sdk-js";
401
- import { PayloadBuilder as PayloadBuilder2 } from "@xyo-network/sdk-js";
402
- import { BridgeIntentSchema } from "@xyo-network/xl1-sdk";
482
+ // src/services/util/generateBridgeEstimate.ts
483
+ import { toAddress as toAddress2 } from "@xylabs/sdk-js";
484
+ import { PayloadBuilder as PayloadBuilder4 } from "@xyo-network/sdk-js";
485
+ import { BridgeIntentSchema as BridgeIntentSchema2 } from "@xyo-network/xl1-sdk";
403
486
  import { v4 } from "uuid";
404
487
  var generateBridgeEstimate = /* @__PURE__ */ __name(async (srcAddress, srcAmount, destAddress, config, nonceOverride) => {
405
488
  const { escrowAddress, feeFixed, feeRateBasisPoints, feesAddress, remoteChainId, remoteTokenAddress, xl1ChainId, xl1TokenAddress } = await getBridgeSettings(config);
406
- const sender = toAddress(srcAddress);
489
+ const sender = toAddress2(srcAddress);
407
490
  const fees = calculateBridgeFees(srcAmount, {
408
491
  feeFixed,
409
492
  feeRateBasisPoints
@@ -422,8 +505,8 @@ var generateBridgeEstimate = /* @__PURE__ */ __name(async (srcAddress, srcAmount
422
505
  destToken: remoteTokenAddress,
423
506
  nonce
424
507
  };
425
- const bridgeIntent = new PayloadBuilder2({
426
- schema: BridgeIntentSchema
508
+ const bridgeIntent = new PayloadBuilder4({
509
+ schema: BridgeIntentSchema2
427
510
  }).fields(bridgeIntentFields).build();
428
511
  const transfer = createBridgeTransfer(sender, srcAmount, escrowAddress, feesAddress, fees);
429
512
  return [
@@ -432,37 +515,37 @@ var generateBridgeEstimate = /* @__PURE__ */ __name(async (srcAddress, srcAmount
432
515
  ];
433
516
  }, "generateBridgeEstimate");
434
517
 
435
- // src/validation/validateBridgeEstimateExact.ts
518
+ // src/services/validation/validateBridgeEstimateExact.ts
436
519
  var validateBridgeEstimateExact = /* @__PURE__ */ __name(async (intent, transfer, config) => {
437
520
  const { srcAddress, srcAmount, destAddress } = intent;
438
- if (hexToBigInt4(srcAmount) < hexToBigInt4(getMinBridgeAmount(config))) return false;
439
- if (hexToBigInt4(srcAmount) > hexToBigInt4(getMaxBridgeAmount(config))) return false;
521
+ if (hexToBigInt5(srcAmount) < hexToBigInt5(getMinBridgeAmount(config))) return false;
522
+ if (hexToBigInt5(srcAmount) > hexToBigInt5(getMaxBridgeAmount(config))) return false;
440
523
  const [calculatedIntent, calculatedTransfer] = await generateBridgeEstimate(srcAddress, srcAmount, destAddress, config);
441
524
  if (isUndefined(calculatedIntent) || isUndefined(calculatedTransfer)) return false;
442
525
  const { nonce: expectedIntentNonce, ...expectedIntentStatic } = calculatedIntent;
443
526
  const { nonce: actualIntentNonce, ...actualIntentStatic } = intent;
444
- if (await PayloadBuilder3.dataHash(expectedIntentStatic) !== await PayloadBuilder3.dataHash(actualIntentStatic)) return false;
527
+ if (await PayloadBuilder5.dataHash(expectedIntentStatic) !== await PayloadBuilder5.dataHash(actualIntentStatic)) return false;
445
528
  const { epoch: expectedTransferEpoch, ...expectedTransferStatic } = calculatedTransfer;
446
529
  const { epoch: actualTransferEpoch, ...actualTransferStatic } = transfer;
447
- if (await PayloadBuilder3.dataHash(expectedTransferStatic) !== await PayloadBuilder3.dataHash(actualTransferStatic)) return false;
530
+ if (await PayloadBuilder5.dataHash(expectedTransferStatic) !== await PayloadBuilder5.dataHash(actualTransferStatic)) return false;
448
531
  return true;
449
532
  }, "validateBridgeEstimateExact");
450
533
 
451
- // src/validation/validateBridgeTransaction.ts
534
+ // src/services/validation/validateBridgeTransaction.ts
452
535
  import { asAddress as asAddress4 } from "@xylabs/sdk-js";
453
536
  import { addressesContains, BoundWitnessValidator, payloadHashesContainsAll, payloadSchemasContainsAll } from "@xyo-network/boundwitness-validator";
454
- import { PayloadBuilder as PayloadBuilder4 } from "@xyo-network/sdk-js";
455
- import { BridgeIntentSchema as BridgeIntentSchema2, TransferSchema } from "@xyo-network/xl1-sdk";
537
+ import { PayloadBuilder as PayloadBuilder6 } from "@xyo-network/sdk-js";
538
+ import { BridgeIntentSchema as BridgeIntentSchema3, TransferSchema } from "@xyo-network/xl1-sdk";
456
539
  var validateBridgeTransaction = /* @__PURE__ */ __name(async (signedTxBw, intent, transfer, config) => {
457
540
  const { srcAddress } = intent;
458
541
  const chainId = getXl1ChainId(config);
459
542
  if (signedTxBw.chain !== chainId) return false;
460
543
  if (signedTxBw.payload_hashes.length != 2) return false;
461
544
  if (!payloadSchemasContainsAll(signedTxBw, [
462
- BridgeIntentSchema2,
545
+ BridgeIntentSchema3,
463
546
  TransferSchema
464
547
  ])) return false;
465
- const hashes = await PayloadBuilder4.hashes([
548
+ const hashes = await PayloadBuilder6.hashes([
466
549
  intent,
467
550
  transfer
468
551
  ]);
@@ -474,16 +557,16 @@ var validateBridgeTransaction = /* @__PURE__ */ __name(async (signedTxBw, intent
474
557
  return true;
475
558
  }, "validateBridgeTransaction");
476
559
 
477
- // src/validation/validateSufficientLiquiditySourceAllowance.ts
478
- import { assertEx as assertEx7, hexToBigInt as hexToBigInt5 } from "@xylabs/sdk-js";
479
- import { isBridgeIntent } from "@xyo-network/xl1-sdk";
560
+ // src/services/validation/validateSufficientLiquiditySourceAllowance.ts
561
+ import { assertEx as assertEx9, hexToBigInt as hexToBigInt6 } from "@xylabs/sdk-js";
562
+ import { isBridgeIntent as isBridgeIntent2 } from "@xyo-network/xl1-sdk";
480
563
  var validateSufficientLiquiditySourceAllowance = /* @__PURE__ */ __name(async (tx, offChainPayloads, bridgeableToken, bridge, logger) => {
481
564
  const allPayloads = [
482
565
  ...tx[1],
483
566
  ...offChainPayloads
484
567
  ];
485
- const bridgeIntent = assertEx7(allPayloads.find(isBridgeIntent), () => "No bridge intent found");
486
- const amount = hexToBigInt5(bridgeIntent.destAmount);
568
+ const bridgeIntent = assertEx9(allPayloads.find(isBridgeIntent2), () => "No bridge intent found");
569
+ const amount = hexToBigInt6(bridgeIntent.destAmount);
487
570
  const liquiditySourceAddress = await bridge.liquiditySource();
488
571
  const bridgeAddress = await bridge.getAddress();
489
572
  const remainingAllowance = await bridgeableToken.allowance(liquiditySourceAddress, bridgeAddress);
@@ -491,27 +574,27 @@ var validateSufficientLiquiditySourceAllowance = /* @__PURE__ */ __name(async (t
491
574
  return remainingAllowance >= amount;
492
575
  }, "validateSufficientLiquiditySourceAllowance");
493
576
 
494
- // src/validation/validateSufficientLiquiditySourceBalance.ts
495
- import { assertEx as assertEx8, hexToBigInt as hexToBigInt6 } from "@xylabs/sdk-js";
496
- import { isBridgeIntent as isBridgeIntent2 } from "@xyo-network/xl1-sdk";
577
+ // src/services/validation/validateSufficientLiquiditySourceBalance.ts
578
+ import { assertEx as assertEx10, hexToBigInt as hexToBigInt7 } from "@xylabs/sdk-js";
579
+ import { isBridgeIntent as isBridgeIntent3 } from "@xyo-network/xl1-sdk";
497
580
  var validateSufficientLiquiditySourceBalance = /* @__PURE__ */ __name(async (tx, offChainPayloads, bridgeableToken, bridge, logger) => {
498
581
  const allPayloads = [
499
582
  ...tx[1],
500
583
  ...offChainPayloads
501
584
  ];
502
- const bridgeIntent = assertEx8(allPayloads.find(isBridgeIntent2), () => "No bridge intent found");
503
- const amount = hexToBigInt6(bridgeIntent.destAmount);
585
+ const bridgeIntent = assertEx10(allPayloads.find(isBridgeIntent3), () => "No bridge intent found");
586
+ const amount = hexToBigInt7(bridgeIntent.destAmount);
504
587
  const liquiditySourceAddress = await bridge.liquiditySource();
505
588
  const balance = await bridgeableToken.balanceOf(liquiditySourceAddress);
506
589
  await logger?.log(`Remaining balance: ${balance.toString()}`);
507
590
  return balance >= amount;
508
591
  }, "validateSufficientLiquiditySourceBalance");
509
592
 
510
- // src/validation/validateSufficientRunnerEthBalanceForGas.ts
511
- import { assertEx as assertEx9 } from "@xylabs/sdk-js";
593
+ // src/services/validation/validateSufficientRunnerEthBalanceForGas.ts
594
+ import { assertEx as assertEx11 } from "@xylabs/sdk-js";
512
595
  var DEFAULT_GAS_BUFFER_BPS = 2000n;
513
596
  var validateSufficientRunnerEthBalanceForGas = /* @__PURE__ */ __name(async (preparedTx, wallet, logger, bufferBps = DEFAULT_GAS_BUFFER_BPS) => {
514
- const provider = assertEx9(wallet.provider, () => "Wallet provider is not defined");
597
+ const provider = assertEx11(wallet.provider, () => "Wallet provider is not defined");
515
598
  const feeData = await provider.getFeeData();
516
599
  const perGas = feeData.maxFeePerGas ?? feeData.gasPrice;
517
600
  if (perGas == null) {
@@ -531,30 +614,40 @@ var validateSufficientRunnerEthBalanceForGas = /* @__PURE__ */ __name(async (pre
531
614
  return balance >= required;
532
615
  }, "validateSufficientRunnerEthBalanceForGas");
533
616
 
534
- // src/validation/validateSufficientXL1SourceAddressBalance.ts
535
- import { asAddress as asAddress5, assertEx as assertEx10, hexToBigInt as hexToBigInt7 } from "@xylabs/sdk-js";
617
+ // src/services/validation/validateSufficientXl1ReserveBalance.ts
618
+ import { assertEx as assertEx12 } from "@xylabs/sdk-js";
619
+ async function validateSufficientXl1ReserveBalance({ amount, bridgeAccount, gateway, logger }) {
620
+ const viewer = assertEx12(gateway.connection.viewer, () => "Gateway connection does not have a viewer");
621
+ const balance = await viewer.account.balance.accountBalance(bridgeAccount.address);
622
+ await logger?.log(`XL1 reserve account ${bridgeAccount.address} balance: ${balance.toString()}; required: ${amount.toString()}`);
623
+ return balance >= amount;
624
+ }
625
+ __name(validateSufficientXl1ReserveBalance, "validateSufficientXl1ReserveBalance");
626
+
627
+ // src/services/validation/validateSufficientXL1SourceAddressBalance.ts
628
+ import { asAddress as asAddress5, assertEx as assertEx13, hexToBigInt as hexToBigInt8 } from "@xylabs/sdk-js";
536
629
  var validateSufficientXL1SourceAddressBalance = /* @__PURE__ */ __name(async (bridgeIntent, gateway, config, logger) => {
537
- const viewer = assertEx10(gateway.connection.viewer, () => "Gateway connection does not have a viewer");
630
+ const viewer = assertEx13(gateway.connection.viewer, () => "Gateway connection does not have a viewer");
538
631
  const { srcAddress, srcAmount, destAddress } = bridgeIntent;
539
632
  const srcAddressBranded = asAddress5(srcAddress, () => `Invalid source address in bridge intent: ${srcAddress}`);
540
633
  const [_, calculatedTransfer] = await generateBridgeEstimate(srcAddress, srcAmount, destAddress, config);
541
- const totalAmount = Object.values(calculatedTransfer.transfers).reduce((acc, transfer) => acc + hexToBigInt7(transfer), 0n);
634
+ const totalAmount = Object.values(calculatedTransfer.transfers).reduce((acc, transfer) => acc + hexToBigInt8(transfer), 0n);
542
635
  const accountBalance = await viewer.account.balance.accountBalance(srcAddressBranded);
543
636
  await logger?.log(`Account balance for ${srcAddressBranded}: ${accountBalance.toString()}`);
544
637
  return accountBalance >= totalAmount;
545
638
  }, "validateSufficientXL1SourceAddressBalance");
546
639
 
547
- // src/queue/workers/EthTransactionPreparation.ts
548
- var name2 = "Prepare ETH Transaction";
549
- var queueName2 = "eth-tx-prepare";
550
- var createWorker2 = /* @__PURE__ */ __name((connection2, telemetry2, services) => {
551
- const bridge = assertEx11(services?.bridge, () => "bridge service not provided");
552
- const bridgeableToken = assertEx11(services?.bridgeableToken, () => "bridgeableToken service not provided");
553
- const stateMap = assertEx11(services?.ethTxStateMap, () => "ethTxStateMap service not provided");
554
- const wallet = assertEx11(services?.wallet, () => "wallet service not provided");
555
- const worker = new Worker2(queueName2, async (job) => {
640
+ // src/services/queue/workers/EthTransactionPreparation.ts
641
+ var name4 = "Prepare ETH Transaction";
642
+ var queueName4 = "eth-tx-prepare";
643
+ var createWorker4 = /* @__PURE__ */ __name((connection2, telemetry2, services) => {
644
+ const bridge = assertEx14(services?.bridge, () => "bridge service not provided");
645
+ const bridgeableToken = assertEx14(services?.bridgeableToken, () => "bridgeableToken service not provided");
646
+ const stateMap = assertEx14(services?.ethTxStateMap, () => "ethTxStateMap service not provided");
647
+ const wallet = assertEx14(services?.wallet, () => "wallet service not provided");
648
+ const worker = new Worker4(queueName4, async (job) => {
556
649
  const { tx, offChainPayloads } = job.data;
557
- const hash = await PayloadBuilder5.hash(tx[0]);
650
+ const hash = await PayloadBuilder7.hash(tx[0]);
558
651
  await job.log(`[${hash}] preparing ETH transaction`);
559
652
  await job.log(`[${hash}] validating liquiditySource has sufficient allowance`);
560
653
  if (!await validateSufficientLiquiditySourceAllowance(tx, offChainPayloads, bridgeableToken, bridge, job)) {
@@ -571,11 +664,11 @@ var createWorker2 = /* @__PURE__ */ __name((connection2, telemetry2, services) =
571
664
  ...tx[1],
572
665
  ...offChainPayloads
573
666
  ];
574
- const bridgeIntent = assertEx11(allPayloads.find(isBridgeIntent3), () => "No bridge intent found");
575
- const amount = hexToBigInt8(bridgeIntent.destAmount);
667
+ const bridgeIntent = assertEx14(allPayloads.find(isBridgeIntent4), () => "No bridge intent found");
668
+ const amount = hexToBigInt9(bridgeIntent.destAmount);
576
669
  const srcAddress = getAddress(bridgeIntent.srcAddress);
577
670
  const destAddress = getAddress(bridgeIntent.destAddress);
578
- const nonce = hexToBigInt8(await PayloadBuilder5.hash(tx[0]));
671
+ const nonce = hexToBigInt9(await PayloadBuilder7.hash(tx[0]));
579
672
  const preparedTx = await bridge.getFunction("bridgeFromRemote").populateTransaction(srcAddress, destAddress, amount, nonce);
580
673
  await job.log(`[${hash}] built ETH transaction`);
581
674
  await job.log(`[${hash}] validating tx runner has sufficient ETH for gas`);
@@ -596,69 +689,41 @@ var createWorker2 = /* @__PURE__ */ __name((connection2, telemetry2, services) =
596
689
  prefix
597
690
  });
598
691
  worker.on("failed", (job, err) => {
599
- console.error(`[${name2}] Job ${job?.id} failed:`, err.message);
692
+ console.error(`[${name4}] Job ${job?.id} failed:`, err.message);
600
693
  });
601
694
  worker.on("error", (err) => {
602
- console.error(`[${name2}] Worker error:`, err);
695
+ console.error(`[${name4}] Worker error:`, err);
603
696
  });
604
697
  }, "createWorker");
605
698
  var EthTransactionPreparation = {
606
- createWorker: createWorker2,
607
- name: name2,
608
- queueName: queueName2
699
+ createWorker: createWorker4,
700
+ name: name4,
701
+ queueName: queueName4
609
702
  };
610
703
 
611
- // src/queue/workers/EthTransactionSubmission.ts
612
- import { assertEx as assertEx13, isDefined as isDefined6 } from "@xylabs/sdk-js";
613
- import { PayloadBuilder as PayloadBuilder7 } from "@xyo-network/sdk-js";
614
- import { Worker as Worker3 } from "bullmq";
615
-
616
- // src/queue/workers/util/submitEthTransaction.ts
617
- import { assertEx as assertEx12, hexToBigInt as hexToBigInt9, toEthAddress } from "@xylabs/sdk-js";
618
- import { PayloadBuilder as PayloadBuilder6 } from "@xyo-network/sdk-js";
619
- import { isBridgeIntent as isBridgeIntent4 } from "@xyo-network/xl1-sdk";
620
- var submitEthTransaction = /* @__PURE__ */ __name(async (tx, offChainPayloads, bridge, wallet) => {
621
- const xl1Transaction = assertEx12(tx[0], () => "No corresponding XL1 transaction found");
622
- const allPayloads = [
623
- ...tx[1],
624
- ...offChainPayloads
625
- ];
626
- const bridgeIntent = assertEx12(allPayloads.find(isBridgeIntent4), () => "No bridge intent found");
627
- const srcAddress = toEthAddress(bridgeIntent.srcAddress);
628
- const destAddress = toEthAddress(bridgeIntent.destAddress);
629
- const amount = hexToBigInt9(bridgeIntent.destAmount);
630
- const nonce = hexToBigInt9(await PayloadBuilder6.hash(xl1Transaction));
631
- const bridgeTx = await bridge.connect(wallet).bridgeFromRemote(srcAddress, destAddress, amount, nonce);
632
- const receipt = await bridgeTx.wait(1);
633
- return receipt?.hash;
634
- }, "submitEthTransaction");
635
-
636
- // src/queue/workers/util/submitXl1Transaction.ts
637
- var submitXl1Transaction = /* @__PURE__ */ __name(async (preparedTx, offChain = [], gateway) => {
638
- const result = await gateway.addTransactionToChain(preparedTx, offChain);
639
- return result;
640
- }, "submitXl1Transaction");
641
-
642
- // src/queue/workers/EthTransactionSubmission.ts
643
- var name3 = "Submit ETH Transaction";
644
- var queueName3 = "eth-tx-submit";
645
- var createWorker3 = /* @__PURE__ */ __name((connection2, telemetry2, services) => {
646
- const bridge = assertEx13(services?.bridge, () => "bridge service not provided");
647
- const wallet = assertEx13(services?.wallet, () => "wallet service not provided");
648
- const stateMap = assertEx13(services?.ethTxStateMap, () => "ethTxStateMap service not provided");
649
- const worker = new Worker3(queueName3, async (job) => {
704
+ // src/services/queue/workers/EthTransactionSubmission.ts
705
+ import { assertEx as assertEx15, isDefined as isDefined7 } from "@xylabs/sdk-js";
706
+ import { PayloadBuilder as PayloadBuilder8 } from "@xyo-network/sdk-js";
707
+ import { Worker as Worker5 } from "bullmq";
708
+ var name5 = "Submit ETH Transaction";
709
+ var queueName5 = "eth-tx-submit";
710
+ var createWorker5 = /* @__PURE__ */ __name((connection2, telemetry2, services) => {
711
+ const bridge = assertEx15(services?.bridge, () => "bridge service not provided");
712
+ const wallet = assertEx15(services?.wallet, () => "wallet service not provided");
713
+ const stateMap = assertEx15(services?.ethTxStateMap, () => "ethTxStateMap service not provided");
714
+ const worker = new Worker5(queueName5, async (job) => {
650
715
  const { tx, offChainPayloads } = job.data;
651
- const hash = await PayloadBuilder7.hash(tx[0]);
652
- const state = assertEx13(await stateMap.get(hash), () => `[${hash}] state not found`);
716
+ const hash = await PayloadBuilder8.hash(tx[0]);
717
+ const state = assertEx15(await stateMap.get(hash), () => `[${hash}] state not found`);
653
718
  const { submissionHash: existingSubmissionHash } = state;
654
- if (isDefined6(existingSubmissionHash)) {
719
+ if (isDefined7(existingSubmissionHash)) {
655
720
  await job.log(`[${hash}] Tx already submitted with submission response hash ${existingSubmissionHash}`);
656
721
  return {
657
722
  submissionHash: existingSubmissionHash
658
723
  };
659
724
  }
660
725
  await job.log(`[${hash}] Submitting ETH tx`);
661
- const submissionHash = assertEx13(await submitEthTransaction(tx, offChainPayloads, bridge, wallet), () => `[${hash}] submissionHash not found in receipt`);
726
+ const submissionHash = assertEx15(await submitEthTransaction(tx, offChainPayloads, bridge, wallet), () => `[${hash}] submissionHash not found in receipt`);
662
727
  await job.log(`[${hash}] Submitted ETH tx and received submission response hash ${submissionHash}`);
663
728
  return {
664
729
  submissionHash
@@ -670,32 +735,32 @@ var createWorker3 = /* @__PURE__ */ __name((connection2, telemetry2, services) =
670
735
  prefix
671
736
  });
672
737
  worker.on("failed", (job, err) => {
673
- console.error(`[${name3}] Job ${job?.id} failed:`, err.message);
738
+ console.error(`[${name5}] Job ${job?.id} failed:`, err.message);
674
739
  });
675
740
  worker.on("error", (err) => {
676
- console.error(`[${name3}] Worker error:`, err);
741
+ console.error(`[${name5}] Worker error:`, err);
677
742
  });
678
743
  }, "createWorker");
679
744
  var EthTransactionSubmission = {
680
- createWorker: createWorker3,
681
- name: name3,
682
- queueName: queueName3
745
+ createWorker: createWorker5,
746
+ name: name5,
747
+ queueName: queueName5
683
748
  };
684
749
 
685
- // src/queue/workers/EthTransactionSubmissionStorage.ts
686
- import { assertEx as assertEx14, isDefined as isDefined7 } from "@xylabs/sdk-js";
687
- import { PayloadBuilder as PayloadBuilder8 } from "@xyo-network/sdk-js";
688
- import { Worker as Worker4 } from "bullmq";
689
- var name4 = "Store ETH Transaction Submission";
690
- var queueName4 = "eth-tx-store-submission";
691
- var createWorker4 = /* @__PURE__ */ __name((connection2, telemetry2, services) => {
692
- const stateMap = assertEx14(services?.ethTxStateMap, () => "ethTxStateMap service not provided");
693
- const worker = new Worker4(queueName4, async (job) => {
750
+ // src/services/queue/workers/EthTransactionSubmissionStorage.ts
751
+ import { assertEx as assertEx16, isDefined as isDefined8 } from "@xylabs/sdk-js";
752
+ import { PayloadBuilder as PayloadBuilder9 } from "@xyo-network/sdk-js";
753
+ import { Worker as Worker6 } from "bullmq";
754
+ var name6 = "Store ETH Transaction Submission";
755
+ var queueName6 = "eth-tx-store-submission";
756
+ var createWorker6 = /* @__PURE__ */ __name((connection2, telemetry2, services) => {
757
+ const stateMap = assertEx16(services?.ethTxStateMap, () => "ethTxStateMap service not provided");
758
+ const worker = new Worker6(queueName6, async (job) => {
694
759
  const { tx } = job.data;
695
- const hash = await PayloadBuilder8.hash(tx[0]);
696
- const state = assertEx14(await stateMap.get(hash), () => `[${hash}] state not found`);
760
+ const hash = await PayloadBuilder9.hash(tx[0]);
761
+ const state = assertEx16(await stateMap.get(hash), () => `[${hash}] state not found`);
697
762
  const { submissionHash: existingSubmissionHash } = state;
698
- if (isDefined7(existingSubmissionHash)) {
763
+ if (isDefined8(existingSubmissionHash)) {
699
764
  await job.log(`[${hash}] submissionHash already stored as ${existingSubmissionHash}`);
700
765
  return {
701
766
  submissionHash: existingSubmissionHash
@@ -705,7 +770,7 @@ var createWorker4 = /* @__PURE__ */ __name((connection2, telemetry2, services) =
705
770
  const jobKey = `${prefix}:${EthTransactionSubmission.queueName}:${hash}`;
706
771
  const childValues = childrenValues?.[jobKey];
707
772
  const submissionHash = childValues?.submissionHash;
708
- const resolvedSubmissionHash = assertEx14(submissionHash, () => `[${hash}] child submissionHash not found in children values`);
773
+ const resolvedSubmissionHash = assertEx16(submissionHash, () => `[${hash}] child submissionHash not found in children values`);
709
774
  await job.log(`[${hash}] Storing ETH submissionHash`);
710
775
  state.submissionHash = resolvedSubmissionHash;
711
776
  await stateMap.set(hash, state);
@@ -719,24 +784,193 @@ var createWorker4 = /* @__PURE__ */ __name((connection2, telemetry2, services) =
719
784
  prefix
720
785
  });
721
786
  worker.on("failed", (job, err) => {
722
- console.error(`[${name4}] Job ${job?.id} failed:`, err.message);
787
+ console.error(`[${name6}] Job ${job?.id} failed:`, err.message);
723
788
  });
724
789
  worker.on("error", (err) => {
725
- console.error(`[${name4}] Worker error:`, err);
790
+ console.error(`[${name6}] Worker error:`, err);
726
791
  });
727
792
  }, "createWorker");
728
793
  var EthTransactionSubmissionStorage = {
729
- createWorker: createWorker4,
730
- name: name4,
731
- queueName: queueName4
794
+ createWorker: createWorker6,
795
+ name: name6,
796
+ queueName: queueName6
732
797
  };
733
798
 
734
- // src/queue/workers/Xl1ToEthBridgeParent.ts
735
- import { Worker as Worker5 } from "bullmq";
736
- var name5 = "Bridge XL1 to Ethereum";
737
- var queueName5 = "xl1-to-eth-bridge";
738
- var createWorker5 = /* @__PURE__ */ __name((connection2, telemetry2) => {
739
- const worker = new Worker5(queueName5, async (job) => {
799
+ // src/services/queue/workers/Xl1ReserveTxFulfillment.ts
800
+ import { assertEx as assertEx17, delay, isDefined as isDefined9, isNull as isNull2 } from "@xylabs/sdk-js";
801
+ import { PayloadBuilder as PayloadBuilder10 } from "@xyo-network/sdk-js";
802
+ import { asXL1BlockNumber } from "@xyo-network/xl1-sdk";
803
+ import { Worker as Worker7 } from "bullmq";
804
+ var name7 = "XL1 Reserve Transfer Fulfillment";
805
+ var queueName7 = "eth-to-xl1-fulfill";
806
+ var EXP_BLOCKS_AHEAD = 1e3;
807
+ var POLL_INTERVAL_MS = 5e3;
808
+ var CONCURRENCY = 32;
809
+ async function tryResumeCurrentAttempt(ctx) {
810
+ const { fulfillmentMap, identity, job, state, viewer } = ctx;
811
+ const attempt = assertEx17(state.currentAttempt, () => "tryResumeCurrentAttempt called without currentAttempt");
812
+ const found = await viewer.transaction.byHash(attempt.txHash);
813
+ if (isDefined9(found) && !isNull2(found)) {
814
+ state.fulfilled = attempt;
815
+ state.currentAttempt = void 0;
816
+ await fulfillmentMap.set(identity, state);
817
+ await job.log(`[${identity}] tx ${attempt.txHash} included on resume`);
818
+ return;
819
+ }
820
+ const head = await viewer.currentBlockNumber();
821
+ if (head > attempt.exp) {
822
+ state.previousAttempts.push(attempt);
823
+ state.currentAttempt = void 0;
824
+ await fulfillmentMap.set(identity, state);
825
+ await job.log(`[${identity}] resumed attempt expired (head=${head}); will build fresh`);
826
+ }
827
+ }
828
+ __name(tryResumeCurrentAttempt, "tryResumeCurrentAttempt");
829
+ async function buildAndSubmitFreshAttempt(ctx) {
830
+ const { account, bridgeId, contractAddress, evmChainId, fulfillmentMap, gateway, identity, job, state, viewer, xl1ChainId, xl1TokenAddress } = ctx;
831
+ const canonical = assertEx17(state.canonical, () => "buildAndSubmitFreshAttempt requires canonical");
832
+ const sufficient = await validateSufficientXl1ReserveBalance({
833
+ amount: canonical.amount,
834
+ bridgeAccount: account,
835
+ gateway
836
+ });
837
+ if (!sufficient) {
838
+ const msg = `[${identity}] XL1 reserve below required ${canonical.amount.toString()}; will retry`;
839
+ await job.log(msg);
840
+ throw new Error(msg);
841
+ }
842
+ const head = await viewer.currentBlockNumber();
843
+ const nbf = asXL1BlockNumber(head, true);
844
+ const exp = asXL1BlockNumber(head + EXP_BLOCKS_AHEAD, true);
845
+ const tx = await buildEthToXl1ReserveTx({
846
+ amount: canonical.amount,
847
+ bridgeAccount: account,
848
+ bridgeId,
849
+ destAddress: canonical.destAddress,
850
+ evmChainId,
851
+ evmContractAddress: contractAddress,
852
+ evmSrcAddress: canonical.srcAddress,
853
+ evmTokenAddress: canonical.destToken,
854
+ evmTxHash: canonical.evmTxHash,
855
+ exp,
856
+ nbf,
857
+ xl1ChainId,
858
+ xl1TokenAddress
859
+ });
860
+ const txHash = await PayloadBuilder10.hash(tx[0]);
861
+ state.currentAttempt = {
862
+ exp: head + EXP_BLOCKS_AHEAD,
863
+ nbf: head,
864
+ submittedAt: Date.now(),
865
+ txHash
866
+ };
867
+ await fulfillmentMap.set(identity, state);
868
+ await submitXl1Transaction(tx, [], gateway);
869
+ await job.log(`[${identity}] attempt ${state.previousAttempts.length + 1} submitted: txHash=${txHash} nbf=${head} exp=${head + EXP_BLOCKS_AHEAD}`);
870
+ }
871
+ __name(buildAndSubmitFreshAttempt, "buildAndSubmitFreshAttempt");
872
+ async function pollUntilIncludedOrExpired(ctx) {
873
+ const { fulfillmentMap, identity, job, state, viewer } = ctx;
874
+ const attempt = assertEx17(state.currentAttempt, () => "pollUntilIncludedOrExpired requires currentAttempt");
875
+ while (true) {
876
+ const found = await viewer.transaction.byHash(attempt.txHash);
877
+ if (isDefined9(found) && !isNull2(found)) {
878
+ state.fulfilled = attempt;
879
+ state.currentAttempt = void 0;
880
+ await fulfillmentMap.set(identity, state);
881
+ await job.log(`[${identity}] tx ${attempt.txHash} included`);
882
+ return;
883
+ }
884
+ const head = await viewer.currentBlockNumber();
885
+ if (head > attempt.exp) {
886
+ state.previousAttempts.push(attempt);
887
+ state.currentAttempt = void 0;
888
+ await fulfillmentMap.set(identity, state);
889
+ const msg = `[${identity}] attempt ${state.previousAttempts.length} expired (head=${head}, exp=${attempt.exp})`;
890
+ await job.log(msg);
891
+ throw new Error(msg);
892
+ }
893
+ await delay(POLL_INTERVAL_MS);
894
+ }
895
+ }
896
+ __name(pollUntilIncludedOrExpired, "pollUntilIncludedOrExpired");
897
+ var createWorker7 = /* @__PURE__ */ __name((connection2, telemetry2, services) => {
898
+ const svc = assertEx17(services, () => "services not provided");
899
+ const { account, bridgeFulfillmentMap, gateway } = svc;
900
+ const worker = new Worker7(queueName7, async (job) => {
901
+ const { bridgeId, contractAddress, evmChainId, identity, xl1ChainId, xl1TokenAddress } = job.data;
902
+ const initialState = await bridgeFulfillmentMap.get(identity);
903
+ if (initialState?.fulfilled) {
904
+ await job.log(`[${identity}] already fulfilled \u2014 skipping`);
905
+ return;
906
+ }
907
+ const state = assertEx17(initialState, () => `[${identity}] no fulfillment state \u2014 Stage 1 did not run`);
908
+ assertEx17(state.canonical, () => `[${identity}] canonical missing \u2014 Stage 1 did not write canonical`);
909
+ if (state.failed) {
910
+ state.failed = void 0;
911
+ await bridgeFulfillmentMap.set(identity, state);
912
+ }
913
+ const viewer = assertEx17(gateway.connection.viewer, () => `[${identity}] gateway viewer not available`);
914
+ const ctx = {
915
+ fulfillmentMap: bridgeFulfillmentMap,
916
+ identity,
917
+ job,
918
+ state,
919
+ viewer
920
+ };
921
+ if (state.currentAttempt) {
922
+ await tryResumeCurrentAttempt(ctx);
923
+ if (state.fulfilled) return;
924
+ }
925
+ if (!state.currentAttempt) {
926
+ await buildAndSubmitFreshAttempt({
927
+ ...ctx,
928
+ account,
929
+ bridgeId: BigInt(bridgeId),
930
+ contractAddress,
931
+ evmChainId,
932
+ gateway,
933
+ xl1ChainId,
934
+ xl1TokenAddress
935
+ });
936
+ }
937
+ await pollUntilIncludedOrExpired(ctx);
938
+ }, {
939
+ concurrency: CONCURRENCY,
940
+ connection: connection2,
941
+ prefix,
942
+ telemetry: telemetry2
943
+ });
944
+ worker.on("failed", async (job, err) => {
945
+ if (!isDefined9(job)) return;
946
+ const attemptsAllowed = job.opts.attempts ?? Infinity;
947
+ if (job.attemptsMade < attemptsAllowed) return;
948
+ const identity = job.data?.identity;
949
+ if (!isDefined9(identity)) return;
950
+ const state = await bridgeFulfillmentMap.get(identity);
951
+ if (!isDefined9(state)) return;
952
+ state.failed = {
953
+ at: Date.now(),
954
+ reason: `attempts exhausted (${job.attemptsMade}/${attemptsAllowed}): ${err.message}`
955
+ };
956
+ await bridgeFulfillmentMap.set(identity, state);
957
+ });
958
+ worker.on("error", (err) => {
959
+ console.error(`[${name7}] Worker error:`, err);
960
+ });
961
+ }, "createWorker");
962
+ var Xl1ReserveTxFulfillment = {
963
+ createWorker: createWorker7,
964
+ name: name7,
965
+ queueName: queueName7
966
+ };
967
+
968
+ // src/services/queue/workers/Xl1ToEthBridgeParent.ts
969
+ import { Worker as Worker8 } from "bullmq";
970
+ var name8 = "Bridge XL1 to Ethereum";
971
+ var queueName8 = "xl1-to-eth-bridge";
972
+ var createWorker8 = /* @__PURE__ */ __name((connection2, telemetry2) => {
973
+ const worker = new Worker8(queueName8, async (job) => {
740
974
  await job.log(`[${job.name}] start`);
741
975
  await job.log(`[${job.name}] done`);
742
976
  return {};
@@ -746,38 +980,38 @@ var createWorker5 = /* @__PURE__ */ __name((connection2, telemetry2) => {
746
980
  prefix
747
981
  });
748
982
  worker.on("failed", (job, err) => {
749
- console.error(`[${name5}] Job ${job?.id} failed:`, err.message);
983
+ console.error(`[${name8}] Job ${job?.id} failed:`, err.message);
750
984
  });
751
985
  worker.on("error", (err) => {
752
- console.error(`[${name5}] Worker error:`, err);
986
+ console.error(`[${name8}] Worker error:`, err);
753
987
  });
754
988
  }, "createWorker");
755
989
  var Xl1ToEthBridgeParent = {
756
- createWorker: createWorker5,
757
- name: name5,
758
- queueName: queueName5
990
+ createWorker: createWorker8,
991
+ name: name8,
992
+ queueName: queueName8
759
993
  };
760
994
 
761
- // src/queue/workers/Xl1TransactionMonitor.ts
762
- import { assertEx as assertEx15, isDefined as isDefined8, isNull } from "@xylabs/sdk-js";
763
- import { PayloadBuilder as PayloadBuilder9 } from "@xyo-network/sdk-js";
764
- import { UnrecoverableError, Worker as Worker6 } from "bullmq";
765
- var name6 = "Monitor Submitted XL1 Transaction";
766
- var queueName6 = "xl1-tx-monitor";
767
- var createWorker6 = /* @__PURE__ */ __name((connection2, telemetry2, services) => {
768
- const gateway = assertEx15(services?.gateway, () => "gateway service not provided");
769
- const stateMap = assertEx15(services?.xl1TxStateMap, () => "xl1TxStateMap service not provided");
770
- const viewer = assertEx15(gateway.connection.viewer, () => "viewer not defined on gateway");
771
- const worker = new Worker6(queueName6, async (job) => {
995
+ // src/services/queue/workers/Xl1TransactionMonitor.ts
996
+ import { assertEx as assertEx18, isDefined as isDefined10, isNull as isNull3 } from "@xylabs/sdk-js";
997
+ import { PayloadBuilder as PayloadBuilder11 } from "@xyo-network/sdk-js";
998
+ import { UnrecoverableError as UnrecoverableError2, Worker as Worker9 } from "bullmq";
999
+ var name9 = "Monitor Submitted XL1 Transaction";
1000
+ var queueName9 = "xl1-tx-monitor";
1001
+ var createWorker9 = /* @__PURE__ */ __name((connection2, telemetry2, services) => {
1002
+ const gateway = assertEx18(services?.gateway, () => "gateway service not provided");
1003
+ const stateMap = assertEx18(services?.xl1TxStateMap, () => "xl1TxStateMap service not provided");
1004
+ const viewer = assertEx18(gateway.connection.viewer, () => "viewer not defined on gateway");
1005
+ const worker = new Worker9(queueName9, async (job) => {
772
1006
  const { tx } = job.data;
773
- const hash = await PayloadBuilder9.hash(tx[0]);
774
- const state = assertEx15(await stateMap.get(hash), () => `[${hash}] state not found`);
775
- const submissionHash = assertEx15(state.submissionHash, () => `[${hash}] submissionHash not found`);
1007
+ const hash = await PayloadBuilder11.hash(tx[0]);
1008
+ const state = assertEx18(await stateMap.get(hash), () => `[${hash}] state not found`);
1009
+ const submissionHash = assertEx18(state.submissionHash, () => `[${hash}] submissionHash not found`);
776
1010
  await job.log(`[${hash}] Checking for XL1 transaction inclusion on chain`);
777
1011
  const foundTx = await viewer.transaction.byHash(submissionHash);
778
- if (isDefined8(foundTx) && !isNull(foundTx)) {
1012
+ if (isDefined10(foundTx) && !isNull3(foundTx)) {
779
1013
  await job.log(`[${hash}] Found transaction on chain`);
780
- const submissionHash2 = await PayloadBuilder9.hash(foundTx[0]);
1014
+ const submissionHash2 = await PayloadBuilder11.hash(foundTx[0]);
781
1015
  return {
782
1016
  submissionHash: submissionHash2
783
1017
  };
@@ -785,7 +1019,7 @@ var createWorker6 = /* @__PURE__ */ __name((connection2, telemetry2, services) =
785
1019
  const currentBlockNumber = await viewer.currentBlockNumber();
786
1020
  if (tx[0].exp < currentBlockNumber) {
787
1021
  await job.log(`[${hash}] Transaction expired at block ${tx[0].exp}, current block ${currentBlockNumber}`);
788
- throw new UnrecoverableError(`[${hash}] Transaction expired and will never be included`);
1022
+ throw new UnrecoverableError2(`[${hash}] Transaction expired and will never be included`);
789
1023
  }
790
1024
  await job.log(`[${hash}] Transaction not yet included, retrying later`);
791
1025
  throw new Error(`[${hash}] Transaction not yet included`);
@@ -795,29 +1029,29 @@ var createWorker6 = /* @__PURE__ */ __name((connection2, telemetry2, services) =
795
1029
  prefix
796
1030
  });
797
1031
  worker.on("failed", (job, err) => {
798
- console.error(`[${name6}] Job ${job?.id} failed:`, err.message);
1032
+ console.error(`[${name9}] Job ${job?.id} failed:`, err.message);
799
1033
  });
800
1034
  worker.on("error", (err) => {
801
- console.error(`[${name6}] Worker error:`, err);
1035
+ console.error(`[${name9}] Worker error:`, err);
802
1036
  });
803
1037
  }, "createWorker");
804
1038
  var Xl1TransactionMonitor = {
805
- createWorker: createWorker6,
806
- name: name6,
807
- queueName: queueName6
1039
+ createWorker: createWorker9,
1040
+ name: name9,
1041
+ queueName: queueName9
808
1042
  };
809
1043
 
810
- // src/queue/workers/Xl1TransactionPreparation.ts
811
- import { assertEx as assertEx16 } from "@xylabs/sdk-js";
812
- import { PayloadBuilder as PayloadBuilder10 } from "@xyo-network/sdk-js";
813
- import { Worker as Worker7 } from "bullmq";
814
- var name7 = "Prepare XL1 Transaction";
815
- var queueName7 = "xl1-tx-prepare";
816
- var createWorker7 = /* @__PURE__ */ __name((connection2, telemetry2, services) => {
817
- const stateMap = assertEx16(services?.xl1TxStateMap, () => "xl1TxStateMap service not provided");
818
- const worker = new Worker7(queueName7, async (job) => {
1044
+ // src/services/queue/workers/Xl1TransactionPreparation.ts
1045
+ import { assertEx as assertEx19 } from "@xylabs/sdk-js";
1046
+ import { PayloadBuilder as PayloadBuilder12 } from "@xyo-network/sdk-js";
1047
+ import { Worker as Worker10 } from "bullmq";
1048
+ var name10 = "Prepare XL1 Transaction";
1049
+ var queueName10 = "xl1-tx-prepare";
1050
+ var createWorker10 = /* @__PURE__ */ __name((connection2, telemetry2, services) => {
1051
+ const stateMap = assertEx19(services?.xl1TxStateMap, () => "xl1TxStateMap service not provided");
1052
+ const worker = new Worker10(queueName10, async (job) => {
819
1053
  const { tx, offChainPayloads = [] } = job.data;
820
- const hash = await PayloadBuilder10.hash(tx[0]);
1054
+ const hash = await PayloadBuilder12.hash(tx[0]);
821
1055
  await job.log(`[${hash}] preparing XL1 transaction`);
822
1056
  const preparedTx = tx;
823
1057
  await job.log(`[${hash}] storing XL1 preparedTx`);
@@ -836,39 +1070,39 @@ var createWorker7 = /* @__PURE__ */ __name((connection2, telemetry2, services) =
836
1070
  prefix
837
1071
  });
838
1072
  worker.on("failed", (job, err) => {
839
- console.error(`[${name7}] Job ${job?.id} failed:`, err.message);
1073
+ console.error(`[${name10}] Job ${job?.id} failed:`, err.message);
840
1074
  });
841
1075
  worker.on("error", (err) => {
842
- console.error(`[${name7}] Worker error:`, err);
1076
+ console.error(`[${name10}] Worker error:`, err);
843
1077
  });
844
1078
  }, "createWorker");
845
1079
  var Xl1TransactionPreparation = {
846
- createWorker: createWorker7,
847
- name: name7,
848
- queueName: queueName7
1080
+ createWorker: createWorker10,
1081
+ name: name10,
1082
+ queueName: queueName10
849
1083
  };
850
1084
 
851
- // src/queue/workers/Xl1TransactionSubmission.ts
852
- import { assertEx as assertEx17, isDefined as isDefined9 } from "@xylabs/sdk-js";
853
- import { PayloadBuilder as PayloadBuilder11 } from "@xyo-network/sdk-js";
854
- import { Worker as Worker8 } from "bullmq";
855
- var name8 = "Submit XL1 Transaction";
856
- var queueName8 = "xl1-tx-submit";
857
- var createWorker8 = /* @__PURE__ */ __name((connection2, telemetry2, services) => {
858
- const gateway = assertEx17(services?.gateway, () => "gateway service not provided");
859
- const stateMap = assertEx17(services?.xl1TxStateMap, () => "xl1TxStateMap service not provided");
860
- const worker = new Worker8(queueName8, async (job) => {
1085
+ // src/services/queue/workers/Xl1TransactionSubmission.ts
1086
+ import { assertEx as assertEx20, isDefined as isDefined11 } from "@xylabs/sdk-js";
1087
+ import { PayloadBuilder as PayloadBuilder13 } from "@xyo-network/sdk-js";
1088
+ import { Worker as Worker11 } from "bullmq";
1089
+ var name11 = "Submit XL1 Transaction";
1090
+ var queueName11 = "xl1-tx-submit";
1091
+ var createWorker11 = /* @__PURE__ */ __name((connection2, telemetry2, services) => {
1092
+ const gateway = assertEx20(services?.gateway, () => "gateway service not provided");
1093
+ const stateMap = assertEx20(services?.xl1TxStateMap, () => "xl1TxStateMap service not provided");
1094
+ const worker = new Worker11(queueName11, async (job) => {
861
1095
  const { tx } = job.data;
862
- const hash = await PayloadBuilder11.hash(tx[0]);
863
- const state = assertEx17(await stateMap.get(hash), () => `[${hash}] state not found`);
1096
+ const hash = await PayloadBuilder13.hash(tx[0]);
1097
+ const state = assertEx20(await stateMap.get(hash), () => `[${hash}] state not found`);
864
1098
  const { preparedTx, offChainPayloads = [], submissionHash: existingSubmissionHash } = state;
865
- if (isDefined9(existingSubmissionHash)) {
1099
+ if (isDefined11(existingSubmissionHash)) {
866
1100
  await job.log(`[${hash}] Tx already submitted with submission response hash ${existingSubmissionHash}`);
867
1101
  return {
868
1102
  submissionHash: existingSubmissionHash
869
1103
  };
870
1104
  }
871
- const txToSubmit = assertEx17(preparedTx, () => `[${hash}] preparedTx not found`);
1105
+ const txToSubmit = assertEx20(preparedTx, () => `[${hash}] preparedTx not found`);
872
1106
  await job.log(`[${hash}] Submitting XL1 tx`);
873
1107
  const [submissionHash] = await submitXl1Transaction(txToSubmit, offChainPayloads, gateway);
874
1108
  await job.log(`[${hash}] Submitted XL1 tx`);
@@ -881,32 +1115,32 @@ var createWorker8 = /* @__PURE__ */ __name((connection2, telemetry2, services) =
881
1115
  prefix
882
1116
  });
883
1117
  worker.on("failed", (job, err) => {
884
- console.error(`[${name8}] Job ${job?.id} failed:`, err.message);
1118
+ console.error(`[${name11}] Job ${job?.id} failed:`, err.message);
885
1119
  });
886
1120
  worker.on("error", (err) => {
887
- console.error(`[${name8}] Worker error:`, err);
1121
+ console.error(`[${name11}] Worker error:`, err);
888
1122
  });
889
1123
  }, "createWorker");
890
1124
  var Xl1TransactionSubmission = {
891
- createWorker: createWorker8,
892
- name: name8,
893
- queueName: queueName8
1125
+ createWorker: createWorker11,
1126
+ name: name11,
1127
+ queueName: queueName11
894
1128
  };
895
1129
 
896
- // src/queue/workers/Xl1TransactionSubmissionStorage.ts
897
- import { assertEx as assertEx18, isDefined as isDefined10 } from "@xylabs/sdk-js";
898
- import { PayloadBuilder as PayloadBuilder12 } from "@xyo-network/sdk-js";
899
- import { Worker as Worker9 } from "bullmq";
900
- var name9 = "Store XL1 Transaction Submission";
901
- var queueName9 = "xl1-tx-store-submission";
902
- var createWorker9 = /* @__PURE__ */ __name((connection2, telemetry2, services) => {
903
- const stateMap = assertEx18(services?.xl1TxStateMap, () => "xl1TxStateMap service not provided");
904
- const worker = new Worker9(queueName9, async (job) => {
1130
+ // src/services/queue/workers/Xl1TransactionSubmissionStorage.ts
1131
+ import { assertEx as assertEx21, isDefined as isDefined12 } from "@xylabs/sdk-js";
1132
+ import { PayloadBuilder as PayloadBuilder14 } from "@xyo-network/sdk-js";
1133
+ import { Worker as Worker12 } from "bullmq";
1134
+ var name12 = "Store XL1 Transaction Submission";
1135
+ var queueName12 = "xl1-tx-store-submission";
1136
+ var createWorker12 = /* @__PURE__ */ __name((connection2, telemetry2, services) => {
1137
+ const stateMap = assertEx21(services?.xl1TxStateMap, () => "xl1TxStateMap service not provided");
1138
+ const worker = new Worker12(queueName12, async (job) => {
905
1139
  const { tx } = job.data;
906
- const hash = await PayloadBuilder12.hash(tx[0]);
907
- const state = assertEx18(await stateMap.get(hash), () => `[${hash}] state not found`);
1140
+ const hash = await PayloadBuilder14.hash(tx[0]);
1141
+ const state = assertEx21(await stateMap.get(hash), () => `[${hash}] state not found`);
908
1142
  const { submissionHash: existingSubmissionHash } = state;
909
- if (isDefined10(existingSubmissionHash)) {
1143
+ if (isDefined12(existingSubmissionHash)) {
910
1144
  await job.log(`[${hash}] submissionHash already stored as ${existingSubmissionHash}`);
911
1145
  return {
912
1146
  submissionHash: existingSubmissionHash
@@ -916,7 +1150,7 @@ var createWorker9 = /* @__PURE__ */ __name((connection2, telemetry2, services) =
916
1150
  const jobKey = `${prefix}:${Xl1TransactionSubmission.queueName}:${hash}`;
917
1151
  const childValues = childrenValues?.[jobKey];
918
1152
  const submissionHash = childValues?.submissionHash;
919
- const resolvedSubmissionHash = assertEx18(submissionHash, () => `[${hash}] child submissionHash not found in children values`);
1153
+ const resolvedSubmissionHash = assertEx21(submissionHash, () => `[${hash}] child submissionHash not found in children values`);
920
1154
  await job.log(`[${hash}] Storing XL1 submissionHash`);
921
1155
  state.submissionHash = resolvedSubmissionHash;
922
1156
  await stateMap.set(hash, state);
@@ -930,39 +1164,102 @@ var createWorker9 = /* @__PURE__ */ __name((connection2, telemetry2, services) =
930
1164
  prefix
931
1165
  });
932
1166
  worker.on("failed", (job, err) => {
933
- console.error(`[${name9}] Job ${job?.id} failed:`, err.message);
1167
+ console.error(`[${name12}] Job ${job?.id} failed:`, err.message);
934
1168
  });
935
1169
  worker.on("error", (err) => {
936
- console.error(`[${name9}] Worker error:`, err);
1170
+ console.error(`[${name12}] Worker error:`, err);
1171
+ });
1172
+ }, "createWorker");
1173
+ var Xl1TransactionSubmissionStorage = {
1174
+ createWorker: createWorker12,
1175
+ name: name12,
1176
+ queueName: queueName12
1177
+ };
1178
+
1179
+ // src/services/queue/workers/createWorkers.ts
1180
+ var createWorkers = /* @__PURE__ */ __name((connection2, telemetry2, services) => {
1181
+ EthEventVerification.createWorker(connection2, telemetry2, services);
1182
+ EthToXl1BridgeParent.createWorker(connection2, telemetry2);
1183
+ EthTransactionMonitor.createWorker(connection2, telemetry2, services);
1184
+ EthTransactionPreparation.createWorker(connection2, telemetry2, services);
1185
+ EthTransactionSubmission.createWorker(connection2, telemetry2, services);
1186
+ EthTransactionSubmissionStorage.createWorker(connection2, telemetry2, services);
1187
+ Xl1ReserveTxFulfillment.createWorker(connection2, telemetry2, services);
1188
+ Xl1ToEthBridgeParent.createWorker(connection2, telemetry2);
1189
+ Xl1TransactionMonitor.createWorker(connection2, telemetry2, services);
1190
+ Xl1TransactionPreparation.createWorker(connection2, telemetry2, services);
1191
+ Xl1TransactionSubmission.createWorker(connection2, telemetry2, services);
1192
+ Xl1TransactionSubmissionStorage.createWorker(connection2, telemetry2, services);
1193
+ }, "createWorkers");
1194
+
1195
+ // src/services/queue/flows/createEthToXl1BridgeJob/getJobIdForEthToXl1BridgeJob.ts
1196
+ function getJobIdForEthToXl1BridgeJob(context) {
1197
+ return `evm:${context.evmChainId.toLowerCase()}:${context.contractAddress.toLowerCase()}:${context.bridgeId.toString()}`;
1198
+ }
1199
+ __name(getJobIdForEthToXl1BridgeJob, "getJobIdForEthToXl1BridgeJob");
1200
+
1201
+ // src/services/queue/flows/createEthToXl1BridgeJob/createEthToXl1BridgeJob.ts
1202
+ var STAGE_2_RETRY = {
1203
+ attempts: 1e3,
1204
+ backoff: {
1205
+ delay: 1e4,
1206
+ type: "fixed"
1207
+ }
1208
+ };
1209
+ var STAGE_1_RETRY = {
1210
+ attempts: 1
1211
+ };
1212
+ var createEthToXl1BridgeJob = /* @__PURE__ */ __name(async (flowProducer2, context) => {
1213
+ const jobId = getJobIdForEthToXl1BridgeJob(context);
1214
+ const identity = jobId;
1215
+ const stageJobData = {
1216
+ bridgeId: context.bridgeId.toString(),
1217
+ contractAddress: context.contractAddress,
1218
+ evmChainId: context.evmChainId,
1219
+ identity,
1220
+ xl1ChainId: context.xl1ChainId,
1221
+ xl1TokenAddress: context.xl1TokenAddress
1222
+ };
1223
+ return flowProducer2.add({
1224
+ name: EthToXl1BridgeParent.name,
1225
+ queueName: EthToXl1BridgeParent.queueName,
1226
+ data: stageJobData,
1227
+ opts: {
1228
+ jobId
1229
+ },
1230
+ children: [
1231
+ {
1232
+ name: Xl1ReserveTxFulfillment.name,
1233
+ queueName: Xl1ReserveTxFulfillment.queueName,
1234
+ data: stageJobData,
1235
+ opts: {
1236
+ jobId,
1237
+ ...STAGE_2_RETRY
1238
+ },
1239
+ children: [
1240
+ {
1241
+ name: EthEventVerification.name,
1242
+ queueName: EthEventVerification.queueName,
1243
+ data: stageJobData,
1244
+ opts: {
1245
+ jobId,
1246
+ ...STAGE_1_RETRY
1247
+ }
1248
+ }
1249
+ ]
1250
+ }
1251
+ ]
937
1252
  });
938
- }, "createWorker");
939
- var Xl1TransactionSubmissionStorage = {
940
- createWorker: createWorker9,
941
- name: name9,
942
- queueName: queueName9
943
- };
944
-
945
- // src/queue/workers/createWorkers.ts
946
- var createWorkers = /* @__PURE__ */ __name((connection2, telemetry2, services) => {
947
- EthTransactionMonitor.createWorker(connection2, telemetry2, services);
948
- EthTransactionPreparation.createWorker(connection2, telemetry2, services);
949
- EthTransactionSubmission.createWorker(connection2, telemetry2, services);
950
- EthTransactionSubmissionStorage.createWorker(connection2, telemetry2, services);
951
- Xl1ToEthBridgeParent.createWorker(connection2, telemetry2);
952
- Xl1TransactionMonitor.createWorker(connection2, telemetry2, services);
953
- Xl1TransactionPreparation.createWorker(connection2, telemetry2, services);
954
- Xl1TransactionSubmission.createWorker(connection2, telemetry2, services);
955
- Xl1TransactionSubmissionStorage.createWorker(connection2, telemetry2, services);
956
- }, "createWorkers");
1253
+ }, "createEthToXl1BridgeJob");
957
1254
 
958
- // src/queue/flows/createXl1ToEthBridgeJob/getJobIdForXl1ToEthBridgeJob.ts
959
- import { PayloadBuilder as PayloadBuilder13 } from "@xyo-network/sdk-js";
1255
+ // src/services/queue/flows/createXl1ToEthBridgeJob/getJobIdForXl1ToEthBridgeJob.ts
1256
+ import { PayloadBuilder as PayloadBuilder15 } from "@xyo-network/sdk-js";
960
1257
  var getJobIdForXl1ToEthBridgeJob = /* @__PURE__ */ __name(async (tx) => {
961
- const jobId = await PayloadBuilder13.hash(tx[0]);
1258
+ const jobId = await PayloadBuilder15.hash(tx[0]);
962
1259
  return jobId;
963
1260
  }, "getJobIdForXl1ToEthBridgeJob");
964
1261
 
965
- // src/queue/flows/createXl1ToEthBridgeJob/createXl1ToEthBridgeJob.ts
1262
+ // src/services/queue/flows/createXl1ToEthBridgeJob/createXl1ToEthBridgeJob.ts
966
1263
  var createXl1ToEthBridgeJob = /* @__PURE__ */ __name(async (flowProducer2, tx, offChainPayloads = []) => {
967
1264
  const jobId = await getJobIdForXl1ToEthBridgeJob(tx);
968
1265
  const flow = await flowProducer2.add({
@@ -1117,7 +1414,7 @@ var createXl1ToEthBridgeJob = /* @__PURE__ */ __name(async (flowProducer2, tx, o
1117
1414
  return flow;
1118
1415
  }, "createXl1ToEthBridgeJob");
1119
1416
 
1120
- // src/queue/flows/createXl1ToEthBridgeJob/getXl1ToEthBridgeJob.ts
1417
+ // src/services/queue/flows/createXl1ToEthBridgeJob/getXl1ToEthBridgeJob.ts
1121
1418
  var getXl1ToEthBridgeJob = /* @__PURE__ */ __name(async (flowProducer2, tx) => {
1122
1419
  const id = await getJobIdForXl1ToEthBridgeJob(tx);
1123
1420
  const flow = await flowProducer2.getFlow({
@@ -1127,7 +1424,30 @@ var getXl1ToEthBridgeJob = /* @__PURE__ */ __name(async (flowProducer2, tx) => {
1127
1424
  return flow;
1128
1425
  }, "getXl1ToEthBridgeJob");
1129
1426
 
1130
- // src/queue/getXl1ToEthQueueJobs.ts
1427
+ // src/services/queue/getEthToXl1Queues.ts
1428
+ import { Queue } from "bullmq";
1429
+ var ethToXl1Queues;
1430
+ var getEthToXl1Queues = /* @__PURE__ */ __name((config) => {
1431
+ if (ethToXl1Queues) return ethToXl1Queues;
1432
+ const connection2 = getConnection(config);
1433
+ ethToXl1Queues = {
1434
+ ethEventVerification: new Queue(EthEventVerification.queueName, {
1435
+ connection: connection2,
1436
+ prefix
1437
+ }),
1438
+ ethToXl1BridgeParent: new Queue(EthToXl1BridgeParent.queueName, {
1439
+ connection: connection2,
1440
+ prefix
1441
+ }),
1442
+ xl1ReserveTxFulfillment: new Queue(Xl1ReserveTxFulfillment.queueName, {
1443
+ connection: connection2,
1444
+ prefix
1445
+ })
1446
+ };
1447
+ return ethToXl1Queues;
1448
+ }, "getEthToXl1Queues");
1449
+
1450
+ // src/services/queue/getXl1ToEthQueueJobs.ts
1131
1451
  var getStatusQueueJobs = /* @__PURE__ */ __name(async (queues, jobId) => {
1132
1452
  const [ethTransactionMonitorJob, ethTransactionPreparationJob, ethTransactionSubmissionJob, xl1ToEthBridgeParentJob, xl1TransactionMonitorJob, xl1TransactionPreparationJob, xl1TransactionSubmissionJob, xl1TransactionSubmissionStorageJob] = await Promise.all([
1133
1453
  queues.ethTransactionMonitor.getJob(jobId),
@@ -1151,42 +1471,42 @@ var getStatusQueueJobs = /* @__PURE__ */ __name(async (queues, jobId) => {
1151
1471
  };
1152
1472
  }, "getStatusQueueJobs");
1153
1473
 
1154
- // src/queue/getXl1ToEthQueues.ts
1155
- import { Queue } from "bullmq";
1474
+ // src/services/queue/getXl1ToEthQueues.ts
1475
+ import { Queue as Queue2 } from "bullmq";
1156
1476
  var xl1ToEthQueues;
1157
1477
  var getXl1ToEthQueues = /* @__PURE__ */ __name((config) => {
1158
1478
  if (xl1ToEthQueues) return xl1ToEthQueues;
1159
1479
  const connection2 = getConnection(config);
1160
1480
  xl1ToEthQueues = {
1161
- ethTransactionMonitor: new Queue(EthTransactionMonitor.queueName, {
1481
+ ethTransactionMonitor: new Queue2(EthTransactionMonitor.queueName, {
1162
1482
  connection: connection2,
1163
1483
  prefix
1164
1484
  }),
1165
- ethTransactionPreparation: new Queue(EthTransactionPreparation.queueName, {
1485
+ ethTransactionPreparation: new Queue2(EthTransactionPreparation.queueName, {
1166
1486
  connection: connection2,
1167
1487
  prefix
1168
1488
  }),
1169
- ethTransactionSubmission: new Queue(EthTransactionSubmission.queueName, {
1489
+ ethTransactionSubmission: new Queue2(EthTransactionSubmission.queueName, {
1170
1490
  connection: connection2,
1171
1491
  prefix
1172
1492
  }),
1173
- xl1ToEthBridgeParent: new Queue(Xl1ToEthBridgeParent.queueName, {
1493
+ xl1ToEthBridgeParent: new Queue2(Xl1ToEthBridgeParent.queueName, {
1174
1494
  connection: connection2,
1175
1495
  prefix
1176
1496
  }),
1177
- xl1TransactionMonitor: new Queue(Xl1TransactionMonitor.queueName, {
1497
+ xl1TransactionMonitor: new Queue2(Xl1TransactionMonitor.queueName, {
1178
1498
  connection: connection2,
1179
1499
  prefix
1180
1500
  }),
1181
- xl1TransactionPreparation: new Queue(Xl1TransactionPreparation.queueName, {
1501
+ xl1TransactionPreparation: new Queue2(Xl1TransactionPreparation.queueName, {
1182
1502
  connection: connection2,
1183
1503
  prefix
1184
1504
  }),
1185
- xl1TransactionSubmission: new Queue(Xl1TransactionSubmission.queueName, {
1505
+ xl1TransactionSubmission: new Queue2(Xl1TransactionSubmission.queueName, {
1186
1506
  connection: connection2,
1187
1507
  prefix
1188
1508
  }),
1189
- xl1TransactionSubmissionStorage: new Queue(Xl1TransactionSubmissionStorage.queueName, {
1509
+ xl1TransactionSubmissionStorage: new Queue2(Xl1TransactionSubmissionStorage.queueName, {
1190
1510
  connection: connection2,
1191
1511
  prefix
1192
1512
  })
@@ -1194,24 +1514,167 @@ var getXl1ToEthQueues = /* @__PURE__ */ __name((config) => {
1194
1514
  return xl1ToEthQueues;
1195
1515
  }, "getXl1ToEthQueues");
1196
1516
 
1197
- // src/queue/telemetry.ts
1198
- import { isDefined as isDefined11 } from "@xylabs/sdk-js";
1517
+ // src/services/queue/scanner/createEnqueueEthToXl1Bridge.ts
1518
+ function createEnqueueEthToXl1Bridge(options2) {
1519
+ const { evmChainId, evmContractAddress, flowProducer: flowProducer2, xl1ChainId, xl1TokenAddress } = options2;
1520
+ return async (bridgeId, jobLog) => {
1521
+ await createEthToXl1BridgeJob(flowProducer2, {
1522
+ bridgeId,
1523
+ contractAddress: evmContractAddress,
1524
+ evmChainId,
1525
+ xl1ChainId,
1526
+ xl1TokenAddress
1527
+ });
1528
+ await jobLog?.(`[bridge-scanner] bridgeId ${bridgeId} enqueued`);
1529
+ };
1530
+ }
1531
+ __name(createEnqueueEthToXl1Bridge, "createEnqueueEthToXl1Bridge");
1532
+
1533
+ // src/services/queue/scanner/EvmBridgeScanner.ts
1534
+ import { isUndefined as isUndefined2 } from "@xylabs/sdk-js";
1535
+
1536
+ // src/services/queue/scanner/EvmBridgeCursor.ts
1537
+ function getEvmBridgeCursorKey(chainId, contractAddress) {
1538
+ return `${chainId.toLowerCase()}:${contractAddress.toLowerCase()}`;
1539
+ }
1540
+ __name(getEvmBridgeCursorKey, "getEvmBridgeCursorKey");
1541
+
1542
+ // src/services/queue/scanner/EvmBridgeScanner.ts
1543
+ function createEvmBridgeScanner(options2) {
1544
+ const { bridge, bridgeAddress, chainId, confirmationDepth, cursors, enqueue, provider } = options2;
1545
+ const cursorKey = getEvmBridgeCursorKey(chainId, bridgeAddress);
1546
+ return {
1547
+ async scan(options3) {
1548
+ const jobLog = options3?.jobLog;
1549
+ const blockTag = await resolveEvmBlockTagAtDepth(provider, confirmationDepth);
1550
+ const confirmedHigh = await bridge.nextBridgeToId({
1551
+ blockTag
1552
+ });
1553
+ const cursor = await cursors.get(cursorKey);
1554
+ const lastProcessedId = isUndefined2(cursor) ? 0n : BigInt(cursor.lastProcessedId);
1555
+ if (confirmedHigh <= lastProcessedId) {
1556
+ return {
1557
+ confirmedHigh,
1558
+ enqueued: 0,
1559
+ lastProcessedId
1560
+ };
1561
+ }
1562
+ let enqueued = 0;
1563
+ for (let id = lastProcessedId + 1n; id <= confirmedHigh; id++) {
1564
+ await enqueue(id, jobLog);
1565
+ enqueued++;
1566
+ }
1567
+ await cursors.set(cursorKey, {
1568
+ lastProcessedId: confirmedHigh.toString()
1569
+ });
1570
+ return {
1571
+ confirmedHigh,
1572
+ enqueued,
1573
+ lastProcessedId
1574
+ };
1575
+ }
1576
+ };
1577
+ }
1578
+ __name(createEvmBridgeScanner, "createEvmBridgeScanner");
1579
+
1580
+ // src/services/queue/scanner/EvmBridgeScannerRunner.ts
1581
+ import { Queue as Queue3, Worker as Worker13 } from "bullmq";
1582
+ var QUEUE_NAME = "eth-to-xl1-scanner";
1583
+ var REPEATABLE_JOB_NAME = "scan";
1584
+ var REPEATABLE_JOB_ID = "eth-to-xl1-scanner-tick";
1585
+ function createEvmBridgeScannerRunner(options2) {
1586
+ const { connection: connection2, intervalMs, scanner, telemetry: telemetry2 } = options2;
1587
+ const logger = options2.logger ?? console;
1588
+ let queue;
1589
+ let worker;
1590
+ return {
1591
+ async start() {
1592
+ queue = new Queue3(QUEUE_NAME, {
1593
+ connection: connection2,
1594
+ prefix,
1595
+ telemetry: telemetry2
1596
+ });
1597
+ worker = new Worker13(QUEUE_NAME, async (job) => {
1598
+ await job.log("[scanner] tick start");
1599
+ const result = await scanner.scan({
1600
+ jobLog: /* @__PURE__ */ __name((msg) => job.log(msg), "jobLog")
1601
+ });
1602
+ await job.log(`[scanner] tick complete: enqueued=${result.enqueued} confirmedHigh=${result.confirmedHigh.toString()} lastProcessedId=${result.lastProcessedId.toString()}`);
1603
+ }, {
1604
+ connection: connection2,
1605
+ prefix,
1606
+ telemetry: telemetry2
1607
+ });
1608
+ worker.on("failed", (job, err) => {
1609
+ logger.error(`[scanner] tick ${job?.id} failed:`, err.message);
1610
+ });
1611
+ worker.on("error", (err) => {
1612
+ logger.error("[scanner] worker error:", err);
1613
+ });
1614
+ await queue.add(REPEATABLE_JOB_NAME, {}, {
1615
+ jobId: REPEATABLE_JOB_ID,
1616
+ repeat: {
1617
+ every: intervalMs
1618
+ }
1619
+ });
1620
+ },
1621
+ async stop() {
1622
+ await worker?.close();
1623
+ await queue?.close();
1624
+ worker = void 0;
1625
+ queue = void 0;
1626
+ }
1627
+ };
1628
+ }
1629
+ __name(createEvmBridgeScannerRunner, "createEvmBridgeScannerRunner");
1630
+
1631
+ // src/services/queue/scanner/buildEvmBridgeScannerRunner.ts
1632
+ function buildEvmBridgeScannerRunner(options2) {
1633
+ const { config, connection: connection2, flowProducer: flowProducer2, logger, services, telemetry: telemetry2 } = options2;
1634
+ const evmChainId = getRemoteChainId(config);
1635
+ const evmContractAddress = config.remoteBridgeContractAddress;
1636
+ const xl1ChainId = getXl1ChainId(config);
1637
+ const xl1TokenAddress = getXl1TokenAddress(config);
1638
+ const intervalMs = getScannerIntervalMs(config);
1639
+ const enqueue = createEnqueueEthToXl1Bridge({
1640
+ evmChainId,
1641
+ evmContractAddress,
1642
+ flowProducer: flowProducer2,
1643
+ xl1ChainId,
1644
+ xl1TokenAddress
1645
+ });
1646
+ const scanner = createEvmBridgeScanner({
1647
+ bridge: services.bridge,
1648
+ bridgeAddress: evmContractAddress,
1649
+ chainId: evmChainId,
1650
+ confirmationDepth: services.remoteConfirmationDepth,
1651
+ cursors: services.evmBridgeCursorMap,
1652
+ enqueue,
1653
+ provider: services.provider
1654
+ });
1655
+ return createEvmBridgeScannerRunner({
1656
+ connection: connection2,
1657
+ intervalMs,
1658
+ logger,
1659
+ scanner,
1660
+ telemetry: telemetry2
1661
+ });
1662
+ }
1663
+ __name(buildEvmBridgeScannerRunner, "buildEvmBridgeScannerRunner");
1664
+
1665
+ // src/services/queue/telemetry.ts
1666
+ import { isDefined as isDefined13 } from "@xylabs/sdk-js";
1199
1667
  import { BullMQOtel } from "bullmq-otel";
1200
1668
  var telemetry;
1201
1669
  var options = {
1202
1670
  enableMetrics: true
1203
1671
  };
1204
1672
  var getTelemetry = /* @__PURE__ */ __name(() => {
1205
- if (isDefined11(telemetry)) return telemetry;
1673
+ if (isDefined13(telemetry)) return telemetry;
1206
1674
  telemetry = new BullMQOtel(options);
1207
1675
  return telemetry;
1208
1676
  }, "getTelemetry");
1209
1677
 
1210
- // src/server/app.ts
1211
- import { standardErrors } from "@xylabs/express";
1212
- import { sharedMiddleware } from "@xyo-network/chain-orchestration";
1213
- import express from "express";
1214
-
1215
1678
  // src/server/addFlowProducer.ts
1216
1679
  var addFlowProducer = /* @__PURE__ */ __name((app, config) => {
1217
1680
  const connection2 = getConnection(config);
@@ -1310,18 +1773,18 @@ var makeBridgeConfigRoute = /* @__PURE__ */ __name((config) => {
1310
1773
 
1311
1774
  // src/server/routes/bridge/routeDefinitions/routes/bridgeFromRemoteStatus.ts
1312
1775
  import { requestHandlerValidator as requestHandlerValidator2 } from "@xylabs/express";
1313
- import { toAddress as toAddress2, toHex as toHex3 } from "@xylabs/sdk-js";
1776
+ import { isDefined as isDefined14, toHex as toHex4 } from "@xylabs/sdk-js";
1314
1777
  import { PayloadZodStrictOfSchema } from "@xyo-network/sdk-js";
1315
- import { BridgeDestinationObservationFieldsZod, BridgeDestinationObservationSchema } from "@xyo-network/xl1-sdk";
1778
+ import { BridgeDestinationObservationFieldsZod, BridgeDestinationObservationSchema, BridgeIntentFieldsZod, BridgeIntentSchema as BridgeIntentSchema4, BridgeSourceObservationFieldsZod, BridgeSourceObservationSchema as BridgeSourceObservationSchema2 } from "@xyo-network/xl1-sdk";
1316
1779
  import { z } from "zod";
1317
1780
 
1318
1781
  // src/server/routes/bridge/routeDefinitions/pathParams/ChainIdPathParam.ts
1319
- import { asHex as asHex2, HexZod, isUndefined as isUndefined2 } from "@xylabs/sdk-js";
1782
+ import { asHex as asHex3, HexZod, isUndefined as isUndefined3 } from "@xylabs/sdk-js";
1320
1783
  var getRemoteChainIdZod = /* @__PURE__ */ __name((config) => {
1321
1784
  const remoteChainId = getRemoteChainId(config);
1322
1785
  return HexZod.superRefine((val, ctx) => {
1323
- const chainId = asHex2(val);
1324
- if (isUndefined2(chainId)) {
1786
+ const chainId = asHex3(val);
1787
+ if (isUndefined3(chainId)) {
1325
1788
  ctx.addIssue("Not a valid chain id");
1326
1789
  return;
1327
1790
  }
@@ -1332,55 +1795,128 @@ var getRemoteChainIdZod = /* @__PURE__ */ __name((config) => {
1332
1795
  }, "getRemoteChainIdZod");
1333
1796
 
1334
1797
  // src/server/routes/bridge/routeDefinitions/routes/bridgeFromRemoteStatus.ts
1798
+ var BridgeIntentResponseZod = PayloadZodStrictOfSchema(BridgeIntentSchema4).extend(BridgeIntentFieldsZod.shape);
1799
+ var BridgeSourceResponseZod = PayloadZodStrictOfSchema(BridgeSourceObservationSchema2).extend(BridgeSourceObservationFieldsZod.shape);
1800
+ var BridgeDestinationResponseZod = PayloadZodStrictOfSchema(BridgeDestinationObservationSchema).extend(BridgeDestinationObservationFieldsZod.shape);
1801
+ var BridgeFromRemoteStatusResponseZod = z.union([
1802
+ z.tuple([]),
1803
+ z.tuple([
1804
+ BridgeIntentResponseZod
1805
+ ]),
1806
+ z.tuple([
1807
+ BridgeIntentResponseZod,
1808
+ BridgeSourceResponseZod
1809
+ ]),
1810
+ z.tuple([
1811
+ BridgeIntentResponseZod,
1812
+ BridgeSourceResponseZod,
1813
+ BridgeDestinationResponseZod
1814
+ ])
1815
+ ]);
1816
+ function buildIntentAndSource(ctx) {
1817
+ const { canonical, config, nonce } = ctx;
1818
+ const amountHex = toHex4(canonical.amount);
1819
+ const xl1ChainId = getXl1ChainId(config);
1820
+ const xl1TokenAddress = getXl1TokenAddress(config);
1821
+ const evmChainId = config.remoteChainId;
1822
+ const evmTokenAddress = getRemoteTokenAddress(config);
1823
+ const intentFields = BridgeIntentFieldsZod.parse({
1824
+ dest: xl1ChainId,
1825
+ destAddress: canonical.destAddress,
1826
+ destAmount: amountHex,
1827
+ destToken: xl1TokenAddress,
1828
+ nonce,
1829
+ src: evmChainId,
1830
+ srcAddress: canonical.srcAddress,
1831
+ srcAmount: amountHex,
1832
+ srcToken: evmTokenAddress
1833
+ });
1834
+ const intent = {
1835
+ schema: BridgeIntentSchema4,
1836
+ ...intentFields
1837
+ };
1838
+ const sourceFields = BridgeSourceObservationFieldsZod.parse({
1839
+ ...intentFields,
1840
+ srcConfirmation: canonical.evmTxHash
1841
+ });
1842
+ const source = {
1843
+ schema: BridgeSourceObservationSchema2,
1844
+ ...sourceFields
1845
+ };
1846
+ return [
1847
+ intent,
1848
+ source
1849
+ ];
1850
+ }
1851
+ __name(buildIntentAndSource, "buildIntentAndSource");
1335
1852
  var makeBridgeFromRemoteStatusRoute = /* @__PURE__ */ __name((config) => {
1336
1853
  const params = z.object({
1337
1854
  chainId: getRemoteChainIdZod(config),
1338
- nonce: z.string().nonempty()
1855
+ nonce: z.string().regex(/^\d+$/, "nonce must be a non-negative integer (the bridge contract's id)")
1339
1856
  });
1340
- const response = PayloadZodStrictOfSchema(BridgeDestinationObservationSchema).extend(BridgeDestinationObservationFieldsZod.shape);
1341
1857
  const validateRequest2 = requestHandlerValidator2({
1342
1858
  params,
1343
- response
1859
+ response: BridgeFromRemoteStatusResponseZod
1344
1860
  });
1345
1861
  return {
1346
1862
  method: "get",
1347
1863
  path: "/bridge/chains/:chainId/bridgeFromRemote/status/:nonce",
1348
1864
  handlers: validateRequest2(async (req, res) => {
1349
- const { remoteChainId, remoteTokenAddress, xl1ChainId, xl1TokenAddress } = await getBridgeSettings(config);
1350
- const rand = await Promise.resolve(Math.random());
1351
- const found = rand > 0.5;
1352
- if (!found) return res.sendStatus(404);
1353
- const confirmed = rand > 0.8;
1354
- if (!confirmed) return res.sendStatus(204);
1355
- const observation = {
1865
+ const bridgeId = BigInt(req.params.nonce);
1866
+ const contractAddress = config.remoteBridgeContractAddress;
1867
+ const evmChainId = config.remoteChainId;
1868
+ const identity = getJobIdForEthToXl1BridgeJob({
1869
+ bridgeId,
1870
+ contractAddress,
1871
+ evmChainId
1872
+ });
1873
+ const services = req.app.services;
1874
+ const state = await services.bridgeFulfillmentMap.get(identity);
1875
+ if (state?.failed) return res.sendStatus(504);
1876
+ if (!state?.canonical) {
1877
+ const queues = getEthToXl1Queues(config);
1878
+ const parentJob = await queues.ethToXl1BridgeParent.getJob(identity);
1879
+ if (!isDefined14(parentJob)) return res.sendStatus(404);
1880
+ return res.json([]);
1881
+ }
1882
+ const [intent, source] = buildIntentAndSource({
1883
+ canonical: state.canonical,
1884
+ config,
1885
+ nonce: identity
1886
+ });
1887
+ if (!state.fulfilled) return res.json([
1888
+ intent,
1889
+ source
1890
+ ]);
1891
+ const destinationFields = BridgeDestinationObservationFieldsZod.parse({
1892
+ ...intent,
1893
+ destConfirmation: state.fulfilled.txHash
1894
+ });
1895
+ const destination = {
1356
1896
  schema: BridgeDestinationObservationSchema,
1357
- dest: xl1ChainId,
1358
- destAddress: toAddress2("0xabc"),
1359
- destAmount: toHex3("0x100"),
1360
- destToken: xl1TokenAddress,
1361
- src: remoteChainId,
1362
- srcAddress: toAddress2("0x123"),
1363
- srcAmount: toHex3("0x200"),
1364
- srcToken: remoteTokenAddress,
1365
- destConfirmation: toHex3("0x9999")
1897
+ ...destinationFields
1366
1898
  };
1367
- res.json(observation);
1899
+ res.json([
1900
+ intent,
1901
+ source,
1902
+ destination
1903
+ ]);
1368
1904
  })
1369
1905
  };
1370
1906
  }, "makeBridgeFromRemoteStatusRoute");
1371
1907
 
1372
1908
  // src/server/routes/bridge/routeDefinitions/routes/bridgeToRemote.ts
1373
1909
  import { requestHandlerValidator as requestHandlerValidator3 } from "@xylabs/express";
1374
- import { isDefined as isDefined12 } from "@xylabs/sdk-js";
1375
- import { PayloadBuilder as PayloadBuilder14, PayloadZodLooseOfSchema, PayloadZodStrictOfSchema as PayloadZodStrictOfSchema2 } from "@xyo-network/sdk-js";
1376
- import { BridgeIntentFieldsZod, BridgeIntentSchema as BridgeIntentSchema3, BridgeSourceObservationFieldsZod, BridgeSourceObservationSchema, SignedTransactionBoundWitnessZod, TransferZod } from "@xyo-network/xl1-sdk";
1910
+ import { isDefined as isDefined15 } from "@xylabs/sdk-js";
1911
+ import { PayloadBuilder as PayloadBuilder16, PayloadZodLooseOfSchema, PayloadZodStrictOfSchema as PayloadZodStrictOfSchema2 } from "@xyo-network/sdk-js";
1912
+ import { BridgeIntentFieldsZod as BridgeIntentFieldsZod2, BridgeIntentSchema as BridgeIntentSchema5, BridgeSourceObservationFieldsZod as BridgeSourceObservationFieldsZod2, BridgeSourceObservationSchema as BridgeSourceObservationSchema3, SignedTransactionBoundWitnessZod, TransferZod } from "@xyo-network/xl1-sdk";
1377
1913
  import { z as z2 } from "zod";
1378
1914
  var BridgeToRemoteBodyZod = z2.tuple([
1379
1915
  SignedTransactionBoundWitnessZod,
1380
- PayloadZodLooseOfSchema(BridgeIntentSchema3).extend(BridgeIntentFieldsZod.shape),
1916
+ PayloadZodLooseOfSchema(BridgeIntentSchema5).extend(BridgeIntentFieldsZod2.shape),
1381
1917
  TransferZod
1382
1918
  ]);
1383
- var BridgeToRemoteResponseZod = PayloadZodStrictOfSchema2(BridgeSourceObservationSchema).extend(BridgeSourceObservationFieldsZod.shape);
1919
+ var BridgeToRemoteResponseZod = PayloadZodStrictOfSchema2(BridgeSourceObservationSchema3).extend(BridgeSourceObservationFieldsZod2.shape);
1384
1920
  var makeBridgeToRemoteRoute = /* @__PURE__ */ __name((config) => {
1385
1921
  const params = z2.object({
1386
1922
  chainId: getRemoteChainIdZod(config)
@@ -1419,22 +1955,22 @@ var makeBridgeToRemoteRoute = /* @__PURE__ */ __name((config) => {
1419
1955
  ]
1420
1956
  ];
1421
1957
  const existingFlow = await getXl1ToEthBridgeJob(flowProducer2, singedHydratedTransaction);
1422
- if (isDefined12(existingFlow)) {
1958
+ if (isDefined15(existingFlow)) {
1423
1959
  res.status(200).send();
1424
1960
  return;
1425
1961
  }
1426
1962
  await createXl1ToEthBridgeJob(flowProducer2, singedHydratedTransaction, [
1427
1963
  bridgeIntent
1428
1964
  ]);
1429
- const srcConfirmation = await PayloadBuilder14.hash(signedTxBw);
1430
- const bridgeCommonFieldsZod = z2.object({}).extend(BridgeSourceObservationFieldsZod.shape);
1965
+ const srcConfirmation = await PayloadBuilder16.hash(signedTxBw);
1966
+ const bridgeCommonFieldsZod = z2.object({}).extend(BridgeSourceObservationFieldsZod2.shape);
1431
1967
  const bridgeCommonFields = bridgeCommonFieldsZod.parse(bridgeIntent);
1432
1968
  const bridgeObservationFields = {
1433
1969
  ...bridgeCommonFields,
1434
1970
  srcConfirmation
1435
1971
  };
1436
- const bridgeObservation = new PayloadBuilder14({
1437
- schema: BridgeSourceObservationSchema
1972
+ const bridgeObservation = new PayloadBuilder16({
1973
+ schema: BridgeSourceObservationSchema3
1438
1974
  }).fields(bridgeObservationFields).build();
1439
1975
  res.status(202).json(bridgeObservation);
1440
1976
  })
@@ -1443,18 +1979,18 @@ var makeBridgeToRemoteRoute = /* @__PURE__ */ __name((config) => {
1443
1979
 
1444
1980
  // src/server/routes/bridge/routeDefinitions/routes/bridgeToRemoteEstimate.ts
1445
1981
  import { requestHandlerValidator as requestHandlerValidator4 } from "@xylabs/express";
1446
- import { assertEx as assertEx19, hexToBigInt as hexToBigInt10, toAddress as toAddress3 } from "@xylabs/sdk-js";
1982
+ import { assertEx as assertEx22, hexToBigInt as hexToBigInt10, toAddress as toAddress3 } from "@xylabs/sdk-js";
1447
1983
  import { PayloadZodStrictOfSchema as PayloadZodStrictOfSchema3 } from "@xyo-network/sdk-js";
1448
- import { BridgeIntentFieldsZod as BridgeIntentFieldsZod2, BridgeIntentSchema as BridgeIntentSchema4, buildUnsignedTransaction, toXL1BlockNumber, TransactionBoundWitnessZod, TransferZod as TransferZod2 } from "@xyo-network/xl1-sdk";
1984
+ import { BridgeIntentFieldsZod as BridgeIntentFieldsZod3, BridgeIntentSchema as BridgeIntentSchema6, buildUnsignedTransaction, toXL1BlockNumber, TransactionBoundWitnessZod, TransferZod as TransferZod2 } from "@xyo-network/xl1-sdk";
1449
1985
  import { z as z3 } from "zod";
1450
- var BridgeToRemoteEstimateBodyZod = BridgeIntentFieldsZod2.pick({
1986
+ var BridgeToRemoteEstimateBodyZod = BridgeIntentFieldsZod3.pick({
1451
1987
  destAddress: true,
1452
1988
  srcAddress: true,
1453
1989
  srcAmount: true
1454
1990
  });
1455
1991
  var BridgeToRemoteEstimateResponseZod = z3.tuple([
1456
1992
  TransactionBoundWitnessZod,
1457
- PayloadZodStrictOfSchema3(BridgeIntentSchema4).extend(BridgeIntentFieldsZod2.shape),
1993
+ PayloadZodStrictOfSchema3(BridgeIntentSchema6).extend(BridgeIntentFieldsZod3.shape),
1458
1994
  TransferZod2
1459
1995
  ]);
1460
1996
  var makeBridgeToRemoteEstimateRoute = /* @__PURE__ */ __name((config, gateway) => {
@@ -1479,7 +2015,7 @@ var makeBridgeToRemoteEstimateRoute = /* @__PURE__ */ __name((config, gateway) =
1479
2015
  }
1480
2016
  const [bridgeIntent, transfer] = await generateBridgeEstimate(srcAddress, srcAmount, destAddress, config);
1481
2017
  const sender = toAddress3(srcAddress);
1482
- const viewer = assertEx19(gateway.connection.viewer, () => new Error("Viewer not available on gateway connection"));
2018
+ const viewer = assertEx22(gateway.connection.viewer, () => new Error("Viewer not available on gateway connection"));
1483
2019
  const currentBlockNumber = await viewer.currentBlockNumber();
1484
2020
  const nbf = toXL1BlockNumber(currentBlockNumber, true);
1485
2021
  const exp = toXL1BlockNumber(currentBlockNumber + 1e3, true);
@@ -1499,18 +2035,18 @@ var makeBridgeToRemoteEstimateRoute = /* @__PURE__ */ __name((config, gateway) =
1499
2035
 
1500
2036
  // src/server/routes/bridge/routeDefinitions/routes/bridgeToRemoteMaxEstimate.ts
1501
2037
  import { requestHandlerValidator as requestHandlerValidator5 } from "@xylabs/express";
1502
- import { assertEx as assertEx20, hexToBigInt as hexToBigInt11, toAddress as toAddress4, toHex as toHex4 } from "@xylabs/sdk-js";
2038
+ import { assertEx as assertEx23, hexToBigInt as hexToBigInt11, toAddress as toAddress4, toHex as toHex5 } from "@xylabs/sdk-js";
1503
2039
  import { PayloadZodStrictOfSchema as PayloadZodStrictOfSchema4 } from "@xyo-network/sdk-js";
1504
- import { BridgeIntentFieldsZod as BridgeIntentFieldsZod3, BridgeIntentSchema as BridgeIntentSchema5, buildUnsignedTransaction as buildUnsignedTransaction2, toXL1BlockNumber as toXL1BlockNumber2, TransactionBoundWitnessZod as TransactionBoundWitnessZod2, TransferZod as TransferZod3 } from "@xyo-network/xl1-sdk";
2040
+ import { BridgeIntentFieldsZod as BridgeIntentFieldsZod4, BridgeIntentSchema as BridgeIntentSchema7, buildUnsignedTransaction as buildUnsignedTransaction2, toXL1BlockNumber as toXL1BlockNumber2, TransactionBoundWitnessZod as TransactionBoundWitnessZod2, TransferZod as TransferZod3 } from "@xyo-network/xl1-sdk";
1505
2041
  import { z as z4 } from "zod";
1506
- var BridgeToRemoteMaxEstimateBodyZod = BridgeIntentFieldsZod3.pick({
2042
+ var BridgeToRemoteMaxEstimateBodyZod = BridgeIntentFieldsZod4.pick({
1507
2043
  destAddress: true,
1508
2044
  srcAddress: true,
1509
2045
  srcAmount: true
1510
2046
  });
1511
2047
  var BridgeToRemoteMaxEstimateResponseZod = z4.tuple([
1512
2048
  TransactionBoundWitnessZod2,
1513
- PayloadZodStrictOfSchema4(BridgeIntentSchema5).extend(BridgeIntentFieldsZod3.shape),
2049
+ PayloadZodStrictOfSchema4(BridgeIntentSchema7).extend(BridgeIntentFieldsZod4.shape),
1514
2050
  TransferZod3
1515
2051
  ]);
1516
2052
  var makeBridgeToRemoteMaxEstimateRoute = /* @__PURE__ */ __name((config, gateway) => {
@@ -1532,10 +2068,10 @@ var makeBridgeToRemoteMaxEstimateRoute = /* @__PURE__ */ __name((config, gateway
1532
2068
  feeFixed,
1533
2069
  feeRateBasisPoints
1534
2070
  });
1535
- const maxBridgeAmount = toHex4(hexToBigInt11(balanceMax) < hexToBigInt11(configMax) ? balanceMax : configMax);
2071
+ const maxBridgeAmount = toHex5(hexToBigInt11(balanceMax) < hexToBigInt11(configMax) ? balanceMax : configMax);
1536
2072
  const [bridgeIntent, transfer] = await generateBridgeEstimate(srcAddress, maxBridgeAmount, destAddress, config);
1537
2073
  const sender = toAddress4(srcAddress);
1538
- const viewer = assertEx20(gateway.connection.viewer, () => new Error("Viewer not available on gateway connection"));
2074
+ const viewer = assertEx23(gateway.connection.viewer, () => new Error("Viewer not available on gateway connection"));
1539
2075
  const currentBlockNumber = await viewer.currentBlockNumber();
1540
2076
  const nbf = toXL1BlockNumber2(currentBlockNumber, true);
1541
2077
  const exp = toXL1BlockNumber2(currentBlockNumber + 1e3, true);
@@ -1555,26 +2091,26 @@ var makeBridgeToRemoteMaxEstimateRoute = /* @__PURE__ */ __name((config, gateway
1555
2091
 
1556
2092
  // src/server/routes/bridge/routeDefinitions/routes/bridgeToRemoteStatus.ts
1557
2093
  import { requestHandlerValidator as requestHandlerValidator6 } from "@xylabs/express";
1558
- import { asHex as asHex3, isDefined as isDefined13 } from "@xylabs/sdk-js";
1559
- import { PayloadBuilder as PayloadBuilder15, PayloadZodStrictOfSchema as PayloadZodStrictOfSchema5 } from "@xyo-network/sdk-js";
1560
- import { asBridgeIntent, BridgeDestinationObservationFieldsZod as BridgeDestinationObservationFieldsZod2, BridgeDestinationObservationSchema as BridgeDestinationObservationSchema2, BridgeIntentFieldsZod as BridgeIntentFieldsZod4, BridgeIntentSchema as BridgeIntentSchema6, BridgeSourceObservationFieldsZod as BridgeSourceObservationFieldsZod2, BridgeSourceObservationSchema as BridgeSourceObservationSchema2, isBridgeIntent as isBridgeIntent5 } from "@xyo-network/xl1-sdk";
2094
+ import { asHex as asHex4, isDefined as isDefined16 } from "@xylabs/sdk-js";
2095
+ import { PayloadBuilder as PayloadBuilder17, PayloadZodStrictOfSchema as PayloadZodStrictOfSchema5 } from "@xyo-network/sdk-js";
2096
+ import { asBridgeIntent, BridgeDestinationObservationFieldsZod as BridgeDestinationObservationFieldsZod2, BridgeDestinationObservationSchema as BridgeDestinationObservationSchema2, BridgeIntentFieldsZod as BridgeIntentFieldsZod5, BridgeIntentSchema as BridgeIntentSchema8, BridgeSourceObservationFieldsZod as BridgeSourceObservationFieldsZod3, BridgeSourceObservationSchema as BridgeSourceObservationSchema4, isBridgeIntent as isBridgeIntent5 } from "@xyo-network/xl1-sdk";
1561
2097
  import { z as z5 } from "zod";
1562
- var BridgeIntentResponseZod = PayloadZodStrictOfSchema5(BridgeIntentSchema6).extend(BridgeIntentFieldsZod4.shape);
1563
- var BridgeSourceResponseZod = PayloadZodStrictOfSchema5(BridgeSourceObservationSchema2).extend(BridgeSourceObservationFieldsZod2.shape);
1564
- var BridgeDestinationResponseZod = PayloadZodStrictOfSchema5(BridgeDestinationObservationSchema2).extend(BridgeDestinationObservationFieldsZod2.shape);
2098
+ var BridgeIntentResponseZod2 = PayloadZodStrictOfSchema5(BridgeIntentSchema8).extend(BridgeIntentFieldsZod5.shape);
2099
+ var BridgeSourceResponseZod2 = PayloadZodStrictOfSchema5(BridgeSourceObservationSchema4).extend(BridgeSourceObservationFieldsZod3.shape);
2100
+ var BridgeDestinationResponseZod2 = PayloadZodStrictOfSchema5(BridgeDestinationObservationSchema2).extend(BridgeDestinationObservationFieldsZod2.shape);
1565
2101
  var BridgeToRemoteStatusResponseZod = z5.union([
1566
2102
  z5.tuple([]),
1567
2103
  z5.tuple([
1568
- BridgeIntentResponseZod
2104
+ BridgeIntentResponseZod2
1569
2105
  ]),
1570
2106
  z5.tuple([
1571
- BridgeIntentResponseZod,
1572
- BridgeSourceResponseZod
2107
+ BridgeIntentResponseZod2,
2108
+ BridgeSourceResponseZod2
1573
2109
  ]),
1574
2110
  z5.tuple([
1575
- BridgeIntentResponseZod,
1576
- BridgeSourceResponseZod,
1577
- BridgeDestinationResponseZod
2111
+ BridgeIntentResponseZod2,
2112
+ BridgeSourceResponseZod2,
2113
+ BridgeDestinationResponseZod2
1578
2114
  ])
1579
2115
  ]);
1580
2116
  var makeBridgeToRemoteStatusRoute = /* @__PURE__ */ __name((config) => {
@@ -1602,14 +2138,14 @@ var makeBridgeToRemoteStatusRoute = /* @__PURE__ */ __name((config) => {
1602
2138
  ];
1603
2139
  const bridgeIntent = allPayloads.find(isBridgeIntent5);
1604
2140
  if (!bridgeIntent) return res.sendStatus(404);
1605
- result[0] = asBridgeIntent(PayloadBuilder15.omitMeta(bridgeIntent));
2141
+ result[0] = asBridgeIntent(PayloadBuilder17.omitMeta(bridgeIntent));
1606
2142
  const { xl1TransactionMonitorJob } = statusQueueJobs;
1607
2143
  const xl1MonitorState = xl1TransactionMonitorJob ? await xl1TransactionMonitorJob.getState() : void 0;
1608
2144
  if (xl1MonitorState === "completed") {
1609
2145
  const srcConfirmation = xl1TransactionMonitorJob?.returnvalue?.submissionHash;
1610
- if (isDefined13(srcConfirmation)) {
1611
- const schema = BridgeSourceObservationSchema2;
1612
- const bridgeSourceObservationFields = BridgeSourceObservationFieldsZod2.parse(bridgeIntent);
2146
+ if (isDefined16(srcConfirmation)) {
2147
+ const schema = BridgeSourceObservationSchema4;
2148
+ const bridgeSourceObservationFields = BridgeSourceObservationFieldsZod3.parse(bridgeIntent);
1613
2149
  const observation = {
1614
2150
  schema,
1615
2151
  ...bridgeSourceObservationFields,
@@ -1621,8 +2157,8 @@ var makeBridgeToRemoteStatusRoute = /* @__PURE__ */ __name((config) => {
1621
2157
  const { ethTransactionMonitorJob } = statusQueueJobs;
1622
2158
  const ethMonitorState = ethTransactionMonitorJob ? await ethTransactionMonitorJob.getState() : void 0;
1623
2159
  if (ethMonitorState === "completed") {
1624
- const destConfirmation = asHex3(ethTransactionMonitorJob?.returnvalue?.submissionHash);
1625
- if (isDefined13(destConfirmation)) {
2160
+ const destConfirmation = asHex4(ethTransactionMonitorJob?.returnvalue?.submissionHash);
2161
+ if (isDefined16(destConfirmation)) {
1626
2162
  const schema = BridgeDestinationObservationSchema2;
1627
2163
  const bridgeDestinationObservationFields = BridgeDestinationObservationFieldsZod2.parse(bridgeIntent);
1628
2164
  const observation = {
@@ -1676,7 +2212,7 @@ var getApp = /* @__PURE__ */ __name((config, gateway) => {
1676
2212
  }, "getApp");
1677
2213
 
1678
2214
  // src/services/getServices.ts
1679
- import { assertEx as assertEx21 } from "@xylabs/sdk-js";
2215
+ import { assertEx as assertEx24 } from "@xylabs/sdk-js";
1680
2216
  import { initEvmProvider, resolveWalletForActor as resolveWalletForActor2 } from "@xyo-network/chain-orchestration";
1681
2217
  import { BridgeableToken__factory, LiquidityPoolBridge__factory } from "@xyo-network/typechain";
1682
2218
  import { getAddress as getAddress2, Wallet } from "ethers";
@@ -1718,6 +2254,8 @@ var getServices = /* @__PURE__ */ __name(async (context, gateway) => {
1718
2254
  const { config } = context;
1719
2255
  const ethTxStateMap = await getIterableMap(config, "liquidity_bridge_xl1_to_eth_eth_tx_state");
1720
2256
  const xl1TxStateMap = await getIterableMap(config, "liquidity_bridge_xl1_to_eth_xl1_tx_state");
2257
+ const evmBridgeCursorMap = await getIterableMap(config, "liquidity_bridge_eth_to_xl1_scanner_cursor");
2258
+ const bridgeFulfillmentMap = await getIterableMap(config, "liquidity_bridge_eth_to_xl1_fulfillment");
1721
2259
  const provider = await initEvmProvider(context);
1722
2260
  const { remoteBridgeContractAddress, remoteChainWalletPrivateKey, remoteTokenAddress, accountPath } = config;
1723
2261
  const account = await resolveWalletForActor2(config.name, accountPath);
@@ -1725,14 +2263,18 @@ var getServices = /* @__PURE__ */ __name(async (context, gateway) => {
1725
2263
  const bridgeableToken = BridgeableToken__factory.connect(getAddress2(remoteTokenAddress), wallet);
1726
2264
  const bridge = LiquidityPoolBridge__factory.connect(getAddress2(remoteBridgeContractAddress), wallet);
1727
2265
  const bridgeOwner = await bridge.owner();
1728
- assertEx21(bridgeOwner.toLowerCase() === wallet.address.toLowerCase(), () => "Wallet is not the owner of the bridge contract");
2266
+ assertEx24(bridgeOwner.toLowerCase() === wallet.address.toLowerCase(), () => "Wallet is not the owner of the bridge contract");
2267
+ const remoteConfirmationDepth = getRemoteConfirmationDepth(config);
1729
2268
  return {
1730
2269
  account,
1731
2270
  bridge,
1732
2271
  bridgeableToken,
2272
+ bridgeFulfillmentMap,
1733
2273
  ethTxStateMap,
2274
+ evmBridgeCursorMap,
1734
2275
  gateway,
1735
2276
  provider,
2277
+ remoteConfirmationDepth,
1736
2278
  wallet,
1737
2279
  xl1TxStateMap
1738
2280
  };
@@ -1754,7 +2296,13 @@ var getServer = /* @__PURE__ */ __name(async (context, gateway) => {
1754
2296
  const services = await getServices(context, gateway);
1755
2297
  app.services = services;
1756
2298
  addWorkers(config, services);
1757
- const server = app.listen(port, hostname, () => logger?.log(`[Bridge] Server listening at http://${hostname}:${port}`));
2299
+ const server = await new Promise((resolve, reject) => {
2300
+ const srv = app.listen(port, hostname, () => {
2301
+ logger?.log(`[Bridge] Server listening at http://${hostname}:${port}`);
2302
+ resolve(srv);
2303
+ });
2304
+ srv.once("error", reject);
2305
+ });
1758
2306
  server.setTimeout(2e4);
1759
2307
  return {
1760
2308
  server,
@@ -1762,6 +2310,139 @@ var getServer = /* @__PURE__ */ __name(async (context, gateway) => {
1762
2310
  };
1763
2311
  }, "getServer");
1764
2312
 
2313
+ // src/telemetry/createBalanceMonitor.ts
2314
+ var DEFAULT_INTERVAL_MS = 6e4;
2315
+ var WEI_PER_GWEI = 10n ** 9n;
2316
+ var TOKEN_DECIMALS = 10n ** 18n;
2317
+ function createBalanceMonitor(config) {
2318
+ const { account, bridge, bridgeableToken, gateway, meter, provider, wallet, intervalMs = DEFAULT_INTERVAL_MS } = config;
2319
+ let timer;
2320
+ const ethWalletGasBalance = meter.createGauge("bridge_eth_wallet_gas_balance_gwei", {
2321
+ description: "ETH balance of the bridge runner wallet (in gwei)",
2322
+ unit: "gwei"
2323
+ });
2324
+ const liquidityTokenBalance = meter.createGauge("bridge_eth_liquidity_token_balance", {
2325
+ description: "ERC-20 token balance of the liquidity source (in whole tokens)",
2326
+ unit: "tokens"
2327
+ });
2328
+ const liquidityTokenAllowance = meter.createGauge("bridge_eth_liquidity_token_allowance", {
2329
+ description: "ERC-20 token allowance from liquidity source to bridge contract (in whole tokens)",
2330
+ unit: "tokens"
2331
+ });
2332
+ const xl1AccountBalance = meter.createGauge("bridge_xl1_account_balance", {
2333
+ description: "XL1 native balance of the bridge reserve account (in whole XL1)",
2334
+ unit: "xl1"
2335
+ });
2336
+ const walletAddress = wallet.address;
2337
+ async function poll() {
2338
+ try {
2339
+ const balance = await provider.getBalance(walletAddress);
2340
+ ethWalletGasBalance.record(Number(balance / WEI_PER_GWEI), {
2341
+ address: walletAddress
2342
+ });
2343
+ } catch (err) {
2344
+ console.error("[BalanceMonitor] Failed to read ETH wallet gas balance:", err);
2345
+ }
2346
+ try {
2347
+ const liquiditySourceAddress = await bridge.liquiditySource();
2348
+ const balance = await bridgeableToken.balanceOf(liquiditySourceAddress);
2349
+ liquidityTokenBalance.record(Number(balance / TOKEN_DECIMALS), {
2350
+ address: liquiditySourceAddress
2351
+ });
2352
+ } catch (err) {
2353
+ console.error("[BalanceMonitor] Failed to read liquidity source token balance:", err);
2354
+ }
2355
+ try {
2356
+ const liquiditySourceAddress = await bridge.liquiditySource();
2357
+ const bridgeAddress = await bridge.getAddress();
2358
+ const allowance = await bridgeableToken.allowance(liquiditySourceAddress, bridgeAddress);
2359
+ liquidityTokenAllowance.record(Number(allowance / TOKEN_DECIMALS), {
2360
+ address: liquiditySourceAddress
2361
+ });
2362
+ } catch (err) {
2363
+ console.error("[BalanceMonitor] Failed to read liquidity source token allowance:", err);
2364
+ }
2365
+ try {
2366
+ const viewer = gateway.connection.viewer;
2367
+ if (viewer) {
2368
+ const balance = await viewer.account.balance.accountBalance(account.address);
2369
+ xl1AccountBalance.record(Number(balance / TOKEN_DECIMALS), {
2370
+ address: account.address.toString()
2371
+ });
2372
+ }
2373
+ } catch (err) {
2374
+ console.error("[BalanceMonitor] Failed to read XL1 account balance:", err);
2375
+ }
2376
+ }
2377
+ __name(poll, "poll");
2378
+ return {
2379
+ start() {
2380
+ void poll();
2381
+ timer = setInterval(() => void poll(), intervalMs);
2382
+ },
2383
+ stop() {
2384
+ if (timer) {
2385
+ clearInterval(timer);
2386
+ timer = void 0;
2387
+ }
2388
+ }
2389
+ };
2390
+ }
2391
+ __name(createBalanceMonitor, "createBalanceMonitor");
2392
+
2393
+ // src/telemetry/createQueueMetrics.ts
2394
+ var DEFAULT_INTERVAL_MS2 = 3e4;
2395
+ function createQueueMetrics(config) {
2396
+ const { meter, queues, intervalMs = DEFAULT_INTERVAL_MS2 } = config;
2397
+ let timer;
2398
+ const waitingGauge = meter.createGauge("bridge_queue_waiting", {
2399
+ description: "Number of waiting jobs in the bridge queue"
2400
+ });
2401
+ const activeGauge = meter.createGauge("bridge_queue_active", {
2402
+ description: "Number of active jobs in the bridge queue"
2403
+ });
2404
+ const completedGauge = meter.createGauge("bridge_queue_completed", {
2405
+ description: "Number of completed jobs in the bridge queue"
2406
+ });
2407
+ const failedGauge = meter.createGauge("bridge_queue_failed", {
2408
+ description: "Number of failed jobs in the bridge queue"
2409
+ });
2410
+ const delayedGauge = meter.createGauge("bridge_queue_delayed", {
2411
+ description: "Number of delayed jobs in the bridge queue"
2412
+ });
2413
+ async function poll() {
2414
+ for (const [name13, queue] of Object.entries(queues)) {
2415
+ try {
2416
+ const counts = await queue.getJobCounts("waiting", "active", "completed", "failed", "delayed");
2417
+ const attrs = {
2418
+ queue_name: name13
2419
+ };
2420
+ waitingGauge.record(counts.waiting ?? 0, attrs);
2421
+ activeGauge.record(counts.active ?? 0, attrs);
2422
+ completedGauge.record(counts.completed ?? 0, attrs);
2423
+ failedGauge.record(counts.failed ?? 0, attrs);
2424
+ delayedGauge.record(counts.delayed ?? 0, attrs);
2425
+ } catch (err) {
2426
+ console.error(`[QueueMetrics] Failed to read job counts for queue ${name13}:`, err);
2427
+ }
2428
+ }
2429
+ }
2430
+ __name(poll, "poll");
2431
+ return {
2432
+ start() {
2433
+ void poll();
2434
+ timer = setInterval(() => void poll(), intervalMs);
2435
+ },
2436
+ stop() {
2437
+ if (timer) {
2438
+ clearInterval(timer);
2439
+ timer = void 0;
2440
+ }
2441
+ }
2442
+ };
2443
+ }
2444
+ __name(createQueueMetrics, "createQueueMetrics");
2445
+
1765
2446
  // src/BridgeActor.ts
1766
2447
  function _ts_decorate(decorators, target, key, desc) {
1767
2448
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
@@ -1774,9 +2455,16 @@ var BridgeActor = class extends ActorV3 {
1774
2455
  static {
1775
2456
  __name(this, "BridgeActor");
1776
2457
  }
2458
+ static needs = {
2459
+ required: [
2460
+ XyoGatewayRunnerMoniker,
2461
+ XyoViewerMoniker
2462
+ ]
2463
+ };
1777
2464
  _gatewayRunner;
1778
2465
  _balanceMonitor;
1779
2466
  _queueMetrics;
2467
+ _scannerRunner;
1780
2468
  server;
1781
2469
  get gatewayRunner() {
1782
2470
  return this._gatewayRunner;
@@ -1792,6 +2480,8 @@ var BridgeActor = class extends ActorV3 {
1792
2480
  }
1793
2481
  async stopHandler() {
1794
2482
  await super.stopHandler();
2483
+ await this._scannerRunner?.stop();
2484
+ this._scannerRunner = void 0;
1795
2485
  this._balanceMonitor?.stop();
1796
2486
  this._queueMetrics?.stop();
1797
2487
  this._balanceMonitor = void 0;
@@ -1800,8 +2490,21 @@ var BridgeActor = class extends ActorV3 {
1800
2490
  }
1801
2491
  async startServer() {
1802
2492
  const context = asBridgeConfigContext(this.context, true);
2493
+ const config = context.config;
1803
2494
  const { server, services } = await getServer(context, this._gatewayRunner);
1804
2495
  this.server = server;
2496
+ const connection2 = getConnection(config);
2497
+ const telemetry2 = getTelemetry();
2498
+ const flowProducer2 = getFlowProducer(connection2, telemetry2);
2499
+ this._scannerRunner = buildEvmBridgeScannerRunner({
2500
+ config,
2501
+ connection: connection2,
2502
+ flowProducer: flowProducer2,
2503
+ logger: this.logger,
2504
+ services,
2505
+ telemetry: telemetry2
2506
+ });
2507
+ await this._scannerRunner.start();
1805
2508
  if (this.meter) {
1806
2509
  this._balanceMonitor = createBalanceMonitor({
1807
2510
  account: services.account,
@@ -1813,7 +2516,10 @@ var BridgeActor = class extends ActorV3 {
1813
2516
  wallet: services.wallet
1814
2517
  });
1815
2518
  this._balanceMonitor.start();
1816
- const queues = getXl1ToEthQueues(context.config);
2519
+ const queues = {
2520
+ ...getXl1ToEthQueues(config),
2521
+ ...getEthToXl1Queues(config)
2522
+ };
1817
2523
  this._queueMetrics = createQueueMetrics({
1818
2524
  meter: this.meter,
1819
2525
  queues
@@ -1829,9 +2535,59 @@ var BridgeActor = class extends ActorV3 {
1829
2535
  BridgeActor = _ts_decorate([
1830
2536
  creatable()
1831
2537
  ], BridgeActor);
2538
+
2539
+ // src/command.ts
2540
+ import { BridgeConfigZod } from "@xyo-network/chain-orchestration";
2541
+
2542
+ // src/run.ts
2543
+ import { exists } from "@xylabs/sdk-js";
2544
+ import { initActorWallet } from "@xyo-network/chain-orchestration";
2545
+ var getBridgeActor = /* @__PURE__ */ __name(async (config, locator) => {
2546
+ const account = await initActorWallet({
2547
+ config,
2548
+ logger: locator.context.logger,
2549
+ singletons: {},
2550
+ caches: {}
2551
+ });
2552
+ return await BridgeActor.create({
2553
+ account,
2554
+ config,
2555
+ locator
2556
+ });
2557
+ }, "getBridgeActor");
2558
+ var runBridge = /* @__PURE__ */ __name(async (config, orchestrator, locator) => {
2559
+ const bridge = await getBridgeActor(config, locator);
2560
+ const actors = [
2561
+ bridge
2562
+ ].filter(exists);
2563
+ for (const actor of actors) {
2564
+ await orchestrator.registerActor(actor);
2565
+ }
2566
+ await orchestrator.start();
2567
+ }, "runBridge");
2568
+
2569
+ // src/command.ts
2570
+ function bridgeCommand(getConfiguration, getLocatorsFromConfig) {
2571
+ return {
2572
+ command: "bridge",
2573
+ deprecated: 'Use "start bridge" instead',
2574
+ describe: "Run a XL1 Bridge Node",
2575
+ handler: /* @__PURE__ */ __name(async () => {
2576
+ const configuration = getConfiguration();
2577
+ const { locators, orchestrator } = await getLocatorsFromConfig([
2578
+ "bridge"
2579
+ ], configuration);
2580
+ await runBridge(BridgeConfigZod.parse(locators["bridge"].context.config), orchestrator, locators["bridge"]);
2581
+ }, "handler")
2582
+ };
2583
+ }
2584
+ __name(bridgeCommand, "bridgeCommand");
1832
2585
  export {
1833
2586
  BridgeActor,
2587
+ bridgeCommand,
1834
2588
  createBalanceMonitor,
1835
- createQueueMetrics
2589
+ createQueueMetrics,
2590
+ getBridgeActor,
2591
+ runBridge
1836
2592
  };
1837
2593
  //# sourceMappingURL=index.mjs.map