@instadapp/interop-x 0.0.0-dev.0b0cc3f

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. package/.env.example +1 -0
  2. package/.github/workflows/publish-dev.yml +30 -0
  3. package/README.md +21 -0
  4. package/bin/interop-x +2 -0
  5. package/dist/abi/erc20.json +350 -0
  6. package/dist/abi/gnosisSafe.json +747 -0
  7. package/dist/abi/index.js +15 -0
  8. package/dist/abi/interopBridgeToken.json +286 -0
  9. package/dist/abi/interopXGateway.json +184 -0
  10. package/dist/config/index.js +17 -0
  11. package/dist/constants/addresses.js +28 -0
  12. package/dist/constants/index.js +17 -0
  13. package/dist/db/index.js +17 -0
  14. package/dist/db/models/index.js +17 -0
  15. package/dist/db/models/transaction.js +52 -0
  16. package/dist/db/sequelize.js +22 -0
  17. package/dist/index.js +43 -0
  18. package/dist/logger/index.js +138 -0
  19. package/dist/net/index.js +19 -0
  20. package/dist/net/peer/index.js +104 -0
  21. package/dist/net/pool/index.js +107 -0
  22. package/dist/net/protocol/dial/BaseDialProtocol.js +106 -0
  23. package/dist/net/protocol/dial/SignatureDialProtocol.js +46 -0
  24. package/dist/net/protocol/index.js +92 -0
  25. package/dist/tasks/BaseTask.js +61 -0
  26. package/dist/tasks/InteropXGateway/SyncDepositEvents.js +79 -0
  27. package/dist/tasks/index.js +27 -0
  28. package/dist/typechain/Erc20.js +2 -0
  29. package/dist/typechain/GnosisSafe.js +2 -0
  30. package/dist/typechain/InteropBridgeToken.js +2 -0
  31. package/dist/typechain/InteropXGateway.js +2 -0
  32. package/dist/typechain/common.js +2 -0
  33. package/dist/typechain/factories/Erc20__factory.js +367 -0
  34. package/dist/typechain/factories/GnosisSafe__factory.js +1174 -0
  35. package/dist/typechain/factories/InteropBridgeToken__factory.js +459 -0
  36. package/dist/typechain/factories/InteropXGateway__factory.js +265 -0
  37. package/dist/typechain/factories/index.js +14 -0
  38. package/dist/typechain/index.js +35 -0
  39. package/dist/types.js +21 -0
  40. package/dist/utils/index.js +101 -0
  41. package/package.json +79 -0
  42. package/src/abi/erc20.json +350 -0
  43. package/src/abi/gnosisSafe.json +747 -0
  44. package/src/abi/index.ts +11 -0
  45. package/src/abi/interopBridgeToken.json +286 -0
  46. package/src/abi/interopXGateway.json +184 -0
  47. package/src/config/index.ts +24 -0
  48. package/src/constants/addresses.ts +25 -0
  49. package/src/constants/index.ts +1 -0
  50. package/src/db/index.ts +1 -0
  51. package/src/db/models/index.ts +1 -0
  52. package/src/db/models/transaction.ts +92 -0
  53. package/src/db/sequelize.ts +21 -0
  54. package/src/index.ts +50 -0
  55. package/src/logger/index.ts +157 -0
  56. package/src/net/index.ts +3 -0
  57. package/src/net/peer/index.ts +119 -0
  58. package/src/net/pool/index.ts +128 -0
  59. package/src/net/protocol/dial/BaseDialProtocol.ts +104 -0
  60. package/src/net/protocol/dial/SignatureDialProtocol.ts +59 -0
  61. package/src/net/protocol/index.ts +138 -0
  62. package/src/tasks/BaseTask.ts +75 -0
  63. package/src/tasks/InteropXGateway/SyncDepositEvents.ts +114 -0
  64. package/src/tasks/index.ts +21 -0
  65. package/src/typechain/Erc20.ts +491 -0
  66. package/src/typechain/GnosisSafe.ts +1728 -0
  67. package/src/typechain/InteropBridgeToken.ts +686 -0
  68. package/src/typechain/InteropXGateway.ts +407 -0
  69. package/src/typechain/common.ts +44 -0
  70. package/src/typechain/factories/Erc20__factory.ts +368 -0
  71. package/src/typechain/factories/GnosisSafe__factory.ts +1178 -0
  72. package/src/typechain/factories/InteropBridgeToken__factory.ts +466 -0
  73. package/src/typechain/factories/InteropXGateway__factory.ts +272 -0
  74. package/src/typechain/factories/index.ts +7 -0
  75. package/src/typechain/index.ts +12 -0
  76. package/src/types.ts +39 -0
  77. package/src/utils/index.ts +129 -0
  78. package/tsconfig.json +30 -0
