Skip to content

feat(plugins): Solana DePIN node — solana-core + depin-attest + depin-uptime-watch#126

Open
darkty0x wants to merge 23 commits into
zeroclaw-labs:mainfrom
darkty0x:feat/solana-depin-core
Open

feat(plugins): Solana DePIN node — solana-core + depin-attest + depin-uptime-watch#126
darkty0x wants to merge 23 commits into
zeroclaw-labs:mainfrom
darkty0x:feat/solana-depin-core

Conversation

@darkty0x

@darkty0x darkty0x commented Jul 21, 2026

Copy link
Copy Markdown

The $40 Pi that talks to Solana

ZeroClaw already runs on a Raspberry Pi with GPIO, MQTT, and cron SOPs. It just had no chain. This PR is the reference DePIN path: a sensor reading becomes an unsigned Solana memo attestation that survives the approval queue, then a cron tool tells you when the node goes quiet.

Tracks C (DePIN) and E (shared core). Custody is T0/T1 only — the agent never holds a key and never calls sendTransaction.

What's in it

Component Track Tier Role
solana-core E Wasm-friendly substrate: injectable JSON-RPC, base58, SPL Memo, durable-nonce parse/advance, legacy unsigned tx encode. No solana-sdk.
depin-attest C T1 Builds an unsigned durable-nonce memo attestation from a device reading. Config-only payer / nonce_account. Metric allowlist + reading caps fail closed.
depin-uptime-watch C T0 Scans recent memos for an exact prefix|device_id match. Returns OK / STALE / MISSING in ≤800 chars for Telegram cron alerts.
[BME280/DHT22] --I2C--> [Raspberry Pi / ZeroClaw SOP]
                              |
                              v
                    depin_attest (T1 unsigned tx)
                              |
                     human signs (durable nonce)
                              v
                      Solana memo on-chain
                              |
              cron --> depin_uptime_watch --> Telegram if STALE/MISSING

Why durable nonce here

The bounty brief calls blockhash expiry the structural problem with approval-gated agent txs. Attestations hit the same trap: the agent builds, Telegram queues, the human is away, the blockhash dies. depin-attest anchors the memo tx to a durable nonce account so the approval queue stays valid until the human signs.

Hard requirements

  • Layout matches plugins/redact-text (pure core + #[cfg(target_family = "wasm")] shim, crate-type = ["cdylib", "rlib"])
  • Host tests with mocked RPC, no live network, no wasm toolchain for cargo test
  • cargo build --target wasm32-wasip2 --release clean
  • Structured logging via log-record only; nothing on stdout
  • rpc_url required in config — never hardcoded with a key; arg overrides rejected
  • Manifests: capabilities = ["tool"], permissions only http_client + config_read
  • READMEs: custody tier, threat model, worked example, traps table, injection transcript, what we'd build next
  • Prompt-injection transcripts are executable (tests/injection.rs) including fund-move / sendTransaction / rpc_url injection
  • Output budgets tested (attest ≤900 chars, watch ≤800, memo ≤566 bytes); no getProgramAccounts
  • Exact memo field matching in the watcher — no substring contains() fallback
  • ./tools/sync-solana-core.sh --check keeps vendored copies drift-free for isolated CI
  • overflow-checks = true in release profiles
  • MIT

Bounty traps

Trap Fix
Blockhash expiry Durable-nonce unsigned tx
solana-sdk on wasip2 Hand-rolled solana-core + bs58/base64/sha2 + waki shim only
Context flood Shaped summaries; no getProgramAccounts
Experimental wit/v0 Pin repo tool-plugin world; expect rebuild
RPC key in code Config-only rpc_url via config_read

Custody

Plugin Tier Secrets What it returns
depin-attest T1 none unsigned_tx_base64 + short summary
depin-uptime-watch T0 RPC URL at most OK / STALE / MISSING

What fought us on wasm32-wasip2

solana-sdk / solana-client are a non-starter inside a WIT component. What worked: bs58 + base64 + sha2 + hand-rolled legacy message / compact-u16 / durable-nonce layout, JSON-RPC behind an injectable HttpClient, and waki only in the wasm shim. Each plugin vendors solana-core under src/vendor/solana_core/ so isolated CI (plugins/<name> + wit/v0 only) still builds. Canonical source: repo-root solana-core/. Sync with ./tools/sync-solana-core.sh; drift check with --check. wit/v0 has no .frozen marker — rebuild when ABI moves.

What we'd build next

  1. Pi SOP pack (BME280 → attest → Telegram approve → session-key sign outside the plugin)
  2. Memo schema v2 under the 566-byte cap
  3. Fleet rollup watch (many devices, still shaped)
  4. Optional separate T2 submit crate — never inside these T0/T1 plugins

Demo / Earn

  • Demo pack + checklist: SUBMISSION.md
  • Live Telegram channel used in demos: @zeroclaw_plugin_bot
  • Video: terminal + agent + on-chain explorer (≤3 min); phone Telegram clip completes the channel requirement

darkty0x and others added 18 commits July 22, 2026 07:48
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Drop substring fallback that let a short prompt-injected device_id
falsely report OK. Also normalize manifests/docs and drop internal planning files.

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
@darkty0x darkty0x changed the title feat(plugins): solana-core + depin-attest + depin-uptime-watch (Track C+E) feat(plugins): Solana DePIN node — solana-core + depin-attest + depin-uptime-watch Jul 21, 2026
darkty0x and others added 2 commits July 22, 2026 09:50
Document bounty traps and “what next” in plugin READMEs, tighten
output budgets and fund-move/RPC injection tests, and add SUBMISSION.md
for Superteam Earn.

Co-authored-by: Cursor <cursoragent@cursor.com>
Add timeouts/retries, watch pagination and CPI memo scans, and emoji
structured tool summaries so channel replies stay clear under T0/T1 custody.

Co-authored-by: Cursor <cursoragent@cursor.com>
@darkty0x

Copy link
Copy Markdown
Author

Update

Pushed production harden + polished Telegram cards (9e2f03e):

  • RPC timeout/retry, watch pagination + CPI memos
  • Emoji structured attest/watch summaries for channel UX
  • Still T0/T1 only (no keys / no submit)

Demo video being refreshed to ≥2 min with Telegram channel scenes for Earn.

darkty0x and others added 3 commits July 22, 2026 14:21
Co-authored-by: Cursor <cursoragent@cursor.com>
Ship scripts, runner, and agent workspace prompts while gitignoring
keys, live config, recordings, and other local secrets/runtime state.

Co-authored-by: Cursor <cursoragent@cursor.com>
Remove make-final-demo, wire-telegram, keep-channel, and related
helpers; keep the host runner and example config only.

Co-authored-by: Cursor <cursoragent@cursor.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant