centaur wallet

A wallet whose private key is never assembled — not on our servers, and not in your browser

Centaur Wallet is a non-custodial wallet built on threshold signatures. A conventional wallet has one private key: whoever holds it can spend, and every design decision after that is an attempt to keep one secret in one place safe. This one has no such key. At setup the wallet generates three shares — one in your browser, one held by a coordination service, one kept in cold storage for recovery — and a signature is produced by two of them working together, using FROST, the threshold Schnorr scheme standardised as RFC 9591. The shares are never combined, not even for an instant, and no participant ever learns another's.

What that buys is concrete: stealing the share in your browser is not enough to move funds, and neither is compromising the coordinator. There is no seed phrase to write down and no single file whose theft is terminal. What it costs is that signing becomes a protocol between parties rather than a local computation — which is what this page exists to show you, round by round, as it happens.

The signing itself runs as a Rust implementation of FROST compiled to WebAssembly, inside a browser tab. This page is a demonstration stand for a system under active development. It is not a product you can put money into, it holds no real funds, and nothing it signs is broadcast to any network.

How it works

1. The key is generated in pieces

Distributed key generation (DKG) runs as four rounds between the three participants. Each ends up with a share of a key that was never whole anywhere. What comes out of it publicly is a group verifying key — the wallet's Ed25519 address, and the only part of the key material that is meant to be seen.

2. Two parties sign, jointly

A transaction is signed by two shares in a two-round protocol: commitments first, then signature shares that are aggregated into one ordinary Ed25519 signature. The chain sees a single signature from a single address and cannot tell it was produced by more than one party — the threshold structure costs nothing on-chain and is invisible to the network.

3. A policy sits in the middle

Because a second party must agree before anything is signed, that party can hold a transfer to the rules you set. A transaction over your limit is queued with a delay and an email that can cancel it — from a device other than the one that asked. A stolen session on your laptop does not survive a message to your inbox.

Why the signing panel is a separate frame

The dark panel further down this page is not part of this page. It is an iframe served from a different origin, and the browser's same-origin policy is what separates them: script running here cannot read its memory, its storage, or the share it holds, and the only thing that crosses between them is a structured message with a fixed set of shapes. This page asks for a signature; it never asks for the share, because there is no message that would answer.

That boundary is the reason an application can embed this wallet without being trusted with anything. It is also why the two halves are built differently on purpose: the page you are reading is an ordinary web application with a framework and a design system, and the signing frame is a deliberately small program with a strict Content Security Policy and no dependency that is not needed to hold a key share. Everything added here is surface area that cannot reach it.

Try it

Sign in with an email address to get a one-time code, create a wallet and watch the four DKG rounds go by, then sign a test transfer and read back what the coordinator understood the transaction to be — amounts and destinations, not a hex blob. Then send one over the limit and watch it get held, with the cancellation link arriving out of band. Nothing here is broadcast, and the balances are fictional.

What this demo proves, and what it does not

It does show

  • A key generated as shares, and an address derived from a key nobody ever held.
  • A signature produced across an origin boundary, with the share never leaving its own origin.
  • A transaction parsed and judged by the second party before it agrees to sign.
  • A held transfer, its countdown, and a cancellation that arrives by email rather than by browser.
  • A share that survives a full page reload, and the unlock step that brings it back.

It does not show

  • Real funds. No transaction here is broadcast to any network, and no balance is real.
  • An audited system. The cryptography is under review and the deployment is a stand, not a service.
  • Protection against a compromised browser. A page that is already running an attacker's code can ask for signatures the same way this one does — which is what the policy layer and the out-of-band cancellation exist to bound.
  • Recovery. The third share and the backup path are a separate piece of work.