powerdlz23 1.1.5 → 1.1.6
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/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
package/package.json
CHANGED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Make sure to rename this file to .env before adding your private keys!!!
|
|
2
|
+
PRIVATE_KEY_1=''
|
|
3
|
+
# Add more if your project requires more private keys
|
|
4
|
+
|
|
5
|
+
# API keys for developer tooling and infra
|
|
6
|
+
OP_ALCHEMY_API_KEY=''
|
|
7
|
+
BASE_ALCHEMY_API_KEY=''
|
|
8
|
+
OP_BLOCKSCOUT_API_KEY=''
|
|
9
|
+
BASE_BLOCKSCOUT_API_KEY=''
|
|
10
|
+
# TENDERLY_TOKEN=''
|
|
11
|
+
|
|
12
|
+
# Contract addresses last updated on 2024-03-05, for public testnet launch
|
|
13
|
+
OP_DISPATCHER='0x58f1863f75c9db1c7266dc3d7b43832b58f35e83'
|
|
14
|
+
BASE_DISPATCHER='0xfc1d3e02e00e0077628e8cc9edb6812f95db05dc'
|
|
15
|
+
|
|
16
|
+
OP_UC_MW='0x34a0e37cCCEdaC70EC1807e5a1f6A4a91D4AE0Ce'
|
|
17
|
+
BASE_UC_MW='0x50E32e236bfE4d514f786C9bC80061637dd5AF98'
|
|
18
|
+
|
|
19
|
+
# Contract addresses for the sim-client
|
|
20
|
+
OP_DISPATCHER_SIM="0x6C9427E8d770Ad9e5a493D201280Cc178125CEc0"
|
|
21
|
+
BASE_DISPATCHER_SIM="0x0dE926fE2001B2c96e9cA6b79089CEB276325E9F"
|
|
22
|
+
|
|
23
|
+
OP_UC_MW_SIM='0xC3318ce027C560B559b09b1aA9cA4FEBDDF252F5'
|
|
24
|
+
BASE_UC_MW_SIM='0x5031fb609569b67608Ffb9e224754bb317f174cD'
|
|
25
|
+
|
|
26
|
+
# Configuration file the scripts will use, defaulting to config.json when not set
|
|
27
|
+
CONFIG_PATH='config.json'
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# This configuration file was automatically generated by Gitpod.
|
|
2
|
+
# Please adjust to your needs (see https://www.gitpod.io/docs/introduction/learn-gitpod/gitpod-yaml)
|
|
3
|
+
# and commit this file to your remote git repository to share the goodness with others.
|
|
4
|
+
|
|
5
|
+
# Learn more from ready-to-use templates: https://www.gitpod.io/docs/introduction/getting-started/quickstart
|
|
6
|
+
|
|
7
|
+
tasks:
|
|
8
|
+
- init: npm install
|
|
9
|
+
|
|
10
|
+
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
# Install dependencies
|
|
2
|
+
install:
|
|
3
|
+
echo "Installing dependencies"
|
|
4
|
+
npm install
|
|
5
|
+
forge install --shallow
|
|
6
|
+
|
|
7
|
+
# Compile contracts using the specified compiler or default to Hardhat
|
|
8
|
+
# The compiler argument is optional; if not provided, it defaults to "hardhat".
|
|
9
|
+
# Usage: just compile [compiler]
|
|
10
|
+
compile COMPILER='hardhat':
|
|
11
|
+
#!/usr/bin/env sh
|
|
12
|
+
if test "{{COMPILER}}" = "hardhat"; then
|
|
13
|
+
echo "Compiling contracts with Hardhat..."
|
|
14
|
+
npx hardhat compile
|
|
15
|
+
elif test "{{COMPILER}}" = "foundry"; then
|
|
16
|
+
echo "Compiling contracts with Foundry..."
|
|
17
|
+
forge build
|
|
18
|
+
else
|
|
19
|
+
echo "Unknown compiler: {{COMPILER}}"
|
|
20
|
+
exit 1
|
|
21
|
+
fi
|
|
22
|
+
|
|
23
|
+
# Update the config.json file with the contract type for a specified chain/rollup
|
|
24
|
+
# The chain and contract-type arguments are REQUIRED;
|
|
25
|
+
# The universal argument is optional; if not provided, it defaults to "true".
|
|
26
|
+
# It indicates whether the contracts to deploy are using custom or universal IBC channels to send packets.
|
|
27
|
+
# Usage: just set-contracts [chain] [contract-type] [universal]
|
|
28
|
+
set-contracts CHAIN CONTRACT_TYPE UNIVERSAL='true':
|
|
29
|
+
echo "Updating config.json with contract type..."
|
|
30
|
+
node scripts/private/_set-contracts-config.js {{CHAIN}} {{CONTRACT_TYPE}} {{UNIVERSAL}}
|
|
31
|
+
|
|
32
|
+
# Deploy the contracts in the /contracts folder using Hardhat and updating the config.json file
|
|
33
|
+
# The source and destination arguments are REQUIRED;
|
|
34
|
+
# Usage: just deploy [source] [destination]
|
|
35
|
+
deploy SOURCE DESTINATION:
|
|
36
|
+
echo "Deploying contracts with Hardhat..."
|
|
37
|
+
node scripts/private/_deploy-config.js {{SOURCE}} {{DESTINATION}}
|
|
38
|
+
|
|
39
|
+
# Run the sanity check script to verify that configuration (.env) files match with deployed contracts' stored values
|
|
40
|
+
# Usage: just sanity-check
|
|
41
|
+
sanity-check:
|
|
42
|
+
echo "Running sanity check..."
|
|
43
|
+
node scripts/private/_sanity-check.js
|
|
44
|
+
|
|
45
|
+
# Update the dispatcher or universal channel handler address on the IBC application, with that from the .env file
|
|
46
|
+
# The chain argument is REQUIRED;
|
|
47
|
+
# Usage: just update-vibc [chain]
|
|
48
|
+
update-vibc CHAIN:
|
|
49
|
+
echo "Updating the dispatcher or universal channel handler address..."
|
|
50
|
+
npx hardhat run scripts/private/_update-vibc-address.js --network {{CHAIN}}
|
|
51
|
+
|
|
52
|
+
# Create a channel by triggering a channel handshake from the source and with parameters found in the config.json file
|
|
53
|
+
# Usage: just create-channel
|
|
54
|
+
create-channel:
|
|
55
|
+
echo "Attempting to create a channel with the values from the config..."
|
|
56
|
+
node scripts/private/_create-channel-config.js
|
|
57
|
+
|
|
58
|
+
# Send a packet over the universal channel or a custom channel as defined in the config.json file
|
|
59
|
+
# The source argument is REQUIRED;
|
|
60
|
+
# Usage: just send-packet [source]
|
|
61
|
+
send-packet SOURCE:
|
|
62
|
+
echo "Sending a packet with the values from the config..."
|
|
63
|
+
node scripts/private/_send-packet-config.js {{SOURCE}}
|
|
64
|
+
|
|
65
|
+
# Switch between the sim client and the client with proofs
|
|
66
|
+
# Usage: just switch-client
|
|
67
|
+
switch-client:
|
|
68
|
+
echo "Switching between sim client and client with proofs..."
|
|
69
|
+
npx hardhat run scripts/private/_update-vibc-address.js --network optimism
|
|
70
|
+
npx hardhat run scripts/private/_update-vibc-address.js --network base
|
|
71
|
+
node scripts/private/_switch-clients.js
|
|
72
|
+
|
|
73
|
+
# Run the full E2E flow by setting the contracts, deploying them, creating a channel, and sending a packet
|
|
74
|
+
# Usage: just do-it
|
|
75
|
+
do-it:
|
|
76
|
+
echo "Running the full E2E flow..."
|
|
77
|
+
just set-contracts optimism XCounter false && just set-contracts base XCounter false
|
|
78
|
+
just deploy optimism base
|
|
79
|
+
just sanity-check
|
|
80
|
+
just create-channel
|
|
81
|
+
just send-packet optimism
|
|
82
|
+
echo "You've done it!"
|
|
83
|
+
|
|
84
|
+
# Clean up the environment by removing the artifacts and cache folders and running the forge clean command
|
|
85
|
+
# Usage: just clean
|
|
86
|
+
clean:
|
|
87
|
+
echo "Cleaning up environment..."
|
|
88
|
+
rm -rf artifacts cache
|
|
89
|
+
forge clean
|
|
90
|
+
|
|
91
|
+
# Fully clean the environment by removing the artifacts, the dependencies, and cache folders and running the forge clean-all command
|
|
92
|
+
# Usage: just clean-all
|
|
93
|
+
clean-all:
|
|
94
|
+
echo "Cleaning up environment..."
|
|
95
|
+
rm -rf artifacts cache
|
|
96
|
+
forge clean
|
|
97
|
+
rm -rf node_modules
|
|
@@ -0,0 +1,312 @@
|
|
|
1
|
+
# ⛓️🔗⛓️ Template for IBC enabled Solidity contracts
|
|
2
|
+
|
|
3
|
+
This repo provides a starter project to build [IBC](https://github.com/cosmos/ibc) enabled Solidity contracts that connect rollups to one another Polymer Hub, through the [vIBC core contracts](https://github.com/open-ibc/vibc-core-smart-contracts).
|
|
4
|
+
|
|
5
|
+
The repository is a _GitHub template_ repository so you can click "Use this template" to create your own project repository without having the entire commit history of the template.
|
|
6
|
+
|
|
7
|
+

|
|
8
|
+
|
|
9
|
+
## 📚 Documentation
|
|
10
|
+
|
|
11
|
+
There's some basic information here in the README but a more comprehensive documentation can be found in [the official Polymer documentation](https://docs.polymerlabs.org/docs/category/build-ibc-dapps-1).
|
|
12
|
+
|
|
13
|
+
## 📋 Prerequisites
|
|
14
|
+
|
|
15
|
+
The repo is **compatible with both Hardhat and Foundry** development environments.
|
|
16
|
+
|
|
17
|
+
- Have [git](https://git-scm.com/downloads) installed
|
|
18
|
+
- Have [node](https://nodejs.org) installed (v18+)
|
|
19
|
+
- Have [Foundry](https://book.getfoundry.sh/getting-started/installation) installed (Hardhat will be installed when running `npm install`)
|
|
20
|
+
- Have [just](https://just.systems/man/en/chapter_1.html) installed (recommended but not strictly necessary)
|
|
21
|
+
|
|
22
|
+
You'll need some API keys from third party's:
|
|
23
|
+
- [Optimism Sepolia](https://optimism-sepolia.blockscout.com/account/api-key) and [Base Sepolia](https://base-sepolia.blockscout.com/account/api-key) Blockscout Explorer API keys
|
|
24
|
+
- Have an [Alchemy API key](https://docs.alchemy.com/docs/alchemy-quickstart-guide) for OP and Base Sepolia
|
|
25
|
+
|
|
26
|
+
Some basic knowledge of all of these tools is also required, although the details are abstracted away for basic usage.
|
|
27
|
+
|
|
28
|
+
## 🧰 Install dependencies
|
|
29
|
+
|
|
30
|
+
To compile your contracts and start testing, make sure that you have all dependencies installed.
|
|
31
|
+
|
|
32
|
+
From the root directory run:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
just install
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
to install the [vIBC core smart contracts](https://github.com/open-ibc/vibc-core-smart-contracts) as a dependency.
|
|
39
|
+
|
|
40
|
+
Additionally Hardhat will be installed as a dev dependency with some useful plugins. Check `package.json` for an exhaustive list.
|
|
41
|
+
|
|
42
|
+
> Note: In case you're experiencing issues with dependencies using the `just install` recipe, check that all prerequisites are correctly installed. If issues persist with forge, try to do the individual dependency installations...
|
|
43
|
+
|
|
44
|
+
## ⚙️ Set up your environment variables
|
|
45
|
+
|
|
46
|
+
Convert the `.env.example` file into an `.env` file. This will ignore the file for future git commits as well as expose the environment variables. Add your private keys and update the other values if you want to customize (advanced usage feature).
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
cp .env.example .env
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
This will enable you to sign transactions with your private key(s). If not added, the scripts from the justfile will fail.
|
|
53
|
+
|
|
54
|
+
### Configuration file
|
|
55
|
+
|
|
56
|
+
The configuration file is where all important data is stored for the just commands and automation. We strive to make direct interaction with the config file as little as possible.
|
|
57
|
+
|
|
58
|
+
By default the configuration file is stored at root as `config.json`.
|
|
59
|
+
|
|
60
|
+
However, it is recommended to split up different contracts/projects in the same repo into different config file in case you want to switch between them.
|
|
61
|
+
|
|
62
|
+
Store alternate config files in the /config directory and set
|
|
63
|
+
```sh
|
|
64
|
+
# .env file
|
|
65
|
+
CONFIG_PATH='config/alt-config.json'
|
|
66
|
+
```
|
|
67
|
+
to use a different config file.
|
|
68
|
+
|
|
69
|
+
### Obtaining testnet ETH
|
|
70
|
+
|
|
71
|
+
The account associated with your private key must have both Base Sepolia and Optimism Sepolia ETH. To obtain the testnet ETH visit:
|
|
72
|
+
|
|
73
|
+
- [Optimism Sepolia Faucet](https://www.alchemy.com/faucets/optimism-sepolia)
|
|
74
|
+
- [Base Sepolia Faucet](https://www.alchemy.com/faucets/base-sepolia)
|
|
75
|
+
|
|
76
|
+
## 🏃🏽🏃🏻♀️ Quickstart
|
|
77
|
+
|
|
78
|
+
The project comes with a built-in dummy application called x-counter (which syncrhonizes a counter across two contracts on remote chains). You can find the contracts in the `/contracts` directory as XCounterUC.sol and XCounter.sol (the former when using the universal channel, the latter when creating a custom IBC channel).
|
|
79
|
+
|
|
80
|
+
### Universal channels
|
|
81
|
+
|
|
82
|
+
The easiest way to get onboarded is to use Universal channels. A universal channel is an IBC channel where the port is owned by Polymer's Universal channel middleware contracts on each chain.
|
|
83
|
+
|
|
84
|
+
When a user deploys a Universal channel compatible contract (this means inheriting the [UniversalChanIbcApp](./contracts/base/UniversalChanIbcApp.sol) base contract), it will be able to connect to the Universal Channel middleware, define Universal packets which will then be wrapped into an IBC packet by the Universal Channel Handler and unwrapped by its counterpart on the destination chain (rollup). The Universal channel middleware on the destination will then unwrap the IBC packet and send the data through to you application on the destination.
|
|
85
|
+
|
|
86
|
+
Find out more about uinversal channels in the [documenation](https://docs.polymerlabs.org/docs/build/ibc-solidity/universal-channel).
|
|
87
|
+
|
|
88
|
+
The configuration file that comes as default in the template repository, allows to quickly send a packet by running:
|
|
89
|
+
|
|
90
|
+
```sh
|
|
91
|
+
just send-packet base
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
To send a packet between the XCounterUC contract on Base Sepolia to OP Sepolia and vice versa.
|
|
95
|
+
|
|
96
|
+
You can find the universal channel middleware details [in the documentation](https://docs.polymerlabs.org/docs/build/supp-networks).
|
|
97
|
+
|
|
98
|
+
Check if the packet got through on the [Polymer IBC explorer](https://sepolia.polymer.zone/packets).
|
|
99
|
+
|
|
100
|
+
### Custom IBC channel
|
|
101
|
+
|
|
102
|
+
There's also a just recipe that quickly enables to try to send packets over a custom IBC channel. Custom IBC channel require a channel hanshake to open a private IBC channel (which can take a while depending on the client latency) but then give complete control over a private IBC channel that enables fault isolation from other applications, compared to unviersal channels.
|
|
103
|
+
|
|
104
|
+
To have your application be compatible with custom IBC channels, have it inherit the [CustomChanIbcApp](./contracts/base/CustomChanIbcApp.sol) base contract.
|
|
105
|
+
|
|
106
|
+
Run the following command to go through a full E2E sweep of the project, using the default XCounter.sol contract:
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
# Usage: just do-it
|
|
110
|
+
just do-it
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
It does the following under the hood:
|
|
114
|
+
```bash
|
|
115
|
+
# Run the full E2E flow by setting the contracts, deploying them, creating a channel, and sending a packet
|
|
116
|
+
# Usage: just do-it
|
|
117
|
+
do-it:
|
|
118
|
+
echo "Running the full E2E flow..."
|
|
119
|
+
just set-contracts optimism XCounter false && just set-contracts base XCounter false
|
|
120
|
+
just deploy optimism base
|
|
121
|
+
just create-channel
|
|
122
|
+
just send-packet optimism
|
|
123
|
+
echo "You've done it!"
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
It makes sure you've got the correct contracts set, deploys new instances, creates a channel and sends a packet over the channel once created.
|
|
127
|
+
|
|
128
|
+
> Note: by default the sim-client is used to improve latency. This is useful for iterative development and testing BUT also insecure as it involves no proofs. Make sure to move to the client **with proofs** by running another just command...
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
# Usage: just switch-client
|
|
132
|
+
just switch-client
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
Check if the packet got through on the [Polymer IBC explorer](https://sepolia.polymer.zone/packets).
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
## 💻 Develop your custom application
|
|
139
|
+
|
|
140
|
+
The main work for you as a developer is to develop the contracts that make up your cross-chain logic.
|
|
141
|
+
|
|
142
|
+
You can use the contracts in the "/contracts/base" directory as base contracts for creating IBC enabled contracts that can either send packets over the universal channel or create their own channel to send packets over.
|
|
143
|
+
|
|
144
|
+
A complete walkthrough on how to develop these contracts is provided in the [official Polymer documentation](https://docs.polymerlabs.org/docs/build/ibc-solidity/).
|
|
145
|
+
|
|
146
|
+
## 🕹️ Interaction with the contracts
|
|
147
|
+
|
|
148
|
+
When the contracts are ready, you can go ahead and interact with the contracts through scripts. There is a Justfile to for the most common commands, with the underlying scripts in the /scripts folder.
|
|
149
|
+
|
|
150
|
+
The `/private` folder within the scripts folder has scripts that you're unlikely to need to touch. The only scripts you'll (potentially) be interacting with are:
|
|
151
|
+
|
|
152
|
+
There's three types of default scripts in the project:
|
|
153
|
+
|
|
154
|
+
- The `deploy.js` allows you to deploy your application contract. You may want to add additional deployment logic to the Hardhat script.
|
|
155
|
+
- In the `/contracts` folder you'll find `arguments.js` to add your custom constructor arguments for automated deployment with the `deploy.js` script.
|
|
156
|
+
- The `send-packet.js` script sends packets over an existing custom channel, and `send-universal-packet.js` is specifically for sending packets over a universal channel. You might want to add additional logic before or after sending the packet to cusotmize your application.
|
|
157
|
+
|
|
158
|
+
For most of the actions above and more, there are just recipes that combine related logic and update the configuation file in an automated way.
|
|
159
|
+
|
|
160
|
+
> **Note**: These are the default scripts provided. They provide the most generic interactions with the contracts to deploy, create channels and send packets. For more complicated use cases you will want to customize the scripts to your use case. See [advanced usage](#🦾-advanced-usage) for more info.
|
|
161
|
+
|
|
162
|
+
### Deploy
|
|
163
|
+
|
|
164
|
+
Before deploying, make sure to update the config.json with your contract type to deploy for each of the chain you wish to deploy to.
|
|
165
|
+
|
|
166
|
+
#### Set contracts to config
|
|
167
|
+
|
|
168
|
+
Do this by running:
|
|
169
|
+
|
|
170
|
+
```bash
|
|
171
|
+
# Usage: just set-contracts [chain] [contract_type] [universal]
|
|
172
|
+
just set-contracts optimism MyContract true
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
to deploy _MyContract_ artefact to the Optimism (Sepolia) chain.
|
|
176
|
+
|
|
177
|
+
> **IMPORTANT**: This is where you set if your contract uses universal or custom channels. Make sure this corresponds to the base contract you've inherited from when developing your application (UniversalChanIbcApp or CustomChanIbcApp).
|
|
178
|
+
|
|
179
|
+
#### Constructor arguments
|
|
180
|
+
|
|
181
|
+
By default any application inheriting a base IBC application contract will need a dispatcher or universal channel handler address passed into the constructor. Obviously you might have other constructor arguments you may want to add. To still make use of the `just deploy source destination` recipe, add your arguments to the arguments.js file
|
|
182
|
+
|
|
183
|
+
```javascript title="/contracts/arguments.js"
|
|
184
|
+
module.exports = {
|
|
185
|
+
"XCounter": [],
|
|
186
|
+
"XCounterUC": [],
|
|
187
|
+
// Add your contract types here, along with the list of custom constructor arguments
|
|
188
|
+
// DO NOT ADD THE DISPATCHER OR UNIVERSAL CHANNEL HANDLER ADDRESSES HERE!!!
|
|
189
|
+
// These will be added in the deploy script at $ROOT/scripts/deploy.js
|
|
190
|
+
};
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
#### Finally: deploy
|
|
194
|
+
|
|
195
|
+
Then run:
|
|
196
|
+
|
|
197
|
+
```bash
|
|
198
|
+
# Usage: just deploy [source] [destination]
|
|
199
|
+
just deploy optimism base
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
where the script will automatically detect whether you are using custom or universal IBC channels.
|
|
203
|
+
|
|
204
|
+
The script will take the output of the deployment and update the config file with all the relevant information.
|
|
205
|
+
|
|
206
|
+
Before moving on, you'll want to check if the variables in your .env and config files line up with what is stored in the actual deployed contracts... especially when you're actively playing around with different configuration files and contracts.
|
|
207
|
+
|
|
208
|
+
To do a sanity check, run:
|
|
209
|
+
```bash
|
|
210
|
+
# Usage: just sanity-check
|
|
211
|
+
just sanity-check
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
### Create a channel
|
|
215
|
+
|
|
216
|
+
If you're **using universal channels, channel creation is not required**. Your contract will send and receive packet data from the Universal channel handler contract which already has a universal channel to send packets over. You can directly proceed to sending (universal) packets in that case.
|
|
217
|
+
|
|
218
|
+
To create a custom channel, run:
|
|
219
|
+
|
|
220
|
+
```bash
|
|
221
|
+
just create-channel
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
This creates a channel between base and optimism. Note that the **ORDER MATTERS**; if you picked optimism as the source chain (first argument) above, by default it will create the channel from optimism and vice versa.
|
|
225
|
+
|
|
226
|
+
The script will take the output of the channel creation and update the config file with all the relevant information.
|
|
227
|
+
|
|
228
|
+
Check out the [channel tab in the explorer](https://sepolia.polymer.zone/channels) to find out if the correct channel-id's related to your contracts were updated in the config.
|
|
229
|
+
|
|
230
|
+
### Send packets
|
|
231
|
+
|
|
232
|
+
Finally Run:
|
|
233
|
+
|
|
234
|
+
```bash
|
|
235
|
+
# Usage: just send-packet
|
|
236
|
+
just send-packet optimism
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
to send a packet over a channel (script looks at the config's isUniversal flag to know if it should use the custom or universal packet). You can pick either optimism or base to send the packet from.
|
|
240
|
+
|
|
241
|
+
## Verify, don't trust
|
|
242
|
+
|
|
243
|
+
As a starter value, the sim-client is used to improve latency. **The sim-client is useful for iterative development and testing BUT also insecure as it involves no proofs**. Make sure to move to the client **with proofs** by running another just command...
|
|
244
|
+
|
|
245
|
+
```bash
|
|
246
|
+
# Usage: just switch-client
|
|
247
|
+
just switch-client
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
This will use the op-stack client with proofs, making sure that the relayer is proving what is being submitted every step along the way, ensuring there's no trust assumption on the relayer.
|
|
251
|
+
|
|
252
|
+
An overview of the different clients can be found in `ibc.json`:
|
|
253
|
+
```json
|
|
254
|
+
{
|
|
255
|
+
"optimism": {
|
|
256
|
+
"sim-client": {
|
|
257
|
+
"canonConnFrom": "connection-0",
|
|
258
|
+
"canonConnTo": "connection-1",
|
|
259
|
+
"universalChannel": "channel-10"
|
|
260
|
+
},
|
|
261
|
+
"op-client": {
|
|
262
|
+
"canonConnFrom": "connection-8",
|
|
263
|
+
"canonConnTo": "connection-9",
|
|
264
|
+
"universalChannel": "channel-16"
|
|
265
|
+
}
|
|
266
|
+
},
|
|
267
|
+
"base": {
|
|
268
|
+
"sim-client" : {
|
|
269
|
+
"canonConnFrom": "connection-4",
|
|
270
|
+
"canonConnTo": "connection-5",
|
|
271
|
+
"universalChannel": "channel-11"
|
|
272
|
+
},
|
|
273
|
+
"op-client": {
|
|
274
|
+
"canonConnFrom": "connection-10",
|
|
275
|
+
"canonConnTo": "connection-11",
|
|
276
|
+
"universalChannel": "channel-17"
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
## 🦾 Advanced usage
|
|
283
|
+
|
|
284
|
+
For advanced users, there's multiple custimizations to follow. These includes configuring the config.json manually and/or running the scripts without using just.
|
|
285
|
+
|
|
286
|
+
For example, the last action to send a packet on a universal channel could be executed with this command:
|
|
287
|
+
|
|
288
|
+
```bash
|
|
289
|
+
npx hardhat run scripts/send-universal-packet.js --network base
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
To send a universal packet from the contract specified in the config.sendUniversalPacket field in the config.
|
|
293
|
+
|
|
294
|
+
## 🤝 Contributing
|
|
295
|
+
|
|
296
|
+
We welcome and encourage contributions from our community! Here’s how you can contribute.
|
|
297
|
+
|
|
298
|
+
Take a look at the open issues. If there's an issue that has the _help wanted_ label or _good first issue_, those are up for grabs. Assign yourself to the issue so people know you're working on it.
|
|
299
|
+
|
|
300
|
+
Alternatively you can open an issue for a new idea or piece of feedback.
|
|
301
|
+
|
|
302
|
+
When you want to contribute code, please follow these steps:
|
|
303
|
+
|
|
304
|
+
1. **Fork the Repository:** Start by forking this repository.
|
|
305
|
+
2. **Apply the improvements:** Want to optimize something or add support for additional developer tooling? Add your changes!
|
|
306
|
+
3. **Create a Pull Request:** Once you're ready and have tested your added code, submit a PR to the repo and we'll review as soon as possible.
|
|
307
|
+
|
|
308
|
+
## 💡 Questions or Suggestions?
|
|
309
|
+
|
|
310
|
+
Feel free to open an issue for questions, suggestions, or discussions related to this repository. For further discussion as well as a showcase of some community projects, check out the [Polymer developer forum](https://forum.polymerlabs.org).
|
|
311
|
+
|
|
312
|
+
Thank you for being a part of our community!
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
{
|
|
2
|
+
"proofsEnabled": false,
|
|
3
|
+
"deploy": {
|
|
4
|
+
"optimism": "XCounterUC",
|
|
5
|
+
"base": "XCounterUC"
|
|
6
|
+
},
|
|
7
|
+
"isUniversal": true,
|
|
8
|
+
"createChannel": {
|
|
9
|
+
"srcChain": "optimism",
|
|
10
|
+
"srcAddr": "0x1234567890AbCdEf1234567890aBcDeF12345678",
|
|
11
|
+
"dstChain": "base",
|
|
12
|
+
"dstAddr": "0x1234567890AbCdEf1234567890aBcDeF12345678",
|
|
13
|
+
"version": "1.0",
|
|
14
|
+
"ordering": 0,
|
|
15
|
+
"fees": false
|
|
16
|
+
},
|
|
17
|
+
"sendPacket": {
|
|
18
|
+
"optimism": {
|
|
19
|
+
"portAddr": "0x1234567890abcdef1234567890abcdef12345678",
|
|
20
|
+
"channelId": "channel-n",
|
|
21
|
+
"timeout": 36000
|
|
22
|
+
},
|
|
23
|
+
"base": {
|
|
24
|
+
"portAddr": "0x1234567890abcdef1234567890abcdef12345678",
|
|
25
|
+
"channelId": "channel-n",
|
|
26
|
+
"timeout": 36000
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
"sendUniversalPacket": {
|
|
30
|
+
"optimism": {
|
|
31
|
+
"portAddr": "0x1234567890abcdef1234567890abcdef12345678",
|
|
32
|
+
"channelId": "channel-x",
|
|
33
|
+
"timeout": 36000
|
|
34
|
+
},
|
|
35
|
+
"base": {
|
|
36
|
+
"portAddr": "0x1234567890abcdef1234567890abcdef12345678",
|
|
37
|
+
"channelId": "channel-y",
|
|
38
|
+
"timeout": 36000
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
"backup": {}
|
|
42
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
{
|
|
2
|
+
"proofsEnabled": false,
|
|
3
|
+
"deploy": {
|
|
4
|
+
"optimism": "XCounter",
|
|
5
|
+
"base": "XCounter"
|
|
6
|
+
},
|
|
7
|
+
"isUniversal": false,
|
|
8
|
+
"createChannel": {
|
|
9
|
+
"srcChain": "optimism",
|
|
10
|
+
"srcAddr": "0x9a5fDA8E49bcd1Ada645c06273A496D9A2397C9e",
|
|
11
|
+
"dstChain": "base",
|
|
12
|
+
"dstAddr": "0x9a5fDA8E49bcd1Ada645c06273A496D9A2397C9e",
|
|
13
|
+
"version": "1.0",
|
|
14
|
+
"ordering": 0,
|
|
15
|
+
"fees": false
|
|
16
|
+
},
|
|
17
|
+
"sendPacket": {
|
|
18
|
+
"optimism": {
|
|
19
|
+
"portAddr": "0x9a5fDA8E49bcd1Ada645c06273A496D9A2397C9e",
|
|
20
|
+
"channelId": "channel-19292",
|
|
21
|
+
"timeout": 36000
|
|
22
|
+
},
|
|
23
|
+
"base": {
|
|
24
|
+
"portAddr": "0x9a5fDA8E49bcd1Ada645c06273A496D9A2397C9e",
|
|
25
|
+
"channelId": "channel-19293",
|
|
26
|
+
"timeout": 36000
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
"sendUniversalPacket": {
|
|
30
|
+
"optimism": {
|
|
31
|
+
"portAddr": "0x1234567890abcdef1234567890abcdef12345678",
|
|
32
|
+
"channelId": "channel-x",
|
|
33
|
+
"timeout": 36000
|
|
34
|
+
},
|
|
35
|
+
"base": {
|
|
36
|
+
"portAddr": "0x1234567890abcdef1234567890abcdef12345678",
|
|
37
|
+
"channelId": "channel-y",
|
|
38
|
+
"timeout": 36000
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
"backup": {}
|
|
42
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
//SPDX-License-Identifier: UNLICENSED
|
|
2
|
+
|
|
3
|
+
pragma solidity ^0.8.9;
|
|
4
|
+
|
|
5
|
+
import './base/CustomChanIbcApp.sol';
|
|
6
|
+
|
|
7
|
+
contract XCounter is CustomChanIbcApp {
|
|
8
|
+
// app specific state
|
|
9
|
+
uint64 public counter;
|
|
10
|
+
mapping (uint64 => address) public counterMap;
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
constructor(IbcDispatcher _dispatcher) CustomChanIbcApp(_dispatcher) {}
|
|
14
|
+
|
|
15
|
+
// app specific logic
|
|
16
|
+
function resetCounter() internal {
|
|
17
|
+
counter = 0;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function increment() internal {
|
|
21
|
+
counter++;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// IBC logic
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* @dev Sends a packet with the caller address over a specified channel.
|
|
28
|
+
* @param channelId The ID of the channel (locally) to send the packet to.
|
|
29
|
+
* @param timeoutSeconds The timeout in seconds (relative).
|
|
30
|
+
*/
|
|
31
|
+
|
|
32
|
+
function sendPacket( bytes32 channelId, uint64 timeoutSeconds) external {
|
|
33
|
+
// incrementing counter on source chain
|
|
34
|
+
increment();
|
|
35
|
+
|
|
36
|
+
// encoding the caller address to update counterMap on destination chain
|
|
37
|
+
bytes memory payload = abi.encode(msg.sender);
|
|
38
|
+
|
|
39
|
+
// setting the timeout timestamp at 10h from now
|
|
40
|
+
uint64 timeoutTimestamp = uint64((block.timestamp + timeoutSeconds) * 1000000000);
|
|
41
|
+
|
|
42
|
+
// calling the Dispatcher to send the packet
|
|
43
|
+
dispatcher.sendPacket(channelId, payload, timeoutTimestamp);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* @dev Packet lifecycle callback that implements packet receipt logic and returns and acknowledgement packet.
|
|
48
|
+
* MUST be overriden by the inheriting contract.
|
|
49
|
+
*
|
|
50
|
+
* @param packet the IBC packet encoded by the source and relayed by the relayer.
|
|
51
|
+
*/
|
|
52
|
+
function onRecvPacket(IbcPacket memory packet) external override onlyIbcDispatcher returns (AckPacket memory ackPacket) {
|
|
53
|
+
recvedPackets.push(packet);
|
|
54
|
+
address _caller = abi.decode(packet.data, (address));
|
|
55
|
+
counterMap[packet.sequence] = _caller;
|
|
56
|
+
|
|
57
|
+
increment();
|
|
58
|
+
|
|
59
|
+
return AckPacket(true, abi.encode(counter));
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* @dev Packet lifecycle callback that implements packet acknowledgment logic.
|
|
64
|
+
* MUST be overriden by the inheriting contract.
|
|
65
|
+
*
|
|
66
|
+
* @param ack the acknowledgment packet encoded by the destination and relayed by the relayer.
|
|
67
|
+
*/
|
|
68
|
+
function onAcknowledgementPacket(IbcPacket calldata, AckPacket calldata ack) external override onlyIbcDispatcher {
|
|
69
|
+
ackPackets.push(ack);
|
|
70
|
+
|
|
71
|
+
(uint64 _counter) = abi.decode(ack.data, (uint64));
|
|
72
|
+
|
|
73
|
+
if (_counter != counter) {
|
|
74
|
+
resetCounter();
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* @dev Packet lifecycle callback that implements packet receipt logic and return and acknowledgement packet.
|
|
80
|
+
* MUST be overriden by the inheriting contract.
|
|
81
|
+
* NOT SUPPORTED YET
|
|
82
|
+
*
|
|
83
|
+
* @param packet the IBC packet encoded by the counterparty and relayed by the relayer
|
|
84
|
+
*/
|
|
85
|
+
function onTimeoutPacket(IbcPacket calldata packet) external override onlyIbcDispatcher {
|
|
86
|
+
timeoutPackets.push(packet);
|
|
87
|
+
// do logic
|
|
88
|
+
}
|
|
89
|
+
}
|