@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.
- package/.env.example +1 -0
- package/.github/workflows/publish-dev.yml +30 -0
- package/README.md +21 -0
- package/bin/interop-x +2 -0
- package/dist/abi/erc20.json +350 -0
- package/dist/abi/gnosisSafe.json +747 -0
- package/dist/abi/index.js +15 -0
- package/dist/abi/interopBridgeToken.json +286 -0
- package/dist/abi/interopXGateway.json +184 -0
- package/dist/config/index.js +17 -0
- package/dist/constants/addresses.js +28 -0
- package/dist/constants/index.js +17 -0
- package/dist/db/index.js +17 -0
- package/dist/db/models/index.js +17 -0
- package/dist/db/models/transaction.js +52 -0
- package/dist/db/sequelize.js +22 -0
- package/dist/index.js +43 -0
- package/dist/logger/index.js +138 -0
- package/dist/net/index.js +19 -0
- package/dist/net/peer/index.js +104 -0
- package/dist/net/pool/index.js +107 -0
- package/dist/net/protocol/dial/BaseDialProtocol.js +106 -0
- package/dist/net/protocol/dial/SignatureDialProtocol.js +46 -0
- package/dist/net/protocol/index.js +92 -0
- package/dist/tasks/BaseTask.js +61 -0
- package/dist/tasks/InteropXGateway/SyncDepositEvents.js +79 -0
- package/dist/tasks/index.js +27 -0
- package/dist/typechain/Erc20.js +2 -0
- package/dist/typechain/GnosisSafe.js +2 -0
- package/dist/typechain/InteropBridgeToken.js +2 -0
- package/dist/typechain/InteropXGateway.js +2 -0
- package/dist/typechain/common.js +2 -0
- package/dist/typechain/factories/Erc20__factory.js +367 -0
- package/dist/typechain/factories/GnosisSafe__factory.js +1174 -0
- package/dist/typechain/factories/InteropBridgeToken__factory.js +459 -0
- package/dist/typechain/factories/InteropXGateway__factory.js +265 -0
- package/dist/typechain/factories/index.js +14 -0
- package/dist/typechain/index.js +35 -0
- package/dist/types.js +21 -0
- package/dist/utils/index.js +101 -0
- package/package.json +79 -0
- package/src/abi/erc20.json +350 -0
- package/src/abi/gnosisSafe.json +747 -0
- package/src/abi/index.ts +11 -0
- package/src/abi/interopBridgeToken.json +286 -0
- package/src/abi/interopXGateway.json +184 -0
- package/src/config/index.ts +24 -0
- package/src/constants/addresses.ts +25 -0
- package/src/constants/index.ts +1 -0
- package/src/db/index.ts +1 -0
- package/src/db/models/index.ts +1 -0
- package/src/db/models/transaction.ts +92 -0
- package/src/db/sequelize.ts +21 -0
- package/src/index.ts +50 -0
- package/src/logger/index.ts +157 -0
- package/src/net/index.ts +3 -0
- package/src/net/peer/index.ts +119 -0
- package/src/net/pool/index.ts +128 -0
- package/src/net/protocol/dial/BaseDialProtocol.ts +104 -0
- package/src/net/protocol/dial/SignatureDialProtocol.ts +59 -0
- package/src/net/protocol/index.ts +138 -0
- package/src/tasks/BaseTask.ts +75 -0
- package/src/tasks/InteropXGateway/SyncDepositEvents.ts +114 -0
- package/src/tasks/index.ts +21 -0
- package/src/typechain/Erc20.ts +491 -0
- package/src/typechain/GnosisSafe.ts +1728 -0
- package/src/typechain/InteropBridgeToken.ts +686 -0
- package/src/typechain/InteropXGateway.ts +407 -0
- package/src/typechain/common.ts +44 -0
- package/src/typechain/factories/Erc20__factory.ts +368 -0
- package/src/typechain/factories/GnosisSafe__factory.ts +1178 -0
- package/src/typechain/factories/InteropBridgeToken__factory.ts +466 -0
- package/src/typechain/factories/InteropXGateway__factory.ts +272 -0
- package/src/typechain/factories/index.ts +7 -0
- package/src/typechain/index.ts +12 -0
- package/src/types.ts +39 -0
- package/src/utils/index.ts +129 -0
- 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
|
+
}
|