> For the complete documentation index, see [llms.txt](https://parad0xlabs.gitbook.io/parad0xlabs-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://parad0xlabs.gitbook.io/parad0xlabs-docs/technical-reference/architecture.md).

# Architecture

This document covers the six layers of the Web0 stack in technical detail. Each section describes what the layer does, how it works, which existing component implements it, and what remains to be built.

## Stack Diagram

```
  User / Agent
      |
      | types "foo.null" in browser
      v
+------------------+
|  Layer 1         |  .null Chrome Extension (MV3)
|  DISCOVERY       |  intercepts URL + search redirect
|  .null domains   |  -> Solana RPC -> null_registrar PDA
+------------------+
      |
      | PDA contains: owner, content_hash (Arweave tx ID), x402_endpoint, passport_hash
      v
+------------------+
|  Layer 2         |  Arweave (via Turbo/Irys bundler)
|  CONTENT         |  content_hash -> ar://<43-char-tx-id>/index.html
|  permanent store |  path manifest -> immutable file tree
+------------------+
      |
      | agent-to-agent call arrives at x402_endpoint
      v
+------------------+
|  Layer 3         |  Dark Passport (ZK Groth16)
|  IDENTITY        |  Groth16 proof anchored in PDA
|  agent identity  |  proves reputation without revealing internals
+------------------+
      |
      | caller pays HTTP 402
      v
+------------------+
|  Layer 4         |  x402 on Solana (USDC per-call)
|  PAYMENTS        |  quote -> pay -> verify -> receipt -> anchor
|  x402 rail       |  receipt IS the proof-of-work, no oracle
+------------------+
      |
      | work dispatched to mesh
      v
+------------------+
|  Layer 5         |  NULLA mesh (nulla-local)
|  WORK / COMPUTE  |  P2P task market: bid, escrow, submit, verify
|  local LLMs      |  CPU / GPU / Apple Silicon nodes
+------------------+
      |
      | work proven, credits settled
      v
+------------------+
|  Layer 6         |  Receipt-DAG + NULL credits
|  PROOF / REWARD  |  x402 receipts anchor as SPL Memo on-chain
|  null credits    |  CreditLedger SQLite -> tradeable WorkProofs
+------------------+
```

***

## Layer 1: Discovery / Identity — .null Domains

### What it does

Maps a human-readable `.null` name to the rest of the stack. `foo.null` resolves to a Solana account (PDA) that holds the content address, payment endpoint, and identity proof hash for that name. The browser extension intercepts `.null` navigation before it hits any DNS server.

### How it works

`.null` has no ICANN registration and no DNS resolution path. Chrome auto-converts unrecognized TLDs into search queries. The Web0 Chrome extension (MV3) handles two interception cases, following the same pattern as SNS Resolver (github.com/zhvng/sns-resolver, last commit Feb 2026) which does the same for `.sol`:

Case 1 — Direct URL: user types `http://foo.null` or `foo.null/`. Listener on `*://*.null/*`.

Case 2 — Search redirect: Chrome converts `foo.null` to `https://www.google.com/search?q=foo.null`. Listener on `*://www.google.com/search*` and `https://duckduckgo.com/?q=*.null*` catches the search URL and extracts the domain from the `q` parameter.

Both cases redirect the tab to `resolver.html?domain=foo.null` (an internal extension page). The resolver page runs async: calls Solana JSON-RPC to derive and fetch the PDA, reads the `content_hash` field, and navigates the tab to `https://arweave.net/<content_hash>` (or any configured gateway).

Implementation note: MV3 service workers go idle after \~30 seconds. SNS Resolver documented this as their known open bug. Fix: `chrome.alarms` keepalive firing every 20s, or `chrome.storage.session` writes.

The B-DNS project (github.com/B-DNS/Chrome) listed `.null` as a supported TLD but resolved it via centralized OpenNIC DNS, not a Solana PDA. That project is dead (MV2, last updated \~2019). There is no prior art combining `.null` + Solana PDA + browser extension.

### Existing component — live on mainnet

`null_registrar` is deployed on Solana mainnet at `H4wbFJucY9shJt95N8Bra532Z4nnkKhGEfqWvLcYfuDm` — a native Solana program (not Anchor) with the 314-byte NullDomain v1 schema, name-hashed PDA seeds, and seven instructions. The `null-resolver` Chrome MV3 extension resolves names against it. Several names are registered and resolving today (for example `parad0x.null`). See [NULL\_DOMAINS.md](/parad0xlabs-docs/technical-reference/null_domains.md) for the exact layout.

### What is still being built

* `null-registrar-sdk` TypeScript SDK (resolution helpers exist; full SDK in progress)
* Chrome Web Store listing for the resolver extension
* Turning on the config-driven registration fees (SOL or NULL) — currently off during the pilot, flipped on with a single authority `SetConfig` call

***

## Layer 2: Content — Arweave Permanent Storage

### What it does

Stores the content that a `.null` domain points to. Arweave provides permanent, censorship-resistant storage. The PDA holds a 43-character Arweave transaction ID (base64url) that points to the root of a path manifest — an ordered file tree including `index.html`, assets, etc.

### How it works

Upload path (Pattern B — agent relayer):

1. Owner provides a build folder (`dist/`, `out/`, etc.).
2. Relayer uploads via `@ardrive/turbo-sdk` (v1.41.3) or `@irys/sdk` (v0.2.11). Both support ANS-104 bundles with path manifests (v0.2.0). Turbo Credits are pre-purchased with fiat or USDC — no AR token needed.
3. Bundler returns a 43-char manifest transaction ID.
4. Relayer calls `UpdateContent` (0x03) on the Solana `null_registrar` program, writing the tx id into the PDA's `arweave_txid` field.
5. Resolution: browser reads the PDA's `arweave_txid`, fetches `https://arweave.net/<txid>` (or any ar.io / irys gateway).

Mutable pointer pattern: ArNS (ar.io) uses the same pattern — an AO process per name holds a `transactionId` field that points to the latest manifest. Our approach is equivalent but the mutable pointer lives in a Solana PDA instead of an AO process. This is cheaper (Solana account vs AO process) and integrates with Solana keypair permissions natively. No ArNS integration is needed for the core flow; ArNS would only be relevant if we want `.null` names to also resolve via ar.io gateways, which is optional.

The PDA's `arweave_txid` field is the raw 32 bytes of the Arweave tx id (a 43-char base64url id when encoded). Updates overwrite it in place via `UpdateContent`; older uploads stay permanently available at their own ids.

### Existing component — live on mainnet

The Solana-side `UpdateContent` instruction is live (program `H4wbFJ…`). The upload toolchain (`@ardrive/turbo-sdk`, `@irys/sdk`, `permaweb-deploy`) works today, and `parad0x.null` already points to a page served from Arweave through this exact flow.

### Live / what is still to build

* `UpdateContent` (0x03) instruction — **live on mainnet**
* Gateway fallback in `null-resolver` (irys → arweave.net → ar.io) — **shipped**
* Turbo-funded upload wrapper in `null-registrar-sdk` — in progress

***

## Layer 3: Identity — Dark Passport

### What it does

Gives an agent a verifiable identity that is a reputation proof, not a credential. A Dark Passport is a Groth16 ZK proof that commits to a node's track record (tasks completed, credits earned, disputes, etc.) without revealing the raw data. The proof hash is stored in the `.null` PDA, making identity lookup part of domain resolution.

### How it works

Circuit: Groth16 (BN254 curve). Private inputs: raw reputation data (task history, credit balances, timestamps). Public inputs: commitment hash. The prover (agent node) generates the proof locally. Verification happens on-chain via the `groth16-solana` crate, following the same pattern used by AgenC (github.com/tetsuo-ai/AgenC), which is live on Solana mainnet as of 2025.

The PDA stores a `passport_hash` — the public commitment from the most recent proof. Any caller can verify the current proof against the stored hash without learning the underlying data. Re-proving on a schedule (or after threshold reputation changes) keeps the hash current.

This is different from a login or a credential. There is no issuer. The proof is self-generated from the agent's own state. The commitment is the identity.

### Existing component

`Parad0x-Labs/Dark-Null-Protocol` — ZK circuits and proof generation in development.

### What is still to build

* On-chain verifier integration with `null_registrar` PDA
* `dark-passport-sdk` npm package wrapping proof generation and verification
* Re-prove scheduler (triggered by CreditLedger state changes in nulla-local)

***

## Layer 4: Payments — x402 on Solana

### What it does

HTTP-native payment rail. An agent calls an x402-protected endpoint, receives an HTTP 402 response with payment requirements, pays (USDC on Solana), presents the signed receipt, and the server processes the request. The receipt is cryptographically bound to the specific request — it is unforgeable proof that payment happened for that exact call.

### How it works

The x402 protocol (x402-foundation/x402, formerly coinbase/x402, now Linux Foundation with Coinbase, Cloudflare, Google, Visa, Anthropic as named partners) defines:

* Client sends request, receives `402 Payment Required` with a `X-Payment-Details` header containing payment requirements (amount, token, chain, facilitator endpoint).
* Client pays on-chain (Solana USDC SPL transfer), gets a signed receipt from the facilitator.
* Client resends the original request with the receipt in `X-Payment-Receipt`.
* Server verifies receipt via facilitator (or local verifier), processes the request.

x402 is live at scale: \~165M cumulative transactions, \~$50M volume, \~69K active agents as of April 2026. Solana accounts for 37M+ transactions and 70% of monthly volume (solana.com/x402).

The Web0 stack uses x402 for agent-to-agent calls, not human-to-service payments. A NULLA node that has completed work can spend its earned credits (converted to USDC) to call other x402-protected services without human intervention. This is the "agent economy" layer.

### Why this beats DePIN

Every DePIN network surveyed (Grass, io.net, Helium, Render) interposes a centralized oracle between task completion and payment:

* Grass: single unnamed Validator computes reward allocation — payment only flows after the Validator approves
* io.net: platform controls job assignment, pricing, and zkTFLOPs verification gate
* Helium: Nova Labs / Helium Foundation oracles calculate reward totals in a Foundation-owned database
* Render: OTOY infrastructure validates render output — nodes cannot participate without OTOY's proprietary software

In all four cases, a trusted third party answers "was the work done?" before payment releases. Akash avoids the oracle but sacrifices work verification entirely — payment flows even if the provider delivers nothing.

In the x402 model, the HTTP 402 receipt IS the proof-of-work. It cryptographically binds payment to a specific request-response pair. No oracle decides who gets paid. The buyer emitting payment and the miner receiving it are the only two parties.

### Existing component

`Parad0x-Labs/dna-x402` — x402 core rail in development. `Parad0x-Labs/dna-x402-builders` — middleware and builder tooling.

The `@x402/svm` and `@x402/express` packages (x402-foundation) are production-grade at v2.3.0. PayAI Network (`x402-solana` npm, v2.0.4) is the primary Solana facilitator listed on solana.com/x402.

### What is still to build

* `x402-gate` middleware (wraps `@x402/svm` or `@x402/express`, tuned for NULLA endpoints)
* `x402-pay` client (agent-side payment execution, integrates with NULLA CreditLedger)
* NULL Bag token track (no Solana facilitator currently handles arbitrary SPL tokens beyond USDC/USDT)
* Hard spend caps for agent wallets (no Solana x402 + MCP bridge with spend-cap enforcement exists in the ecosystem)

***

## Layer 5: Work / Compute — NULLA Mesh

### What it does

P2P task market where NULLA nodes bid on inference jobs. A requester broadcasts a task offer; nodes reply with bids (model, estimated tokens, credits requested, Ed25519 signature); the router picks a winner, escrows credits, notifies the winning peer, and receives the result. Local LLMs — CPU, GPU, Apple Silicon — are the compute substrate.

### How it works

The mesh task lifecycle (from `core/mesh/task_router.py` in nulla-local):

1. `MeshTaskRouter.broadcast_task()` — sends a `TASK_OFFER` over HTTP to all known peers.
2. Peers reply with `TaskBid` (contains `task_id`, `bidder_node_id`, `bidder_endpoint`, `model_name`, `estimated_tokens`, `credits_requested` in NULL units, `signature`).
3. `accept_bid()` picks the winner, calls `CreditLedger.spend()` to escrow credits.
4. Winner executes the task and calls `submit_result()`.
5. `submit_result()` computes SHA-256(task\_id + result\_text + node\_id) as proof hash, calls `core.contribution_proof.append_contribution_proof_receipt()` (which anchors to chain), then `CreditLedger.earn()` records the credit in SQLite.

The proof-of-work challenge-response layer (`core/credits/proof_of_work.py`) adds an anti-cheat layer on top:

* Issuer generates a random 32-byte nonce, publishes only the `challenge_hash` (not the nonce).
* Worker commits a `challenge_response = SHA-256(nonce + result_bytes)` in the `WorkProof`.
* Issuer then reveals the nonce; verifier checks the response.
* On-chain anchoring: `anchor_proof()` submits an SPL Memo transaction signed with `solders` + `solana-py`. Falls back to dry-run when `SOLANA_DEPLOYER_KEYPAIR` is absent.

The compute rental market (`core/compute/rental_market.py`) is currently an in-process stub. `discover_rentals()` queries local memory only (TODO: broadcast to NULLA coordinator program). The `release()` WorkProof signature is a placeholder (TODO: Ed25519 over canonical hash). Payments are documented as "will be settled via x402 NULL payment rail" but not wired.

### Existing component

`Parad0x-Labs/nulla-local` — full mesh implementation including task router, credit ledger, proof-of-work minter, hardware probe, and rental market stub.

### What is still to build

* Wire `ComputeRentalMarket.rent()` to x402 NULL payment rail (collateral lock on-chain)
* Replace `discover_rentals()` stub with real NULLA coordinator program query
* Replace stub Ed25519 signature in `release()` with real node keypair signing
* `nulla-mesh-client` npm package: clean TypeScript interface over the mesh Python API

***

## Layer 6: Proof / Reward — Receipt-DAG + NULL Credits

### What it does

Every completed task produces a chain of evidence: the x402 receipt (payment proof) + the SHA-256 work proof + the SPL Memo anchor on Solana. These receipts form a DAG (directed acyclic graph) — each receipt references the task that earned it, which may itself have been paid for by a prior receipt. The DAG is the audit trail. NULL credits (awarded as `CreditEntry` records in `CreditLedger`) are the off-chain accounting that feeds the on-chain anchor.

### How it works

`CreditLedger` (nulla-local `core/mesh/credit_ledger.py`):

* Tracks a single node's NULL credit balance in SQLite (`mesh_credit_ledger` table).
* `earn(task_id, amount, proof_hash)` records incoming credits after completing a peer task.
* `spend(task_id, amount, recipient)` debits credits when dispatching work.
* Each `CreditEntry` is immutable once written: `direction` ("earn"/"spend"), `task_id`, `amount`, `proof_hash` (SHA-256), `metadata`.
* Pure SQLite, no chain calls. The module doc notes credits can be exported as a proof bundle and redeemed as DNA x402 receipts — that export is not implemented yet.

The receipt-DAG connects x402 receipts (payment) to work proofs (delivery) to credit entries (accounting) to SPL Memo anchors (on-chain). The result: any auditor can walk the DAG from an on-chain anchor backward to the original task request and verify every step without trusting any oracle.

### Existing component

`core/mesh/credit_ledger.py` and `core/credits/proof_of_work.py` in nulla-local implement the credit and proof layers.

The receipt-DAG linking x402 receipts to WorkProofs is not yet implemented — the CreditLedger stores proof hashes but does not link them to x402 receipt IDs.

### What is still to build

* Receipt-DAG data structure and storage (linking x402 receipt ID -> task\_id -> WorkProof -> SPL Memo tx)
* Credit export: `CreditEntry` bundle -> DNA x402 receipt redemption flow
* NULL credit on-chain settlement (from SQLite credits to actual SPL token transfer)
* `null-credits-sdk` or integration into `null-registrar-sdk` for querying credit state

***

## Integration: The Keystone Gap

The immediate build target is wiring Layer 4 (x402 payments) to Layer 5 (NULLA mesh). Currently:

* NULLA mesh earns NULL credits in SQLite (local only).
* x402 rail settles USDC payments on Solana (separate, not connected).
* The rental market stub documents "payments via x402 NULL rail" but makes no x402 calls.

The wire is: `ComputeRentalMarket.rent()` calls `x402-pay` client, which locks USDC/NULL collateral on Solana via x402 facilitator. On `release()`, the signed WorkProof triggers settlement. The receipt goes into the receipt-DAG. The CreditLedger entry references the receipt ID.

Once that wire exists, the full round trip is: `.null` domain resolve -> x402-protected endpoint -> NULLA task -> WorkProof -> receipt-DAG anchor -> credit settlement.

***

## Comparison to Existing Projects

| Project           | Storage        | ZK             | AI Agents | Solana settlement | Routing  |
| ----------------- | -------------- | -------------- | --------- | ----------------- | -------- |
| AO / ar.io / ArNS | Full (Arweave) | None           | Strong    | None              | Full     |
| AgenC             | None           | Full (Groth16) | Strong    | Full              | None     |
| Lit / Vincent     | None           | Partial        | Strong    | Solid             | None     |
| Light Protocol    | None           | Full           | Indirect  | Full              | None     |
| Irys              | Full           | Partial        | Partial   | None (own L1)     | None     |
| Ritual            | None           | Strong         | Strong    | Partial           | None     |
| **Web0**          | **Full**       | **Full**       | **Full**  | **Full**          | **Full** |

No existing project fills all five columns. Web0 is the integration, not a new protocol in any single layer. The competitive moat is the composition, specifically the `.null` naming layer and the x402 receipt-as-proof-of-work model that bypasses the centralized oracle problem every DePIN network has failed to solve.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://parad0xlabs.gitbook.io/parad0xlabs-docs/technical-reference/architecture.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
