{"circuit_id":"oidc_domain_attestation","display_name":"OIDC Domain","description":"Prove email domain affiliation via OIDC JWT verification","overview":{"what":"Prove email domain affiliation without disclosing the full email in the public proof.","how":"The SDK takes a Google or Microsoft JWT and scope, fetches JWKS, and sends jwt, jwks, scope and provider to the prover. The prover validates the JWT and builds circuit inputs.","privacy":"HTTPS protects transport, but this prover receives the JWT. Public proof inputs reveal the domain and nullifier."},"e2e_encryption":{"enabled":false,"description":"This deployment provides no hardware TEE attestation. HTTPS protects transport; the prover receives proof inputs.","sdk_usage":"generateProof checks the actual challenge for teePublicKey and encrypts when available."},"local_mcp_server":{"recommended":true,"npm_package":"@zkproofport-ai/mcp","version":"0.3.0","install":"npm install -g @zkproofport-ai/mcp@latest","readme":"https://www.npmjs.com/package/@zkproofport-ai/mcp","required_arguments":["circuit","jwt"],"generate_proof":{"circuit":"oidc_domain","scope":"myapp:membership","jwt":"<existing id_token>","provider":"google"}},"sdk":{"package":"@zkproofport-ai/sdk","repository":"https://github.com/zkproofport/proofport-ai","install":"npm install @zkproofport-ai/sdk@latest ethers","description":"Use generateProof to prepare witnesses, request a challenge, pay using the explicit payment wallet, and encrypt when the deployment supplies a TEE key.","quick_start":"import { createConfig, generateProof } from '@zkproofport-ai/sdk';\n// Existing signer and explicitly selected funded payment wallet stay in local code.\nconst result = await generateProof(\n  createConfig({ baseUrl: 'https://ai.zkproofport.app' }),\n  { attestation: existingAttestationSigner, payment: existingPaymentWallet },\n  { circuit: 'oidc_domain', scope: 'myapp:membership', jwt: existingIdToken, provider: 'google' },\n);","cli":"Use local MCP generate_proof with jwt and provider, or the SDK example. Keep JWTs out of shell history.","payment_selection":"Load PAYMENT_PRIVATE_KEY for pay_with=key, or select an existing Circle/CDP payment wallet. The attestation signer is not a payment fallback."},"constants":{"contracts":{"verifier_address":"0x9677ba46ad226ce8b3c4517d9c0143e4d458beae","chain_id":8453},"payment":{"required":true,"recipient":"0xc5B29033e63A986b601Fe430806A2C9735F2ea97","amount":"100000","asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"base","currency":"USDC","decimals":6,"source":"The first configured offer is shown here for compatibility. Use the live 402 accepts list to select a network."},"rpc":{"verification_rpc_url":"https://base.gateway.tenderly.co"},"x402":{"protocol":"x402 v2; use the selected live offer","chains":[{"network":"eip155:8453","network_name":"base","asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","decimals":6,"settlement":"facilitator","eip712_domain":{"name":"USD Coin","version":"2","chainId":8453,"verifyingContract":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"}},{"network":"eip155:1","network_name":"ethereum","asset":"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48","decimals":6,"settlement":"payee","eip712_domain":{"name":"USD Coin","version":"2","chainId":1,"verifyingContract":"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"}}],"single_step_flow":"POST /api/v1/prove → 402 PAYMENT-REQUIRED and accepts → sign the selected offer → retry with PAYMENT-SIGNATURE. Return X-Payment-Nonce when the challenge supplied one.","nonce_details":"X-Payment-Nonce is single-use and circuit-bound; required with X-Payment-TX. Signed authorization payments also have their own replay protection.","nanopayments":"For arc-testnet-nano, use @circle-fin/x402-batching. Circle Agent Wallet backing EOA signs GatewayWalletBatched; Gateway settles against deposited balance. USDC in the wallet and deposited Gateway balance are separate."},"verification":{"verifier_address":"0x9677ba46ad226ce8b3c4517d9c0143e4d458beae","chain_id":8453,"chain_name":"Base","rpc_url":"https://base.gateway.tenderly.co","function_signature":"verify(bytes proof, bytes32[] publicInputs) external view returns (bool)","input_format":"Keep proof and publicInputs separate; split the publicInputs hex blob into bytes32 words."}},"formulas":{"scope":{"description":"Keccak-256 hash of the scope string. Used to partition nullifiers.","formula":"scope = keccak256(toUtf8Bytes(scope_string))"},"nullifier":{"description":"Prevents double-proving for the same email + scope. Deterministic from email and scope.","formula":"nullifier = keccak256(keccak256(email_bytes) ++ scope_bytes)"},"domain":{"description":"Extracted from email claim in JWT payload (everything after @).","formula":"domain = email.split(\"@\")[1]"},"partial_sha256":{"description":"SHA-256 is precomputed up to the \"email\" key in the JWT payload. The remaining data (containing email value) is passed as circuit input.","formula":"partialHash = SHA256(jwt_signed_data[0..emailKeyOffset])"},"rsa_limbs":{"description":"RSA-2048 values (modulus, signature, redc_params) are split into 18 x 120-bit limbs (little-endian).","formula":"limbs[i] = (value >> (i * 120)) & ((1 << 120) - 1)"}},"input_schema":{"note":"Use generateProof or prepareOidcPayload: the SDK fetches JWKS and sends jwt, jwks, scope and provider. The prover validates the JWT and builds circuit inputs.","client_fields":[{"name":"jwt","type":"string","description":"RS256 id_token from Google or Microsoft containing the required email claims."},{"name":"jwks","type":"object","description":"Issuer JWKS fetched by prepareOidcPayload."},{"name":"scope","type":"string","description":"Application scope string for nullifier partitioning."},{"name":"provider","type":"google | microsoft","description":"Provider matching the JWT issuer; defaults to google in the SDK."}],"server_computed_fields":[{"name":"pubkey_modulus_limbs","description":"18 x u128 RSA public key modulus limbs (from JWKS)"},{"name":"domain","description":"BoundedVec<u8, 64> — email domain bytes"},{"name":"scope","description":"32-byte keccak256(scope_string)"},{"name":"nullifier","description":"32-byte keccak256(keccak256(email) ++ scope)"},{"name":"partial_data","description":"BoundedVec<u8, 640> — remaining JWT data after partial SHA"},{"name":"partial_hash","description":"8 x u32 — intermediate SHA-256 state"},{"name":"full_data_length","description":"Total byte length of JWT signed data"},{"name":"base64_decode_offset","description":"Alignment offset for base64 decoding"},{"name":"redc_params_limbs","description":"18 x u128 Barrett reduction parameter limbs"},{"name":"signature_limbs","description":"18 x u128 RSA signature limbs"}]},"endpoints":{"prove":{"method":"POST","url":"https://ai.zkproofport.app/api/v1/prove","content_type":"application/json","flow":"x402 single-step: POST with {circuit} → 402 with nonce and live offers → pay when required → retry with {circuit, inputs} over HTTPS and payment headers","timeout_hint":"10-30 seconds","description":"Settles the selected payment and generates the proof. Encrypt with teePublicKey when the challenge supplies it; otherwise the prover receives the witness over HTTPS."},"guide":{"method":"GET","url":"https://ai.zkproofport.app/api/v1/guide/oidc_domain_attestation","description":"Returns this guide as JSON (the document you are reading)"}}}