143 Commits

Author SHA1 Message Date
Dorian
d341585bed fix: Phase 8 — mesh hardening: atomic writes, unwrap elimination, GPS opt-out
- Ratchet state: atomic write via tmp + rename to prevent corruption on crash
- Block header decode: replaced .unwrap() with proper error handling on
  untrusted network data (was a crash vector from malicious peers)
- Shutdown channel: replaced .unwrap() with .ok_or_else() error propagation
- Dead man's switch GPS: default changed to opt-out (auto_include_gps=false)
- Alert signature verification: already covered by Phase 4 envelope checks

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 01:04:19 +00:00
Dorian
36a33f3575 fix: Phase 7 — key zeroization, OsRng, checked arithmetic, TOTP rate limits
- SecretsManager: raw key stored in Zeroizing<[u8; 32]>, auto-zeroed on drop
- SecretsManager: replaced thread_rng with OsRng (CSPRNG) for nonces
- Remember-me secret: derived from machine-id via SHA-256 (deterministic, no
  plaintext key storage)
- Bitcoin ecash balance: uses checked_add with u64::MAX saturation on overflow
- TOTP setup/confirm: added to EndpointRateLimiter (3 and 5 per 5min)
- AppId validation and Tor service name validation already existed

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 01:00:57 +00:00
Dorian
5853b6a065 feat: Phase 4 — mesh authentication, envelope signature verification, TX validation
- Identity announcements: verify Ed25519 key validity and X25519 consistency
- Envelope signatures: verify Ed25519 signatures on signed messages, drop invalid
- Block header validation: height range, hash length, timestamp sanity checks
- TX relay validation: hex validity, size bounds, version check before broadcast
- Rate limiter struct for per-peer relay operations
- Message sequence number field (seq) added to TypedEnvelope for ordering

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 00:49:38 +00:00
Dorian
dd8e8e9e4f fix: Phase 3 — command injection, unwrap/expect panics, unsigned image acceptance
- VPN key gen: replaced sh -c with format string (command injection) with
  safe stdin piping to wg pubkey
- Secrets manager: replaced .unwrap() on path.parent() with proper error
- Tor proxy: replaced .expect("valid proxy") with continue on error
- Image verifier: added require_signatures flag, strict mode rejects
  unsigned images and missing cosign binary

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 00:45:15 +00:00
Dorian
c005dc9a22 feat: Phase 2 — systemd sandboxing, Bitcoin RPC localhost binding, Tailscale deprivilege
- Service runs as unprivileged `archipelago` user instead of root
- Added systemd sandboxing: ProtectSystem=strict, NoNewPrivileges, PrivateTmp,
  MemoryDenyWriteExecute, RestrictNamespaces, SystemCallFilter
- Bitcoin RPC rpcallowip restricted to localhost + Podman subnet (10.88.0.0/16)
- Tailscale container: removed --privileged, uses cap-drop ALL + cap-add NET_ADMIN/NET_RAW

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 00:42:29 +00:00
Dorian
809a976960 feat: Phase 1 — per-installation credential generation, eliminate hardcoded passwords
Generate unique random passwords at first boot for Bitcoin RPC, all database
services (mempool, btcpay, immich, penpot, mysql-root), and Fedimint gateway.
Credentials stored in /var/lib/archipelago/secrets/ with 600 permissions.

Scripts: first-boot-containers.sh, deploy-to-target.sh, deploy-bitcoin-knots.sh,
container-doctor.sh all read from secrets files instead of hardcoded values.

Rust backend: new bitcoin_rpc module reads password from secrets file, env var,
or dev fallback. All .basic_auth() calls and container config strings now use
the shared credential reader instead of hardcoded "archipelago123".

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 00:39:52 +00:00
Dorian
f273816405 feat: v1.2.0-alpha — E2E encrypted mesh relay, steganography, relay status polling
Phase 5 mesh networking:
- E2E encrypted TX relay (X25519 + ChaCha20-Poly1305) — non-Archy nodes
  relay encrypted blobs transparently via Meshcore native routing
- Steganographic encoding modes (WeatherStation, SensorNetwork) — traffic
  looks like sensor data on the wire, 0xAA marker, configurable per-node
- Pre-flight Bitcoin Core health check on relay node — specific error codes
  (bitcoin_unreachable, bitcoin_syncing, tx_rejected) instead of generic fails
- mesh.relay-status RPC endpoint — frontend polls for relay result every 3s
- On-Chain / Lightning tabs in Off-Grid Bitcoin panel
- Archy Peers vs Mesh Broadcast relay mode selector
- Mesh view fills viewport (no page scroll), internal panel scrolling
- Version bump to 1.2.0-alpha

