Skip to main content
Use this checklist before enabling prepaid-wallet or x402 traffic in a self-hosted environment. Repository tests prove the Grantex authorization and sandbox_ledger paths; they do not provision a custody provider, merchant recovery store, notification channel, or regulatory approval for the operator.

Dependency matrix

The source checkout includes a specific Base USDC adapter. It requires migration 094, operator-provisioned keys, a trusted Base RPC, verified funding and reconciliation monitoring. Python 0.5.0 and Go v0.3.0 publish the response and reconciliation APIs; published TypeScript 0.6.0 and x402 0.4.0 support opt-in automatic Base payment retries. Other external providers still need their own adapter. Signed EVM holds are not released on a wallet block or a local timeout alone.

Choose the custody mode honestly

sandbox_ledger is complete local/off-chain accounting with PostgreSQL as the system of record. It is suitable for development, deterministic integration tests, and deployments that explicitly intend to operate an internal ledger. It is not a bank account, prepaid card, on-chain balance, proof of external funds, or a regulated stored-value product. external requires provider-specific verification. The included base_usdc adapter verifies finalized native USDC funding and settlement through RPC and retains outstanding signed exposure through blocks and provider outages. It requires explicit operator provisioning; installation alone does not enable it. Other providers remain unavailable. Do not turn arbitrary provider references into balance. A production adapter must, at minimum:
  • authenticate signed provider webhooks and reject stale or replayed events;
  • deduplicate funding and settlement references transactionally;
  • reconcile Grantex available/reserved amounts with provider state;
  • reserve and settle through provider-supported atomic or compensating flows;
  • persist provider transaction and evidence references without exposing credentials to agents;
  • define timeout, partial failure, reversal, dispute, and restart recovery;
  • fail closed when provider state is unavailable or ambiguous.

Route the public resource

Set JWT_ISSUER to the exact issuer URL used in tokens and PUBLIC_BASE_URL to the browser-reachable origin. In a normal reverse-proxy deployment, route the entire API origin to the auth service. If a static host and API share one domain, explicitly forward at least:
The OAuth resource and access-token audience must be the same exact URL, for example https://auth.example.com/v1/prepaid-wallets. TLS is required outside loopback development. A static-host 404 at this path means the agent cannot list wallets, request reloads, or authorize a payment even if Cloud Run or the origin service itself is healthy. After deployment, unauthenticated probes should reach the auth service and fail with structured authentication errors, not HTML:

Preserve the financial evidence store

Migration 091_agent_prepaid_wallets.sql creates wallet, assignment, reservation, reload, control, and append-only ledger structures. Migration 092_layered_wallet_spend_controls.sql adds safe assignment defaults, reload velocity controls, layered policy, exact payment approval, semantic reservation context, and append-only policy decisions. Treat PostgreSQL as durable financial evidence:
  • take and restore-test backups before and after migration;
  • run every auth-service instance against the same authoritative database;
  • monitor migration completion before marking a new instance ready;
  • retain ledger and audit records according to an approved policy;
  • never repair balances by deleting ledger or reservation rows;
  • reconcile available_amount, reserved_amount, ledger entries, and any provider evidence before reopening a blocked wallet.
Redis is required for the service and real-time event delivery, but PostgreSQL remains the wallet system of record.

Deliver reload notifications

The service emits wallet.low_balance, wallet.reload.requested, wallet.reload.approved, wallet.reload.rejected, wallet.reloaded, wallet.payment.denied, wallet.payment.approval_required, wallet.payment.approval_approved, wallet.payment.approval_rejected, and wallet.spend_policy.changed events. Agents can request a reload but cannot approve or fund it. There is no built-in promise that a reload request reaches email, SMS, Slack, WhatsApp, or another human channel. The current public webhook-registration API accepts only its documented grant/token event allowlist. For wallet alerts, operate an authenticated SSE/WebSocket consumer and bridge events to the principal’s approved channel, or implement a separately reviewed webhook extension. The bridge must deduplicate by event ID, retry durably, protect principal contact data, and expose delivery failures to operators. Do not auto-approve or auto-fund merely because a notification was delivered. The principal decision and funding calls remain separate authenticated actions.

Make merchant work recoverable

For a side-effecting paid request, the resource server must use this order:
  1. Validate the x402 request and call /v1/x402/verify.
  2. Complete /v1/x402/settle successfully.
  3. Atomically create or retrieve the protected business result under the caller’s HTTP Idempotency-Key.
  4. Return the cached result on an identical retry.
