nomos_flutter 0.50.0 copy "nomos_flutter: ^0.50.0" to clipboard
nomos_flutter: ^0.50.0 copied to clipboard

Drive the real Nomos GitHolon from a Flutter app — a local-first domain runtime. iOS + macOS run the native-AOT kernel (no WebView memory cap); Android uses a hidden secure WebView. Write TypeScript d [...]

nomos_flutter #

Drive the real Nomos GitHolon from a Flutter app. You write a powerful, polymorphic TypeScript domain, run nomos compile, and get a typesafe Dart client. This package is the runtime that client runs on: it boots the byte-identical wasm32-wasip1 GitHolon inside a hidden, secure WebView host and hands you a connected bridge. TS domains in, Flutter widgets out — the webview embedding, the secure loopback origin, the runner bundle, the wasm, and sync are all hidden in here.

Local-first: every read, write, and merge happens on-device against the local holon; the cloud is custody + sync. One binary on web/iOS/Android/macOS.

Use it #

# pubspec.yaml
dependencies:
  nomos_flutter: ^0.1.0
import 'package:flutter/material.dart';
import 'package:nomos_flutter/nomos_flutter.dart';
import 'nomos/todo.dart'; // the generated package barrel (`nomos compile`; copy build/dart/ into your app)

void main() => runApp(const MaterialApp(home: Home()));

class Home extends StatelessWidget {
  const Home({super.key, required this.uid, required this.token});
  final String uid;     // the signed-in user's auth-provider uid (e.g. Supabase / Firebase)
  final String token;   // their access token (sent as x-nomos-auth, kernel-verified)
  @override
  Widget build(BuildContext context) => NomosScope(
        cloud: 'https://nomos.captainapp.co.uk',
        workspace: homeNameOf('user:$uid'),  // the user's OWN home holon (see "Auth + home" below)
        authToken: token,                    // proves who they are — required for private/home data
        builder: (context, nomos) {
          final app = TodoClient(nomos.bridge);          // your generated typed client
          return TodoPage(app);                          // app.addTodo(...), app.watchTodosByList(...)
        },
      );
}

That's the whole integration. NomosScope boots the holon, connects to the workspace, and rebuilds with a connected NomosClient; everything platform-specific is inside the package.

A public, shared workspace (a guestbook, a demo) can pass a fixed workspace: 'my-workspace' and omit authToken. But a per-user app should address the user's OWN workspace by identity and authenticate — see Auth + home holons below.

Auth + home holons #

Nomos identity comes from YOUR auth provider (Supabase, Firebase, Auth0 — any OIDC-style issuer the cloud or your platform trusts). A request proves who it is by sending its access token as x-nomos-auth; NomosScope does that for you when you pass authToken:

final session = Supabase.instance.client.auth.currentSession;   // your provider's SDK
NomosScope(
  cloud: 'https://nomos.captainapp.co.uk',
  workspace: homeNameOf('user:${session!.user.id}'),
  authToken: session.accessToken,        // → x-nomos-auth: <token>, verified IN the kernel
  builder: (context, nomos) => YourPage(nomos.bridge),
);

The token is verified by the githolon itself (ES256-via-JWKS, or the legacy HS256 lane) — the host verifies nothing. An invalid token is REFUSED; if you omit authToken, the request rides the open anonymous lane (fine for public reads, but private/home data fails closed without a principal). (Transitional bare-uid lane: a backend that already trusts the caller can send the raw uid as x-nomos-principal instead — there is no NomosScope field for it; it's a raw-HTTP detail.)

What a home holon is #

A home holon is the workspace that belongs to ONE identity — a user's personal, subject-side root. "Workspace", "platform", and "home" are the SAME githolon wearing the role its installed law gives it; a home runs the identity law (its public device-key directory, a "shared-with-me" index, and an inbox of grants/invites/notifications). Private keys never leave the device, so the cloud hosting it stays operator-blind.

A home is addressed by a DETERMINISTIC, collision-free name derived from the identity's SUBJECT — never the raw uid and never an app-chosen string — so the same principal always resolves the same home, on every peer and on the cloud, and a share addressed to a subject routes to exactly ONE home:

// homeNameOf(subject) == 'home-' + first 40 hex chars of sha256(utf8(subject))
final ws = homeNameOf('user:$uid');   // e.g. 'home-9f86d081884c7d659a2feaa0...'

homeNameOf is exported from package:nomos_flutter/nomos_flutter.dart (and from @githolon/client in JS, and the law side in dsl/src/framework/home.ts) — all three are byte-identical, and the home's own law carries a "squat" invariant that asserts its name hashes its owner, so a workspace named home-<h> can only ever be its rightful owner's slot. Use it directly as the workspace. A home is born lazily — a share can be delivered to a stranger's home before they ever log in.

The typed client #

nomos compile emits ONE package barrel build/dart/<name>.dart (the stable entrypoint; the per-domain types + clients + vendored support live under build/dart/src/generated/, generated-owned and wiped per compile) exporting a <Domain>Client per domain — each over a NomosBridge with typed dispatch, reactive watch… queries parsed into read models, by-id reads, and O(1) count/sum. You wrap it over nomos.bridge:

final app = TodoClient(nomos.bridge);
final head = await app.addTodo(AddTodoPayload(listId: id, text: 'milk'));   // offline-first write
app.watchTodosByList(listId: id).listen((rows) => setState(() => _todos = rows)); // reactive read
await nomos.bridge.sync();   // push session branch → cloud admission → pull main

Platform setup #

Almost nothing — but Apple's sandbox needs one line that a package cannot set for you:

  • macOS: add to macos/Runner/DebugProfile.entitlements and Release.entitlements:
    <key>com.apple.security.network.client</key>
    <true/>
    
    (The sandbox blocks even the loopback host without it.)
  • iOS / Android / Web: nothing. (iOS loopback is exempt from Local Network privacy; web uses the page origin.)

How it works (so you don't have to think about it) #

The holon is JavaScript+wasm; Flutter can't run it directly. NomosScope mounts a 1×1 flutter_inappwebview and serves the bundled runner over a loopback http://127.0.0.1 origin — a secure context, so crypto.subtle + storage + WebAssembly all work (an about:blank/file: origin silently breaks them). The runner boots @githolon/client, which pulls the byte-identical holon wasm + the workspace ledger from the cloud and replays it locally. A small JSON bridge connects Dart ↔ the runner. flutter_inappwebview is used (not the official webview_flutter) because its WKWebView embedding is the robust one across macOS/iOS.

Platform setup (Firebase auth + home holons + estate invitations) #

If you are standing up a product on a Nomos platform (e.g. co2): the full step-by-step — set Firebase BYOAuth, give each user a home holon, birth estate workspaces, and the free SharedWithMe invitation system — is in architecture/co2_platform_runbook.md. Every step is proof-backed (bench/scale/home_delivery_e2e.mjs).

0
likes
0
points
4.18k
downloads

Publisher

unverified uploader

Weekly Downloads

Drive the real Nomos GitHolon from a Flutter app — a local-first domain runtime. iOS + macOS run the native-AOT kernel (no WebView memory cap); Android uses a hidden secure WebView. Write TypeScript domains, get a typesafe Dart client, build Flutter widgets.

Repository (GitHub)
View/report issues

License

unknown (license)

Dependencies

ffi, flutter, flutter_inappwebview, flutter_js, nomos_client, path_provider, web

More

Packages that depend on nomos_flutter

Packages that implement nomos_flutter