@instadapp/interop-x 0.0.0-dev.1abc1ca → 0.0.0-dev.285d847

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 (34) hide show
  1. package/bin/interop-x +1 -1
  2. package/dist/package.json +6 -3
  3. package/dist/src/config/index.js +1 -0
  4. package/dist/src/constants/itokens.js +1 -1
  5. package/dist/src/index.js +39 -5
  6. package/dist/src/net/peer/index.js +6 -2
  7. package/dist/src/net/pool/index.js +27 -9
  8. package/dist/src/net/protocol/dial/SignatureDialProtocol.js +11 -4
  9. package/dist/src/net/protocol/index.js +30 -1
  10. package/dist/src/tasks/AutoUpdateTask.js +44 -0
  11. package/dist/src/tasks/BaseTask.js +1 -1
  12. package/dist/src/tasks/InteropBridge/ProcessWithdrawEvents.js +147 -0
  13. package/dist/src/tasks/InteropBridge/SyncWithdrawEvents.js +70 -0
  14. package/dist/src/tasks/InteropXGateway/ProcessDepositEvents.js +32 -22
  15. package/dist/src/tasks/InteropXGateway/SyncDepositEvents.js +4 -4
  16. package/dist/src/tasks/index.js +15 -0
  17. package/dist/src/utils/index.js +98 -7
  18. package/package.json +6 -3
  19. package/patches/@ethersproject+properties+5.6.0.patch +13 -0
  20. package/src/config/index.ts +2 -0
  21. package/src/constants/itokens.ts +1 -1
  22. package/src/index.ts +47 -6
  23. package/src/net/peer/index.ts +7 -6
  24. package/src/net/pool/index.ts +37 -11
  25. package/src/net/protocol/dial/SignatureDialProtocol.ts +12 -4
  26. package/src/net/protocol/index.ts +45 -1
  27. package/src/tasks/AutoUpdateTask.ts +54 -0
  28. package/src/tasks/BaseTask.ts +1 -1
  29. package/src/tasks/InteropBridge/ProcessWithdrawEvents.ts +233 -0
  30. package/src/tasks/InteropBridge/SyncWithdrawEvents.ts +121 -0
  31. package/src/tasks/InteropXGateway/ProcessDepositEvents.ts +44 -31
  32. package/src/tasks/InteropXGateway/SyncDepositEvents.ts +6 -6
  33. package/src/tasks/index.ts +22 -2
  34. package/src/utils/index.ts +131 -9
@@ -5,6 +5,7 @@ import { SignatureDialProtocol, ISignatureRequest, ISignatureResponse } from "./
5
5
  import { IPeerInfo, peerPool } from "..";
6
6
  import config from "@/config";
7
7
  import { Event } from "@/types";
8
+ import { Transaction } from "@/db";
8
9
 
