Skip to content

Protocol · commitment

Make a promise anyone can check, with your bitcoin behind it.

Pledge your word to bitcoin. Bond your stake. Anyone verifies the outcome. OC Pledge writes a public promise so a machine can check it, and puts your own coins behind it without handing them to anyone.

A pledge · test vector v01
oc-pledge/v1
swearer: bc1qalice000000000000000000000000000000000
proposition: I will not spend the bonded UTXO before block 920000.
resolution:
  mechanism: chain_state
  query: address(bc1qalice000000000000000000000000000000000).utxo_count >= 1 AND address(bc1qalice000000000000000000000000000000000).balance >= 500000
resolves_at:
  block: 920000
expires_at: 2026-12-31T00:00:00Z
bond:
  attestation_id: 1111111111111111111111111111111111111111111111111111111111111111
  min_sats: 500000
  min_days: 180
counterparty: null
dispute:
  mechanism: null
  params: null
remediation: breach_recorded
sworn_at: 2026-04-24T18:30:00Z
nonce: 0123456789abcdef0123456789abcdef
  • Open spec, MIT
  • The bond stays in your wallet
  • Never slashed
  • Anyone can check the outcome

The problem

Today someone else keeps the score.

People make public promises all the time. A release date. A service level. A research plan registered before the data comes in.

A registrar holds the record, an escrow agent holds the money, or a court decides. Each one is a party you have to trust. Most promises are also written so that only a person can judge whether they were kept.

OC Pledge does two things instead. It writes the promise so a machine can check it. And it puts something at stake without handing your coins to anyone.

How it works

Write it. Bond it. Anyone checks.

  1. 01

    Write the promise and the rule that checks it

    One line in plain words, plus one rule from a closed list of seven: a Bitcoin block or balance, a Nostr post, an OC Stamp, a file at a URL, a DNS record, an OC Vote result, or the other party’s signature. Set a deadline, as a date or a block height.
  2. 02

    Bond it and sign it

    Point to an OC Attest attestation: sats at your address, left unspent. Name the minimum amount and age. Sign once with your Bitcoin wallet. Nothing is sent and nothing moves. The pledge is published to Nostr relays.
  3. 03

    Anyone checks the outcome

    At the deadline, anyone runs the rule against public data and gets the same answer: kept or broken. The result stays attached to your address. You cannot take a pledge back. If you give up early, you publish an abandonment, and it counts as broken.
What Bitcoin does here
The bond is coins at your address that stay unspent, and anyone can see their amount and age on the chain. Deadlines can be block heights, and the chain_state rule reads Bitcoin directly. An Ed25519 key has no stake to point at and no neutral clock.

Why it exists

Every other way keeps the score for you.

The spec’s own audit of the field, in words.

  • A promise about the future
    OC PledgeYes
    Escrow or multisigYes
    EAS (Ethereum)Yes
    Arbitration courtsYes
    OSF preregistrationYes
  • Bitcoin behind it
    OC PledgeYes, an OC Attest bond
    Escrow or multisigYes
    EAS (Ethereum)No
    Arbitration courtsNo
    OSF preregistrationNo
  • No one holds the coins
    OC PledgeYes
    Escrow or multisigNo: the escrow holds them
    EAS (Ethereum)Partly
    Arbitration courtsNo
    OSF preregistrationYes
  • A machine can check it
    OC PledgeYes, by one of seven rules
    Escrow or multisigYes
    EAS (Ethereum)Yes
    Arbitration courtsPartly
    OSF preregistrationNo: free text
  • No issuer
    OC PledgeYes, BIP-322 only
    Escrow or multisigPartly
    EAS (Ethereum)No: token-gated
    Arbitration courtsNo
    OSF preregistrationNo: a registrar
  • Checks offline
    OC PledgeYes
    Escrow or multisigYes
    EAS (Ethereum)No: needs an RPC node
    Arbitration courtsNo
    OSF preregistrationNo

The full argument is in the spec’s WHY.md.

Where it stands

Open, stable, and free to use.

The spec is v1.0, stable since May 2026, published under MIT. The tools at pledge.ochk.io are free and work today. OC Pledge never holds your coins and never slashes them: the bond stays in your wallet. orangecheck as a whole has not launched publicly yet.

The spec

oc-pledge-protocol

Version
1.0
Licence
MIT
Nostr kind
30078
Test vectors
30

Try it

What you can do today.

  • You need a Bitcoin wallet that can sign a message (or you can sign by hand), and an OC Attest attestation for that address.

    pledge.ochk.io/create
  • It also takes an outcome or an abandonment, and opens share links.

    pledge.ochk.io/verify
  • Every pledge it swore, kept, broken and in flight.

    pledge.ochk.io/address
  • The playground checks resolution rules in your browser. Nothing leaves the page.

    pledge.ochk.io/playground
  • The bond a pledge points to is an OC Attest proof for the same address.

    attest.ochk.io/create

