@instadapp/interop-x 0.0.0-dev.75809ae → 0.0.0-dev.79c1ae5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (95) hide show
  1. package/.env.example +2 -1
  2. package/dist/package.json +73 -0
  3. package/dist/src/abi/erc20.json +350 -0
  4. package/dist/src/abi/gnosisSafe.json +747 -0
  5. package/dist/src/abi/index.js +15 -0
  6. package/dist/src/abi/interopBridgeToken.json +286 -0
  7. package/dist/src/abi/interopXGateway.json +184 -0
  8. package/dist/src/api/index.js +33 -0
  9. package/dist/{config → src/config}/index.js +6 -1
  10. package/dist/src/constants/addresses.js +20 -0
  11. package/dist/{constants → src/constants}/index.js +2 -0
  12. package/dist/src/constants/itokens.js +13 -0
  13. package/dist/src/constants/tokens.js +107 -0
  14. package/dist/{db → src/db}/index.js +0 -0
  15. package/dist/{db → src/db}/models/index.js +1 -1
  16. package/dist/src/db/models/transaction.js +54 -0
  17. package/dist/{db → src/db}/sequelize.js +2 -1
  18. package/dist/src/index.js +103 -0
  19. package/dist/{logger → src/logger}/index.js +0 -0
  20. package/dist/{net → src/net}/index.js +0 -0
  21. package/dist/{net → src/net}/peer/index.js +11 -7
  22. package/dist/{net → src/net}/pool/index.js +29 -11
  23. package/dist/{net → src/net}/protocol/dial/BaseDialProtocol.js +1 -1
  24. package/dist/{net → src/net}/protocol/dial/SignatureDialProtocol.js +22 -14
  25. package/dist/{net → src/net}/protocol/index.js +33 -4
  26. package/dist/src/tasks/AutoUpdateTask.js +43 -0
  27. package/dist/{tasks → src/tasks}/BaseTask.js +3 -3
  28. package/dist/src/tasks/InteropBridge/ProcessWithdrawEvents.js +147 -0
  29. package/dist/src/tasks/InteropBridge/SyncWithdrawEvents.js +70 -0
  30. package/dist/src/tasks/InteropXGateway/ProcessDepositEvents.js +150 -0
  31. package/dist/src/tasks/InteropXGateway/SyncDepositEvents.js +75 -0
  32. package/dist/src/tasks/index.js +42 -0
  33. package/dist/src/typechain/Erc20.js +2 -0
  34. package/dist/src/typechain/GnosisSafe.js +2 -0
  35. package/dist/src/typechain/InteropBridgeToken.js +2 -0
  36. package/dist/src/typechain/InteropXGateway.js +2 -0
  37. package/dist/src/typechain/common.js +2 -0
  38. package/dist/src/typechain/factories/Erc20__factory.js +367 -0
  39. package/dist/src/typechain/factories/GnosisSafe__factory.js +1174 -0
  40. package/dist/src/typechain/factories/InteropBridgeToken__factory.js +459 -0
  41. package/dist/src/typechain/factories/InteropXGateway__factory.js +265 -0
  42. package/dist/src/typechain/factories/index.js +14 -0
  43. package/dist/src/typechain/index.js +35 -0
  44. package/dist/{types.js → src/types.js} +0 -0
  45. package/dist/src/utils/index.js +228 -0
  46. package/package.json +20 -6
  47. package/patches/@ethersproject+properties+5.6.0.patch +13 -0
  48. package/src/abi/erc20.json +350 -0
  49. package/src/abi/gnosisSafe.json +747 -0
  50. package/src/abi/index.ts +11 -0
  51. package/src/abi/interopBridgeToken.json +286 -0
  52. package/src/abi/interopXGateway.json +184 -0
  53. package/src/api/index.ts +33 -0
  54. package/src/config/index.ts +9 -1
  55. package/src/constants/addresses.ts +9 -2
  56. package/src/constants/index.ts +2 -0
  57. package/src/constants/itokens.ts +10 -0
  58. package/src/constants/tokens.ts +104 -0
  59. package/src/db/index.ts +1 -1
  60. package/src/db/models/index.ts +1 -1
  61. package/src/db/models/transaction.ts +96 -0
  62. package/src/db/sequelize.ts +2 -1
  63. package/src/index.ts +90 -6
  64. package/src/net/peer/index.ts +10 -9
  65. package/src/net/pool/index.ts +39 -13
  66. package/src/net/protocol/dial/BaseDialProtocol.ts +1 -1
  67. package/src/net/protocol/dial/SignatureDialProtocol.ts +26 -17
  68. package/src/net/protocol/index.ts +48 -4
  69. package/src/tasks/AutoUpdateTask.ts +55 -0
  70. package/src/tasks/BaseTask.ts +3 -4
  71. package/src/tasks/InteropBridge/ProcessWithdrawEvents.ts +233 -0
  72. package/src/tasks/InteropBridge/SyncWithdrawEvents.ts +121 -0
  73. package/src/tasks/InteropXGateway/ProcessDepositEvents.ts +245 -0
  74. package/src/tasks/InteropXGateway/SyncDepositEvents.ts +126 -0
  75. package/src/tasks/index.ts +24 -1
  76. package/src/typechain/Erc20.ts +491 -0
  77. package/src/typechain/GnosisSafe.ts +1728 -0
  78. package/src/typechain/InteropBridgeToken.ts +686 -0
  79. package/src/typechain/InteropXGateway.ts +407 -0
  80. package/src/typechain/common.ts +44 -0
  81. package/src/typechain/factories/Erc20__factory.ts +368 -0
  82. package/src/typechain/factories/GnosisSafe__factory.ts +1178 -0
  83. package/src/typechain/factories/InteropBridgeToken__factory.ts +466 -0
  84. package/src/typechain/factories/InteropXGateway__factory.ts +272 -0
  85. package/src/typechain/factories/index.ts +7 -0
  86. package/src/typechain/index.ts +12 -0
  87. package/src/types.ts +2 -2
  88. package/src/utils/index.ts +193 -2
  89. package/tsconfig.json +3 -0
  90. package/dist/constants/addresses.js +0 -13
  91. package/dist/db/models/execution.js +0 -38
  92. package/dist/index.js +0 -34
  93. package/dist/tasks/index.js +0 -19
  94. package/dist/utils/index.js +0 -89
  95. package/src/db/models/execution.ts +0 -57
