@instadapp/interop-x 0.0.0-dev.d05464a → 0.0.0-dev.d71f27e

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 (80) hide show
  1. package/dist/package.json +3 -3
  2. package/dist/src/abi/index.js +2 -4
  3. package/dist/src/abi/interopXContract.json +391 -0
  4. package/dist/src/alias.js +10 -0
  5. package/dist/src/api/index.js +4 -1
  6. package/dist/src/config/index.js +10 -1
  7. package/dist/src/constants/addresses.js +3 -3
  8. package/dist/src/constants/index.js +0 -1
  9. package/dist/src/db/models/transaction.js +27 -9
  10. package/dist/src/gnosis/actions/index.js +9 -0
  11. package/dist/src/gnosis/actions/withdraw/index.js +41 -0
  12. package/dist/src/gnosis/index.js +20 -0
  13. package/dist/src/index.js +39 -23
  14. package/dist/src/net/peer/index.js +2 -1
  15. package/dist/src/net/pool/index.js +7 -2
  16. package/dist/src/net/protocol/dial/SignatureDialProtocol.js +9 -10
  17. package/dist/src/net/protocol/dial/TransactionStatusDialProtocol.js +30 -0
  18. package/dist/src/net/protocol/index.js +26 -5
  19. package/dist/src/tasks/AutoUpdateTask.js +33 -11
  20. package/dist/src/tasks/BaseTask.js +11 -3
  21. package/dist/src/tasks/{InteropXGateway/ProcessDepositEvents.js → InteropXContract/ProcessBridgeRequestEvents.js} +54 -52
  22. package/dist/src/tasks/InteropXContract/SyncBridgeRequestEvents.js +78 -0
  23. package/dist/src/tasks/InteropXContract/SyncBridgeRequestSentEvents.js +89 -0
  24. package/dist/src/tasks/Transactions/SyncTransactionStatusTask.js +55 -0
  25. package/dist/src/tasks/index.js +13 -17
  26. package/dist/src/typechain/{InteropBridgeToken.js → InteropXContract.js} +0 -0
  27. package/dist/src/typechain/factories/InteropXContract__factory.js +526 -0
  28. package/dist/src/typechain/factories/index.js +3 -5
  29. package/dist/src/typechain/index.js +3 -5
  30. package/dist/src/utils/index.js +27 -87
  31. package/package.json +3 -3
  32. package/src/abi/index.ts +2 -4
  33. package/src/abi/interopXContract.json +391 -0
  34. package/src/alias.ts +6 -0
  35. package/src/api/index.ts +4 -1
  36. package/src/config/index.ts +9 -1
  37. package/src/constants/addresses.ts +3 -3
  38. package/src/constants/index.ts +0 -1
  39. package/src/db/models/transaction.ts +66 -21
  40. package/src/gnosis/actions/index.ts +5 -0
  41. package/src/gnosis/actions/withdraw/index.ts +56 -0
  42. package/src/gnosis/index.ts +19 -0
  43. package/src/index.ts +52 -25
  44. package/src/net/peer/index.ts +2 -1
  45. package/src/net/pool/index.ts +7 -3
  46. package/src/net/protocol/dial/SignatureDialProtocol.ts +11 -13
  47. package/src/net/protocol/dial/TransactionStatusDialProtocol.ts +33 -0
  48. package/src/net/protocol/index.ts +28 -6
  49. package/src/tasks/AutoUpdateTask.ts +36 -14
  50. package/src/tasks/BaseTask.ts +13 -3
  51. package/src/tasks/{InteropBridge/ProcessWithdrawEvents.ts → InteropXContract/ProcessBridgeRequestEvents.ts} +78 -95
  52. package/src/tasks/InteropXContract/SyncBridgeRequestEvents.ts +116 -0
  53. package/src/tasks/InteropXContract/SyncBridgeRequestSentEvents.ts +120 -0
  54. package/src/tasks/Transactions/SyncTransactionStatusTask.ts +67 -0
  55. package/src/tasks/index.ts +17 -18
  56. package/src/typechain/InteropXContract.ts +524 -0
  57. package/src/typechain/factories/InteropXContract__factory.ts +533 -0
  58. package/src/typechain/factories/index.ts +1 -2
  59. package/src/typechain/index.ts +2 -4
  60. package/src/utils/index.ts +61 -128
  61. package/tsconfig.json +7 -2
  62. package/dist/src/abi/interopBridgeToken.json +0 -286
  63. package/dist/src/abi/interopXGateway.json +0 -184
  64. package/dist/src/constants/itokens.js +0 -13
  65. package/dist/src/tasks/InteropBridge/ProcessWithdrawEvents.js +0 -147
  66. package/dist/src/tasks/InteropBridge/SyncWithdrawEvents.js +0 -70
  67. package/dist/src/tasks/InteropXGateway/SyncDepositEvents.js +0 -75
  68. package/dist/src/typechain/InteropXGateway.js +0 -2
  69. package/dist/src/typechain/factories/InteropBridgeToken__factory.js +0 -459
  70. package/dist/src/typechain/factories/InteropXGateway__factory.js +0 -265
  71. package/src/abi/interopBridgeToken.json +0 -286
  72. package/src/abi/interopXGateway.json +0 -184
  73. package/src/constants/itokens.ts +0 -10
  74. package/src/tasks/InteropBridge/SyncWithdrawEvents.ts +0 -121
  75. package/src/tasks/InteropXGateway/ProcessDepositEvents.ts +0 -245
  76. package/src/tasks/InteropXGateway/SyncDepositEvents.ts +0 -126
  77. package/src/typechain/InteropBridgeToken.ts +0 -686
  78. package/src/typechain/InteropXGateway.ts +0 -407
  79. package/src/typechain/factories/InteropBridgeToken__factory.ts +0 -466
  80. package/src/typechain/factories/InteropXGateway__factory.ts +0 -272
