npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@bsvkey/dtn-custody

v0.5.0

Published

Verifiable data custody and relay payment for delay/disruption-tolerant networks (BPv7), settled on BSV.

Readme

dtn-custody-demo

License: Apache 2.0

Demo: the test suite, the full pipeline, a real netem blackout, real BPv7 custody across a contact gap, and delivery bound to a real on-chain settlement

The demo above is a real run (npm test, npm run demo, make spike, make r2, make live), recorded by demo/record.mjs and rendered by demo/render.mjs. The closing card reads the anchor transaction live from the chain and recomputes the payload's root.

Walkthrough: custody receipts for space networks, paid and anchored on Bitcoin BSV

At scale, on mainnet: watch the narrated walkthrough (under six minutes, demo/walkthrough.mp4). 4,032 satellites on real Starlink orbits, 30,502 paid custody receipts on Bitcoin BSV mainnet, 0 rejected, all mined, and 100 of 100 sampled bundles proven from the chain alone. Every txid is in constellation/RUNS.md.

A reference implementation of a verifiable data-custody and relay-payment layer for delay/disruption-tolerant networking (DTN), with settlement on BSV. A chunked payload crosses a multi-hop, occultation-interrupted link where every chunk is verified against a Merkle root, each relay hop leaves a signed custody receipt, the blackout produces a documented gap object, and delivery is bound to a real on-chain BSV settlement, with the manifest root anchored on chain for provenance.

It rides standard BPv7 (RFC 9171) for transport (µD3TN) and adds the custody, verification, and payment work as an optional agent beside the bundle protocol agent, using the same content-addressed receipt route as @bsvkey/x402-bsv-client and the ASM capacity-attest work. Out of scope, by design: the physical RF layer (modulation, coding, pointing, FEC).

This is published as an open reference implementation for the BSV ecosystem: the protocol, agent library, DTN adapters, and on-chain verifiers are here under Apache-2.0 so anyone can build verifiable data-custody and relay settlement on BSV. See Open core vs. hosted service.

New here? Start with docs/QUICKSTART.md: install, the four calls, and a runnable example (npm run quickstart) in five minutes.

Full design, milestones, and acceptance criteria: docs/BUILD-PLAN.md.

One-line scope

chunk → Merkle → BPv7 bundles → multi-hop store-and-forward with a scripted occultation → out-of-order Merkle verification → per-hop custody receipts → gap object across the blackout → delivery bound to a real BSV settlement → provenance anchor.

Layout

index.mjs            public entry point: the whole agent API in one import
examples/            quickstart.mjs, the smallest end-to-end integration
agent/               the application agent
  lib/               canonical hashing, Merkle tree, keys, receipts, gap object
  source.mjs         chunk + Merkle + signed manifest
  relay.mjs          per-hop custody receipts
  dest.mjs           out-of-order verify, reassemble, chain check, settlement binding
transport/
  sim.mjs            in-process DTN simulator (delay, reorder, occultation)
  bpv7-adapter.md    the real BPv7/uD3TN + netem seam (same shape as sim.mjs)
  bpv7/              Custody Receipt Block: the custody chain inside the BPv7 bundle (block 224)
relief/              disaster relief: clinic reports by courier and satellite, with proof
  kit/               field pilot kit: provisioning, node daemon, hub dashboard, payouts, Docker
  realnet/           the scenario over real network namespaces with a real blackout
  scale/             480 clinics, 48 couriers, 16 relays, six attacks
radio/               pay over LoRa radio: offline-signed payment, gateway receipt back
ground/              ground-side pilot kit: station-signed ledgers from received data, no flight change
flight/              onboard signing in C (byte-identical to the test vectors)
constellation/       thousands of satellites: batch receipts, changing routes, attacks
mars/                JPL ION over LTP at Mars light time
voyager/             Voyager 1 and 2 at a light-day: signed DSN schedule, 160/16 bps, bit errors
ion/, mix/, hardy/  JPL ION, mixed uD3TN/HDTN and Aalyria Hardy interop runs
bench/               performance and overhead measurements
test/                the acceptance-criteria suite (node --test)
contact-plans/       per-tier link schedules with occultation windows
docs/                BUILD-PLAN.md (the full plan)
docker-compose.yml   the 4-node BPv7 + netem testbed (stub)
Makefile             one-command entry points
run-demo.mjs         the end-to-end demo (npm run demo)

Status

