Skip to content

Commit 4a2f062

Browse files
first pass moving all "contract dependency manager" code to its own repository
0 parents  commit 4a2f062

42 files changed

Lines changed: 2401 additions & 0 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/ci.yml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
branches: [main]
8+
9+
jobs:
10+
lint:
11+
runs-on: ubuntu-latest
12+
steps:
13+
- uses: actions/checkout@v4
14+
- uses: oven-sh/setup-bun@v2
15+
- run: bun install
16+
- run: bun run build
17+
18+
test:
19+
runs-on: ubuntu-latest
20+
steps:
21+
- uses: actions/checkout@v4
22+
- uses: oven-sh/setup-bun@v2
23+
- run: bun install
24+
- run: bun test

.github/workflows/release.yml

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
name: Release
2+
3+
on:
4+
push:
5+
tags:
6+
- 'v*'
7+
8+
permissions:
9+
contents: write
10+
11+
jobs:
12+
build:
13+
strategy:
14+
matrix:
15+
include:
16+
- target: bun-linux-x64
17+
os: ubuntu-latest
18+
artifact: cdm-linux-x64
19+
- target: bun-darwin-x64
20+
os: macos-latest
21+
artifact: cdm-darwin-x64
22+
- target: bun-darwin-arm64
23+
os: macos-latest
24+
artifact: cdm-darwin-arm64
25+
26+
runs-on: ${{ matrix.os }}
27+
28+
steps:
29+
- uses: actions/checkout@v4
30+
31+
- uses: oven-sh/setup-bun@v2
32+
33+
- run: bun install
34+
35+
- name: Compile binary
36+
run: bun build --compile --target=${{ matrix.target }} src/cli.ts --outfile ${{ matrix.artifact }}
37+
38+
- name: Upload artifact
39+
uses: actions/upload-artifact@v4
40+
with:
41+
name: ${{ matrix.artifact }}
42+
path: ${{ matrix.artifact }}
43+
44+
release:
45+
needs: build
46+
runs-on: ubuntu-latest
47+
steps:
48+
- uses: actions/checkout@v4
49+
50+
- name: Download all artifacts
51+
uses: actions/download-artifact@v4
52+
with:
53+
path: artifacts
54+
55+
- name: Create Release
56+
uses: softprops/action-gh-release@v2
57+
with:
58+
files: |
59+
artifacts/cdm-linux-x64/cdm-linux-x64
60+
artifacts/cdm-darwin-x64/cdm-darwin-x64
61+
artifacts/cdm-darwin-arm64/cdm-darwin-arm64
62+
generate_release_notes: true

.gitignore

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
node_modules/
2+
dist/
3+
target/
4+
.papi/
5+
*.polkavm
6+
7+
*.lock
8+
9+
ppn/

CLAUDE.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
## Workflow Rules
2+
3+
- **Always act as team leader.** The primary agent the user is talking to MUST act as a team leader and delegate work to sub-agents for almost everything.
4+
- **Always use team mode.** You MUST always run agents in team mode (using `TeamCreate` + `Task` with `team_name`) so the user can properly watch their work. Never use standalone agents outside of a team. This applies to ALL agent usage — no exceptions.

Cargo.toml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
[workspace]
2+
resolver = "2"
3+
members = ["contracts/registry"]
4+
5+
[workspace.dependencies]
6+
pvm_contract = "0.3"
7+
polkavm-derive = "0.31"
8+
parity-scale-codec = { version = "3.7", default-features = false, features = ["derive"] }
9+
picoalloc = "0.2"

Makefile

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
.PHONY: install dev build compile compile-all build-registry test clean
2+
3+
setup:
4+
curl -sL https://raw.githubusercontent.com/paritytech/ppn-proxy/main/install.sh | bash
5+
bun instal
6+
bunx papi generatel
7+
8+
start-network:
9+
cd ppn && make start
10+
11+
install:
12+
bun install
13+
14+
dev:
15+
bun run src/cli.ts
16+
17+
build:
18+
bun run build
19+
20+
compile:
21+
bun build --compile src/cli.ts --outfile dist/cdm
22+
23+
compile-all:
24+
mkdir -p dist
25+
bun build --compile --target=bun-darwin-arm64 src/cli.ts --outfile dist/cdm-darwin-arm64
26+
bun build --compile --target=bun-darwin-x64 src/cli.ts --outfile dist/cdm-darwin-x64
27+
bun build --compile --target=bun-linux-x64 src/cli.ts --outfile dist/cdm-linux-x64
28+
29+
build-registry:
30+
cargo pvm-contract build --manifest-path Cargo.toml -p contracts
31+
32+
test:
33+
bun test tests/detection.test.ts tests/commands.test.ts
34+
35+
test-e2e:
36+
bun test tests/e2e.test.ts
37+
38+
clean:
39+
rm -rf dist/ target/ node_modules/

