Skip to content

april-gate/coldchain-core

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

coldchain-core

Reference protocol implementation for April Gate — tamper-evident cold chain verification on Solana.

This repository contains the protocol types, simulation tooling, a Solana client library, and a demo binary that exercises the full pipeline from sensor readings through BLS-aggregated consensus to on-chain submission on Solana devnet. The on-chain program lives in coldchain-programs; the production consensus engine, ZK proof circuits, and hardware firmware are part of April Gate's proprietary stack and are not in this repository.

What this demonstrates

Five simulated sensors, each producing a hardware-style signed temperature attestation per round. Attestations are aggregated into a single BLS12-381 signature, and the round's slot-owning device submits two on-chain artifacts atomically in a single transaction:

  1. A Memo with human-readable JSON — a preview of what will eventually be stored encrypted on Filecoin and viewable through the April Gate web portal by authorized parties.
  2. A device_registry::submit_proof call writing a 32-byte commitment to the slot owner's on-chain assignment — the production-shaped tamper-evident record.

The memo JSON references the production proof PDA and includes the commitment hex, so anyone reading the human-readable record can navigate to the production proof account and verify that the on-chain commitment field matches.

Across the demo, five distinct device keypairs each take their turn as the on-chain submitter — the round-robin slot rotation made concrete in chain history.

What you can verify on-chain after running the demo:

  • Five sensor node identities participating in each round
  • A single BLS aggregate signature representing all five (binding off-chain evidence)
  • Median temperature consensus (Byzantine-robust to faulty readings)
  • Round-robin slot rotation distributing submission across five distinct devices
  • For each round, a Proof account on the device_registry program with the round's commitment, anchored to the slot owner's DeviceAssignment

Architecture

┌─────────────────────────────────────────────────────────────────┐
│                         consensus crate                          │
│  Protocol types · TemperatureSource trait · BLS aggregation     │
│  Median consensus · Slot scheduling · Canonical message format   │
└─────────────────────────────────────────────────────────────────┘
         ▲                                          ▲
         │                                          │
┌────────┴──────────────┐               ┌──────────┴──────────────┐
│   simulation crate    │               │   coldchain-engine      │
│                       │               │   (PRIVATE)             │
│  SimSensor: software  │               │                         │
│  BLS keys + synthetic │               │  Production sensor      │
│  readings             │               │  with ATECC608 hardware │
│                       │               │  BFT engine, ZK proofs  │
└───────────────────────┘               └─────────────────────────┘
         ▲
         │                              ┌─────────────────────────┐
         │                              │   chain-client crate    │
         │                              │                         │
         │                              │  PDA derivation         │
         │                              │  Anchor ix builders     │
         │                              │  Account decoders       │
         │                              │  devnet.json schema     │
         │                              └────────┬────────────────┘
         │                                       │
         │                              ┌────────┴────────────────┐
         │                              │  bin/setup-devnet       │
         │                              │                         │
         │                              │  Idempotent provisioner:│
         │                              │  generates keys,        │
         │                              │  registers devices,     │
         │                              │  creates shipments,     │
         │                              │  assigns devices,       │
         │                              │  writes devnet.json     │
         │                              └─────────────────────────┘
         │                                       │
┌────────┴───────────────────────────────────────┴────────────────┐
│           bin/sim-cluster  ·  bin/sim-cluster-full-demo          │
│                                                                  │
│  sim-cluster: 5-round happy demo on the happy shipment.          │
│  sim-cluster-full-demo: full arc (happy → mid-demo reassignment  │
│  → degradation → quorum collapse), exercising the architecture   │
│  end to end.                                                     │
│                                                                  │
│  Both atomically submit Memo (human-readable) + submit_proof     │
│  (commitment) per round when consensus is achievable.            │
└─────────────────────────────────────────────────────────────────┘

What's here vs. what's proprietary

