← All projects

Active development · web available AirChat

Conversations whose keys stay with you

A messenger without phone numbers or sign-up. Your seed phrase is your account: one identity unlocks encrypted history on another device.

My role

Product logic, account model and architecture

Milestone / date

Current snapshot: September 2026

Development approach

I own logic and architecture. Code is developed with AI tools.

Problem & my contribution

Changing phones often means depending on a phone number, an account operator or a separate backup. The goal is a portable identity and synchronized history without giving the server the keys to the content.

My contribution. I define account and recovery behavior, user journeys, client/server trust boundaries and the synchronization design. I own the product logic that explains what is protected, what remains visible and what losing the key means.

Identity is derived from a seed phrase. Clients encrypt records before upload; the server holds encrypted entities with revisions and cursors. The local database is a UI projection. WebRTC signaling stays separate from history storage.

Outcome

A browser client is available. The source implements portable identity, encrypted account sync, revisions, tombstone deletion and profile boundaries. Native builds add LAN messaging. The visual below shows the actual entry screen, not an end-to-end cryptographic audit.

Engineering highlights

Retry delivery, not the mutation

Idempotent mutations and cursors let a client recover after a connection loss. Signed requests and nonces address the separate problem of replay.

Deletion is synchronized state

A tombstone preserves the deletion. Otherwise another client can reload an old record and bring a deleted message back.

History and connectivity are separate

Signaling establishes peer connections; it does not become a second message database.

Architecture

Device A · key
Device B · key
↓ one seed identity
Client-side encryption
↓ signed requests
Sync API · ciphertext + cursor
↓ pull → decrypt → apply
Local projection
Separate WebRTC signaling
Layer Technology & purpose
Frontend React Native, Expo 55, TypeScript; web and native clients
Backend Node.js, cloud-vault / sync, separate WebRTC signaling
Data Client SQLite; encrypted entities, revisions and server cursors
Security BIP39, did:key, @noble; client-side keys and encryption

Trade-offs & lessons

Seed-based recovery removes dependence on a phone number, but the operator cannot reset a lost phrase. Encrypted records protect content, not all connection and synchronization metadata.

What the implementation taught

A core sync failure mode is a locally successful deletion that does not survive a later pull. Deletion is therefore record state, and the cursor advances after application. This is an architectural risk, not a fabricated incident story.

What I would improve now

I would prioritize reproducible two-device scenarios: concurrent edits, deletion while offline, recovery and device revocation. Evidence from those runs is more useful than a broad “secure messenger” claim.

Operations & data

Sync, signaling and notifications are separate services. Source includes log scrubbing and Sentry integration. Native clients require platform builds and dependencies; web has its own capability limits.

Data & migrations

A mutation carries an identifier, revision, owner and tombstone. sync_entity_heads tracks local record versions; sync_state stores the cursor and sync state. Schema ownership follows service boundaries rather than one shared database for every client.

Entity Stored state
Mutation idempotency key, revision, owner, tombstone
sync_entity_heads Local synchronized record version
sync_state epoch, pull cursor, timestamps
Media Encrypted bytes + reference; client holds the key

Limits

Servers see metadata. Public-link posts are unencrypted. Browser key storage is weaker than native secure storage. Sync and calls require connectivity. No independent cryptographic audit is claimed here.

Evidence & source

Verified 24 Sep 2026: 71 sync/vault checks; local /health responds. These are targeted checks of the described decisions, not a full application audit.

Claims above are tied to public code and documentation. Evidence links point to the reviewed revision; CI status may change.

CI / checks · MIT licence · Quick start

Have a problem or an idea?

Let’s talk.

A project, a partnership or a strong team — I’m open to a conversation.