README.md

Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
# Contract Dependency Manager (CDM)
2+
3+
A CLI tool for managing PVM smart contract dependencies on Polkadot. CDM automates contract deployment ordering, cross-contract address resolution, and TypeScript type generation.
4+
5+
## Quick Install
6+
7+
```bash
8+
curl -fsSL https://raw.githubusercontent.com/paritytech/contract-dependency-manager/main/install.sh | bash
9+
```
10+
11+
## Quick Start
12+
13+
```bash
14+
# Start a local network (Product Preview Net)
15+
curl -sL https://raw.githubusercontent.com/paritytech/ppn-proxy/main/install.sh | bash
16+
cd ppn && make start
17+
18+
# Scaffold a new project
19+
cdm template my-project
20+
cd my-project
21+
22+
# Build contracts
23+
cdm build
24+
25+
# Deploy to local Asset Hub (bootstrap mode)
26+
cdm deploy --bootstrap ws://127.0.0.1:10020
27+
28+
# Add a contract library to your TypeScript project
29+
cdm add @polkadot/reputation --registry 0x...
30+
```
31+
32+
## Local Network (PPN)
33+
34+
CDM requires a running Polkadot chain with the Revive pallet for contract deployment. For local development, use **Product Preview Net (PPN)**, which spins up both a Bulletin and Asset Hub parachain locally.
35+
36+
```bash
37+
# Install and start PPN
38+
curl -sL https://raw.githubusercontent.com/paritytech/ppn-proxy/main/install.sh | bash
39+
cd ppn && make start
40+
```
41+
42+
Once running, Asset Hub is available at `ws://127.0.0.1:10020`. This is the default URL used by CDM scripts for local development.
43+
44+
## How It Works
45+
46+
CDM solves the "chicken-and-egg" problem of smart contract deployment. When contracts depend on each other, they need to know each other's addresses - but addresses aren't known until deployment.
47+
48+
CDM uses an on-chain **ContractRegistry** to resolve addresses at runtime:
49+
50+
1. Contracts declare dependencies via `#[pvm::contract(cdm = "@scope/name")]`
51+
2. CDM scans your workspace, builds a dependency graph, and topologically sorts it
52+
3. Contracts are deployed in order, each registered in the ContractRegistry
53+
4. At runtime, `cdm_reference()` looks up the latest address from the registry
54+
55+
## Commands
56+
57+
### `cdm build`
58+
Build all contracts with the ContractRegistry address baked in.
59+
60+
```bash
61+
CONTRACTS_REGISTRY_ADDR=0x... cdm build
62+
cdm build --contracts counter counter_writer # Build specific contracts
63+
cdm build --root /path/to/workspace # Custom workspace root
64+
```
65+
66+
### `cdm deploy <url>`
67+
Deploy and register all contracts to a chain.
68+
69+
```bash
70+
# Bootstrap: deploy ContractRegistry + all contracts from scratch (local PPN)
71+
cdm deploy --bootstrap ws://127.0.0.1:10020
72+
73+
# Standard: deploy CDM contracts (registry already exists)
74+
CONTRACTS_REGISTRY_ADDR=0x... cdm deploy ws://127.0.0.1:10020
75+
76+
# Options
77+
cdm deploy --signer Bob ws://127.0.0.1:10020 # Use different signer
78+
cdm deploy --dry-run ws://127.0.0.1:10020 # Preview deployment plan
79+
cdm deploy --skip-build ws://127.0.0.1:10020 # Use pre-built artifacts
80+
```
81+
82+
### `cdm add <library>`
83+
Add a CDM contract library for use with polkadot-api. Queries the on-chain registry for the contract's ABI metadata and installs it locally.
84+
85+
```bash
86+
cdm add @polkadot/reputation --registry 0x...
87+
cdm add @polkadot/disputes --url wss://asset-hub.polkadot.io
88+
```
89+
90+
### `cdm template [dir]`
91+
Scaffold a complete example project with 3 contracts demonstrating cross-contract CDM dependencies.
92+
93+
```bash
94+
cdm template my-project # Create in ./my-project
95+
cdm template # Create in current directory
96+
```
97+
98+
## Writing CDM Contracts
99+
100+
Annotate your contract with a CDM package name:
101+
102+
```rust
103+
#[pvm::contract(cdm = "@yourscope/mycontract")]
104+
mod mycontract {
105+
#[pvm::constructor]
106+
pub fn new() -> Result<(), Error> { Ok(()) }
107+
108+
#[pvm::method]
109+
pub fn do_something() -> u32 { 42 }
110+
}
111+
```
112+
113+
To call another CDM contract:
114+
115+
```rust
116+
// Add the contract as a Cargo dependency
117+
// Then use cdm_reference() for runtime address lookup
118+
let other = other_contract::cdm_reference();
119+
other.do_something().expect("call failed");
120+
```
121+
122+
## Example: Shared Counter
123+
124+
The included shared-counter template demonstrates a 3-contract system:
125+
126+
- **counter** - Stores a shared count value
127+
- **counter-writer** - Calls counter to increment (depends on counter via CDM)
128+
- **counter-reader** - Queries counter for the current value (depends on counter via CDM)
129+
130+
```
131+
cdm template my-counter
132+
cd my-counter
133+
cdm deploy --bootstrap ws://127.0.0.1:10020
134+
cd ts && bun install && bun run src/validate.ts
135+
```
136+
137+
## Development
138+
139+
```bash
140+
git clone https://github.com/paritytech/contract-dependency-manager.git
141+
cd contract-dependency-manager
142+
./scripts/setup.sh
143+
144+
# Run in dev mode
145+
bun run src/cli.ts --help
146+
147+
# Run tests
148+
make test
149+
150+
# Build native binary
151+
make compile
152+
153+
# Cross-compile for all platforms
154+
make compile-all
155+
```
156+
157+
## Architecture
158+
159+
```
160+
src/
161+
cli.ts Entry point (Commander.js)
162+
commands/
163+
build.ts Build contracts with registry address
164+
deploy.ts Deploy + register contracts on-chain
165+
add.ts Add contract types via papi
166+
template.ts Scaffold example project
167+
lib/
168+
detection.ts Workspace scanning, dependency graph, topological sort
169+
deployer.ts On-chain deployment + ABI encoding
170+
connection.ts WebSocket / Smoldot chain connections
171+
signer.ts sr25519 key derivation
172+
contracts/
173+
registry/ ContractRegistry on-chain contract (Rust/PolkaVM)
174+
templates/
175+
shared-counter/ Example project template
176+
```
177+
178+
## License
179+
180+
Apache-2.0

contracts/registry/Cargo.toml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
[package]
2+
name = "contracts"
3+
version = "0.1.0"
4+
edition = "2024"
5+
6+
[lib]
7+
path = "lib.rs"
8+
9+
[[bin]]
10+
name = "contracts"
11+
path = "lib.rs"
12+
13+
[dependencies]
14+
pvm_contract = { workspace = true }
15+
polkavm-derive = { workspace = true }
16+
parity-scale-codec = { workspace = true }
17+
picoalloc = { workspace = true }

contracts/registry/allocator.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
/// 256 KiB global allocator for dynamic storage
2+
#[global_allocator]
3+
static mut ALLOC: picoalloc::Mutex<picoalloc::Allocator<picoalloc::ArrayPointer<262144>>> = {
4+
static mut ARRAY: picoalloc::Array<262144> = picoalloc::Array([0u8; 262144]);
5+
6+
picoalloc::Mutex::new(picoalloc::Allocator::new(unsafe {
7+
picoalloc::ArrayPointer::new(&raw mut ARRAY)
8+
}))
9+
};

0 commit comments

Comments
 (0)