Also includes: deploy hardening, container fixes, IndeedHub updates,
boot screen, dashboard improvements, MASTER_PLAN task tracking

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 23:56:37 +00:00
Dorian
d1ac098edb feat: Phase 4 — off-grid Bitcoin relay, block headers, dead man's switch
- Typed message dispatch in listener (BlockHeader, TxRelay, LightningRelay, Alert, TxConfirmation)
- Base64 encoding for binary payloads over LoRa (fixes NUL byte truncation)
- Compact block header announcements (88 bytes, fits 160-byte LoRa limit)
- Block header announcer: internet nodes auto-announce new blocks to Archy peers
- TX relay: mesh-only nodes can broadcast transactions via internet-connected peers
- Confirmation tracking: relay node monitors 1/3, 2/3, 3/3 confirmations, sends updates back
- Dead man's switch background task with configurable interval and signed alert broadcast
- 6 new RPC endpoints: relay-tx, block-headers, relay-lightning, deadman-status/configure/checkin
- lnd.create-raw-tx: create signed TX without broadcasting (for mesh relay)
- Web5 wallet: offline detection + "Send via mesh?" prompt with auto relay + confirmation polling
- Mesh.vue: Off-Grid Bitcoin tab, Dead Man tab, Send Bitcoin/Lightning buttons
- TX/Lightning relay sends only to Archy peers (not broadcast to all devices)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 15:51:56 +00:00
Dorian
c6f1894e10 feat: Phase 3-4 Weeks 5+6 — off-grid Bitcoin ops + emergency alert system
Bitcoin relay (mesh/bitcoin_relay.rs):
- BlockHeaderCache: stores latest block headers from internet peers for SPV
- RelayTracker: tracks in-flight TX and Lightning relay requests
- Builder functions: block header announcements (Ed25519 signed),
  TX relay request/response, Lightning invoice relay/response
- All amounts as u64 sats, never float
- 4 unit tests

Emergency alerts (mesh/alerts.rs):
- AlertConfig: dead man switch settings, GPS, emergency contacts
- DeadManSwitch: background timer, auto-trigger after configurable interval
  (default 6h), signed alert broadcast with GPS coordinates
- check_in() resets timer, is_triggered() checks elapsed time
- GPS as integer microdegrees (Coordinate type from message_types)
- Disk persistence for config
- 4 unit tests

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 02:26:07 +00:00
Dorian
f504f08cd4 feat: Phase 3 Week 4 — mesh RPC endpoints for typed messages + session management
Backend (6 new RPC endpoints):
- mesh.send-invoice: create Lightning invoice, send bolt11 to mesh peer
- mesh.send-coordinate: send GPS coordinates (integer microdegrees)
- mesh.send-alert: send signed emergency alert (with optional GPS)
- mesh.outbox: list pending store-and-forward messages
- mesh.session-status: get Double Ratchet session info per peer
- mesh.rotate-prekeys: force X3DH prekey rotation

Mock backend: matching dev mode responses for all 6 new endpoints

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 02:23:30 +00:00
Dorian
c5c3dc856b feat: Phase 3 Week 3 — typed messages + store-and-forward outbox
- Create mesh/message_types.rs: typed message envelope system
  - MeshMessageType enum: Text, Alert, Invoice, PsbtHash, Coordinate,
    PrekeyBundle, SessionInit, BlockHeader, TxRelay, LightningRelay
  - TypedEnvelope: CBOR wire format with 0x02 prefix, optional Ed25519 sig
  - Payload types: AlertPayload (with AlertType enum), InvoicePayload
    (sats as u64), Coordinate (integer microdegrees, no float),
    PsbtHashPayload, BlockHeaderPayload, TxRelayPayload, LightningRelayPayload
  - Signed envelope creation + verification for alerts/block headers
  - 8 unit tests

- Create mesh/outbox.rs: store-and-forward message queue
  - PendingMessage with TTL (24h default), retry count, relay hops (max 3)
  - MeshOutbox: persistent VecDeque, max 200 messages, expiry, relay support
  - Disk persistence to mesh-outbox.json
  - 6 unit tests: enqueue, deliver, expire, persistence, max size, relay hops

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 02:08:58 +00:00
Dorian
6c23360522 feat: add per-peer ratchet session manager with disk persistence
- Create mesh/session.rs: SessionManager for Double Ratchet state lifecycle
  - Lazy-loads sessions from disk on first message
  - Saves after every encrypt/decrypt (chain key advancement)
  - Per-DID storage at {data_dir}/ratchet/{sha256(did)}.json
  - Session info API for RPC status reporting
  - Zeroize on drop for all key material
