Skip to content
Tandem
Start reading

A Bitcoin primitive for two

Some things belong to
two people, not one.

Tandem gives two people one Bitcoin object they hold together. It keeps a continuous history, neither person can move it alone, recovery is arranged before anyone needs it, and its state is published only when two independently built indexers agree on what it is.

Carrier value
20,000 sats, fixed by the protocol
Signatures to move it
Two, always
Recovery delay
52,560 blocks
Indexers that must agree
Two, at the same height

Tandem is early, and this page is going to keep saying so. The specification is frozen and the indexer's protocol boundaries are written and tested, but Tandem is not activated on any Bitcoin network, the block ingestion loop is not built, and the verified surface refuses mainnet responses until an operator switches them on. Nothing here claims users, adoption, or a production deployment, because there are none to claim.

The object

This is the whole primitive.

Press anything. The object answers the way the protocol requires, not the way a demo would prefer. Notice what a rotation does to the chapter count, and what recovery does to the sequence number.

0active
chapters
0
founding
yes
carrier
20,000 sats
key0
0296090…e60d41
key1
02fc8a2…61c94c
address
bcrt1q79zm…sp8470c

The record so far1 entry

CREATEseq 0

Both parties signed. The object exists at sequence 0 with no chapters yet.

This is a teaching model. It runs entirely in this page, builds no transaction, and touches no Bitcoin network. The rules it follows are the ones insrc/protocol/state-engine.ts.

One minute

Enough to explain Tandem to somebody else.

What is it?

A Bitcoin object that belongs to two people at once. It lives in a single output that only their two keys together can move, and every move it makes is written into a history that nobody can edit afterwards.

Why does it need two people?

The object sits in a 2 of 2 output worth exactly 20,000 satoshis. Both signatures are required to move it. That is not a policy anyone enforces on top of Bitcoin. It is the spending condition itself.

What is a Tandem object?

Whatever the two of you decide it stands for. The protocol gives it an identity derived from the transaction that founded it, a status, a sequence number, a key pair, and a chapter count. It does not tell you what it means.

What is a chapter?

One entry in the object's history. A chapter commits to content by its hash, so the record survives even if the content it points at does not. Only a chapter increases the chapter count.

Who controls it?

The two current keys, together, and nobody else. No administrator, coordinator, indexer, or issuer can change its keys, its sequence, its status, or its history. There is no role in the protocol that could.

What happens when keys change?

A rotation replaces both keys in one transaction and leaves the history alone. The sequence advances by one, the chapter count does not move, and everything written before the rotation stays exactly as it was.

How does recovery work?

The two of you sign a refund in advance. It spends the same 2 of 2 output, so both signatures are on it, but its input sequence is 52,560 blocks, which means Bitcoin itself refuses to confirm it until the carrier is that old. After roughly a year of silence, either of you can broadcast it without the other doing anything, and it splits the value evenly. Every move restarts the clock, so an active object never becomes recoverable by accident.

Why are there two indexer pipelines?

Because one indexer reporting on itself is an opinion. Two independently built indexers, run by different people, that arrive at the same state and sign it separately, is evidence.

What if they disagree?

The verified surface closes. It answers 503 and tells you nothing about the state rather than telling you something it cannot stand behind. Disagreement is treated as a fault, never as a tiebreak.

What can people build with it?

Anything that needs a permanent two party record with no host: shared archives, partnership registries, collaboration provenance, long running agreements. The protocol is deliberately silent about meaning.

Longer answers live in the questions page and inprotocol concepts.

Why this could only work here

Five properties, none of which a platform can offer you.

  1. 01

    The object is the output

    There is no database row that represents your object and no server that remembers it. The object is a 20,000 satoshi output on Bitcoin. If the indexer disappears, the object does not.

  2. 02

    History cannot be quietly rewritten

    Each state carries a sequence number that has to be exactly one more than the last. A chapter is unique by object and sequence. There is no operation in the protocol that removes one.

  3. 03

    A silent takeover is impossible

    Any confirmed transaction that spends an active carrier without being a valid Tandem operation terminates the object in the open, with a reason code attached. The protocol gives nobody a way to make that quiet.

  4. 04

    Recovery is designed in, not bolted on

    The two of you sign a refund at the start, and Bitcoin will not confirm it until the carrier is 52,560 blocks old. After that either of you can broadcast it without asking the other, and it always splits the value evenly. No service is involved and nobody can withhold it.

  5. 05

    State is published only under agreement

    Two implementations compute the state separately, sign a tuple each, and a gateway compares nine fields at the same height. Data is served when they match and withheld when they do not.