In this repository (public reference implementation)

  • Protocol typesSensorReading, SignedAttestation, AggregatedProof
  • TemperatureSource trait — uniform abstraction across simulated and hardware sensors
  • Median consensus — Byzantine-robust aggregation across signed readings
  • BLS12-381 primitives — signature and public-key aggregation via blst
  • Round-robin slot scheduling — simple deterministic rotation
  • Canonical signing message format — used for both ECDSA (production) and BLS (demo)
  • Anchor instruction builders — PDA derivation and device_registry instruction construction with no anchor-client dependency, keeping build times reasonable
  • Idempotent devnet provisioning — one command brings devnet to a known-good state
  • Dual on-chain submission — Memo (human-readable preview) plus production-shaped submit_proof, atomically per round

In April Gate's private coldchain-engine repository

  • Position-aware tampering detection — using known relative sensor placements within a shipment; patent application in preparation
  • Hardware-to-BLS bridge — derives BLS signing capability from ATECC608 hardware identity
  • Slot-owner election with failover — deterministic recovery when designated submitter is offline
  • Clock synchronization — across offline sensor meshes (NTP-on-reconnect + mesh time consensus)
  • ZK proof circuit design — binding device identity, shipment, and range constraints into a single succinct proof
  • Filecoin/Solana coordination — Merkle structure linking on-chain anchors to off-chain encrypted archives
  • Production sensor firmwareno_std Rust on Pico W with ATECC608 driver, DS18B20 reading, WiFi management
  • Encrypted Memo summaries — privacy-preserving on-chain summaries decryptable only by authorized parties (operator, insurer, regulator)

Quick start

