Guide · for people building on it
Integration guide
Drops is small enough that a full implementation is a few hundred lines. The work that matters is not the parser, it is the discipline: verify before you record, publish what you are relative to, and never let a display field become an identity.
Support matrix
This table lists only what is wired into the org's own code and recorded in the Bitcoin Universe capability registry. Actions not listed here are not claimed.
| Surface | Actions | Status |
|---|---|---|
| Core | view, discover, view-collection, view-activity, view-transaction, list, update-listing, unlist, buy, make-offer, accept-offer, cancel-offer, settle, reconcile |
feature-gated behind dropsMarketplaceV1, mode external-execution |
| Wallet | view, send, receive |
declared surface |
| Inscribe | inscribe, transfer |
declared surface |
| Any surface | sell |
not supported. Registry reason: DROPS has no executable offer workflow on this marketplace surface. |
Every marketplace action above is implemented and switched off by default. Availability is feature-gated and the execution mode is external-execution, so a deployment that has not enabled dropsMarketplaceV1 offers none of them. Do not design a user flow that assumes a gate is on; check, and degrade honestly when it is not.
Registered marketplace semantics, for the deployments that do enable the gate: settlement is recorded at a minimum of one confirmation and only when the finalized-block scanner has verified the exact intent transaction and the custody transition. There is no enforced freshness limit at the registry level, so operator readiness must impose deployment-specific lag limits. Reorganisation reconciliation is automatic: rollback removes block-bound settlement evidence, marks the intent reorged, and preserves the rebroadcast lineage.
Support outside Bitcoin Universe is not claimed. If another wallet, explorer, marketplace or indexer supports Drops, that is for them to state, and their rules are theirs.
Implementation order
Build in this order and each stage is testable against the test vectors before the next one exists.
- Leaf parser
Ten chunks, five fields, minimal pushes, re-serialization equality. Run every
VTandIVvector through it. Do this before touching a node. - Field validators
Marker allowlist, content-type grammar, hash length and match, body bounds and encodability, x-only point validation. Point validation is the one people skip; do not skip it.
- Taproot commitment
Control block structure, leaf version, internal key validity, tapleaf hash, merkle fold, tweak, parity and key equality. Compare against the
CTvectors. - Witness gate
Exactly three items, signature 64 or 65 bytes, no annex. This is cheap and rejects most non-Drops inputs before any hashing.
- Block scanner
Walk confirmed blocks up to
tip - (N - 1). For each transaction, for each input, apply steps 4, 1, 2 then 3. Record on success. - Identity and storage
Key everything on
drops:<network>:<txid>:d<input>. Store the raw body bytes; derive everything else. - Custody projection
Track output 0 of the reveal, then output 0 of each spend, with the P2WPKH and P2TR value test. Rebuild rather than patch.
- Reorg handling
Keep a block journal. On divergence, roll back to the common ancestor and rebuild projections. Set a budget, and stop with a named reason when you exceed it.
- Serving
If you serve bodies over HTTP, apply the passive-content policy. Treat every body as hostile.
Patterns worth copying
Publish what your answer is relative to
Every response should be accompanied by the network, the confirmation depth and the indexed height. A balance or a record with no context is a claim; with context it is a measurement. The reference health payload carries confirmationsRequired, lagBlocks, tipAgeSeconds and an indexer state for exactly this reason.
Record rejections without letting them affect state
Storing why a candidate failed makes an indexer auditable. It must never change another record. A rejection is a diagnostic, not a ledger event.
Separate provisional from recorded, visibly
If you show unconfirmed activity, label it and keep it in a different field, the way the OP_DROP layer marks finality: provisional with a chainState of mempool, mined, finalized or reorged. Blending the two is how users end up trusting a transaction that never confirmed.
Fail closed
An error during verification is a rejection. An ambiguous reorg ancestor is a stop, not a guess. A missing previous output is an unresolved candidate, not an accepted one.
Mistakes that produce a wrong ledger
| Mistake | What goes wrong |
|---|---|
Matching on the string drops anywhere in a transaction | You will record arbitrary data as artifacts, including data deliberately planted to look like one. |
| Skipping the Taproot commitment check | Anyone can put any leaf in a witness. Without the commitment, a Drop proves nothing at all. |
| Validating the key by length only | 32 bytes that are not a curve point pass a length check and fail rule D-19. See vector IV-8. |
| Accepting non-minimal pushes | Two different byte strings decode to the same fields, so the leaf no longer has one serialization. |
Accepting bip110-op-drop | You have merged two ledgers. A token event becomes an artifact and the balances stop being reproducible. |
Keying on sequence or displayName | They are deployment-local. Two indexers will disagree and your references will break. |
| Using output index rather than input index for identity | A transaction revealing two Drops collapses into one, or into the wrong one. |
| Rendering a body with its declared content type | An SVG or HTML body executes in your origin. Serve unknown and active types as opaque attachments. |
| Patching a projection after a reorg | Projections drift from the immutable records and cannot be reproduced. Rebuild. |
| Assuming a feature gate is on | Marketplace actions are off by default. A flow that assumes otherwise breaks on every deployment that has not opted in. |
Before you call it done
Work through the conformance checklist. It is the same content as this page expressed as things you can tick off, and it includes the tests an implementation should be able to pass on demand.