@@ -0,0 +1,96 @@
1
+ import { sequelize } from '@/db/sequelize'
2
+ import { CreationOptional, InferAttributes, InferCreationAttributes, Model, DataTypes } from 'sequelize';
3
+
4
+ export class Transaction extends Model<InferAttributes<Transaction>, InferCreationAttributes<Transaction>> {
5
+ declare id: CreationOptional<number>;
6
+
7
+ declare transactionHash: string;
8
+ declare action: string;
9
+ declare from: string;
10
+ declare to: string;
11
+
12
+ declare submitTransactionHash: string;
13
+ declare submitBlockNumber: number;
14
+
15
+ declare sourceChainId: number;
16
+ declare sourceTransactionHash: CreationOptional<string>;
17
+ declare sourceBlockNumber: CreationOptional<number>;
18
+ declare sourceStatus: string;
19
+ declare sourceErrors: CreationOptional<string[]>;
20
+ declare sourceCreatedAt: CreationOptional<Date>;
21
+ declare sourceDelayUntil: CreationOptional<Date>;
22
+
23
+ declare targetChainId: number;
24
+ declare targetTransactionHash: CreationOptional<string>;
25
+ declare targetBlockNumber: CreationOptional<number>;
26
+ declare targetStatus: string;
27
+ declare targetErrors: CreationOptional<string[]>;
28
+ declare targetCreatedAt: CreationOptional<Date>;
29
+ declare targetDelayUntil: CreationOptional<Date>;
30
+
31
+ declare submitEvent: any;
32
+ declare sourceEvent: CreationOptional<any>;
33
+ declare targetEvent: CreationOptional<any>;
34
+
35
+ declare metadata: CreationOptional<any>;
36
+
37
+ declare status: string;
38
+
39
+ declare createdAt: CreationOptional<Date>;
40
+ declare updatedAt: CreationOptional<Date>;
41
+ }
42
+
43
+ Transaction.init({
44
+ id: {
45
+ type: DataTypes.INTEGER,
46
+ autoIncrement: true,
47
+ primaryKey: true
48
+ },
49
+
50
+ submitTransactionHash: DataTypes.NUMBER,
51
+ submitBlockNumber: DataTypes.NUMBER,
52
+
53
+ transactionHash: DataTypes.STRING,
54
+ action: DataTypes.STRING,
55
+
56
+ from: DataTypes.STRING,
57
+ to: DataTypes.STRING,
58
+
59
+ sourceChainId: DataTypes.NUMBER,
60
+ sourceTransactionHash: DataTypes.STRING,
61
+ sourceBlockNumber: DataTypes.NUMBER,
62
+ sourceStatus: DataTypes.STRING,
63
+ sourceErrors: {
64
+ type: DataTypes.JSON,
65
+ // defaultValue: [],
66
+ },
67
+ sourceCreatedAt: {
68
+ type: DataTypes.DATE,
69
+ defaultValue: Date.now()
70
+ },
71
+ sourceDelayUntil: DataTypes.STRING,
72
+
73
+ targetChainId: DataTypes.NUMBER,
74
+ targetTransactionHash: DataTypes.STRING,
75
+ targetBlockNumber: DataTypes.NUMBER,
76
+ targetStatus: DataTypes.STRING,
77
+ targetErrors: {
78
+ type: DataTypes.JSON,
79
+ // defaultValue: [],
80
+ },
81
+ targetCreatedAt: DataTypes.DATE,
82
+ targetDelayUntil: DataTypes.DATE,
83
+
84
+ submitEvent: DataTypes.JSON,
85
+ sourceEvent: DataTypes.JSON,
86
+ targetEvent: DataTypes.JSON,
87
+
88
+ metadata: DataTypes.JSON,
89
+
90
+ status: {
91
+ type: DataTypes.STRING,
92
+ defaultValue: 'pending'
93
+ },
94
+ createdAt: DataTypes.DATE,
95
+ updatedAt: DataTypes.DATE,
96
+ }, { sequelize, tableName: 'transactions' });
@@ -1,9 +1,10 @@
1
1
  //@ts-ignore