Prerequisites

  • Rust 1.85+ (the version April Gate's Solana toolchain ships with)
  • Solana CLI configured for devnet
  • A Solana wallet with at least 0.5 SOL on devnet (covers payer rent, device funding, and per-round transaction fees)

Build and test

cargo build --release
cargo test

Tests should pass across the consensus, simulation, and chain-client crates.

Dry run (no Solana submission)

cargo run --release -p sim-cluster

Five rounds of five sensors each, with full output showing readings, consensus, BLS aggregation, and the computed on-chain commitment. No transactions submitted.

Live run (submits to Solana devnet)

The live run is a two-step flow. Step 1 is one-time setup; step 2 is the demo itself.

There are two demo binaries — pick one:

  • sim-cluster — simple happy-path demo. 5 rounds, all sensors healthy. For a quick look at the consensus + on-chain submission pipeline.
  • sim-cluster-full-demo — full architecture arc. 5 happy rounds (including a transient outlier event consensus invisibly absorbs), then mid-demo reassignment to a new shipment (ENTER prompt for live control), then 8 rounds covering graceful degradation, threshold-limit operation, and quorum collapse. For a thorough end-to-end demonstration.
# 1. One-time setup. Converges devnet to a known target state:
#    - 5 device authorities under keys/
#    - 5 devices registered on the device_registry program
#    - 2 shipments created (happy + faulty)
#    - All devices currently assigned to the happy shipment
#    Idempotent — safe to re-run if anything fails partway.
cargo run --release -p setup-devnet -- \
  --wallet ~/.config/solana/AprilGate/wallet.json

# 2a. Run the simple happy demo (devices stay on happy shipment).
cargo run --release -p sim-cluster -- --submit

# OR

# 2b. Run the full demo. Reassigns devices to the faulty shipment
#     mid-run. Re-run setup-devnet afterward if you want to run any
#     demo again — it resets devices back to the happy shipment.
cargo run --release -p sim-cluster-full-demo -- --submit

Each round prints a Solscan transaction link plus a direct link to the new Proof account.

After setup-devnet finishes, the repo contains keys/device_01.json … keys/device_05.json (gitignored) and devnet.json (gitignored).

Recovery from devnet state pollution

The on-chain program enforces two properties by design — both load-bearing for tamper-evidence:

  • Device authority is immutable after registration. Once a DeviceRegistry PDA is created, its authority field is set forever. The keypair that registered it is the only key that can ever assign/reassign that device, sign on its behalf, or end its assignments. Hardware-rooted identity in production; the same property in demo.
  • Shipment status is monotonic. Created → InTransit → Delivered → Closed. Once a shipment passes InTransit, it cannot accept new assignments. You can't retroactively add sensors to a delivered shipment.

These properties produce two recoverable failure modes worth knowing about:

keys/ was regenerated since the first setup-devnet run

You'll see this from setup-devnet:

device_01 on-chain authority mismatch:
  PDA:      <addr>
  on-chain: <old pubkey>
  local:    <new pubkey>

The on-chain device is locked to a keypair you no longer have. Fix:

chain-client/src/lib.rs    — bump DEMO_NODE_DST (e.g. "april-gate-demo-node-v2" → "-v3")
simulation/src/lib.rs      — match the same string in derive_demo_node_id
cargo build && cargo run -p setup-devnet -- --wallet <PATH>

This is the demo equivalent of replacing hardware in production. The previous on-chain devices stay valid (their historical proofs remain), they're just no longer signable by you.

Shipments are stuck in Delivered or Closed state

You'll see this from setup-devnet:

shipment 'happy' PDA <addr> is in 'Delivered' state —
does not accept new device assignments.

Usually caused by prior test runs that exercised the full lifecycle. Fix:

chain-client/src/lib.rs    — bump HAPPY_SHIPMENT_NONCE and FAULTY_SHIPMENT_NONCE
                              (e.g. 1001/1002 → 2001/2002)
cargo build && cargo run -p setup-devnet -- --wallet <PATH>

This is the demo equivalent of starting a new shipment with new manifest IDs in production. The previous shipments stay valid; you're just creating new state alongside them.

A future iteration of setup-devnet will detect these conditions and auto-increment, removing the manual constant bump. For the current hackathon-grade demo, the manual recovery path is two minutes and teaches the architecture honestly: the chain is monotonic; recovery means moving forward, never rewriting.

Example on-chain record

For each round, sim-cluster sends one transaction containing two instructions. Clicking the printed Solscan link shows:

The Memo program log — (hackathon convenience!) human-readable JSON the way it will appear in production previews before the encrypted-Filecoin path is wired in:

Program log: Memo (len 305): "{\"round\":0,\"timestamp\":1746464567,
\"temp_x100\":415,\"participants\":5,\"nodes\":[\"82ef683e\",\"84458f29\",
\"439e018b\",\"c904bd6e\",\"6e3cf4b5\"],
\"agg_sig_fingerprint\":\"a27cb164b8...\",
\"proof_pda\":\"4xPb…vQz\",
\"commitment_hex\":\"7f3a…c012\"}"

A newly-created Proof account at proof_pda — the production-shaped tamper-evident record. The account holds:

  • The 32-byte commitment binding the full off-chain AggregatedProof (including the BLS aggregate signature and pubkey)
  • The sequence number within its assignment
  • The submitter (the slot owner's device keypair)
  • The timestamp

Mutated DeviceAssignment and Shipment accountsproof_count incremented on each.

The on-chain commitment field on the Proof account equals the commitment_hex value in the Memo JSON of the same transaction. That's the bridge from "human-readable preview" to "tamper-evident production record": one inspection path runs from the memo, through the named proof PDA, to the cryptographic anchor.

In production, the memo path is replaced by an encrypted summary readable only by authorized parties (operator, insurer, regulator), with the full sensor evidence archived to Filecoin. The Proof::commitment field provides the tamper-evidence binding.

Project structure

.
├── Cargo.toml                          Workspace config
│
├── consensus/                          Public protocol types and primitives
│   ├── Cargo.toml
│   └── src/lib.rs
│
├── simulation/                         Simulated sensors for demo
│   ├── Cargo.toml
│   └── src/lib.rs
│
├── chain-client/                       Solana client library
│   ├── Cargo.toml                      PDA derivation · Anchor ix builders
│   └── src/lib.rs                      Account decoders · devnet.json schema
│
└── bin/
    ├── sim-cluster/                    Simple happy demo
    │   ├── Cargo.toml
    │   └── src/main.rs
    │
    ├── sim-cluster-full-demo/          Full architecture arc
    │   ├── Cargo.toml                  (happy → reassignment → degradation
    │   └── src/main.rs                  → quorum collapse)
    │
    └── setup-devnet/                   Devnet provisioning utility
        ├── Cargo.toml
        └── src/main.rs

License

Apache 2.0


Built for the Solana Frontier Hackathon — Colosseum, May 2026.

About

Zero-knowledge cold chain verification · hardware-signed sensor consensus · Solana

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages