Skip to content

Publishing

Covers how the tx402 name was reserved on both registries and how real releases are cut.

Registry Name Owner First functional release
npm tx402 jay.komarraju 0.1.0
PyPI tx402 jay.komarraju 0.1.0

Neither registry offers a true “reserve” operation — a name is held only by publishing to it, so a deliberately inert 0.0.0 placeholder was published first to hold each name. 0.1.0 is the first functional release.

npm unpublish window. npm permits unpublishing a version only within 72 hours of publication, and only when nothing depends on it. After that the version is permanent — a republish of 0.0.0 is impossible and the version number is burned.


Completed 2026-08-03. The prebuilt placeholder wheel and source distribution were published without rebuilding later development code into version 0.0.0.

  1. Register at https://pypi.org/account/register/ if you do not already have an account.
  2. Enable 2FA (PyPI requires it for publishing).
  3. Create an API token at https://pypi.org/manage/account/token/.
    • Scope: “Entire account”. A project-scoped token cannot be created before the project exists, and this publish is what creates it.
    • Immediately after the first publish, replace it with a project-scoped token for tx402.

The distributions are already built and verified:

packages/tx402-python/dist/tx402-0.0.0.tar.gz
packages/tx402-python/dist/tx402-0.0.0-py3-none-any.whl

Rebuild and publish:

Terminal window
cd packages/tx402-python
uv build # regenerates dist/
read -rs UV_PUBLISH_TOKEN && export UV_PUBLISH_TOKEN # paste at the prompt; never echoed
uv publish
unset UV_PUBLISH_TOKEN

The token does not go on the command line. uv publish reads UV_PUBLISH_TOKEN from the environment, and that is the form to use: argv is visible to every process on the machine and is routinely captured by shell history, ps output, and CI logs. This is the same rule the SDK applies to itself — the CLI accepts no flag that carries a key, and the manifest runbook refuses one for the signing key on identical grounds. A publish token is a credential for the package name; it gets the same treatment.

Do not put it in .pypirc, a shell profile, or any tracked file either. .pypirc and .env* are gitignored, which protects against committing it and not against anything else.

Real releases go through trusted publishing (OIDC) and need no token at all. Reach for this path only for a manual reservation publish.

Terminal window
curl -s https://pypi.org/pypi/tx402/json | python3 -c \
"import sys,json; d=json.load(sys.stdin)['info']; \
print(d['name'], d['version'], d.get('license_expression') or d['license'])"

info.license is null for anything published with modern metadata — PyPI serves the SPDX string as info.license_expression instead, and reading only the old field prints None on a package whose licence is perfectly well declared. The fallback keeps the command working against both.

Then update the table at the top of this file.

Publication verification on 2026-08-03:

  • PyPI reported tx402 version 0.0.0, Apache-2.0, Python >=3.10.
  • Wheel SHA-256: d2e81d16f19a1cae92f049d5298bd8ff85293a491c1b862c4f36f02a2aee036b.
  • Source SHA-256: 01d32fbdba6c816215a585c3575684a24aa72c35e2c2c0373b83724b9f0f49e8.
  • A clean uvx --from tx402==0.0.0 tx402 --version returned tx402 0.0.0.

Placeholder publishing is a one-off. Every subsequent release goes through CI, never a laptop.

  • All P0/P1 tests green on protected main
  • No unresolved critical/high severity finding in reachable production code
  • TypeScript ↔ Python conformance parity at 100 % (T-016)
  • SBOM, license report, and vulnerability scan clean
  • Reproducible build verified
  • Public testnet smoke suite passed twice from clean environments (T-019)
  • API docs, migration notes, examples, and the error reference published
  • Independent security review closed with no release-blocking finding

Both registries must be configured for OIDC trusted publishing before 0.1.0, so that no long-lived token exists anywhere:

  • npm — provenance is already declared in packages/tx402/package.json (publishConfig.provenance: true). It requires a supported CI with an OIDC identity, which is why the local placeholder publish used --no-provenance. The release workflow must not pass that flag.
  • PyPI — configure a trusted publisher at https://pypi.org/manage/project/tx402/settings/publishing/ pointing at this repository and the release workflow. Then uv publish needs no token at all.
  • Semantic versioning applies. During 0.x, release notes must explicitly call out breaks.
  • After 1.0, any exported type removal, error code change, default policy relaxation, or wire behavior change requires a major version.
  • Network/token manifest updates that do not change API behavior are patch releases.
  • Adding a production network is a minor release and requires a chain adapter security review.
  • Upgrading the pinned @x402/* or x402 dependency requires replaying every conformance fixture and adding fixtures for each newly accepted envelope or scheme.

Every outward-facing repository URL is centralized, so there is one place to change per language and nothing drifts:

  • packages/tx402/src/meta.ts → PROJECT_URLS
  • packages/tx402-python/src/tx402/meta.py → PROJECT_URLS
  • packages/tx402/package.json and packages/tx402-python/pyproject.toml → the URL blocks

Nothing else should ever hardcode a repository URL.