@clearproof/content 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/content/explainers/pilot-proof-public-signals.md +80 -0
  2. package/content/explainers/portable-evidence-review.md +103 -0
  3. package/content/explainers/usd-cents-without-a-price-feed.md +106 -0
  4. package/content/explainers/verify-independently.md +106 -0
  5. package/content/explainers/what-clearproof-does.md +92 -0
  6. package/content/explainers/who-verifies-what.md +86 -0
  7. package/content/recipes/deploy-contracts.md +45 -0
  8. package/content/recipes/full-walkthrough.md +84 -0
  9. package/content/recipes/generate-proof.md +43 -0
  10. package/content/recipes/update-sanctions.md +35 -0
  11. package/content/recipes/verify-onchain.md +41 -0
  12. package/content/recipes/verify-proof.md +36 -0
  13. package/content/signals.yaml +128 -0
  14. package/content/topics/api.md +61 -0
  15. package/content/topics/architecture.md +50 -0
  16. package/content/topics/circuits.md +66 -0
  17. package/content/topics/contracts.md +60 -0
  18. package/content/topics/gdpr.md +36 -0
  19. package/content/topics/quickstart.md +77 -0
  20. package/content/topics/sdk.md +56 -0
  21. package/content/topics/security.md +33 -0
  22. package/content/topics/troubleshooting.md +109 -0
  23. package/content/updates/2026-09-09-adoption-roadmap.md +27 -0
  24. package/content/updates/2026-09-12-full-walkthrough.md +31 -0
  25. package/content/updates/2026-09-12-npm-status.md +27 -0
  26. package/content/updates/2026-09-12-proof-boundaries.md +40 -0
  27. package/content/updates/2026-09-21-sanctions-schedule.md +43 -0
  28. package/content/updates/2026-09-25-pilot-transfer-v3.md +60 -0
  29. package/dist/explainers.d.ts +29 -0
  30. package/dist/explainers.d.ts.map +1 -0
  31. package/dist/explainers.js +71 -0
  32. package/dist/explainers.js.map +1 -0
  33. package/dist/index.d.ts +13 -0
  34. package/dist/index.d.ts.map +1 -0
  35. package/dist/index.js +25 -0
  36. package/dist/index.js.map +1 -0
  37. package/dist/parser.d.ts +25 -0
  38. package/dist/parser.d.ts.map +1 -0
  39. package/dist/parser.js +97 -0
  40. package/dist/parser.js.map +1 -0
  41. package/dist/recipes.d.ts +28 -0
  42. package/dist/recipes.d.ts.map +1 -0
  43. package/dist/recipes.js +103 -0
  44. package/dist/recipes.js.map +1 -0
  45. package/dist/signals.d.ts +18 -0
  46. package/dist/signals.d.ts.map +1 -0
  47. package/dist/signals.js +34 -0
  48. package/dist/signals.js.map +1 -0
  49. package/dist/topics.d.ts +18 -0
  50. package/dist/topics.d.ts.map +1 -0
  51. package/dist/topics.js +41 -0
  52. package/dist/topics.js.map +1 -0
  53. package/dist/updates.d.ts +27 -0
  54. package/dist/updates.d.ts.map +1 -0
  55. package/dist/updates.js +69 -0
  56. package/dist/updates.js.map +1 -0
  57. package/package.json +42 -0
