Control any backend with a signed transaction.
Sigil turns the Solana ledger into a programmable command bus. Drop a JSON command into a transaction memo, sign it, and your backend runs it. Build anything — and your users never connect a wallet again.
Signed by the user, carried as a memo, interpreted by your backend. No session, nothing live to phish.
From a signed memo to a real action.
A command is just a JSON memo inside a signed transaction. The relayer streams it; the interpreter validates, authorizes and runs it. Watch one charge through the pipeline.
{ "cmd": "post", "args": { "text": "gm" } }
signed · sent as memo · no wallet connect
on-chain · ordered · timestamped · with backfill
Bring your own command language
Define your own JSON commands and the handlers that run them, on top of one shared engine. Ship a game, a dApp, a vote, a bot or an automation in minutes — without writing a protocol of your own.
Stop connecting wallets
No connect button. No session. No approve-this-site popups. People just sign and send a transaction — from a wallet, a CLI, a script or an agent. The frontend never touches keys and holds nothing an attacker can drain.
Go deeper, or just run a command.
The path every command takes, and the frozen v1 envelope it travels in.
ReadGames, dApps, ops, automation, agents, token-gating — one engine for all.
ExploreDeclare a command with a schema and handler. SDKs and an API do the rest.
StartFrom devnet today to a public, open command layer on mainnet.
ViewWallets, contracts, spam, cost, the token — the honest answers.
ReadBuild, sign and simulate a command end to end. Watch it move received → done.
LaunchA signed transaction in. A real action out. All verifiable.
Every command takes the same path. Because it is signed, you get authentication for free. Because it is on-chain, you get ordering, timestamps and a public audit trail for free. No smart contract of your own to deploy.
Build a JSON command and sign a transaction that carries it in the memo. No site connection, no session.
The transaction lands on Solana: ordered, timestamped and permanent. The ledger is the message bus.
A relayer streams transactions filtered to each app's control address, with backfill so a dropped socket never loses a command.
Validate the schema, authorize the signer against the allowlist, and dedupe by transaction signature.
Run the matching handler serially per app, so no two commands ever race. State stays consistent.
An optional on-chain receipt makes the whole round trip provable, end to end.
One frozen shape. Commands are data, never code.
A command is an ordinary transaction with two things: a memo instruction carrying a single JSON object, and a transfer to the app's control address — its inbox. The v1 envelope is frozen, and validation is strict: unknown top-level keys are rejected.
- Per-command JSON schema. The engine never runs arbitrary code.
- The signer is cryptographically proven. No tokens, no secret URLs.
- One command record per signature. Replays are deduped automatically.
{ "v": 1, // frozen version "app": "board", // namespace "cmd": "post", // command name "args": { "text": "gm, on-chain" }, "nonce": "1a2b3c" // optional, idempotency }
One engine. Anything you can name.
The only thing that changes between apps is the command set they register, and who is allowed to call it. Many apps run on one engine, isolated by namespace and control address.
Every move is a signed, ordered, permanent action. Provably fair, replayable, and playable from any client — wallet, CLI or bot.
Users act by signing a transaction, not by connecting. The frontend can be a fully static file with no live link to a wallet.
deploy, rotate-key, set-flag, restart. Every privileged action is signed and logged forever — a control plane, not a remote-code hole.
Schedules, triggers and dead-man switches on a public, ordered ledger — not a hidden cron job no one can audit.
Issue an AI agent's actions as signed commands. Provable, auditable behavior — every decision is on the record, after the fact.
Only holders, stakers or a multisig may issue a command. Authorization comes straight from the signer set — no extra gatekeeper.
Add your app by dropping a new namespace into the registry. No new protocol, no new infrastructure.
Declare a command. Sigil does the rest.
Register a command with its schema and a handler. The framework validates, authorizes, dedupes, orders and executes it for you. That is your whole backend.
Define an app: a namespace, commands, handlers.
- Strict JSON schema per command — never arbitrary code.
- Authorization fails closed: signer → role → command.
- Idempotent by transaction signature, ordered per app.
- Copy one file to build a game, a dApp, an ops plane — anything.
registerApp({ namespace: 'board', controlAddress: INBOX, commands: { post: { schema: z.object({ text: z.string().max(280) }), handler: (ctx) => board.add(ctx.signer, ctx.args.text), }, }, })
Integration in a few lines, from any client.
Use the TypeScript SDK — sigilsol-sdk, published on npm — or call the same HTTP API from any language. The same API powers the console.
// npm i sigilsol-sdk import { createClient } from 'sigilsol-sdk' const sigil = createClient({ signer: 'Demo7xQ…' }) const receipt = await sigil.simulate({ app: 'board', cmd: 'post', args: { text: 'gm, on-chain' }, }) // → { status: 'done', result: { posted: true } }
The same endpoints that run the console.
From a signed memo to an on-chain operating layer.
We ship the open-source core first, then layer the rest on top — in public. Honest status: the core engine, the command envelope and the console run on devnet today.
sigilsol-sdk). On-chain receipts, signer roles, and Rust / Python clients are next.Sigil command desk LIVE
Real Ed25519-signed commands, verified server-side. Every number on this screen is measured live — nothing is mocked.
A fresh Ed25519 keypair generated in your browser this session.
Don't trust the UI — check it. Forge a signature and watch the server reject it, or verify the last one independently.
———Sigil documentation.
Everything you need to send your first command and build an app on the signed command bus. Self-hosting the framework is free.
Introduction
Sigil is a command bus built on the Solana ledger. Instead of connecting a wallet to a website, a user puts a small JSON command in a transaction memo and signs it. A relayer streams that transaction, and an interpreter validates, authorizes and runs it.
Because every command is signed, you get authentication for free. Because it is on-chain, you get ordering, timestamps and a public audit trail for free. You never deploy a smart contract of your own — the ledger is only the ordered message bus.
New here? Jump to the Quickstart, then open the console to watch a command run end to end.
Quickstart
Install the SDK and run a command end to end. In simulate mode the interpreter validates, authorizes, dedupes and executes it, then returns a receipt — no wallet connection, no session.
$ npm i sigilsol-sdk added 2 packages in 1.4s
import { createClient } from 'sigilsol-sdk' const sigil = createClient({ signer: 'Demo7xQ…' }) const receipt = await sigil.simulate({ app: 'board', cmd: 'post', args: { text: 'gm, on-chain' }, }) // → { status: 'done', result: { posted: true } }
The command envelope
A command is a small JSON object carried in the transaction memo. This v1 shape is frozen and validated with a strict schema on the way in — unknown top-level keys are rejected.
{ "v": 1, // frozen version "app": "board", // namespace "cmd": "post", // command name "args": { "text": "gm, on-chain" }, "nonce": "1a2b3c" // optional, idempotency }
The memo carries a single JSON object. The v1 shape is frozen so clients, interpreters and SDKs never drift apart.
Apps & handlers
An app is a namespace, a set of commands with schemas, and the handlers that run them. Many apps run on one engine, isolated by namespace and control address.
registerApp({ namespace: 'board', controlAddress: INBOX, commands: { post: { schema: z.object({ text: z.string().max(280) }), handler: (ctx) => board.add(ctx.signer, ctx.args.text), }, }, })
The handler context (ctx) gives you the proven signer, the validated args, and the transaction signature. Commands are data, never code — there is no eval, ever.
Authorization
Anyone can send a memo to a public address, so the allowlist / role check must be airtight and fail closed. Authorization is enforced from the on-chain signer set: only holders, stakers or a multisig may issue a command.
- Authorization fails closed: signer → role → command.
- Unauthorized or garbage commands are rejected cheaply and never executed.
- Per-signer rate limits, per-command caps and a blast-radius kill switch.
Interpreter pipeline
Every command — real or simulated — flows through the same path:
- received — the relayer reads the transaction from the stream.
- signature verified — the Ed25519 signature is checked against the signer's public key; forgeries are rejected.
- schema valid — the args are validated against the command schema.
- signer authorized — the signer is checked against roles, fail closed.
- deduped — one command record per transaction signature.
- executing — enqueue on a serial queue keyed by resource so two commands never race.
- done — the handler runs and an optional on-chain receipt is posted.
Watch this happen live in the command console.
Streaming
The relayer exposes a live transaction stream filtered to each registered control address — an app inbox. Backfill on startup and reconnect means a dropped socket never loses a command.
for await (const cmd of sigil.stream({ app: 'board' })) { console.log(cmd.cmd, cmd.status) // post received // post done }
SDKs
Use the TypeScript SDK (sigilsol-sdk), or call the same HTTP API from any language. Native Rust and Python clients are on the roadmap.
$ npm i sigilsol-sdk # TypeScript SDK — published on npm $ # Rust & Python: call the HTTP API (native clients on the roadmap)
API reference
The same endpoints run the console. Every endpoint here exists in the backend today.
$ curl -s https://sigil-backend-production-41ef.up.railway.app/api/apps { "apps": [ { "namespace": "board", "commands": ["post"] } ] }
Try it
The fastest way to understand Sigil is to run a command and watch it move through the interpreter.
How the engine stays safe by design.
Sigil is a control plane, not a remote-code-execution hole. Safety does not depend on a careful operator — it falls out of the architecture. The frontend holds no keys, commands are data, and authorization fails closed.
No live session between a site and a wallet means there is nothing to phish, hijack or drain. The frontend can be a fully static file.
Every command has a JSON schema. Anything that does not validate is rejected and logged. Commands are data — no eval, ever.
The signer is cryptographically proven by the transaction itself. No tokens, no secret URLs. Authorization fails closed: signer → role → command.
One command record per transaction signature. Replays are deduped automatically and never run twice.
Act only at confirmed or finalized — never on processed or unconfirmed transactions that could later vanish in a reorg.
Per-signer rate limits, per-command caps, and a blast-radius kill switch per control address. Memo parsing is hardened against malformed, oversized and duplicate payloads.
Every action is permanent and independently auditable.
Every privileged action is signed and permanently logged — a tamper-proof audit trail instead of a private admin panel. Every real command links straight to the Solana explorer, and the full log is queryable over the API.
Planned before mainnet: an independent security review of the interpreter, authorization and dedupe paths, plus reorg, gap and spam fuzzing against the relayer. See the roadmap.