v0.1GitHub

Open sourceRust and TypeScriptv0.1

One bit per token.
No accounts.
Idle tokens expire.

Worgl is an open-source issuer for the credits, quotas and points that services and agents hand each other. It keeps one bit per token. Tokens change hands with no accounts, under a fresh key every time, and a token that sits still expires.

A simulated mint running in this page, with a rotation every 12 seconds. Brighter notes are worth more. Hover a bit to read its note and click a lit one to spend it. Then stop moving for a few seconds and watch what happens to idle notes.

Every lit square is a live note. The pale line in each layer is its last-used bit.

0Transfers
0Live notes
0Expired
12 sNext rotation
Moving
01Storage

You hold 149 bytes.
The mint keeps one bit

    Note 1291:238066, byte by byte. Hover or tap a field to see what it holds.

    The holder keeps the note: the mint's key, a serial, an amount, the holder's one-time key and the mint's signature. The mint keeps none of it. It keeps one bit per note, 1 while the note is live and 0 once it is spent, so checking a note is a signature check and one bit read.

    512 KiBFour layers of 220 bits, holding over four million notes in flight. README
    0.65 µsTo map a serial to its bit and read it, in a release build. README
    0 notesStored by the mint. It keeps bits, a few counters and recent receipts. README
    02Privacy

    The mint sees every hop.
    It never sees who.

    There are no accounts to look anyone up in. Every note is bound to a fresh one-time key, so the mint can follow how value moves without knowing whose it is.

    Every box is a note under its own one-time key. The mint can draw these lines. It can't say which boxes belong to the same holder.
    1. A fresh key for every note

      Each note is bound to a one-time key of whoever receives it. No key is used twice, so no key names an owner.

    2. One note per transfer

      Spending two notes together would tell the mint they had one owner. The default policy refuses it.

    3. Transfers spread out in time

      The SDKs submit the parts of one payment, and the refreshes before a rotation, at random moments.

    The issuer sees moreThe issuer sees less

    Account ledgers

    Every balance has a name. The issuer knows who holds what.

    Worgl

    Sees each note's lineage, never its holder. While holders keep the three rules, it can't tell that two unrelated notes share an owner.

    Blind signatures

    Chaum, Cashu, GNU Taler. The issuer can't even link a note to the one it replaced.

    Blind signatures don't fit this design: the mint has to choose each note's serial, because the serial names the note's bit. Timing still shows, too. Three notes sent to one payee in the same second invite a guess, which is why the SDKs space them out. README

    03Circulation

    Every rotation drops a layer.

    The bits are split into layers, oldest first. New notes land in the second-to-last layer, and a transfer issues its outputs one layer on. The last layer is frozen until the next rotation, which drops the oldest layer and every note still in it.

    Four layers, oldest at the top. Click a note to transfer it, or use the buttons.

    0Rotations
    0Value expired

    Built for

    One setting, the rotation period, sets both how fast tokens can move and how long they can sit still. Three uses, with a setting each:

    UseRotationLayersIdle tokens die within
    API quotasSell quota as tokens a customer splits across its systems. Quota nobody uses lapses.1 minute60an hour
    Agent creditsAgents and services that pay per call, with no account per agent.1 hour168a week
    Points that circulateRewards worth more moving than hoarded, because idle points expire.1 day30a month
    04Origin

    Wörgl, 1932.

    In the summer of 1932, deep in the Depression, the Austrian town of Wörgl began paying for public works with notes of its own.

    The notes carried a cost borrowed from the economist Silvio Gesell. Each month the holder had to buy a stamp worth 1% of the note and stick it on, or the note stopped being valid. Holding one cost money, so nobody held them for long.

    The notes kept moving. Mayor Michael Unterguggenberger's experiment ran until Austria's central bank ended it in September 1933.

    One stamp a month. An illustration, not a replica of the note.

    Wörgl stamped its notes every month. Worgl drops a layer every rotation.

    Sources: Wörgl on Wikipedia and Wörgl Shillings on the P2P Foundation wiki. They differ on the exact day in September 1933.

    Why Worgl
    05Build

    Built in the open.

    A Rust workspace with a TypeScript SDK, dual-licensed MIT or Apache-2.0. Its libraries, server and command are on crates.io; the example runs from the repository.

    Try it locally
    $ git clone https://github.com/zhangheqi/worgl
    $ cd worgl && cargo run --example lifecycle
    # mint, split, pay, freeze, rotate, expire
    1

    Request

    The payee asks for the amount as notes, each to a fresh key of its own.

    2

    Pay

    The payer signs one transfer per note it spends, each with a time to submit it.

    3

    Settle

    The mint clears each input's bit and issues the new notes. A resent request gets the same answer.

    import { Client, Purse } from 'worgl';
    import { FileStore } from 'worgl/node';
    
    const client = new Client('https://mint.example.com');
    const alice = await Purse.open(client, { store: new FileStore('alice.json') });
    const bob = await Purse.open(client, { store: new FileStore('bob.json') });
    
    const request = await bob.request(mint, 5n);          // Bob sends request.json to Alice
    const payment = await alice.pay(request);             // Alice sends payment.json to Bob
    const received = await bob.receive(request, payment); // checks, submits at its times, keeps
    await alice.accept(received.theirs);                  // Alice keeps the change Bob sends
    17,000/sTransfers through the server on a 4-core cloud VM with 64 clients. One mint sustains at most 8,192/s by default. README
    41,000/sTransfers the library alone commits, in batches of 256. README
    2 of 3Cluster members that hold a transfer on disk before it is answered. README

    Eight crates and a package

    worglLedger, note format, transfer protocol, policy and crash-safe storage.
    worgl-serverAn HTTP server that hosts many mints side by side.
    worgl-raftRaft replication, so three members keep every mint.
    worgl-sdkThe holder's side, with the privacy rules built in.
    worgl-clientTyped calls for every route, and a purse over HTTP.
    worgl-cliA command-line purse in a passphrase-encrypted file.
    worgl-faucetHands out notes of a playground mint, within limits.
    worgl-wasmThe SDK core compiled to WebAssembly.
    sdk/typescriptThe TypeScript SDK for Node and browsers.

    What Worgl is not

    • Not a blockchain. Each mint has one issuer and one ledger, run by whoever runs the mint. Nothing is mined.
    • Not money. Worgl never sells, buys or redeems tokens. What a token is worth is up to whoever mints it.
    • Not untraceable. The issuer sees each token's lineage from hop to hop. It never learns who holds them.
    Worgl Cloud · Not available yet

    Your mints, run for you.

    Worgl Cloud will run your mints for you, replicated across three zones, on the same open server. It is not available yet. Tell us what you'd build.