@xyo-network/chain-bridge 1.20.15 → 1.20.16

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 (147) hide show
  1. package/README.md +9 -75
  2. package/dist/node/index.mjs +44 -0
  3. package/dist/node/index.mjs.map +1 -1
  4. package/dist/node/queue/flows/createXl1ToEthBridgeJob/getJobIdForXl1ToEthBridgeJob.d.ts +1 -1
  5. package/dist/node/queue/flows/createXl1ToEthBridgeJob/getJobIdForXl1ToEthBridgeJob.d.ts.map +1 -1
  6. package/dist/node/server/routes/addProbeRoutes.d.ts +3 -0
  7. package/dist/node/server/routes/addProbeRoutes.d.ts.map +1 -0
  8. package/dist/node/server/routes/addRoutes.d.ts.map +1 -1
  9. package/dist/node/server/routes/bridge/routeDefinitions/routes/bridgeConfig.d.ts +7 -7
  10. package/dist/node/server/routes/{healthz → livez}/get.d.ts +1 -1
  11. package/dist/node/server/routes/livez/get.d.ts.map +1 -0
  12. package/dist/node/server/routes/livez/index.d.ts.map +1 -0
  13. package/dist/node/server/routes/readyz/get.d.ts +4 -0
  14. package/dist/node/server/routes/readyz/get.d.ts.map +1 -0
  15. package/dist/node/server/routes/readyz/index.d.ts +2 -0
  16. package/dist/node/server/routes/readyz/index.d.ts.map +1 -0
  17. package/dist/node/server/routes/startupz/get.d.ts +4 -0
  18. package/dist/node/server/routes/startupz/get.d.ts.map +1 -0
  19. package/dist/node/server/routes/startupz/index.d.ts +2 -0
  20. package/dist/node/server/routes/startupz/index.d.ts.map +1 -0
  21. package/package.json +141 -52
  22. package/dist/node/server/routes/healthz/get.d.ts.map +0 -1
  23. package/dist/node/server/routes/healthz/index.d.ts.map +0 -1
  24. package/src/BridgeActor.ts +0 -51
  25. package/src/config/asChainId.ts +0 -7
  26. package/src/config/asToken.ts +0 -7
  27. package/src/config/getBridgeEscrowAddress.ts +0 -13
  28. package/src/config/getBridgeFeesAddress.ts +0 -13
  29. package/src/config/getBridgeSettings.ts +0 -24
  30. package/src/config/getBridgeWalletAccount.ts +0 -37
  31. package/src/config/getFeeStructure.ts +0 -8
  32. package/src/config/getMaxBridgeAmount.ts +0 -7
  33. package/src/config/getMinBridgeAmount.ts +0 -7
  34. package/src/config/getRemoteChainId.ts +0 -10
  35. package/src/config/getRemoteTokenAddress.ts +0 -10
  36. package/src/config/getTestGateway.ts +0 -24
  37. package/src/config/getTransferAddresses.ts +0 -17
  38. package/src/config/getXl1ChainId.ts +0 -13
  39. package/src/config/getXl1TokenAddress.ts +0 -12
  40. package/src/config/index.ts +0 -15
  41. package/src/index.ts +0 -1
  42. package/src/interface/index.ts +0 -4
  43. package/src/interface/interface/ChainBridgeRelayInterface.ts +0 -9
  44. package/src/interface/interface/IntentIndexerInterface.ts +0 -8
  45. package/src/interface/interface/LockingProcessorInterface.ts +0 -10
  46. package/src/interface/interface/ObservationIndexerInterface.ts +0 -12
  47. package/src/interface/interface/Params.ts +0 -26
  48. package/src/interface/interface/RelayInterface.ts +0 -8
  49. package/src/interface/interface/index.ts +0 -6
  50. package/src/interface/repository/RepositoryInterface.ts +0 -28
  51. package/src/interface/repository/index.ts +0 -1
  52. package/src/interface/service/Observer/ERC20TransferObserver/ERC20TransferObserver.ts +0 -180
  53. package/src/interface/service/Observer/ERC20TransferObserver/index.ts +0 -1
  54. package/src/interface/service/Observer/LiquidityPoolBridgeObserver/LiquidityPoolBridgeObserver.ts +0 -210
  55. package/src/interface/service/Observer/LiquidityPoolBridgeObserver/index.ts +0 -1
  56. package/src/interface/service/Observer/Observer.ts +0 -48
  57. package/src/interface/service/Observer/index.ts +0 -1
  58. package/src/interface/service/Relay/ChainBridgeRelay/ChainBridgeRelayInterface.ts +0 -11
  59. package/src/interface/service/Relay/ChainBridgeRelay/ChainBridgeRelayService.ts +0 -116
  60. package/src/interface/service/Relay/ChainBridgeRelay/index.ts +0 -1
  61. package/src/interface/service/Relay/LiquidityPoolBridgeRelay/LiquidityPoolBridgeRelay.ts +0 -227
  62. package/src/interface/service/Relay/LiquidityPoolBridgeRelay/index.ts +0 -1
  63. package/src/interface/service/Relay/index.ts +0 -1
  64. package/src/interface/service/index.ts +0 -2
  65. package/src/interface/util/getBridgeIntentIdentifier.ts +0 -18
  66. package/src/interface/util/index.ts +0 -1
  67. package/src/modules/EVMLiquidityBridgeTransactionCompletionMonitorSentinel/EVMLiquidityBridgeTransactionCompletionMonitorSentinel.ts +0 -235
  68. package/src/modules/EVMLiquidityBridgeTransactionCompletionMonitorSentinel/index.ts +0 -1
  69. package/src/modules/index.ts +0 -1
  70. package/src/queue/connection.ts +0 -16
  71. package/src/queue/flowProducer.ts +0 -16
  72. package/src/queue/flows/createEthToXl1BridgeJob.ts +0 -71
  73. package/src/queue/flows/createXl1ToEthBridgeJob/createXl1ToEthBridgeJob.ts +0 -127
  74. package/src/queue/flows/createXl1ToEthBridgeJob/getJobIdForXl1ToEthBridgeJob.ts +0 -18
  75. package/src/queue/flows/createXl1ToEthBridgeJob/getXl1ToEthBridgeJob.ts +0 -11
  76. package/src/queue/flows/createXl1ToEthBridgeJob/index.ts +0 -3
  77. package/src/queue/flows/index.ts +0 -2
  78. package/src/queue/getXl1ToEthQueueJobs.ts +0 -57
  79. package/src/queue/getXl1ToEthQueues.ts +0 -39
  80. package/src/queue/index.ts +0 -8
  81. package/src/queue/prefix.ts +0 -1
  82. package/src/queue/telemetry.ts +0 -12
  83. package/src/queue/workers/EthToXl1BridgeParent.ts +0 -40
  84. package/src/queue/workers/EthTransactionMonitor.ts +0 -59
  85. package/src/queue/workers/EthTransactionPreparation.ts +0 -83
  86. package/src/queue/workers/EthTransactionSubmission.ts +0 -63
  87. package/src/queue/workers/EthTransactionSubmissionStorage.ts +0 -76
  88. package/src/queue/workers/WorkerDescription.ts +0 -10
  89. package/src/queue/workers/Xl1ToEthBridgeParent.ts +0 -41
  90. package/src/queue/workers/Xl1TransactionJobData.ts +0 -12
  91. package/src/queue/workers/Xl1TransactionMonitor.ts +0 -82
  92. package/src/queue/workers/Xl1TransactionPreparation.ts +0 -52
  93. package/src/queue/workers/Xl1TransactionSubmission.ts +0 -70
  94. package/src/queue/workers/Xl1TransactionSubmissionStorage.ts +0 -77
  95. package/src/queue/workers/createWorkers.ts +0 -29
  96. package/src/queue/workers/index.ts +0 -11
  97. package/src/queue/workers/util/index.ts +0 -2
  98. package/src/queue/workers/util/submitEthTransaction.ts +0 -32
  99. package/src/queue/workers/util/submitXl1Transaction.ts +0 -26
  100. package/src/server/addFlowProducer.ts +0 -14
  101. package/src/server/addWorkers.ts +0 -13
  102. package/src/server/app.ts +0 -20
  103. package/src/server/index.ts +0 -19
  104. package/src/server/instrumentation.ts +0 -15
  105. package/src/server/routes/addRoutes.ts +0 -9
  106. package/src/server/routes/bridge/addBridgeRoutes.ts +0 -12
  107. package/src/server/routes/bridge/index.ts +0 -1
  108. package/src/server/routes/bridge/routeDefinitions/getRouteDefinitions.ts +0 -18
  109. package/src/server/routes/bridge/routeDefinitions/index.ts +0 -1
  110. package/src/server/routes/bridge/routeDefinitions/pathParams/ChainIdPathParam.ts +0 -21
  111. package/src/server/routes/bridge/routeDefinitions/pathParams/index.ts +0 -1
  112. package/src/server/routes/bridge/routeDefinitions/routes/bridgeConfig.ts +0 -46
  113. package/src/server/routes/bridge/routeDefinitions/routes/bridgeFromRemoteStatus.ts +0 -58
  114. package/src/server/routes/bridge/routeDefinitions/routes/bridgeToRemote.ts +0 -93
  115. package/src/server/routes/bridge/routeDefinitions/routes/bridgeToRemoteEstimate.ts +0 -69
  116. package/src/server/routes/bridge/routeDefinitions/routes/bridgeToRemoteMaxEstimate.ts +0 -64
  117. package/src/server/routes/bridge/routeDefinitions/routes/bridgeToRemoteStatus.ts +0 -98
  118. package/src/server/routes/bridge/routeDefinitions/routes/index.ts +0 -6
  119. package/src/server/routes/healthz/get.ts +0 -20
  120. package/src/server/routes/healthz/index.ts +0 -1
  121. package/src/server/routes/index.ts +0 -1
  122. package/src/server/server.ts +0 -21
  123. package/src/services/EthTxState.ts +0 -5
  124. package/src/services/IBridgeServiceCollection.ts +0 -19
  125. package/src/services/TxState.ts +0 -14
  126. package/src/services/Xl1TxState.ts +0 -9
  127. package/src/services/getIterableMap.ts +0 -34
  128. package/src/services/getServices.ts +0 -41
  129. package/src/services/index.ts +0 -5
  130. package/src/util/BridgeFees.ts +0 -16
  131. package/src/util/bridgeFeesAsBigInt.ts +0 -15
  132. package/src/util/calculateBridgeFees.ts +0 -33
  133. package/src/util/calculateMaxBridgeAmount.ts +0 -22
  134. package/src/util/createBridgeTransfer.ts +0 -31
  135. package/src/util/generateBridgeEstimate.ts +0 -55
  136. package/src/util/getConfigFromEnv.ts +0 -15
  137. package/src/util/index.ts +0 -7
  138. package/src/validation/AsyncLogger.ts +0 -5
  139. package/src/validation/index.ts +0 -6
  140. package/src/validation/validateBridgeEstimate.ts +0 -60
  141. package/src/validation/validateBridgeEstimateExact.ts +0 -39
  142. package/src/validation/validateBridgeTransaction.ts +0 -53
  143. package/src/validation/validateSufficientLiquiditySourceAllowance.ts +0 -39
  144. package/src/validation/validateSufficientLiquiditySourceBalance.ts +0 -38
  145. package/src/validation/validateSufficientRunnerEthBalanceForGas.ts +0 -57
  146. package/src/validation/validateSufficientXL1SourceAddressBalance.ts +0 -39
  147. /package/dist/node/server/routes/{healthz → livez}/index.d.ts +0 -0
