@instadapp/interop-x 0.0.0-dev.9b1fcb8 → 0.0.0-dev.9b26e43

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