The custody agent is implemented and green, and it has been proven over real infrastructure:

  • npm test passes the acceptance criteria; npm run demo runs the full pipeline offline (zero dependencies).

  • M0 (make spike / make spike-local) carries the payload over a real transport through an occultation: spike-local over real sockets, make spike over real veths with tc netem and a real 100%-loss L2 blackout. make spike-moon repeats it at real Earth-Moon light time (1.3 s one way on the Earth link) with a 20 s blackout. See m0/RESULTS.md.

  • R2 (make r2) carries the same custody chain over real µD3TN BPv7, with the bundles held in µD3TN storage across a scheduled contact gap (real bundle custody, not TCP retransmit). See r2/RESULTS.md.

  • Live settlement (make live) binds the delivery receipt to a real, on-chain- verified BSV settlement (WhatsOnChain): the receipt names the txid the verifier paid, and that txid is confirmed on chain to pay the seller. Verified against a real mainnet settlement (5942 sats, 2351+ conf). See live/.

  • Provenance anchor is on chain: the manifest root of live/anchored-payload.txt is committed in an OP_RETURN (tx 733dcc21…b51207), and make live verifies it by default. buildAnchorTx builds (never broadcasts) the anchor for a new root; broadcasting is the operator's step. See live/RESULTS.md.

  • Disaster relief (relief/): with the cell network down, two field clinics send encrypted reports by motorbike courier and a solar-powered satellite terminal to a district hub. Every chunk and handoff verifies, the 70-minute power cut is a gap record, relay operators are paid only for custody they can prove, and an impostor relay is refused. node relief/run.mjs, see relief/README.md. It is also a deployable field pilot kit (relief/kit/): key provisioning, a node daemon for clinic tablets, courier phones and satellite relays over real µD3TN, a hub dashboard and BSV relay payouts, in one docker compose up. Over five Linux network namespaces with real loss, rate limits, delay and a real 100%-loss satellite blackout, every file arrived verified and byte-identical in all five runs (relief/realnet/). At regional scale, 480 clinics, 48 couriers and 16 relays over three days, every delivered bundle verified, payouts follow proven handoffs only, and six attacks are each contained to exactly the bundles they touch (relief/scale/).

  • Pay over radio (radio/): a BSV payment signed with no internet crosses a LoRa (Meshtastic) link in frames of 200 bytes or less, missing frames are asked for again, and the gateway checks it offline, broadcasts only when told to, and radios back a signed receipt. A payment is 2 frames, about 3 s on air on LongFast. node radio/run-demo.mjs over a simulated lossy link; radio/cli.mjs for real radios; passed through real Meshtastic firmware in Docker (radio/meshtasticd/run-sim.sh), not yet on two physical radios. With no radio at all, a phone page hands the payment over by QR code or sound (radio/handoff/index.html), and an SMS gateway takes it by text and replies with the signed receipt (radio/sms/). The phone page has carried a real payment by sound: 1,000 sat signed in one wallet's page, played to a second wallet's page, then broadcast and mined in block 971842 on Bitcoin BSV mainnet (radio/RESULTS.md). A bearer faucet has also run on mainnet: coins announced as sound, heard by an iPhone, and claimed and broadcast from the phone. See radio/README.md.

  • Ground-side pilot kit (ground/) signs what a ground station received, reports every scheduled pass (a silent pass becomes a gap record), seals the ledger under one root, and corroborates two stations. Runs on existing received files; no flight change. node ground/demo.mjs.

  • Constellation scale (constellation/): 4,032 satellites with routes that change while bundles are in flight, one batch receipt per satellite per contact, and verification that accepts any authorized, linked path. 10,000 to 200,000 bundles all verify; under harsh outages (most cross-links failing, ground stations offline) 9,040 bundles wait in storage and still verify; five attacks are each caught for exactly the bundles they touch. node constellation/run.mjs, see constellation/RESULTS.md. The same runs over real orbits: public Starlink elements propagated with SGP4, links and ground visibility from geometry each minute. At 4,032 and at 9,732 satellites (the whole active fleet in the snapshot) every bundle verifies, with thousands rerouted mid-transfer. node constellation/orbits-run.mjs, see constellation/ORBITS-RESULTS.md. On a real BSV node: every batch receipt from the 4,032-satellite real-orbit run went through Teranode (private regtest chain) as a transaction that pays the relaying satellite and commits that receipt: 30,502 transactions, all confirmed, and 100 of 100 sampled bundles proven custodied and paid at every hop from the chain alone. See constellation/TERANODE-RESULTS.md. On teratestnet, BSV's public Teranode test network, through Arcade: the same 30,502 paid receipts all mined, every merkle proof matching its block header, and 100 of 100 bundles proven (constellation/TTN-RESULTS.md). On Bitcoin BSV mainnet, through ARC: all 30,502 paid receipts and 11 anchors mined, every proof matching a header whose proof of work was verified, 100 of 100 bundles proven (constellation/MAIN-RESULTS.md). Every run, with its transaction records, is listed in constellation/RUNS.md. With --batch=100 one transaction pays 100 satellites (output i for receipt i, the receipt ids listed in one OP_RETURN): 306 transactions instead of 30,502, submitted at about 750 payments per second instead of 80, with each payment to a fresh payout address. --confirm rebuilds every block header it relies on and checks its proof of work before trusting its merkle root, and constellation/sweep.mjs collects the satellites' payments back.

  • Mars light time (mars/): JPL ION over its LTP convergence layer at 4, 12.5 and 22 minutes each way (close approach, average and near-maximum Mars distance), every file arriving exactly one light time later; and a rover to relay-orbiter to Earth chain with 5% packet loss each way on a 4-minute link, repaired by LTP. make mars, see mars/RESULTS.md.

  • Offline key management (spec/KEY-RECORDS.md): the key-management gap BPSec leaves out of scope, closed for custody receipts. Signed key and revocation records chain to operator root keys and travel inside bundles (block 225); a verifier needs only the root keys and its own clock. Rotation, self-revocation, issuer compromise, and witnessed time, so a stolen key cannot backdate a receipt past an honest custodian. Live through uD3TN, HDTN, ION and Hardy (make bpv7-keyring-all), and onboard in C (flight/keyring.c, about 3 KB on a Cortex-M4).

  • Voyager 1 and 2 (voyager/): custody both ways at 23.8 and 20-hour light times, 160 bps down and 16 bps up (simulated, virtual time). Link windows come only from a DSN schedule signed as a dtn.contact-plan/1 record; the spacecraft transmits a light time before each track; bundles that miss a window are held and recorded in gap records checked against the signed plan. Voyager 2 can be commanded only from DSS-43, which shows: 112 h from command ready to its signed receipt at JPL, against 88 h for Voyager 1. A bit error sweep with NACK-driven resends shows each lost bundle costs about two days. make voyager, node voyager/sweep.mjs, see voyager/RESULTS.md. Real JPL ION over LTP also passes at Voyager's data rates, 160 bps down and 16 bps up, with a 240 s light time (netem-capped): make ion-voyager, see voyager/ION-RESULTS.md.

  • Onboard signing in C (flight/): the same records produced in portable C99 with TweetNaCl Ed25519, byte-identical to the published test vectors (signatures included), about 12 KB of code on an ARM Cortex-M4. make flight. The same signer also ships as a NASA cFS application that self-tests at boot and signs receipts on command over the software bus (make cfs, see flight/cfs/).

  • Performance (bench/): about 30,000 custody receipts signed per second on one desktop core; custody adds about 2% at 64 KiB chunks. See bench/RESULTS.md.

