Warning
Experimental software. borg is part of bstack, the applications and patterns built on BSV Layered Multicast. It is published to be built on and improved. Interfaces, formats and behavior may change rapidly between releases; pin an exact version.
Organizations and groups on Bitcoin, replicated by overlay hosts. An organization issues each member a certificate; a group's membership is a chain of mined tokens; and every removal from a group begins a new epoch whose key the removed member never receives.
flowchart LR
O["borg (organization)"] -->|"grants, policy records, tokens, wraps"| H["overlay hosts<br/>tm_borg_<name>_<suffix>, ls_borg"]
O -->|"one small tx per change"| B[("BSV blockchain")]
M["borg (member)"] -->|"open, roll, member, policy"| H
M -->|headers| S["header source<br/>woc:main"]
B -.-> S
H -. "records + proofs" .-> M
%% The last node is an invisible spacer in the rightmost rank: the rendered
%% viewer places its zoom and pan controls over the bottom-right corner.
B ~~~ pad
pad[" <br/> <br/> <br/> <br/> "]:::pad
classDef pad fill:none,stroke:none,color:transparent
- Membership is a certificate. Each member holds a BRC-52 certificate issued by the organization's key, with a role, a scope and an expiry. Its revocation outpoint is the output that funds it, so one mined spend revokes it for every verifier and retracts it from every host.
- Roles decide. A role names the permissions it carries, and a binding gives it to a group or to one key. Both ride the organization's own chain beside the roll, so a service reads what a subject may do out of the same committed order that says who the subject is, and can prove what it decided and the state it decided against.
- Changes are ordered by the chain. The roll and each group are chains of mined tokens, one per change. Two changes made at once spend the same output and only one is ever mined: no coordinator, no merge.
- Removal is a rekey, checked by every host. A transition that removes anyone must begin a new epoch with a new key commitment, or no host admits it. The new key is random, committed before anyone holds it (BRC-369), and wrapped only to the members who remain.
- Hosts are replicas, not authorities. A host can withhold; it cannot
forge. Roots over the roll and over each group's members make withholding
visible, and
borg fillrepairs a host that missed something.
$ go install github.com/lightwebinc/borg/cmd/borg@latestOr download a static binary for Linux or macOS (amd64, arm64) from Releases, or run the image:
$ docker run --rm -v borg-home:/home/nonroot/.borg ghcr.io/lightwebinc/borg -versionYou need BSV in a wallet you control and overlay hosts that carry the borg module (host.md). No node is needed: headers, transactions, proofs and spends come from WhatsOnChain and broadcasts go through GorillaPool's public arcade by default, every proof checked against the headers; a node of your own is the better option where you have one. Nothing is mined for you: the organization is funded with a payment you send.
$ borg -network main init
identity 02c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5
fund address 1BvBMSEYstWetqTFn5Au4m4GFg7xJaNVN2 (main)
$ # send about 20,000 sat from your own wallet to the fund address
$ borg fund -txid <txid of that payment> # once mined; or fund -beef FILE at once
$ borg hall new example
$ borg org create 'Example' -member <alice key> -member <bob key>
$ borg group create engineering -member <alice key> -member <bob key>A member, with org, hall and hosts in their config, opens the group's key with borg open engineering. The full walk,
on mainnet or testnet, is docs/examples.md; a private
sandbox that needs no coin is QUICKSTART.md.
| If you want to | Read |
|---|---|
| Run it on mainnet or testnet, step by step | docs/examples.md |
| Try it on one machine with no coin (a private regtest chain) | QUICKSTART.md |
| Run an organization, or use one as a member | docs/user-guide.md |
| Set every key, flag and environment variable | docs/configuration.md |
| Look up a command or an exit code | docs/usage.md |
| See how the pieces fit | docs/architecture.md |
| Run a host: the module, its configuration, its index and its terms route | docs/host.md |
| Know the defaults and caps, and what things cost | docs/limits.md |
| Implement a compatible organization, member client or host | docs/spec.md |
| Know what cannot change once published | docs/frozen.md |
| Read borg's chains from another Go program | docs/packages.md |
| See what comes next, and what is left open on purpose | docs/roadmap.md |
$ (cd host && npm ci) # once
$ make verify # gofmt, vet, dependency set, licenses, typecheck, vectors, tests
$ make borg # the command, bin/borg
$ make module # the host module, host/bundle/borg-module.js
$ make docker-build # the images, locallyGo 1.27.2 or later and Node 24 (NODE=/path/to/node selects one not on
PATH). The golden vectors in testdata/vectors are generated by the Go
codec (borgrec) and testdata/ts by the TypeScript codec in host/;
each side's tests read the other's, byte for byte. The end-to-end targets
(make e2e, make e2e-client, make quickstart-check) need Docker and a
reference overlay host; see the Makefile.
The TypeScript codec ships as a package of its own for other applications'
pages and helpers (bchat's verifies groups and opens epochs with it): npm pack in host/, from a clean clone at a tag, writes
lightwebinc-borg-host-<version>.tgz (the version equals the tag), holding
only the codec files (admit, beef, borgrec, chain, epoch,
merkle, query, scope, script, util), imported as
@lightwebinc/borg-host/codec/<file>.js. bcommon's TypeScript package is
its peer. A consumer vendors the tarball and pins it by its hash in its
lockfile, as with bcommon's.
Apache 2.0; see LICENSE, NOTICE and LICENSE-THIRD-PARTY.