The SDK idempotencyKey recovers a Grantex reservation response lost before settlement. The HTTP Idempotency-Key recovers merchant work lost after settlement. They should contain the same durable logical operation ID, but one does not replace the other.

Registry availability

Server deployment and npm publication are independent. A self-hosted server can run repository source while its application consumers still resolve older npm packages. Check the registry before deployment:
Published and clean-install verified: SDK 0.6.0 and x402 0.4.0 on September 7, 2026. Registry publication is not inferred from the source tree, so treat the registry as authoritative and verify exact versions before each deployment. See Release Status for the public artifact matrix.

Maintainer-only PowerShell publication

Publishing is irreversible for an already consumed version. Run this only as an npm maintainer of the @grantex scope, from a reviewed and clean main. Direct publication requires npm publishing permission and either account 2FA or an appropriately restricted publishing credential.

1. Verify repository and registry state

Stop if either target version already exists. npm will not let a version be overwritten, and changing tags is not a substitute for a new version.

2. Build, test, audit, and inspect both packages

Review the npm pack --dry-run file lists. Each package should contain its compiled dist output, README.md, package metadata, and no keys, credentials, environment files, test fixtures, or unrelated repository content.

3. Publish in dependency order

Publish the SDK first. Let npm prompt for the one-time code instead of placing an OTP in shell history.
Do not continue to x402 if SDK publication or registry verification fails.

4. Test the registry artifacts

After registry smoke passes, tag the exact reviewed commit and update release-status.json, web/release-status.json, COMPATIBILITY.md, the root README, release documentation, and public website notices in one release PR. Do not describe the packages as published until the exact registry queries above succeed.

Python and Go publication

Python 0.5.0 passed source import, Ruff, strict Mypy, Pytest, distribution build, and Twine metadata checks before upload:
The Go module path is a separate repository, github.com/mishrasanjeev/grantex-go. Publishing requires copying the reviewed packages/go-sdk tree to that repository, rerunning go test ./..., committing the exact source, and pushing annotated tag v0.3.0. A tag in the Grantex monorepo does not publish that module. Python 0.5.0 and Go v0.3.0 were published on 7 September 2026 and verified from clean public-registry consumers. The steps remain here as the release runbook; they are not instructions to overwrite those immutable versions. The guarded Publish primary SDKs workflow tests and builds all four SDKs once, uploads immutable distributions, and makes publication jobs consume those exact artifacts. Before the first run:
  1. Create the GitHub sdk-release environment and require a human reviewer.
  2. On npm, configure trusted-publisher records for both @grantex/sdk and @grantex/x402 using repository mishrasanjeev/grantex, workflow publish-primary-sdks.yml, environment sdk-release, and the npm publish action. Do not add a long-lived npm token fallback.
  3. On PyPI, configure the grantex project’s trusted publisher with the same repository, workflow filename, and sdk-release environment.
  4. Add GRANTEX_GO_RELEASE_TOKEN to the environment with write access limited to mishrasanjeev/grantex-go; do not use a broadly scoped account token.
  5. Protect main and the publication workflow through review and required CI.
Run the workflow only from reviewed main, type RELEASE_PRIMARY_SDKS, and select the registries to publish. The workflow fails closed when trusted publishing or the Go credential is absent; a version bump is not evidence that a registry release exists. After publication, verify from empty temporary projects rather than importing the monorepo checkout:
The workflow uses npm trusted publishing with OIDC and provenance instead of a long-lived npm token. See npm’s official scoped public package publishing and trusted publishing documentation before changing the release mechanism.

Go-live checklist

  • Exact repository commit and npm package versions are recorded.
  • Migrations 091_agent_prepaid_wallets.sql and 092_layered_wallet_spend_controls.sql completed and backup restore was tested.
  • Public OAuth, wallet, principal, and x402 routes reach the auth service over TLS.
  • DPoP tokens use the exact public wallet audience.
  • sandbox_ledger or external custody behavior is described accurately to users.
  • External custody remains disabled unless the provider adapter and reconciliation runbook passed review.
  • Reload alerts have a monitored consumer and delivery-failure path.
  • Merchant handlers persist results by HTTP Idempotency-Key after settlement.
  • Wallet blocking, reservation release, reload approval, restart recovery, and provider outage drills passed.
  • Security, privacy, financial, and regulatory owners approved the intended production use.
Last modified on September 7, 2026