Mission-latency contact plans (Moon, Sun-Earth L1, Mars, Uranus) ship in contact-plans/ and compile to the formats NASA's DTN software loads (verified end to end with NASA HDTN: our custody payload was stored by the HDTN router across a scheduled gap and verified at the receiver, see hdtn/RESULTS.md): HDTN (NASA Glenn) JSON and JPL ION contact and range commands (node contact-plans/compile.mjs <plan>), also verified end to end with JPL ION: ION's contact graph routing held our payload across a scheduled 20 s gap and every chunk and custody handoff verified on arrival (make ion, see ion/RESULTS.md). A mixed chain also passes: uD3TN hands the payload to NASA HDTN over TCPCLv3, HDTN stores it across a scheduled gap, and delivers it to a second uD3TN node, where every chunk and handoff verifies (make mix, see mix/RESULTS.md). It also runs on Aalyria's Hardy: our agent attaches through Hardy's gRPC application and convergence-layer APIs, Hardy's time-variant routing agent (fed a contact plan from our compiler, --hardy) holds the payload across a scheduled gap, and every chunk verifies (make hardy, see hardy/RESULTS.md). The demo runs any of them: node run-demo.mjs --plan contact-plans/mars-relay.json.

Run it:

npm test        # acceptance criteria, offline, deterministic
npm run demo    # the end-to-end pipeline with readable output
npm run quickstart  # the 40-line integration example (docs/QUICKSTART.md)

