@instadapp/interop-x 0.0.0-dev.9b1fcb8 → 0.0.0-dev.9e91661
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 +6 -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/gnosis/actions/deposit.js +40 -0
- package/dist/src/gnosis/actions/index.js +11 -0
- package/dist/src/gnosis/actions/withdraw.js +45 -0
- package/dist/src/gnosis/index.js +16 -0
- package/dist/src/index.js +69 -7
- package/dist/src/net/peer/index.js +2 -1
- package/dist/src/net/pool/index.js +18 -2
- package/dist/src/net/protocol/dial/SignatureDialProtocol.js +2 -8
- 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 +11 -3
- package/dist/src/tasks/InteropBridge/ProcessWithdrawEvents.js +147 -0
- package/dist/src/tasks/InteropBridge/{SyncWithdrawEvents.js → SyncBurnEvents.js} +12 -9
- package/dist/src/tasks/InteropBridge/SyncMintEvents.js +67 -0
- package/dist/src/tasks/InteropXGateway/ProcessDepositEvents.js +18 -2
- package/dist/src/tasks/InteropXGateway/SyncDepositEvents.js +2 -3
- package/dist/src/tasks/InteropXGateway/SyncWithdrawtEvents.js +72 -0
- package/dist/src/tasks/Transactions/SyncTransactionStatusTask.js +53 -0
- package/dist/src/tasks/index.js +22 -3
- 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 +19 -40
- package/package.json +6 -5
- 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/gnosis/actions/deposit.ts +54 -0
- package/src/gnosis/actions/index.ts +7 -0
- package/src/gnosis/actions/withdraw.ts +61 -0
- package/src/gnosis/index.ts +13 -0
- package/src/index.ts +90 -9
- package/src/net/peer/index.ts +2 -1
- package/src/net/pool/index.ts +25 -5
- package/src/net/protocol/dial/SignatureDialProtocol.ts +3 -10
- 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 +13 -3
- package/src/tasks/InteropBridge/ProcessWithdrawEvents.ts +232 -0
- package/src/tasks/InteropBridge/{SyncWithdrawEvents.ts → SyncBurnEvents.ts} +13 -11
- package/src/tasks/InteropBridge/SyncMintEvents.ts +99 -0
- package/src/tasks/InteropXGateway/ProcessDepositEvents.ts +24 -7
- package/src/tasks/InteropXGateway/SyncDepositEvents.ts +2 -4
- package/src/tasks/InteropXGateway/SyncWithdrawtEvents.ts +105 -0
- package/src/tasks/Transactions/SyncTransactionStatusTask.ts +65 -0
- package/src/tasks/index.ts +33 -3
- 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 +22 -62
@@ -0,0 +1,232 @@
|
|
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 { buildSignatureBytes, getContract, getRpcProviderUrl, Signature } from "@/utils";
|
7
|
+
import { addresses } from "@/constants";
|
8
|
+
import { ChainId } from "@/types";
|
9
|
+
import config from "@/config";
|
10
|
+
import { GnosisSafe } 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
|
+
import { buildGnosisData } from "@/gnosis";
|
16
|
+
|
17
|
+
const generateGnosisTransaction = async (transactionData: any, safeContract: GnosisSafe) => {
|
18
|
+
console.log(transactionData);
|
19
|
+
|
20
|
+
let isExecuted = await safeContract.dataHashes(
|
21
|
+
await safeContract.getTransactionHash(
|
22
|
+
transactionData.to,
|
23
|
+
transactionData.value,
|
24
|
+
transactionData.data,
|
25
|
+
transactionData.operation,
|
26
|
+
transactionData.safeTxGas,
|
27
|
+
transactionData.baseGas,
|
28
|
+
transactionData.gasPrice,
|
29
|
+
transactionData.gasToken,
|
30
|
+
transactionData.refundReceiver,
|
31
|
+
transactionData.nonce
|
32
|
+
)
|
33
|
+
)
|
34
|
+
|
35
|
+
while (isExecuted == 1) {
|
36
|
+
transactionData.safeTxGas = BigNumber.from(String(transactionData.safeTxGas)).add(1).toString()
|
37
|
+
|
38
|
+
isExecuted = await safeContract.dataHashes(
|
39
|
+
await safeContract.getTransactionHash(
|
40
|
+
transactionData.to,
|
41
|
+
transactionData.value,
|
42
|
+
transactionData.data,
|
43
|
+
transactionData.operation,
|
44
|
+
transactionData.safeTxGas,
|
45
|
+
transactionData.baseGas,
|
46
|
+
transactionData.gasPrice,
|
47
|
+
transactionData.gasToken,
|
48
|
+
transactionData.refundReceiver,
|
49
|
+
transactionData.nonce
|
50
|
+
)
|
51
|
+
)
|
52
|
+
}
|
53
|
+
|
54
|
+
return transactionData
|
55
|
+
}
|
56
|
+
|
57
|
+
class ProcessWithdrawEvents extends BaseTask {
|
58
|
+
provider: ethers.providers.JsonRpcProvider;
|
59
|
+
chainId: ChainId;
|
60
|
+
leadNodeOnly = true
|
61
|
+
|
62
|
+
constructor({ chainId }: { chainId: ChainId }) {
|
63
|
+
super({
|
64
|
+
logger: new Logger("InteropXGateway::ProcessWithdrawEvents"),
|
65
|
+
})
|
66
|
+
this.chainId = chainId;
|
67
|
+
}
|
68
|
+
|
69
|
+
async pollHandler() {
|
70
|
+
const blockNumber = await this.provider.getBlockNumber()
|
71
|
+
|
72
|
+
const transaction = await Transaction.findOne({
|
73
|
+
where: {
|
74
|
+
status: 'pending',
|
75
|
+
sourceStatus: 'success',
|
76
|
+
targetStatus: 'uninitialised',
|
77
|
+
action: 'withdraw',
|
78
|
+
sourceCreatedAt: {
|
79
|
+
[Op.gte]: new Date(Date.now() - 12 * 60 * 60 * 1000),
|
80
|
+
},
|
81
|
+
targetDelayUntil: {
|
82
|
+
[Op.or]: {
|
83
|
+
[Op.is]: null,
|
84
|
+
[Op.lt]: new Date(),
|
85
|
+
}
|
86
|
+
},
|
87
|
+
sourceBlockNumber: {
|
88
|
+
[Op.lt]: blockNumber - 12,
|
89
|
+
},
|
90
|
+
sourceChainId: this.chainId,
|
91
|
+
}
|
92
|
+
})
|
93
|
+
|
94
|
+
if (!transaction) {
|
95
|
+
return;
|
96
|
+
}
|
97
|
+
|
98
|
+
console.log(`Processing transaction ${transaction.transactionHash}`);
|
99
|
+
|
100
|
+
transaction.targetStatus = 'pending';
|
101
|
+
await transaction.save();
|
102
|
+
|
103
|
+
// refresh event data?
|
104
|
+
|
105
|
+
const targetChainProvider = new ethers.providers.JsonRpcProvider(
|
106
|
+
getRpcProviderUrl(transaction.targetChainId as ChainId)
|
107
|
+
);
|
108
|
+
|
109
|
+
const targetWallet = new ethers.Wallet(config.privateKey!, targetChainProvider);
|
110
|
+
|
111
|
+
const safeAddress = addresses[transaction.targetChainId].gnosisSafe;
|
112
|
+
|
113
|
+
|
114
|
+
const safeContract = getContract<GnosisSafe>(
|
115
|
+
safeAddress,
|
116
|
+
abi.gnosisSafe,
|
117
|
+
targetWallet
|
118
|
+
)
|
119
|
+
|
120
|
+
const ownersThreshold = await safeContract.getThreshold();
|
121
|
+
await wait(10000);
|
122
|
+
|
123
|
+
let gnosisTx = await generateGnosisTransaction({
|
124
|
+
baseGas: "0",
|
125
|
+
data: await buildGnosisData(transaction),
|
126
|
+
gasPrice: "0",
|
127
|
+
gasToken: "0x0000000000000000000000000000000000000000",
|
128
|
+
nonce: '0',
|
129
|
+
operation: "1",
|
130
|
+
refundReceiver: "0x0000000000000000000000000000000000000000",
|
131
|
+
safeAddress: safeAddress,
|
132
|
+
safeTxGas: "79668",
|
133
|
+
to: addresses[transaction.targetChainId].multisend,
|
134
|
+
value: "0",
|
135
|
+
}, safeContract);
|
136
|
+
|
137
|
+
const owners = await safeContract.getOwners().then(owners => owners.map(owner => owner.toLowerCase()));
|
138
|
+
|
139
|
+
const ownerPeerIds = peerPool.activePeers.filter(peer => owners.includes(peer.publicAddress.toLowerCase())).map(peer => peer.id)
|
140
|
+
|
141
|
+
console.log(`Collecting signatures for execution ${transaction.transactionHash}`)
|
142
|
+
|
143
|
+
console.log(ownerPeerIds);
|
144
|
+
|
145
|
+
const signatures = await protocol.requestSignatures({
|
146
|
+
type: 'source',
|
147
|
+
transactionHash: transaction.transactionHash,
|
148
|
+
safeTxGas: gnosisTx.safeTxGas,
|
149
|
+
safeNonce: gnosisTx.nonce
|
150
|
+
}, ownerPeerIds)
|
151
|
+
|
152
|
+
|
153
|
+
const validSignatures = signatures.filter(s => !!s.data && s.data !== '0x') as Signature[];
|
154
|
+
|
155
|
+
console.log({ signatures, validSignatures, ownersThreshold: ownersThreshold.toString() });
|
156
|
+
|
157
|
+
if (validSignatures.length === 0 || ownersThreshold.gt(validSignatures.length)) {
|
158
|
+
await transaction.save();
|
159
|
+
transaction.targetDelayUntil = new Date(Date.now() + 30 * 1000);
|
160
|
+
transaction.targetStatus = 'uninitialised'
|
161
|
+
|
162
|
+
await transaction.save();
|
163
|
+
const errorMessage = signatures.find(s => !!s.error)?.error;
|
164
|
+
throw new Error(`Not enough signatures` + (errorMessage ? `: ${errorMessage}` : ''));
|
165
|
+
}
|
166
|
+
|
167
|
+
|
168
|
+
console.log(`Executing transaction for execution ${transaction.transactionHash}`)
|
169
|
+
|
170
|
+
const { data: txData } = await safeContract.populateTransaction.execTransaction(
|
171
|
+
gnosisTx.to,
|
172
|
+
gnosisTx.value,
|
173
|
+
gnosisTx.data,
|
174
|
+
gnosisTx.operation,
|
175
|
+
gnosisTx.safeTxGas,
|
176
|
+
gnosisTx.baseGas,
|
177
|
+
gnosisTx.gasPrice,
|
178
|
+
gnosisTx.gasToken,
|
179
|
+
gnosisTx.refundReceiver,
|
180
|
+
buildSignatureBytes(validSignatures)
|
181
|
+
);
|
182
|
+
|
183
|
+
console.log({
|
184
|
+
from: targetWallet.address,
|
185
|
+
gasPrice: BigNumber.from(120 * 10 ** 9).toString(),
|
186
|
+
to: safeAddress,
|
187
|
+
data: txData,
|
188
|
+
})
|
189
|
+
|
190
|
+
|
191
|
+
const txSent = await targetWallet.sendTransaction({
|
192
|
+
from: targetWallet.address,
|
193
|
+
gasPrice: BigNumber.from(120 * 10 ** 9),
|
194
|
+
to: safeAddress,
|
195
|
+
data: txData,
|
196
|
+
})
|
197
|
+
|
198
|
+
const receipt = await txSent.wait();
|
199
|
+
|
200
|
+
const parsedLogs: LogDescription[] = [];
|
201
|
+
|
202
|
+
receipt.logs.forEach((log) => {
|
203
|
+
try {
|
204
|
+
parsedLogs.push(safeContract.interface.parseLog(log));
|
205
|
+
} catch (e) { }
|
206
|
+
});
|
207
|
+
|
208
|
+
if (parsedLogs.find(e => e.name === 'ExecutionSuccess')) {
|
209
|
+
console.log('ExecutionSuccess')
|
210
|
+
transaction.targetStatus = 'success'
|
211
|
+
transaction.targetTransactionHash = txSent.hash
|
212
|
+
transaction.status = 'success'
|
213
|
+
await transaction.save();
|
214
|
+
} else {
|
215
|
+
console.log('ExecutionFailure')
|
216
|
+
transaction.targetStatus = 'failed'
|
217
|
+
transaction.targetTransactionHash = txSent.hash
|
218
|
+
transaction.status = 'failed'
|
219
|
+
await transaction.save();
|
220
|
+
}
|
221
|
+
}
|
222
|
+
|
223
|
+
async start(): Promise<void> {
|
224
|
+
this.provider = new ethers.providers.JsonRpcProvider(
|
225
|
+
getRpcProviderUrl(this.chainId)
|
226
|
+
);
|
227
|
+
|
228
|
+
await super.start()
|
229
|
+
}
|
230
|
+
}
|
231
|
+
|
232
|
+
export default ProcessWithdrawEvents;
|
@@ -8,7 +8,7 @@ import { ChainId } from "@/types";
|
|
8
8
|
import config from "@/config";
|
9
9
|
import { InteropBridgeToken } from "@/typechain";
|
10
10
|
|
11
|
-
class
|
11
|
+
class SyncBurnEvents extends BaseTask {
|
12
12
|
contractAddress: string;
|
13
13
|
provider: ethers.providers.JsonRpcProvider;
|
14
14
|
contract: InteropBridgeToken;
|
@@ -17,7 +17,7 @@ class SyncWithdrawEvents extends BaseTask {
|
|
17
17
|
|
18
18
|
constructor({ chainId, itokenAddress }: { chainId: ChainId, itokenAddress: string }) {
|
19
19
|
super({
|
20
|
-
logger: new Logger("InteropBridgeToken::
|
20
|
+
logger: new Logger("InteropBridgeToken::SyncBurnEvents"),
|
21
21
|
})
|
22
22
|
this.chainId = chainId;
|
23
23
|
this.itokenAddress = itokenAddress;
|
@@ -41,13 +41,13 @@ class SyncWithdrawEvents extends BaseTask {
|
|
41
41
|
continue;
|
42
42
|
}
|
43
43
|
|
44
|
-
const { to, amount,
|
44
|
+
const { to, amount, sourceChainId, targetChainId } = event.args;
|
45
45
|
|
46
46
|
const uniqueIdentifier = {
|
47
47
|
action: 'withdraw',
|
48
48
|
submitTransactionHash: event.transactionHash,
|
49
|
-
sourceChainId:
|
50
|
-
targetChainId:
|
49
|
+
sourceChainId: sourceChainId,
|
50
|
+
targetChainId: targetChainId,
|
51
51
|
}
|
52
52
|
|
53
53
|
if (await Transaction.findOne({ where: uniqueIdentifier })) {
|
@@ -75,14 +75,18 @@ class SyncWithdrawEvents extends BaseTask {
|
|
75
75
|
|
76
76
|
submitEvent: {
|
77
77
|
to,
|
78
|
-
amount: amount.toString(),
|
79
|
-
|
78
|
+
amount: amount.toString(),
|
79
|
+
itoken: this.itokenAddress,
|
80
|
+
sourceChainId: sourceChainId,
|
81
|
+
targetChainId: targetChainId,
|
80
82
|
},
|
81
83
|
|
82
84
|
sourceEvent: {
|
83
85
|
to,
|
84
86
|
amount: amount.toString(),
|
85
|
-
|
87
|
+
itoken: this.itokenAddress,
|
88
|
+
sourceChainId: sourceChainId,
|
89
|
+
targetChainId: targetChainId,
|
86
90
|
},
|
87
91
|
status: "pending",
|
88
92
|
})
|
@@ -100,8 +104,6 @@ class SyncWithdrawEvents extends BaseTask {
|
|
100
104
|
}
|
101
105
|
|
102
106
|
async start(): Promise<void> {
|
103
|
-
this.logger.info(`Starting execution watcher on interop chain`);
|
104
|
-
|
105
107
|
this.provider = new ethers.providers.JsonRpcProvider(
|
106
108
|
getRpcProviderUrl(this.chainId)
|
107
109
|
);
|
@@ -116,4 +118,4 @@ class SyncWithdrawEvents extends BaseTask {
|
|
116
118
|
}
|
117
119
|
}
|
118
120
|
|
119
|
-
export default
|
121
|
+
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,10 +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 { buildGnosisData } from "@/gnosis";
|
15
16
|
|
16
17
|
const generateGnosisTransaction = async (transactionData: any, safeContract: GnosisSafe) => {
|
17
18
|
console.log(transactionData);
|
18
|
-
|
19
|
+
|
19
20
|
let isExecuted = await safeContract.dataHashes(
|
20
21
|
await safeContract.getTransactionHash(
|
21
22
|
transactionData.to,
|
@@ -97,7 +98,7 @@ class ProcessDepositEvents extends BaseTask {
|
|
97
98
|
}
|
98
99
|
|
99
100
|
console.log(`Processing transaction ${transaction.transactionHash}`);
|
100
|
-
|
101
|
+
|
101
102
|
transaction.targetStatus = 'pending';
|
102
103
|
await transaction.save();
|
103
104
|
|
@@ -121,9 +122,23 @@ class ProcessDepositEvents extends BaseTask {
|
|
121
122
|
const ownersThreshold = await safeContract.getThreshold();
|
122
123
|
await wait(10000);
|
123
124
|
|
125
|
+
let data;
|
126
|
+
|
127
|
+
try {
|
128
|
+
data = await buildGnosisData(transaction);
|
129
|
+
} catch (error) {
|
130
|
+
console.log(error);
|
131
|
+
transaction.targetStatus = 'failed';
|
132
|
+
transaction.targetErrors = [error.message];
|
133
|
+
transaction.status = 'failed'
|
134
|
+
await transaction.save();
|
135
|
+
protocol.sendTransaction(transaction)
|
136
|
+
return;
|
137
|
+
}
|
138
|
+
|
124
139
|
let gnosisTx = await generateGnosisTransaction({
|
125
140
|
baseGas: "0",
|
126
|
-
data
|
141
|
+
data,
|
127
142
|
gasPrice: "0",
|
128
143
|
gasToken: "0x0000000000000000000000000000000000000000",
|
129
144
|
nonce: '0',
|
@@ -142,7 +157,7 @@ class ProcessDepositEvents extends BaseTask {
|
|
142
157
|
console.log(`Collecting signatures for execution ${transaction.transactionHash}`)
|
143
158
|
|
144
159
|
console.log(ownerPeerIds);
|
145
|
-
|
160
|
+
|
146
161
|
const signatures = await protocol.requestSignatures({
|
147
162
|
type: 'source',
|
148
163
|
transactionHash: transaction.transactionHash,
|
@@ -209,19 +224,21 @@ class ProcessDepositEvents extends BaseTask {
|
|
209
224
|
if (parsedLogs.find(e => e.name === 'ExecutionSuccess')) {
|
210
225
|
console.log('ExecutionSuccess')
|
211
226
|
transaction.targetStatus = 'success'
|
227
|
+
transaction.targetTransactionHash = txSent.hash
|
212
228
|
transaction.status = 'success'
|
213
229
|
await transaction.save();
|
214
230
|
} else {
|
215
231
|
console.log('ExecutionFailure')
|
216
232
|
transaction.targetStatus = 'failed'
|
233
|
+
transaction.targetTransactionHash = txSent.hash
|
217
234
|
transaction.status = 'failed'
|
218
235
|
await transaction.save();
|
219
236
|
}
|
237
|
+
|
238
|
+
protocol.sendTransaction(transaction)
|
220
239
|
}
|
221
240
|
|
222
241
|
async start(): Promise<void> {
|
223
|
-
this.logger.info(`Starting execution watcher on interop chain`);
|
224
|
-
|
225
242
|
this.contractAddress = addresses[this.chainId].interopXGateway;
|
226
243
|
|
227
244
|
this.provider = new ethers.providers.JsonRpcProvider(
|
@@ -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 })) {
|
@@ -105,8 +105,6 @@ 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(
|
@@ -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;
|