powerdlz23 1.1.5 โ 1.1.7
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/Zefoy-Automation/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
- package/Zefoy-Automation/README.md +134 -0
- package/Zefoy-Automation/captcha.png +0 -0
- package/Zefoy-Automation/donation-userlist.md +7 -0
- package/Zefoy-Automation/main.py +257 -0
- package/Zefoy-Automation/output/Zefoy Automation for Windows.exe +0 -0
- package/Zefoy-Automation/requirements.txt +5 -0
- package/Zefoy-Automation/src/captcha.png +0 -0
- package/Zefoy-Automation/src/process.py +269 -0
- package/package.json +1 -1
- package/polymer/polymer-template/.env.example +27 -0
- package/polymer/polymer-template/.gitmodules +6 -0
- package/polymer/polymer-template/.gitpod.yml +10 -0
- package/polymer/polymer-template/Justfile +97 -0
- package/polymer/polymer-template/README.md +312 -0
- package/polymer/polymer-template/config/alt-config.json +42 -0
- package/polymer/polymer-template/config.json +42 -0
- package/polymer/polymer-template/contracts/XCounter.sol +89 -0
- package/polymer/polymer-template/contracts/XCounterUC.sol +100 -0
- package/polymer/polymer-template/contracts/arguments.js +7 -0
- package/polymer/polymer-template/contracts/base/CustomChanIbcApp.sol +205 -0
- package/polymer/polymer-template/contracts/base/GeneralMiddleware.sol +200 -0
- package/polymer/polymer-template/contracts/base/UniversalChanIbcApp.sol +93 -0
- package/polymer/polymer-template/foundry.toml +6 -0
- package/polymer/polymer-template/hardhat.config.js +66 -0
- package/polymer/polymer-template/ibc.json +26 -0
- package/polymer/polymer-template/img/gh_template.png +0 -0
- package/polymer/polymer-template/package-lock.json +7672 -0
- package/polymer/polymer-template/package.json +34 -0
- package/polymer/polymer-template/remappings.txt +5 -0
- package/polymer/polymer-template/scripts/deploy.js +51 -0
- package/polymer/polymer-template/scripts/private/_create-channel-config.js +62 -0
- package/polymer/polymer-template/scripts/private/_create-channel.js +96 -0
- package/polymer/polymer-template/scripts/private/_deploy-config.js +62 -0
- package/polymer/polymer-template/scripts/private/_events.js +241 -0
- package/polymer/polymer-template/scripts/private/_helpers.js +113 -0
- package/polymer/polymer-template/scripts/private/_sanity-check-custom.js +69 -0
- package/polymer/polymer-template/scripts/private/_sanity-check-universal.js +120 -0
- package/polymer/polymer-template/scripts/private/_sanity-check.js +21 -0
- package/polymer/polymer-template/scripts/private/_send-packet-config.js +53 -0
- package/polymer/polymer-template/scripts/private/_set-contracts-config.js +50 -0
- package/polymer/polymer-template/scripts/private/_switch-clients.js +90 -0
- package/polymer/polymer-template/scripts/private/_update-vibc-address.js +52 -0
- package/polymer/polymer-template/scripts/private/_vibc-helpers.js +118 -0
- package/polymer/polymer-template/scripts/send-packet.js +38 -0
- package/polymer/polymer-template/scripts/send-universal-packet.js +44 -0
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "ibc-app-solidity-template",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Template project to start building IBC enabled Solidity contracts, with Hardhat and Foundry support",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
8
|
+
},
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "git+https://github.com/open-ibc/ibc-app-solidity-template.git"
|
|
12
|
+
},
|
|
13
|
+
"keywords": [
|
|
14
|
+
"IBC",
|
|
15
|
+
"Solidity"
|
|
16
|
+
],
|
|
17
|
+
"author": "Polymer Labs",
|
|
18
|
+
"license": "MIT",
|
|
19
|
+
"bugs": {
|
|
20
|
+
"url": "https://github.com/open-ibc/ibc-app-solidity-template/issues"
|
|
21
|
+
},
|
|
22
|
+
"homepage": "https://github.com/open-ibc/ibc-app-solidity-template#readme",
|
|
23
|
+
"devDependencies": {
|
|
24
|
+
"@nomicfoundation/hardhat-foundry": "^1.1.1",
|
|
25
|
+
"@nomicfoundation/hardhat-toolbox": "^4.0.0",
|
|
26
|
+
"hardhat": "^2.19.5"
|
|
27
|
+
},
|
|
28
|
+
"dependencies": {
|
|
29
|
+
"@openzeppelin/contracts": "^4.7.6",
|
|
30
|
+
"axios": "^1.6.7",
|
|
31
|
+
"dotenv": "^16.4.1",
|
|
32
|
+
"hardhat-verify": "^1.0.0"
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
// We require the Hardhat Runtime Environment explicitly here. This is optional
|
|
2
|
+
// but useful for running the script in a standalone fashion through `node <script>`.
|
|
3
|
+
//
|
|
4
|
+
// You can also run a script with `npx hardhat run <script>`. If you do that, Hardhat
|
|
5
|
+
// will compile your contracts, add the Hardhat Runtime Environment's members to the
|
|
6
|
+
// global scope, and execute the script.
|
|
7
|
+
const hre = require("hardhat");
|
|
8
|
+
const {getConfigPath} = require('./private/_helpers.js');
|
|
9
|
+
const { getDispatcherAddress, getUcHandlerAddress } = require('./private/_vibc-helpers.js');
|
|
10
|
+
|
|
11
|
+
async function main() {
|
|
12
|
+
const config = require(getConfigPath());
|
|
13
|
+
const argsObject = require('../contracts/arguments.js');
|
|
14
|
+
const networkName = hre.network.name;
|
|
15
|
+
|
|
16
|
+
// The config should have a deploy object with the network name as the key and contract type as the value
|
|
17
|
+
const contractType = config["deploy"][`${networkName}`];
|
|
18
|
+
const args = argsObject[`${contractType}`];
|
|
19
|
+
if (!args) {
|
|
20
|
+
console.warn(`No arguments found for contract type: ${contractType}`);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// TODO: update to switch statement when supporting more networks
|
|
24
|
+
let constructorArgs;
|
|
25
|
+
if (config.isUniversal) {
|
|
26
|
+
const ucHandlerAddr = getUcHandlerAddress(networkName);
|
|
27
|
+
constructorArgs = [ucHandlerAddr, ...(args ?? [])];
|
|
28
|
+
} else if (!config.isUniversal) {
|
|
29
|
+
const dispatcherAddr = getDispatcherAddress(networkName);
|
|
30
|
+
constructorArgs = [dispatcherAddr, ...(args ?? [])];
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Deploy the contract
|
|
34
|
+
// NOTE: when adding additional args to the constructor, add them to the array as well
|
|
35
|
+
const myContract = await hre.ethers.deployContract(contractType, constructorArgs);
|
|
36
|
+
|
|
37
|
+
await myContract.waitForDeployment();
|
|
38
|
+
|
|
39
|
+
// NOTE: Do not change the output string, its output is formatted to be used in the deploy-config.js script
|
|
40
|
+
// to update the config.json file
|
|
41
|
+
console.log(
|
|
42
|
+
`Contract ${contractType} deployed to ${myContract.target} on network ${networkName}`
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// We recommend this pattern to be able to use async/await everywhere
|
|
47
|
+
// and properly handle errors.
|
|
48
|
+
main().catch((error) => {
|
|
49
|
+
console.error(error);
|
|
50
|
+
process.exitCode = 1;
|
|
51
|
+
});
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
const { exec } = require("child_process");
|
|
2
|
+
const { getConfigPath, updateConfigCreateChannel, getWhitelistedNetworks } = require('./_helpers.js');
|
|
3
|
+
const { setupIbcChannelEventListener } = require('./_events.js');
|
|
4
|
+
|
|
5
|
+
// Function to run the deploy script and capture output
|
|
6
|
+
function createChannelAndCapture() {
|
|
7
|
+
const config = require(getConfigPath());
|
|
8
|
+
const srcChain = config.createChannel.srcChain;
|
|
9
|
+
|
|
10
|
+
// Check if the source chain from user input is whitelisted
|
|
11
|
+
const allowedNetworks = getWhitelistedNetworks();
|
|
12
|
+
if (!allowedNetworks.includes(srcChain)) {
|
|
13
|
+
console.error('โ Invalid network name');
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
exec(`npx hardhat run scripts/private/_create-channel.js --network ${srcChain}`, (error, stdout, stderr) => {
|
|
17
|
+
if (error) {
|
|
18
|
+
console.error(`exec error: ${error}`);
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// Process stdout to find the contract address and network
|
|
23
|
+
const output = stdout.trim();
|
|
24
|
+
const match = output.match(/Channel created: (\S+) with portID (\S+) on network (\S+), Counterparty: (\S+) on network (\S+)/);
|
|
25
|
+
|
|
26
|
+
if (match) {
|
|
27
|
+
const channel = match[1];
|
|
28
|
+
const portId = match[2];
|
|
29
|
+
const network = match[3];
|
|
30
|
+
const cpChannel = match[4];
|
|
31
|
+
const cpNetwork = match[5];
|
|
32
|
+
|
|
33
|
+
console.log(`
|
|
34
|
+
๐ Created Channel ๐
|
|
35
|
+
-----------------------------------------
|
|
36
|
+
๐ฃ๏ธ Channel ID: ${channel}
|
|
37
|
+
๐ Port ID: ${portId}
|
|
38
|
+
๐ Network: ${network}
|
|
39
|
+
-----------------------------------------
|
|
40
|
+
๐ฃ๏ธ Counterparty Channel ID: ${cpChannel}
|
|
41
|
+
๐ช Counterparty Network: ${cpNetwork}
|
|
42
|
+
-----------------------------------------\n`
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
// Update the config.json file
|
|
46
|
+
updateConfigCreateChannel(network, channel, cpNetwork, cpChannel);
|
|
47
|
+
console.log(`๐ Updated config.json with ${channel} on network ${network} and ${cpChannel} on network ${cpNetwork}`);
|
|
48
|
+
} else {
|
|
49
|
+
console.error("โ Could not find required parameters in output");
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
async function main() {
|
|
55
|
+
await setupIbcChannelEventListener();
|
|
56
|
+
createChannelAndCapture();
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
main().catch((error) => {
|
|
60
|
+
console.error(error);
|
|
61
|
+
process.exitCode = 1;
|
|
62
|
+
});
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
// We require the Hardhat Runtime Environment explicitly here. This is optional
|
|
2
|
+
// but useful for running the script in a standalone fashion through `node <script>`.
|
|
3
|
+
//
|
|
4
|
+
// You can also run a script with `npx hardhat run <script>`. If you do that, Hardhat
|
|
5
|
+
// will compile your contracts, add the Hardhat Runtime Environment's members to the
|
|
6
|
+
// global scope, and execute the script.
|
|
7
|
+
const hre = require('hardhat');
|
|
8
|
+
const { getConfigPath, addressToPortId } = require('./_helpers');
|
|
9
|
+
const { getIbcApp } = require('./_vibc-helpers.js');
|
|
10
|
+
const ibcConfig = require('../../ibc.json');
|
|
11
|
+
|
|
12
|
+
function createDummyProof() {
|
|
13
|
+
return {
|
|
14
|
+
proof: [
|
|
15
|
+
{
|
|
16
|
+
path: [
|
|
17
|
+
{
|
|
18
|
+
prefix: hre.ethers.toUtf8Bytes("prefixExample1"),
|
|
19
|
+
suffix: hre.ethers.toUtf8Bytes("suffixExample1"),
|
|
20
|
+
},
|
|
21
|
+
// Add more OpIcs23ProofPath objects as needed
|
|
22
|
+
],
|
|
23
|
+
key: hre.ethers.toUtf8Bytes("keyExample"),
|
|
24
|
+
value: hre.ethers.toUtf8Bytes("valueExample"),
|
|
25
|
+
prefix: hre.ethers.toUtf8Bytes("prefixExample")
|
|
26
|
+
},
|
|
27
|
+
// Add more OpIcs23Proof objects as needed
|
|
28
|
+
],
|
|
29
|
+
height: 123456, // example block height
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
async function main() {
|
|
34
|
+
const config = require(getConfigPath());
|
|
35
|
+
const chanConfig = config.createChannel;
|
|
36
|
+
const networkName = hre.network.name;
|
|
37
|
+
|
|
38
|
+
// Get the contract type from the config and get the contract
|
|
39
|
+
const ibcApp = await getIbcApp(networkName);
|
|
40
|
+
const connectedChannelsBefore = await ibcApp.getConnectedChannels();
|
|
41
|
+
|
|
42
|
+
// Prepare the arguments to create the channel
|
|
43
|
+
const connHop1 = ibcConfig[chanConfig.srcChain][`${config.proofsEnabled ? 'op-client' : 'sim-client'}`].canonConnFrom;
|
|
44
|
+
const connHop2 = ibcConfig[chanConfig.dstChain][`${config.proofsEnabled ? 'op-client' : 'sim-client'}`].canonConnTo;
|
|
45
|
+
const srcPortId = addressToPortId(`polyibc.${chanConfig.srcChain}`, chanConfig.srcAddr);
|
|
46
|
+
const dstPortId = addressToPortId(`polyibc.${chanConfig.dstChain}`, chanConfig.dstAddr);
|
|
47
|
+
|
|
48
|
+
const local = {
|
|
49
|
+
portId: srcPortId,
|
|
50
|
+
channelId: hre.ethers.encodeBytes32String(''),
|
|
51
|
+
version: chanConfig.version,
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
const cp = {
|
|
55
|
+
portId: dstPortId,
|
|
56
|
+
channelId: hre.ethers.encodeBytes32String(''),
|
|
57
|
+
version: '',
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
// Create the channel
|
|
61
|
+
// Note: The proofHeight and proof are dummy values and will be dropped in the future
|
|
62
|
+
await ibcApp.createChannel(
|
|
63
|
+
local,
|
|
64
|
+
chanConfig.ordering,
|
|
65
|
+
chanConfig.fees,
|
|
66
|
+
[ connHop1, connHop2 ],
|
|
67
|
+
cp,
|
|
68
|
+
createDummyProof()
|
|
69
|
+
);
|
|
70
|
+
|
|
71
|
+
if (!config.proofsEnabled) {
|
|
72
|
+
// Wait for the channel handshake to complete
|
|
73
|
+
await new Promise((r) => setTimeout(r, 90000));
|
|
74
|
+
|
|
75
|
+
// Get the connected channels and print the new channel along with its counterparty
|
|
76
|
+
const connectedChannelsAfter = await ibcApp.getConnectedChannels();
|
|
77
|
+
|
|
78
|
+
if (connectedChannelsAfter!== undefined && connectedChannelsAfter.length > connectedChannelsBefore.length) {
|
|
79
|
+
|
|
80
|
+
const newChannelBytes = connectedChannelsAfter[connectedChannelsAfter.length - 1].channelId;
|
|
81
|
+
const newChannel = hre.ethers.decodeBytes32String(newChannelBytes);
|
|
82
|
+
|
|
83
|
+
const cpChannelBytes = connectedChannelsAfter[connectedChannelsAfter.length - 1].cpChannelId;
|
|
84
|
+
const cpChannel = hre.ethers.decodeBytes32String(cpChannelBytes);
|
|
85
|
+
|
|
86
|
+
console.log(`โ
Channel created: ${newChannel} with portID ${srcPortId} on network ${networkName}, Counterparty: ${cpChannel} on network ${chanConfig.dstChain}`);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// We recommend this pattern to be able to use async/await everywhere
|
|
92
|
+
// and properly handle errors.
|
|
93
|
+
main().catch((error) => {
|
|
94
|
+
console.error(error);
|
|
95
|
+
process.exitCode = 1;
|
|
96
|
+
});
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
const { exec } = require("child_process");
|
|
2
|
+
const { updateConfigDeploy, getWhitelistedNetworks } = require('./_helpers');
|
|
3
|
+
|
|
4
|
+
// Run script with source and destination networks as arguments
|
|
5
|
+
// Example:
|
|
6
|
+
// $ node deploy-config.js optimism base
|
|
7
|
+
const source = process.argv[2];
|
|
8
|
+
const destination = process.argv[3];
|
|
9
|
+
|
|
10
|
+
if (!source || !destination) {
|
|
11
|
+
console.error('Usage: node deploy-config.js <source_network> <destination_network>');
|
|
12
|
+
process.exit(1);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// Function to run the deploy script and capture output
|
|
16
|
+
function deployAndCapture(network, isSource) {
|
|
17
|
+
const allowedNetworks = getWhitelistedNetworks();
|
|
18
|
+
if (!allowedNetworks.includes(network)) {
|
|
19
|
+
console.error('Invalid network. Please provide a valid network as an argument.');
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
exec(`npx hardhat run scripts/deploy.js --network ${network}`, (error, stdout, stderr) => {
|
|
23
|
+
if (error) {
|
|
24
|
+
console.error(`exec error: ${error}`);
|
|
25
|
+
return;
|
|
26
|
+
} else {
|
|
27
|
+
console.log(stdout);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// Process stdout to find the contract address and network
|
|
31
|
+
const output = stdout.trim();
|
|
32
|
+
const match = output.match(/Contract (\S+) deployed to (\S+) on network (\S+)/);
|
|
33
|
+
|
|
34
|
+
if (match) {
|
|
35
|
+
const contractType = match[1];
|
|
36
|
+
const address = match[2];
|
|
37
|
+
const network = match[3];
|
|
38
|
+
|
|
39
|
+
console.log(`
|
|
40
|
+
โ
Deployment Successful โ
|
|
41
|
+
-------------------------------
|
|
42
|
+
๐ Contract Type: ${contractType}
|
|
43
|
+
๐ Address: ${address}
|
|
44
|
+
๐ Network: ${network}
|
|
45
|
+
-------------------------------\n
|
|
46
|
+
`);
|
|
47
|
+
|
|
48
|
+
// Update the config.json file
|
|
49
|
+
updateConfigDeploy(network, address, isSource);
|
|
50
|
+
console.log(`๐ Updated ${process.env.CONFIG_PATH || 'config.json'} with address ${address} on network ${network}`);
|
|
51
|
+
} else {
|
|
52
|
+
console.error("โ Could not find contract address and network in output");
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function main() {
|
|
58
|
+
deployAndCapture(source, true);
|
|
59
|
+
deployAndCapture(destination, false);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
main();
|
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
const hre = require("hardhat");
|
|
2
|
+
const { areAddressesEqual, getConfigPath } = require("./_helpers.js");
|
|
3
|
+
const { getDispatcher, getUcHandlerAddress } = require("./_vibc-helpers.js");
|
|
4
|
+
|
|
5
|
+
const explorerOpUrl = "https://optimism-sepolia.blockscout.com/";
|
|
6
|
+
const explorerBaseUrl = "https://base-sepolia.blockscout.com/";
|
|
7
|
+
|
|
8
|
+
function filterChannelEvents(portAddress) {
|
|
9
|
+
const config = require(getConfigPath());
|
|
10
|
+
return areAddressesEqual(portAddress, config.createChannel["srcAddr"]) || areAddressesEqual(portAddress, config.createChannel["dstAddr"]);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function listenForIbcChannelEvents(network, source, dispatcher) {
|
|
14
|
+
const explorerUrl = network === "optimism" ? explorerOpUrl : explorerBaseUrl;
|
|
15
|
+
console.log(`๐ Listening for IBC channel events on ${network}...`);
|
|
16
|
+
dispatcher.on(
|
|
17
|
+
"OpenIbcChannel",
|
|
18
|
+
(portAddress, version, ordering, feeEnabled, connectionHops, counterparytPortId, counterpartyChannelId, event) => {
|
|
19
|
+
const txHash = event.log.transactionHash;
|
|
20
|
+
const counterpartyChannelIdString = hre.ethers.decodeBytes32String(counterpartyChannelId);
|
|
21
|
+
const url = `${explorerUrl}tx/${txHash}`;
|
|
22
|
+
|
|
23
|
+
if (filterChannelEvents(portAddress)) {
|
|
24
|
+
console.log(`
|
|
25
|
+
-------------------------------------------`);
|
|
26
|
+
if (source) {
|
|
27
|
+
console.log(`
|
|
28
|
+
๐โโ๏ธ CHANNEL OPEN INIT !!! ๐โโ๏ธ`);
|
|
29
|
+
} else {
|
|
30
|
+
console.log(`
|
|
31
|
+
๐โโ๏ธ CHANNEL OPEN TRY !!! ๐โโ๏ธ`);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
console.log(`
|
|
35
|
+
-------------------------------------------
|
|
36
|
+
๐ Event name: ${event.log.fragment.name}
|
|
37
|
+
โ๏ธ Network: ${network}
|
|
38
|
+
๐ Port Address: ${portAddress}
|
|
39
|
+
๐ Counterparty Port ID: ${counterparytPortId}
|
|
40
|
+
๐ฃ๏ธ Counterparty Channel ID: ${counterpartyChannelIdString}
|
|
41
|
+
๐ฆ Connection Hops: ${connectionHops}
|
|
42
|
+
๐ Ordering: ${ordering}
|
|
43
|
+
๐ฐ Fee Enabled: ${feeEnabled}
|
|
44
|
+
#๏ธโฃ Version: ${version}
|
|
45
|
+
-------------------------------------------
|
|
46
|
+
๐งพ TxHash: ${txHash}
|
|
47
|
+
๐ Explorer URL: ${url}
|
|
48
|
+
-------------------------------------------\n`);
|
|
49
|
+
|
|
50
|
+
if (source) {
|
|
51
|
+
console.log(` โฑ๏ธ Waiting for channel open try...`);
|
|
52
|
+
} else {
|
|
53
|
+
console.log(` โฑ๏ธ Waiting for channel open ack...`);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
);
|
|
58
|
+
|
|
59
|
+
dispatcher.on("ConnectIbcChannel", (portAddress, channelId, event) => {
|
|
60
|
+
const txHash = event.log.transactionHash;
|
|
61
|
+
const channelIdString = hre.ethers.decodeBytes32String(channelId);
|
|
62
|
+
const url = `${explorerUrl}tx/${txHash}`;
|
|
63
|
+
if (filterChannelEvents(portAddress)) {
|
|
64
|
+
console.log(`
|
|
65
|
+
-------------------------------------------`);
|
|
66
|
+
if (source) {
|
|
67
|
+
console.log(`
|
|
68
|
+
๐ฉโโค๏ธโ๐โ๐จ CHANNEL OPEN ACK !!! ๐ฉโโค๏ธโ๐โ๐จ`);
|
|
69
|
+
} else {
|
|
70
|
+
console.log(`
|
|
71
|
+
๐คตโโ๏ธ๐๐ฐโโ๏ธ CHANNEL OPEN CONFIRM !!! ๐ฐโโ๏ธ๐๐คตโโ๏ธ`);
|
|
72
|
+
}
|
|
73
|
+
console.log(`
|
|
74
|
+
-------------------------------------------
|
|
75
|
+
๐ Event name: ${event.log.fragment.name}
|
|
76
|
+
โ๏ธ Network: ${network}
|
|
77
|
+
๐ Port Address: ${portAddress}
|
|
78
|
+
๐ฃ๏ธ Channel ID: ${channelIdString}
|
|
79
|
+
-------------------------------------------
|
|
80
|
+
๐งพ TxHash: ${txHash}
|
|
81
|
+
๐ Explorer URL: ${url}
|
|
82
|
+
-------------------------------------------\n`);
|
|
83
|
+
if (source) {
|
|
84
|
+
console.log(` โฑ๏ธ Waiting for channel open confirm...`);
|
|
85
|
+
} else {
|
|
86
|
+
console.log(` โฑ๏ธ Waiting for channel creation overview...`);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
dispatcher.removeAllListeners();
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
dispatcher.on("CloseIbcChannel", (portAddress, channelId, event) => {
|
|
93
|
+
const txHash = event.log.transactionHash;
|
|
94
|
+
const channelIdString = hre.ethers.decodeBytes32String(channelId);
|
|
95
|
+
const url = `${explorerUrl}tx/${txHash}`;
|
|
96
|
+
if (filterChannelEvents(portAddress)) {
|
|
97
|
+
console.log(`
|
|
98
|
+
-------------------------------------------
|
|
99
|
+
๐ ๐ IBC CHANNEL CLOSED !!! ๐ ๐
|
|
100
|
+
-------------------------------------------
|
|
101
|
+
๐ Event name: ${event.log.fragment.name}
|
|
102
|
+
โ๏ธ Network: ${network}
|
|
103
|
+
๐ Port Address: ${portAddress}
|
|
104
|
+
๐ฃ๏ธ Channel ID: ${channelIdString}
|
|
105
|
+
-------------------------------------------
|
|
106
|
+
๐งพ TxHash: ${txHash}
|
|
107
|
+
๐ Explorer URL: ${url}
|
|
108
|
+
-------------------------------------------\n`);
|
|
109
|
+
}
|
|
110
|
+
dispatcher.removeAllListeners();
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
function filterPacketEvents(portAddress, network) {
|
|
115
|
+
const config = require(getConfigPath());
|
|
116
|
+
const sendPacketConfig = config.sendPacket;
|
|
117
|
+
const ucHandlerAddr = getUcHandlerAddress(network);
|
|
118
|
+
|
|
119
|
+
return areAddressesEqual(portAddress, sendPacketConfig[`${network}`].portAddr) || areAddressesEqual(portAddress, ucHandlerAddr);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function listenForIbcPacketEvents(network, dispatcher) {
|
|
123
|
+
const explorerUrl = network === "optimism" ? explorerOpUrl : explorerBaseUrl;
|
|
124
|
+
console.log(`๐ Listening for IBC packet events on ${network}...`);
|
|
125
|
+
|
|
126
|
+
dispatcher.on("SendPacket", (sourcePortAddress, sourceChannelId, packet, sequence, timeoutTimestamp, event) => {
|
|
127
|
+
const txHash = event.log.transactionHash;
|
|
128
|
+
const sourceChannelIdString = hre.ethers.decodeBytes32String(sourceChannelId);
|
|
129
|
+
const url = `${explorerUrl}tx/${txHash}`;
|
|
130
|
+
|
|
131
|
+
if (filterPacketEvents(sourcePortAddress, network)) {
|
|
132
|
+
console.log(`
|
|
133
|
+
-------------------------------------------
|
|
134
|
+
๐ฆ ๐ฎ PACKET HAS BEEN SENT !!! ๐ฆ ๐ฎ
|
|
135
|
+
-------------------------------------------
|
|
136
|
+
๐ Event name: ${event.log.fragment.name}
|
|
137
|
+
โ๏ธ Network: ${network}
|
|
138
|
+
๐ Source Port Address: ${sourcePortAddress}
|
|
139
|
+
๐ฃ๏ธ Source Channel ID: ${sourceChannelIdString}
|
|
140
|
+
๐ Sequence: ${sequence}
|
|
141
|
+
โณ Timeout Timestamp: ${timeoutTimestamp}
|
|
142
|
+
-------------------------------------------
|
|
143
|
+
๐งพ TxHash: ${txHash}
|
|
144
|
+
๐ Explorer URL: ${url}
|
|
145
|
+
-------------------------------------------\n`);
|
|
146
|
+
console.log(` โฑ๏ธ Waiting for packet receipt...`);
|
|
147
|
+
}
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
dispatcher.on("RecvPacket", (destPortAddress, destChannelId, sequence, event) => {
|
|
151
|
+
const txHash = event.log.transactionHash;
|
|
152
|
+
const destChannelIdString = hre.ethers.decodeBytes32String(destChannelId);
|
|
153
|
+
const url = `${explorerUrl}tx/${txHash}`;
|
|
154
|
+
|
|
155
|
+
if (filterPacketEvents(destPortAddress,network)) {
|
|
156
|
+
console.log(`
|
|
157
|
+
-------------------------------------------
|
|
158
|
+
๐ฆ ๐ฌ PACKET IS RECEIVED !!! ๐ฆ ๐ฌ
|
|
159
|
+
-------------------------------------------
|
|
160
|
+
๐ Event name: ${event.log.fragment.name}
|
|
161
|
+
โ๏ธ Network: ${network}
|
|
162
|
+
๐ Destination Port Address: ${destPortAddress}
|
|
163
|
+
๐ฃ๏ธ Destination Channel ID: ${destChannelIdString}
|
|
164
|
+
๐ Sequence: ${sequence}
|
|
165
|
+
-------------------------------------------
|
|
166
|
+
๐งพ TxHash: ${txHash}
|
|
167
|
+
๐ Explorer URL: ${url}
|
|
168
|
+
-------------------------------------------\n`);
|
|
169
|
+
console.log(` โฑ๏ธ Waiting for write acknowledgement...`);
|
|
170
|
+
}
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
dispatcher.on("WriteAckPacket", (writerPortAddress, writerChannelId, sequence, ackPacket, event) => {
|
|
174
|
+
const txHash = event.log.transactionHash;
|
|
175
|
+
const writerChannelIdString = hre.ethers.decodeBytes32String(writerChannelId);
|
|
176
|
+
const url = `${explorerUrl}tx/${txHash}`;
|
|
177
|
+
if (filterPacketEvents(writerPortAddress, network)) {
|
|
178
|
+
console.log(`
|
|
179
|
+
-------------------------------------------
|
|
180
|
+
๐ฆ ๐ ACKNOWLEDGEMENT WRITTEN !!! ๐ฆ ๐
|
|
181
|
+
-------------------------------------------
|
|
182
|
+
๐ Event name: ${event.log.fragment.name}
|
|
183
|
+
โ๏ธ Network: ${network}
|
|
184
|
+
๐ Destination Port Address: ${writerPortAddress}
|
|
185
|
+
๐ฃ๏ธ Channel ID: ${writerChannelIdString}
|
|
186
|
+
๐ Sequence: ${sequence}
|
|
187
|
+
-------------------------------------------
|
|
188
|
+
๐งพ TxHash: ${txHash}
|
|
189
|
+
๐ Explorer URL: ${url}
|
|
190
|
+
-------------------------------------------\n`);
|
|
191
|
+
console.log(` โฑ๏ธ Waiting for acknowledgement...`);
|
|
192
|
+
}
|
|
193
|
+
dispatcher.removeAllListeners();
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
dispatcher.on("Acknowledgement", (sourcePortAddress, sourceChannelId, sequence, event) => {
|
|
197
|
+
const txHash = event.log.transactionHash;
|
|
198
|
+
const sourceChannelIdString = hre.ethers.decodeBytes32String(sourceChannelId);
|
|
199
|
+
const url = `${explorerUrl}tx/${txHash}`;
|
|
200
|
+
if (filterPacketEvents(sourcePortAddress, network)) {
|
|
201
|
+
console.log(`
|
|
202
|
+
-------------------------------------------
|
|
203
|
+
๐ฆ ๐ PACKET IS ACKNOWLEDGED !!! ๐ฆ ๐
|
|
204
|
+
-------------------------------------------
|
|
205
|
+
๐ Event name: ${event.log.fragment.name}
|
|
206
|
+
โ๏ธ Network: ${network}
|
|
207
|
+
๐ Source Port Address: ${sourcePortAddress}
|
|
208
|
+
๐ฃ๏ธ Source Channel ID: ${sourceChannelIdString}
|
|
209
|
+
๐ Sequence: ${sequence}
|
|
210
|
+
-------------------------------------------
|
|
211
|
+
๐งพ TxHash: ${txHash}
|
|
212
|
+
๐ Explorer URL: ${url}
|
|
213
|
+
-------------------------------------------\n`);
|
|
214
|
+
}
|
|
215
|
+
dispatcher.removeAllListeners();
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
async function setupIbcPacketEventListener() {
|
|
220
|
+
console.log("๐ Setting up IBC packet event listener...")
|
|
221
|
+
// Get the dispatchers for both source and destination to listen for IBC packet events
|
|
222
|
+
const opDispatcher = await getDispatcher("optimism");
|
|
223
|
+
const baseDispatcher = await getDispatcher("base");
|
|
224
|
+
listenForIbcPacketEvents("optimism", opDispatcher);
|
|
225
|
+
listenForIbcPacketEvents("base", baseDispatcher);
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
async function setupIbcChannelEventListener() {
|
|
229
|
+
console.log("๐ Setting up IBC channel event listener...")
|
|
230
|
+
const config = require(getConfigPath());
|
|
231
|
+
const opIsSource = config.createChannel.srcChain === "optimism";
|
|
232
|
+
const baseIsSource = config.createChannel.srcChain === "base";
|
|
233
|
+
|
|
234
|
+
// Get the dispatchers for both source and destination to listen for IBC packet events
|
|
235
|
+
const opDispatcher = await getDispatcher("optimism");
|
|
236
|
+
const baseDispatcher = await getDispatcher("base");
|
|
237
|
+
listenForIbcChannelEvents("optimism", opIsSource , opDispatcher);
|
|
238
|
+
listenForIbcChannelEvents("base", baseIsSource, baseDispatcher);
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
module.exports = { listenForIbcChannelEvents, listenForIbcPacketEvents, setupIbcPacketEventListener, setupIbcChannelEventListener };
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const axios = require('axios');
|
|
3
|
+
const hre = require('hardhat');
|
|
4
|
+
const ibcConfig = require("../../ibc.json");
|
|
5
|
+
|
|
6
|
+
// Function to get the path to the configuration file
|
|
7
|
+
function getConfigPath() {
|
|
8
|
+
const path = require('path');
|
|
9
|
+
const configRelativePath = process.env.CONFIG_PATH ? process.env.CONFIG_PATH : 'config.json';
|
|
10
|
+
// console.log(`๐ Using config file at ${configRelativePath}`);
|
|
11
|
+
const configPath = path.join(__dirname, '../..' , configRelativePath);
|
|
12
|
+
return configPath;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// Function to update config.json
|
|
16
|
+
function updateConfigDeploy(network, address, isSource) {
|
|
17
|
+
try {
|
|
18
|
+
const configPath = getConfigPath();
|
|
19
|
+
const config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
|
|
20
|
+
// Update the config object
|
|
21
|
+
if (!config.isUniversal) {
|
|
22
|
+
if (isSource) {
|
|
23
|
+
config["createChannel"]["srcChain"] = network;
|
|
24
|
+
config["createChannel"]["srcAddr"] = address;
|
|
25
|
+
} else {
|
|
26
|
+
config["createChannel"]["dstChain"] = network;
|
|
27
|
+
config["createChannel"]["dstAddr"] = address;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
config["sendPacket"][`${network}`]["portAddr"] = address;
|
|
31
|
+
} else if (config.isUniversal){
|
|
32
|
+
// When using the universal channel, we can skip channel creation and instead update the sendUniversalPacket field in the config
|
|
33
|
+
const client = config.proofsEnabled ? 'op-client' : 'sim-client';
|
|
34
|
+
config["sendUniversalPacket"][`${network}`]["portAddr"] = address;
|
|
35
|
+
config["sendUniversalPacket"][`${network}`]["channelId"] = ibcConfig[`${network}`][`${client}`]["universalChannel"];
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Write the updated config back to the file
|
|
39
|
+
fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
|
|
40
|
+
} catch (error) {
|
|
41
|
+
console.error('โ Error updating config:', error);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// Function to update config.json
|
|
46
|
+
function updateConfigCreateChannel(network, channel, cpNetwork, cpChannel) {
|
|
47
|
+
try {
|
|
48
|
+
const configPath = getConfigPath();
|
|
49
|
+
const upConfig = JSON.parse(fs.readFileSync(configPath, 'utf8'));
|
|
50
|
+
|
|
51
|
+
// Update the config object
|
|
52
|
+
upConfig["sendPacket"][`${network}`]["channelId"] = channel;
|
|
53
|
+
upConfig["sendPacket"][`${cpNetwork}`]["channelId"] = cpChannel;
|
|
54
|
+
|
|
55
|
+
// Write the updated config back to the file
|
|
56
|
+
fs.writeFileSync(configPath, JSON.stringify(upConfig, null, 2));
|
|
57
|
+
} catch (error) {
|
|
58
|
+
console.error('โ Error updating config:', error);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
async function fetchABI(explorerUrl, contractAddress) {
|
|
63
|
+
try {
|
|
64
|
+
const response = await axios.get(`${explorerUrl}api/v2/smart-contracts/${contractAddress}`);
|
|
65
|
+
if (response.status === 200) {
|
|
66
|
+
const abi = response.data.abi;
|
|
67
|
+
return abi;
|
|
68
|
+
} else {
|
|
69
|
+
console.error(`โ Failed to fetch ABI, status code: ${response.status}`);
|
|
70
|
+
return null;
|
|
71
|
+
}
|
|
72
|
+
} catch (error) {
|
|
73
|
+
console.error('โ Error fetching ABI:', error);
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function areAddressesEqual(address1, address2) {
|
|
79
|
+
// Validate input addresses
|
|
80
|
+
if (!hre.ethers.isAddress(address1) || !hre.ethers.isAddress(address2)) {
|
|
81
|
+
throw new Error('โ One or both addresses are not valid Ethereum addresses');
|
|
82
|
+
}
|
|
83
|
+
// Normalize addresses to checksummed format
|
|
84
|
+
|
|
85
|
+
const checksumAddress1 = hre.ethers.getAddress(address1);
|
|
86
|
+
const checksumAddress2 = hre.ethers.getAddress(address2);
|
|
87
|
+
|
|
88
|
+
// Compare addresses
|
|
89
|
+
const areEqual = checksumAddress1 === checksumAddress2;
|
|
90
|
+
return areEqual;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// Helper function to convert an address to a port ID
|
|
94
|
+
function addressToPortId(portPrefix, address) {
|
|
95
|
+
const config = require(getConfigPath());
|
|
96
|
+
const simAddOn = config.proofsEnabled ? '-proofs-1' :'-sim';
|
|
97
|
+
const suffix = address.slice(2);
|
|
98
|
+
return `${portPrefix}${simAddOn}.${suffix}`;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function getWhitelistedNetworks() {
|
|
102
|
+
return Object.keys(ibcConfig);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
module.exports = {
|
|
106
|
+
getConfigPath,
|
|
107
|
+
updateConfigDeploy,
|
|
108
|
+
updateConfigCreateChannel,
|
|
109
|
+
fetchABI,
|
|
110
|
+
areAddressesEqual,
|
|
111
|
+
addressToPortId,
|
|
112
|
+
getWhitelistedNetworks
|
|
113
|
+
};
|