Give an AI agent the ability to act on nostr — it drafts the action, you enact it with a signature, it broadcasts. The agent never holds the key.
The missing safety layer for agentic nostr
Almost every “AI posts to social” integration hands the bot your credentials — which is why nobody sane points one at their real account. nact inverts that: the authorization is your signature, and the key that produces it never leaves you. An agent can compose, schedule, and publish on your behalf, but every outbound action passes a human tap. Human-in-the-loop isn’t a setting you can forget to enable — it’s the architecture.
An unsigned event — note, reaction, follow, zap, any kind.
You approve on your channel; your key signs. Reject = nothing happens.
The finished, signed event goes to the relays.
Why it’s safe
Role keys are custodial only by your explicit choice; your sovereign identity signs via NIP-46 and never touches a server.
Approvals are checked against a single identity — your Telegram ID, or your npub in the nostr-DM adapter.
You see the exact event and a rationale before signing. No standing “post whenever” authority — ever.
Scoped autonomy
An agent bounded on both ends — what it may perceive, and what it may do.
| governs | direction | |
|---|---|---|
| Nvoy | what the agent may perceive — scoped, revocable data grants | in |
| nact | what the agent may do — signature-gated actions | out |
Quickstart
// the agent drafts; nact routes it to you; your key signs on approval import { Nact } from 'nact' import { telegramApproval } from 'nact/adapters/telegram' const nact = new Nact({ identities: { nave: { nsec: NAVE_NSEC }, luke: { nsec: LUKE_NSEC } }, relays: ['wss://relay.damus.io', 'wss://nos.lol'], approval: telegramApproval({ botToken, approverId, webhookSecret }), }) // your proposer (LLM + signals + voice) asks for an action to be enacted: await nact.propose({ identity: 'nave', event: { kind: 1, content: 'shipped nact today — an agent that acts only when you sign.' }, context: 'launch note', // shown to you, never published }) // → you get an Approve / Reject prompt. Approve → signed & broadcast.
Ships with a Telegram approval adapter and a custodial signer today; a NIP-59 gift-wrap DM adapter (approve in any nostr client) and a NIP-46 signer (your key stays on your phone) are the nostr-native path. See the design →