Standards and heritage

This layer sits on top of a deployed, standardized transport; it does not reinvent DTN.

  • Standard. Bundle Protocol v7 is an IETF standard: RFC 9171, with BPSec (RFC 9172), default security contexts (RFC 9173), and the TCP convergence layer (RFC 9174), updated by RFC 9713 (2025). BPv6 was RFC 5050; the architecture is RFC 4838.
  • Deployed. DTN runs operationally on the International Space Station (the DTNME engine), first flew in space on UK-DMC (2008), was demonstrated deep-space by NASA JPL's DINET (Deep Impact / EPOXI), and is used by NASA's PACE mission. This reference uses µD3TN, a space-tested BPv7 implementation.
  • Heritage. "Delay-tolerant networking" was coined by Kevin Fall (2002), out of Vint Cerf's Interplanetary Internet work, with ARPA/DARPA lineage.
  • The gap this fills. BPv7 standardizes how bundles move, but defines no native payment, incentive, or economic model, and only limited trust verification. It does not say who paid for a delivery, or how to prove the custody chain offline. That settlement and verifiable-custody layer is what this adds, on top of the standard, not instead of it.
  • Our Internet-Draft. The Custody Receipt Block is written up as an individual draft, draft-bsvkey-dtn-custody-receipt-block, with a discussion draft on accountability between administrative domains. A one-page summary with the interoperability evidence and the questions for the DTN Working Group is at dtn.bsvkey.com/ietf.

Record format specification

spec/CUSTODY-RECORDS.md specifies the record formats (canonical JSON, content identifiers, signatures, Merkle proofs, custody, gap and delivery records, plus the satellite-downlink and mirror-corroborated records of the sibling projects), with test vectors that the test suite regenerates from the code on every run.

Receipts can also travel inside the BPv7 bundle itself, as the Custody Receipt Block (extension block 224, spec section 2.1): each custodian appends its signed receipt, and BPv7 nodes that do not know the block forward it unchanged. Plain forwarders never read the payload or sign; only the origin reads the payload, later custodians copy the ids from the block. Where a route crosses forwarders that did not sign, the destination audit (auditBundleCustody) reports each unsigned stretch as an uncustodied transit gap instead of passing or failing the whole chain. Checked against uD3TN's own BPv7 library byte for byte, and live through all four BPv7 stacks used here, each holding the bundle across a scheduled gap and none of them knowing the block: uD3TN, NASA HDTN, JPL ION and Aalyria Hardy (make bpv7-block-all, see transport/bpv7/RESULTS.md). A BPSec payload signature (RFC 9172/9173 BIB) survives every receipt appended, through all four stacks (make bpv7-bpsec-all), and JPL ION built with real crypto accepts our BIB and signs one our code verifies (make bpv7-bpsec-ion, bpv7-bpsec-ion-source).

Acceptance criteria (what "done" means)

  1. Out-of-order chunk integrity against a Merkle root; a tampered chunk is rejected.
  2. A custody chain across the relays verifies (three links, two relay custody hops); a forged or missing hop is detected.
  3. A gap object documents the occultation and reconciles on link reopen.
  4. Delivery is bound to a settlement (matching txid passes, unbound refuses).
  5. The manifest root is anchored on-chain and re-derives from the received payload.
  6. Runs headless in CI on every push (GitHub Actions, offline suite) plus a --live mode with one real anchor.

Open core vs. hosted service

This repository is the open core under Apache-2.0: the protocol, the agent library (agent/), the DTN transport adapters (transport/, m0/, r2/), the verifiers, and the live on-chain checks (live/). Use it, fork it, build on it.

What is not in this repository and is not covered by this license: a hosted BSV settlement facilitator and relay marketplace, managed key custody, enterprise and compliance features, and the BSVKey brand. Those are operated separately. The open core settles on BSV; running a production relay-payment service on top of it is where the hosted offering lives.

Contributing and security

See CONTRIBUTING.md and SECURITY.md. The keys and funds in any live path are yours; this reference implementation never holds them.


Copyright 2026 Embryo Space Inc. (DBA BSVKey). Licensed under the Apache License 2.0. See LICENSE and NOTICE.