dune_core 0.0.1
dune_core: ^0.0.1 copied to clipboard
Core Dune SDK, runtime contracts, and peer-to-peer protocol logic.
Dune Core #
Dune Core is the protocol and Dart SDK for building Dune apps.
Dune is private social software for small trusted groups. Instead of sending group content to a central app server, Dune stores messages, posts, media, and shared canvas state on participant devices and syncs them over a Tailscale private network.
This repository is the home of the reusable core: identity, signed events, local storage, peer networking, resource APIs, protocol docs, and deterministic test harnesses. The Flutter app is one client built on top of it; other Dart clients can use the same runtime to build CLIs, bots, desktop apps, or long-running peers.
Start Here #
- Website - product overview and architecture story.
- Protocol docs - the Dune protocol, canonical encoding, and test vectors.
- Security review - trust boundaries and residual risks.
- Storage policy - what host apps must provide for durable runtime storage.
- Test plan - unit, P2P, and Tailscale e2e test strategy.
What Dune Core Provides #
- A local-first social runtime for messages, posts, media, spaces, devices, peers, search, logs, and shared canvas state.
- A signed event protocol so peers can validate who did what before materializing local state.
- Device-owned storage through host-provided secret storage and directories, instead of a Dune-hosted content service.
- Peer networking over Tailscale so approved devices can discover and reach each other on a private WireGuard-based network.
- A public Dart API shaped around app resources such as
Dune.messages,Dune.devices,Dune.peers, andDune.canvas. - Protocol and integration test tools for building realistic multi-peer tests without a full Flutter app.
The Programming Model #
Applications import the app-facing SDK:
import 'package:dune_core/dune_core.dart';
The host app configures storage, starts the runtime, and then uses resource
APIs off the Dune namespace:
Future<void> startDune({
required SecretStore secretStore,
required DirectoryConfig directories,
}) async {
Dune.configure(
secretStore: secretStore,
directoryConfig: directories,
);
await Dune.start();
await Dune.network.connect();
}
From there, app code stays close to product intent:
final recoveryPhrase = await Dune.peers.createRecoveryPhrase();
final peerKey = await Dune.peers.create(
recoveryPhrase: recoveryPhrase,
name: 'Jessica',
deviceName: 'MacBook',
);
final invite = await Dune.devices.createInviteLink();
await Dune.messages.sendText(
'Hello from Dune',
recipients: [peerKey],
);
final recent = await Dune.messages.query().latest(limit: 50).get();
The public API is intentionally resource-oriented. Apps should not need to know which tables, repositories, or peer-server endpoints power each operation.
Package Libraries #
| Library | Audience | Purpose |
|---|---|---|
dune_core.dart |
App developers | Stable resource APIs such as Dune.peers, Dune.devices, Dune.messages, Dune.posts, and Dune.canvas. |
dune_core_protocol.dart |
Protocol tooling | Event models, canonical encoding helpers, and protocol-level DTOs for advanced consumers. |
dune_core_testing.dart |
App and SDK tests | Supported peer harnesses and deterministic testing helpers. |
dune_core_testing_internals.dart |
Dune-owned tests | Explicit escape hatch for internal services and repositories. This is not a stable app-facing API. |
Normal application code should import only package:dune_core/dune_core.dart.
The protocol and testing libraries exist for protocol tools, non-Dart
implementation work, and Dune's own integration tests.
How The Protocol Fits Together #
Dune Core is designed around a few core ideas:
- Peers are people or agents. A peer has a recovery phrase and signing key.
- Devices are approved runtime nodes. Device identity is bound to a Tailscale node ID so a revoked node cannot immediately rejoin as a new device.
- Events are the durable source of truth. Messages, posts, device changes, peer updates, and canvas state are published as signed events.
- Local projections make apps fast. Each device materializes the event log into local queryable state for normal app screens.
- Sync is peer-to-peer. Devices exchange events and current resource state directly over the private network.
See the protocol spec for the precise data model, authorization rules, canonical JSON profile, and current protocol gaps.
Runtime Configuration #
Dune Core does not choose a platform secret store or app directory layout. Production hosts must provide durable implementations before starting the runtime:
Dune.configure(
secretStore: platformSecretStore,
directoryConfig: platformDirectories,
);
await Dune.start();
For tests and demos, hosts can explicitly opt into an ephemeral runtime:
Dune.configure(
secretStore: InMemorySecretStore(),
directoryConfig: TemporaryDirectoryConfig(),
);
await Dune.start();
Use durable platform secure storage for production identities and durable app support directories for the database and media store.
Testing #
The repository test suite is split by the kind of confidence each layer should provide:
dart analyze
dart test test/unit test/api --timeout=240s
dart test test/p2p --timeout=240s --concurrency=1
The real Tailscale/Headscale smoke suite is opt-in:
RUN_TAILSCALE_E2E=1 tool/test_release.sh
See test/README.md and doc/test_plan.md for the full test architecture.
Status #
Dune Core is in a pre-1.0 launch phase. The public app-facing API is intended to be usable by real Dune clients, while protocol docs, test vectors, and package boundaries are still being hardened before a stable 1.0 contract.
The published package intentionally excludes repository-only test harnesses, release scripts, and GitHub Pages assets. Use the repository checkout when working on the protocol, integration tests, or release validation.