Skip to content

Repository files navigation

LOCKET

A vault that listens for your heartbeat.

Locket wraps a crypto asset in a small encrypted file you can hand to the people you trust today. They hold it, but they can't touch it. If your heartbeat ever goes missing for longer than a window you chose (a day to 180 days), the file opens for them. Until then, and always, your own key opens it. Change your mind later and you can take a locket back for good.

Built on Unicity, where an asset is a self-contained file and the rules for spending it live inside the file itself. Background reading: the Unicity whitepaper and the developer portal.

created with love by @0XM0RA

Testnet preview. Do not seal real funds. Every network call targets the Unicity testnet, and the badge in the app never comes off.

Quickstart

npm install
npm run dev      # http://localhost:3000
npm test         # 145 unit tests: crypto, envelope, .locket format, predicate, anchor, guardian, connect, DM, relay pulses, revocation, identity derivation, backup, notify, calendar, amounts
npm run build    # production build

No environment variables, no secrets, no backend. Deploy notes for someone who has never used a terminal live in DEPLOY.md.

What's live and what's preview

Piece Today Notes
Identity and keys live testnet BIP39 + secp256k1 via the Sphere SDK, created in the browser
Test coins (UCT) live testnet self-minted on the v2 token engine; there is no faucet
Heartbeat live testnet each beat lands as a certified state transition on the aggregation layer (delegated anchor key, deed-pinned) and publishes to the relays; signed local fallback
Heartbeat identity live derived from a wallet signature, so any device holding the wallet rebuilds the same one; older identities keep beating, and re-importing your own file rescues its clock
Vault backup live one passphrase-sealed file carries the vault list, received files, and heartbeat keys to a new device, merged on restore
Deed signatures in .locket files live real wallet-key signatures, verifiable offline
Encryption live a random content key under AES-256-GCM, wrapped to every wallet key named in the deed (ephemeral ECDH); key-only by default, with an opt-in passphrase door (PBKDF2 310k) for recipients without a Locket wallet
Handover over Sphere DMs live testnet the sealed file rides an end to end encrypted message to a @nametag
Sphere Connect live testnet Connect protocol 2.1: extension, embedding frame, or the hosted wallet's own popup host; sign/mint/DM as wallet-approved intents. A wallet lock keeps the session alive and says so; only a disconnect stands it down
The silence clock live testnet recipients verify anchored beats with BFT inclusion proofs and relay events with the owner key, and the clock fails closed when the network doesn't answer
The window's enforcement preview who-may-claim is still client-checked; time predicates aren't public yet
Taking a locket back preview an owner-signed revocation rides the relays and the aggregation layer; Locket clients refuse a retired file for everyone but the maker, and a device never forgets one it verified
Staged release live one seal can make two lockets: words on the shorter window, coins waiting behind a longer one
Claim settlement preview nothing moves at sealing; claiming mints the amount to the named recipient (or the owner); moving the original tokens under a network-enforced predicate is the roadmap
Guardian live testnet delegated heartbeat-only key; --relay mode publishes verified beats to the relay and lands them on the aggregation layer, and imported beat files (script or Astrid capsule) reach both the moment they verify

The longer, honest version lives at /docs in the app.

How it's put together

lib/crypto/vault.ts        WebCrypto: PBKDF2 (310k) + AES-256-GCM envelopes
lib/crypto/envelope.ts     the key layer: content keys wrapped to wallet
                           keys (ephemeral ECDH + HKDF + AES-GCM)
lib/sphere/                Sphere SDK wiring; wallet state is encrypted
                           before it ever touches IndexedDB
lib/sphere/pulse-anchor.ts heartbeats as certified state transitions on
                           the aggregation layer, verified with BFT
                           inclusion proofs; the fail-closed epoch scan
lib/sphere/pulse-relay.ts  heartbeats as signed relay events, one round
                           per relay, reachability reported honestly;
                           revocations ride the same wire
lib/sphere/pulse-identity.ts the wallet-derived pulse identity: same
                           wallet, same identity, on any device
lib/locket/backup.ts       the whole device state as one passphrase-
                           sealed file, merged on restore
lib/locket/predicate.ts    the SilencePredicate interface and both
                           implementations (Unicity + faithful local preview)
lib/locket/file.ts         the .locket format v2: LCKT magic, envelope
                           header (key wraps + optional passphrase door),
                           AES-256-GCM
lib/locket/guardian.ts     heartbeat-only key delegation and verification
lib/sphere/dm.ts           sealed lockets over encrypted Sphere DMs
lib/sphere/connect.ts      Sphere Connect (bring-your-own-wallet handshake)
public/guardian.mjs        the downloadable Guardian agent
capsules/locket-guardian   the same Guardian as an Astrid OS wasm capsule
app/                       landing page, vault, seal, receive, guardian, docs

The Guardian runs three ways

  1. A tap in the app (or a browser reminder at 80% of the window).
  2. guardian.mjs, a dependency-free Node script with a delegated heartbeat-only key.
  3. An Astrid OS capsule: the same agent as a sandboxed wasm32-wasip2 component, built with the published Astrid toolchain. Campaign details in SUBMISSION.md.

License

MIT

About

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages