# Integrate a producer This page is for developers who want their own app to make PCOCs. A producer is the part of an app that makes a PCOC on the user's device, from the user's own key. Start with the SDK in your language: the Rust, Go and Java SDKs all produce and verify, and each has a runnable produce example. The desktop app is a complete example of that path. The Primal Android demonstrator builds on the Rust SDK tag sdk-rust-v2.3.1. The specification and the details below are there for when you need more. ## Examples - **Desktop app:** [apps/desktop](https://github.com/groundinglab/pcoc/tree/main/apps/desktop), on [sdk/rust/pcoc](https://github.com/groundinglab/pcoc/tree/sdk-rust-v2.3.1/sdk/rust/pcoc), shipped as a Flatpak. - **Primal Android demonstrator:** [groundinglab/primal-pcoc](https://github.com/groundinglab/primal-pcoc), which produces through [pcoc-bridge/bridge/src/produce.rs](https://github.com/groundinglab/primal-pcoc/blob/main/pcoc-bridge/bridge/src/produce.rs) over JNI. It builds on the Rust SDK tag sdk-rust-v2.3.1. - **SDK produce commands:** [sdk/rust/pcoc-cli/src/main.rs](https://github.com/groundinglab/pcoc/blob/sdk-rust-v2.3.1/sdk/rust/pcoc-cli/src/main.rs), [sdk/go/cmd/pcoc/main.go](https://github.com/groundinglab/pcoc/blob/sdk/go/v2.3.1/sdk/go/cmd/pcoc/main.go), [sdk/java/src/main/java/io/groundinglab/pcoc/cli/Main.java](https://github.com/groundinglab/pcoc/blob/sdk-java-v2.3.1/sdk/java/src/main/java/io/groundinglab/pcoc/cli/Main.java). Assumes: the [specification pack](spec.md). The produce program's flags are in each SDK's `--help` ([SDKs](sdk.md)). Minimal checklist (inputs → the PCOC): 1. A public key (x-only) for the object. 2. A Bari URL and a gossip peer (or live DNS-seed fallback). 3. Run produce until the final block arrives; write the CBOR object. 4. Verify the PCOC against an index; keep the §14 record for your policy. 1. Output. A producer is the program that makes a PCOC. Its output is a PCOC of kind `v2.2-pcoc-object`: 18 stages, deterministic CBOR (SPEC §7.3, §8 Rule A3). STEPS_PER_LEG 2000000, SAMPLE_BYTES 1024, checkpoint preimage 1096 bytes (SPEC §6). A verifier records any other kind as an unknown kind (Rule A5). 2. Inputs. (a) A tip sequence of Bitcoin headers. It is the public sequencer that paces the stages ([sdk/README.md](https://github.com/groundinglab/pcoc/blob/main/sdk/README.md); SPEC §9). (b) A Bari, a service that timestamps the producer's waypoints (32-byte values recorded at each stage) against Bitcoin. It must accept paid waypoints and serve Merkle paths (SPEC §13.6). A paid waypoint is `POST /waypoint` with a Hashcash stamp of 21 leading zero bits: the nonce in `X-Bari-Hashcash-Nonce` and the 80-byte fee header in `X-Bari-Hashcash-Header`, solved on Bari's current block, the one before it or the one after it (Rule BR1). Paths are `GET /path/{leaf}` (Rule BR4; [services/README.md](https://github.com/groundinglab/pcoc/blob/main/services/README.md)). (c) The producer's x-only public key (`--pubkey-hex`). Keys. nip06 holds demo keys only and isn't the seed ([sdk/rust/README.md](https://github.com/groundinglab/pcoc/blob/main/sdk/rust/README.md)). The 64 bytes `public_key ‖ seed_beacon` are the seed preimage. The seed is SHA-256 of those bytes, 32 bytes with no label, read as four little-endian lanes (SPEC §10, P10.1; §4 glossary "Seed preimage"). 3. Endpoints, all opt-in. The hosted Bari is https://bari.groundinglab.io. To run your own: `bari` with BARI_TIP_SOURCE=bitcoin-gossip, your own peer (PCOC_LIVE_GOSSIP_PEER) and Bitcoin Core RPC plus a wallet for the plant, or `synth` for the test plane ([services/bari/README.md](https://github.com/groundinglab/pcoc/blob/main/services/bari/README.md), [deploy/env.example](https://github.com/groundinglab/pcoc/blob/main/services/bari/deploy/env.example)). If you run your own Bari, the plant-fee settings are operator settings in [env.example](https://github.com/groundinglab/pcoc/blob/main/services/bari/deploy/env.example), not rules of the specification. A plant (the Bitcoin transaction output that timestamps a batch of waypoints) is a 39-byte tag: `OP_RETURN` ‖ push-37 ‖ `BARI` ‖ 0x02 ‖ 32-byte root ([services/index/README.md](https://github.com/groundinglab/pcoc/blob/main/services/index/README.md)). An app that uses a Bari does not fund the plant transactions itself. For the initial release, plants are identified by that tag alone; operator-key attribution is planned and optional ([spec/03-Waypoint_Publication_Process.md](https://github.com/groundinglab/pcoc/blob/main/spec/03-Waypoint_Publication_Process.md)). 4. The procedure at a high level. The seed beacon is the latest header already known at start, with no wait (SPEC §9). Each stage runs its legs back to back (every step reads a full 16 KiB slot of a 256 MiB terrain), then its checkpoint (§11), then a waypoint (§12.2). Nothing pauses a leg (Rule A6): the waypoint post, the Hashcash solve, path asks, peer and header reads and log writes all run alongside the legs. There is no wait inside the making. A post that gets no HTTP status line, or a 502, 503 or 504, is a transitory send failure: the producer resends the identical post once, in the background, 30 seconds later, then drops that waypoint if the resend fails too (P13.13). No other answer is retried. After each header in the anchor window, offsets 2, 3, 4 (§13.1), the producer asks for the paths of W_1…W_16; W_17 is posted but never asked. Production closes as soon as the final block is observed (§13.2). Paths not yet fetched at the close are recorded as skips, so the last stages are unanchored by design (§13.3). Reorgs and clock reads that fail never stop a run; they are logged. Event order at stage boundaries follows Rule A1 (§13). 5. Integration routes. Shell out to the SDK `pcoc` command (its `--help`; [sdk/README.md](https://github.com/groundinglab/pcoc/blob/main/sdk/README.md)), or call the SDK's produce function from your own code, as the [Rust command](https://github.com/groundinglab/pcoc/tree/sdk-rust-v2.3.1/sdk/rust/pcoc-cli) does. The Android demonstrator links the Rust SDK over JNI. The current build guide is the [primal-pcoc README](https://github.com/groundinglab/primal-pcoc/blob/5a1d4f5f3c06cd92cfc1ae758418a47122853d3a/README.md). [apps/android/README.md](https://github.com/groundinglab/pcoc/blob/main/apps/android/README.md) records the earlier vendored build. 6. Restart and log. Bari restart is §13.4 (Informative): replacing a live Bari during produce is normal, a pooled waypoint survives a quick restart, and the worst case is a skip, not a replaced plant. The live event log is §13.5 (Normative): live profile only, an append-only file at the object path plus `.events`, one compact JSON line per record (block, waypoint, posted, checked, fetch, alert). Each post attempt, including the one resend, is its own posted record. Every append is asynchronous. The log is not part of the object or an input to any leg, and a failed write leaves the PCOC unchanged. 7. Conformance. Byte-equality targets are in the single conformance pack, [spec/conformance/pack](https://github.com/groundinglab/pcoc/tree/spec-2.3.0/spec/conformance/pack). The pack status is complete. Its manifest SHA-256 is `91ded57e5c05b7cb4cd74d313a51d83d2373fa86dc625df41faed9586e9032af`. The [README](https://github.com/groundinglab/pcoc/blob/spec-2.3.0/spec/conformance/pack/README.md) names the vectors. A §13.2 producer replay must equal the pack's object bytes. Produce does no signature check (SPEC §2). Signing happens at sign-in ([Sign-in wire](sign-in-wire.md)). Next: check what you made ([Verifier and policy](verifier-and-policy.md)).