@@ -0,0 +1,138 @@
1
+ import { EventEmitter } from "stream";
2
+ import Libp2p from 'libp2p';
3
+ import { bufferToInt, rlp } from 'ethereumjs-util'
4
+ import { SignatureDialProtocol, ISignatureRequest, ISignatureResponse } from "./dial/SignatureDialProtocol";
5
+ import { IPeerInfo, peerPool } from "..";
6
+ import config from "@/config";
7
+ import { Event } from "@/types";
8
+
9
+ export interface ProtocolOptions {
10
+ /* Handshake timeout in ms (default: 8000) */
11
+ timeout?: number
12
+ }
13
+
14
+
15
+ export type Message = {
16
+ name: string
17
+ code: number
18
+ payload?: any
19
+ response?: number
20
+ encode: Function
21
+ decode: Function
22
+ }
23
+
24
+ interface BaseMessageEvent {
25
+ peerId: string
26
+ name: string
27
+ code: number
28
+ data: any
29
+ }
30
+
31
+
32
+ interface PeerInfoEvent extends BaseMessageEvent {
33
+ data: Omit<IPeerInfo, 'id' | 'updated' | 'idle' | 'pooled'>
34
+ }
35
+
36
+ declare interface Protocol {
37
+ on(event: 'PeerInfo', listener: (payload: PeerInfoEvent) => void): this;
38
+ on(event: string, listener: (payload: BaseMessageEvent) => void): this;
39
+ }
40
+
41
+ class Protocol extends EventEmitter {
42
+ private libp2p: Libp2p;
43
+ private topic: string;
44
+ private protocolMessages: Message[] = [
45
+ {
46
+ name: 'PeerInfo',
47
+ code: 0x09,
48
+ encode: (info: Pick<IPeerInfo, 'publicAddress'>) => [
49
+ Buffer.from(info.publicAddress),
50
+ ],
51
+ decode: ([publicAddress]: [Buffer]) => ({
52
+ publicAddress: publicAddress.toString(),
53
+ }),
54
+ },
55
+ ];
56
+ private signature: SignatureDialProtocol;
57
+
58
+
59
+ start({ libp2p, topic = null, }) {
60
+ this.libp2p = libp2p
61
+ this.topic = topic || 'itnerop-x-protocol'
62
+
63
+ if (this.libp2p.isStarted()) this.init()
64
+
65
+ this.on('PeerInfo', (payload) => {
66
+
67
+ config.events.emit(Event.PEER_CONNECTED, {
68
+ id: payload.peerId,
69
+ publicAddress: payload.data.publicAddress,
70
+ pooled: false,
71
+ updated: new Date(),
72
+ })
73
+ })
74
+
75
+ this.signature = new SignatureDialProtocol(this.libp2p);
76
+ }
77
+
78
+
79
+ init() {
80
+ this.libp2p.pubsub.subscribe(this.topic)
81
+
82
+ this.libp2p.pubsub.on(this.topic, (message) => {
83
+ try {
84
+ const [codeBuf, payload]: any = rlp.decode(message.data);
85
+
86
+ const code = bufferToInt(codeBuf);
87
+
88
+ const protocolMessage = this.protocolMessages.find((m) => m.code === code);
89
+ if (!protocolMessage) {
90
+ return;
91
+ }
92
+ const decoded = protocolMessage.decode(payload);
93
+ this.emit(
94
+ protocolMessage.name,
95
+ {
96
+ peerId: message.from,
97
+ name: protocolMessage.name,
98
+ code: protocolMessage.code,
99
+ data: decoded
100
+ }
101
+ )
102
+
103
+ this.emit('all', {
104
+ peerId: message.from,
105
+ name: protocolMessage.name,
106
+ code: protocolMessage.code,
107
+ data: decoded,
108
+ })
109
+ } catch (err) {
110
+ console.error(err)
111
+ }
112
+ })
113
+ }
114
+
115
+
116
+ public sendPeerInfo(data: Pick<IPeerInfo, 'publicAddress'>) {
117
+ const message = this.protocolMessages.find((m) => m.name === 'PeerInfo')!
118
+
119
+ const encoded = rlp.encode([message.code, message.encode(data)]);
120
+
121
+ this.libp2p.pubsub.publish(this.topic, encoded)
122
+ }
123
+
124
+ async requestSignatures(data: ISignatureRequest, peerIds?: string[]) {
125
+ try {
126
+ peerIds = peerIds || peerPool.activePeerIds;
127
+ const promises = peerIds.map((peerId) => this.signature.send(data, peerId))
128
+ return (await Promise.allSettled(promises))
129
+ .map((p) => p.status === 'fulfilled' ? p.value : null)
130
+ .filter(Boolean) as ISignatureResponse[]
131
+ } catch (error) {
132
+ console.log(error);
133
+ return []
134
+ }
135
+ }
136
+ }
137
+
138
+ export const protocol = new Protocol();
@@ -0,0 +1,75 @@
1
+ import config from "@/config";
2
+ import EventEmitter from "events";
3
+ import wait from "waait";
4
+ import Logger from "@/logger";
5
+
6
+ export interface IBaseTask {
7
+ pollCheck(): Promise<void>
8
+ prePollHandler(): boolean
9
+ pollHandler(): Promise<void>
10
+ postPollHandler(): Promise<void>
11
+
12
+ start(): Promise<void>
13
+ stop(): Promise<void>
14
+ }
15
+
16
+
17
+ export class BaseTask extends EventEmitter implements IBaseTask {
18
+ logger: Logger
19
+ started: boolean = false
20
+ pollIntervalMs: number = 10 * 1000
21
+ leadNodeOnly: boolean = false
22
+
23
+ public constructor({ logger }: { logger?: Logger }) {
24
+ super()
25
+
26
+ this.logger = logger ?? new Logger('BaseTask')
27
+ }
28
+
29
+ async pollCheck() {
30
+ while (true) {
31
+ if (!this.started) {
32
+ return
33
+ }
34
+ try {
35
+ const shouldPoll = this.prePollHandler()
36
+ if (shouldPoll) {
37
+ await this.pollHandler()
38
+ }
39
+ } catch (err) {
40
+ this.logger.error(`poll check error: ${err.message}\ntrace: ${err.stack}`)
41
+ }
42
+
43
+ await this.postPollHandler()
44
+ }
45
+ }
46
+
47
+ prePollHandler(): boolean {
48
+ if (!this.leadNodeOnly) {
49
+ return true
50
+ }
51
+
52
+ return config.isLeadNode()
53
+ }
54
+
55
+ async pollHandler() {
56
+ this.logger.warn('pollHandler not implemented')
57
+ }
58
+
59
+ async postPollHandler() {
60
+ await wait(this.pollIntervalMs)
61
+ }
62
+
63
+ async start() {
64
+ this.started = true
65
+ try {
66
+ await this.pollCheck()
67
+ } catch (err) {
68
+ this.logger.error(`base task error: ${err.message}\ntrace: ${err.stack}`)
69
+ }
70
+ }
71
+
72
+ async stop() {
73
+ this.started = false
74
+ }
75
+ }
@@ -0,0 +1,114 @@
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, 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 SyncDepositEvents 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::SyncDepositEvents"),
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.LogGatewayDeposit(),
30
+ currentBlock - 2000,
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 { sourceChainId, targetChainId, user, vnonce, amount, token } = event.args;
44
+
45
+ const uniqueIdentifier = {
46
+ type: 'desposit',
47
+ sourceTransactionHash: event.transactionHash,
48
+ sourceChainId: sourceChainId.toNumber(),
49
+ targetChainId: targetChainId.toNumber(),
50
+ }
51
+
52
+ if (await Transaction.findOne({ where: uniqueIdentifier })) {
53
+ continue;
54
+ }
55
+
56
+ const tx = await event.getTransaction()
57
+
58
+ await Transaction.create({
59
+ transactionHash: generateInteropTransactionHash(uniqueIdentifier),
60
+ type: 'deposit',
61
+ from: tx.from,
62
+ to: user,
63
+
64
+ sourceChainId: sourceChainId.toNumber(),
65
+ sourceTransactionHash: event.transactionHash,
66
+ sourceBlockNumber: event.blockNumber,
67
+ sourceStatus: "uninitialised",
68
+
69
+ targetChainId: targetChainId.toNumber(),
70
+ targetStatus: "uninitialised",
71
+
72
+ submitEvent: {
73
+ user,
74
+ sourceChainId: sourceChainId.toString(),
75
+ targetChainId: targetChainId.toString(),
76
+ token: token,
77
+ ammout: amount.toString(),
78
+ vnonce: vnonce.toString(),
79
+ },
80
+ status: "pending",
81
+ })
82
+
83
+ this.logger.info(
84
+ `Execution queued: ${event.transactionHash} ${event.blockNumber}`
85
+ );
86
+ } catch (error) {
87
+ this.logger.error(error);
88
+ }
89
+ }
90
+
91
+ if (processedEvents > 0)
92
+ this.logger.info(`${processedEvents} events processed`);
93
+ }
94
+
95
+ async start(): Promise<void> {
96
+ this.logger.info(`Starting execution watcher on interop chain`);
97
+
98
+ this.contractAddress = addresses[this.chainId].interopXGateway;
99
+
100
+ this.provider = new ethers.providers.JsonRpcProvider(
101
+ getRpcProviderUrl(this.chainId)
102
+ );
103
+
104
+ this.contract = new ethers.Contract(
105
+ this.contractAddress,
106
+ abi.interopXGateway,
107
+ new ethers.Wallet(config.privateKey!, this.provider)
108
+ ) as InteropXGateway;
109
+
110
+ await super.start()
111
+ }
112
+ }
113
+
114
+ export default SyncDepositEvents;
@@ -0,0 +1,21 @@
1
+ import { BaseTask } from "./BaseTask";
2
+ import SyncInteropXGatewayDepositEvents from "./InteropXGateway/SyncDepositEvents";
3
+
4
+ export class Tasks {
5
+
6
+ tasks: BaseTask[] = [
7
+ new SyncInteropXGatewayDepositEvents({
8
+ chainId: 43114
9
+ })
10
+ ];
11
+
12
+ async start() {
13
+ for (const task of this.tasks) {
14
+ try {
15
+ task.start();
16
+ } catch (error) {
17
+ console.error(`Error starting task: ${task.constructor.name}`);
18
+ }
19
+ }
20
+ }
21
+ }