@xyo-network/chain-bridge 1.19.5 → 1.19.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/node/config/getGateway.d.ts.map +1 -1
- package/dist/node/index.mjs +339 -337
- package/dist/node/index.mjs.map +1 -1
- package/dist/node/manifest/getIterableMap.d.ts +10 -0
- package/dist/node/manifest/getIterableMap.d.ts.map +1 -0
- package/dist/node/manifest/getModuleLocator.d.ts.map +1 -1
- package/dist/node/manifest/getNode.d.ts.map +1 -1
- package/dist/node/manifest/getServices.d.ts.map +1 -1
- package/dist/node/queue/flows/createXl1ToEthBridgeJob.d.ts +6 -0
- package/dist/node/queue/flows/createXl1ToEthBridgeJob.d.ts.map +1 -1
- package/dist/node/queue/workers/EthTransactionMonitor.d.ts +3 -0
- package/dist/node/queue/workers/EthTransactionMonitor.d.ts.map +1 -0
- package/dist/node/queue/workers/EthTransactionPreparation.d.ts +6 -0
- package/dist/node/queue/workers/EthTransactionPreparation.d.ts.map +1 -0
- package/dist/node/queue/workers/EthTransactionSubmission.d.ts +3 -0
- package/dist/node/queue/workers/EthTransactionSubmission.d.ts.map +1 -0
- package/dist/node/queue/workers/WorkerDescription.d.ts +2 -1
- package/dist/node/queue/workers/WorkerDescription.d.ts.map +1 -1
- package/dist/node/queue/workers/Xl1ToEthBridgeParent.d.ts +3 -0
- package/dist/node/queue/workers/Xl1ToEthBridgeParent.d.ts.map +1 -0
- package/dist/node/queue/workers/Xl1TransactionMonitor.d.ts +3 -0
- package/dist/node/queue/workers/Xl1TransactionMonitor.d.ts.map +1 -0
- package/dist/node/queue/workers/Xl1TransactionPreparation.d.ts +3 -0
- package/dist/node/queue/workers/Xl1TransactionPreparation.d.ts.map +1 -0
- package/dist/node/queue/workers/Xl1TransactionSubmission.d.ts +3 -0
- package/dist/node/queue/workers/Xl1TransactionSubmission.d.ts.map +1 -0
- package/dist/node/queue/workers/createWorkers.d.ts +2 -1
- package/dist/node/queue/workers/createWorkers.d.ts.map +1 -1
- package/dist/node/queue/workers/index.d.ts +7 -7
- package/dist/node/queue/workers/util/index.d.ts +3 -0
- package/dist/node/queue/workers/util/index.d.ts.map +1 -0
- package/dist/node/queue/workers/util/submitEthTransaction.d.ts +5 -0
- package/dist/node/queue/workers/util/submitEthTransaction.d.ts.map +1 -0
- package/dist/node/queue/workers/util/submitXl1Transaction.d.ts +43 -0
- package/dist/node/queue/workers/util/submitXl1Transaction.d.ts.map +1 -0
- package/dist/node/server/{flowProducer.d.ts → addFlowProducer.d.ts} +1 -1
- package/dist/node/server/addFlowProducer.d.ts.map +1 -0
- package/dist/node/server/addWorkers.d.ts +4 -0
- package/dist/node/server/addWorkers.d.ts.map +1 -0
- package/dist/node/server/index.d.ts +0 -2
- package/dist/node/server/index.d.ts.map +1 -1
- package/dist/node/server/routes/bridge/routeDefinitions/routes/bridgeConfig.d.ts +22 -0
- package/dist/node/server/routes/bridge/routeDefinitions/routes/bridgeConfig.d.ts.map +1 -1
- package/dist/node/server/routes/bridge/routeDefinitions/routes/bridgeToRemote.d.ts +81 -0
- package/dist/node/server/routes/bridge/routeDefinitions/routes/bridgeToRemote.d.ts.map +1 -1
- package/dist/node/server/routes/bridge/routeDefinitions/routes/bridgeToRemoteEstimate.d.ts +72 -0
- package/dist/node/server/routes/bridge/routeDefinitions/routes/bridgeToRemoteEstimate.d.ts.map +1 -1
- package/dist/node/server/routes/bridge/routeDefinitions/routes/bridgeToRemoteStatus.d.ts +81 -0
- package/dist/node/server/routes/bridge/routeDefinitions/routes/bridgeToRemoteStatus.d.ts.map +1 -1
- package/dist/node/server/server.d.ts.map +1 -1
- package/dist/node/services/IBridgeServiceCollection.d.ts +2 -1
- package/dist/node/services/IBridgeServiceCollection.d.ts.map +1 -1
- package/dist/node/util/getConfigFromEnv.d.ts +6 -0
- package/dist/node/util/getConfigFromEnv.d.ts.map +1 -0
- package/dist/node/util/index.d.ts +1 -0
- package/dist/node/util/index.d.ts.map +1 -1
- package/package.json +23 -19
- package/src/config/getGateway.ts +6 -11
- package/src/manifest/getIterableMap.ts +34 -0
- package/src/manifest/getModuleLocator.ts +3 -5
- package/src/manifest/getNode.ts +8 -6
- package/src/manifest/getServices.ts +10 -46
- package/src/queue/flows/createXl1ToEthBridgeJob.ts +34 -19
- package/src/queue/workers/{ethTransactionMonitor.ts → EthTransactionMonitor.ts} +16 -7
- package/src/queue/workers/{ethTransactionPreparation.ts → EthTransactionPreparation.ts} +21 -9
- package/src/queue/workers/{ethTransactionSubmission.ts → EthTransactionSubmission.ts} +24 -9
- package/src/queue/workers/WorkerDescription.ts +3 -1
- package/src/queue/workers/{xl1ToEthBridgeParent.ts → Xl1ToEthBridgeParent.ts} +10 -2
- package/src/queue/workers/{xl1TransactionMonitor.ts → Xl1TransactionMonitor.ts} +20 -10
- package/src/queue/workers/{xl1TransactionPreparation.ts → Xl1TransactionPreparation.ts} +16 -5
- package/src/queue/workers/{xl1TransactionSubmission.ts → Xl1TransactionSubmission.ts} +21 -10
- package/src/queue/workers/createWorkers.ts +16 -9
- package/src/queue/workers/index.ts +7 -7
- package/src/queue/workers/util/index.ts +2 -0
- package/src/queue/workers/util/submitEthTransaction.ts +25 -0
- package/src/queue/workers/util/submitXl1Transaction.ts +9 -0
- package/src/server/addWorkers.ts +9 -0
- package/src/server/app.ts +1 -1
- package/src/server/index.ts +2 -2
- package/src/server/routes/bridge/routeDefinitions/routes/bridgeConfig.ts +4 -2
- package/src/server/routes/bridge/routeDefinitions/routes/bridgeToRemote.ts +13 -10
- package/src/server/routes/bridge/routeDefinitions/routes/bridgeToRemoteEstimate.ts +21 -15
- package/src/server/routes/bridge/routeDefinitions/routes/bridgeToRemoteStatus.ts +17 -15
- package/src/server/server.ts +3 -1
- package/src/services/IBridgeServiceCollection.ts +2 -1
- package/src/util/getConfigFromEnv.ts +15 -0
- package/src/util/index.ts +1 -0
- package/dist/node/queue/workers/ethTransactionMonitor.d.ts +0 -3
- package/dist/node/queue/workers/ethTransactionMonitor.d.ts.map +0 -1
- package/dist/node/queue/workers/ethTransactionPreparation.d.ts +0 -5
- package/dist/node/queue/workers/ethTransactionPreparation.d.ts.map +0 -1
- package/dist/node/queue/workers/ethTransactionSubmission.d.ts +0 -3
- package/dist/node/queue/workers/ethTransactionSubmission.d.ts.map +0 -1
- package/dist/node/queue/workers/xl1ToEthBridgeParent.d.ts +0 -3
- package/dist/node/queue/workers/xl1ToEthBridgeParent.d.ts.map +0 -1
- package/dist/node/queue/workers/xl1TransactionMonitor.d.ts +0 -3
- package/dist/node/queue/workers/xl1TransactionMonitor.d.ts.map +0 -1
- package/dist/node/queue/workers/xl1TransactionPreparation.d.ts +0 -3
- package/dist/node/queue/workers/xl1TransactionPreparation.d.ts.map +0 -1
- package/dist/node/queue/workers/xl1TransactionSubmission.d.ts +0 -3
- package/dist/node/queue/workers/xl1TransactionSubmission.d.ts.map +0 -1
- package/dist/node/server/flowProducer.d.ts.map +0 -1
- /package/src/server/{flowProducer.ts → addFlowProducer.ts} +0 -0
|
@@ -7,7 +7,7 @@ import type { WorkerDescription } from './WorkerDescription.ts'
|
|
|
7
7
|
const name = 'Bridge XL1 to Ethereum'
|
|
8
8
|
const queueName = 'xl1-to-eth-bridge'
|
|
9
9
|
const createWorker = (connection: Redis) => {
|
|
10
|
-
new Worker(
|
|
10
|
+
const worker = new Worker(
|
|
11
11
|
queueName,
|
|
12
12
|
async (job: Job) => {
|
|
13
13
|
await job.log(`[${job.name}] start`)
|
|
@@ -18,8 +18,16 @@ const createWorker = (connection: Redis) => {
|
|
|
18
18
|
},
|
|
19
19
|
{ connection },
|
|
20
20
|
)
|
|
21
|
+
|
|
22
|
+
worker.on('failed', (job, err) => {
|
|
23
|
+
console.error(`[${name}] Job ${job?.id} failed:`, err.message)
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
worker.on('error', (err) => {
|
|
27
|
+
console.error(`[${name}] Worker error:`, err)
|
|
28
|
+
})
|
|
21
29
|
}
|
|
22
30
|
|
|
23
|
-
export const
|
|
31
|
+
export const Xl1ToEthBridgeParent: WorkerDescription = {
|
|
24
32
|
createWorker, name, queueName,
|
|
25
33
|
}
|
|
@@ -10,35 +10,37 @@ import type { Redis } from 'ioredis'
|
|
|
10
10
|
import type { IBridgeServiceCollection } from '../../services/index.ts'
|
|
11
11
|
import type { WorkerDescription } from './WorkerDescription.ts'
|
|
12
12
|
|
|
13
|
-
type JobData =
|
|
13
|
+
type JobData = { tx: SignedHydratedTransaction }
|
|
14
14
|
|
|
15
15
|
interface ReturnType {
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
const name = 'Monitor Submitted XL1 Transaction'
|
|
19
19
|
const queueName = 'xl1-tx-monitor'
|
|
20
|
-
const createWorker = (connection: Redis) => {
|
|
21
|
-
|
|
20
|
+
const createWorker = (connection: Redis, services?: IBridgeServiceCollection) => {
|
|
21
|
+
const gateway = assertEx(services?.gateway, () => 'gateway service not provided')
|
|
22
|
+
const stateMap = assertEx(services?.xl1TxStateMap, () => 'xl1TxStateMap service not provided')
|
|
23
|
+
|
|
24
|
+
const worker = new Worker(
|
|
22
25
|
queueName,
|
|
23
26
|
async (job: Job<JobData, ReturnType>) => {
|
|
24
|
-
const {
|
|
25
|
-
gateway, tx, xl1TxStateMap: stateMap,
|
|
26
|
-
} = job.data
|
|
27
|
+
const { tx } = job.data
|
|
27
28
|
// Get the hash of the transaction
|
|
28
29
|
const hash = await PayloadBuilder.hash(tx[0])
|
|
29
30
|
// Get the state of the transaction
|
|
30
31
|
const viewer = assertEx(gateway.connection.viewer, () => `[${hash}] viewer not defined on gateway`)
|
|
31
32
|
const state = assertEx(await stateMap.get(hash), () => `[${hash}] state not found`)
|
|
33
|
+
const submissionHash = assertEx(state?.submissionHash, () => `[${hash}] submissionHash not found`)
|
|
32
34
|
|
|
33
35
|
// Check for transaction inclusion on chain
|
|
34
36
|
await job.log(`[${hash}] Checking for XL1 transaction inclusion on chain`)
|
|
35
|
-
const foundTx = await viewer.transactionByHash(
|
|
37
|
+
const foundTx = await viewer.transactionByHash(submissionHash)
|
|
36
38
|
|
|
37
39
|
// Transaction found on chain
|
|
38
40
|
if (isDefined(foundTx) && !isNull(foundTx)) {
|
|
39
41
|
await job.log(`[${hash}] Found transaction on chain`)
|
|
40
|
-
//
|
|
41
|
-
state.confirmationHash = hash
|
|
42
|
+
// Store the block hash
|
|
43
|
+
state.confirmationHash = await PayloadBuilder.hash(foundTx[0])
|
|
42
44
|
await stateMap.set(hash, state)
|
|
43
45
|
return {}
|
|
44
46
|
}
|
|
@@ -59,8 +61,16 @@ const createWorker = (connection: Redis) => {
|
|
|
59
61
|
},
|
|
60
62
|
{ connection },
|
|
61
63
|
)
|
|
64
|
+
|
|
65
|
+
worker.on('failed', (job, err) => {
|
|
66
|
+
console.error(`[${name}] Job ${job?.id} failed:`, err.message)
|
|
67
|
+
})
|
|
68
|
+
|
|
69
|
+
worker.on('error', (err) => {
|
|
70
|
+
console.error(`[${name}] Worker error:`, err)
|
|
71
|
+
})
|
|
62
72
|
}
|
|
63
73
|
|
|
64
|
-
export const
|
|
74
|
+
export const Xl1TransactionMonitor: WorkerDescription = {
|
|
65
75
|
createWorker, name, queueName,
|
|
66
76
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { assertEx } from '@xylabs/sdk-js'
|
|
1
2
|
import { PayloadBuilder } from '@xyo-network/payload-builder'
|
|
2
3
|
import type { SignedHydratedTransaction } from '@xyo-network/xl1-sdk'
|
|
3
4
|
import type { Job } from 'bullmq'
|
|
@@ -7,17 +8,19 @@ import type { Redis } from 'ioredis'
|
|
|
7
8
|
import type { IBridgeServiceCollection } from '../../services/index.ts'
|
|
8
9
|
import type { WorkerDescription } from './WorkerDescription.ts'
|
|
9
10
|
|
|
10
|
-
type JobData =
|
|
11
|
+
type JobData = { tx: SignedHydratedTransaction }
|
|
11
12
|
|
|
12
13
|
interface ReturnType {}
|
|
13
14
|
|
|
14
15
|
const name = 'Prepare XL1 Transaction'
|
|
15
16
|
const queueName = 'xl1-tx-prepare'
|
|
16
|
-
const createWorker = (connection: Redis) => {
|
|
17
|
-
|
|
17
|
+
const createWorker = (connection: Redis, services?: IBridgeServiceCollection) => {
|
|
18
|
+
const stateMap = assertEx(services?.xl1TxStateMap, () => 'xl1TxStateMap service not provided')
|
|
19
|
+
|
|
20
|
+
const worker = new Worker(
|
|
18
21
|
queueName,
|
|
19
22
|
async (job: Job<JobData, ReturnType>) => {
|
|
20
|
-
const { tx
|
|
23
|
+
const { tx } = job.data
|
|
21
24
|
const hash = await PayloadBuilder.hash(tx[0])
|
|
22
25
|
await job.log(`[${hash}] preparing XL1 transaction`)
|
|
23
26
|
const preparedTx = tx
|
|
@@ -29,8 +32,16 @@ const createWorker = (connection: Redis) => {
|
|
|
29
32
|
},
|
|
30
33
|
{ connection },
|
|
31
34
|
)
|
|
35
|
+
|
|
36
|
+
worker.on('failed', (job, err) => {
|
|
37
|
+
console.error(`[${name}] Job ${job?.id} failed:`, err.message)
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
worker.on('error', (err) => {
|
|
41
|
+
console.error(`[${name}] Worker error:`, err)
|
|
42
|
+
})
|
|
32
43
|
}
|
|
33
44
|
|
|
34
|
-
export const
|
|
45
|
+
export const Xl1TransactionPreparation: WorkerDescription = {
|
|
35
46
|
createWorker, name, queueName,
|
|
36
47
|
}
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
import { assertEx, isDefined } from '@xylabs/sdk-js'
|
|
2
2
|
import { PayloadBuilder } from '@xyo-network/payload-builder'
|
|
3
|
-
import type
|
|
3
|
+
import { type SignedHydratedTransaction } from '@xyo-network/xl1-sdk'
|
|
4
4
|
import type { Job } from 'bullmq'
|
|
5
5
|
import { Worker } from 'bullmq'
|
|
6
6
|
import type { Redis } from 'ioredis'
|
|
7
7
|
|
|
8
8
|
import type { IBridgeServiceCollection, Xl1TxState } from '../../services/index.ts'
|
|
9
|
+
import { submitXl1Transaction } from './util/index.ts'
|
|
9
10
|
import type { WorkerDescription } from './WorkerDescription.ts'
|
|
10
11
|
|
|
11
|
-
type JobData =
|
|
12
|
+
type JobData = { tx: SignedHydratedTransaction }
|
|
12
13
|
|
|
13
14
|
interface ReturnType {
|
|
14
15
|
submissionHash: Required<Xl1TxState>['submissionHash']
|
|
@@ -16,13 +17,14 @@ interface ReturnType {
|
|
|
16
17
|
|
|
17
18
|
const name = 'Submit XL1 Transaction'
|
|
18
19
|
const queueName = 'xl1-tx-submit'
|
|
19
|
-
const createWorker = (connection: Redis) => {
|
|
20
|
-
|
|
20
|
+
const createWorker = (connection: Redis, services?: IBridgeServiceCollection) => {
|
|
21
|
+
const gateway = assertEx(services?.gateway, () => 'gateway service not provided')
|
|
22
|
+
const stateMap = assertEx(services?.xl1TxStateMap, () => 'xl1TxStateMap service not provided')
|
|
23
|
+
|
|
24
|
+
const worker = new Worker(
|
|
21
25
|
queueName,
|
|
22
26
|
async (job: Job<JobData, ReturnType>) => {
|
|
23
|
-
const {
|
|
24
|
-
gateway, tx, xl1TxStateMap: stateMap,
|
|
25
|
-
} = job.data
|
|
27
|
+
const { tx } = job.data
|
|
26
28
|
// Get the hash of the transaction
|
|
27
29
|
const hash = await PayloadBuilder.hash(tx[0])
|
|
28
30
|
// Get the state of the transaction
|
|
@@ -38,9 +40,10 @@ const createWorker = (connection: Redis) => {
|
|
|
38
40
|
|
|
39
41
|
// Submit the transaction to the XL1 network
|
|
40
42
|
await job.log(`[${hash}] Submitting XL1 tx`)
|
|
41
|
-
const [submissionHash] = await
|
|
43
|
+
const [submissionHash] = await submitXl1Transaction(preparedTx, gateway)
|
|
44
|
+
|
|
42
45
|
// Ensure the submission hash matches the expected hash
|
|
43
|
-
assertEx(submissionHash === hash, () => `[${hash}] Submitted transaction hash ${submissionHash} does not match expected hash`)
|
|
46
|
+
// assertEx(submissionHash === hash, () => `[${hash}] Submitted transaction hash ${submissionHash} does not match expected hash`)
|
|
44
47
|
await job.log(`[${hash}] Submitted XL1 tx`)
|
|
45
48
|
|
|
46
49
|
// Store the submission hash in the state
|
|
@@ -53,8 +56,16 @@ const createWorker = (connection: Redis) => {
|
|
|
53
56
|
},
|
|
54
57
|
{ connection },
|
|
55
58
|
)
|
|
59
|
+
|
|
60
|
+
worker.on('failed', (job, err) => {
|
|
61
|
+
console.error(`[${name}] Job ${job?.id} failed:`, err.message)
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
worker.on('error', (err) => {
|
|
65
|
+
console.error(`[${name}] Worker error:`, err)
|
|
66
|
+
})
|
|
56
67
|
}
|
|
57
68
|
|
|
58
|
-
export const
|
|
69
|
+
export const Xl1TransactionSubmission: WorkerDescription = {
|
|
59
70
|
createWorker, name, queueName,
|
|
60
71
|
}
|
|
@@ -1,15 +1,22 @@
|
|
|
1
1
|
import type { Redis } from 'ioredis'
|
|
2
2
|
|
|
3
|
+
import type { IBridgeServiceCollection } from '../../services/index.ts'
|
|
3
4
|
import {
|
|
4
|
-
|
|
5
|
+
EthTransactionMonitor,
|
|
6
|
+
EthTransactionPreparation,
|
|
7
|
+
EthTransactionSubmission,
|
|
8
|
+
Xl1ToEthBridgeParent,
|
|
9
|
+
Xl1TransactionMonitor,
|
|
10
|
+
Xl1TransactionPreparation,
|
|
11
|
+
Xl1TransactionSubmission,
|
|
5
12
|
} from './index.ts'
|
|
6
13
|
|
|
7
|
-
export const createWorkers = (connection: Redis) => {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
14
|
+
export const createWorkers = (connection: Redis, services: IBridgeServiceCollection) => {
|
|
15
|
+
Xl1ToEthBridgeParent.createWorker(connection)
|
|
16
|
+
Xl1TransactionPreparation.createWorker(connection, services)
|
|
17
|
+
Xl1TransactionSubmission.createWorker(connection, services)
|
|
18
|
+
Xl1TransactionMonitor.createWorker(connection, services)
|
|
19
|
+
EthTransactionPreparation.createWorker(connection, services)
|
|
20
|
+
EthTransactionSubmission.createWorker(connection, services)
|
|
21
|
+
EthTransactionMonitor.createWorker(connection, services)
|
|
15
22
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
export * from './createWorkers.ts'
|
|
2
|
-
export * from './
|
|
3
|
-
export * from './
|
|
4
|
-
export * from './
|
|
5
|
-
export * from './
|
|
6
|
-
export * from './
|
|
7
|
-
export * from './
|
|
8
|
-
export * from './
|
|
2
|
+
export * from './EthTransactionMonitor.ts'
|
|
3
|
+
export * from './EthTransactionPreparation.ts'
|
|
4
|
+
export * from './EthTransactionSubmission.ts'
|
|
5
|
+
export * from './Xl1ToEthBridgeParent.ts'
|
|
6
|
+
export * from './Xl1TransactionMonitor.ts'
|
|
7
|
+
export * from './Xl1TransactionPreparation.ts'
|
|
8
|
+
export * from './Xl1TransactionSubmission.ts'
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import {
|
|
2
|
+
assertEx, hexToBigInt, toEthAddress,
|
|
3
|
+
} from '@xylabs/sdk-js'
|
|
4
|
+
import { PayloadBuilder } from '@xyo-network/payload-builder'
|
|
5
|
+
import type { BridgeableToken, LiquidityPoolBridge } from '@xyo-network/typechain'
|
|
6
|
+
import { isBridgeIntent, type SignedHydratedTransaction } from '@xyo-network/xl1-sdk'
|
|
7
|
+
import type { Wallet } from 'ethers'
|
|
8
|
+
|
|
9
|
+
export const submitEthTransaction = async (tx: SignedHydratedTransaction, bridgeableToken: BridgeableToken, bridge: LiquidityPoolBridge, wallet: Wallet) => {
|
|
10
|
+
// Approve the bridge to spend tokens
|
|
11
|
+
const xl1Transaction = assertEx(tx[0], () => 'No corresponding XL1 transaction found')
|
|
12
|
+
const bridgeIntent = assertEx(tx[1].find(isBridgeIntent), () => 'No bridge intent found')
|
|
13
|
+
const srcAddress = toEthAddress(bridgeIntent.srcAddress)
|
|
14
|
+
const destAddress = toEthAddress(bridgeIntent.destAddress)
|
|
15
|
+
const amount = hexToBigInt(bridgeIntent.destAmount)
|
|
16
|
+
const nonce = hexToBigInt(await PayloadBuilder.hash(xl1Transaction))
|
|
17
|
+
// Assume approval has already been done out of band for simplicity
|
|
18
|
+
// const contractApprovalTx = await bridgeableToken.connect(wallet).approve(bridge.getAddress(), amount)
|
|
19
|
+
// await contractApprovalTx.wait(1)
|
|
20
|
+
|
|
21
|
+
// Send tokens to bridge
|
|
22
|
+
const bridgeTx = await bridge.connect(wallet).bridgeFromRemote(srcAddress, destAddress, amount, nonce)
|
|
23
|
+
const receipt = await bridgeTx.wait(1)
|
|
24
|
+
return receipt?.hash
|
|
25
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { SignedHydratedTransaction, XyoGatewayRunner } from '@xyo-network/xl1-sdk'
|
|
2
|
+
import { isAllowedBlockPayload } from '@xyo-network/xl1-sdk'
|
|
3
|
+
|
|
4
|
+
export const submitXl1Transaction = async (preparedTx: SignedHydratedTransaction, gateway: XyoGatewayRunner) => {
|
|
5
|
+
const onChain = preparedTx[1].filter(isAllowedBlockPayload)
|
|
6
|
+
const offChainPayloads = preparedTx[1].filter(p => !isAllowedBlockPayload(p))
|
|
7
|
+
const result = await gateway.addPayloadsToChain(onChain, offChainPayloads)
|
|
8
|
+
return result
|
|
9
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Config } from '@xyo-network/xl1-sdk'
|
|
2
|
+
|
|
3
|
+
import { createWorkers, getConnection } from '../queue/index.ts'
|
|
4
|
+
import type { IBridgeServiceCollection } from '../services/index.ts'
|
|
5
|
+
|
|
6
|
+
export const addWorkers = (config: Config, services: IBridgeServiceCollection) => {
|
|
7
|
+
const connection = getConnection(config)
|
|
8
|
+
createWorkers(connection, services)
|
|
9
|
+
}
|
package/src/server/app.ts
CHANGED
|
@@ -9,7 +9,7 @@ import cors from 'cors'
|
|
|
9
9
|
import type { Express } from 'express'
|
|
10
10
|
import express from 'express'
|
|
11
11
|
|
|
12
|
-
import { addFlowProducer } from './
|
|
12
|
+
import { addFlowProducer } from './addFlowProducer.ts'
|
|
13
13
|
import { addInstrumentation } from './instrumentation.ts'
|
|
14
14
|
import { addRoutes } from './routes/index.ts'
|
|
15
15
|
|
package/src/server/index.ts
CHANGED
|
@@ -4,7 +4,7 @@ export * from './server.ts'
|
|
|
4
4
|
import type { NodeInstance } from '@xyo-network/node-model'
|
|
5
5
|
import type { FlowProducer } from 'bullmq'
|
|
6
6
|
|
|
7
|
-
import type { IBridgeServiceCollection } from '../services/index.ts'
|
|
7
|
+
// import type { IBridgeServiceCollection } from '../services/index.ts'
|
|
8
8
|
|
|
9
9
|
declare global {
|
|
10
10
|
// eslint-disable-next-line @typescript-eslint/no-namespace
|
|
@@ -12,7 +12,7 @@ declare global {
|
|
|
12
12
|
interface Application {
|
|
13
13
|
flowProducer: FlowProducer
|
|
14
14
|
node: NodeInstance
|
|
15
|
-
services: IBridgeServiceCollection
|
|
15
|
+
// services: IBridgeServiceCollection
|
|
16
16
|
}
|
|
17
17
|
}
|
|
18
18
|
}
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import type { RouteDefinition } from '@xylabs/express'
|
|
2
2
|
import { requestHandlerValidator } from '@xylabs/express'
|
|
3
3
|
import { BridgeSettingsZod, type Config } from '@xyo-network/xl1-sdk'
|
|
4
|
+
import type { z } from 'zod'
|
|
4
5
|
|
|
5
6
|
import { getBridgeSettings } from '../../../../../config/index.ts'
|
|
6
7
|
|
|
7
|
-
const
|
|
8
|
+
export const BridgeConfigResponseZod = BridgeSettingsZod
|
|
9
|
+
export type BridgeConfigResponse = z.infer<typeof BridgeConfigResponseZod>
|
|
8
10
|
|
|
9
|
-
const validateRequest = requestHandlerValidator({ response })
|
|
11
|
+
const validateRequest = requestHandlerValidator({ response: BridgeConfigResponseZod })
|
|
10
12
|
|
|
11
13
|
export const makeBridgeConfigRoute = (config: Config): RouteDefinition => {
|
|
12
14
|
return {
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import type { RouteDefinition } from '@xylabs/express'
|
|
2
2
|
import { requestHandlerValidator } from '@xylabs/express'
|
|
3
3
|
import { PayloadBuilder } from '@xyo-network/payload-builder'
|
|
4
|
-
import { PayloadZodStrictOfSchema } from '@xyo-network/payload-model'
|
|
4
|
+
import { PayloadZodLooseOfSchema, PayloadZodStrictOfSchema } from '@xyo-network/payload-model'
|
|
5
5
|
import type {
|
|
6
|
-
BridgeSourceObservation, BridgeSourceObservationFields, Config,
|
|
7
|
-
SignedHydratedTransaction,
|
|
6
|
+
BridgeSourceObservation, BridgeSourceObservationFields, Config, SignedHydratedTransaction,
|
|
8
7
|
} from '@xyo-network/xl1-sdk'
|
|
9
8
|
import {
|
|
10
9
|
BridgeIntentFieldsZod, BridgeIntentSchema, BridgeSourceObservationFieldsZod, BridgeSourceObservationSchema, SignedTransactionBoundWitnessZod, TransferZod,
|
|
@@ -15,17 +14,21 @@ import { createXl1ToEthBridgeJob } from '../../../../../queue/index.ts'
|
|
|
15
14
|
import { validateBridgeEstimateExact, validateBridgeTransaction } from '../../../../../util/index.ts'
|
|
16
15
|
import { getRemoteChainIdZod } from '../pathParams/index.ts'
|
|
17
16
|
|
|
17
|
+
export const BridgeToRemoteBodyZod = z.tuple([
|
|
18
|
+
SignedTransactionBoundWitnessZod,
|
|
19
|
+
PayloadZodLooseOfSchema(BridgeIntentSchema).extend(BridgeIntentFieldsZod.shape),
|
|
20
|
+
TransferZod,
|
|
21
|
+
])
|
|
22
|
+
export type BridgeToRemoteBody = z.infer<typeof BridgeToRemoteBodyZod>
|
|
23
|
+
|
|
24
|
+
export const BridgeToRemoteResponseZod = PayloadZodStrictOfSchema(BridgeSourceObservationSchema).extend(BridgeSourceObservationFieldsZod.shape)
|
|
25
|
+
export type BridgeToRemoteResponse = z.infer<typeof BridgeToRemoteResponseZod>
|
|
26
|
+
|
|
18
27
|
export const makeBridgeToRemoteRoute = (config: Config): RouteDefinition => {
|
|
19
28
|
const params = z.object({ chainId: getRemoteChainIdZod(config) })
|
|
20
|
-
const body = z.tuple([
|
|
21
|
-
SignedTransactionBoundWitnessZod,
|
|
22
|
-
PayloadZodStrictOfSchema(BridgeIntentSchema).extend(BridgeIntentFieldsZod.shape),
|
|
23
|
-
TransferZod,
|
|
24
|
-
])
|
|
25
|
-
const response = PayloadZodStrictOfSchema(BridgeSourceObservationSchema).extend(BridgeSourceObservationFieldsZod.shape)
|
|
26
29
|
|
|
27
30
|
const validateRequest = requestHandlerValidator({
|
|
28
|
-
params, body, response,
|
|
31
|
+
params, body: BridgeToRemoteBodyZod, response: BridgeToRemoteResponseZod,
|
|
29
32
|
})
|
|
30
33
|
return {
|
|
31
34
|
method: 'post',
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import type { RouteDefinition } from '@xylabs/express'
|
|
2
2
|
import { requestHandlerValidator } from '@xylabs/express'
|
|
3
3
|
import { assertEx, toAddress } from '@xylabs/sdk-js'
|
|
4
|
-
import {
|
|
5
|
-
import { buildUnsignedTransaction, type Config } from '@xyo-network/xl1-sdk'
|
|
4
|
+
import { PayloadZodStrictOfSchema } from '@xyo-network/payload-model'
|
|
6
5
|
import {
|
|
7
|
-
|
|
6
|
+
buildUnsignedTransaction, type Config, TransferZod,
|
|
7
|
+
} from '@xyo-network/xl1-sdk'
|
|
8
|
+
import {
|
|
9
|
+
BridgeIntentFieldsZod, BridgeIntentSchema, toXL1BlockNumber, TransactionBoundWitnessZod,
|
|
8
10
|
} from '@xyo-network/xl1-sdk'
|
|
9
11
|
import { z } from 'zod'
|
|
10
12
|
|
|
@@ -12,22 +14,26 @@ import { getGateway, getXl1ChainId } from '../../../../../config/index.ts'
|
|
|
12
14
|
import { generateBridgeEstimate } from '../../../../../util/index.ts'
|
|
13
15
|
import { getRemoteChainIdZod } from '../pathParams/index.ts'
|
|
14
16
|
|
|
17
|
+
export const BridgeToRemoteEstimateBodyZod = BridgeIntentFieldsZod.pick({
|
|
18
|
+
destAddress: true,
|
|
19
|
+
srcAddress: true,
|
|
20
|
+
srcAmount: true,
|
|
21
|
+
})
|
|
22
|
+
export type BridgeToRemoteEstimateBody = z.infer<typeof BridgeToRemoteEstimateBodyZod>
|
|
23
|
+
|
|
24
|
+
export const BridgeToRemoteEstimateResponseZod = z.tuple([
|
|
25
|
+
TransactionBoundWitnessZod,
|
|
26
|
+
PayloadZodStrictOfSchema(BridgeIntentSchema).extend(BridgeIntentFieldsZod.shape),
|
|
27
|
+
TransferZod,
|
|
28
|
+
])
|
|
29
|
+
|
|
30
|
+
export type BridgeToRemoteEstimateResponse = z.infer<typeof BridgeToRemoteEstimateResponseZod>
|
|
31
|
+
|
|
15
32
|
export const makeBridgeToRemoteEstimateRoute = (config: Config): RouteDefinition => {
|
|
16
33
|
const params = z.object({ chainId: getRemoteChainIdZod(config) })
|
|
17
|
-
const body = BridgeIntentFieldsZod.pick({
|
|
18
|
-
destAddress: true,
|
|
19
|
-
srcAddress: true,
|
|
20
|
-
srcAmount: true,
|
|
21
|
-
})
|
|
22
|
-
const response = z.tuple([
|
|
23
|
-
TransactionBoundWitnessZod,
|
|
24
|
-
PayloadZodStrictOfSchema(BridgeIntentSchema).extend(BridgeIntentFieldsZod.shape),
|
|
25
|
-
PayloadZodLooseOfSchema(TransferSchema),
|
|
26
|
-
])
|
|
27
34
|
const validateRequest = requestHandlerValidator({
|
|
28
|
-
params, body, response,
|
|
35
|
+
params, body: BridgeToRemoteEstimateBodyZod, response: BridgeToRemoteEstimateResponseZod,
|
|
29
36
|
})
|
|
30
|
-
|
|
31
37
|
return {
|
|
32
38
|
method: 'post',
|
|
33
39
|
path: '/bridge/chains/:chainId/bridgeToRemote/estimate',
|
|
@@ -17,28 +17,30 @@ import { getBridgeSettings } from '../../../../../config/index.ts'
|
|
|
17
17
|
import { generateBridgeEstimate } from '../../../../../util/index.ts'
|
|
18
18
|
import { getRemoteChainIdZod } from '../pathParams/index.ts'
|
|
19
19
|
|
|
20
|
+
export const BridgeToRemoteStatusResponseZod = z.union([
|
|
21
|
+
z.tuple([]),
|
|
22
|
+
z.tuple([PayloadZodStrictOfSchema(BridgeIntentSchema).extend(BridgeIntentFieldsZod.shape)]),
|
|
23
|
+
z.tuple([
|
|
24
|
+
PayloadZodStrictOfSchema(BridgeIntentSchema).extend(BridgeIntentFieldsZod.shape),
|
|
25
|
+
PayloadZodStrictOfSchema(BridgeSourceObservationSchema).extend(BridgeSourceObservationFieldsZod.shape),
|
|
26
|
+
]),
|
|
27
|
+
z.tuple([
|
|
28
|
+
PayloadZodStrictOfSchema(BridgeIntentSchema).extend(BridgeIntentFieldsZod.shape),
|
|
29
|
+
PayloadZodStrictOfSchema(BridgeSourceObservationSchema).extend(BridgeSourceObservationFieldsZod.shape),
|
|
30
|
+
PayloadZodStrictOfSchema(BridgeDestinationObservationSchema).extend(BridgeDestinationObservationFieldsZod.shape),
|
|
31
|
+
]),
|
|
32
|
+
])
|
|
33
|
+
export type BridgeToRemoteStatusResponse = z.infer<typeof BridgeToRemoteStatusResponseZod>
|
|
34
|
+
|
|
20
35
|
export const makeBridgeToRemoteStatusRoute = (config: Config): RouteDefinition => {
|
|
21
36
|
const params = z.object({
|
|
22
37
|
chainId: getRemoteChainIdZod(config),
|
|
23
38
|
nonce: z.string().nonempty(),
|
|
24
39
|
})
|
|
25
40
|
const query = z.object({ mockStatus: z.coerce.number().default(0) })
|
|
26
|
-
const response = z.union([
|
|
27
|
-
z.tuple([]),
|
|
28
|
-
z.tuple([PayloadZodStrictOfSchema(BridgeIntentSchema).extend(BridgeIntentFieldsZod.shape)]),
|
|
29
|
-
z.tuple([
|
|
30
|
-
PayloadZodStrictOfSchema(BridgeIntentSchema).extend(BridgeIntentFieldsZod.shape),
|
|
31
|
-
PayloadZodStrictOfSchema(BridgeSourceObservationSchema).extend(BridgeSourceObservationFieldsZod.shape),
|
|
32
|
-
]),
|
|
33
|
-
z.tuple([
|
|
34
|
-
PayloadZodStrictOfSchema(BridgeIntentSchema).extend(BridgeIntentFieldsZod.shape),
|
|
35
|
-
PayloadZodStrictOfSchema(BridgeSourceObservationSchema).extend(BridgeSourceObservationFieldsZod.shape),
|
|
36
|
-
PayloadZodStrictOfSchema(BridgeDestinationObservationSchema).extend(BridgeDestinationObservationFieldsZod.shape),
|
|
37
|
-
]),
|
|
38
|
-
])
|
|
39
41
|
|
|
40
42
|
const validateRequest = requestHandlerValidator({
|
|
41
|
-
params, query, response,
|
|
43
|
+
params, query, response: BridgeToRemoteStatusResponseZod,
|
|
42
44
|
})
|
|
43
45
|
|
|
44
46
|
return {
|
|
@@ -47,7 +49,7 @@ export const makeBridgeToRemoteStatusRoute = (config: Config): RouteDefinition =
|
|
|
47
49
|
handlers: validateRequest(async (req, res) => {
|
|
48
50
|
const { chainId } = req.params
|
|
49
51
|
const { mockStatus = 0 } = req.query
|
|
50
|
-
const result: z.infer<typeof
|
|
52
|
+
const result: z.infer<typeof BridgeToRemoteStatusResponseZod> = [] as unknown as z.infer<typeof BridgeToRemoteStatusResponseZod>
|
|
51
53
|
|
|
52
54
|
const {
|
|
53
55
|
remoteTokenAddress, xl1ChainId, xl1TokenAddress,
|
package/src/server/server.ts
CHANGED
|
@@ -8,6 +8,7 @@ import { HDWallet } from '@xyo-network/wallet'
|
|
|
8
8
|
import { type Config } from '@xyo-network/xl1-sdk'
|
|
9
9
|
|
|
10
10
|
import { getNode, getServices } from '../manifest/index.ts'
|
|
11
|
+
import { addWorkers } from './addWorkers.ts'
|
|
11
12
|
import { getApp } from './app.ts'
|
|
12
13
|
|
|
13
14
|
const hostname = '::'
|
|
@@ -52,7 +53,8 @@ export const getServer = async (context: GetServerContext) => {
|
|
|
52
53
|
}
|
|
53
54
|
const node = context.node ?? await getNode(nodeContext)
|
|
54
55
|
const app = getApp(node, config)
|
|
55
|
-
|
|
56
|
+
const services = await getServices({ config, logger })
|
|
57
|
+
addWorkers(config, services)
|
|
56
58
|
const server = app.listen(port, hostname, () => logger?.log(`[Bridge] Server listening at http://${hostname}:${port}`))
|
|
57
59
|
server.setTimeout(20_000)
|
|
58
60
|
return server
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Hash } from '@xylabs/sdk-js'
|
|
2
2
|
import type { AccountInstance } from '@xyo-network/account-model'
|
|
3
|
-
import type { LiquidityPoolBridge } from '@xyo-network/typechain'
|
|
3
|
+
import type { BridgeableToken, LiquidityPoolBridge } from '@xyo-network/typechain'
|
|
4
4
|
import type { IterableMap, XyoGatewayRunner } from '@xyo-network/xl1-sdk'
|
|
5
5
|
import type { Provider, Wallet } from 'ethers'
|
|
6
6
|
|
|
@@ -10,6 +10,7 @@ import type { Xl1TxState } from './Xl1TxState.ts'
|
|
|
10
10
|
export interface IBridgeServiceCollection {
|
|
11
11
|
account: AccountInstance
|
|
12
12
|
bridge: LiquidityPoolBridge
|
|
13
|
+
bridgeableToken: BridgeableToken
|
|
13
14
|
ethTxStateMap: IterableMap<Hash, EthTxState>
|
|
14
15
|
gateway: XyoGatewayRunner
|
|
15
16
|
provider: Provider
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type Config, ConfigZod } from '@xyo-network/xl1-sdk'
|
|
2
|
+
import type { Configuration } from 'yargs-parser'
|
|
3
|
+
import parser from 'yargs-parser'
|
|
4
|
+
|
|
5
|
+
export const ConfigParserEnvPrefix = 'XL1_'
|
|
6
|
+
export const ConfigParserConfiguration: Partial<Configuration> = {
|
|
7
|
+
'dot-notation': true, // foo.bar → { foo: { bar } }
|
|
8
|
+
'parse-numbers': false, // Don't auto-parse numbers to allow strings like "0x1"
|
|
9
|
+
'populate--': true, // Populate -- with all options so we can detected user-supplied vs defaults
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export const getConfigFromEnv = (): Config => {
|
|
13
|
+
const parsed = parser([], { configuration: ConfigParserConfiguration, envPrefix: ConfigParserEnvPrefix })
|
|
14
|
+
return ConfigZod.parse(parsed)
|
|
15
|
+
}
|
package/src/util/index.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export * from './calculateBridgeFees.ts'
|
|
2
2
|
export * from './generateBridgeEstimate.ts'
|
|
3
|
+
export * from './getConfigFromEnv.ts'
|
|
3
4
|
export * from './validateBridgeEstimate.ts'
|
|
4
5
|
export * from './validateBridgeEstimateExact.ts'
|
|
5
6
|
export * from './validateBridgeTransaction.ts'
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ethTransactionMonitor.d.ts","sourceRoot":"","sources":["../../../../src/queue/workers/ethTransactionMonitor.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAA;AA+B/D,eAAO,MAAM,qBAAqB,EAAE,iBAEnC,CAAA"}
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
import type { Redis } from 'ioredis';
|
|
2
|
-
import type { WorkerDescription } from './WorkerDescription.ts';
|
|
3
|
-
export declare const createWorker: (connection: Redis) => void;
|
|
4
|
-
export declare const ethTransactionPreparation: WorkerDescription;
|
|
5
|
-
//# sourceMappingURL=ethTransactionPreparation.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ethTransactionPreparation.d.ts","sourceRoot":"","sources":["../../../../src/queue/workers/ethTransactionPreparation.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA;AAGpC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAA;AAS/D,eAAO,MAAM,YAAY,GAAI,YAAY,KAAK,SAwB7C,CAAA;AAED,eAAO,MAAM,yBAAyB,EAAE,iBAEvC,CAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ethTransactionSubmission.d.ts","sourceRoot":"","sources":["../../../../src/queue/workers/ethTransactionSubmission.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAA;AAkE/D,eAAO,MAAM,wBAAwB,EAAE,iBAEtC,CAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"xl1ToEthBridgeParent.d.ts","sourceRoot":"","sources":["../../../../src/queue/workers/xl1ToEthBridgeParent.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAA;AAkB/D,eAAO,MAAM,oBAAoB,EAAE,iBAElC,CAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"xl1TransactionMonitor.d.ts","sourceRoot":"","sources":["../../../../src/queue/workers/xl1TransactionMonitor.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAA;AAqD/D,eAAO,MAAM,qBAAqB,EAAE,iBAEnC,CAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"xl1TransactionPreparation.d.ts","sourceRoot":"","sources":["../../../../src/queue/workers/xl1TransactionPreparation.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAA;AA0B/D,eAAO,MAAM,yBAAyB,EAAE,iBAEvC,CAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"xl1TransactionSubmission.d.ts","sourceRoot":"","sources":["../../../../src/queue/workers/xl1TransactionSubmission.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAA;AAiD/D,eAAO,MAAM,wBAAwB,EAAE,iBAEtC,CAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"flowProducer.d.ts","sourceRoot":"","sources":["../../../src/server/flowProducer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAA;AAClD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AAItC,eAAO,MAAM,eAAe,GAAI,KAAK,OAAO,EAAE,QAAQ,MAAM,KAAG,OAK9D,CAAA"}
|
|
File without changes
|