@instadapp/interop-x 0.0.0-dev.7a02577 → 0.0.0-dev.868731f
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 +5 -2
- package/dist/src/index.js +1 -1
- package/dist/src/net/peer/index.js +6 -2
- package/dist/src/net/pool/index.js +9 -2
- package/dist/src/tasks/BaseTask.js +1 -1
- package/dist/src/tasks/InteropXGateway/ProcessDepositEvents.js +19 -7
- package/dist/src/tasks/InteropXGateway/SyncDepositEvents.js +3 -3
- package/dist/src/tasks/index.js +4 -0
- package/dist/src/utils/index.js +44 -3
- package/package.json +5 -2
- package/patches/@ethersproject+properties+5.6.0.patch +13 -0
- package/src/net/peer/index.ts +7 -6
- package/src/net/pool/index.ts +12 -2
- package/src/tasks/BaseTask.ts +1 -1
- package/src/tasks/InteropXGateway/ProcessDepositEvents.ts +27 -12
- package/src/tasks/InteropXGateway/SyncDepositEvents.ts +5 -5
- package/src/tasks/index.ts +7 -2
- package/src/utils/index.ts +58 -5
package/dist/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@instadapp/interop-x",
|
3
|
-
"version": "0.0.0-dev.
|
3
|
+
"version": "0.0.0-dev.868731f",
|
4
4
|
"license": "MIT",
|
5
5
|
"main": "dist/index.js",
|
6
6
|
"engines": {
|
@@ -12,7 +12,8 @@
|
|
12
12
|
"build": "yarn generate-abi-types && export GIT_REF=$(git rev-parse --short HEAD) && rimraf ./dist && tsc -p tsconfig.json && replace-in-file '@GIT_SHORT_HASH@' $GIT_REF ./dist/**/*.js",
|
13
13
|
"dev": "yarn generate-abi-types && NODE_ENV=development nodemon",
|
14
14
|
"generate-abi-types": "typechain --target=ethers-v5 'src/abi/*.json' --out-dir 'src/typechain'",
|
15
|
-
"prepublishOnly": "yarn build"
|
15
|
+
"prepublishOnly": "yarn build",
|
16
|
+
"postinstall": "patch-package"
|
16
17
|
},
|
17
18
|
"nodemonConfig": {
|
18
19
|
"watch": [
|
@@ -59,6 +60,8 @@
|
|
59
60
|
"@types/fs-extra": "^9.0.13",
|
60
61
|
"@types/node": "^17.0.17",
|
61
62
|
"nodemon": "^2.0.15",
|
63
|
+
"patch-package": "^6.4.7",
|
64
|
+
"postinstall-postinstall": "^2.1.0",
|
62
65
|
"replace-in-file": "^6.3.2",
|
63
66
|
"rimraf": "^3.0.2",
|
64
67
|
"ts-node": "^10.5.0",
|
package/dist/src/index.js
CHANGED
@@ -40,7 +40,7 @@ catch (e) {
|
|
40
40
|
logger.error('Invalid private key');
|
41
41
|
process.exit(1);
|
42
42
|
}
|
43
|
-
logger.debug(`Starting Interop X Node (v${package_json_1.default.version} - rev.
|
43
|
+
logger.debug(`Starting Interop X Node (v${package_json_1.default.version} - rev.868731f)`);
|
44
44
|
const tasks_1 = require("@/tasks");
|
45
45
|
const net_1 = require("@/net");
|
46
46
|
const api_1 = require("@/api");
|
@@ -82,8 +82,12 @@ const startPeer = async ({}) => {
|
|
82
82
|
net_1.protocol.start({
|
83
83
|
libp2p: node
|
84
84
|
});
|
85
|
-
node.on("peer:discovery", (peer) =>
|
86
|
-
|
85
|
+
node.on("peer:discovery", (peer) => {
|
86
|
+
// logger.log(`Discovered peer ${peer}`)
|
87
|
+
}); // peer disc.
|
88
|
+
node.connectionManager.on("peer:connect", (connection) => {
|
89
|
+
// logger.log(`Connected to ${connection.remotePeer.toB58String()}`)
|
90
|
+
});
|
87
91
|
logger.log("Peer discovery started");
|
88
92
|
await (0, waait_1.default)(1000);
|
89
93
|
setInterval(() => net_1.protocol.sendPeerInfo({
|
@@ -6,6 +6,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.peerPool = exports.PeerPool = void 0;
|
7
7
|
const types_1 = require("@/types");
|
8
8
|
const config_1 = __importDefault(require("@/config"));
|
9
|
+
const logger_1 = __importDefault(require("@/logger"));
|
10
|
+
const logger = new logger_1.default('PeerPool');
|
9
11
|
class PeerPool {
|
10
12
|
constructor() {
|
11
13
|
this.PEERS_CLEANUP_TIME_LIMIT = 1;
|
@@ -62,10 +64,14 @@ class PeerPool {
|
|
62
64
|
* @emits {@link Event.POOL_PEER_ADDED}
|
63
65
|
*/
|
64
66
|
add(peer) {
|
65
|
-
if (peer && peer.id
|
67
|
+
if (peer && peer.id) {
|
68
|
+
const newPeer = !this.pool.get(peer.id);
|
66
69
|
this.pool.set(peer.id, peer);
|
67
70
|
peer.pooled = true;
|
68
|
-
|
71
|
+
if (newPeer) {
|
72
|
+
config_1.default.events.emit(types_1.Event.POOL_PEER_ADDED, peer);
|
73
|
+
logger.info(`Peer ${peer.id} with address ${peer.publicAddress} added to pool`);
|
74
|
+
}
|
69
75
|
}
|
70
76
|
}
|
71
77
|
/**
|
@@ -78,6 +84,7 @@ class PeerPool {
|
|
78
84
|
if (this.pool.delete(peer.id)) {
|
79
85
|
peer.pooled = false;
|
80
86
|
config_1.default.events.emit(types_1.Event.POOL_PEER_REMOVED, peer);
|
87
|
+
logger.info(`Peer ${peer.id} with address ${peer.publicAddress} removed from pool`);
|
81
88
|
}
|
82
89
|
}
|
83
90
|
}
|
@@ -28,7 +28,7 @@ class BaseTask extends events_1.default {
|
|
28
28
|
}
|
29
29
|
}
|
30
30
|
catch (err) {
|
31
|
-
this.logger.error(`poll check error
|
31
|
+
this.logger.error(`poll check error:\n${err.message}\ntrace: ${err.stack}`);
|
32
32
|
}
|
33
33
|
await this.postPollHandler();
|
34
34
|
}
|
@@ -15,6 +15,7 @@ const sequelize_1 = require("sequelize");
|
|
15
15
|
const waait_1 = __importDefault(require("waait"));
|
16
16
|
const net_1 = require("@/net");
|
17
17
|
const generateGnosisTransaction = async (transactionData, safeContract) => {
|
18
|
+
console.log(transactionData);
|
18
19
|
let isExecuted = await safeContract.dataHashes(await safeContract.getTransactionHash(transactionData.to, transactionData.value, transactionData.data, transactionData.operation, transactionData.safeTxGas, transactionData.baseGas, transactionData.gasPrice, transactionData.gasToken, transactionData.refundReceiver, transactionData.nonce));
|
19
20
|
while (isExecuted == 1) {
|
20
21
|
transactionData.safeTxGas = ethers_1.BigNumber.from(String(transactionData.safeTxGas)).add(1).toString();
|
@@ -37,30 +38,32 @@ class ProcessDepositEvents extends BaseTask_1.BaseTask {
|
|
37
38
|
where: {
|
38
39
|
status: 'pending',
|
39
40
|
sourceStatus: 'success',
|
41
|
+
targetStatus: 'uninitialised',
|
40
42
|
action: 'deposit',
|
41
43
|
sourceCreatedAt: {
|
42
44
|
[sequelize_1.Op.gte]: new Date(Date.now() - 12 * 60 * 60 * 1000),
|
43
45
|
},
|
44
46
|
sourceBlockNumber: {
|
45
47
|
[sequelize_1.Op.lt]: blockNumber - 12,
|
46
|
-
}
|
48
|
+
},
|
49
|
+
sourceChainId: this.chainId,
|
47
50
|
}
|
48
51
|
});
|
49
52
|
if (!transaction) {
|
50
53
|
return;
|
51
54
|
}
|
52
|
-
transaction.
|
55
|
+
transaction.targetStatus = 'pending';
|
53
56
|
await transaction.save();
|
54
57
|
// refresh event data?
|
55
58
|
const targetChainProvider = new ethers_1.ethers.providers.JsonRpcProvider((0, utils_1.getRpcProviderUrl)(transaction.targetChainId));
|
56
59
|
const targetWallet = new ethers_1.ethers.Wallet(config_1.default.privateKey, targetChainProvider);
|
57
60
|
const safeAddress = constants_1.addresses[transaction.targetChainId].gnosisSafe;
|
58
|
-
const safeContract =
|
61
|
+
const safeContract = (0, utils_1.getContract)(safeAddress, abi_1.default.gnosisSafe, targetWallet);
|
59
62
|
const ownersThreshold = await safeContract.getThreshold();
|
60
63
|
await (0, waait_1.default)(10000);
|
61
64
|
let gnosisTx = await generateGnosisTransaction({
|
62
65
|
baseGas: "0",
|
63
|
-
data: (0, utils_1.buildDataForTransaction)(transaction),
|
66
|
+
data: await (0, utils_1.buildDataForTransaction)(transaction),
|
64
67
|
gasPrice: "0",
|
65
68
|
gasToken: "0x0000000000000000000000000000000000000000",
|
66
69
|
nonce: '0',
|
@@ -74,6 +77,7 @@ class ProcessDepositEvents extends BaseTask_1.BaseTask {
|
|
74
77
|
const owners = await safeContract.getOwners().then(owners => owners.map(owner => owner.toLowerCase()));
|
75
78
|
const ownerPeerIds = net_1.peerPool.activePeers.filter(peer => owners.includes(peer.publicAddress.toLowerCase())).map(peer => peer.id);
|
76
79
|
console.log(`Collecting signatures for execution ${transaction.transactionHash}`);
|
80
|
+
console.log(ownerPeerIds);
|
77
81
|
const signatures = await net_1.protocol.requestSignatures({
|
78
82
|
type: 'source',
|
79
83
|
transactionHash: transaction.transactionHash,
|
@@ -84,8 +88,8 @@ class ProcessDepositEvents extends BaseTask_1.BaseTask {
|
|
84
88
|
console.log({ signatures, validSignatures, ownersThreshold: ownersThreshold.toString() });
|
85
89
|
if (validSignatures.length === 0 || ownersThreshold.gt(validSignatures.length)) {
|
86
90
|
await transaction.save();
|
87
|
-
transaction.
|
88
|
-
transaction.
|
91
|
+
transaction.targetDelayUntil = new Date(Date.now() + 30 * 1000);
|
92
|
+
transaction.targetStatus = 'pending';
|
89
93
|
await transaction.save();
|
90
94
|
const errorMessage = (_a = signatures.find(s => !!s.error)) === null || _a === void 0 ? void 0 : _a.error;
|
91
95
|
throw new Error(`Not enough signatures` + (errorMessage ? `: ${errorMessage}` : ''));
|
@@ -107,6 +111,14 @@ class ProcessDepositEvents extends BaseTask_1.BaseTask {
|
|
107
111
|
execTransactionParams
|
108
112
|
});
|
109
113
|
const { data: txData } = await safeContract.populateTransaction.execTransaction(gnosisTx.to, gnosisTx.value, gnosisTx.data, gnosisTx.operation, gnosisTx.safeTxGas, gnosisTx.baseGas, gnosisTx.gasPrice, gnosisTx.gasToken, gnosisTx.refundReceiver, (0, utils_1.buildSignatureBytes)(validSignatures));
|
114
|
+
console.log({
|
115
|
+
from: targetWallet.address,
|
116
|
+
gasPrice: ethers_1.BigNumber.from(120 * 10 ** 9).toString(),
|
117
|
+
gasLimit: ethers_1.BigNumber.from(6000000).toString(),
|
118
|
+
to: safeAddress,
|
119
|
+
data: txData,
|
120
|
+
});
|
121
|
+
return;
|
110
122
|
const txSent = await targetWallet.sendTransaction({
|
111
123
|
from: targetWallet.address,
|
112
124
|
gasPrice: ethers_1.BigNumber.from(120 * 10 ** 9),
|
@@ -133,7 +145,7 @@ class ProcessDepositEvents extends BaseTask_1.BaseTask {
|
|
133
145
|
this.logger.info(`Starting execution watcher on interop chain`);
|
134
146
|
this.contractAddress = constants_1.addresses[this.chainId].interopXGateway;
|
135
147
|
this.provider = new ethers_1.ethers.providers.JsonRpcProvider((0, utils_1.getRpcProviderUrl)(this.chainId));
|
136
|
-
this.contract =
|
148
|
+
this.contract = (0, utils_1.getContract)(this.contractAddress, abi_1.default.interopXGateway, new ethers_1.ethers.Wallet(config_1.default.privateKey, this.provider));
|
137
149
|
await super.start();
|
138
150
|
}
|
139
151
|
}
|
@@ -45,14 +45,14 @@ class SyncDepositEvents extends BaseTask_1.BaseTask {
|
|
45
45
|
sourceChainId: sourceChainId.toString(),
|
46
46
|
targetChainId: targetChainId.toString(),
|
47
47
|
token: token,
|
48
|
-
|
48
|
+
amount: amount.toString(),
|
49
49
|
vnonce: vnonce.toString(),
|
50
50
|
}, sourceEvent: {
|
51
51
|
user,
|
52
52
|
sourceChainId: sourceChainId.toString(),
|
53
53
|
targetChainId: targetChainId.toString(),
|
54
54
|
token: token,
|
55
|
-
|
55
|
+
amount: amount.toString(),
|
56
56
|
vnonce: vnonce.toString(),
|
57
57
|
}, status: "pending" }));
|
58
58
|
this.logger.info(`Execution queued: ${event.transactionHash} ${event.blockNumber}`);
|
@@ -68,7 +68,7 @@ class SyncDepositEvents extends BaseTask_1.BaseTask {
|
|
68
68
|
this.logger.info(`Starting execution watcher on interop chain`);
|
69
69
|
this.contractAddress = constants_1.addresses[this.chainId].interopXGateway;
|
70
70
|
this.provider = new ethers_1.ethers.providers.JsonRpcProvider((0, utils_1.getRpcProviderUrl)(this.chainId));
|
71
|
-
this.contract =
|
71
|
+
this.contract = (0, utils_1.getContract)(this.contractAddress, abi_1.default.interopXGateway, new ethers_1.ethers.Wallet(config_1.default.privateKey, this.provider));
|
72
72
|
await super.start();
|
73
73
|
}
|
74
74
|
}
|
package/dist/src/tasks/index.js
CHANGED
@@ -4,12 +4,16 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
4
4
|
};
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
6
6
|
exports.Tasks = void 0;
|
7
|
+
const ProcessDepositEvents_1 = __importDefault(require("./InteropXGateway/ProcessDepositEvents"));
|
7
8
|
const SyncDepositEvents_1 = __importDefault(require("./InteropXGateway/SyncDepositEvents"));
|
8
9
|
class Tasks {
|
9
10
|
constructor() {
|
10
11
|
this.tasks = [
|
11
12
|
new SyncDepositEvents_1.default({
|
12
13
|
chainId: 43114
|
14
|
+
}),
|
15
|
+
new ProcessDepositEvents_1.default({
|
16
|
+
chainId: 43114
|
13
17
|
})
|
14
18
|
];
|
15
19
|
}
|
package/dist/src/utils/index.js
CHANGED
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
4
4
|
};
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
6
|
-
exports.buildDataForTransaction = exports.generateInteropTransactionHash = exports.asyncCallWithTimeout = exports.buildSignatureBytes = exports.getRpcProviderUrl = exports.signGnosisSafeTx = exports.short = exports.http = void 0;
|
6
|
+
exports.getContract = exports.buildDataForTransaction = exports.generateInteropTransactionHash = exports.asyncCallWithTimeout = exports.buildSignatureBytes = exports.getRpcProviderUrl = exports.signGnosisSafeTx = exports.short = exports.http = void 0;
|
7
7
|
/**
|
8
8
|
* @module util
|
9
9
|
*/
|
@@ -124,8 +124,8 @@ const buildDataForTransaction = async (transaction, type) => {
|
|
124
124
|
}
|
125
125
|
const targetChainProvider = new ethers_1.ethers.providers.JsonRpcProvider((0, exports.getRpcProviderUrl)(transaction.targetChainId));
|
126
126
|
const targetWallet = new ethers_1.ethers.Wallet(config_1.default.privateKey, targetChainProvider);
|
127
|
-
const interopBridgeContract =
|
128
|
-
const { data } = await interopBridgeContract.populateTransaction.mint(transaction.submitEvent.
|
127
|
+
const interopBridgeContract = getContract(itoken.address, abi_1.default.interopBridgeToken, targetWallet);
|
128
|
+
const { data } = await interopBridgeContract.populateTransaction.mint(transaction.submitEvent.user, ethers_1.ethers.BigNumber.from(transaction.submitEvent.amount.toString()), ethers_1.ethers.BigNumber.from(transaction.submitEvent.sourceChainId.toString()), transaction.sourceTransactionHash);
|
129
129
|
transactions.push({
|
130
130
|
to: itoken.address,
|
131
131
|
data: data,
|
@@ -135,3 +135,44 @@ const buildDataForTransaction = async (transaction, type) => {
|
|
135
135
|
return (0, ethers_multisend_1.encodeMulti)(transactions).data;
|
136
136
|
};
|
137
137
|
exports.buildDataForTransaction = buildDataForTransaction;
|
138
|
+
function getContract(address, contractInterface, signerOrProvider) {
|
139
|
+
if (!ethers_1.ethers.utils.getAddress(address) || address === ethers_1.ethers.constants.AddressZero) {
|
140
|
+
throw Error(`Invalid 'address' parameter '${address}'.`);
|
141
|
+
}
|
142
|
+
const contract = new ethers_1.ethers.Contract(address, contractInterface, signerOrProvider);
|
143
|
+
return new Proxy(contract, {
|
144
|
+
get(target, prop, receiver) {
|
145
|
+
const value = Reflect.get(target, prop, receiver);
|
146
|
+
if (typeof value === 'function' && (contract.functions.hasOwnProperty(prop) || ['queryFilter'].includes(String(prop)))) {
|
147
|
+
return async (...args) => {
|
148
|
+
try {
|
149
|
+
return await value.bind(contract)(...args);
|
150
|
+
}
|
151
|
+
catch (error) {
|
152
|
+
throw new Error(`Error calling "${String(prop)}" on "${address}": ${error.reason || error.message}`);
|
153
|
+
}
|
154
|
+
};
|
155
|
+
}
|
156
|
+
if (typeof value === 'object' && ['populateTransaction', 'estimateGas', 'functions', 'callStatic'].includes(String(prop))) {
|
157
|
+
const parentProp = String(prop);
|
158
|
+
return new Proxy(value, {
|
159
|
+
get(target, prop, receiver) {
|
160
|
+
const value = Reflect.get(target, prop, receiver);
|
161
|
+
if (typeof value === 'function') {
|
162
|
+
return async (...args) => {
|
163
|
+
try {
|
164
|
+
return await value.bind(contract)(...args);
|
165
|
+
}
|
166
|
+
catch (error) {
|
167
|
+
throw new Error(`Error calling "${String(prop)}" using "${parentProp}" on "${address}": ${error.reason || error.message}`);
|
168
|
+
}
|
169
|
+
};
|
170
|
+
}
|
171
|
+
}
|
172
|
+
});
|
173
|
+
}
|
174
|
+
return value;
|
175
|
+
},
|
176
|
+
});
|
177
|
+
}
|
178
|
+
exports.getContract = getContract;
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@instadapp/interop-x",
|
3
|
-
"version": "0.0.0-dev.
|
3
|
+
"version": "0.0.0-dev.868731f",
|
4
4
|
"license": "MIT",
|
5
5
|
"main": "dist/index.js",
|
6
6
|
"engines": {
|
@@ -12,7 +12,8 @@
|
|
12
12
|
"build": "yarn generate-abi-types && export GIT_REF=$(git rev-parse --short HEAD) && rimraf ./dist && tsc -p tsconfig.json && replace-in-file '@GIT_SHORT_HASH@' $GIT_REF ./dist/**/*.js",
|
13
13
|
"dev": "yarn generate-abi-types && NODE_ENV=development nodemon",
|
14
14
|
"generate-abi-types": "typechain --target=ethers-v5 'src/abi/*.json' --out-dir 'src/typechain'",
|
15
|
-
"prepublishOnly": "yarn build"
|
15
|
+
"prepublishOnly": "yarn build",
|
16
|
+
"postinstall": "patch-package"
|
16
17
|
},
|
17
18
|
"nodemonConfig": {
|
18
19
|
"watch": [
|
@@ -59,6 +60,8 @@
|
|
59
60
|
"@types/fs-extra": "^9.0.13",
|
60
61
|
"@types/node": "^17.0.17",
|
61
62
|
"nodemon": "^2.0.15",
|
63
|
+
"patch-package": "^6.4.7",
|
64
|
+
"postinstall-postinstall": "^2.1.0",
|
62
65
|
"replace-in-file": "^6.3.2",
|
63
66
|
"rimraf": "^3.0.2",
|
64
67
|
"ts-node": "^10.5.0",
|
@@ -0,0 +1,13 @@
|
|
1
|
+
diff --git a/node_modules/@ethersproject/properties/lib/index.js b/node_modules/@ethersproject/properties/lib/index.js
|
2
|
+
index 41e0b52..4c7a9e3 100644
|
3
|
+
--- a/node_modules/@ethersproject/properties/lib/index.js
|
4
|
+
+++ b/node_modules/@ethersproject/properties/lib/index.js
|
5
|
+
@@ -44,7 +44,7 @@ function defineReadOnly(object, name, value) {
|
6
|
+
Object.defineProperty(object, name, {
|
7
|
+
enumerable: true,
|
8
|
+
value: value,
|
9
|
+
- writable: false,
|
10
|
+
+ writable: true,
|
11
|
+
});
|
12
|
+
}
|
13
|
+
exports.defineReadOnly = defineReadOnly;
|
package/src/net/peer/index.ts
CHANGED
@@ -88,12 +88,13 @@ export const startPeer = async ({ }: IPeerOptions) => {
|
|
88
88
|
libp2p: node
|
89
89
|
})
|
90
90
|
|
91
|
-
node.on("peer:discovery", (peer) =>
|
92
|
-
logger.log(`Discovered peer ${peer}`)
|
93
|
-
); // peer disc.
|
94
|
-
|
95
|
-
|
96
|
-
|
91
|
+
node.on("peer:discovery", (peer) => {
|
92
|
+
// logger.log(`Discovered peer ${peer}`)
|
93
|
+
}); // peer disc.
|
94
|
+
|
95
|
+
node.connectionManager.on("peer:connect", (connection) => {
|
96
|
+
// logger.log(`Connected to ${connection.remotePeer.toB58String()}`)
|
97
|
+
});
|
97
98
|
|
98
99
|
logger.log("Peer discovery started");
|
99
100
|
|
package/src/net/pool/index.ts
CHANGED
@@ -1,5 +1,9 @@
|
|
1
1
|
import { Event } from "@/types";
|
2
2
|
import config from "@/config";
|
3
|
+
import Logger from "@/logger";
|
4
|
+
|
5
|
+
|
6
|
+
const logger = new Logger('PeerPool')
|
3
7
|
|
4
8
|
export interface IPeerInfo {
|
5
9
|
id: string;
|
@@ -75,10 +79,15 @@ export class PeerPool {
|
|
75
79
|
* @emits {@link Event.POOL_PEER_ADDED}
|
76
80
|
*/
|
77
81
|
add(peer?: IPeerInfo) {
|
78
|
-
if (peer && peer.id
|
82
|
+
if (peer && peer.id) {
|
83
|
+
const newPeer = !this.pool.get(peer.id);
|
79
84
|
this.pool.set(peer.id, peer)
|
80
85
|
peer.pooled = true
|
81
|
-
|
86
|
+
|
87
|
+
if(newPeer) {
|
88
|
+
config.events.emit(Event.POOL_PEER_ADDED, peer)
|
89
|
+
logger.info(`Peer ${peer.id} with address ${peer.publicAddress} added to pool`)
|
90
|
+
}
|
82
91
|
}
|
83
92
|
}
|
84
93
|
|
@@ -92,6 +101,7 @@ export class PeerPool {
|
|
92
101
|
if (this.pool.delete(peer.id)) {
|
93
102
|
peer.pooled = false
|
94
103
|
config.events.emit(Event.POOL_PEER_REMOVED, peer)
|
104
|
+
logger.info(`Peer ${peer.id} with address ${peer.publicAddress} removed from pool`)
|
95
105
|
}
|
96
106
|
}
|
97
107
|
}
|
package/src/tasks/BaseTask.ts
CHANGED
@@ -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
|
40
|
+
this.logger.error(`poll check error:\n${err.message}\ntrace: ${err.stack}`)
|
41
41
|
}
|
42
42
|
|
43
43
|
await this.postPollHandler()
|
@@ -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:
|
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,15 @@ 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
|
},
|
79
82
|
sourceBlockNumber: {
|
80
83
|
[Op.lt]: blockNumber - 12,
|
81
|
-
}
|
84
|
+
},
|
85
|
+
sourceChainId: this.chainId,
|
82
86
|
}
|
83
87
|
})
|
84
88
|
|
@@ -87,7 +91,7 @@ class ProcessDepositEvents extends BaseTask {
|
|
87
91
|
}
|
88
92
|
|
89
93
|
|
90
|
-
transaction.
|
94
|
+
transaction.targetStatus = 'pending';
|
91
95
|
await transaction.save();
|
92
96
|
|
93
97
|
|
@@ -101,19 +105,19 @@ class ProcessDepositEvents extends BaseTask {
|
|
101
105
|
|
102
106
|
const safeAddress = addresses[transaction.targetChainId].gnosisSafe;
|
103
107
|
|
104
|
-
|
108
|
+
|
109
|
+
const safeContract = getContract<GnosisSafe>(
|
105
110
|
safeAddress,
|
106
111
|
abi.gnosisSafe,
|
107
112
|
targetWallet
|
108
|
-
)
|
113
|
+
)
|
109
114
|
|
110
115
|
const ownersThreshold = await safeContract.getThreshold();
|
111
|
-
|
112
116
|
await wait(10000);
|
113
117
|
|
114
118
|
let gnosisTx = await generateGnosisTransaction({
|
115
119
|
baseGas: "0",
|
116
|
-
data: buildDataForTransaction(transaction),
|
120
|
+
data: await buildDataForTransaction(transaction),
|
117
121
|
gasPrice: "0",
|
118
122
|
gasToken: "0x0000000000000000000000000000000000000000",
|
119
123
|
nonce: '0',
|
@@ -131,6 +135,8 @@ class ProcessDepositEvents extends BaseTask {
|
|
131
135
|
|
132
136
|
console.log(`Collecting signatures for execution ${transaction.transactionHash}`)
|
133
137
|
|
138
|
+
console.log(ownerPeerIds);
|
139
|
+
|
134
140
|
const signatures = await protocol.requestSignatures({
|
135
141
|
type: 'source',
|
136
142
|
transactionHash: transaction.transactionHash,
|
@@ -145,8 +151,8 @@ class ProcessDepositEvents extends BaseTask {
|
|
145
151
|
|
146
152
|
if (validSignatures.length === 0 || ownersThreshold.gt(validSignatures.length)) {
|
147
153
|
await transaction.save();
|
148
|
-
transaction.
|
149
|
-
transaction.
|
154
|
+
transaction.targetDelayUntil = new Date(Date.now() + 30 * 1000);
|
155
|
+
transaction.targetStatus = 'pending'
|
150
156
|
|
151
157
|
await transaction.save();
|
152
158
|
const errorMessage = signatures.find(s => !!s.error)?.error;
|
@@ -185,6 +191,15 @@ class ProcessDepositEvents extends BaseTask {
|
|
185
191
|
buildSignatureBytes(validSignatures)
|
186
192
|
);
|
187
193
|
|
194
|
+
console.log({
|
195
|
+
from: targetWallet.address,
|
196
|
+
gasPrice: BigNumber.from(120 * 10 ** 9).toString(),
|
197
|
+
gasLimit: BigNumber.from(6_000_000).toString(),
|
198
|
+
to: safeAddress,
|
199
|
+
data: txData,
|
200
|
+
})
|
201
|
+
return;
|
202
|
+
|
188
203
|
const txSent = await targetWallet.sendTransaction({
|
189
204
|
from: targetWallet.address,
|
190
205
|
gasPrice: BigNumber.from(120 * 10 ** 9),
|
@@ -219,11 +234,11 @@ class ProcessDepositEvents extends BaseTask {
|
|
219
234
|
getRpcProviderUrl(this.chainId)
|
220
235
|
);
|
221
236
|
|
222
|
-
this.contract =
|
237
|
+
this.contract = getContract<InteropXGateway>(
|
223
238
|
this.contractAddress,
|
224
239
|
abi.interopXGateway,
|
225
240
|
new ethers.Wallet(config.privateKey!, this.provider)
|
226
|
-
)
|
241
|
+
);
|
227
242
|
|
228
243
|
await super.start()
|
229
244
|
}
|
@@ -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";
|
@@ -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,7 +86,7 @@ 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",
|
@@ -113,11 +113,11 @@ class SyncDepositEvents extends BaseTask {
|
|
113
113
|
getRpcProviderUrl(this.chainId)
|
114
114
|
);
|
115
115
|
|
116
|
-
this.contract =
|
116
|
+
this.contract = getContract<InteropXGateway>(
|
117
117
|
this.contractAddress,
|
118
118
|
abi.interopXGateway,
|
119
119
|
new ethers.Wallet(config.privateKey!, this.provider)
|
120
|
-
)
|
120
|
+
);
|
121
121
|
|
122
122
|
await super.start()
|
123
123
|
}
|
package/src/tasks/index.ts
CHANGED
@@ -1,10 +1,15 @@
|
|
1
1
|
import { BaseTask } from "./BaseTask";
|
2
|
-
import
|
2
|
+
import InteropXGatewayProcessDepositEvents from "./InteropXGateway/ProcessDepositEvents";
|
3
|
+
import InteropXGatewaySyncDepositEvents from "./InteropXGateway/SyncDepositEvents";
|
3
4
|
|
4
5
|
export class Tasks {
|
5
6
|
|
6
7
|
tasks: BaseTask[] = [
|
7
|
-
new
|
8
|
+
new InteropXGatewaySyncDepositEvents({
|
9
|
+
chainId: 43114
|
10
|
+
}),
|
11
|
+
|
12
|
+
new InteropXGatewayProcessDepositEvents({
|
8
13
|
chainId: 43114
|
9
14
|
})
|
10
15
|
];
|
package/src/utils/index.ts
CHANGED
@@ -138,7 +138,7 @@ export const buildDataForTransaction = async (transaction: Transaction, type?: '
|
|
138
138
|
|
139
139
|
const transactions: MetaTransaction[] = [];
|
140
140
|
|
141
|
-
if(transaction.action != 'deposit') {
|
141
|
+
if (transaction.action != 'deposit') {
|
142
142
|
throw new Error('Invalid action');
|
143
143
|
}
|
144
144
|
|
@@ -165,12 +165,12 @@ export const buildDataForTransaction = async (transaction: Transaction, type?: '
|
|
165
165
|
|
166
166
|
const targetChainProvider = new ethers.providers.JsonRpcProvider(getRpcProviderUrl(transaction.targetChainId as ChainId));
|
167
167
|
const targetWallet = new ethers.Wallet(config.privateKey, targetChainProvider);
|
168
|
-
const interopBridgeContract =
|
168
|
+
const interopBridgeContract = getContract<InteropBridgeToken>(itoken.address, abi.interopBridgeToken, targetWallet);
|
169
169
|
|
170
170
|
const { data } = await interopBridgeContract.populateTransaction.mint(
|
171
|
-
transaction.submitEvent.
|
172
|
-
transaction.submitEvent.amount,
|
173
|
-
transaction.sourceChainId,
|
171
|
+
transaction.submitEvent.user,
|
172
|
+
ethers.BigNumber.from(transaction.submitEvent.amount.toString()),
|
173
|
+
ethers.BigNumber.from(transaction.submitEvent.sourceChainId.toString()),
|
174
174
|
transaction.sourceTransactionHash,
|
175
175
|
);
|
176
176
|
|
@@ -183,3 +183,56 @@ export const buildDataForTransaction = async (transaction: Transaction, type?: '
|
|
183
183
|
|
184
184
|
return encodeMulti(transactions).data
|
185
185
|
}
|
186
|
+
|
187
|
+
|
188
|
+
export function getContract<TContract extends ethers.Contract>(address: string, contractInterface: ethers.ContractInterface | any, signerOrProvider?: ethers.Signer | ethers.providers.Provider) {
|
189
|
+
if (!ethers.utils.getAddress(address) || address === ethers.constants.AddressZero) {
|
190
|
+
throw Error(`Invalid 'address' parameter '${address}'.`)
|
191
|
+
}
|
192
|
+
|
193
|
+
const contract = new ethers.Contract(
|
194
|
+
address,
|
195
|
+
contractInterface,
|
196
|
+
signerOrProvider
|
197
|
+
) as TContract
|
198
|
+
|
199
|
+
|
200
|
+
return new Proxy(contract, {
|
201
|
+
get(target, prop, receiver) {
|
202
|
+
const value = Reflect.get(target, prop, receiver);
|
203
|
+
|
204
|
+
if (typeof value === 'function' && (contract.functions.hasOwnProperty(prop) || ['queryFilter'].includes(String(prop)))) {
|
205
|
+
return async (...args: any[]) => {
|
206
|
+
try {
|
207
|
+
return await value.bind(contract)(...args);
|
208
|
+
} catch (error) {
|
209
|
+
throw new Error(`Error calling "${String(prop)}" on "${address}": ${error.reason || error.message}`)
|
210
|
+
}
|
211
|
+
}
|
212
|
+
}
|
213
|
+
|
214
|
+
|
215
|
+
if (typeof value === 'object' && ['populateTransaction', 'estimateGas', 'functions', 'callStatic'].includes(String(prop))) {
|
216
|
+
const parentProp = String(prop);
|
217
|
+
|
218
|
+
return new Proxy(value, {
|
219
|
+
get(target, prop, receiver) {
|
220
|
+
const value = Reflect.get(target, prop, receiver);
|
221
|
+
|
222
|
+
if (typeof value === 'function') {
|
223
|
+
return async (...args: any[]) => {
|
224
|
+
try {
|
225
|
+
return await value.bind(contract)(...args);
|
226
|
+
} catch (error) {
|
227
|
+
throw new Error(`Error calling "${String(prop)}" using "${parentProp}" on "${address}": ${error.reason || error.message}`)
|
228
|
+
}
|
229
|
+
}
|
230
|
+
}
|
231
|
+
}
|
232
|
+
})
|
233
|
+
}
|
234
|
+
|
235
|
+
return value;
|
236
|
+
},
|
237
|
+
});
|
238
|
+
}
|