Skip to content
Chippr Robotics

Chippr Robotics

Happy Helpful Robots

  • Home
  • Research
  • Our Github
  • About Us

Tag: account-recovery

Posted on August 11, 2026August 9, 2026

Shared Vaults Where No One Person Can Move the Money

How FairWins lets a group hold a shared treasury and act as the group — using battle-tested multisig wallets, and nothing but the blockchain to coordinate

Note: FairWins wagers are peer-to-peer forecasts on publicly available information. Nothing here changes that: money that moves out of a shared vault passes the same sanctions and membership checks as a personal-wallet action, and everyone involved remains subject to applicable law.


Several People, One Vault, No Server

The Ethereum Classic Cooperative holds its money the way most serious on-chain organizations do: in a multisig — a shared wallet where several people must approve before any money moves. No single keyholder can drain it. If one laptop is stolen or one person goes rogue, the funds are still safe, because a spend needs, say, two of the three owners to sign off.

We wanted groups to do exactly this inside FairWins: hold a shared treasury, then place a wager or send a payment as the group, with a spend only going through once enough co-owners approve. The shared wallet itself was the easy part. We use Safe, the most widely used multisig on Ethereum and its cousins — audited for years, already deployed on the networks we care about. Rolling our own would have been the worst security decision available to us.

The hard part was everything around the wallet. The usual way people coordinate a Safe assumes a hosted server in the middle: it stores proposed transactions, collects approvals, and feeds them to the wallet’s screen. FairWins has a firm rule against exactly this — no company server the app must depend on. The app has to keep working, and members must never be locked out of their own money, even if every piece of FairWins-run infrastructure disappeared tomorrow.

So the real question was: how do the co-owners of a shared vault discover a pending transaction, check that it’s legitimate, approve it, and execute it — using nothing but the blockchain itself? The answer needed surprisingly little new code: one tiny contract that holds no money and has no power.

Why Safe, and Which Version

A “vault” in FairWins is a standard Safe multisig — not a fork, not a wrapper. Vaults you create work with the rest of the Safe ecosystem, and an existing Safe (like the Cooperative’s) can be loaded just by its address.

The version we picked mattered more than we expected. We chose the release whose official contracts sit at the same addresses on every network we support — Ethereum Classic, its Mordor test network, and Polygon. One consistent set of addresses everywhere means far less that can go wrong, and it let us confirm each contract was really deployed by asking the chain directly rather than trusting a list. When those contracts aren’t present on a network, the app honestly says the feature is unavailable. The app also carries no heavyweight Safe software library — the standard toolkit assumes the hosted server we don’t run, and the little we actually need is stable enough to talk to directly.

Approving Without a Middleman

A Safe can authorize a transaction two ways: owners can sign it off-chain and someone gathers the signatures, or each owner can register their approval directly on the blockchain. We use only the second. In plain terms:

  1. Build the exact transaction the group wants to make.
  2. Fingerprint it — reduce it to a unique hash, a short code that stands in for the full transaction and can’t be forged.
  3. Approve — each owner sends a small on-chain transaction that says “I approve the transaction with this fingerprint.” The blockchain itself becomes the record of who has approved.
  4. Execute — once enough approvals exist to meet the threshold, any owner triggers the transaction. The Safe checks the on-chain approvals and runs it.

No signatures are collected off-chain, and the same approval can’t be counted twice. Best of all, this flow can never strand anyone: the vault’s own on-chain state is the coordination, so if FairWins vanished, any standard Safe tool could read those same approvals and finish the job.

The Missing Piece: Knowing What You’re Approving

On-chain approvals create one real gap. When an owner is asked to approve, all the blockchain shows is the fingerprint — a meaningless-looking code that reveals nothing about where the money is going. The full details don’t appear on-chain until the transaction executes, far too late to review.

The hosted server most people run exists largely to fill this gap. Our replacement is a deliberately tiny contract — think of it as a public bulletin board. When someone proposes a transaction, they post its full details there, and everyone else’s app watches for proposals affecting their vault.

The clever part is that the board holds no trust. Each co-owner’s app takes the posted details, re-computes the fingerprint itself, and refuses to approve anything whose details don’t match the fingerprint being claimed. A tampered or spoofed proposal produces a different fingerprint and dies inside the co-owner’s own app; the worst a bad actor can do by posting junk is waste their own transaction fee. The board carries information, never authority.

And because even this contract is optional, there’s a fallback: a proposer can export the full transaction as a signed file and share it as a link or QR code. The co-owner imports it, checks the same fingerprint, and approves — working even on a network where the board was never deployed.

“Operate As the Vault”

