A dead man's switch for your crypto. Write down where the wallets, seeds and logins are, seal it with a passphrase only your family knows, and check in now and then. If you stop checking in, the people you chose get the sealed bundle.
- Web: https://deadman.switch.pit.world (on Moshpit DNS: https://deadman.switch)
- CLI and TUI:
bunx @profullstack/deadman - MCP:
claude mcp add deadman -- bunx @profullstack/deadman mcp - API:
https://deadman.switch.pit.world/api/v1(Authorization: Bearer ds_…)
- Seal. The bundle (a note plus files) is encrypted on your device: PBKDF2-SHA256 (600,000 rounds) into AES-256-GCM. The server stores only the ciphertext. You give the passphrase to your heir yourself.
- Check in. Every 1 to 365 days. The email link, the push notification's "I'm OK" button, the web, the CLI, the API or MCP all restart the clock.
- Reminders. A missed check-in gets three reminders across the grace period (1 to 30 days), by email and push, and on paid plans a phone call on the last one. Reminders are at least 12 hours apart.
- Release. Only after the grace period, and at least a day after the last reminder (so an outage can never skip the warnings), each recipient gets their own link. The page shows your hint, asks for the passphrase, and opens the bundle in their browser.
The server cannot read a bundle, and nobody can open one before it fires.
| Free | Keeper ($49/year or $149 for life) | |
|---|---|---|
| Switches | 1 | 10 |
| People per switch | 2 | 10 |
| Sealed bundle | 64 KB | 5 MB |
| Reminders | email, push | email, push, phone call |
Paid in crypto through CoinPay. A lapsed plan never switches protection off: existing switches keep running on the free channels.
Credit codes (@profullstack/redeem-credits):
a code grants the unit keeper_days, days of the Keeper plan. Redeem it under
"Have a code?" on /me, with deadman redeem <code>, MCP redeem_code, or
POST /api/v1/redeem {"code"}. The days go through the same columns a payment
writes (users.plan / plan_until): on the end of a running plan, from now on
a lapsed one. Keeper for life is refused before the code is spent, so it can be
passed on. Days granted out of band are applied when that person next opens /me.
The redeem-credits CLI only speaks SQLite, so mint on the box with bin/codes.ts:
cd /opt/deadman.switch && set -a && . /root/.local/share/deadman-switch/app.env && set +a
bun bin/codes.ts mint --days 30 --label "for Dan" [--max 1] [--expires 30d]
bun bin/codes.ts list
bun bin/codes.ts revoke <codeId>
bun bin/codes.ts grant someone@example.com --days 7Invites (@profullstack/affiliates):
three single-use links per account at /invites (deadman invites [new],
GET/POST /api/v1/invites). A link lands on /i/<code>, rides in a 7-day
cookie and on the sign-in email link (so it survives opening the email in
another browser), and is spent when a new account is made through it. Then
both people get 7 days of Keeper. Every account also has an open affiliate
link (/?ref=<code>), remembered first-touch for 30 days and credited to new
accounts. bin/codes.ts invites <email> --total N changes someone's allowance.
deadman login ds_… # key from /me#account
deadman status
deadman checkin
deadman new "My crypto" --every=30 --grace=7 --to=kid@example.com
deadman seal "My crypto" note.md seed-card.png --hint="first dog, then the year"
deadman read "My crypto"
deadman open https://deadman.switch.pit.world/r/r_…
deadman redeem CR-XXXX-XXXX-XXXX-XXXX
deadman invites new --note="for Sam"Bun + Hono + Postgres (DATABASE_URL). Tables are made on boot.
bun install
DATABASE_URL=postgres://… DEADMAN_SECRET=$(openssl rand -hex 32) bun src/server.ts| Variable | |
|---|---|
DATABASE_URL |
Postgres |
DEADMAN_SECRET |
32+ characters; signs check-in links and CSRF tokens |
RESEND_API_KEY, MAIL_FROM |
email (without a key, mail goes to the log) |
VAPID_PUBLIC_KEY, VAPID_PRIVATE_KEY |
web push (bunx web-push generate-vapid-keys) |
COINPAY_API_KEY, COINPAY_BUSINESS_ID, COINPAY_WEBHOOK_SECRET |
payments |
TELNYX_API_KEY, TELNYX_CONNECTION_ID, TELNYX_FROM, TELNYX_PUBLIC_KEY |
phone calls |
ADMIN_EMAILS |
accounts that get Keeper free |
PORT (8801), WORKER=off |
Tests: TEST_DATABASE_URL=postgres://postgres:test@127.0.0.1:55491/postgres bun test
(see test/app.test.ts for a one-line docker Postgres).
Deploy: bin/install.sh on the box (OpenInstall), settings in bin/install.conf.
MIT. By Profullstack, Inc.