Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 76 additions & 15 deletions chains/solana/README.md
Original file line number Diff line number Diff line change
@@ -1,28 +1,89 @@
# CCIP Solana Onchain

- `contracts`: solana programs (rust) + tests (go) built on the anchor framework
- `gobindings`: auto-generated go bindings for contracts using `anchor-go`
- `scripts`: various scripts for generating artifacts
## Project Structure

- `contracts/` — Solana programs (Rust/Anchor) + integration tests (Go)
- `programs/` — Anchor program source code (ccip-router, fee-quoter, token pools, mcm, timelock, etc.)
- `tests/` — Go integration tests organized by area (`ccip/`, `mcms/`, `examples/`)
- `target/deploy/` — compiled `.so` program binaries and IDL JSON files
- `target/vendor/` — pre-built third-party program binaries (CCTP), committed to git
- `gobindings/` — auto-generated Go bindings for contracts using `anchor-go`
- `scripts/` — build and generation scripts (e.g. `anchor-go-gen.sh`)
- `utils/` — shared Go utility libraries

## Dependencies

- rust: https://www.rust-lang.org/tools/install
- go: https://go.dev/doc/install
- solana: https://docs.anza.xyz/cli/install
- anchor: https://www.anchor-lang.com/docs/installation
- [Rust](https://www.rust-lang.org/tools/install) (version pinned via `contracts/rust-toolchain.toml`)
- [Go](https://go.dev/doc/install) (see `go.mod` for required version)
- [Solana CLI](https://docs.anza.xyz/cli/install) (provides `solana-test-validator`)
- [Anchor CLI](https://www.anchor-lang.com/docs/installation)
- [anchor-go](https://github.com/gagliardetto/anchor-go) v0.2.3 — `GOTOOLCHAIN=go1.20 go install github.com/gagliardetto/anchor-go@v0.2.3`
- [golangci-lint](https://golangci-lint.run/welcome/install/) v2.7.0 — `go install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.7.0`
- [gotestloghelper](https://github.com/smartcontractkit/chainlink-testing-framework) — for `make go-tests` output formatting

### macOS (Apple Silicon) Note

The `solana-test-validator` requires GNU tar. Without it, you'll see errors like
`Archive error: extra entry found: "._genesis.bin"`. Install it and put it on your PATH:

```bash
brew install gnu-tar
export PATH="/opt/homebrew/opt/gnu-tar/libexec/gnubin:$PATH"
```

See [solana-labs/solana#35629](https://github.com/solana-labs/solana/issues/35629) for details.

## Development

### Build contracts

```bash
# Build on the host (requires Anchor CLI + Solana CLI + Rust toolchain)
make build-contracts

# Or build inside Docker for reproducibility
make docker-build-contracts
```

### Generate Go bindings

After any contract changes, regenerate the Go bindings:

```bash
# install anchor-go if needed
go install github.com/gagliardetto/anchor-go@v0.2.3
make anchor-go-gen
```

This builds the contracts, then runs `anchor-go` against the IDL files to produce bindings in `gobindings/`.

### Run tests

```bash
# Go integration tests (spins up local solana-test-validator per test)
make go-tests

# Rust unit tests
make rust-tests

# Run a specific test suite
go test ./contracts/tests/ccip/ -run TestCCIPRouter -v -count=1
go test ./contracts/tests/mcms/ -run TestMcmSetConfig -v -count=1
go test ./contracts/tests/examples/ -run TestBaseTokenPoolHappyPath -v -count=1
```

# build contracts + IDL
anchor build
Note: Go integration tests require that contracts have been built (`make build-contracts`)
and that the vendor `.so` files exist in `contracts/target/vendor/`.

# go bindings need to be regenerated if contract changes were made
./scripts/anchor-go-gen.sh
### Format and lint

# test contracts
go test ./... -v -count=1 -failfast
```bash
make format # format Go + Rust
make lint-go # run golangci-lint
```

### Full CI check

```bash
make solana-checks
```

This runs, in order: `clippy`, `anchor-go-gen`, `format`, `gomodtidy`, `lint-go`, `rust-tests`, `go-tests`, `build-contracts`.
100 changes: 39 additions & 61 deletions chains/solana/contracts/README.md
Original file line number Diff line number Diff line change
@@ -1,97 +1,75 @@
# Chainlink Solana contracts (programs)
# Chainlink Solana Contracts (Programs)

## Prerequisites

Install Rust, Solana & Anchor. See https://solana.com/docs/intro/installation
- [Rust](https://www.rust-lang.org/tools/install) (version pinned via `rust-toolchain.toml`)
- [Solana CLI](https://docs.anza.xyz/cli/install) (provides `solana-test-validator`)
- [Anchor CLI](https://www.anchor-lang.com/docs/installation)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This repo requires anchor 0.29, which you may want to call out here. It also requires older solana & rust versions sadly

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Rust version I pinned in chains/solana/contracts/rust-toolchain.toml, which should force the right one to be installed + used. As for anchor, it's not quite 1:1 because this is about the Anchor CLI, which works all the way up to 0.32.1 (latest I think). I thought about restricting the CLI to be the same version as the anchor dependency, but I don't know if there's a reason to. Do you know if anything breaks when using a newer anchor CLI?

- [Go](https://go.dev/doc/install) (see `go.mod` for required version)
- [anchor-go](https://github.com/gagliardetto/anchor-go) v0.2.3 — `GOTOOLCHAIN=go1.20 go install github.com/gagliardetto/anchor-go@v0.2.3`

## Build

To build on the host:

```
```bash
anchor build
# or from the repo root:
make build-contracts
```

To build inside a docker environment:
To build inside a Docker environment (reproducible builds):

```bash
anchor build --verifiable
make docker-build-contracts
```

To build for a specific network, specify via a cargo feature:
## Test

### Rust unit tests

```bash
anchor build -- --features mainnet
cargo test
# or from the repo root:
make rust-tests
```

Available networks with declared IDs:

- mainnet
- testnet
- devnet
- localnet (default)
### Go integration tests

## Test
The Go tests spin up a local `solana-test-validator`, deploy the compiled programs, and run
integration tests against them.

Make sure to run `pnpm i` to fetch mocha and other test dependencies.
Prerequisites:

Start a dockerized shell that contains Solana and Anchor:
- `solana-test-validator` installed and on your PATH
- Contracts built (`anchor build` or `make build-contracts`)
- Vendor programs present in `target/vendor/` (pre-built CCTP `.so` files, committed to git)

```bash
./scripts/anchor-shell.sh
# from the repo root:
make go-tests
```

Next, generate a keypair for anchor:
To run specific test suites:

```bash
solana-keygen new -o id.json
go test ./tests/ccip/ -run TestCCIPRouter -v -count=1
go test ./tests/mcms/ -run TestMcmSetConfig -v -count=1
go test ./tests/examples/ -run TestBaseTokenPoolHappyPath -v -count=1
```

### Run anchor TypeScript tests (automatically tests against a local node)
Note: subtests within a single top-level `Test*` function share sequential state, so running
an individual subtest in isolation (e.g. `-run TestCCIPRouter/Config`) will likely fail because
earlier setup subtests won't have executed.

```bash
anchor test
```

### Run GoLang tests (automatically tests against a local node)
## Go bindings generation

Pre-requisites:

- Have the `solana-test-validator` command installed
- Run `anchor build` if there have been any changes to the program under test.
Install `anchor-go` and regenerate bindings after contract changes:

```bash
make contracts-go-tests
GOTOOLCHAIN=go1.20 go install github.com/gagliardetto/anchor-go@v0.2.3
make anchor-go-gen
```

#### `anchor-go` bindings generation

Install `https://github.com/gagliardetto/anchor-go`

Current version: [v0.2.3](https://github.com/gagliardetto/anchor-go/tree/v0.2.3)

To install `anchor-go` locally so that you can use the `anchor-go` command globally, follow these steps:

1. **Clone the repository:**

```bash
git clone https://github.com/gagliardetto/anchor-go.git
cd anchor-go
git checkout v0.2.3
```

2. **Install the command globally:**

Run the following command to install the `anchor-go` command globally:

```bash
go install
```

This will install the `anchor-go` binary to your `$GOPATH/bin` directory. Make sure that this directory is included in your system's `PATH` environment variable.

3. **Then run the following command to generate the Go bindings:**

```bash
make anchor-go-gen
```
This builds the contracts, generates Go bindings from the IDL files in `target/idl/` and
`target/vendor/`, and outputs them to `gobindings/`.
3 changes: 3 additions & 0 deletions chains/solana/contracts/rust-toolchain.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[toolchain]
channel = "1.73.0"
components = ["clippy", "rustfmt"]
7 changes: 7 additions & 0 deletions chains/solana/scripts/anchor-go-gen.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@

set -e

# Ensure anchor-go v0.2.3 is installed. It requires Go <= 1.22 to compile,
# so we pin GOTOOLCHAIN=go1.20 for the install step.
if ! command -v anchor-go &>/dev/null; then
echo "anchor-go not found, installing v0.2.3..."
GOTOOLCHAIN=go1.20 go install github.com/gagliardetto/anchor-go@v0.2.3
fi

function generate_bindings() {
local idl_path_str="$1"
IFS='/' read -r -a idl_path <<< "${idl_path_str}"
Expand Down
Loading