@@ -1,12 +0,0 @@
1
- import type { Hex } from '@xylabs/sdk-js'
2
- import { isDefined } from '@xylabs/sdk-js'
3
- import type { BridgeConfig } from '@xyo-network/chain-orchestration'
4
-
5
- import { asToken } from './asToken.ts'
6
- import { getXl1ChainId } from './getXl1ChainId.ts'
7
-
8
- export const getXl1TokenAddress = (config: BridgeConfig): Hex => {
9
- const token = asToken(config.xl1TokenAddress)
10
- if (isDefined(token)) return token
11
- return getXl1ChainId(config)
12
- }
@@ -1,15 +0,0 @@
1
- export * from './asChainId.ts'
2
- export * from './asToken.ts'
3
- export * from './getBridgeEscrowAddress.ts'
4
- export * from './getBridgeFeesAddress.ts'
5
- export * from './getBridgeSettings.ts'
6
- export * from './getBridgeWalletAccount.ts'
7
- export * from './getFeeStructure.ts'
8
- export * from './getMaxBridgeAmount.ts'
9
- export * from './getMinBridgeAmount.ts'
10
- export * from './getRemoteChainId.ts'
11
- export * from './getRemoteTokenAddress.ts'
12
- export * from './getTestGateway.ts'
13
- export * from './getTransferAddresses.ts'
14
- export * from './getXl1ChainId.ts'
15
- export * from './getXl1TokenAddress.ts'
package/src/index.ts DELETED
@@ -1 +0,0 @@
1
- export * from './BridgeActor.ts'
@@ -1,4 +0,0 @@
1
- export * from './interface/index.ts'
2
- export * from './repository/index.ts'
3
- export * from './service/index.ts'
4
- export * from './util/index.ts'
@@ -1,9 +0,0 @@
1
- import type { BridgeDestinationObservation, BridgeIntent } from '@xyo-network/xl1-sdk'
2
-
3
- import type { AsynchronousRelayInterface, SynchronousRelayInterface } from './RelayInterface.ts'
4
-
5
- export interface AsynchronousChainBridgeRelayInterface extends AsynchronousRelayInterface<BridgeIntent, BridgeDestinationObservation> {}
6
-
7
- export interface SynchronousChainBridgeRelayInterface extends SynchronousRelayInterface<BridgeIntent, BridgeDestinationObservation> {}
8
-
9
- export interface ChainBridgeRelayInterface extends AsynchronousChainBridgeRelayInterface, SynchronousChainBridgeRelayInterface {}
@@ -1,8 +0,0 @@
1
- import type { Address, Hex } from '@xylabs/sdk-js'
2
-
3
- export interface IntentIndexerInterface<T> {
4
- addIntent(intent: T): Promise<boolean>
5
- getIntentByNonce(nonce: Hex): Promise<T | undefined>
6
- getIntentsForDestination(dest: Address): Promise<T[]>
7
- getIntentsForSource(src: Address): Promise<T[]>
8
- }
@@ -1,10 +0,0 @@
1
- import type { Address } from '@xylabs/sdk-js'
2
-
3
- export interface LockingProcessorInterface<T> {
4
- isLocked(intent: T): Promise<Address | null>
5
- lock(processor: Address, intent: T): Promise<boolean>
6
- }
7
-
8
- export interface UnlockingProcessorInterface<T> extends LockingProcessorInterface<T> {
9
- unlock(processor: Address, intent: T): Promise<boolean>
10
- }
@@ -1,12 +0,0 @@
1
- import type {
2
- BridgeDestinationObservation, BridgeIntent, BridgeSourceObservation,
3
- } from '@xyo-network/xl1-sdk'
4
-
5
- export interface ObservationIndexerInterface<
6
- TObservation extends BridgeSourceObservation | BridgeDestinationObservation,
7
- TIntent extends BridgeIntent = BridgeIntent,
8
- > {
9
- addObservation(observation: TObservation, intent: TIntent): Promise<boolean>
10
- getIntentForObservation(observation: TObservation): Promise<TIntent | null>
11
- getObservationForIntent(intent: TIntent): Promise<TObservation | null>
12
- }
@@ -1,26 +0,0 @@
1
- import { type BaseAccountableServiceParams } from '@xyo-network/chain-services'
2
- import type {
3
- BridgeDestinationObservation, BridgeIntent, BridgeSourceObservation,
4
- } from '@xyo-network/xl1-sdk'
5
-
6
- import type { ChainBridgeRelayInterface } from './ChainBridgeRelayInterface.ts'
7
- import type { IntentIndexerInterface } from './IntentIndexerInterface.ts'
8
- import type { LockingProcessorInterface, UnlockingProcessorInterface } from './LockingProcessorInterface.ts'
9
- import type { ObservationIndexerInterface } from './ObservationIndexerInterface.ts'
10
-
11
- export interface BridgeIntentIndexerInterface extends IntentIndexerInterface<BridgeIntent> {}
12
- export interface BridgeSourceObservationIndexerInterface extends ObservationIndexerInterface<BridgeSourceObservation> {}
13
- export interface BridgeDestinationObservationIndexerInterface extends ObservationIndexerInterface<BridgeDestinationObservation> {}
14
- export interface LockingBridgeIntentProcessorInterface extends LockingProcessorInterface<BridgeIntent> {}
15
- export interface UnlockingBridgeIntentProcessorInterface extends UnlockingProcessorInterface<BridgeIntent> {}
16
-
17
- export type BridgeServiceCollection = {
18
- destinationObservations: BridgeDestinationObservationIndexerInterface
19
- destinationRelay: ChainBridgeRelayInterface
20
- intentProcessed: LockingBridgeIntentProcessorInterface
21
- intentProcessing: UnlockingBridgeIntentProcessorInterface
22
- intents: BridgeIntentIndexerInterface
23
- sourceObservations: BridgeSourceObservationIndexerInterface
24
- }
25
-
26
- export type BridgeServiceParams = BaseAccountableServiceParams & BridgeServiceCollection
@@ -1,8 +0,0 @@
1
- export interface SynchronousRelayInterface<T, U> {
2
- relaySync(message: T): Promise<U | null>
3
- }
4
-
5
- export interface AsynchronousRelayInterface<T, U> {
6
- beginRelay(message: T): Promise<boolean>
7
- onDestinationObservation(observation: U): Promise<boolean>
8
- }
@@ -1,6 +0,0 @@
1
- export * from './ChainBridgeRelayInterface.ts'
2
- export * from './IntentIndexerInterface.ts'
3
- export * from './LockingProcessorInterface.ts'
4
- export * from './ObservationIndexerInterface.ts'
5
- export * from './Params.ts'
6
- export * from './RelayInterface.ts'
@@ -1,28 +0,0 @@
1
- import type { Address } from '@xylabs/sdk-js'
2
- import type {
3
- BridgeDestinationObservation, BridgeIntent, BridgeSourceObservation,
4
- } from '@xyo-network/xl1-sdk'
5
-
6
- export interface IntentRepository {
7
- getBridgeIntents(src: Address, nonce?: string): Promise<BridgeIntent[]>
8
- }
9
-
10
- export interface SourceObservationRepository {
11
- getBridgeSourceObservation(intent: BridgeIntent): Promise<BridgeSourceObservation[]>
12
- }
13
-
14
- export interface DestinationObservationRepository {
15
- getBridgeDestinationObservation(intent: BridgeIntent): Promise<BridgeDestinationObservation[]>
16
- }
17
-
18
- export interface IntentProcessingRepository {
19
- isIntentProcessing(intent: BridgeIntent): Promise<boolean>
20
- markIntentProcessed(intent: BridgeIntent): Promise<void>
21
- markIntentProcessing(intent: BridgeIntent): Promise<void>
22
- unmarkIntentProcessing(intent: BridgeIntent): Promise<void>
23
- }
24
-
25
- export interface IntentProcessedRepository {
26
- isIntentProcessed(intent: BridgeIntent): Promise<boolean>
27
- markIntentProcessed(intent: BridgeIntent): Promise<void>
28
- }
@@ -1 +0,0 @@
1
- export * from './RepositoryInterface.ts'
@@ -1,180 +0,0 @@
1
- import type { Address } from '@xylabs/sdk-js'
2
- import {
3
- asAddress, asHex, hexToBigInt, isBigInt, isNull, isUndefined,
4
- toAddress,
5
- } from '@xylabs/sdk-js'
6
- import type { BridgeDestinationObservation, BridgeSourceObservation } from '@xyo-network/xl1-sdk'
7
- import {
8
- BridgeDestinationObservationSchema, BridgeSourceObservationSchema, XYO_ZERO_ADDRESS,
9
- } from '@xyo-network/xl1-sdk'
10
- import type { EventLog, WebSocketProvider } from 'ethers'
11
- import { Contract } from 'ethers'
12
- import { getAddress } from 'ethers/address'
13
-
14
- import type { BridgeServiceParams } from '../../../interface/index.ts'
15
- import { AbstractBridgeObserverService } from '../Observer.ts'
16
-
17
- export type ERC20TransferObserverParams = BridgeServiceParams & {
18
- /**
19
- * An ethers.js WebSocketProvider connected to the Ethereum network to monitor for ERC-20 transfers.
20
- */
21
- provider: WebSocketProvider
22
- /**
23
- * The ERC-20 token contract address to monitor (e.g., XYO, USDC).
24
- */
25
- tokenAddress: string
26
- /**
27
- * The address to watch for incoming or outgoing ERC-20 token transfers.
28
- */
29
- watchAddress: string
30
- /**
31
- * Specify whether to watch for 'incoming' or 'outgoing' types of transfers.
32
- */
33
- watchDirection: 'incoming' | 'outgoing'
34
- }
35
-
36
- // Minimal ERC-20 ABI only with Transfer event
37
- const ERC20_ABI = [
38
- 'event Transfer(address indexed from, address indexed to, uint256 value)',
39
- ]
40
-
41
- export class ERC20TransferObserver extends AbstractBridgeObserverService<ERC20TransferObserverParams> {
42
- moniker = 'ERC20TransferObserver'
43
- protected get tokenAddress(): Address {
44
- return toAddress(this.params.tokenAddress)
45
- }
46
-
47
- override async createHandler() {
48
- const {
49
- provider, tokenAddress, watchAddress, watchDirection,
50
- } = this.params
51
- // The custodial wallet to watch for transfers
52
- const normalizedWatchAddress = getAddress(watchAddress)
53
-
54
- // Create a Contract for the ERC-20 token
55
- const token = new Contract(getAddress(tokenAddress), ERC20_ABI, provider)
56
-
57
- // Listen for transfers involving WATCH_ADDRESS
58
- const filterIncoming = token.filters.Transfer(null, normalizedWatchAddress)
59
- const filterOutgoing = token.filters.Transfer(normalizedWatchAddress, null)
60
-
61
- // Pick correct filter + direction
62
- const filter = watchDirection === 'incoming' ? filterIncoming : filterOutgoing
63
-
64
- // Replay old logs
65
- const currentBlock = await provider.getBlockNumber()
66
- const pastEvents = await token.queryFilter(filter, 0, currentBlock)
67
- for (const ev of pastEvents) {
68
- const {
69
- from, to, value,
70
- } = (ev as EventLog)?.args
71
- await (watchDirection === 'incoming' ? this.handleTransfer(from, value, 'incoming') : this.handleTransfer(to, value, 'outgoing'))
72
- }
73
-
74
- // Watch for new events
75
- if (watchDirection === 'incoming') {
76
- await token.on(filterIncoming, (ev: EventLog) => {
77
- // Sanitize event log
78
- const { from, value } = ev.args
79
- if (isUndefined(from) || isUndefined(value)) return
80
- const sender = asAddress(from)
81
- // Ignore mints
82
- if (isUndefined(sender) || sender === XYO_ZERO_ADDRESS) return
83
- // Ensure value is bigint and non-zero
84
- if (!isBigInt(value) || value === 0n) return
85
- // Handle transfer
86
- this.handleTransfer(sender, value, 'incoming').catch(console.error)
87
- })
88
- } else if (watchDirection === 'outgoing') {
89
- await token.on(filterOutgoing, (ev: EventLog) => {
90
- // Sanitize event log
91
- const { to, value } = ev.args
92
- if (isUndefined(to) || isUndefined(value)) return
93
- const receiver = asAddress(to)
94
- // Ignore burns
95
- if (isUndefined(receiver) || receiver === XYO_ZERO_ADDRESS) return
96
- // Ensure value is bigint and non-zero
97
- if (!isBigInt(value) || value === 0n) return
98
- this.handleTransfer(receiver, value, 'outgoing').catch(console.error)
99
- })
100
- } else {
101
- throw new Error(`Invalid watchDirection: ${watchDirection}`)
102
- }
103
- }
104
-
105
- private async handleTransfer(account: Address, value: bigint, direction: 'incoming' | 'outgoing'): Promise<void> {
106
- if (direction === 'incoming') {
107
- const sender = asAddress(account)
108
- if (isUndefined (sender) || sender === XYO_ZERO_ADDRESS) return
109
- const intents = await this.intents.getIntentsForSource(sender)
110
- if (intents.length === 0) return
111
- // Find the intent that matches the transfer amount (chain and token are implicit to provider and intents were already indexed by address)
112
- const intent = intents.findLast((i) => {
113
- try {
114
- // Source address matches intent
115
- const address = asAddress(i.srcAddress)
116
- if (isUndefined(address) || address !== sender) return false
117
- // Source token must match
118
- const token = asHex(i.srcToken)
119
- if (isUndefined(token) || token !== this.tokenAddress) return false
120
- // Source amount must match
121
- const hexAmount = asHex(i.srcAmount)
122
- if (isUndefined(hexAmount)) return false
123
- const amount = hexToBigInt(hexAmount)
124
- if (amount !== value) return false
125
- // Otherwise matches
126
- return true
127
- } catch {
128
- return false
129
- }
130
- })
131
- if (isUndefined(intent)) return
132
- // Found matching intent, check if observation already exists
133
- const observations = this.sourceObservations
134
- const existing = await observations.getObservationForIntent(intent)
135
- // Only add if observation not already existing
136
- if (isUndefined(existing) || isNull(existing)) {
137
- const { schema, ...rest } = intent
138
- const observation: BridgeSourceObservation = { schema: BridgeSourceObservationSchema, ...rest }
139
- await observations.addObservation(observation, intent)
140
- }
141
- } else if (direction === 'outgoing') {
142
- const receiver = asAddress(account)
143
- if (isUndefined (receiver) || receiver === XYO_ZERO_ADDRESS) return
144
- const intents = await this.intents.getIntentsForDestination(receiver)
145
- if (intents.length === 0) return
146
- // Find the intent that matches the transfer amount (chain and token are implicit to provider and intents were already indexed by address)
147
- const intent = intents.findLast((i) => {
148
- try {
149
- // Source address matches intent
150
- const address = asAddress(i.destAddress)
151
- if (isUndefined(address) || address !== receiver) return false
152
- // Source token must match
153
- const token = asHex(i.destToken)
154
- if (isUndefined(token) || token !== this.tokenAddress) return false
155
- // Source amount must match
156
- const hexAmount = asHex(i.destAmount)
157
- if (isUndefined(hexAmount)) return false
158
- const amount = hexToBigInt(hexAmount)
159
- if (amount !== value) return false
160
- // Otherwise matches
161
- return true
162
- } catch {
163
- return false
164
- }
165
- })
166
- if (isUndefined(intent)) return
167
- // Found matching intent, check if observation already exists
168
- const observations = this.destinationObservations
169
- const existing = await observations.getObservationForIntent(intent)
170
- // Only add if observation not already existing
171
- if (isUndefined(existing) || isNull(existing)) {
172
- const { schema, ...rest } = intent
173
- const observation: BridgeDestinationObservation = { schema: BridgeDestinationObservationSchema, ...rest }
174
- await observations.addObservation(observation, intent)
175
- }
176
- } else {
177
- throw new Error(`Invalid direction: ${direction}`)
178
- }
179
- }
180
- }
@@ -1 +0,0 @@
1
- export * from './ERC20TransferObserver.ts'
@@ -1,210 +0,0 @@
1
- import type { Address, Hex } from '@xylabs/sdk-js'
2
- import {
3
- asAddress, asHex, assertEx, hexFromBigInt, hexToBigInt, isNull, isUndefined, toAddress,
4
- } from '@xylabs/sdk-js'
5
- import { PayloadBuilder } from '@xyo-network/sdk-js'
6
- import type { ILiquidityPoolBridge } from '@xyo-network/typechain'
7
- import { ILiquidityPoolBridge__factory } from '@xyo-network/typechain'
8
- import type {
9
- BridgeDestinationObservation, BridgeIntent, BridgeSourceObservation,
10
- } from '@xyo-network/xl1-sdk'
11
- import {
12
- BridgeDestinationObservationSchema, BridgeIntentSchema, BridgeSourceObservationSchema,
13
- } from '@xyo-network/xl1-sdk'
14
- import type { ContractEventPayload, WebSocketProvider } from 'ethers'
15
- import { getAddress } from 'ethers'
16
-
17
- import type { BridgeServiceParams } from '../../../interface/index.ts'
18
- import { AbstractBridgeObserverService } from '../Observer.ts'
19
-
20
- export type LiquidityPoolBridgeObserverParams = BridgeServiceParams & {
21
- /**
22
- * The address to watch for incoming or outgoing ERC-20 token transfers.
23
- */
24
- bridgeAddress: Address
25
- /**
26
- * An ethers.js WebSocketProvider connected to the Ethereum network to monitor for ERC-20 transfers.
27
- */
28
- provider: WebSocketProvider
29
- /**
30
- * The block number to start monitoring from.
31
- */
32
- startBlock?: number
33
- }
34
-
35
- export class LiquidityPoolBridgeObserver extends AbstractBridgeObserverService<LiquidityPoolBridgeObserverParams> {
36
- moniker = 'LiquidityPoolBridgeObserver'
37
- protected _bridge: ILiquidityPoolBridge | undefined
38
- protected _bridgeChainId: Hex | undefined
39
- protected _bridgeRemoteChainId: Hex | undefined
40
- protected _bridgeTokenAddress: Address | undefined
41
-
42
- protected get bridge(): ILiquidityPoolBridge {
43
- return assertEx(this._bridge, () => new Error('Bridge contract not initialized'))
44
- }
45
-
46
- protected get bridgeChainId(): Hex {
47
- return assertEx(this._bridgeChainId, () => new Error('Bridge chain ID not initialized'))
48
- }
49
-
50
- protected get bridgeRemoteChainId(): Hex {
51
- return assertEx(this._bridgeRemoteChainId, () => new Error('Bridge remote chain ID not initialized'))
52
- }
53
-
54
- protected get bridgeTokenAddress(): Address {
55
- return assertEx(this._bridgeTokenAddress, () => new Error('Bridge token address not initialized'))
56
- }
57
-
58
- protected get provider(): WebSocketProvider {
59
- return assertEx(this.params.provider, () => new Error('Provider not initialized'))
60
- }
61
-
62
- protected get startBlock(): number {
63
- return isUndefined(this.params.startBlock) ? 0 : this.params.startBlock
64
- }
65
-
66
- override async createHandler() {
67
- const { provider, bridgeAddress } = this.params
68
-
69
- // Connect to the bridge contract
70
- this._bridge = ILiquidityPoolBridge__factory.connect(getAddress(bridgeAddress), provider)
71
-
72
- // Parse bridge network chain ID
73
- const network = await provider.getNetwork()
74
- this._bridgeChainId = assertEx(hexFromBigInt(network.chainId), () => new Error('Failed to parse bridgeChainId'))
75
-
76
- // Parse bridge token address
77
- const tokenAddress = await this.bridge.token()
78
- this._bridgeTokenAddress = toAddress(tokenAddress)
79
-
80
- // Parse bridge remote chain ID
81
- const bridgeRemoteChain = await this.bridge.remoteChain()
82
- this._bridgeRemoteChainId = asHex(bridgeRemoteChain)
83
-
84
- // Grab the current block number to avoid processing old events
85
- const currentBlock = await provider.getBlockNumber()
86
- const manualIndexThroughBlockNumber = Math.max(currentBlock, this.startBlock)
87
-
88
- // Watch for & process new events
89
- await this.bridge.on(this.bridge.getEvent('BridgedToRemote'), (id, from, to, amount, remoteChain, args) => {
90
- const contractEvent = args as unknown as ContractEventPayload
91
- if (contractEvent?.log?.blockNumber <= manualIndexThroughBlockNumber) return
92
- this.handleBridgeToRemote(id, from, to, amount, remoteChain).catch(console.error)
93
- })
94
- await this.bridge.on(this.bridge.getEvent('BridgedFromRemote'), (id, from, to, amount, remoteChain, args) => {
95
- const contractEvent = args as unknown as ContractEventPayload
96
- if (contractEvent?.log?.blockNumber <= manualIndexThroughBlockNumber) return
97
- this.handleBridgeFromRemote(id, from, to, amount, remoteChain).catch(console.error)
98
- })
99
-
100
- // Process old events
101
- await this.processOldEvents(this.startBlock, manualIndexThroughBlockNumber)
102
- }
103
-
104
- private async handleBridgeFromRemote(id: bigint, from: string, to: string, value: bigint, remoteChain: string): Promise<void> {
105
- const srcAddress = asAddress(from)
106
- const destAddress = asAddress(to)
107
- const remoteChainId = asHex(remoteChain)
108
- if (isUndefined (srcAddress) || isUndefined (destAddress) || isUndefined (remoteChainId)) return
109
-
110
- const intents = await this.intents.getIntentsForDestination(destAddress)
111
- if (intents.length === 0) return
112
- // Find the intent that matches the transfer amount (chain and token are implicit to provider and intents were already indexed by address)
113
- const intent = intents.findLast((i) => {
114
- try {
115
- // TODO: Add source to event signature to capture intent
116
- // Source address matches intent
117
- // const intentSrcAddress = asAddress(i.srcAddress)
118
- // if (isUndefined(intentSrcAddress) || intentSrcAddress !== srcAddress) return false
119
- // Destination address matches intent
120
- const intentDestAddress = asAddress(i.destAddress)
121
- if (isUndefined(intentDestAddress) || intentDestAddress !== destAddress) return false
122
-
123
- // Source token matches intent
124
- const intentSrcToken = i.srcToken
125
- if (isUndefined(intentSrcToken) || intentSrcToken !== this.bridgeRemoteChainId) return false
126
- // Destination token matches intent
127
- const intentDestToken = asHex(i.destToken)
128
- if (isUndefined(intentDestToken) || intentDestToken !== this.bridgeTokenAddress) return false
129
-
130
- // Destination amount must match
131
- const intentDestAmountHex = asHex(i.destAmount)
132
- if (isUndefined(intentDestAmountHex)) return false
133
- const intentDestAmountBigInt = hexToBigInt(intentDestAmountHex)
134
- if (intentDestAmountBigInt !== value) return false
135
-
136
- // Otherwise matches
137
- return true
138
- } catch {
139
- return false
140
- }
141
- })
142
-
143
- if (isUndefined(intent)) return
144
- // Found matching intent, check if observation already exists
145
- const observations = this.destinationObservations
146
- const existing = await observations.getObservationForIntent(intent)
147
- // Only add if observation not already existing
148
- if (isUndefined(existing) || isNull(existing)) {
149
- const { schema, ...rest } = intent
150
- const observation: BridgeDestinationObservation = { schema: BridgeDestinationObservationSchema, ...rest }
151
- await observations.addObservation(observation, intent)
152
- }
153
- }
154
-
155
- private async handleBridgeToRemote(id: bigint, from: string, to: string, value: bigint, remoteChain: string): Promise<void> {
156
- const srcAddress = asAddress(from)
157
- const destAddress = asAddress(to)
158
- const remoteChainId = asHex(remoteChain)
159
- if (isUndefined (srcAddress) || isUndefined (destAddress) || isUndefined (remoteChainId)) return
160
- if (remoteChainId != this.bridgeRemoteChainId) return
161
-
162
- // If we don't have an intent for this nonce already
163
- const nonce = hexFromBigInt(id)
164
- let intent = await this.intents.getIntentByNonce(nonce)
165
- if (isUndefined(intent)) {
166
- // Create observation for intent if none exists
167
- intent = new PayloadBuilder<BridgeIntent>({ schema: BridgeIntentSchema }).fields({
168
- nonce,
169
- dest: this.bridgeRemoteChainId,
170
- destAddress,
171
- destAmount: hexFromBigInt(value),
172
- destToken: this.bridgeRemoteChainId,
173
- src: this.bridgeChainId,
174
- srcAddress,
175
- srcAmount: hexFromBigInt(value),
176
- srcToken: this.bridgeTokenAddress,
177
- }).build()
178
- await this.intents.addIntent(intent)
179
- }
180
- // Ensure we have an intent to match against
181
- if (isUndefined(intent)) return
182
- // Found matching intent, check if observation already exists
183
- const observations = this.sourceObservations
184
- const existing = await observations.getObservationForIntent(intent)
185
- // Only add if observation not already existing
186
- if (isUndefined(existing) || isNull(existing)) {
187
- const { schema, ...rest } = intent
188
- const observation: BridgeSourceObservation = { schema: BridgeSourceObservationSchema, ...rest }
189
- await observations.addObservation(observation, intent)
190
- }
191
- }
192
-
193
- private async processOldEvents(startBlock: number, endBlock: number): Promise<void> {
194
- const bridgedToRemote = await this.bridge.queryFilter(this.bridge.filters.BridgedToRemote(), startBlock, endBlock)
195
- for (const log of bridgedToRemote) {
196
- const {
197
- id, srcAddress, destAddress, amount, destToken,
198
- } = log.args
199
- await this.handleBridgeToRemote(id, srcAddress, destAddress, amount, destToken)
200
- }
201
-
202
- const bridgedFromRemote = await this.bridge.queryFilter(this.bridge.filters.BridgedFromRemote(), startBlock, endBlock)
203
- for (const log of bridgedFromRemote) {
204
- const {
205
- id, srcAddress, destAddress, amount, srcToken,
206
- } = log.args
207
- await this.handleBridgeFromRemote(id, srcAddress, destAddress, amount, srcToken)
208
- }
209
- }
210
- }
@@ -1 +0,0 @@
1
- export * from './LiquidityPoolBridgeObserver.ts'
@@ -1,48 +0,0 @@
1
- import { assertEx } from '@xylabs/sdk-js'
2
- import { AbstractCreatableProvider } from '@xyo-network/xl1-sdk'
3
-
4
- import type {
5
- BridgeDestinationObservationIndexerInterface, BridgeIntentIndexerInterface, BridgeServiceParams,
6
- BridgeSourceObservationIndexerInterface,
7
- ChainBridgeRelayInterface,
8
- LockingBridgeIntentProcessorInterface, UnlockingBridgeIntentProcessorInterface,
9
- } from '../../interface/index.ts'
10
-
11
- export interface BridgeObserverInterface {
12
- // TODO:
13
- }
14
-
15
- export abstract class AbstractBridgeObserverService<TParams extends BridgeServiceParams = BridgeServiceParams>
16
- extends AbstractCreatableProvider<TParams> implements BridgeObserverInterface {
17
- protected get account() {
18
- return assertEx(this.params.account, () => 'account is required')
19
- }
20
-
21
- protected get destinationObservations(): BridgeDestinationObservationIndexerInterface {
22
- return assertEx(this.params.destinationObservations, () => 'destinationObservations is required')
23
- }
24
-
25
- protected get destinationRelay(): ChainBridgeRelayInterface {
26
- return assertEx(this.params.destinationRelay, () => 'destinationRelay is required')
27
- }
28
-
29
- protected get intentProcessed(): LockingBridgeIntentProcessorInterface {
30
- return assertEx(this.params.intentProcessed, () => 'intentProcessed is required')
31
- }
32
-
33
- protected get intentProcessing(): UnlockingBridgeIntentProcessorInterface {
34
- return assertEx(this.params.intentProcessing, () => 'intentProcessing is required')
35
- }
36
-
37
- protected get intents(): BridgeIntentIndexerInterface {
38
- return assertEx(this.params.intents, () => 'intents is required')
39
- }
40
-
41
- protected get sourceObservations(): BridgeSourceObservationIndexerInterface {
42
- return assertEx(this.params.sourceObservations, () => 'sourceObservations is required')
43
- }
44
-
45
- async process(): Promise<void> {
46
- await Promise.resolve()
47
- }
48
- }
@@ -1 +0,0 @@
1
- export * from './Observer.ts'
@@ -1,11 +0,0 @@
1
- import type { BridgeDestinationObservation, BridgeIntent } from '@xyo-network/xl1-sdk'
2
-
3
- import type { AsynchronousRelayInterface, SynchronousRelayInterface } from '../../../interface/index.ts'
4
-
5
- export interface BlockingChainBridgeRelay extends SynchronousRelayInterface<BridgeIntent, BridgeDestinationObservation> {}
6
-
7
- export interface ChainBridgeRelay extends AsynchronousRelayInterface<BridgeIntent, BridgeDestinationObservation> {}
8
-
9
- export interface ChainBridgeRelayInterface extends
10
- AsynchronousRelayInterface<BridgeIntent, BridgeDestinationObservation>,
11
- SynchronousRelayInterface<BridgeIntent, BridgeDestinationObservation> {}