@@ -1,12 +1,16 @@
1
1
  import { BaseTask } from "./BaseTask";
2
2
  import Logger from '@/logger';
3
- import { http } from "@/utils";
4
- import spawn from 'await-spawn';
3
+ import spawnAsync from 'await-spawn';
4
+ import { spawn } from 'child_process'
5
5
  import config from "@/config";
6
6
  import wait from "waait";
7
+ import packageJson from "../../package.json";
8
+
9
+ const currentVersion = packageJson.version;
10
+ const tag = config.staging ? 'dev' : 'latest';
7
11
 
8
12
  class AutoUpdateTask extends BaseTask {
9
- pollIntervalMs: number = 60 * 5 * 1000
13
+ pollIntervalMs: number = 60 * 10 * 1000
10
14
 
11
15
  constructor() {
12
16
  super({
@@ -18,15 +22,28 @@ class AutoUpdateTask extends BaseTask {
18
22
  return config.autoUpdate && !config.isLeadNode();
19
23
  }
20
24
 
21
- getCurrentVersion() {
22
- return require('../../package.json').version
25
+ async getInstalledVersion() {
26
+ try {
27
+ const stdout = await spawnAsync('npm', ['-g', 'ls', '--depth=0', '--json'])
28
+ return JSON.parse(stdout.toString()).dependencies[packageJson.name].version
29
+ } catch (error) {
30
+ this.logger.error(error)
31
+ return currentVersion
32
+ }
23
33
  }
24
- async pollHandler() {
25
34
 
26
- const { data } = await http.get('https://registry.npmjs.org/@instadapp/interop-x')
35
+ async getLatestVersion() {
36
+ try {
37
+ const stdout = await spawnAsync('npm', ['view', `${packageJson.name}@${tag}`, 'version'])
38
+ return stdout.toString().trim()
39
+ } catch (error) {
40
+ this.logger.error(error)
41
+ return currentVersion
42
+ }
43
+ }
27
44
 
28
- const version = data['dist-tags'].latest
29
- const currentVersion = this.getCurrentVersion()
45
+ async pollHandler() {
46
+ const version = await this.getLatestVersion()
30
47
 
31
48
  if (version === currentVersion) {
32
49
  return;
@@ -34,13 +51,13 @@ class AutoUpdateTask extends BaseTask {
34
51
 
35
52
  this.logger.warn(`New version ${version} available.`)
36
53
 
54
+ this.logger.info('Updating...')
37
55
 
38
- await spawn('npm', ['-g', 'install', '@instadapp/interop-x', '-f']);
39
-
56
+ await spawnAsync('npm', ['-g', 'install', `@instadapp/interop-x@${tag}`, '-f']);
40
57
 
41
58
  await wait(5000)
42
59
 
43
- if (currentVersion === this.getCurrentVersion()) {
60
+ if (version !== await this.getInstalledVersion()) {
44
61
  this.logger.warn(`failed to install ${version}, retrying in 5 minutes`)
45
62
  return;
46
63
  }
@@ -48,11 +65,16 @@ class AutoUpdateTask extends BaseTask {
48
65
  this.logger.warn(`Installed version ${version}`)
49
66
  this.logger.warn(`Restarting...`)
50
67
 
51
- spawn(process.argv[0], process.argv.slice(1), {
68
+
69
+ // TODO: its restarting in the bg, but it should be in the fg
70
+ const subprocess = spawn(process.argv[0], process.argv.slice(1), {
52
71
  cwd: process.cwd(),
53
- stdio: "inherit"
72
+ stdio: "inherit",
73
+ // shell: process.env.SHELL,
54
74
  });
55
75
 
76
+ subprocess.unref();
77
+
56
78
  process.exit()
57
79
  }
58
80
  }
@@ -19,6 +19,7 @@ export class BaseTask extends EventEmitter implements IBaseTask {
19
19
  started: boolean = false
20
20
  pollIntervalMs: number = 10 * 1000
21
21
  leadNodeOnly: boolean = false
22
+ exceptLeadNode: boolean = false
22
23
 
23
24
  public constructor({ logger }: { logger?: Logger }) {
24
25
  super()
@@ -45,11 +46,20 @@ export class BaseTask extends EventEmitter implements IBaseTask {
45
46
  }
46
47
 
47
48
  prePollHandler(): boolean {
48
- if (!this.leadNodeOnly) {
49
- return true
49
+ if(config.isMaintenanceMode()){
50
+ this.logger.warn('Maintenance mode is enabled. Skipping task.')
51
+ return false
50
52
  }
51
53
 
52
- return config.isLeadNode()
54
+ if (this.exceptLeadNode) {
55
+ return !config.isLeadNode();
56
+ }
57
+
58
+ if (this.leadNodeOnly) {
59
+ return config.isLeadNode()
60
+ }
61
+
62
+ return true
53
63
  }
54
64
 
55
65
  async pollHandler() {
@@ -1,66 +1,33 @@
1
1
  import { BaseTask } from "../BaseTask";
2
2
  import Logger from '@/logger';
3
- import { BigNumber, ethers } from "ethers";
3
+ import { ethers, Wallet } from "ethers";
4
4
  import abi from "@/abi";
5
5
  import { Transaction } from "@/db";
6
- import { buildDataForTransaction, buildSignatureBytes, getContract, getRpcProviderUrl, Signature } from "@/utils";
6
+ import { buildSignatureBytes, generateGnosisTransaction, generateInteropTransactionHash, getContract, getRpcProviderUrl, Signature } from "@/utils";
7
7
  import { addresses } from "@/constants";
8
+ import { Op } from "sequelize";
8
9
  import { ChainId } from "@/types";
9
10
  import config from "@/config";
10
- import { GnosisSafe, InteropXGateway } from "@/typechain";
11
- import { Op } from "sequelize";
11
+ import { GnosisSafe, InteropXContract } from "@/typechain";
12
12
  import wait from "waait";
13
+ import { buildGnosisAction } from "@/gnosis";
13
14
  import { peerPool, protocol } from "@/net";
14
15
  import { LogDescription } from "ethers/lib/utils";
15
16
 
16
- const generateGnosisTransaction = async (transactionData: any, safeContract: GnosisSafe) => {
17
- console.log(transactionData);
18
-
19
- let isExecuted = await safeContract.dataHashes(
20
- await safeContract.getTransactionHash(
21
- transactionData.to,
22
- transactionData.value,
23
- transactionData.data,
24
- transactionData.operation,
25
- transactionData.safeTxGas,
26
- transactionData.baseGas,
27
- transactionData.gasPrice,
28
- transactionData.gasToken,
29
- transactionData.refundReceiver,
30
- transactionData.nonce
31
- )
32
- )
33
-
34
- while (isExecuted == 1) {
35
- transactionData.safeTxGas = BigNumber.from(String(transactionData.safeTxGas)).add(1).toString()
36
-
37
- isExecuted = await safeContract.dataHashes(
38
- await safeContract.getTransactionHash(
39
- transactionData.to,
40
- transactionData.value,
41
- transactionData.data,
42
- transactionData.operation,
43
- transactionData.safeTxGas,
44
- transactionData.baseGas,
45
- transactionData.gasPrice,
46
- transactionData.gasToken,
47
- transactionData.refundReceiver,
48
- transactionData.nonce
49
- )
50
- )
51
- }
52
-
53
- return transactionData
54
- }
55
-
56
- class ProcessWithdrawEvents extends BaseTask {
17
+ class ProccessBridgeRequestEvents extends BaseTask {
18
+ contractAddress: string;
19
+ safeContractAddress: string;
57
20
  provider: ethers.providers.JsonRpcProvider;
21
+ contract: InteropXContract;
22
+ safeContract: GnosisSafe;
58
23
  chainId: ChainId;
59
- leadNodeOnly = true
24
+ sourceWallet: Wallet;
25
+
26
+ leadNodeOnly: boolean = true;
60
27
 
61
28
  constructor({ chainId }: { chainId: ChainId }) {
62
29
  super({
63
- logger: new Logger("InteropXGateway::ProcessWithdrawEvents"),
30
+ logger: new Logger("InteropXContract::ProccessBridgeRequestEvents"),
64
31
  })
65
32
  this.chainId = chainId;
66
33
  }
@@ -71,19 +38,17 @@ class ProcessWithdrawEvents extends BaseTask {
71
38
  const transaction = await Transaction.findOne({
72
39
  where: {
73
40
  status: 'pending',
74
- sourceStatus: 'success',
75
- targetStatus: 'uninitialised',
76
- action: 'withdraw',
77
- sourceCreatedAt: {
41
+ sourceStatus: 'uninitialised',
42
+ createdAt: {
78
43
  [Op.gte]: new Date(Date.now() - 12 * 60 * 60 * 1000),
79
44
  },
80
- targetDelayUntil: {
45
+ sourceDelayUntil: {
81
46
  [Op.or]: {
82
47
  [Op.is]: null,
83
48
  [Op.lt]: new Date(),
84
49
  }
85
50
  },
86
- sourceBlockNumber: {
51
+ requestBlockNumber: {
87
52
  [Op.lt]: blockNumber - 12,
88
53
  },
89
54
  sourceChainId: this.chainId,
@@ -95,52 +60,53 @@ class ProcessWithdrawEvents extends BaseTask {
95
60
  }
96
61
 
97
62
  console.log(`Processing transaction ${transaction.transactionHash}`);
98
-
63
+
99
64
  transaction.targetStatus = 'pending';
100
65
  await transaction.save();
101
66
 
102
- // refresh event data?
67
+ const ownersThreshold = await this.safeContract.getThreshold();
68
+ await wait(10000);
103
69
 
104
- const targetChainProvider = new ethers.providers.JsonRpcProvider(
105
- getRpcProviderUrl(transaction.targetChainId as ChainId)
106
- );
107
70
 
108
- const targetWallet = new ethers.Wallet(config.privateKey!, targetChainProvider);
71
+ let data, logs = [];
109
72
 
110
- const safeAddress = addresses[transaction.targetChainId].gnosisSafe;
73
+ try {
74
+ ({ data, logs } = await buildGnosisAction(transaction, 'source'));
111
75
 
76
+ } catch (error) {
77
+ console.log(error);
78
+ transaction.sourceStatus = 'failed';
79
+ transaction.sourceErrors = [error.message];
80
+ transaction.targetStatus = 'failed';
112
81
 
113
- const safeContract = getContract<GnosisSafe>(
114
- safeAddress,
115
- abi.gnosisSafe,
116
- targetWallet
117
- )
118
-
119
- const ownersThreshold = await safeContract.getThreshold();
120
- await wait(10000);
82
+ transaction.status = 'failed'
83
+ await transaction.save();
84
+ protocol.sendTransaction(transaction)
85
+ return;
86
+ }
121
87
 
122
88
  let gnosisTx = await generateGnosisTransaction({
123
89
  baseGas: "0",
124
- data: await buildDataForTransaction(transaction),
90
+ data,
125
91
  gasPrice: "0",
126
92
  gasToken: "0x0000000000000000000000000000000000000000",
127
93
  nonce: '0',
128
94
  operation: "1",
129
95
  refundReceiver: "0x0000000000000000000000000000000000000000",
130
- safeAddress: safeAddress,
96
+ safeAddress: this.safeContractAddress,
131
97
  safeTxGas: "79668",
132
- to: addresses[transaction.targetChainId].multisend,
98
+ to: addresses[transaction.sourceChainId].multisend,
133
99
  value: "0",
134
- }, safeContract);
100
+ }, this.safeContract);
135
101
 
136
- const owners = await safeContract.getOwners().then(owners => owners.map(owner => owner.toLowerCase()));
102
+ const owners = await this.safeContract.getOwners().then(owners => owners.map(owner => owner.toLowerCase()));
137
103
 
138
104
  const ownerPeerIds = peerPool.activePeers.filter(peer => owners.includes(peer.publicAddress.toLowerCase())).map(peer => peer.id)
139
105
 
140
106
  console.log(`Collecting signatures for execution ${transaction.transactionHash}`)
141
107
 
142
108
  console.log(ownerPeerIds);
143
-
109
+
144
110
  const signatures = await protocol.requestSignatures({
145
111
  type: 'source',
146
112
  transactionHash: transaction.transactionHash,
@@ -155,18 +121,17 @@ class ProcessWithdrawEvents extends BaseTask {
155
121
 
156
122
  if (validSignatures.length === 0 || ownersThreshold.gt(validSignatures.length)) {
157
123
  await transaction.save();
158
- transaction.targetDelayUntil = new Date(Date.now() + 30 * 1000);
159
- transaction.targetStatus = 'uninitialised'
124
+ transaction.sourceDelayUntil = new Date(Date.now() + 30 * 1000);
125
+ transaction.sourceStatus = 'uninitialised'
160
126
 
161
127
  await transaction.save();
162
128
  const errorMessage = signatures.find(s => !!s.error)?.error;
163
129
  throw new Error(`Not enough signatures` + (errorMessage ? `: ${errorMessage}` : ''));
164
130
  }
165
131
 
166
-
167
132
  console.log(`Executing transaction for execution ${transaction.transactionHash}`)
168
133
 
169
- const { data: txData } = await safeContract.populateTransaction.execTransaction(
134
+ const { data: txData } = await this.safeContract.populateTransaction.execTransaction(
170
135
  gnosisTx.to,
171
136
  gnosisTx.value,
172
137
  gnosisTx.data,
@@ -179,20 +144,15 @@ class ProcessWithdrawEvents extends BaseTask {
179
144
  buildSignatureBytes(validSignatures)
180
145
  );
181
146
 
182
- console.log({
183
- from: targetWallet.address,
184
- gasPrice: BigNumber.from(120 * 10 ** 9).toString(),
185
- to: safeAddress,
147
+ const txSent = await this.sourceWallet.sendTransaction({
148
+ from: this.sourceWallet.address,
149
+ gasPrice: ethers.BigNumber.from(120 * 10 ** 9),
150
+ to: this.safeContractAddress,
186
151
  data: txData,
187
152
  })
188
153
 
154
+ console.log(txSent);
189
155
 
190
- const txSent = await targetWallet.sendTransaction({
191
- from: targetWallet.address,
192
- gasPrice: BigNumber.from(120 * 10 ** 9),
193
- to: safeAddress,
194
- data: txData,
195
- })
196
156
 
197
157
  const receipt = await txSent.wait();
198
158
 
@@ -200,34 +160,57 @@ class ProcessWithdrawEvents extends BaseTask {
200
160
 
201
161
  receipt.logs.forEach((log) => {
202
162
  try {
203
- parsedLogs.push(safeContract.interface.parseLog(log));
163
+ parsedLogs.push(this.safeContract.interface.parseLog(log));
204
164
  } catch (e) { }
205
165
  });
206
166
 
207
167
  if (parsedLogs.find(e => e.name === 'ExecutionSuccess')) {
208
168
  console.log('ExecutionSuccess')
209
- transaction.targetStatus = 'success'
210
- transaction.targetTransactionHash = txSent.hash
169
+ transaction.sourceStatus = 'success'
170
+ if (txSent.blockNumber)
171
+ transaction.sourceBlockNumber = txSent.blockNumber;
172
+ transaction.sourceTransactionHash = txSent.hash
173
+ transaction.sourceLogs = logs;
211
174
  transaction.status = 'success'
212
175
  await transaction.save();
213
176
  } else {
214
177
  console.log('ExecutionFailure')
215
- transaction.targetStatus = 'failed'
216
- transaction.targetTransactionHash = txSent.hash
178
+ transaction.sourceStatus = 'failed'
179
+ if (txSent.blockNumber)
180
+ transaction.sourceBlockNumber = txSent.blockNumber;
181
+ transaction.sourceTransactionHash = txSent.hash
182
+ transaction.sourceTransactionHash = txSent.hash
217
183
  transaction.status = 'failed'
218
184
  await transaction.save();
219
185
  }
186
+
187
+ protocol.sendTransaction(transaction)
220
188
  }
221
189
 
222
190
  async start(): Promise<void> {
223
- this.logger.info(`Starting execution watcher on interop chain`);
191
+ this.contractAddress = addresses[this.chainId].interopXContract;
224
192
 
225
193
  this.provider = new ethers.providers.JsonRpcProvider(
226
194
  getRpcProviderUrl(this.chainId)
227
195
  );
228
196
 
197
+ this.sourceWallet = new ethers.Wallet(config.privateKey!, this.provider);
198
+
199
+ this.contract = getContract<InteropXContract>(
200
+ this.contractAddress,
201
+ abi.interopXContract,
202
+ this.sourceWallet
203
+ );
204
+
205
+ this.safeContractAddress = addresses[this.chainId].gnosisSafe;
206
+ this.safeContract = getContract<GnosisSafe>(
207
+ this.safeContractAddress,
208
+ abi.gnosisSafe,
209
+ this.sourceWallet
210
+ );
211
+
229
212
  await super.start()
230
213
  }
231
214
  }
232
215
 
233
- export default ProcessWithdrawEvents;
216
+ export default ProccessBridgeRequestEvents;
@@ -0,0 +1,116 @@
1
+ import { BaseTask } from "../BaseTask";
2
+ import Logger from '@/logger';
3
+ import { ethers } from "ethers";
4
+ import abi from "@/abi";
5
+ import { Transaction } from "@/db";
6
+ import { generateInteropTransactionHash, getContract, getRpcProviderUrl } from "@/utils";
7
+ import { addresses } from "@/constants";
8
+ import { ChainId } from "@/types";
9
+ import config from "@/config";
10
+ import { InteropXContract } from "@/typechain";
11
+
12
+ class SyncBridgeRequestEvents extends BaseTask {
13
+ contractAddress: string;
14
+ provider: ethers.providers.JsonRpcProvider;
15
+ contract: InteropXContract;
16
+ chainId: ChainId;
17
+
18
+ constructor({ chainId }: { chainId: ChainId }) {
19
+ super({
20
+ logger: new Logger("InteropXContract::SyncBridgeRequestEvents"),
21
+ })
22
+ this.chainId = chainId;
23
+ }
24
+
25
+ async pollHandler() {
26
+ const currentBlock = await this.provider.getBlockNumber();
27
+
28
+ const events = await this.contract.queryFilter(
29
+ this.contract.filters.LogBridgeRequest(),
30
+ currentBlock - 2000,
31
+ currentBlock,
32
+ );
33
+
34
+ let processedEvents = 0;
35
+
36
+ for (const event of events) {
37
+
38
+ try {
39
+ if (!event.args) {
40
+ continue;
41
+ }
42
+
43
+ const { bridger, position, sourceChainId, targetChainId, metadata } = event.args;
44
+
45
+ const uniqueIdentifier = {
46
+ action: 'withdraw', //todo
47
+ bridger,
48
+ requestTransactionHash: event.transactionHash,
49
+ sourceChainId: sourceChainId.toNumber(),
50
+ targetChainId: targetChainId.toNumber(),
51
+ }
52
+
53
+ let transactionHash = generateInteropTransactionHash(uniqueIdentifier);
54
+
55
+ const transaction = await Transaction.findOne({ where: { transactionHash } });
56
+
57
+ if (transaction) {
58
+ continue;
59
+ }
60
+
61
+ await Transaction.create({
62
+ transactionHash,
63
+ ...uniqueIdentifier,
64
+ position,
65
+ metadata,
66
+ requestBlockNumber: event.blockNumber,
67
+ requestEvent: {
68
+ bridger,
69
+ position: {
70
+ withdraw: position.withdraw.map((v) => ({
71
+ sourceToken: v.sourceToken,
72
+ targetToken: v.targetToken,
73
+ amount: v.amount.toString()
74
+ })),
75
+ supply: position.supply.map((v) => ({
76
+ sourceToken: v.sourceToken,
77
+ targetToken: v.targetToken,
78
+ amount: v.amount.toString()
79
+ })),
80
+ },
81
+ sourceChainId: sourceChainId.toNumber(),
82
+ targetChainId: targetChainId.toNumber(),
83
+ metadata,
84
+ }
85
+ })
86
+
87
+ this.logger.info(
88
+ `New bridge request received: ${transactionHash} `
89
+ );
90
+ } catch (error) {
91
+ this.logger.error(error);
92
+ }
93
+ }
94
+
95
+ if (processedEvents > 0)
96
+ this.logger.info(`${processedEvents} events processed`);
97
+ }
98
+
99
+ async start(): Promise<void> {
100
+ this.contractAddress = addresses[this.chainId].interopXContract;
101
+
102
+ this.provider = new ethers.providers.JsonRpcProvider(
103
+ getRpcProviderUrl(this.chainId)
104
+ );
105
+
106
+ this.contract = getContract<InteropXContract>(
107
+ this.contractAddress,
108
+ abi.interopXContract,
109
+ new ethers.Wallet(config.privateKey!, this.provider)
110
+ );
111
+
112
+ await super.start()
113
+ }
114
+ }
115
+
116
+ export default SyncBridgeRequestEvents;
@@ -0,0 +1,120 @@
1
+ import { BaseTask } from "../BaseTask";
2
+ import Logger from '@/logger';
3
+ import { ethers } from "ethers";
4
+ import abi from "@/abi";
5
+ import { Transaction } from "@/db";
6
+ import { generateInteropTransactionHash, getContract, getRpcProviderUrl } from "@/utils";
7
+ import { addresses } from "@/constants";
8
+ import { ChainId } from "@/types";
9
+ import config from "@/config";
10
+ import { InteropXContract } from "@/typechain";
11
+ import { Op } from "sequelize";
12
+
13
+ class SyncBridgeRequestSentEvents extends BaseTask {
14
+ contractAddress: string;
15
+ provider: ethers.providers.JsonRpcProvider;
16
+ contract: InteropXContract;
17
+ chainId: ChainId;
18
+
19
+ constructor({ chainId }: { chainId: ChainId }) {
20
+ super({
21
+ logger: new Logger("InteropXContract::SyncBridgeRequestSentEvents"),
22
+ })
23
+ this.chainId = chainId;
24
+ }
25
+
26
+ async pollHandler() {
27
+ const currentBlock = await this.provider.getBlockNumber();
28
+
29
+ const events = await this.contract.queryFilter(
30
+ this.contract.filters.LogBridgeRequestSent(),
31
+ currentBlock - 2000,
32
+ currentBlock,
33
+ );
34
+
35
+ let processedEvents = 0;
36
+
37
+ for (const event of events) {
38
+
39
+ try {
40
+ if (!event.args) {
41
+ continue;
42
+ }
43
+
44
+ const { bridger, position, sourceChainId, targetChainId, requestTransactionHash, metadata } = event.args;
45
+
46
+ const uniqueIdentifier = {
47
+ action: 'withdraw',
48
+ bridger,
49
+ requestTransactionHash,
50
+ sourceChainId: sourceChainId,
51
+ targetChainId: targetChainId,
52
+ }
53
+
54
+ let transactionHash = generateInteropTransactionHash(uniqueIdentifier);
55
+
56
+ const transaction = await Transaction.findOne({
57
+ where: {
58
+ transactionHash, sourceStatus: {
59
+ [Op.ne]: 'success',
60
+ }
61
+ }
62
+ });
63
+
64
+ if (!transaction) {
65
+ continue;
66
+ }
67
+ transaction.sourceStatus = 'success'
68
+ transaction.sourceBlockNumber = event.blockNumber;
69
+ transaction.sourceTransactionHash = event.transactionHash
70
+ transaction.requestSentEvent = {
71
+ bridger,
72
+ position: {
73
+ withdraw: position.withdraw.map((v) => ({
74
+ sourceToken: v.sourceToken,
75
+ targetToken: v.targetToken,
76
+ amount: v.amount.toString()
77
+ })),
78
+ supply: position.supply.map((v) => ({
79
+ sourceToken: v.sourceToken,
80
+ targetToken: v.targetToken,
81
+ amount: v.amount.toString()
82
+ })),
83
+ },
84
+ sourceChainId: sourceChainId,
85
+ targetChainId: targetChainId,
86
+ metadata,
87
+ requestTransactionHash,
88
+ }
89
+ await transaction.save()
90
+
91
+ this.logger.info(
92
+ `New bridge request sent received: ${transactionHash} `
93
+ );
94
+ } catch (error) {
95
+ this.logger.error(error);
96
+ }
97
+ }
98
+
99
+ if (processedEvents > 0)
100
+ this.logger.info(`${processedEvents} events processed`);
101
+ }
102
+
103
+ async start(): Promise<void> {
104
+ this.contractAddress = addresses[this.chainId].interopXContract;
105
+
106
+ this.provider = new ethers.providers.JsonRpcProvider(
107
+ getRpcProviderUrl(this.chainId)
108
+ );
109
+
110
+ this.contract = getContract<InteropXContract>(
111
+ this.contractAddress,
112
+ abi.interopXContract,
113
+ new ethers.Wallet(config.privateKey!, this.provider)
114
+ );
115
+
116
+ await super.start()
117
+ }
118
+ }
119
+
120
+ export default SyncBridgeRequestSentEvents;