@@ -0,0 +1,84 @@
1
+ ---
2
+ title: Full End-to-End Walkthrough
3
+ prereqs:
4
+ - api-running
5
+ - circuits-compiled
6
+ - contracts-deployed
7
+ - sepolia-rpc
8
+ estimated-time: 10 min
9
+ ---
10
+
11
+ # Full End-to-End Walkthrough
12
+
13
+ > **Legacy demo path.** This recipe uses the 16-signal legacy profile (`/proof/generate`, `/proof/verify`). It does not exercise the current `pilot-transfer-v3` workflow; for that, follow the [local acceptance guide](https://github.com/repfigit/clearproof/blob/main/docs/operations/local-pilot-acceptance.md).
14
+
15
+ Complete compliance flow: issue a credential, generate a proof, verify off-chain, and record on-chain.
16
+
17
+ The local API defaults to API-key auth:
18
+
19
+ ```bash:run
20
+ export CLEARPROOF_API_KEY="dev-api-key"
21
+ export AUTH_MODE="api-key"
22
+ export API_KEY="$CLEARPROOF_API_KEY"
23
+ ```
24
+
25
+ ## 1. Build the sanctions tree
26
+
27
+ ```bash:run
28
+ python scripts/build_sanctions_tree.py --offline
29
+ ```
30
+
31
+ Expected: Sanctions tree built with root hash and leaf count displayed
32
+
33
+ ## 2. Issue a zkKYC credential
34
+
35
+ ```bash:run
36
+ curl -s -X POST http://localhost:8000/credential/issue \
37
+ -H "X-API-Key: $CLEARPROOF_API_KEY" \
38
+ -H "Content-Type: application/json" \
39
+ -d '{"issuer_did":"did:web:vasp.example.com","subject_wallet":"0x1234abcd5678ef901234abcd5678ef9012345678","jurisdiction":"US","kyc_tier":"retail"}'
40
+ ```
41
+
42
+ Expected: 200 with `credential_id` and `commitment`
43
+
44
+ ## 3. Generate a compliance proof
45
+
46
+ ```bash:run
47
+ curl -s -X POST http://localhost:8000/proof/generate \
48
+ -H "X-API-Key: $CLEARPROOF_API_KEY" \
49
+ -H "Content-Type: application/json" \
50
+ -d '{"credential_id":"CRED_ID_FROM_STEP_2","wallet_address":"0x1234abcd5678ef901234abcd5678ef9012345678","amount_usd":500,"asset":"USDC","destination_wallet":"0xabcd1234abcd1234abcd1234abcd1234abcd1234","jurisdiction":"US","idempotency_key":"recipe-full-001"}'
51
+ ```
52
+
53
+ Expected: 200 with `compliance_proof` (Groth16 proof + 16 public signals) and `encrypted_pii`
54
+
55
+ ## 4. Verify the proof off-chain
56
+
57
+ ```bash:run
58
+ curl -s -X POST http://localhost:8000/proof/verify \
59
+ -H "X-API-Key: $CLEARPROOF_API_KEY" \
60
+ -H "Content-Type: application/json" \
61
+ -d '{"proof_id":"PROOF_ID_FROM_STEP_3","groth16_proof":{"pi_a":["..."],"pi_b":["..."],"pi_c":["..."]},"public_signals":["1","0","..."],"expected_amount_tier":1,"originator_vasp_did":"did:web:vasp.example.com","transfer_timestamp":1711929600}'
62
+ ```
63
+
64
+ Expected: 200 with `valid: true` and `is_compliant: true`
65
+
66
+ ## 5. Record the proof on-chain
67
+
68
+ ```bash:run
69
+ export PROOF_PATH="$PWD/artifacts/latest_proof.json"
70
+ export TRANSFER_ID="recipe-transfer-001"
71
+ export VASP_DID="did:web:vasp.example.com"
72
+ cd packages/contracts && npx hardhat run scripts/verify-onchain.ts --network sepolia
73
+ ```
74
+
75
+ Expected: Transaction hash and `ProofVerified` event emitted on ComplianceRegistry
76
+
77
+ ## 6. Confirm on-chain recording
78
+
79
+ ```bash:run
80
+ export TRANSFER_ID="recipe-transfer-001"
81
+ cd packages/contracts && npx hardhat run scripts/check-transfer.ts --network sepolia
82
+ ```
83
+
84
+ Expected: `isVerified` returns `true` for the transfer ID
@@ -0,0 +1,43 @@
1
+ ---
2
+ title: Generate a Compliance Proof
3
+ prereqs:
4
+ - api-running
5
+ - circuits-compiled
6
+ estimated-time: 2 min
7
+ ---
8
+
9
+ # Generate a Compliance Proof
10
+
11
+ > **Legacy demo path.** This recipe uses the 16-signal legacy profile (`/proof/generate`, `/proof/verify`). It does not exercise the current `pilot-transfer-v3` workflow; for that, follow the [local acceptance guide](https://github.com/repfigit/clearproof/blob/main/docs/operations/local-pilot-acceptance.md).
12
+
13
+ Issue a zkKYC credential and then generate a Groth16 compliance proof against it.
14
+
15
+ The local API defaults to API-key auth:
16
+
17
+ ```bash:run
18
+ export CLEARPROOF_API_KEY="dev-api-key"
19
+ export AUTH_MODE="api-key"
20
+ export API_KEY="$CLEARPROOF_API_KEY"
21
+ ```
22
+
23
+ ## 1. Issue a credential
24
+
25
+ ```bash:run
26
+ curl -s -X POST http://localhost:8000/credential/issue \
27
+ -H "X-API-Key: $CLEARPROOF_API_KEY" \
28
+ -H "Content-Type: application/json" \
29
+ -d '{"issuer_did":"did:web:vasp.example.com","subject_wallet":"0x1234abcd5678ef901234abcd5678ef9012345678","jurisdiction":"US","kyc_tier":"retail"}'
30
+ ```
31
+
32
+ Expected: 200 with `credential_id` and `commitment`
33
+
34
+ ## 2. Generate proof
35
+
36
+ ```bash:run
37
+ curl -s -X POST http://localhost:8000/proof/generate \
38
+ -H "X-API-Key: $CLEARPROOF_API_KEY" \
39
+ -H "Content-Type: application/json" \
40
+ -d '{"credential_id":"CRED_ID_FROM_STEP_1","wallet_address":"0x1234abcd5678ef901234abcd5678ef9012345678","amount_usd":500,"asset":"USDC","destination_wallet":"0xabcd1234abcd1234abcd1234abcd1234abcd1234","jurisdiction":"US","idempotency_key":"recipe-generate-001"}'
41
+ ```
42
+
43
+ Expected: 200 with `compliance_proof` containing Groth16 proof, 16 public signals, and `encrypted_pii`
@@ -0,0 +1,35 @@
1
+ ---
2
+ title: Update Sanctions Tree
3
+ prereqs:
4
+ - api-running
5
+ - contracts-deployed
6
+ estimated-time: 2 min
7
+ ---
8
+
9
+ # Update Sanctions Tree
10
+
11
+ Rebuild the sanctions Merkle tree from OFAC/UN/EU lists and relay the new root to the on-chain SanctionsOracle.
12
+
13
+ ## 1. Build the sanctions tree
14
+
15
+ ```bash:run
16
+ python scripts/build_sanctions_tree.py --offline
17
+ ```
18
+
19
+ Expected: Tree built with leaf count printed, root hash displayed. The `--offline` flag uses cached list data; omit it to fetch fresh lists from OFAC/UN/EU sources.
20
+
21
+ ## 2. Relay the new root to SanctionsOracle
22
+
23
+ ```bash:run
24
+ python scripts/relay_sanctions_root.py --network sepolia
25
+ ```
26
+
27
+ Expected: Transaction hash printed, `RootUpdated` event emitted on SanctionsOracle with new root and leaf count
28
+
29
+ ## 3. Verify the oracle is not stale
30
+
31
+ ```bash:run
32
+ cd packages/contracts && npx hardhat run scripts/check-oracle-staleness.ts --network sepolia
33
+ ```
34
+
35
+ Expected: `isStale` returns `false`, `lastUpdated` is recent
@@ -0,0 +1,41 @@
1
+ ---
2
+ title: Verify a Proof On-Chain
3
+ prereqs:
4
+ - contracts-deployed
5
+ - proof-generated
6
+ - sepolia-rpc
7
+ estimated-time: 3 min
8
+ ---
9
+
10
+ # Verify a Proof On-Chain
11
+
12
+ Submit a compliance proof to the ComplianceRegistry contract on Sepolia testnet. The contract performs 14 checks including Groth16 verification, sanctions root validation, and nullifier uniqueness.
13
+
14
+ ## 1. Set environment variables
15
+
16
+ ```bash:run
17
+ export SEPOLIA_RPC_URL="https://rpc.sepolia.org"
18
+ export DEPLOYER_PRIVATE_KEY="YOUR_VASP_WALLET_PRIVATE_KEY"
19
+ export COMPLIANCE_REGISTRY="YOUR_COMPLIANCE_REGISTRY_ADDRESS" # optional if deployments/sepolia.json exists
20
+ export PROOF_PATH="$PWD/../../artifacts/latest_proof.json"
21
+ export TRANSFER_ID="recipe-transfer-001"
22
+ export VASP_DID="did:web:vasp.example.com"
23
+ ```
24
+
25
+ Expected: No output (variables set)
26
+
27
+ ## 2. Submit proof to ComplianceRegistry
28
+
29
+ ```bash:run
30
+ cd packages/contracts && npx hardhat run scripts/verify-onchain.ts --network sepolia
31
+ ```
32
+
33
+ Expected: Transaction hash and `ProofVerified` event emitted with the blinded nullifier
34
+
35
+ ## 3. Confirm the transfer is recorded
36
+
37
+ ```bash:run
38
+ cd packages/contracts && npx hardhat run scripts/check-transfer.ts --network sepolia
39
+ ```
40
+
41
+ Expected: `isVerified` returns `true` for the transfer ID
@@ -0,0 +1,36 @@
1
+ ---
2
+ title: Verify a Proof Off-Chain
3
+ prereqs:
4
+ - api-running
5
+ - proof-generated
6
+ estimated-time: 1 min
7
+ ---
8
+
9
+ # Verify a Proof Off-Chain
10
+
11
+ > **Legacy demo path.** This recipe uses the 16-signal legacy profile (`/proof/generate`, `/proof/verify`). It does not exercise the current `pilot-transfer-v3` workflow; for that, follow the [local acceptance guide](https://github.com/repfigit/clearproof/blob/main/docs/operations/local-pilot-acceptance.md).
12
+
13
+ Take an existing compliance proof and verify it locally using the API server. This does not interact with any blockchain.
14
+
15
+ The local API defaults to API-key auth:
16
+
17
+ ```bash:run
18
+ export CLEARPROOF_API_KEY="dev-api-key"
19
+ ```
20
+
21
+ ## 1. Verify the proof
22
+
23
+ ```bash:run
24
+ curl -s -X POST http://localhost:8000/proof/verify \
25
+ -H "X-API-Key: $CLEARPROOF_API_KEY" \
26
+ -H "Content-Type: application/json" \
27
+ -d '{"proof_id":"PROOF_ID_FROM_GENERATE","groth16_proof":{"pi_a":["..."],"pi_b":["..."],"pi_c":["..."]},"public_signals":["1","0","..."],"expected_amount_tier":2,"originator_vasp_did":"did:web:vasp.example.com","transfer_timestamp":1711929600}'
28
+ ```
29
+
30
+ Expected: 200 with `valid: true` and `compliance_attestations` showing `is_compliant: true`
31
+
32
+ The verification checks:
33
+ - Groth16 proof is cryptographically valid against the verification key
34
+ - `is_compliant` signal equals 1
35
+ - Amount tier matches the expected tier
36
+ - Transfer timestamp is reasonable
@@ -0,0 +1,128 @@
1
+ signals:
2
+ - index: 0
3
+ name: is_compliant
4
+ type: bit
5
+ description: 1 for the encoded circuit checks; not a legal compliance determination
6
+ source: circuits/compliance.circom
7
+ onChainUsage: Must equal 1 for proof acceptance
8
+ isOutput: true
9
+
10
+ - index: 1
11
+ name: sar_review_flag
12
+ type: bit
13
+ description: Public tier-derived advisory bit; 1 if amount_tier >= 3, not a suspicious-activity determination
14
+ source: circuits/amount_tier.circom
15
+ onChainUsage: Emitted as the review bit in the development ProofVerified event
16
+ isOutput: true
17
+
18
+ - index: 2
19
+ name: sanctions_tree_root
20
+ type: field
21
+ description: Merkle root of the supplied sanctions dataset; source completeness and freshness require verification
22
+ source: circuits/compliance.circom
23
+ onChainUsage: Checked against SanctionsOracle.currentRoot()
24
+ isOutput: false
25
+
26
+ - index: 3
27
+ name: issuer_tree_root
28
+ type: field
29
+ description: Merkle root of the trusted VASP issuer tree
30
+ source: circuits/compliance.circom
31
+ onChainUsage: Checked against VASPRegistry.issuerMerkleRoot()
32
+ isOutput: false
33
+
34
+ - index: 4
35
+ name: amount_tier
36
+ type: uint64
37
+ description: Amount bucket 1 through 4 under the supplied ordered thresholds
38
+ source: circuits/amount_tier.circom
39
+ onChainUsage: Used for tier-based compliance rules
40
+ isOutput: false
41
+
42
+ - index: 5
43
+ name: transfer_timestamp
44
+ type: uint64
45
+ description: Unix timestamp of the transfer
46
+ source: circuits/compliance.circom
47
+ onChainUsage: Must be <= block.timestamp
48
+ isOutput: false
49
+
50
+ - index: 6
51
+ name: jurisdiction_code
52
+ type: uint16
53
+ description: 16-bit jurisdiction input; integrations must agree on its encoding
54
+ source: circuits/credential_validity.circom
55
+ onChainUsage: Used for jurisdiction-specific compliance rules
56
+ isOutput: false
57
+
58
+ - index: 7
59
+ name: credential_commitment
60
+ type: field
61
+ description: Poseidon hash of credential preimage (issuer_did, kyc_tier, sanctions_clear, issued_at, expires_at)
62
+ source: circuits/credential_validity.circom
63
+ onChainUsage: Used for credential binding
64
+ isOutput: false
65
+
66
+ - index: 8
67
+ name: tier2_threshold
68
+ type: uint64
69
+ description: Inclusive lower boundary in USD cents for tier 2
70
+ source: circuits/amount_tier.circom
71
+ onChainUsage: Jurisdiction-configurable threshold
72
+ isOutput: false
73
+
74
+ - index: 9
75
+ name: tier3_threshold
76
+ type: uint64
77
+ description: Inclusive lower boundary in USD cents for tier 3
78
+ source: circuits/amount_tier.circom
79
+ onChainUsage: Jurisdiction-configurable threshold
80
+ isOutput: false
81
+
82
+ - index: 10
83
+ name: tier4_threshold
84
+ type: uint64
85
+ description: Inclusive lower boundary in USD cents for tier 4
86
+ source: circuits/amount_tier.circom
87
+ onChainUsage: Jurisdiction-configurable threshold
88
+ isOutput: false
89
+
90
+ - index: 11
91
+ name: domain_chain_id
92
+ type: uint256
93
+ description: Ethereum chain ID (e.g., 1=mainnet, 11155111=Sepolia)
94
+ source: circuits/compliance.circom
95
+ onChainUsage: Must equal block.chainid
96
+ isOutput: false
97
+
98
+ - index: 12
99
+ name: domain_contract_hash
100
+ type: field
101
+ description: keccak256 of the encoded ComplianceRegistry address reduced modulo the scalar field
102
+ source: circuits/compliance.circom
103
+ onChainUsage: Must equal keccak256(address(this)) % BN128_R
104
+ isOutput: false
105
+
106
+ - index: 13
107
+ name: transfer_id_hash
108
+ type: field
109
+ description: Registry expects keccak256 of encoded transferId reduced modulo the scalar field; API consistency remains open
110
+ source: circuits/compliance.circom
111
+ onChainUsage: Checked against transferId by the registry, alongside duplicate-record and nullifier checks
112
+ isOutput: false
113
+
114
+ - index: 14
115
+ name: credential_nullifier
116
+ type: field
117
+ description: Poseidon(credential_commitment, transfer_id_hash) -- one-time-use value stored on-chain
118
+ source: circuits/compliance.circom
119
+ onChainUsage: Stored in usedNullifiers mapping, checked for uniqueness
120
+ isOutput: false
121
+
122
+ - index: 15
123
+ name: proof_expires_at
124
+ type: uint64
125
+ description: Unix timestamp after which proof is invalid
126
+ source: circuits/compliance.circom
127
+ onChainUsage: Must be >= block.timestamp
128
+ isOutput: false
@@ -0,0 +1,61 @@
1
+ ---
2
+ title: API Reference
3
+ category: reference
4
+ order: 5
5
+ cli-topic: api
6
+ ---
7
+
8
+ # API reference
9
+
10
+ The Python API (FastAPI) is a development component in the source checkout, reviewed September 25, 2026. It is not part of the published npm packages. Use the running application's [local OpenAPI UI](http://localhost:8000/docs) for exact request and response schemas.
11
+
12
+ Protected routes require the configured authentication. Pilot routes also require an authenticated tenant principal with explicit roles and issuer scope; there is no implicit administrator override. PostgreSQL, storage keys and tenant trust configuration are required for the pilot routes. See [deployment](/docs/deployment).
13
+
14
+ ## Pilot routes
15
+
16
+ | Route | Purpose |
17
+ | --- | --- |
18
+ | `POST /pilot/credential/enroll` | Enroll a credential with the holder wallet's signed consent |
19
+ | `POST /pilot/credential/revoke` | Revoke an enrolled credential permanently |
20
+ | `POST /pilot/policy/approve` | Approve a reviewed policy version (activation is a separate step) |
21
+ | `POST /pilot/policy/diff` | Compare a proposed policy against supplied cases |
22
+ | `POST /pilot/policy/diff/stored` | Compare a proposed policy against retained evidence |
23
+ | `POST /pilot/proof/inspect` | Read-only inspection of a current proof against current state; never consumes |
24
+ | `POST /pilot/proof/evaluate` | Explained policy evaluation of a current proof |
25
+ | `POST /pilot/proof/authorize` | Consume one authorization after an `ALLOW`, sealing information to the recipient |
26
+ | `POST /pilot/proof/observe` | Record a non-authorizing observation |
27
+ | `POST /pilot/proof/observations/read`, `/list`, `/report` | Read observations and cohort reports |
28
+ | `POST /pilot/events/ingest` | Ingest signed custody, counterparty or chain events |
29
+ | `POST /pilot/events/investigate` | Transfer investigation timeline |
30
+ | `POST /pilot/events/queue` | Paginated investigation queue |
31
+ | `POST /pilot/fireblocks/{integration_id}` | Verify and retain a signed Fireblocks notification from a tenant relay |
32
+ | `GET /pilot/usage` | Retained record counters (not billable charges) |
33
+
34
+ ## Wallet ownership extension
35
+
36
+ | Route | Purpose |
37
+ | --- | --- |
38
+ | `POST /wallet/ownership/challenge` | Five-minute EOA signing challenge for an enrolled credential |
39
+ | `POST /wallet/ownership/verify` | Verify the EIP-191 signature; issue a 24-hour attestation |
40
+ | `GET /wallet/ownership/attestations/{attestation_id}` | Current attestation eligibility |
41
+ | `POST /wallet/ownership/revoke` | Revoke an attestation |
42
+ | `POST /wallet/ownership/credential` | Issue the optional versioned extension credential |
43
+
44
+ The extension circuit is staged; no deployed verifier accepts it. See the [wallet ownership guide](https://github.com/repfigit/clearproof/blob/main/docs/internal/WALLET_OWNERSHIP.md).
45
+
46
+ ## Shared and legacy routes
47
+
48
+ | Route | Purpose |
49
+ | --- | --- |
50
+ | `GET /health` | Process liveness, not pilot readiness |
51
+ | `GET /metrics` | Operational counters |
52
+ | `GET /.well-known/clearproof.json` | Discovery metadata: exact `did:web` identity and HPKE key |
53
+ | `GET /auth/nonce`, `POST /auth/verify` | SIWE challenge and verification |
54
+ | `POST /credential/issue`, `POST /credential/revoke` | Legacy development credentials |
55
+ | `POST /proof/generate`, `POST /proof/verify` | Legacy 16-signal demo proof generation and verification |
56
+
57
+ The legacy routes serve the demo profile. A legacy proof is never current pilot authorization.
58
+
59
+ ## Limits
60
+
61
+ A successful response is not legal compliance, settlement or a live counterparty's acceptance. Inspection and observation results never authorize a transfer. Only `/pilot/proof/authorize` consumes an authorization, and only after an `ALLOW`. See [architecture](/docs/architecture) and [security](/docs/security).
@@ -0,0 +1,50 @@
1
+ ---
2
+ title: Architecture
3
+ category: concepts
4
+ order: 2
5
+ cli-topic: architecture
6
+ ---
7
+
8
+ # Architecture
9
+
10
+ clearproof combines a Python API with PostgreSQL storage, Circom circuits, TypeScript proof tooling and Solidity contracts. The pilot workflow below is implemented in the source checkout and tested locally with synthetic data and real development proofs. It has not been independently audited or deployed to production.
11
+
12
+ ## Pilot workflow
13
+
14
+ ```mermaid
15
+ flowchart LR
16
+ Enroll[Wallet-signed credential enrollment] --> Roots[Signed issuance, issuer and sanctions roots]
17
+ Roots --> Prove[pilot-transfer-v3 Groth16 proof]
18
+ Policy[Reviewed, active policy] --> Authorize
19
+ Prove --> Authorize[Authorization service: current state + policy ALLOW]
20
+ Authorize --> Seal[Information sealed to recipient's HPKE key]
21
+ Authorize --> Receipt[Consumed receipt in PostgreSQL]
22
+ Receipt --> Mirror[Optional on-chain receipt mirror]
23
+ Seal --> Peer[Counterparty verifies and responds]
24
+ Receipt --> Evidence[Encrypted evidence export for offline review]
25
+ ```
26
+
27
+ ## Responsibilities
28
+
29
+ The **circuit** proves the transfer projection, credential, issuer membership and sanctions non-membership relationships. See [circuits](/docs/circuits).
30
+
31
+ The **authorization service** checks everything the circuit cannot: the current roots and their signatures, credential revocation, the active policy, signed valuation and external facts, and the real proof pairing. Only a policy `ALLOW` can consume an authorization. `DENY`, `REVIEW`, `INDETERMINATE`, invalid pairing and untrusted inputs cannot. On `ALLOW` it seals the approved transfer information to a trusted recipient key and records the evidence, the receipt and the consumed nullifier in one PostgreSQL transaction.
32
+
33
+ The **contract** (`PilotCurrentRegistry`) mirrors receipts that were already consumed, under checkpoints published by a trusted publisher. It checks the chain ID, its own address and the expiry, but it cannot create an authorization or detect a publisher that lies about private records.
34
+
35
+ Read-only inspection and observation never consume an authorization.
36
+
37
+ ## Around the proof
38
+
39
+ - **Policy review:** explained outcomes, stored comparisons of a proposed policy against past cases, and separate approval and activation history.
40
+ - **Investigations:** read-only timelines that join policy, counterparty, custody, chain and evidence events, keeping duplicates, ordering and unresolved conflicts visible.
41
+ - **Historical evidence:** recipient-encrypted exports that an independent reviewer can check offline after the proof expires, using separately configured trust.
42
+ - **Observation mode:** runs alongside an existing workflow and records explained outcomes without authorizing anything.
43
+
44
+ ## Legacy path
45
+
46
+ The original `compliance.circom` profile, `/proof/generate`, `/proof/verify`, the `ComplianceRegistry` contract and the hybrid payload remain as a separate demo and parity path. Their proofs are not current pilot authorization.
47
+
48
+ ## Not yet done
49
+
50
+ Live provider and counterparty interoperability, remote TRP/TRISA conformance, re-screening from an upstream feed, managed distribution, an independent audit and a production setup are separate follow-on gates. See [project status](/docs/status).
@@ -0,0 +1,66 @@
1
+ ---
2
+ title: Circuits
3
+ category: concepts
4
+ order: 3
5
+ cli-topic: circuits
6
+ ---
7
+
8
+ # Circuits
9
+
10
+ clearproof uses Circom and Groth16 over BN254. CI compiles with circom **2.2.2**. These are unaudited development components with development-only proving keys. See [security](/docs/security).
11
+
12
+ There are two proof profiles. **Never select a profile by its signal count.**
13
+
14
+ | Profile | Circuit | Public signals | Status |
15
+ | --- | --- | --- | --- |
16
+ | `pilot-transfer-v3` | `pilot_compliance.circom` | 8 | **Current** pilot profile |
17
+ | `pilot-transfer-v2` / `v1` | same circuit, earlier tree depths or binding | 8 | Historical; current checks reject them |
18
+ | Legacy | `compliance.circom` | 16 | Separate demo and parity path; never current pilot authorization |
19
+
20
+ ## Current profile: pilot-transfer-v3
21
+
22
+ The circuit is instantiated as `PilotCompliance(32, 20, 20)`: an issuance tree of depth 32 (about 4.3 billion credentials per issuer), an authorized-issuer tree of depth 20 and a sanctions tree of depth 20 (1,048,574 addresses plus two boundary leaves). It has 95,408 constraints and needs `2^17` powers-of-tau parameters. The authoritative statement is [`specs/pilot-transfer-v3.md`](https://github.com/repfigit/clearproof/blob/main/specs/pilot-transfer-v3.md).
23
+
24
+ ```text
25
+ PilotCompliance(32, 20, 20)
26
+ ├── PilotTransferProjection 48 private transfer fields, exact valuation, private tier
27
+ ├── PilotCredentialValidity credential, holder secret, issuance and issuer membership
28
+ └── PilotSanctionsGap × 2 raw-address non-membership for originator and beneficiary
29
+ ```
30
+
31
+ ### Public signals
32
+
33
+ | Index | Signal | What the circuit enforces |
34
+ | --- | --- | --- |
35
+ | 0 | `projection_commitment` | Commits to the private transfer projection, the exact credential and the issuance root |
36
+ | 1 | `authorized_issuer_root` | The credential's issuer is a member of this tree |
37
+ | 2 | `sanctions_root` | Neither wallet is in this sorted address tree |
38
+ | 3 | `authorization_nullifier` | Derived from the holder secret and the transfer's authorization scope |
39
+ | 4 | `evaluated_at` | Evaluation time; the credential must be valid at this time |
40
+ | 5 | `proof_expires_at` | Later than `evaluated_at`, and no later than the transfer expiry, the credential expiry or `evaluated_at` + 300 seconds |
41
+ | 6 | `domain_chain_id` | Equals the private deployment field only; the registry checks the real chain |
42
+ | 7 | `domain_registry` | Equals the private deployment field only; the registry checks its own address |
43
+
44
+ The amount, tier, wallets, jurisdiction, participants and credential fields are **private**. There is no public amount tier or review flag. A verifier must reconstruct signal 0 from its own authenticated records; a proof that verifies cryptographically says nothing about which transfer it covers until that check passes.
45
+
46
+ ### What each part checks
47
+
48
+ - **Transfer projection.** All 48 fields are range-checked. Time ordering (observation ≤ creation ≤ evaluation < transfer expiry ≤ quote expiry), maximum age, decimals and nonzero identities are enforced. The amount is converted to USD cents with exact integer arithmetic, and the tier is derived privately from the policy thresholds.
49
+ - **Credential.** The credential commitment must be a member of the issuance root, and the issuer's leaf must be a member of the authorized-issuer root. The holder must know the secret behind the credential's holder commitment. Tenant, subject wallet and jurisdiction must match the transfer.
50
+ - **Sanctions.** A sorted-tree gap proof shows each raw 160-bit wallet address lies strictly between two adjacent leaves. Adjacency is derived from the Merkle path bits, and all compared values are range-checked.
51
+ - **Replay and expiry.** The nullifier stays the same for a given holder and transfer scope, so a replacement proof cannot be spent twice. The five-minute expiry bound is enforced in the circuit.
52
+
53
+ Some acceptance properties live outside the circuit. The authorization service checks current roots, revocation, policy and signed facts, and consumes the nullifier in PostgreSQL. `PilotCurrentRegistry` checks the chain ID, its own address and the expiry against published statements. See [architecture](/docs/architecture).
54
+
55
+ ## Legacy profile
56
+
57
+ `ComplianceProof(20, 10)` in `compliance.circom` publishes 16 values, including `is_compliant`, a tier-derived `sar_review_flag`, the amount tier, the jurisdiction and the tier thresholds. It remains a demo and parity path with its own verifier, SDK function and tests. Legacy proofs are never current pilot authorization.
58
+
59
+ ## Building development artifacts
60
+
61
+ ```bash
62
+ .venv/bin/python scripts/test_development_circuits.py /absolute/new-directory \
63
+ --prepared-ptau /absolute/ppot_0080_17.ptau
64
+ ```
65
+
66
+ This compiles both profiles, creates explicitly unapproved development keys and runs real proof round trips. CI uses the SHA-256-pinned [PSE perpetual powers of tau](https://pse-trusted-setup-ppot.s3.eu-central-1.amazonaws.com/pot28_0080/ppot_0080_17.ptau) file (`f807e065…3a367c`). Without `--prepared-ptau`, a local single-party `2^17` setup is generated, which can take over an hour. Development keys are not production keys; the production setup path is still an open decision (ADR 0004).
@@ -0,0 +1,60 @@
1
+ ---
2
+ title: Smart Contracts
3
+ category: concepts
4
+ order: 4
5
+ cli-topic: contracts
6
+ ---
7
+
8
+ # Smart Contracts
9
+
10
+ The project includes two sets of EVM contracts. The **pilot contracts** verify and mirror current `pilot-transfer-v3` proofs; they exist in source and are tested locally, but are **not deployed** to any shared network. The **legacy contracts** serve the 16-signal demo profile; the Sepolia addresses below are historical testnet records of those. None of these contracts has been independently audited.
11
+
12
+ ## Pilot contracts (source, not deployed)
13
+
14
+ **PilotGroth16Verifier** checks the eight-signal pilot proof against a verification key and artifact manifest digest fixed at construction. It reports `proofProfile` as `pilot-transfer-v3` and `assurance` as `development-unapproved`. Pairing alone does not reconstruct the transfer statement, check current state or consume a nullifier.
15
+
16
+ **PilotCurrentRegistry** publishes tenant checkpoints (revisioned heads for issuance, issuers, sanctions, credential, policy, valuation, participants and authorization) and statement bindings from one assigned publisher per tenant. `inspect` is a read-only call that checks a proof against a published statement, including the chain ID, the registry's own address and the expiry. It then mirrors receipts that PostgreSQL has already consumed. It cannot create an authorization, and it cannot detect a publisher that lies about private records. See the [registry trust boundary](https://github.com/repfigit/clearproof/blob/main/docs/internal/PILOT_CURRENT_REGISTRY.md).
17
+
18
+ ## Legacy contracts: recorded Sepolia deployments
19
+
20
+ The July 20, 2026 manifest records these addresses for the legacy demo profile. Bytecode was present at all five on September 5, 2026. This check does not establish equivalence between every current source change and deployed bytecode.
21
+
22
+ | Contract | Sepolia address |
23
+ | --- | --- |
24
+ | Groth16Verifier | [0x6F8e6f64C5601Eb25716f45C78c9B7C9c0bde8EA](https://sepolia.etherscan.io/address/0x6F8e6f64C5601Eb25716f45C78c9B7C9c0bde8EA#code) |
25
+ | VASPRegistry | [0x99FE2813FD9D66Df43d1ce37d39341F5A7a557F0](https://sepolia.etherscan.io/address/0x99FE2813FD9D66Df43d1ce37d39341F5A7a557F0#code) |
26
+ | SanctionsOracle | [0x2822db7e67E1152a9cC81E44Df2182CA4662c7a2](https://sepolia.etherscan.io/address/0x2822db7e67E1152a9cC81E44Df2182CA4662c7a2#code) |
27
+ | ComplianceRegistry | [0x941F7f188843279C03D1960821B4332A40e806F7](https://sepolia.etherscan.io/address/0x941F7f188843279C03D1960821B4332A40e806F7#code) |
28
+ | SanctionsRootRelay | [0x911d8244F3b63a40040862dB0CC285A753036F87](https://sepolia.etherscan.io/address/0x911d8244F3b63a40040862dB0CC285A753036F87#code) |
29
+
30
+ ## Groth16Verifier
31
+
32
+ Checks cryptographic proof validity against its verification key. That check alone does not establish source authenticity, current state, legal compliance or authorization to execute a transfer. Verifiers and artifacts must match the intended proof version.
33
+
34
+ ## ComplianceRegistry
35
+
36
+ The development registry coordinates proof acceptance with other contracts. Its source checks duplicate transfer records, dependency pause/freshness, active VASP and submitting wallet, chain/contract domain, expiry and future timestamps, sanctions/issuer roots, transfer reference, configured thresholds, revocation and nullifier use. The current development code routes cryptographic verification through a versioned verifier router and configured selector.
37
+
38
+ Successful acceptance records the proof and consumes a nullifier. Read-only cryptographic verification in an SDK is a different operation. A recorded proof is not itself evidence of successful transfer settlement.
39
+
40
+ ## VASPRegistry
41
+
42
+ Stores registered VASPs, authorized submitting wallets, jurisdictions, discovery endpoints and the issuer Merkle root. Registration and directory metadata must be interpreted under an explicit trust policy; they do not independently establish licensing or factual credential validity.
43
+
44
+ ## SanctionsOracle
45
+
46
+ Stores a current root, update time, leaf count and bounded history. Controls include a one-hour update cooldown, a configured staleness window and a leaf-count floor. The history is a ring of up to 1,000 records, not a complete long-term evidence archive.
47
+
48
+ ## SanctionsRootRelay
49
+
50
+ Forwards authorized root updates to the oracle. A local tree rebuild is not evidence that every intended chain received its update.
51
+
52
+ ## Development
53
+
54
+ ```bash
55
+ cd packages/contracts
56
+ npx hardhat compile
57
+ npx hardhat test
58
+ ```
59
+
60
+ Use the ABI and deployment configuration for your exact target. Existing testnet addresses must not be represented as an independently audited production release.
@@ -0,0 +1,36 @@
1
+ ---
2
+ title: GDPR Data-Minimization
3
+ category: concepts
4
+ order: 8
5
+ cli-topic: gdpr
6
+ ---
7
+
8
+ # Privacy and data minimization
9
+
10
+ clearproof explores reducing disclosure by separating verification of specific predicates from encrypted exchange of required personal information. This is an architectural objective, not a GDPR exemption or a compliance certification.
11
+
12
+ ## Encryption and proofs have different roles
13
+
14
+ A proof can establish its encoded statement without exposing every private witness value. Encrypted personal information can travel to an authorized recipient. The recipient may still need to obtain, verify and retain information under applicable requirements.
15
+
16
+ For covered EU crypto transfers, the Transfer of Funds Regulation sets information and missing-information obligations. An amount tier does not define a blanket exemption from those obligations. [EU Regulation 2023/1113, Articles 14–17](https://eur-lex.europa.eu/eli/reg/2023/1113/oj/eng)
17
+
18
+ Encrypted personal data remains personal data. Keeping it off-chain and limiting disclosure must be considered alongside purpose, access, retention and governance. [EDPB Guidelines 02/2025, final version 2, July 7, 2026](https://www.edpb.europa.eu/system/files/2026-07/edpb_guidelines_202502_blockchain_v2_en.pdf)
19
+
20
+ ## What remains visible
21
+
22
+ A current `pilot-transfer-v3` proof publishes eight values: a commitment to the transfer and credential, the authorized-issuer and sanctions roots, a nullifier, the evaluation and expiry times, and the chain and registry it is bound to. The amount, tier, wallets, jurisdiction and participants stay private. See [circuits](/docs/circuits).
23
+
24
+ Commitments, nullifiers and timestamps are still not automatically anonymous. Linking them to other records, on-chain transactions or retained evidence can identify or correlate people. The legacy 16-signal demo circuit publishes more, including an amount tier, jurisdiction and a tier-derived review flag; do not use it where that metadata matters.
25
+
26
+ ## Deployment questions
27
+
28
+ - Which facts actually need a private predicate proof?
29
+ - Which recipient is authorized to receive each piece of information?
30
+ - How are credentials, source data and recipient keys authenticated?
31
+ - What can repeated commitments, timestamps and status checks reveal?
32
+ - How are retention, access, deletion, incident handling and evidence export implemented?
33
+
34
+ Measure disclosure and operational data copying in the intended deployment. Neither encryption, ZK, nor explorer verification independently establishes compliance.
35
+
36
+ Read [current assurance limits](/docs/security).