Skip to content

Latest commit

 

History

History
77 lines (49 loc) · 4.07 KB

Codebase.md

File metadata and controls

77 lines (49 loc) · 4.07 KB

Configuration

Configuration that is common to all devs is in taskfile/config.yml

Secrets and other configuration that is per-individual is in .env files (copied from .env.example) which are gitignored.

These are the only places where configuration should be stored!

Well, not quite, there's two exceptions:

  1. backend/wavs-home/wavs.toml - hardcoded WAVS configuration for operators/aggregators and local testing
  2. backend/chains/start_neutron.sh - local-chain configuration for testing

But really, that's it... if you find yourself adding configuration somewhere else, think again!

High-level directory structure

Additionally, there are important gitignored directories that are generated by building and deploying:

  • .builds/ - built components and contracts
  • .deployments/ - deployment artifacts and info

Taskfile

The overall idea is to use Taskfile tasks for all common operations, so that devs don't have to remember complex commands.

Since all the config is loaded from the taskfile/config.yml and .env files, the flow is that it passes these onto docker, binary arguments, etc.

Sometimes the Taskfile syntax isn't expressive enough, in which case we have the task-helper binary, which is strongly typed Rust code that is deeply integrated with the codebase.

Development workflow

There are a few overriding ideas that permeate the codebase:

Share Rust types everywhere

For example, we point at the shared contract api in the root Cargo.toml, so that types are shared (via the app-contract-api package name) and there's no chance of drift.

This allows catching type-like bugs at compiletime in components, tests, task-helper, etc.

Share Contract clients everywhere

By "contract client" we mean a client that knows the specific methods of a contract (not just execute/query, but things like "query all the emails")

By "everywhere" we mean multitest, real async with tokio, components with wasi, and so on.

This is done by having bit of complexity tucked away in the local client package (e.g. the heavy feature-gating), and then building abstractions on top of that.

It's also empowered by the Rust climb client, which works natively in binaries, WASI, and WASM/browser.

Tests

The concept is to make iterating on tests as easy as possible, so that devs can quickly add tests for new features and fix bugs.

That means:

  • off-chain tests with multitest for fast iteration
  • on-chain tests with tokio for real-world testing
  • shared test utils in the tests package for reusability