One pledge lives at pledge.ochk.io/p/<id>. It finds the pledge and its outcome on Nostr.

For developers

Build on it.

@orangecheck/pledge-core (MIT) builds and verifies pledge, outcome and abandonment envelopes, runs the state machine, and validates the seven rules. It does no networking and no signing of its own: you pass in a BIP-322 verifier and, for bond checks, a chain lookup.

npm install @orangecheck/pledge-core @orangecheck/bip322

Core

@orangecheck/pledge-core

envelopes, the state machine and the seven rules; MIT

Python

orangecheck.pledge

the same logic, in the orangecheck package on PyPI

TypeScript · verify a pledge and read its state
import { verifySignature } from '@orangecheck/bip322';
import { verifyPledge, classifyState } from '@orangecheck/pledge-core';

const pledge = JSON.parse(pledgeJson); // a .pledge envelope
const r = await verifyPledge({
  envelope: pledge,
  verifyBip322: async (msg, sig, addr) => verifySignature(addr, msg, sig),
});
if (!r.ok) throw new Error(`${r.code}: ${r.message}`);
const now = new Date().toISOString().replace(/\.\d+Z$/, 'Z');
const state = classifyState({ pledge, outcome: null, abandonment: null, now });
The bond check is verifyBond, with a lookup you supply. The reference site wires it to @orangecheck/sdk.

Check one

Verify a pledge someone sent you.

Paste the pledge, its id or its share link. An id opens the pledge’s own page; a pledge, an outcome or an abandonment opens in pledge.ochk.io’s verifier.

The verifier checks, in order:

  1. Shape and version. Every required field is present and well formed.
  2. The id. It rebuilds the signed text from the fields and confirms its SHA-256 is the pledge’s id. Change one character and the id changes.
  3. The signature. A BIP-322 signature from the swearer’s address. If an agent signed, it also checks the OC Agent delegation that allowed it.
  4. The bond, now. It finds the OC Attest attestation, confirms it belongs to the same address, and confirms the coins are still unspent and meet the minimum amount and age.
  5. The state. Pending, resolvable, kept, broken, disputed, or expired unresolved.

An envelope travels in the link’s fragment, which browsers never send to a server.

All of it runs in your browser, with no orangecheck server involved. The id and signature checks need only the pledge itself. The bond check reads public Nostr relays and a Bitcoin chain API.

One step is not built into the site yet: re-running the rule against public data. An unsigned outcome found on a relay is shown as a claim and does not change the state until it is recomputed. Outcomes signed by a counterparty, and abandonments, do count.

What you trust

Every party you rely on, by name.

Bitcoin, for the bond
The site reads chain data from mempool.space by default. Developers can point the lookup at their own Esplora-compatible endpoint.
The rule you chose
Each rule names its own anchor. chain_state trusts only Bitcoin. counterparty_signs trusts the named counterparty; if they never sign, the pledge expires unresolved. A dispute goes to the poll or oracle address named when the pledge was sworn, or nowhere. vote_resolves trusts the voters of the named OC Vote poll. http_get_hash trusts the server and its certificate authority. dns_record trusts the DNS-over-HTTPS resolvers (at least two of Cloudflare, Google and Quad9). nostr_event_exists and stamp_published trust Nostr relays: at least two are queried, and one honest relay is enough.
Relays, for finding pledges
pledge.ochk.io publishes to nos.lol, relay.primal.net, offchain.pub, relay.snort.social and relay.ochk.io. A pledge is a file, so it can also travel any other way.
The swearer’s clock
The “sworn at” time is set by the person signing. Use a block height when time matters.

What it is not

The limits, plainly.

Not escrow and not a contract
Nothing can seize the bond. The only consequence of breaking a pledge is that the record says so, publicly and for good.
Spending the bond is visible, not punished
Verifiers then see the bond as spent. The pledge’s state still comes only from its outcome.
Not private
Your address, your promises and their outcomes are public. Use a fresh address if that matters, at the cost of your history.
Not a score
The protocol publishes the raw record of kept and broken pledges. Each app decides what that record means.

Where it is used

Apps that use it.

No showcase app yet
None of the showcase apps uses OC Pledge yet. The tools at pledge.ochk.io are the reference implementation.
OC Attest
Every pledge’s bond is an OC Attest proof, re-checked against the chain whenever the pledge is verified.

Make your first pledge.

The tools are free and need no account. The spec is open to anyone who wants to build their own.

With thanks to Bram Kanstein, whose work on Bitcoin as a sovereignty layer shaped the premise.