9
10
  export interface ProtocolOptions {
10
11
  /* Handshake timeout in ms (default: 8000) */
@@ -33,7 +34,12 @@ interface PeerInfoEvent extends BaseMessageEvent {
33
34
  data: Omit<IPeerInfo, 'id' | 'updated' | 'idle' | 'pooled'>
34
35
  }
35
36
 
37
+ interface TransactionStatusEvent extends BaseMessageEvent {
38
+ data: Pick<Transaction, 'transactionHash' | 'sourceStatus' | 'sourceTransactionHash' | 'sourceErrors' | 'targetStatus' | 'targetTransactionHash' | 'targetErrors' | 'status'>
39
+ }
40
+
36
41
  declare interface Protocol {
42
+ on(event: 'TransactionStatus', listener: (payload: TransactionStatusEvent) => void): this;
37
43
  on(event: 'PeerInfo', listener: (payload: PeerInfoEvent) => void): this;
38
44
  on(event: string, listener: (payload: BaseMessageEvent) => void): this;
39
45
  }
@@ -44,7 +50,7 @@ class Protocol extends EventEmitter {
44
50
  private protocolMessages: Message[] = [
45
51
  {
46
52
  name: 'PeerInfo',
47
- code: 0x09,
53
+ code: 0x01,
48
54
  encode: (info: Pick<IPeerInfo, 'publicAddress'>) => [
49
55
  Buffer.from(info.publicAddress),
50
56
  ],
@@ -52,6 +58,36 @@ class Protocol extends EventEmitter {
52
58
  publicAddress: publicAddress.toString(),
53
59
  }),
54
60
  },
61
+ {
62
+ name: 'TransactionStatus',
63
+ code: 0x02,
64
+ encode: (transaction: Transaction) => [
65
+ Buffer.from(transaction.transactionHash),
66
+
67
+ Buffer.from(transaction.sourceStatus),
68
+ Buffer.from(transaction.sourceTransactionHash),
69
+ transaction.sourceErrors ? transaction.sourceErrors.map((e) => Buffer.from(e)) : [],
70
+
71
+ Buffer.from(transaction.targetStatus),
72
+ Buffer.from(transaction.targetTransactionHash),
73
+ transaction.targetErrors ? transaction.targetErrors.map((e) => Buffer.from(e)) : [],
74
+
75
+ Buffer.from(transaction.status),
76
+ ],
77
+ decode: ([transactionHash, sourceStatus, sourceTransactionHash, sourceErrors, targetStatus, targetTransactionHash, targetErrors, status]: [Buffer, Buffer, Buffer, Buffer[], Buffer, Buffer, Buffer[], Buffer]) => ({
78
+ transactionHash: transactionHash.toString(),
79
+
80
+ sourceStatus: sourceStatus.toString(),
81
+ sourceTransactionHash: sourceTransactionHash.toString(),
82
+ sourceErrors: sourceErrors.map((e) => e.toString()),
83
+
84
+ targetStatus: targetStatus.toString(),
85
+ targetTransactionHash: targetTransactionHash.toString(),
86
+ targetErrors: targetErrors.map((e) => e.toString()),
87
+
88
+ status: status.toString(),
89
+ }),
90
+ },
55
91
  ];
56
92
  private signature: SignatureDialProtocol;
57
93
 
@@ -121,6 +157,14 @@ class Protocol extends EventEmitter {
121
157
  this.libp2p.pubsub.publish(this.topic, encoded)
122
158
  }
123
159
 
160
+ public sendTransaction(transaction: Transaction) {
161
+ const message = this.protocolMessages.find((m) => m.name === 'TransactionStatus')!
162
+
163
+ const encoded = rlp.encode([message.code, message.encode(transaction)]);
164
+
165
+ this.libp2p.pubsub.publish(this.topic, encoded)
166
+ }
167
+
124
168
  async requestSignatures(data: ISignatureRequest, peerIds?: string[]) {
125
169
  try {
126
170
  peerIds = peerIds || peerPool.activePeerIds;
@@ -0,0 +1,54 @@
1
+ import { BaseTask } from "./BaseTask";
2
+ import Logger from '@/logger';
3
+ import packageJson from '../../package.json'
4
+ import { http } from "@/utils";
5
+ import { spawn } from 'child_process';
6
+ import config from "@/config";
7
+ const currentVersion = packageJson.version;
8
+
9
+ class AutoUpdateTask extends BaseTask {
10
+ pollIntervalMs: number = 60 * 1000
11
+
12
+ constructor() {
13
+ super({
14
+ logger: new Logger("AutoUpdateTask"),
15
+ })
16
+ }
17
+
18
+
19
+ prePollHandler(): boolean {
20
+ return config.autoUpdate && !config.isLeadNode();
21
+ }
22
+
23
+ async pollHandler() {
24
+
25
+ const { data } = await http.get('https://registry.npmjs.org/@instadapp/interop-x')
26
+
27
+ const version = data['dist-tags'].latest
28
+
29
+ if (version === currentVersion) {
30
+ return;
31
+ }
32
+
33
+ this.logger.warn(`New version ${version} available.`)
34
+
35
+
36
+ const update = spawn('npm', ['-g', 'install', '@instadapp/interop-x']);
37
+
38
+ update.on("close", () => {
39
+ this.logger.warn(`Installed version ${version}`)
40
+ this.logger.warn(`Restarting...`)
41
+
42
+ spawn(process.argv[0], process.argv.slice(1), {
43
+ cwd: process.cwd(),
44
+ env: Object.create(process.env),
45
+ detached: true,
46
+ stdio: "inherit"
47
+ });
48
+
49
+ process.exit()
50
+ })
51
+ }
52
+ }
53
+
54
+ export default AutoUpdateTask;
@@ -37,7 +37,7 @@ export class BaseTask extends EventEmitter implements IBaseTask {
37
37
  await this.pollHandler()
38
38
  }
39
39
  } catch (err) {
40
- this.logger.error(`poll check error: ${err.message}\ntrace: ${err.stack}`)
40
+ this.logger.error(`poll check error:\n${err.message}\ntrace: ${err.stack}`)
41
41
  }
42
42
 
43
43
  await this.postPollHandler()
@@ -0,0 +1,233 @@
1
+ import { BaseTask } from "../BaseTask";
2
+ import Logger from '@/logger';
3
+ import { BigNumber, ethers } from "ethers";
4
+ import abi from "@/abi";
5
+ import { Transaction } from "@/db";
6
+ import { buildDataForTransaction, buildSignatureBytes, getContract, getRpcProviderUrl, Signature } from "@/utils";
7
+ import { addresses } from "@/constants";
8
+ import { ChainId } from "@/types";
9
+ import config from "@/config";
10
+ import { GnosisSafe, InteropXGateway } from "@/typechain";
11
+ import { Op } from "sequelize";
12
+ import wait from "waait";
13
+ import { peerPool, protocol } from "@/net";
14
+ import { LogDescription } from "ethers/lib/utils";
15
+
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 {
57
+ provider: ethers.providers.JsonRpcProvider;
58
+ chainId: ChainId;
59
+ leadNodeOnly = true
60
+
61
+ constructor({ chainId }: { chainId: ChainId }) {
62
+ super({
63
+ logger: new Logger("InteropXGateway::ProcessWithdrawEvents"),
64
+ })
65
+ this.chainId = chainId;
66
+ }
67
+
68
+ async pollHandler() {
69
+ const blockNumber = await this.provider.getBlockNumber()
70
+
71
+ const transaction = await Transaction.findOne({
72
+ where: {
73
+ status: 'pending',
74
+ sourceStatus: 'success',
75
+ targetStatus: 'uninitialised',
76
+ action: 'withdraw',
77
+ sourceCreatedAt: {
78
+ [Op.gte]: new Date(Date.now() - 12 * 60 * 60 * 1000),
79
+ },
80
+ targetDelayUntil: {
81
+ [Op.or]: {
82
+ [Op.is]: null,
83
+ [Op.lt]: new Date(),
84
+ }
85
+ },
86
+ sourceBlockNumber: {
87
+ [Op.lt]: blockNumber - 12,
88
+ },
89
+ sourceChainId: this.chainId,
90
+ }
91
+ })
92
+
93
+ if (!transaction) {
94
+ return;
95
+ }
96
+
97
+ console.log(`Processing transaction ${transaction.transactionHash}`);
98
+
99
+ transaction.targetStatus = 'pending';
100
+ await transaction.save();
101
+
102
+ // refresh event data?
103
+
104
+ const targetChainProvider = new ethers.providers.JsonRpcProvider(
105
+ getRpcProviderUrl(transaction.targetChainId as ChainId)
106
+ );
107
+
108
+ const targetWallet = new ethers.Wallet(config.privateKey!, targetChainProvider);
109
+
110
+ const safeAddress = addresses[transaction.targetChainId].gnosisSafe;
111
+
112
+
113
+ const safeContract = getContract<GnosisSafe>(
114
+ safeAddress,
115
+ abi.gnosisSafe,
116
+ targetWallet
117
+ )
118
+
119
+ const ownersThreshold = await safeContract.getThreshold();
120
+ await wait(10000);
121
+
122
+ let gnosisTx = await generateGnosisTransaction({
123
+ baseGas: "0",
124
+ data: await buildDataForTransaction(transaction),
125
+ gasPrice: "0",
126
+ gasToken: "0x0000000000000000000000000000000000000000",
127
+ nonce: '0',
128
+ operation: "1",
129
+ refundReceiver: "0x0000000000000000000000000000000000000000",
130
+ safeAddress: safeAddress,
131
+ safeTxGas: "79668",
132
+ to: addresses[transaction.targetChainId].multisend,
133
+ value: "0",
134
+ }, safeContract);
135
+
136
+ const owners = await safeContract.getOwners().then(owners => owners.map(owner => owner.toLowerCase()));
137
+
138
+ const ownerPeerIds = peerPool.activePeers.filter(peer => owners.includes(peer.publicAddress.toLowerCase())).map(peer => peer.id)
139
+
140
+ console.log(`Collecting signatures for execution ${transaction.transactionHash}`)
141
+
142
+ console.log(ownerPeerIds);
143
+
144
+ const signatures = await protocol.requestSignatures({
145
+ type: 'source',
146
+ transactionHash: transaction.transactionHash,
147
+ safeTxGas: gnosisTx.safeTxGas,
148
+ safeNonce: gnosisTx.nonce
149
+ }, ownerPeerIds)
150
+
151
+
152
+ const validSignatures = signatures.filter(s => !!s.data && s.data !== '0x') as Signature[];
153
+
154
+ console.log({ signatures, validSignatures, ownersThreshold: ownersThreshold.toString() });
155
+
156
+ if (validSignatures.length === 0 || ownersThreshold.gt(validSignatures.length)) {
157
+ await transaction.save();
158
+ transaction.targetDelayUntil = new Date(Date.now() + 30 * 1000);
159
+ transaction.targetStatus = 'uninitialised'
160
+
161
+ await transaction.save();
162
+ const errorMessage = signatures.find(s => !!s.error)?.error;
163
+ throw new Error(`Not enough signatures` + (errorMessage ? `: ${errorMessage}` : ''));
164
+ }
165
+
166
+
167
+ console.log(`Executing transaction for execution ${transaction.transactionHash}`)
168
+
169
+ const { data: txData } = await safeContract.populateTransaction.execTransaction(
170
+ gnosisTx.to,
171
+ gnosisTx.value,
172
+ gnosisTx.data,
173
+ gnosisTx.operation,
174
+ gnosisTx.safeTxGas,
175
+ gnosisTx.baseGas,
176
+ gnosisTx.gasPrice,
177
+ gnosisTx.gasToken,
178
+ gnosisTx.refundReceiver,
179
+ buildSignatureBytes(validSignatures)
180
+ );
181
+
182
+ console.log({
183
+ from: targetWallet.address,
184
+ gasPrice: BigNumber.from(120 * 10 ** 9).toString(),
185
+ to: safeAddress,
186
+ data: txData,
187
+ })
188
+
189
+
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
+
197
+ const receipt = await txSent.wait();
198
+
199
+ const parsedLogs: LogDescription[] = [];
200
+
201
+ receipt.logs.forEach((log) => {
202
+ try {
203
+ parsedLogs.push(safeContract.interface.parseLog(log));
204
+ } catch (e) { }
205
+ });
206
+
207
+ if (parsedLogs.find(e => e.name === 'ExecutionSuccess')) {
208
+ console.log('ExecutionSuccess')
209
+ transaction.targetStatus = 'success'
210
+ transaction.targetTransactionHash = txSent.hash
211
+ transaction.status = 'success'
212
+ await transaction.save();
213
+ } else {
214
+ console.log('ExecutionFailure')
215
+ transaction.targetStatus = 'failed'
216
+ transaction.targetTransactionHash = txSent.hash
217
+ transaction.status = 'failed'
218
+ await transaction.save();
219
+ }
220
+ }
221
+
222
+ async start(): Promise<void> {
223
+ this.logger.info(`Starting execution watcher on interop chain`);
224
+
225
+ this.provider = new ethers.providers.JsonRpcProvider(
226
+ getRpcProviderUrl(this.chainId)
227
+ );
228
+
229
+ await super.start()
230
+ }
231
+ }
232
+
233
+ export default ProcessWithdrawEvents;
@@ -0,0 +1,121 @@
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 { ChainId } from "@/types";
8
+ import config from "@/config";
9
+ import { InteropBridgeToken } from "@/typechain";
10
+
11
+ class SyncWithdrawEvents extends BaseTask {
12
+ contractAddress: string;
13
+ provider: ethers.providers.JsonRpcProvider;
14
+ contract: InteropBridgeToken;
15
+ chainId: ChainId;
16
+ itokenAddress: string;
17
+
18
+ constructor({ chainId, itokenAddress }: { chainId: ChainId, itokenAddress: string }) {
19
+ super({
20
+ logger: new Logger("InteropBridgeToken::SyncWithdrawEvents"),
21
+ })
22
+ this.chainId = chainId;
23
+ this.itokenAddress = itokenAddress;
24
+ }
25
+
26
+ async pollHandler() {
27
+ const currentBlock = await this.provider.getBlockNumber();
28
+
29
+ const events = await this.contract.queryFilter(
30
+ this.contract.filters.Burn(),
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 { to, amount, chainId } = event.args;
45
+
46
+ const uniqueIdentifier = {
47
+ action: 'withdraw',
48
+ submitTransactionHash: event.transactionHash,
49
+ sourceChainId:this.chainId,
50
+ targetChainId: chainId.toNumber(),
51
+ }
52
+
53
+ if (await Transaction.findOne({ where: uniqueIdentifier })) {
54
+ continue;
55
+ }
56
+
57
+ const tx = await event.getTransaction()
58
+
59
+ await Transaction.create({
60
+ ...uniqueIdentifier,
61
+ transactionHash: generateInteropTransactionHash(uniqueIdentifier),
62
+ from: tx.from,
63
+ to,
64
+
65
+
66
+ submitTransactionHash: event.transactionHash,
67
+ submitBlockNumber: event.blockNumber,
68
+
69
+ // submit & source are the same
70
+ sourceTransactionHash: event.transactionHash,
71
+ sourceBlockNumber: event.blockNumber,
72
+ sourceStatus: "success",
73
+
74
+ targetStatus: "uninitialised",
75
+
76
+ submitEvent: {
77
+ to,
78
+ amount: amount.toString(),
79
+ itoken: this.itokenAddress,
80
+ chainId: chainId.toString()
81
+ },
82
+
83
+ sourceEvent: {
84
+ to,
85
+ amount: amount.toString(),
86
+ itoken: this.itokenAddress,
87
+ chainId: chainId.toString(),
88
+ },
89
+ status: "pending",
90
+ })
91
+
92
+ this.logger.info(
93
+ `Withdraw queued: ${event.transactionHash} ${event.blockNumber}`
94
+ );
95
+ } catch (error) {
96
+ this.logger.error(error);
97
+ }
98
+ }
99
+
100
+ if (processedEvents > 0)
101
+ this.logger.info(`${processedEvents} events processed`);
102
+ }
103
+
104
+ async start(): Promise<void> {
105
+ this.logger.info(`Starting execution watcher on interop chain`);
106
+
107
+ this.provider = new ethers.providers.JsonRpcProvider(
108
+ getRpcProviderUrl(this.chainId)
109
+ );
110
+
111
+ this.contract = getContract<InteropBridgeToken>(
112
+ this.itokenAddress,
113
+ abi.interopBridgeToken,
114
+ new ethers.Wallet(config.privateKey!, this.provider)
115
+ );
116
+
117
+ await super.start()
118
+ }
119
+ }
120
+
121
+ export default SyncWithdrawEvents;
@@ -3,7 +3,7 @@ import Logger from '@/logger';
3
3
  import { BigNumber, ethers } from "ethers";
4
4
  import abi from "@/abi";
5
5
  import { Transaction } from "@/db";
6
- import { buildDataForTransaction, buildSignatureBytes, getRpcProviderUrl, Signature } from "@/utils";
6
+ import { buildDataForTransaction, buildSignatureBytes, getContract, getRpcProviderUrl, Signature } from "@/utils";
7
7
  import { addresses } from "@/constants";
8
8
  import { ChainId } from "@/types";
9
9
  import config from "@/config";
@@ -13,7 +13,9 @@ import wait from "waait";
13
13
  import { peerPool, protocol } from "@/net";
14
14
  import { LogDescription } from "ethers/lib/utils";
15
15
 
16
- const generateGnosisTransaction = async (transactionData: any, safeContract: any) => {
16
+ const generateGnosisTransaction = async (transactionData: any, safeContract: GnosisSafe) => {
17
+ console.log(transactionData);
18
+
17
19
  let isExecuted = await safeContract.dataHashes(
18
20
  await safeContract.getTransactionHash(
19
21
  transactionData.to,
@@ -72,13 +74,21 @@ class ProcessDepositEvents extends BaseTask {
72
74
  where: {
73
75
  status: 'pending',
74
76
  sourceStatus: 'success',
77
+ targetStatus: 'uninitialised',
75
78
  action: 'deposit',
76
79
  sourceCreatedAt: {
77
80
  [Op.gte]: new Date(Date.now() - 12 * 60 * 60 * 1000),
78
81
  },
82
+ targetDelayUntil: {
83
+ [Op.or]: {
84
+ [Op.is]: null,
85
+ [Op.lt]: new Date(),
86
+ }
87
+ },
79
88
  sourceBlockNumber: {
80
89
  [Op.lt]: blockNumber - 12,
81
- }
90
+ },
91
+ sourceChainId: this.chainId,
82
92
  }
83
93
  })
84
94
 
@@ -86,11 +96,11 @@ class ProcessDepositEvents extends BaseTask {
86
96
  return;
87
97
  }
88
98
 
89
-
90
- transaction.sourceStatus = 'pending';
99
+ console.log(`Processing transaction ${transaction.transactionHash}`);
100
+
101
+ transaction.targetStatus = 'pending';
91
102
  await transaction.save();
92
103
 
93
-
94
104
  // refresh event data?
95
105
 
96
106
  const targetChainProvider = new ethers.providers.JsonRpcProvider(
@@ -101,19 +111,19 @@ class ProcessDepositEvents extends BaseTask {
101
111
 
102
112
  const safeAddress = addresses[transaction.targetChainId].gnosisSafe;
103
113
 
104
- const safeContract = new ethers.Contract(
114
+
115
+ const safeContract = getContract<GnosisSafe>(
105
116
  safeAddress,
106
117
  abi.gnosisSafe,
107
118
  targetWallet
108
- ) as GnosisSafe;
119
+ )
109
120
 
110
121
  const ownersThreshold = await safeContract.getThreshold();
111
-
112
122
  await wait(10000);
113
123
 
114
124
  let gnosisTx = await generateGnosisTransaction({
115
125
  baseGas: "0",
116
- data: buildDataForTransaction(transaction),
126
+ data: await buildDataForTransaction(transaction),
117
127
  gasPrice: "0",
118
128
  gasToken: "0x0000000000000000000000000000000000000000",
119
129
  nonce: '0',
@@ -131,6 +141,8 @@ class ProcessDepositEvents extends BaseTask {
131
141
 
132
142
  console.log(`Collecting signatures for execution ${transaction.transactionHash}`)
133
143
 
144
+ console.log(ownerPeerIds);
145
+
134
146
  const signatures = await protocol.requestSignatures({
135
147
  type: 'source',
136
148
  transactionHash: transaction.transactionHash,
@@ -145,33 +157,17 @@ class ProcessDepositEvents extends BaseTask {
145
157
 
146
158
  if (validSignatures.length === 0 || ownersThreshold.gt(validSignatures.length)) {
147
159
  await transaction.save();
148
- transaction.sourceDelayUntil = new Date(Date.now() + 30 * 1000);
149
- transaction.sourceStatus = 'pending'
160
+ transaction.targetDelayUntil = new Date(Date.now() + 30 * 1000);
161
+ transaction.targetStatus = 'uninitialised'
150
162
 
151
163
  await transaction.save();
152
164
  const errorMessage = signatures.find(s => !!s.error)?.error;
153
165
  throw new Error(`Not enough signatures` + (errorMessage ? `: ${errorMessage}` : ''));
154
166
  }
155
167
 
156
- const execTransactionParams = [
157
- gnosisTx.to,
158
- gnosisTx.value,
159
- gnosisTx.data,
160
- gnosisTx.operation,
161
- gnosisTx.safeTxGas,
162
- gnosisTx.baseGas,
163
- gnosisTx.gasPrice,
164
- gnosisTx.gasToken,
165
- gnosisTx.refundReceiver,
166
- buildSignatureBytes(validSignatures),
167
- ];
168
168
 
169
169
  console.log(`Executing transaction for execution ${transaction.transactionHash}`)
170
170
 
171
- console.log({
172
- execTransactionParams
173
- })
174
-
175
171
  const { data: txData } = await safeContract.populateTransaction.execTransaction(
176
172
  gnosisTx.to,
177
173
  gnosisTx.value,
@@ -185,10 +181,17 @@ class ProcessDepositEvents extends BaseTask {
185
181
  buildSignatureBytes(validSignatures)
186
182
  );
187
183
 
184
+ console.log({
185
+ from: targetWallet.address,
186
+ gasPrice: BigNumber.from(120 * 10 ** 9).toString(),
187
+ to: safeAddress,
188
+ data: txData,
189
+ })
190
+
191
+
188
192
  const txSent = await targetWallet.sendTransaction({
189
193
  from: targetWallet.address,
190
194
  gasPrice: BigNumber.from(120 * 10 ** 9),
191
- gasLimit: BigNumber.from(6_000_000),
192
195
  to: safeAddress,
193
196
  data: txData,
194
197
  })
@@ -205,9 +208,19 @@ class ProcessDepositEvents extends BaseTask {
205
208
 
206
209
  if (parsedLogs.find(e => e.name === 'ExecutionSuccess')) {
207
210
  console.log('ExecutionSuccess')
211
+ transaction.targetStatus = 'success'
212
+ transaction.targetTransactionHash = txSent.hash
213
+ transaction.status = 'success'
214
+ await transaction.save();
208
215
  } else {
209
216
  console.log('ExecutionFailure')
217
+ transaction.targetStatus = 'failed'
218
+ transaction.targetTransactionHash = txSent.hash
219
+ transaction.status = 'failed'
220
+ await transaction.save();
210
221
  }
222
+
223
+ protocol.sendTransaction(transaction)
211
224
  }
212
225
 
213
226
  async start(): Promise<void> {
@@ -219,11 +232,11 @@ class ProcessDepositEvents extends BaseTask {
219
232
  getRpcProviderUrl(this.chainId)
220
233
  );
221
234
 
222
- this.contract = new ethers.Contract(
235
+ this.contract = getContract<InteropXGateway>(
223
236
  this.contractAddress,
224
237
  abi.interopXGateway,
225
238
  new ethers.Wallet(config.privateKey!, this.provider)
226
- ) as InteropXGateway;
239
+ );
227
240
 
228
241
  await super.start()
229
242
  }