- Tests: store+load roundtrip, encrypt/decrypt through manager, session removal

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 01:54:26 +00:00
Dorian
e60ac99b12 feat: Phase 3 Week 2 — Double Ratchet protocol for forward-secret mesh messaging
- Create mesh/ratchet.rs: full Signal-style Double Ratchet implementation
  - DH ratchet with X25519 ephemeral keypairs per step
  - Symmetric-key ratchet via HKDF-SHA256 chain derivation
  - Per-message ChaCha20-Poly1305 encryption with derived message keys
  - Out-of-order delivery via skipped message key cache (max 100)
  - Forward secrecy: old keys zeroized on ratchet step
  - Wire format: 40B header + nonce + ciphertext + tag
- Tests: full conversation, out-of-order, forward secrecy, wire format,
  long conversation (50 messages alternating), message roundtrip

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 01:50:22 +00:00
Dorian
37a591618d feat: Phase 3 Week 1 — X3DH key agreement + HKDF foundation
- Add hkdf = "0.12" dependency for Double Ratchet key derivation
- Extend mesh/crypto.rs with hkdf_sha256, hkdf_sha256_32, hkdf_sha256_64,
  and generate_x25519_ephemeral() for DH ratchet steps
- Create mesh/x3dh.rs: full X3DH key agreement protocol
  - PrekeyBundle generation with Ed25519-signed prekeys
  - 3-way (or 4-way) ECDH → HKDF-SHA256 → root key
  - Initiator and responder sides derive identical root key
  - CBOR encoding for mesh transmission
  - Bundle signature verification
  - 5 unit tests: generate+verify, both-sides-same-key,
    without-one-time-prekey, cbor-roundtrip, tamper-detection

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 01:28:35 +00:00
Dorian
7867ac1931 feat: complete Phase 2 transport layer — off-grid mode, transport icons, federation sync
- Add off-grid (mesh only) toggle to Mesh.vue with orange OFF-GRID banner
- Add per-peer transport indicator in Federation.vue (mesh/lan/tor icons)
- Add sync_with_peer_via_transport() for CBOR delta sync via transport router
- Fetch transport store on mount in both Mesh and Federation views

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 00:45:37 +00:00
Dorian
f42ff45475 fix: resolve merge conflicts and compile errors for transport layer
- Resolve stash conflicts in Cargo.toml, rpc/mod.rs, AppDetails.vue, Apps.vue
- Fix ScopedIp conversion in LAN transport (mdns-sd compatibility)
- Fix String vs &str in transport RPC send handler
- Remove duplicate mod transport declaration
- Remove stale mesh.discover route (replaced by mesh.peers/messages/send)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 00:34:37 +00:00
Dorian
32f89fa8d5 backup commit 2026-03-17 00:03:08 +00:00
Dorian
57f3416d60 fix: Tor toggle tries systemd before container restart
The toggle handler only tried `podman restart archy-tor` which fails
on servers running Tor as a systemd service. Now tries
`systemctl restart tor` first (like the rotation handler already does),
falling back to container restart.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 17:41:32 +00:00
Dorian
30164fd12a feat: bitcoin-ui CSS fix, HTTPS proxy support, deploy script improvements
Bitcoin UI:
- Replace cdn.tailwindcss.com with locally bundled tailwind.css (CSP blocks external scripts)
- Make all asset paths relative for nginx proxy compatibility
- Add bitcoin-ui build/deploy to deploy-to-target.sh (was missing entirely)
- Use --network host (bitcoin-ui proxies Bitcoin RPC at 127.0.0.1:8332)

HTTPS mixed content fix:
- Add HTTPS_PROXY_PATHS in AppSession.vue — when parent page is HTTPS,
  iframe loads through nginx proxy instead of direct HTTP port
- Prevents browser blocking HTTP iframes inside HTTPS pages
- All Tailscale servers use HTTPS, this was breaking all app iframes

Deploy & first-boot improvements:
- first-boot-containers.sh auto-detects disk size for pruning vs txindex
- first-boot-containers.sh checks fallback source path for UI containers
- Added mempool-electrs to APP_PORTS mapping
- ElectrumX container creation in first-boot
- Podman doctor/fix/uptime skills added