2
+ import config from "@/config";
2
3
  import expandHomeDir from "expand-home-dir";
3
4
 
4
5
  import { Sequelize } from 'sequelize';
5
6
 
6
- const basePath = expandHomeDir('~/.interop-x/data');
7
+ const basePath = expandHomeDir(`~/.interop-x/data/${config.publicAddress}/${config.staging ? 'staging' : ''}`);
7
8
 
8
9
  export const sequelize = new Sequelize({
9
10
  dialect: 'sqlite',
package/src/index.ts CHANGED
@@ -1,14 +1,70 @@
1
- import { assert } from "console";
1
+ import moduleAlias from 'module-alias';
2
+
3
+ moduleAlias.addAliases({
4
+ "@/": __dirname + "/",
5
+ "@/logger": __dirname + "/logger",
6
+ "@/tasks": __dirname + "/tasks",
7
+ "@/utils": __dirname + "/utils",
8
+ "@/api": __dirname + "/api",
9
+ "@/net": __dirname + "/net",
10
+ "@/db": __dirname + "/db",
11
+ "@/config": __dirname + "/config",
12
+ "@/types": __dirname + "/types",
13
+ "@/abi": __dirname + "/abi",
14
+ "@/constants": __dirname + "/constants",
15
+ "@/typechain": __dirname + "/typechain"
16
+ })
17
+
18
+ moduleAlias();
2
19
  import dotenv from "dotenv";
3
- import { Tasks } from "tasks";
4
- import Logger from "./logger";
5
- import { startPeer } from "./net";
20
+ import chalk from 'chalk';
21
+ import { ethers } from "ethers";
22
+ import packageJson from '../package.json'
6
23
  dotenv.config();
7
24
 
8
- assert(process.env.PRIVATE_KEY, "PRIVATE_KEY is not defined");
9
-
25
+ import Logger from "@/logger";
10
26
  const logger = new Logger('Process')
11
27
 
28
+ const printUsage = () => {
29
+ console.log('Usage:')
30
+ console.log(' PRIVATE_KEY=abcd1234 interop-x')
31
+ console.log(' PRIVATE_KEY=abcd1234 STAGING=true interop-x')
32
+ console.log(' PRIVATE_KEY=abcd1234 AUTO_UPDATE=true interop-x')
33
+ console.log(' PRIVATE_KEY=abcd1234 API_HOST=0.0.0.0 API_PORT=8080 interop-x')
34
+ }
35
+
36
+ if (process.argv.at(-1) === 'help') {
37
+ printUsage()
38
+ process.exit(0)
39
+ }
40
+
41
+ const GIT_SHORT_HASH = '@GIT_SHORT_HASH@';
42
+
43
+ if (process.argv.at(-1) === 'version') {
44
+ console.log(`Interop X Node (v${packageJson.version} - rev.${GIT_SHORT_HASH})`)
45
+ process.exit(0)
46
+ }
47
+
48
+ if(! process.env.PRIVATE_KEY) {
49
+ console.error(chalk.bgRed.white.bold('Please provide a private key\n'))
50
+ printUsage()
51
+ process.exit(1)
52
+ }
53
+ try {
54
+ new ethers.Wallet(process.env.PRIVATE_KEY!)
55
+ } catch (e) {
56
+ console.error(chalk.bgRed.white('Invalid private key\n'))
57
+ printUsage()
58
+ process.exit(1)
59
+ }
60
+
61
+ logger.debug(`Starting Interop X Node (v${packageJson.version} - rev.${GIT_SHORT_HASH})`)
62
+
63
+ import { Tasks } from "@/tasks";
64
+ import { startPeer, protocol, peerPool } from "@/net";
65
+ import { startApiServer } from '@/api';
66
+ import { Transaction } from './db';
67
+
12
68
  async function main() {
13
69
 
14
70
  startPeer({})
@@ -16,6 +72,34 @@ async function main() {
16
72
  const tasks = new Tasks()
17
73
 
18
74
  tasks.start();
75
+
76
+ startApiServer()
77
+
78
+ protocol.on('TransactionStatus', async (payload) => {
79
+ if (!peerPool.isLeadNode(payload.peerId)) {
80
+ const peer = peerPool.getPeer(payload.peerId)
81
+ logger.info(`ignored transaction status from ${payload.peerId} ${peer?.publicAddress} `)
82
+ return;
83
+ }
84
+
85
+ const transaction = await Transaction.findOne({ where: { transactionHash: payload.data.transactionHash } })
86
+
87
+ if (!transaction) {
88
+ return;
89
+ }
90
+
91
+ transaction.sourceStatus = payload.data.sourceStatus
92
+ transaction.sourceTransactionHash = payload.data.sourceTransactionHash
93
+ transaction.sourceErrors = payload.data.sourceErrors
94
+
95
+ transaction.targetStatus = payload.data.targetStatus
96
+ transaction.targetTransactionHash = payload.data.targetTransactionHash
97
+ transaction.targetErrors = payload.data.targetErrors
98
+
99
+ transaction.status = payload.data.status
100
+
101
+ await transaction.save()
102
+ })
19
103
  }
20
104
 
21
105
  main()
@@ -5,7 +5,7 @@ import WS from "libp2p-websockets";
5
5
  //@ts-ignore
6
6
  import Mplex from "libp2p-mplex";
7
7
  import { NOISE } from "libp2p-noise";
8
- import Logger from "../../logger";
8
+ import Logger from "@/logger";
9
9
  import Bootstrap from "libp2p-bootstrap";
10
10
  import wait from "waait";
11
11
  import Gossipsub from "@achingbrain/libp2p-gossipsub";
@@ -15,8 +15,8 @@ import MulticastDNS from "libp2p-mdns";
15
15
  import KadDHT from "libp2p-kad-dht";
16
16
  //@ts-ignore
17
17
  import PubsubPeerDiscovery from "libp2p-pubsub-peer-discovery";
18
- import { protocol } from "../protocol";
19
- import config from "../../config";
18
+ import { protocol } from "@/net";
19
+ import config from "@/config";
20
20
 
21
21
  const logger = new Logger("Peer");
22
22
 
@@ -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
- node.connectionManager.on("peer:connect", (connection) =>
95
- logger.log(`Connected to ${connection.remotePeer.toB58String()}`)
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
 
@@ -1,5 +1,10 @@
1
- import { Event } from "../../types";
2
- import config from "../../config";
1
+ import { Event } from "@/types";
2
+ import config from "@/config";
3
+ import Logger from "@/logger";
4
+ import { getAddress } from "ethers/lib/utils";
5
+
6
+
7
+ const logger = new Logger('PeerPool')
3
8
 
4
9
  export interface IPeerInfo {
5
10
  id: string;
@@ -75,10 +80,15 @@ export class PeerPool {
75
80
  * @emits {@link Event.POOL_PEER_ADDED}
76
81
  */
77
82
  add(peer?: IPeerInfo) {
78
- if (peer && peer.id && !this.pool.get(peer.id)) {
83
+ if (peer && peer.id) {
84
+ const newPeer = !this.pool.get(peer.id);
79
85
  this.pool.set(peer.id, peer)
80
86
  peer.pooled = true
81
- config.events.emit(Event.POOL_PEER_ADDED, peer)
87
+
88
+ if (newPeer) {
89
+ config.events.emit(Event.POOL_PEER_ADDED, peer)
90
+ logger.info(`Peer ${peer.id} with address ${peer.publicAddress} added to pool`)
91
+ }
82
92
  }
83
93
  }
84
94
 
@@ -92,6 +102,7 @@ export class PeerPool {
92
102
  if (this.pool.delete(peer.id)) {
93
103
  peer.pooled = false
94
104
  config.events.emit(Event.POOL_PEER_REMOVED, peer)
105
+ logger.info(`Peer ${peer.id} with address ${peer.publicAddress} removed from pool`)
95
106
  }
96
107
  }
97
108
  }
@@ -100,7 +111,7 @@ export class PeerPool {
100
111
  this.cleanup()
101
112
 
102
113
  return this.peers.filter((p) => {
103
- if(!p.pooled) return false;
114
+ if (!p.pooled) return false;
104
115
 
105
116
  const now = new Date()
106
117
 
@@ -113,15 +124,30 @@ export class PeerPool {
113
124
  }
114
125
 
115
126
 
116
- cleanup() {
117
- let compDate = Date.now() - this.PEERS_CLEANUP_TIME_LIMIT * 60
127
+ getPeer(id: string){
128
+ return this.pool.get(id);
129
+ }
118
130
 
119
- this.peers.forEach((peerInfo) => {
120
- if (peerInfo.updated.getTime() < compDate) {
121
- console.log(`Peer ${peerInfo.id} idle for ${this.PEERS_CLEANUP_TIME_LIMIT} minutes`)
122
- this.remove(peerInfo)
123
- }
124
- })
131
+ isLeadNode(id: string) {
132
+ const peer = this.pool.get(id);
133
+
134
+ if (!peer) {
135
+ return false;
136
+ }
137
+
138
+ return getAddress(peer.publicAddress) === getAddress(config.leadNodeAddress)
139
+ }
140
+
141
+
142
+ cleanup() {
143
+ // let compDate = Date.now() - this.PEERS_CLEANUP_TIME_LIMIT * 60
144
+
145
+ // this.peers.forEach((peerInfo) => {
146
+ // if (peerInfo.updated.getTime() < compDate) {
147
+ // console.log(`Peer ${peerInfo.id} idle for ${this.PEERS_CLEANUP_TIME_LIMIT} minutes`)
148
+ // this.remove(peerInfo)
149
+ // }
150
+ // })
125
151
  }
126
152
  }
127
153
 
@@ -1,7 +1,7 @@
1
1
  import pipe from 'it-pipe';
2
2
  import Libp2p from 'libp2p';
3
3
  import PeerId from 'peer-id';
4
- import { asyncCallWithTimeout } from '../../../utils';
4
+ import { asyncCallWithTimeout } from '@/utils';
5
5
  import wait from 'waait';
6
6
 
7
7
  export class BaseDialProtocol<TRequest extends any, TResponse extends any> {
@@ -1,14 +1,14 @@
1
- import { signGnosisSafeTx } from "../../../utils";
2
1
  import { BaseDialProtocol } from "./BaseDialProtocol";
3
2
  import wait from "waait";
4
- import { ChainId } from "../../../types";
5
- import config from "config";
6
- import { addresses } from "../../../constants";
7
- import { Execution } from "db";
3
+ import config from "@/config";
4
+ import { Transaction } from "@/db";
5
+ import { buildDataForTransaction, signGnosisSafeTx } from "@/utils";
6
+ import { addresses } from "@/constants";
7
+ import { ChainId } from "@/types";
8
8
 
9
9
  export interface ISignatureRequest {
10
- type: string,
11
- vnonce: string
10
+ type: 'source' | 'target' ,
11
+ transactionHash: string
12
12
  safeTxGas: string
13
13
  safeNonce: string
14
14
  }
@@ -21,25 +21,25 @@ export class SignatureDialProtocol extends BaseDialProtocol<ISignatureRequest, I
21
21
  protected timeout = 30000;
22
22
 
23
23
  constructor(libp2p) {
24
- super(libp2p, '/signatures')
24
+ super(libp2p, '/interop-x/signatures')
25
25
  }
26
26
 
27
27
  async response(data: ISignatureRequest): Promise<ISignatureResponse> {
28
28
  const signer = config.wallet;
29
29
 
30
- let event: Execution | null;
30
+ let transaction: Transaction | null;
31
31
  let maxTimeout = 20000;
32
32
 
33
33
  do {
34
- event = await Execution.findOne({ where: { vnonce: data.vnonce.toString() } })
34
+ transaction = await Transaction.findOne({ where: { transactionHash: data.transactionHash } })
35
35
 
36
- if (!event) {
36
+ if (!transaction) {
37
37
  await wait(1000);
38
38
  maxTimeout -= 1000;
39
39
  }
40
- } while (!event && maxTimeout > 0)
40
+ } while (!transaction && maxTimeout > 0)
41
41
 
42
- if (!event) {
42
+ if (!transaction) {
43
43
  return {
44
44
  signer: signer.address,
45
45
  data: null,
@@ -47,16 +47,25 @@ export class SignatureDialProtocol extends BaseDialProtocol<ISignatureRequest, I
47
47
  };
48
48
  }
49
49
 
50
+ console.log("signing:", {
51
+ to: addresses[transaction.targetChainId].multisend,
52
+ data: await buildDataForTransaction(transaction, data.type),
53
+ chainId: transaction.targetChainId as ChainId,
54
+ safeTxGas: data.safeTxGas,
55
+ nonce: data.safeNonce,
56
+ });
57
+
50
58
  const signedData = await signGnosisSafeTx({
51
- to: addresses[event.chainId as ChainId].multisend,
52
- data: 'TODO',
53
- chainId: event.chainId as ChainId,
59
+ to: addresses[transaction.targetChainId].multisend,
60
+ data: await buildDataForTransaction(transaction, data.type),
61
+ chainId: transaction.targetChainId as ChainId,
54
62
  safeTxGas: data.safeTxGas,
63
+ nonce: data.safeNonce,
55
64
  }, { signer });
56
65
 
57
66
  return {
58
67
  signer: signer.address,
59
- data: signedData,
68
+ data: signedData
60
69
  }
61
70
  }
62
71
  }
@@ -3,8 +3,9 @@ import Libp2p from 'libp2p';
3
3
  import { bufferToInt, rlp } from 'ethereumjs-util'
4
4
  import { SignatureDialProtocol, ISignatureRequest, ISignatureResponse } from "./dial/SignatureDialProtocol";
5
5
  import { IPeerInfo, peerPool } from "..";
6
- import config from "config";
7
- import { Event } from "types";
6
+ import config from "@/config";
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,13 +58,43 @@ 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
 
58
94
 
59
95
  start({ libp2p, topic = null, }) {
60
96
  this.libp2p = libp2p
61
- this.topic = topic || 'protocol'
97
+ this.topic = topic || 'itnerop-x-protocol'
62
98
 
63
99
  if (this.libp2p.isStarted()) this.init()
64
100
 
@@ -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,55 @@
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 'await-spawn';
6
+ import config from "@/config";
7
+ import wait from "waait";
8
+ const currentVersion = packageJson.version;
9
+
10
+ class AutoUpdateTask extends BaseTask {
11
+ pollIntervalMs: number = 60 * 1000
12
+
13
+ constructor() {
14
+ super({
15
+ logger: new Logger("AutoUpdateTask"),
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
+ await spawn('npm', ['-g', 'install', '@instadapp/interop-x']);
37
+
38
+ this.logger.warn(`Installed version ${version}`)
39
+ this.logger.warn(`Restarting...`)
40
+
41
+ await wait(1000)
42
+
43
+ console.log(process.argv[0], process.argv.slice(1));
44
+
45
+
46
+ spawn(process.argv[0], process.argv.slice(1), {
47
+ cwd: process.cwd(),
48
+ stdio: "inherit"
49
+ });
50
+
51
+ process.exit()
52
+ }
53
+ }
54
+
55
+ export default AutoUpdateTask;
@@ -1,8 +1,7 @@
1
- import config from "config";
2
- import { ethers } from "ethers";
1
+ import config from "@/config";
3
2
  import EventEmitter from "events";
4
3
  import wait from "waait";
5
- import Logger from "../logger";
4
+ import Logger from "@/logger";
6
5
 
7
6
  export interface IBaseTask {
8
7
  pollCheck(): Promise<void>
@@ -38,7 +37,7 @@ export class BaseTask extends EventEmitter implements IBaseTask {
38
37
  await this.pollHandler()
39
38
  }
40
39
  } catch (err) {
41
- this.logger.error(`poll check error: ${err.message}\ntrace: ${err.stack}`)
40
+ this.logger.error(`poll check error:\n${err.message}\ntrace: ${err.stack}`)
42
41
  }
43
42
 
44
43
  await this.postPollHandler()