Why Tandem exists works through the alternatives and where each one breaks.

Independent verification

Two indexers. Nine fields.
No answer unless they match.

Bitcoin Core feeds two implementations that share no code and no operator. Each computes Tandem state on its own and signs a tuple. The gateway compares them at one canonical height and serves data only if every compared field is identical. Try breaking it.

Verified gateway

verified

Pipeline A and pipeline B independently reached the same canonical height and signed identical protocol state. The gateway compares the two tuples, finds no difference, and serves the data.

Pipeline Athis repository

Pipeline Bseparate team, separate code

What the caller receives

What the operator sees in the log

The caller is never told which check failed. Every failure returns the same body, so a probing client cannot map the gateway's internals.

Modelled from src/verification/verified-gateway.service.ts. The nine compared fields, the status codes, and the response bodies are the ones in that file.

The full contract is in the verified surface, and the reasoning behind it is inwhy two indexers.

Where it fits Not built yet

Things two people could keep this way.

None of these exist yet. The protocol supports the shape of all of them, and nobody has built them, which is the interesting part.

Two artists, one body of work

A collaboration that records each release as a chapter, so the provenance of the partnership outlives any platform that hosted the files.

Co-founders before the paperwork

A founding moment fixed in a block, with milestones added as they happen, and a clean cooperative close if the two of you go separate ways.

A record two families keep

A shared object passed between two households, rotated when the people responsible for it change, with recovery already arranged.

A long agreement with a spine

Two parties commit to terms by hash and add an entry each time the terms move, leaving a sequence anyone can audit without asking either of them.

More of them, with the mechanics spelled out, inuse cases andideas to build.

The route through

Nine stages, in order.

Each one teaches one idea and ends with something you can do. Your place is remembered in this browser and never sent anywhere.

01Discover TandemThe primitive in plain language, and the four promises it makes.02See what makes it differentWhat a shared object can do that a shared wallet and a shared account cannot.03Follow one object end to endFounding, chapters, a key rotation, and two different endings.04Understand two party controlThe 2 of 2 carrier, the sorted key pair, and why a spend is never silent.05Explore independent verificationWhy one indexer is an opinion and two indexers are evidence.06Try the protocol conceptsDrive an object through every transition and watch the state respond.07Integrate the APIRead the verified surface and handle the case where it closes.08Run the indexerBring up pipeline A, prove readiness, and keep mainnet gated.09Join the ecosystemOpen questions, unbuilt ideas, and how to contribute.

Where things actually stand

Readiness, without the varnish.

The protocol specification

In the code

Frozen bytes. The spec hash commits to the exact file and every deployment binds to it.

Protocol boundaries in pipeline A

In the code

Marker detection, the state engine, reorg rollback, agreement signing, the verified gateway, and both API surfaces are written, typed, and covered by 32 tests.

A block ingestion loop

Not built yet

Nothing in the repository schedules work or writes a canonical row yet. It is the largest open piece, and pretending otherwise would be the easiest lie on this page.

A live Bitcoin Core connection

You supply this

The RPC client and the chain identity check exist. A node, its credentials, and its data are yours to supply.

Pipeline B

Separate system

Deliberately not in this repository. A second implementation, second team, second key, reached over HTTP.

Signed agreement tuples

You supply this

The signing code is here and tested. The Ed25519 key and the release identity values come from your deployment.

Verified mainnet responses

Off by default

Refused unless an operator sets the mainnet flag deliberately. Readiness fails closed until every dependency is proven.

Every page on this site carries one of these labels next to its title, so you always know whether you are reading about code that runs, a model that teaches, or an intention.

You are early. That is the opportunity.

The specification is frozen, the reference parser is published, the indexer is here, and nothing has been built on top of it yet. Everything below is unclaimed ground.