Also includes: session persistence, identity management, LND transactions,
ElectrumX status UI, nostr-provider improvements, Web5 enhancements

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 12:58:35 +00:00
Dorian
cc270bcf34 fix: use c.name not c.names in factory reset
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 05:21:32 +00:00
Dorian
7b9fa08493 fix: use PodmanClient::new() in factory reset handler
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 05:20:15 +00:00
Dorian
c545b79b65 feat: factory reset, backup restore, auto-identity creation
- system.factory-reset RPC: wipes user data, preserves images/node_key
- Factory Reset button in Settings with confirmation modal
- backup.restore-identity RPC: decrypts and restores DID key
- Restore from Backup panel in OnboardingIntro first screen
- Auto-create default identity with Nostr key on boot if none exist

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 05:18:12 +00:00
Dorian
b447100637 fix: remove duplicate get_default_id, fix tests to use list()
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 05:02:51 +00:00
Dorian
53ac7e5f65 feat: identity lifecycle tests and ADR-011 DWN deprioritization
Added 8 integration tests for identity manager covering create,
sign/verify, list, delete, default management, and Nostr key gen.
Documented DWN deprioritization decision.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 05:01:06 +00:00
Dorian
ae5d04993c feat: Phase 8 — encrypt credentials at rest, DHT refresh, pkarr eval
- Credentials now encrypted with ChaCha20-Poly1305 using node key
- Auto-detects plaintext JSON for migration from existing installs
- Added did:dht auto-refresh background task (every 2 hours)
- Documented pkarr evaluation findings

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 04:59:20 +00:00
Dorian
ef30a38969 fix: restore Instant for rate limiters, keep SystemTime for sessions
Rate limiters correctly use monotonic Instant. Session TTL uses
SystemTime for wall-clock accuracy across sleep/hibernate.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 04:36:23 +00:00
Dorian
9a3bff1c61 refactor: remove dead code and #[allow(dead_code)] annotations
Removed unused sync podman_command/docker_command methods.
Removed dead_code annotations from User and AuthManager (now actively used).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 04:34:14 +00:00
Dorian
ef58b2ad18 feat: enforce RBAC in RPC dispatcher
Check user role against method permissions before dispatch.
All current users default to Admin, laying groundwork for multi-user.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 04:32:59 +00:00
Dorian
299357e908 fix: use SystemTime instead of Instant for session TTL
Instant is monotonic but drifts on sleep/hibernate common on NUC
hardware. SystemTime gives proper wall-clock expiry for sessions.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 04:32:24 +00:00
Dorian
a6ab181136 fix: correct IndeedHub port mapping from 8190 to 7777
Backend metadata and manifest now match the actual running config
and the frontend port mapping.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 04:28:18 +00:00
Dorian
9ba8731816 fix: consolidate IndeedHub icon to indeedhub.png and fix all references
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 04:01:58 +00:00
Dorian
b29f798e05 fix: correct PhotoPrism icon filename typo in backend metadata
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 04:01:12 +00:00
Dorian
bd40fac0e6 bullshit 2026-03-15 00:40:55 +00:00
Dorian
ee15fbc457 bug fixes from sxsw 2026-03-14 17:12:41 +00:00
Dorian
8669dfc3ca feat: hardware compatibility, TPM attestation, security audit prep
- Y2-01: docs/hardware-compatibility.md — 2 certified platforms,
  4 planned, minimum requirements, known quirks
- Y3-04: tpm.rs — TPM 2.0 attestation types (TpmStatus, TpmAttestation,
  detect_tpm), ready for tss-esapi integration
