@instadapp/interop-x 0.0.0-dev.7a02577 → 0.0.0-dev.7adf1b5
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/package.json +9 -5
- package/dist/src/abi/interopBridgeToken.json +21 -9
- package/dist/src/abi/interopXGateway.json +11 -11
- package/dist/src/api/index.js +6 -3
- package/dist/src/config/index.js +11 -1
- package/dist/src/constants/addresses.js +1 -1
- package/dist/src/constants/itokens.js +1 -1
- package/dist/src/db/models/transaction.js +8 -0
- package/dist/src/gnosis/actions/deposit.js +48 -0
- package/dist/src/gnosis/actions/index.js +11 -0
- package/dist/src/gnosis/actions/withdraw.js +50 -0
- package/dist/src/gnosis/index.js +20 -0
- package/dist/src/index.js +69 -7
- package/dist/src/net/peer/index.js +8 -3
- package/dist/src/net/pool/index.js +32 -9
- package/dist/src/net/protocol/dial/SignatureDialProtocol.js +6 -4
- package/dist/src/net/protocol/dial/TransactionStatusDialProtocol.js +28 -0
- package/dist/src/net/protocol/index.js +41 -1
- package/dist/src/tasks/AutoUpdateTask.js +70 -0
- package/dist/src/tasks/BaseTask.js +12 -4
- package/dist/src/tasks/InteropBridge/ProcessWithdrawEvents.js +162 -0
- package/dist/src/tasks/InteropBridge/SyncBurnEvents.js +71 -0
- package/dist/src/tasks/InteropBridge/SyncMintEvents.js +67 -0
- package/dist/src/tasks/InteropXGateway/ProcessDepositEvents.js +47 -23
- package/dist/src/tasks/InteropXGateway/SyncDepositEvents.js +6 -7
- package/dist/src/tasks/InteropXGateway/SyncWithdrawtEvents.js +72 -0
- package/dist/src/tasks/Transactions/SyncTransactionStatusTask.js +53 -0
- package/dist/src/tasks/index.js +28 -0
- package/dist/src/typechain/factories/InteropBridgeToken__factory.js +23 -11
- package/dist/src/typechain/factories/InteropXGateway__factory.js +14 -14
- package/dist/src/utils/index.js +57 -37
- package/package.json +9 -5
- package/patches/@ethersproject+properties+5.6.0.patch +13 -0
- package/src/abi/interopBridgeToken.json +21 -9
- package/src/abi/interopXGateway.json +11 -11
- package/src/api/index.ts +5 -2
- package/src/config/index.ts +11 -1
- package/src/constants/addresses.ts +1 -1
- package/src/constants/itokens.ts +1 -1
- package/src/db/models/transaction.ts +10 -0
- package/src/gnosis/actions/deposit.ts +63 -0
- package/src/gnosis/actions/index.ts +7 -0
- package/src/gnosis/actions/withdraw.ts +67 -0
- package/src/gnosis/index.ts +19 -0
- package/src/index.ts +90 -9
- package/src/net/peer/index.ts +9 -7
- package/src/net/pool/index.ts +41 -11
- package/src/net/protocol/dial/SignatureDialProtocol.ts +8 -6
- package/src/net/protocol/dial/TransactionStatusDialProtocol.ts +31 -0
- package/src/net/protocol/index.ts +57 -1
- package/src/tasks/AutoUpdateTask.ts +82 -0
- package/src/tasks/BaseTask.ts +14 -4
- package/src/tasks/InteropBridge/ProcessWithdrawEvents.ts +249 -0
- package/src/tasks/InteropBridge/SyncBurnEvents.ts +119 -0
- package/src/tasks/InteropBridge/SyncMintEvents.ts +99 -0
- package/src/tasks/InteropXGateway/ProcessDepositEvents.ts +60 -32
- package/src/tasks/InteropXGateway/SyncDepositEvents.ts +8 -10
- package/src/tasks/InteropXGateway/SyncWithdrawtEvents.ts +105 -0
- package/src/tasks/Transactions/SyncTransactionStatusTask.ts +65 -0
- package/src/tasks/index.ts +43 -2
- package/src/typechain/InteropBridgeToken.ts +23 -17
- package/src/typechain/InteropXGateway.ts +13 -13
- package/src/typechain/factories/InteropBridgeToken__factory.ts +23 -11
- package/src/typechain/factories/InteropXGateway__factory.ts +14 -14
- package/src/utils/index.ts +66 -53
@@ -0,0 +1,119 @@
|
|
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 SyncBurnEvents 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::SyncBurnEvents"),
|
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, sourceChainId, targetChainId } = event.args;
|
45
|
+
|
46
|
+
const uniqueIdentifier = {
|
47
|
+
action: 'withdraw',
|
48
|
+
submitTransactionHash: event.transactionHash,
|
49
|
+
sourceChainId: sourceChainId,
|
50
|
+
targetChainId: targetChainId,
|
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
|
+
submitTransactionHash: event.transactionHash,
|
66
|
+
submitBlockNumber: event.blockNumber,
|
67
|
+
|
68
|
+
// submit & source are the same
|
69
|
+
sourceTransactionHash: event.transactionHash,
|
70
|
+
sourceBlockNumber: event.blockNumber,
|
71
|
+
sourceStatus: "success",
|
72
|
+
targetStatus: "uninitialised",
|
73
|
+
|
74
|
+
submitEvent: {
|
75
|
+
to,
|
76
|
+
amount: amount.toString(),
|
77
|
+
itoken: this.itokenAddress,
|
78
|
+
sourceChainId: sourceChainId,
|
79
|
+
targetChainId: targetChainId,
|
80
|
+
},
|
81
|
+
|
82
|
+
sourceEvent: {
|
83
|
+
to,
|
84
|
+
amount: amount.toString(),
|
85
|
+
itoken: this.itokenAddress,
|
86
|
+
sourceChainId: sourceChainId,
|
87
|
+
targetChainId: targetChainId,
|
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.provider = new ethers.providers.JsonRpcProvider(
|
106
|
+
getRpcProviderUrl(this.chainId)
|
107
|
+
);
|
108
|
+
|
109
|
+
this.contract = getContract<InteropBridgeToken>(
|
110
|
+
this.itokenAddress,
|
111
|
+
abi.interopBridgeToken,
|
112
|
+
new ethers.Wallet(config.privateKey!, this.provider)
|
113
|
+
);
|
114
|
+
|
115
|
+
await super.start()
|
116
|
+
}
|
117
|
+
}
|
118
|
+
|
119
|
+
export default SyncBurnEvents;
|
@@ -0,0 +1,99 @@
|
|
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 { getContract, getRpcProviderUrl } from "@/utils";
|
7
|
+
import { ChainId } from "@/types";
|
8
|
+
import config from "@/config";
|
9
|
+
import { InteropBridgeToken } from "@/typechain";
|
10
|
+
|
11
|
+
class SyncMintEvents 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::SyncMintEvents"),
|
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.Mint(),
|
31
|
+
currentBlock - 500,
|
32
|
+
currentBlock,
|
33
|
+
);
|
34
|
+
|
35
|
+
for (const event of events) {
|
36
|
+
|
37
|
+
try {
|
38
|
+
if (!event.args) {
|
39
|
+
continue;
|
40
|
+
}
|
41
|
+
|
42
|
+
const { sourceChainId, targetChainId, amount, to, submitTransactionHash } = event.args;
|
43
|
+
|
44
|
+
const uniqueIdentifier = {
|
45
|
+
action: 'deposit',
|
46
|
+
submitTransactionHash: submitTransactionHash,
|
47
|
+
sourceChainId: sourceChainId,
|
48
|
+
targetChainId: targetChainId,
|
49
|
+
|
50
|
+
targetEvent: null
|
51
|
+
}
|
52
|
+
|
53
|
+
const transaction = await Transaction.findOne({ where: uniqueIdentifier });
|
54
|
+
|
55
|
+
if(! transaction){
|
56
|
+
return;
|
57
|
+
}
|
58
|
+
|
59
|
+
const tx = await event.getTransaction()
|
60
|
+
|
61
|
+
transaction.targetStatus = 'success'
|
62
|
+
transaction.targetErrors = []
|
63
|
+
transaction.targetTransactionHash = tx.hash
|
64
|
+
transaction.targetEvent = {
|
65
|
+
sourceChainId,
|
66
|
+
targetChainId,
|
67
|
+
amount: amount.toString(),
|
68
|
+
to,
|
69
|
+
submitTransactionHash
|
70
|
+
}
|
71
|
+
transaction.status = 'success'
|
72
|
+
|
73
|
+
await transaction.save()
|
74
|
+
|
75
|
+
this.logger.info(
|
76
|
+
`Mint confirmation received: ${transaction.transactionHash} `
|
77
|
+
);
|
78
|
+
} catch (error) {
|
79
|
+
this.logger.error(error);
|
80
|
+
}
|
81
|
+
}
|
82
|
+
}
|
83
|
+
|
84
|
+
async start(): Promise<void> {
|
85
|
+
this.provider = new ethers.providers.JsonRpcProvider(
|
86
|
+
getRpcProviderUrl(this.chainId)
|
87
|
+
);
|
88
|
+
|
89
|
+
this.contract = getContract<InteropBridgeToken>(
|
90
|
+
this.itokenAddress,
|
91
|
+
abi.interopBridgeToken,
|
92
|
+
new ethers.Wallet(config.privateKey!, this.provider)
|
93
|
+
);
|
94
|
+
|
95
|
+
await super.start()
|
96
|
+
}
|
97
|
+
}
|
98
|
+
|
99
|
+
export default SyncMintEvents;
|
@@ -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 {
|
6
|
+
import { buildSignatureBytes, getContract, getRpcProviderUrl, Signature } from "@/utils";
|
7
7
|
import { addresses } from "@/constants";
|
8
8
|
import { ChainId } from "@/types";
|
9
9
|
import config from "@/config";
|
@@ -12,8 +12,11 @@ import { Op } from "sequelize";
|
|
12
12
|
import wait from "waait";
|
13
13
|
import { peerPool, protocol } from "@/net";
|
14
14
|
import { LogDescription } from "ethers/lib/utils";
|
15
|
+
import { buildGnosisAction } from "@/gnosis";
|
16
|
+
|
17
|
+
const generateGnosisTransaction = async (transactionData: any, safeContract: GnosisSafe) => {
|
18
|
+
console.log(transactionData);
|
15
19
|
|
16
|
-
const generateGnosisTransaction = async (transactionData: any, safeContract: any) => {
|
17
20
|
let isExecuted = await safeContract.dataHashes(
|
18
21
|
await safeContract.getTransactionHash(
|
19
22
|
transactionData.to,
|
@@ -72,13 +75,21 @@ class ProcessDepositEvents extends BaseTask {
|
|
72
75
|
where: {
|
73
76
|
status: 'pending',
|
74
77
|
sourceStatus: 'success',
|
78
|
+
targetStatus: 'uninitialised',
|
75
79
|
action: 'deposit',
|
76
80
|
sourceCreatedAt: {
|
77
81
|
[Op.gte]: new Date(Date.now() - 12 * 60 * 60 * 1000),
|
78
82
|
},
|
83
|
+
targetDelayUntil: {
|
84
|
+
[Op.or]: {
|
85
|
+
[Op.is]: null,
|
86
|
+
[Op.lt]: new Date(),
|
87
|
+
}
|
88
|
+
},
|
79
89
|
sourceBlockNumber: {
|
80
90
|
[Op.lt]: blockNumber - 12,
|
81
|
-
}
|
91
|
+
},
|
92
|
+
sourceChainId: this.chainId,
|
82
93
|
}
|
83
94
|
})
|
84
95
|
|
@@ -86,11 +97,11 @@ class ProcessDepositEvents extends BaseTask {
|
|
86
97
|
return;
|
87
98
|
}
|
88
99
|
|
100
|
+
console.log(`Processing transaction ${transaction.transactionHash}`);
|
89
101
|
|
90
|
-
transaction.
|
102
|
+
transaction.targetStatus = 'pending';
|
91
103
|
await transaction.save();
|
92
104
|
|
93
|
-
|
94
105
|
// refresh event data?
|
95
106
|
|
96
107
|
const targetChainProvider = new ethers.providers.JsonRpcProvider(
|
@@ -101,19 +112,34 @@ class ProcessDepositEvents extends BaseTask {
|
|
101
112
|
|
102
113
|
const safeAddress = addresses[transaction.targetChainId].gnosisSafe;
|
103
114
|
|
104
|
-
|
115
|
+
|
116
|
+
const safeContract = getContract<GnosisSafe>(
|
105
117
|
safeAddress,
|
106
118
|
abi.gnosisSafe,
|
107
119
|
targetWallet
|
108
|
-
)
|
120
|
+
)
|
109
121
|
|
110
122
|
const ownersThreshold = await safeContract.getThreshold();
|
111
|
-
|
112
123
|
await wait(10000);
|
113
124
|
|
125
|
+
let data, logs = [];
|
126
|
+
|
127
|
+
try {
|
128
|
+
({ data, logs } = await buildGnosisAction(transaction));
|
129
|
+
|
130
|
+
} catch (error) {
|
131
|
+
console.log(error);
|
132
|
+
transaction.targetStatus = 'failed';
|
133
|
+
transaction.targetErrors = [error.message];
|
134
|
+
transaction.status = 'failed'
|
135
|
+
await transaction.save();
|
136
|
+
protocol.sendTransaction(transaction)
|
137
|
+
return;
|
138
|
+
}
|
139
|
+
|
114
140
|
let gnosisTx = await generateGnosisTransaction({
|
115
141
|
baseGas: "0",
|
116
|
-
data
|
142
|
+
data,
|
117
143
|
gasPrice: "0",
|
118
144
|
gasToken: "0x0000000000000000000000000000000000000000",
|
119
145
|
nonce: '0',
|
@@ -131,6 +157,8 @@ class ProcessDepositEvents extends BaseTask {
|
|
131
157
|
|
132
158
|
console.log(`Collecting signatures for execution ${transaction.transactionHash}`)
|
133
159
|
|
160
|
+
console.log(ownerPeerIds);
|
161
|
+
|
134
162
|
const signatures = await protocol.requestSignatures({
|
135
163
|
type: 'source',
|
136
164
|
transactionHash: transaction.transactionHash,
|
@@ -145,33 +173,17 @@ class ProcessDepositEvents extends BaseTask {
|
|
145
173
|
|
146
174
|
if (validSignatures.length === 0 || ownersThreshold.gt(validSignatures.length)) {
|
147
175
|
await transaction.save();
|
148
|
-
transaction.
|
149
|
-
transaction.
|
176
|
+
transaction.targetDelayUntil = new Date(Date.now() + 30 * 1000);
|
177
|
+
transaction.targetStatus = 'uninitialised'
|
150
178
|
|
151
179
|
await transaction.save();
|
152
180
|
const errorMessage = signatures.find(s => !!s.error)?.error;
|
153
181
|
throw new Error(`Not enough signatures` + (errorMessage ? `: ${errorMessage}` : ''));
|
154
182
|
}
|
155
183
|
|
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
184
|
|
169
185
|
console.log(`Executing transaction for execution ${transaction.transactionHash}`)
|
170
186
|
|
171
|
-
console.log({
|
172
|
-
execTransactionParams
|
173
|
-
})
|
174
|
-
|
175
187
|
const { data: txData } = await safeContract.populateTransaction.execTransaction(
|
176
188
|
gnosisTx.to,
|
177
189
|
gnosisTx.value,
|
@@ -185,10 +197,17 @@ class ProcessDepositEvents extends BaseTask {
|
|
185
197
|
buildSignatureBytes(validSignatures)
|
186
198
|
);
|
187
199
|
|
200
|
+
console.log({
|
201
|
+
from: targetWallet.address,
|
202
|
+
gasPrice: BigNumber.from(120 * 10 ** 9).toString(),
|
203
|
+
to: safeAddress,
|
204
|
+
data: txData,
|
205
|
+
})
|
206
|
+
|
207
|
+
|
188
208
|
const txSent = await targetWallet.sendTransaction({
|
189
209
|
from: targetWallet.address,
|
190
210
|
gasPrice: BigNumber.from(120 * 10 ** 9),
|
191
|
-
gasLimit: BigNumber.from(6_000_000),
|
192
211
|
to: safeAddress,
|
193
212
|
data: txData,
|
194
213
|
})
|
@@ -205,25 +224,34 @@ class ProcessDepositEvents extends BaseTask {
|
|
205
224
|
|
206
225
|
if (parsedLogs.find(e => e.name === 'ExecutionSuccess')) {
|
207
226
|
console.log('ExecutionSuccess')
|
227
|
+
transaction.targetStatus = 'success'
|
228
|
+
transaction.targetTransactionHash = txSent.hash
|
229
|
+
transaction.targetLogs = logs;
|
230
|
+
transaction.status = 'success'
|
231
|
+
await transaction.save();
|
208
232
|
} else {
|
209
233
|
console.log('ExecutionFailure')
|
234
|
+
transaction.targetStatus = 'failed'
|
235
|
+
transaction.targetTransactionHash = txSent.hash
|
236
|
+
transaction.status = 'failed'
|
237
|
+
await transaction.save();
|
210
238
|
}
|
239
|
+
|
240
|
+
protocol.sendTransaction(transaction)
|
211
241
|
}
|
212
242
|
|
213
243
|
async start(): Promise<void> {
|
214
|
-
this.logger.info(`Starting execution watcher on interop chain`);
|
215
|
-
|
216
244
|
this.contractAddress = addresses[this.chainId].interopXGateway;
|
217
245
|
|
218
246
|
this.provider = new ethers.providers.JsonRpcProvider(
|
219
247
|
getRpcProviderUrl(this.chainId)
|
220
248
|
);
|
221
249
|
|
222
|
-
this.contract =
|
250
|
+
this.contract = getContract<InteropXGateway>(
|
223
251
|
this.contractAddress,
|
224
252
|
abi.interopXGateway,
|
225
253
|
new ethers.Wallet(config.privateKey!, this.provider)
|
226
|
-
)
|
254
|
+
);
|
227
255
|
|
228
256
|
await super.start()
|
229
257
|
}
|
@@ -3,7 +3,7 @@ import Logger from '@/logger';
|
|
3
3
|
import { ethers } from "ethers";
|
4
4
|
import abi from "@/abi";
|
5
5
|
import { Transaction } from "@/db";
|
6
|
-
import { generateInteropTransactionHash, getRpcProviderUrl } from "@/utils";
|
6
|
+
import { generateInteropTransactionHash, getContract, getRpcProviderUrl } from "@/utils";
|
7
7
|
import { addresses } from "@/constants";
|
8
8
|
import { ChainId } from "@/types";
|
9
9
|
import config from "@/config";
|
@@ -45,8 +45,8 @@ class SyncDepositEvents extends BaseTask {
|
|
45
45
|
const uniqueIdentifier = {
|
46
46
|
action: 'deposit',
|
47
47
|
submitTransactionHash: event.transactionHash,
|
48
|
-
sourceChainId: sourceChainId
|
49
|
-
targetChainId: targetChainId
|
48
|
+
sourceChainId: sourceChainId,
|
49
|
+
targetChainId: targetChainId,
|
50
50
|
}
|
51
51
|
|
52
52
|
if (await Transaction.findOne({ where: uniqueIdentifier })) {
|
@@ -77,7 +77,7 @@ class SyncDepositEvents extends BaseTask {
|
|
77
77
|
sourceChainId: sourceChainId.toString(),
|
78
78
|
targetChainId: targetChainId.toString(),
|
79
79
|
token: token,
|
80
|
-
|
80
|
+
amount: amount.toString(),
|
81
81
|
vnonce: vnonce.toString(),
|
82
82
|
},
|
83
83
|
|
@@ -86,14 +86,14 @@ class SyncDepositEvents extends BaseTask {
|
|
86
86
|
sourceChainId: sourceChainId.toString(),
|
87
87
|
targetChainId: targetChainId.toString(),
|
88
88
|
token: token,
|
89
|
-
|
89
|
+
amount: amount.toString(),
|
90
90
|
vnonce: vnonce.toString(),
|
91
91
|
},
|
92
92
|
status: "pending",
|
93
93
|
})
|
94
94
|
|
95
95
|
this.logger.info(
|
96
|
-
`
|
96
|
+
`Deposit queued: ${event.transactionHash} ${event.blockNumber}`
|
97
97
|
);
|
98
98
|
} catch (error) {
|
99
99
|
this.logger.error(error);
|
@@ -105,19 +105,17 @@ class SyncDepositEvents extends BaseTask {
|
|
105
105
|
}
|
106
106
|
|
107
107
|
async start(): Promise<void> {
|
108
|
-
this.logger.info(`Starting execution watcher on interop chain`);
|
109
|
-
|
110
108
|
this.contractAddress = addresses[this.chainId].interopXGateway;
|
111
109
|
|
112
110
|
this.provider = new ethers.providers.JsonRpcProvider(
|
113
111
|
getRpcProviderUrl(this.chainId)
|
114
112
|
);
|
115
113
|
|
116
|
-
this.contract =
|
114
|
+
this.contract = getContract<InteropXGateway>(
|
117
115
|
this.contractAddress,
|
118
116
|
abi.interopXGateway,
|
119
117
|
new ethers.Wallet(config.privateKey!, this.provider)
|
120
|
-
)
|
118
|
+
);
|
121
119
|
|
122
120
|
await super.start()
|
123
121
|
}
|
@@ -0,0 +1,105 @@
|
|
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 { getContract, getRpcProviderUrl } from "@/utils";
|
7
|
+
import { addresses } from "@/constants";
|
8
|
+
import { ChainId } from "@/types";
|
9
|
+
import config from "@/config";
|
10
|
+
import { InteropXGateway } from "@/typechain";
|
11
|
+
|
12
|
+
class SyncWithdrawEvents extends BaseTask {
|
13
|
+
contractAddress: string;
|
14
|
+
provider: ethers.providers.JsonRpcProvider;
|
15
|
+
contract: InteropXGateway;
|
16
|
+
chainId: ChainId;
|
17
|
+
|
18
|
+
constructor({ chainId }: { chainId: ChainId }) {
|
19
|
+
super({
|
20
|
+
logger: new Logger("InteropXGateway::SyncWithdrawEvents"),
|
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.LogGatewayWithdraw(),
|
30
|
+
currentBlock - 500,
|
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 { user, token, amount, sourceChainId, targetChainId, transactionHash } = event.args;
|
44
|
+
|
45
|
+
const uniqueIdentifier = {
|
46
|
+
action: 'withdraw',
|
47
|
+
submitTransactionHash: transactionHash,
|
48
|
+
sourceChainId: sourceChainId,
|
49
|
+
targetChainId: targetChainId,
|
50
|
+
|
51
|
+
targetEvent: null
|
52
|
+
}
|
53
|
+
const transaction = await Transaction.findOne({ where: uniqueIdentifier });
|
54
|
+
|
55
|
+
if (!transaction) {
|
56
|
+
return;
|
57
|
+
}
|
58
|
+
|
59
|
+
const tx = await event.getTransaction()
|
60
|
+
|
61
|
+
transaction.targetStatus = 'success'
|
62
|
+
transaction.targetErrors = []
|
63
|
+
transaction.targetTransactionHash = tx.hash
|
64
|
+
transaction.targetEvent = {
|
65
|
+
user,
|
66
|
+
token,
|
67
|
+
amount: amount.toString(),
|
68
|
+
sourceChainId,
|
69
|
+
targetChainId,
|
70
|
+
transactionHash,
|
71
|
+
}
|
72
|
+
transaction.status = 'success'
|
73
|
+
|
74
|
+
await transaction.save()
|
75
|
+
|
76
|
+
this.logger.info(
|
77
|
+
`Witdraw confirmation received: ${transaction.transactionHash} `
|
78
|
+
);
|
79
|
+
} catch (error) {
|
80
|
+
this.logger.error(error);
|
81
|
+
}
|
82
|
+
}
|
83
|
+
|
84
|
+
if (processedEvents > 0)
|
85
|
+
this.logger.info(`${processedEvents} events processed`);
|
86
|
+
}
|
87
|
+
|
88
|
+
async start(): Promise<void> {
|
89
|
+
this.contractAddress = addresses[this.chainId].interopXGateway;
|
90
|
+
|
91
|
+
this.provider = new ethers.providers.JsonRpcProvider(
|
92
|
+
getRpcProviderUrl(this.chainId)
|
93
|
+
);
|
94
|
+
|
95
|
+
this.contract = getContract<InteropXGateway>(
|
96
|
+
this.contractAddress,
|
97
|
+
abi.interopXGateway,
|
98
|
+
new ethers.Wallet(config.privateKey!, this.provider)
|
99
|
+
);
|
100
|
+
|
101
|
+
await super.start()
|
102
|
+
}
|
103
|
+
}
|
104
|
+
|
105
|
+
export default SyncWithdrawEvents;
|
@@ -0,0 +1,65 @@
|
|
1
|
+
import { BaseTask } from "../BaseTask";
|
2
|
+
import Logger from '@/logger';
|
3
|
+
import config from "@/config";
|
4
|
+
import { peerPool, protocol } from "@/net";
|
5
|
+
import { Transaction } from "@/db";
|
6
|
+
import { Op } from "sequelize";
|
7
|
+
|
8
|
+
class SyncTransactionStatusTask extends BaseTask {
|
9
|
+
pollIntervalMs: number = 60 * 1000
|
10
|
+
exceptLeadNode: boolean = true;
|
11
|
+
|
12
|
+
constructor() {
|
13
|
+
super({
|
14
|
+
logger: new Logger("SyncTransactionStatusTask"),
|
15
|
+
})
|
16
|
+
}
|
17
|
+
|
18
|
+
async pollHandler() {
|
19
|
+
// if transaction is pending for more than 1 hour, check lead node for status
|
20
|
+
const leadNode = peerPool.getLeadPeer();
|
21
|
+
|
22
|
+
if (!leadNode) {
|
23
|
+
return;
|
24
|
+
}
|
25
|
+
|
26
|
+
const transaction = await Transaction.findOne({
|
27
|
+
where: {
|
28
|
+
status: 'pending',
|
29
|
+
sourceCreatedAt: {
|
30
|
+
[Op.gte]: new Date(Date.now() - 60 * 60 * 1000),
|
31
|
+
},
|
32
|
+
}
|
33
|
+
})
|
34
|
+
|
35
|
+
if (!transaction) {
|
36
|
+
return;
|
37
|
+
}
|
38
|
+
|
39
|
+
this.logger.info(`Requesting transaction status for ${transaction.transactionHash}`)
|
40
|
+
|
41
|
+
const transactionStatus = await protocol.requestTransactionStatus(transaction.transactionHash, leadNode.id);
|
42
|
+
|
43
|
+
if (!transactionStatus) {
|
44
|
+
return;
|
45
|
+
}
|
46
|
+
|
47
|
+
this.logger.info(`Received transaction status for ${transaction.transactionHash}`)
|
48
|
+
|
49
|
+
transaction.sourceStatus = transactionStatus.sourceStatus
|
50
|
+
transaction.sourceTransactionHash = transactionStatus.sourceTransactionHash
|
51
|
+
transaction.sourceErrors = transactionStatus.sourceErrors
|
52
|
+
|
53
|
+
transaction.targetStatus = transactionStatus.targetStatus
|
54
|
+
transaction.targetTransactionHash = transactionStatus.targetTransactionHash
|
55
|
+
transaction.targetErrors = transactionStatus.targetErrors
|
56
|
+
|
57
|
+
transaction.status = transactionStatus.status
|
58
|
+
|
59
|
+
await transaction.save()
|
60
|
+
|
61
|
+
this.logger.info(`Updated transaction status for ${transaction.transactionHash}`)
|
62
|
+
}
|
63
|
+
}
|
64
|
+
|
65
|
+
export default SyncTransactionStatusTask;
|