A custody tab that only sends simple transfers is just a basic Safe client, not a real integration. The whole point is that a member can become the vault: create a wager staked from the vault’s funds, or pay someone from it, with the action held until the co-owners approve. Originally the app only knew you as your personal connected wallet. Rather than teach every feature about shared vaults, every money-moving action now flows through one shared checkpoint:

  • Personal mode: send from your own wallet, exactly as before.
  • Vault mode: assemble the group transaction, post it to the bulletin board, record your own approval — and return a pending proposal, never a completed action.

A persistent banner shows which identity is active, and a pending vault action shows up only in the vault’s own queue — never as a phantom entry in your wager list or payment history until the blockchain confirms it. Implying money moved when it hasn’t is exactly the dishonesty the design refuses.

One honest wrinkle surfaced along the way. Inbound movements — receiving funds, or a refund owed to the vault — need no group approval, since the contract routes that money to the recorded party no matter who asks. But claiming a winning payout is different: the contract insists the winner themselves claim it, so a vault that wins a wager must claim through the normal group-approval path. We documented that as a known exception rather than pretend a single owner could pull the payout alone.

A Socket for Rules

Everything above makes the vault usable; it doesn’t yet make it governable beyond “enough people approved.” A multisig has exactly one control — a set number of owners agree — and once that bar is cleared it will send any amount, anywhere. Safe’s answer is a transaction guard: a contract the Safe consults before executing anything, which can veto a transaction that breaks the rules. This feature ships the wiring so a brand-new vault can be rule-governed from its very first transaction. What those rules look like — spending limits and allowlists enforced at execution time, so even a quorum of compromised signers can’t break them — is the subject of part 2.

Design Decisions

  • Adopt a proven multisig, don’t build one. Years of audits and a whole ecosystem of compatible tools, for free — and we picked the version whose official addresses match across all three of our networks.
  • No hosted coordination. On-chain approvals replace the middleman server. Each approval is a small fee-paying transaction; in exchange, the blockchain is the single source of truth and no one can ever be locked out.
  • A bulletin board that carries data, never trust. Every proposal is re-verified inside each co-owner’s own app, and the signed-file fallback means zero required infrastructure.
  • Honesty over convenience. Every money-moving flow reroutes through one well-reviewed checkpoint, pending vault actions live only in the vault queue, backups store addresses and labels but never key material, and the vault-won-payout exception is documented rather than papered over.

Further reading

  • Safe, the multisig wallet used here — https://safe.global
  • The EIP-712 standard for human-readable, signable transaction data — https://eips.ethereum.org/EIPS/eip-712
  • EIP-1271, how smart-contract accounts prove a signature — https://eips.ethereum.org/EIPS/eip-1271
Posted on August 4, 2026July 22, 2026

Losing Every Passkey Shouldn’t Mean Losing the Account

How FairWins made passkey accounts recoverable — without bringing back the seed phrase — and folded connecting, controlling, and recovering into one simple screen

The phone in the river

Someone signs up for FairWins with a passkey. No seed phrase, no browser extension — Face ID creates the credential, and a smart-contract account springs from it. The onboarding passkeys always promised: nothing to write down, nothing to lose.

Then the phone goes in the river. Or the browser profile gets wiped, or the laptop dies. Most of the time your phone’s built-in sync (iCloud Keychain, Google Password Manager) has quietly backed the passkey up and you’re fine — but not always. A passkey created in a browser profile that wasn’t syncing is simply gone. With an old-style wallet, recovery was brutal but obvious: retype your twelve words. Passkeys deliberately removed those words. So what’s the recovery story now?

There was a second, quieter problem that made the recovery question moot: even connecting was broken. The app offered three different places to connect, each with different options, and one couldn’t even reach the passkey option. Worse, two real bugs locked passkey users out: on some browsers, signing back in left every transaction crashing, and one browser would silently sign you into your first passkey no matter which account you picked.

The insight was to treat all of this as one thing. Connecting, managing who controls your account, and recovering after a lost device are really the same lifecycle — so they should live behind one door. This post walks through how that works, and why none of it touched the account contracts.

The account already knew how to be recovered

Remember from the previous post: a FairWins passkey account doesn’t have a single owner. It keeps a list of owners, each of which can be a passkey or an ordinary wallet address. They’re equal peers — any one can add or remove the others.

That is the entire recovery mechanism, hiding in plain sight. If a second controller exists when your phone dies, recovery is a single action: that controller adds a fresh passkey. And because a linked ordinary wallet can do this with a plain everyday transaction, recovery needs no special infrastructure — no relayer, no service, nobody’s permission but your own. The account also protects itself: it refuses to remove its last remaining owner, and it only accepts changes from a genuine current owner.

So the real work was never in the contracts. It was in getting people to actually have that second controller before disaster, and making the app honest and reliable enough to use it.

One front door for connecting

The first fix was a single connect screen. Every entry point now opens the same dialog; nothing else renders its own list of choices. The options are ordered passkey first, then WalletConnect, then browser-extension wallets, and the app checks up front whether each is actually available — showing an honest “not detected” or “not supported” instead of failing after you tap.