- Y5-03: docs/security-audit-prep.md — audit scope, completed internal
  audits, recommended firms, budget estimates

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-14 05:57:32 +00:00
Dorian
a7e0a847a8 fix: stub marketplace payment check, fix build errors
Replace handle_lnd_lookupinvoice (doesn't exist) with stub.
Payment verification deferred to Y4-02 marketplace implementation.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-14 05:56:07 +00:00
Dorian
5ea45d77a1 feat: add cluster HA module stub and mark PWA mobile companion done
- Y3-03: cluster.rs with Raft types (ClusterRole, ClusterState,
  AppPlacement, ClusterConfig). Ready for openraft integration.
- Y2-04: Existing PWA already serves as mobile companion (installable,
  read-only dashboard works on mobile via HTTPS).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-14 05:55:03 +00:00
Dorian
6c71e525ea feat: add Monero and Liquid Network container support
- AppMetadata for monerod/monero and elementsd/liquid in docker_packages
- Marketplace entries with pinned images from trusted registries
- Monero: sethforprivacy/simple-monerod:v0.18.3.4
- Liquid: vulpemventures/elements:23.2.2

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-14 05:53:41 +00:00
Dorian
139c89d27b fix: add missing tracing::warn import in update.rs
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-14 05:52:16 +00:00
Dorian
8044c08279 feat: add Lightning payment endpoints for paid marketplace
- marketplace.create-invoice: generates BOLT11 via LND for app purchase
- marketplace.check-payment: checks invoice settlement status
- Uses existing LND integration (createinvoice/lookupinvoice)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-14 05:51:09 +00:00
Dorian
8e27c11b74 fix: add missing role field to User struct, fix unused variable
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-14 05:49:52 +00:00
Dorian
077e2887b5 feat: rolling container restart and RBAC user roles
- Y5-02: rolling_container_restart() in update.rs — restarts containers
  one at a time with health checks, reports success/failure per container
- Y3-01: UserRole enum (Admin/Viewer/AppUser) with can_access() RBAC

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-14 05:48:53 +00:00
Dorian
ad49670da5 feat: add UserRole RBAC framework for multi-user support
- UserRole enum: Admin (full), Viewer (read-only), AppUser (minimal)
- can_access() method checks RPC method against role permissions
- Role field on User struct with serde default (backward-compatible)
- Viewer: read system/federation/DWN/identity/backup/container status
- AppUser: system.stats, node.did, container list, password change

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-14 05:46:10 +00:00
Dorian
f49340e179 feat: add opt-in anonymous node analytics (Y4-03)
New RPC endpoints:
- analytics.get-status: Check if analytics opted in
- analytics.enable/disable: Toggle opt-in
- analytics.get-snapshot: Anonymous aggregate data (version, app count,
  hardware tier, CPU cores, RAM, federation peers)

No personal data: no DIDs, no IPs, no secrets. Strictly opt-in.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-14 05:45:52 +00:00
Dorian
c5064b6979 feat: add S3-compatible backup upload/download (Y3-02)
New RPC endpoints:
- backup.upload-s3: Upload encrypted backup to any S3-compatible endpoint
- backup.download-s3: Download backup from S3 to local storage

Supports MinIO, Backblaze B2, Wasabi via basic auth + S3 API.
Backups are AES-256-GCM encrypted before upload.
Rate-limited at 3 requests per 10 minutes.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-14 05:44:05 +00:00
Dorian
16b389dda1 fix: watchdog killing backend every 60s on .198 (47 restarts/day)
Root cause: sd_notify::notify(true, ...) cleared NOTIFY_SOCKET env var,
so watchdog pings never reached systemd. Backend killed every 60s.

Fixes:
- Change sd_notify::notify first param to false (keep socket)
- Increase WatchdogSec from 60 to 300 (5min) for crash recovery
- Add TimeoutStartSec=300 for slow container startups
- Adjust watchdog ping interval to 120s

This was causing 47 restarts/day on .198 and blocking REBOOT-03,
FLEET-03, FLEET-04, VC-04.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-14 04:30:57 +00:00
Dorian
aabe28fc98 fix: add bytes crate for mainline DHT Bytes type
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-14 04:18:32 +00:00
Dorian
dc48d6fc8c fix: use correct mainline v2 API for DHT operations
- get_mutable takes &[u8; 32] directly (not VerifyingKey)
- MutableItem::new takes bytes::Bytes (not Vec<u8>)
- Remove VerifyingKey import (not exported from mainline v2)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-14 04:17:05 +00:00
Dorian
4a3611f3b4 fix: resolve did:dht compilation errors
- Simplify DHT encoding: use JSON instead of DNS packets (drop simple-dns)
- Fix mainline crate API: SigningKey takes 32 bytes, get_mutable returns Result
- Add missing dht_did field to IdentityRecord constructor
- Store DID Document as JSON in DHT (DNS encoding deferred)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-14 04:14:04 +00:00
Dorian
66eba4a46d feat: implement did:dht creation and resolution via Mainline DHT
DHT-02: did:dht creation
- network/did_dht.rs: z-base-32 encoding, DNS packet encoding, BEP-44
  mutable item publication via mainline crate
- identity.create-dht-did RPC endpoint
- dht_did field added to IdentityRecord
- get_signing_key() exposed on IdentityManager

DHT-03: did:dht resolution
- did_dht::resolve() queries DHT, parses DNS → DID Document
- DhtDidCache with 1-hour TTL
- identity.resolve-dht-did, identity.refresh-dht-did, identity.dht-status

New dependencies: mainline 2, zbase32 0.1, simple-dns 0.7

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-14 04:01:56 +00:00