Skip to content

Commit

Permalink
add npm package
Browse files Browse the repository at this point in the history
  • Loading branch information
RnkSngh committed May 14, 2024
1 parent aabf701 commit 3e5df0a
Show file tree
Hide file tree
Showing 25 changed files with 1,868 additions and 29 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,17 @@ jobs:
runs-on: ubuntu-latest

steps:
- name: Install Foundry
uses: foundry-rs/foundry-toolchain@v1
- uses: actions/checkout@v3
with:
submodules: recursive
- uses: actions/setup-node@v3
with:
node-version: '16'
node-version: "16"
- uses: bahmutov/npm-install@v1
with:
install-command: npm install
- run: npm run lint
- name: Install Foundry
uses: foundry-rs/foundry-toolchain@v1
- name: Check formatting
run: forge fmt --check
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,4 @@ artifacts
report/
lcov.info

src/evm/contracts
123 changes: 103 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# vIBC Core Smart Contracts

This project includes the core smart contracts for the vIBC protocol, and a few demo contracts that simulate testing and serve as a template for integrating dapp devs.
This project includes the core smart contracts for the vIBC protocol, a few demo contracts that simulate testing and serve as a template for integrating dapp devs, and an npm package to aid with deploying and sending transactions to deployed contracts.

![](./diagrams/vibcContractsOverview.jpg)

Expand Down Expand Up @@ -35,35 +35,118 @@ The optimisticProofVerifier verifies proofs for the optimistic light client.
## UniversalChannelHandler
The UniversalChannelHandler is a middleware contract that can be used to save dapps from having to go through the 4-step channel handshake to send or receive Ibc packets.

## Quick Start with Forge/Foundry
## Building Contracts and Testing
This repository uses Foundry for testing and development of smart contracts