It also runs only one connection attempt at a time, so a background attempt to restore your previous session can never barge in and override one you started yourself — which is what used to produce those stuck states.

The two bugs that made passkeys unusable

A single front door only helps if the passkey path behind it is solid. Two root-cause fixes shipped alongside it, both app-side bugs against perfectly correct contracts.

The half-saved credential. When you first signed up, the app recorded everything it needed about your passkey. When you later signed back in, it didn’t record the same details — and that missing information was exactly what the transaction machinery needed, causing the crash-on-every-transaction bug. The fix: repair the record on every sign-in, and if it’s still incomplete, catch it early with a clear “please sign in again with your passkey” message instead of letting it explode deep in the signing code later.

The passkey the app didn’t choose. When a browser holds several passkeys and the app makes an unspecific request, some browsers just grab the first one — locking multi-account users into account number one. The fix was to always tell the browser exactly which passkey this session should use, and, when several exist, show the app’s own account picker before the biometric prompt rather than letting the browser guess.

A third, subtler fix falls out of recovery: once an account can gain new controllers, the app can no longer assume your passkey is “owner number one.” It now reads the account’s real owner list on-chain and matches your credential to its actual position — and if your credential isn’t in the list, it stops rather than sign blindly.

Linking before disaster

Recovery depends on having a second controller while you still have passkey access. So the account screen lists every current controller and lets you add a second passkey, link an external wallet, or remove one — each a single biometric approval.

Two honesty rules govern linking. First, the app states plainly that a linked wallet gains full control — equal peers means equal power. Second, every wallet you try to link is screened against sanctions lists before anything goes on-chain, and it fails closed: flagged or impossible to screen means refused. Any account still down to a single controller gets a persistent “link a backup before you lose this device” warning.

Recovery without FairWins

There’s also a wallet-only recovery flow for the worst case: your passkeys are gone, but you linked a wallet earlier. You connect that wallet — no passkey anywhere — and the app walks you through it:

  1. Which account? The blockchain has no “look up my accounts by owner” index, so the app asks for the account address, suggesting ones your browser has previously associated with passkeys.
  2. Prove ownership. The app confirms the address is a real, deployed account, then that your connected wallet really is an owner, before letting you continue.
  3. Create and authorize. You make a fresh passkey on the new device, and your linked wallet sends one ordinary transaction adding it as an owner. Only once that confirms does the app save the new credential — so your very next sign-in can transact.

Because the account is a standard, publicly documented smart contract, this same recovery works with generic, off-the-shelf tools even if FairWins the company vanished. Your funds were never dependent on us being around.

Why we built it this way

No guardians, no social recovery. Recovery is strictly “any controller you linked ahead of time can act.” An account whose only passkey lived on a lost, un-synced device is unrecoverable by design — no one, including FairWins, can help. That’s a hard trade, made on purpose: guardian schemes reintroduce trusted third parties, and phone sync already covers the common case. The answer is gentle pressure to link a backup early, not a custodial safety net that would compromise self-custody.

Equal owners, not thresholds. Every controller is a full peer. That’s simpler to reason about and it’s what makes wallet-only recovery a single transaction — but it means linking a wallet hands over full control, which the app says out loud. People who want “2-of-3”-style shared custody have a separate multisig option.

Recovery restores control, not secrets. The owner list guards your funds, but encrypted private features use a separate master seed. A freshly recovered controller that never held that seed can’t read old encrypted data until the keys are re-shared to it. Getting your funds back and getting your encrypted history back are two different steps, and the app is upfront about that.

A frontend fix for a frontend problem. Fixing both bugs in the app — with clear error messages instead of crashes — kept the audited account contracts untouched.

The result: connecting has one front door, every passkey prompt is pinned to the account you actually chose, and losing every passkey becomes an inconvenience instead of an ending — as long as you linked a backup first. Making sure you did is the app’s whole job.

Further reading

  • Passkeys / WebAuthn (W3C): https://www.w3.org/TR/webauthn-2/
  • What passkeys are, in plain terms (FIDO Alliance): https://fidoalliance.org/passkeys/
  • The ERC-4337 account-abstraction standard (smart-contract wallets): https://eips.ethereum.org/EIPS/eip-4337
  • Coinbase Smart Wallet (open source): https://github.com/coinbase/smart-wallet

Recent Posts

  • Censor, Never Steal: Why the Service That Decides Is Never the Service That Signs
  • Compliance as Code: On-Chain Screening, KYC/AML Programs, and the Travel Rule
  • One Signature, Zero Gas: How Gasless Payments Actually Work
  • Enough Signatures Is Not Enough: Adding Real Rules to a Shared Vault
  • Passkeys and Smart Accounts: A Wallet With No Password to Write Down
  • Instagram
  • Twitter
  • Linkedin
  • Discord
Privacy Policy Proudly powered by WordPress