### Install Forge
## Deploying Contracts
All deployments can either be done through the command line, or through javascript code through importing modules.
After each deployment, deployment files are saved in deployment artifacts as json files, structured similar to how [hardhat deploy stores its deploy files](https://github.com/wighawag/hardhat-deploy).

```sh
curl -L https://foundry.paradigm.xyz | bash
```

This will install Foundryup, then simply follow the instructions on-screen, which will make the `foundryup` command available in your CLI.
Before deploying, the accounts used to deploy and any constructor arguments must be configured. This configuration can either be read from a yaml file or set through environment variables (see the sections below on how to configure each deployments).

Running `foundryup` by itself will install the latest (nightly) precompiled binaries: `forge`, `cast`, `anvil`, and `chisel`. See `foundryup --help` for more options, like installing from a specific version or commit.
The constructor arguments for each deployment. This supports syntax - which looks through written. You can also specify.
This file is read in-order, so each entry in this file should be in-order where dependencies come first and the contract that depends on them comes later.

Or go to https://book.getfoundry.sh/getting-started/installation for more installation options.
### Deploying via Command Line
This npm package exposes two commands - one to deploy new contacts (which automatically creates persisted deployment files), and one to send transactions to contracts from persisted artifact files. The following steps are needed to deploy contracts via the command line:

### Build contracts
1. Ensure that your deployer account and constructor arguments are configured. This can either be done through adding contract spec yaml files located in the specs/ from the root of where this npm module is installed from (requires adding a `specs/evm.accounts.yaml` file and either a `specs/contracts.spec.yaml` or `specs/upgrade.spec.yaml`), or by setting the KEY_POLYMER, RPC_URL, DEPLOYMENT_CHAIN_ID, CHAIN_NAME environment variables. For examples of contract and account spec files, see the `/specs` folder in this repo.
2. Run either `npx deploy-vibc-core-smart-contracts` to deploy contracts from the contract spec, or `npx upgrade-vibc-core-smart-contracts` to send an upgrade transaction.

```sh
forge build
```
### Deploying via imports
Deployments can also be done through calls through the `deployToChain` and the `sendTxToChain` methods.

### Run Tests
#### Deploying new contracts via imports

```sh
forge test
```
import {
AccountRegistry,
Chain,
ContractRegistryLoader,
deployToChain,
parseObjFromFile,
} from "@open-ibc/vibc-core-smart-contracts";
import { getMainLogger } from "@open-ibc/vibc-core-smart-contracts/utils/cli";
import { DEFAULT_RPC_URL } from "../utils/constants";
// Or can parse it form the env
const accountConfig = {
name: "local",
registry: [
{
name: "KEY_POLYMER",
privateKey: process.env.KEY_POLYMER
},
],
};
const accounts = AccountRegistry.loadMultiple([accountConfig]);
const contracts = ContractRegistryLoader.loadSingle(
parseObjFromFile("specs/contracts.spec.yaml")
);
const chain: Chain = {
rpc: process.env.RPC_URL ,
chainId: process.env.DEPLOYMENT_CHAIN_ID,
chainName: process.env.CHAIN_NAME,
vmType: "evm",
description: "local chain",
};
deployToChain(
chain,
accounts.mustGet(chain.chainName),
contracts.subset(),
getMainLogger(),
false
);
```

similar to the command line deploy, this will create a deployment artifact file in the `deployments/` folder.

### Clean environment
#### Upgrading existing contracts via imports
Proxy upgrades to existing contracts can be done through the `sendTxToChain` method :

```sh
forge clean
```
#!/usr/bin/env node
import {
AccountRegistry,
Chain,
parseObjFromFile,
} from "@open-ibc/vibc-core-smart-contracts";
import { loadTxRegistry } from "@open-ibc/vibc-core-smart-contracts/evm/schemas/tx";
import { sendTxToChain } from "@open-ibc/vibc-core-smart-contracts";
import { getOutputLogger } from "@open-ibc/vibc-core-smart-contracts/utils/cli";
// Or can parse it form the env
const accountConfig = {
name: "local",
registry: [
{
name: "KEY_POLYMER",
privateKey: process.env.KEY_POLYMER,
},
],
};
const accounts = AccountRegistry.loadMultiple([accountConfig]);
const upgradeTxs = loadTxRegistry(parseObjFromFile("specs/upgrade.spec.yaml"));
const chain: Chain = {
rpc: process.env.RPC_URL,
chainId: process.env.CHAIN_ID,
chainName: "local",
vmType: "evm",
description: "local chain",
};
sendTxToChain(
chain,
accounts.mustGet(chain.chainName),
upgradeTxs.subset(),
getOutputLogger(),
false
);
```

6 changes: 6 additions & 0 deletions hardhat.config.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
require("@nomicfoundation/hardhat-toolbox");

/** @type import('hardhat/config').HardhatUserConfig */
module.exports = {
solidity: "0.8.24",
};
82 changes: 76 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,13 +1,83 @@
{
"name": "vibc-core-smart-contracts",
"version": "1.0.0",
"main": "index.js",
"repository": "https://github.com/open-ibc/vibc-core-smart-contracts",
"name": "@open-ibc/vibc-core-smart-contracts",
"version": "0.1.3",
"main": "dist/index.js",
"bin": {
"deploy-vibc-core-smart-contracts": "./dist/scripts/deploy-script.js",
"upgrade-vibc-core-smart-contracts": "./dist/scripts/upgrade-script.js"
},
"license": "MIT",
"dependencies": {
"solhint": "^4.1.1"
"@commander-js/extra-typings": "^12.0.1",
"@typechain/ethers-v6": "^0.5.0",
"ethers": "^6.4.0",
"nunjucks": "^3.2.4",
"solhint": "^4.1.1",
"typechain": "^8.3.0",
"winston": "^3.13.0",
"yaml": "^2.4.1",
"zod": "^3.23.4",
"zx": "^8.0.2"
},
"devDependencies": {
"@nomicfoundation/hardhat-chai-matchers": "^2.0.0",
"@nomicfoundation/hardhat-ethers": "^3.0.0",
"@nomicfoundation/hardhat-ignition": "^0.15.0",
"@nomicfoundation/hardhat-ignition-ethers": "^0.15.0",
"@nomicfoundation/hardhat-network-helpers": "^1.0.0",
"@nomicfoundation/hardhat-toolbox": "^5.0.0",
"@nomicfoundation/hardhat-verify": "^2.0.0",
"@typechain/hardhat": "^9.0.0",
"@types/nunjucks": "^3.2.6",
"@types/winston": "^2.4.4",
"chai": "^4.2.0",
"hardhat": "^2.14.0",
"hardhat-gas-reporter": "^1.0.8",
"solidity-coverage": "^0.8.0",
"tsup": "^8.0.2"
},
"scripts": {
"lint": "solhint contracts/**/*.sol"
"lint": "solhint contracts/**/*.sol",
"test": "forge test",
"build": "npm run gen-types && tsup",
"build-contracts": "forge build",
"gen-types": "npm run build-contracts && typechain --target ethers-v6 --out-dir src/evm/contracts/ './out/?(OpProofVerifier|ProofVerifier|Ibc|Channel|Dispatcher|Mars|Earth|UniversalChannelHandler|DummyProofVerifier|DummyLightClient|ERC1967Proxy|OpLightClient).sol/*.json'",
"deploy-contracts": "npm run build && node dist/deploy.js",
"deploy-simple": "node dist/deploy.js",
"prepublish": "npm run build"
},
"keywords": [
"evm",
"cosmos",
"rollup",
"op-stack",
"interoperability",
"solidity"
],
"author": "Polymer Labs",
"type": "module",
"exports": {
".": {
"require": "./dist/index.js",
"import": "./dist/index.js",
"types": "./dist/index.d.ts"
},
"./evm": {
"require": "./dist/evm/index.js",
"import": "./dist/evm/index.js",
"types": "./dist/evm/index.d.ts"
},
"./evm/account": "./dist/evm/account.js",
"./evm/chain": "./dist/evm/chain.js",
"./evm/schemas/contract": "./dist/evm/schemas/contract.js",
"./evm/schemas/tx": "./dist/evm/schemas/tx.js",
"./utils": {
"require": "./dist/utils/index.js",
"import": "./dist/utils/index.js",
"types": "./dist/utils/index.d.ts"
},
"./utils/cli": "./dist/utils/cli.js",
"./utils/io": "./dist/utils/io.js"
}

}
77 changes: 77 additions & 0 deletions specs/contracts.spec.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# spec for deploying contracts
# {{name}} is replaced with one of the following, whichever matches first
# - the deployed contract address whose name matches `name` (not factoryName)
# - variables of the running chain, e.g. {{chain.chainName}}, {{chain.chainId}}
# NOTE: order of the contracts matters, as some contracts depend on others
# contracts with no deps should be placed before those with deps
# deployer: must be a valid name in accountRegistry; default to 'default' if not specified

- name: LightClient
description: 'DummyLightClient'
factoryName: 'DummyLightClient'
deployer: 'KEY_POLYMER'

- name: Ibc
description: 'IBC library'
factoryName: 'Ibc'
deployer: 'KEY_POLYMER'

- name: IbcUtils
description: 'IBC utils library'
factoryName: 'IbcUtils'
deployer: 'KEY_POLYMER'

- name: Dispatcher
description: 'IBC Core contract'
factoryName: 'Dispatcher'
libraries:
- name: 'contracts/libs/Ibc.sol:Ibc'
address: '{{Ibc}}'
deployer: 'KEY_POLYMER'

- name: DispatcherProxy
description: 'Dispatcher proxy contract'
factoryName: 'ERC1967Proxy'
deployArgs:
- '{{Dispatcher}}'
- '$INITARGS'
init:
signature: 'initialize(string,address)'
args:
- 'polyibc.{{chain.chainName}}.'
- '{{LightClient}}'
deployer: 'KEY_POLYMER'

- name: UC
description: 'Universal Chanel IBC-middleware contract'
factoryName: 'UniversalChannelHandler'
deployer: 'KEY_POLYMER'
libraries:
- name: 'contracts/libs/Ibc.sol:IbcUtils'
address: '{{IbcUtils}}'

- name: UCProxy
description: 'Universal Chanel IBC-middleware proxy'
factoryName: 'ERC1967Proxy'
deployArgs:
- '{{UC}}'
- '$INITARGS'
init:
signature: 'initialize(address)'
args:
- '{{DispatcherProxy}}'
deployer: 'KEY_POLYMER'

# dApp contracts for testing and as examples

- name: Mars
description: 'Mars contract directly owns a IBC channel'
deployArgs:
- '{{DispatcherProxy}}'
deployer: 'KEY_POLYMER'

- name: Earth
description: 'Earth contract uses shared universal channel'
deployArgs:
- '{{UCProxy}}'
deployer: 'KEY_POLYMER'
3 changes: 3 additions & 0 deletions specs/evm.accounts.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# These accounts are derived from a test mnemonic by Anvil/Hardhat and used for testing purposes only.
- name: 'KEY_POLYMER'
privateKey: '0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80'
16 changes: 16 additions & 0 deletions specs/upgrade.spec.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# spec for deploying contracts
# {{name}} is replaced with one of the following, whichever matches first
# - the deployed contract address whose name matches `name` (not factoryName)
# - variables of the running chain, e.g. {{chain.chainName}}, {{chain.chainId}}
# NOTE: order of the contracts matters, as some contracts depend on others
# contracts with no deps should be placed before those with deps
# deployer: must be a valid name in accountRegistry; default to 'default' if not specified

# call on a given factoryname
- name: DispatcherUpgradeII
description: 'Upgrade for dispatcher contract'
deployer: 'KEY_POLYMER' # can be set in the accounts.yaml
signature: "upgradeTo(address)"
factoryName: "Dispatcher"
args:
- '{{Dispatcher}}'
Loading

0 comments on commit 3e5df0a

Please sign in to comment.