From e39324dbacea8024617c87905921f5dac5547290 Mon Sep 17 00:00:00 2001 From: ais Date: Thu, 30 Apr 2026 10:07:16 +0200 Subject: [PATCH 01/25] solutions/x402 placement --- docs/solutions/finance/index.mdx | 6 ++++++ docs/solutions/finance/x402.mdx | 1 + docs/solutions/overview.mdx | 1 + sidebars.ts | 14 ++++++++++++++ 4 files changed, 22 insertions(+) create mode 100644 docs/solutions/finance/index.mdx create mode 100644 docs/solutions/finance/x402.mdx create mode 100644 docs/solutions/overview.mdx diff --git a/docs/solutions/finance/index.mdx b/docs/solutions/finance/index.mdx new file mode 100644 index 0000000..87d29d0 --- /dev/null +++ b/docs/solutions/finance/index.mdx @@ -0,0 +1,6 @@ +Here's where we guide you through the financial solutions +- payments +- x402 +- yield +- compliance +etc... \ No newline at end of file diff --git a/docs/solutions/finance/x402.mdx b/docs/solutions/finance/x402.mdx new file mode 100644 index 0000000..283c1e9 --- /dev/null +++ b/docs/solutions/finance/x402.mdx @@ -0,0 +1 @@ +Here's a bit about confidential x402 \ No newline at end of file diff --git a/docs/solutions/overview.mdx b/docs/solutions/overview.mdx new file mode 100644 index 0000000..4141725 --- /dev/null +++ b/docs/solutions/overview.mdx @@ -0,0 +1 @@ +Here are some things about our Solutions. They cover the Finance and Identity verticals \ No newline at end of file diff --git a/sidebars.ts b/sidebars.ts index 721c9d9..1c7b405 100644 --- a/sidebars.ts +++ b/sidebars.ts @@ -68,6 +68,20 @@ const sidebars: SidebarsConfig = { "taceo-proof/dev/bestpractice", ], }, + ["solutions/finance/x402"], + ], + }, + { + type: "category", + label: "TACEO Solutions", + link: { type: "doc", id: "solutions/overview" }, + items: [ + { + type: "category", + label: "Finance", + link: { type: "doc", id: "solutions/finance/index" }, + items: ["solutions/finance/x402"], + }, ], }, { From 82f2d8cb96eec6520d55c91b89d3631892417eed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20G=C3=B6tz?= Date: Thu, 30 Apr 2026 14:16:33 +0200 Subject: [PATCH 02/25] added new section x402 --- docs/finance-solutions/overview.mdx | 8 + docs/finance-solutions/x402/how-it-works.mdx | 137 ++++++ .../x402/integration-guide.mdx | 404 ++++++++++++++++++ docs/finance-solutions/x402/introduction.mdx | 78 ++++ .../x402/network-and-contracts.mdx | 87 ++++ .../x402/protocol-reference.mdx | 278 ++++++++++++ docs/finance-solutions/x402/quickstart.mdx | 181 ++++++++ 7 files changed, 1173 insertions(+) create mode 100644 docs/finance-solutions/overview.mdx create mode 100644 docs/finance-solutions/x402/how-it-works.mdx create mode 100644 docs/finance-solutions/x402/integration-guide.mdx create mode 100644 docs/finance-solutions/x402/introduction.mdx create mode 100644 docs/finance-solutions/x402/network-and-contracts.mdx create mode 100644 docs/finance-solutions/x402/protocol-reference.mdx create mode 100644 docs/finance-solutions/x402/quickstart.mdx diff --git a/docs/finance-solutions/overview.mdx b/docs/finance-solutions/overview.mdx new file mode 100644 index 0000000..a273dac --- /dev/null +++ b/docs/finance-solutions/overview.mdx @@ -0,0 +1,8 @@ +Here are some things about our Solutions. They cover the Finance and Identity verticals + +Here's where we guide you through the financial solutions +- payments +- x402 +- yield +- compliance +etc... \ No newline at end of file diff --git a/docs/finance-solutions/x402/how-it-works.mdx b/docs/finance-solutions/x402/how-it-works.mdx new file mode 100644 index 0000000..c7a97ce --- /dev/null +++ b/docs/finance-solutions/x402/how-it-works.mdx @@ -0,0 +1,137 @@ +--- +title: How it works +--- + +# How it works + +A Confidential x402 payment flows through five components. This page describes each component's +role and walks through a full payment end-to-end. + + +## Components + +**Client** — the agent or application making the API request. It holds the secret key to the spending wallet, generates +the ZK proof, and constructs the payment payload. The client library handles all cryptographic +operations; the client application only needs to register the scheme and make HTTP requests as +normal. + +**Resource server** — the API provider. It issues `402 Payment Required` responses, forwards +payment payloads to the facilitator for verification, and serves content on success. Apart from +advertising `scheme: "confidential"` in its payment requirements, it behaves identically to a +standard x402 resource server. + +**Facilitator** — an off-chain service that verifies payment proofs and routes settlements. It +checks the ZK proof, validates the EIP-712 signature, queries the MPC network for balance +sufficiency, and submits the settlement transaction on-chain. TACEO operates a facilitator that can be +used directly. + +**MPC network** — a committee of three operators that collectively hold secret-shared balances. No +single operator ever sees a plaintext balance or payment amount. The network answers +yes/no affordability queries during verification and processes transfers during +settlement. + +**Merces contract** — Stores balances in encryped form (i.e., commitments), verifies +the client's Groth16 proof on-chain during `transferFrom`, enqueues transfer actions for the MPC +network, and verifies the MPC's proof when the balance update is finalised. + +## Sequence diagram + +```mermaid +sequenceDiagram + participant C as Client + participant R as Resource Server + participant F as Facilitator + participant X as Merces Contract + participant M as MPC Network + + + C->>R: GET /api/ + R-->>C: 402 + PaymentRequired (scheme: confidential) + + Note over C: Generate commitment, secret shares,
ciphertexts, EIP-712 signature,
Groth16 proof (~800ms) + + C->>R: GET /api/ + PAYMENT + + R->>F: POST /verify + X-->>F: commitment + Note over F: verify commitment, signature and client proof + F->>M: enough balance? + Signature + M-->>F: yes/no + F-->>R: isValid: true + R->>F: POST /settle + note over F: do verification (as in /verify route) + F-->>R: success: true + R-->>C: 200 + content + F->>X: transferFrom() + Note over X: verify Groth16 proof on-chain via ClientTransferVerifier + X-->>F: action_index + Note over M: read_queue, decrypt, update bal, gen proof + M->>X: processMPC + Note over X: verify proof, update comms +``` + + +## Payment flow + +### Phase 1 — Discovery + +The client sends an unauthenticated HTTP request to a protected endpoint. The resource server +checks its configuration, finds no valid payment attached, and responds with `HTTP 402 Payment +Required`. The response body contains a base64-encoded `PaymentRequired` payload advertising the +`confidential` scheme, the required token and amount, the recipient address, and the MPC network's +current public keys. + +### Phase 2 — Payment construction + +The client builds the payment payload locally. No network calls are required for this step. + +1. Generate a random blinding factor `r`. +2. Compute a **Poseidon2 commitment** to the amount: `commit(amount, r)`. +3. Split the amount into three additive secret shares — one per MPC operator. +4. Encrypt each share to the corresponding operator's BabyJubJub public key using ECDH. +5. Generate a **Groth16 ZK proof** that proves all of the above is consistent: + - The commitment is the hash of the true amount and blinding factor. + - The three shares sum to the committed amount. + - Each share is correctly encrypted to the stated operator key. + - The amount fits in 80 bits. +6. Sign the full payload with **EIP-712** — binding sender, receiver, commitment, ciphertexts, nonce, and deadline. +7. Re-send the original request with a `PAYMENT` header containing the encoded payload. + +### Phase 3 — Verification + +The resource server decodes the payment signature and forwards it to the facilitator's `/verify` +endpoint. The facilitator runs a series of checks: + +- **Schema match** — the accepted scheme matches `"confidential"`. +- **Recipient match** — `payload.to` equals the resource server's address. +- **Deadline** — the payment has not expired. +- **Nonce** — not already used on-chain. +- **Signature** — the EIP-712 signature recovers to the claimed sender. +- **ZK proof** — the Groth16 proof is valid against 15 public signals (sender key, commitment, ciphertexts, MPC keys). +- **Balance** — the facilitator queries all three MPC nodes; they collectively confirm the sender holds sufficient funds without revealing the balance to anyone. + +If all checks pass, the facilitator returns `{ valid: true }` to the resource server. + +### Phase 4 — Content delivery & settlement + +On a valid response, the resource server immediately returns `HTTP 200` with the requested content. +Settlement is asynchronous — the client already has its response. + +The resource server then calls the facilitator's `/settle` endpoint. The facilitator calls +`transferFrom()` on the Merces contract, passing the proof and ciphertexts. The contract verifies +the proof on-chain and enqueues a transfer action. + +The MPC network picks up the queued action, decrypts the secret shares to recover the actual +amount, verifies the commitment, updates both parties' balance commitments, and generates a second +ZK proof that the update is correct. It calls `processMPC()` on the contract, which verifies the +proof and commits the new balance state. + + +## Performance + +| Operation | Cost | +|---|---| +| Proof generation (client) | ~800ms | +| Off-chain proof verification (facilitator) | ~13ms | +| On-chain proof verification | ~300,000 gas | + diff --git a/docs/finance-solutions/x402/integration-guide.mdx b/docs/finance-solutions/x402/integration-guide.mdx new file mode 100644 index 0000000..38c330c --- /dev/null +++ b/docs/finance-solutions/x402/integration-guide.mdx @@ -0,0 +1,404 @@ +--- +sidebar_position: 4 +title: Integration guide +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +# Integration guide + +This page covers integrating the confidential payment scheme into your own client application and +API server. If you just want to run a quick end-to-end test using TACEO's hosted infrastructure, +start with the [Quickstart](../quickstart) instead. + +## Install + + + + +```bash +npm install @taceolabs/taceo-merces1-x402-js @x402/fetch viem +``` + + + + +```toml +[dependencies] +taceo-merces1-x402 = "1.0" +x402-reqwest = "1.4" +x402-axum = "1.4" +reqwest = { version = "0.13", default-features = false, features = ["json", "rustls"] } +alloy = { version = "2", default-features = false, features = ["signers", "primitives"] } +axum = "0.8" +tokio = { version = "1", features = ["macros", "rt-multi-thread"] } +``` + + + + +--- + +## Client + +The client library intercepts any `402 Payment Required` response, constructs the ZK proof and +signed payment payload, and retries the request automatically. Your application code makes a +normal HTTP request — the payment is invisible to it. + +### Register the scheme + + + + +```typescript +import { privateKeyToAccount } from 'viem/accounts'; +import { x402Client, wrapFetchWithPayment } from '@x402/fetch'; +import { ConfidentialEvmScheme } from '@taceolabs/taceo-merces1-x402-js/client'; + +const signer = privateKeyToAccount(process.env.PRIVATE_KEY as `0x${string}`); + +const client = new x402Client(); +client.register('eip155:*', new ConfidentialEvmScheme(signer)); + +export const fetchWithPayment = wrapFetchWithPayment(fetch, client); +``` + +`fetchWithPayment` is a drop-in replacement for `fetch`. Use it anywhere you would normally +call `fetch`. + + + + +```rust +use alloy::signers::local::PrivateKeySigner; +use reqwest::Client; +use taceo_merces1_x402::V2Eip155ConfidentialClient; +use x402_reqwest::{ReqwestWithPayments, ReqwestWithPaymentsBuild, X402Client}; + +let signer: PrivateKeySigner = std::env::var("PRIVATE_KEY")?.parse()?; + +let x402_client = X402Client::new() + .register(V2Eip155ConfidentialClient::new(signer)); + +let http_client = Client::new() + .with_payments(x402_client) + .build(); +``` + +`http_client` is a drop-in replacement for `reqwest::Client`. + + + + +### Make a payment-gated request + + + + +```typescript +const response = await fetchWithPayment( + 'https://api.example.com/api/premium-data', + { method: 'GET' } +); + +if (response.ok) { + const data = await response.json(); + console.log(data); +} +``` + + + + +```rust +let response = http_client + .get("https://api.example.com/api/premium-data") + .send() + .await?; + +println!("Status: {}", response.status()); +println!("Body: {}", response.text().await?); +``` + + + + +When the server responds with `402`, the client handles it invisibly: parses the `PaymentRequired` +payload, generates the Groth16 ZK proof (~800ms), retries the request with a `PAYMENT-SIGNATURE` +header, and returns the final `200 OK` to your code. + +### Restrict to specific networks + +By default, the scheme registers for all EIP-155 chains (`eip155:*`). To restrict to a specific +chain: + + + + +```typescript +import { registerConfidentialEvmScheme } from '@taceolabs/taceo-merces1-x402-js/client'; + +registerConfidentialEvmScheme(client, { + signer, + networks: ['eip155:84532'], // Base Sepolia only +}); +``` + + + + +The Rust client selects the scheme based on the `network` field in the server's `PaymentRequired` +response. No additional configuration is needed to restrict by chain. + + + + +### Check your private balance + +Your Merces balance is secret-shared across three MPC nodes and never appears on-chain in +plaintext. The client queries all three nodes and reconstructs the balance locally. + + + + +```typescript +import { Client } from '@taceolabs/taceo-merces1-client-js'; +import { createWalletClient, createPublicClient, http } from 'viem'; +import { baseSepolia } from 'viem/chains'; +import { privateKeyToAccount } from 'viem/accounts'; + +const account = privateKeyToAccount(process.env.PRIVATE_KEY as `0x${string}`); + +const merces = new Client({ + nodeUrls: [ + 'https://node0.merces.taceo.io', + 'https://node1.merces.taceo.io', + 'https://node2.merces.taceo.io', + ], + contractAddress: '0xTODO', + token: { type: 'ERC20', address: '0xTODO' }, + walletClient: createWalletClient({ account, chain: baseSepolia, transport: http() }), + publicClient: createPublicClient({ chain: baseSepolia, transport: http() }), +}); + +const balance = await merces.getPrivateBalance(); +console.log('Private balance:', balance.toString()); +``` + + + + +Balance queries are handled internally by the facilitator during payment verification. Direct +balance reads are not exposed in the current Rust client — use the TypeScript client or the +faucet API if you need to inspect balances during development. + + + + +:::info Funding your wallet +Use the [faucet](../quickstart/#step-2--get-test-tokens-from-the-faucet) to top up your Merces balance with test tokens. +::: + +### Error handling + + + + +```typescript +import { + InsufficientBalanceError, + ProofError, +} from '@taceolabs/taceo-merces1-client-js'; + +try { + const response = await fetchWithPayment(url, { method: 'GET' }); +} catch (err) { + if (err instanceof InsufficientBalanceError) { + console.error('Top up your Merces balance via the faucet.'); + } else if (err instanceof ProofError) { + console.error('ZK proof generation failed:', err.message); + } else { + throw err; + } +} +``` + + + + +```rust +match http_client.get(url).send().await { + Ok(response) => println!("Status: {}", response.status()), + Err(e) => eprintln!("Payment or request failed: {e}"), +} +``` + + + + +--- + +## Server + +The server middleware intercepts incoming requests, returns `402 Payment Required` when no valid +payment is attached, and verifies the payment against the TACEO facilitator before forwarding the +request to your handler. + +### Basic example + +The following examples protect a single route at `GET /api/protected` and price it at $1 of +confidential USDC. + + + + +```typescript +import express from 'express'; +import { paymentMiddleware, x402ResourceServer } from '@x402/express'; +import { HTTPFacilitatorClient } from '@x402/core/server'; +import { ConfidentialEvmScheme } from '@taceolabs/taceo-merces1-x402-js/server'; + +const app = express(); + +const facilitatorClient = new HTTPFacilitatorClient({ + url: 'https://facilitator.merces.taceo.io', +}); + +app.use( + paymentMiddleware( + { + 'GET /api/protected': { + accepts: [ + { + scheme: 'confidential', + price: '$1', + network: 'eip155:84532', + payTo: process.env.WALLET_ADDRESS as `0x${string}`, + }, + ], + }, + }, + new x402ResourceServer(facilitatorClient).register( + 'eip155:84532', + new ConfidentialEvmScheme({ asset: process.env.TOKEN_ADDRESS as string }) + ) + ) +); + +app.get('/api/protected', (req, res) => { + res.json({ message: 'Payment verified. Here is your data.' }); +}); + +app.listen(8081, () => console.log('Listening on http://localhost:8081')); +``` + + + + +```rust +use std::str::FromStr; +use alloy::primitives::Address; +use axum::{Router, routing::get, response::IntoResponse, http::StatusCode}; +use taceo_merces1_x402::{ConfidentialUSDC, V2Eip155Confidential}; +use x402_axum::X402Middleware; + +#[tokio::main] +async fn main() -> eyre::Result<()> { + let pay_to = Address::from_str(&std::env::var("WALLET_ADDRESS")?)?; + let facilitator_url = std::env::var("FACILITATOR_URL") + .unwrap_or("https://facilitator.merces.taceo.io".to_string()); + + let usdc = ConfidentialUSDC::base_sepolia(); + let x402 = X402Middleware::new(&facilitator_url); + + let app = Router::new().route( + "/api/protected", + get(handler).layer( + x402.with_price_tag( + V2Eip155Confidential::price_tag(pay_to, usdc.parse("$1")?) + ), + ), + ); + + let listener = tokio::net::TcpListener::bind("0.0.0.0:8081").await?; + println!("Listening on http://0.0.0.0:8081"); + axum::serve(listener, app).await?; + + Ok(()) +} + +async fn handler() -> impl IntoResponse { + (StatusCode::OK, "Payment verified. Here is your data.") +} +``` + + + + +### How the middleware works + +When a request arrives without a valid `PAYMENT-SIGNATURE` header: + +1. The middleware returns `HTTP 402 Payment Required` with a base64-encoded `PaymentRequired` + payload containing the scheme, required amount, your wallet address, and the MPC public keys + (fetched from the facilitator's `/supported` endpoint). +2. When the client retries with a payment, the middleware forwards it to the facilitator's + `/verify` endpoint. +3. If verification succeeds, the request is forwarded to your handler. +4. After your handler responds, the middleware calls `/settle` asynchronously. Your handler is + not blocked by settlement. + +### Protecting multiple routes + + + + +```typescript +app.use( + paymentMiddleware( + { + 'GET /api/basic': { accepts: [{ scheme: 'confidential', price: '$0.10', network: 'eip155:84532', payTo: address }] }, + 'GET /api/premium': { accepts: [{ scheme: 'confidential', price: '$5.00', network: 'eip155:84532', payTo: address }] }, + 'POST /api/action': { accepts: [{ scheme: 'confidential', price: '$1.00', network: 'eip155:84532', payTo: address }] }, + }, + resourceServer + ) +); +``` + + + + +```rust +let app = Router::new() + .route("/api/basic", + get(basic_handler).layer( + x402.with_price_tag(V2Eip155Confidential::price_tag(pay_to, usdc.parse("$0.10")?)) + ) + ) + .route("/api/premium", + get(premium_handler).layer( + x402.with_price_tag(V2Eip155Confidential::price_tag(pay_to, usdc.parse("$5.00")?)) + ) + ); +``` + + + + +### Configuration reference + +| Parameter | Description | +|---|---| +| `scheme` | Must be `"confidential"` | +| `price` | Required payment amount, e.g. `"$1"`, `"$0.50"` | +| `network` | CAIP-2 chain ID, e.g. `"eip155:84532"` for Base Sepolia | +| `payTo` | Your wallet address that receives payments | +| `asset` | Token contract address (provided by the TACEO facilitator automatically) | +| Facilitator URL | `https://facilitator.merces.taceo.io` for TACEO's hosted facilitator | + +:::info Receiving payments +Payments are credited to your `payTo` address as confidential Merces balance. To withdraw tokens +back to a regular ERC-20 balance, use the `withdraw` function in the Merces client library. +::: diff --git a/docs/finance-solutions/x402/introduction.mdx b/docs/finance-solutions/x402/introduction.mdx new file mode 100644 index 0000000..baa5158 --- /dev/null +++ b/docs/finance-solutions/x402/introduction.mdx @@ -0,0 +1,78 @@ +--- +title: Introduction +--- + +# Confidential x402 + +Confidential x402 is a privacy extension to the x402 payment protocol that +hides payment amounts from public view while keeping the full payment flow on-chain and verifiable. + +:::info What is x402? +x402 is an open HTTP payment protocol for machine-to-machine payments. A resource server responds +with HTTP `402 Payment Required` when a request lacks a valid payment. The client attaches a +signed payment to its next request, the server verifies it, and access is granted. +See the [x402 documentation](https://x402.org) for the full protocol specification. +::: + +## The problem with public payments + +Standard x402 settles payments as plain ERC-20 token transfers — every amount is visible on-chain. +This works for flat-rate APIs, but breaks down the moment pricing becomes dynamic: + +- **Competitors can read your pricing strategy off the blockchain.** Every `transferWithAuthorization` + call exposes exactly what each customer paid. +- **Per-customer deals are impossible to keep confidential.** Volume discounts, enterprise rates, + and promotional pricing are all public record. +- **AI agents reveal their economic strategy.** Spending patterns across API providers expose which + data sources an agent values by much budget it allocates. + +## How Confidential x402 addresses this + +Confidential x402 introduces a `confidential` payment scheme built on top of +[Merces](https://core.taceo.io/articles/merces-onchain-finance/), TACEO's confidential token +transfer system. Instead of transferring a plaintext amount, the client: + +1. Commits to the payment amount using a Poseidon2 cryptographic commitment. +2. Secret-shares the amount across a network of MPC operators, encrypted to their public keys. +3. Generates a Groth16 ZK proof that the commitment and ciphertexts are consistent. +4. Signs the payload with EIP-712 for replay protection. + +The on-chain contract verifies the proof and updates balance commitments — without any plaintext +amount ever appearing on-chain. The MPC network holds balances as secret shares, so no single +party learns what anyone has or spends. + + +## Get started + +To run a full x402 confidential payment cycle TACEO operates all required components: + +| Component | Description | +|---|---| +| **Resource server** | Endpoint that responds with a x402 payment request when called | +| **MPC network** | 3-party network that secret-shares balances and processes transfers | +| **Facilitator** | Off-chain service that verifies payment proofs and settles transactions | +| **Merces contract** | Holds balance commitments and verifies ZK proofs on-chain | +| **Faucet** | Funds new wallets with test tokens so that clients can start paying immediately | + + +See [Network & Contracts](../network-and-contracts) for addresses and endpoints. + +## Privacy assumptions + +Confidential x402 hides **payment amounts** and **account balances**. It does not hide sender or +receiver addresses, payment frequency, or the sender–receiver relationship. For a full privacy +analysis, see [Privacy & Trust Model](../protocol-reference/#privacy--trust-model). + +:::info[Private Payments] +The current payment model is built on confidential transfers i.e., intentionally leaking the involved wallet addresses. +An upgrade to **fully private payments** is planned in upcoming versions of the protocol +::: + +## Where to go next + +| Goal | Start here | +|---|---| +| Understand how the system works before writing code | [How it works](../how-it-works) | +| Run a payment end-to-end right now | [Quickstart](../quickstart) | +| Add the confidential scheme to your own client & server | [Integration guide](../integration-guide) | +| Look up message schemas and ZK circuit details | [Protocol reference](../protocol-reference) | diff --git a/docs/finance-solutions/x402/network-and-contracts.mdx b/docs/finance-solutions/x402/network-and-contracts.mdx new file mode 100644 index 0000000..6f4378e --- /dev/null +++ b/docs/finance-solutions/x402/network-and-contracts.mdx @@ -0,0 +1,87 @@ +--- +sidebar_position: 6 +title: Network & contracts +--- + +# Network & contracts + +All Confidential x402 infrastructure is currently deployed on **Base Sepolia** (chain ID 84532). +This is a testnet environment intended for development and integration testing. + +:::warning Testnet only +The current deployment uses test tokens with no real-world value. Do not use mainnet private keys +or real funds. +::: + +## Deployed contracts + +| Contract | Address | +|---|---| +| Merces Contract | `0xTODO` | +| Confidential USDC token | `0xTODO` | + +Contract source code is available in the +[merces1-x402 GitHub repository](https://github.com/TaceoLabs/merces1-x402). + +## TACEO-hosted endpoints + +| Service | URL | +|---|---| +| Faucet | `https://faucet.merces.taceo.io` | +| Facilitator | `https://facilitator.merces.taceo.io` | +| Resource server (test) | `https://resource.merces.taceo.io` | +| MPC node 0 | `https://node0.merces.taceo.io` | +| MPC node 1 | `https://node1.merces.taceo.io` | +| MPC node 2 | `https://node2.merces.taceo.io` | + +## Chain details + +| Parameter | Value | +|---|---| +| Network name | Base Sepolia | +| Chain ID | `84532` | +| CAIP-2 identifier | `eip155:84532` | +| Block explorer | [https://sepolia.basescan.org](https://sepolia.basescan.org) | +| Public RPC | `https://sepolia.base.org` | + +## Faucet API + +The faucet funds a new Merces wallet with 1,000 test tokens. Each address is limited to one +claim per 24 hours. + +**Endpoint:** `POST /claim/{address}` + +```bash +curl -X POST https://faucet.merces.taceo.io/claim/0xYourWalletAddress +``` + +**Responses:** + +| Status | Meaning | +|---|---| +| `200 OK` | Tokens deposited successfully | +| `429 Too Many Requests` | Address already claimed within the last 24 hours | +| `500 Internal Server Error` | Faucet encountered an error — try again shortly | + +## MPC public keys + +The BabyJubJub public keys of the three MPC operators are published by the facilitator's +`/supported` endpoint and injected into every `PaymentRequired` response automatically. You do +not need to configure them manually. + +To fetch them directly: + +```bash +curl https://facilitator.merces.taceo.io/supported +``` + +The response includes the current MPC public keys alongside the supported scheme, network, and +contract address. + +## Support + +For questions, issues, or integration help: + +- **Discord:** [taceo.io/discord](https://taceo.io/discord) +- **GitHub:** [github.com/TaceoLabs/merces1-x402](https://github.com/TaceoLabs/merces1-x402) +- **Email:** [hello@taceo.io](mailto:hello@taceo.io) diff --git a/docs/finance-solutions/x402/protocol-reference.mdx b/docs/finance-solutions/x402/protocol-reference.mdx new file mode 100644 index 0000000..6daadc2 --- /dev/null +++ b/docs/finance-solutions/x402/protocol-reference.mdx @@ -0,0 +1,278 @@ +--- +sidebar_position: 5 +title: Protocol reference +--- + +# Protocol reference + +This page documents the wire format for each message in the Confidential x402 protocol, the ZK +circuit, and the privacy and trust model. + +--- + +## Payment schemas + +### PaymentRequired (402 response) + +The resource server encodes this object as base64 and sends it in the body of its `402` response. + +```json +{ + "x402Version": 2, + "resource": { + "url": "/api/premium-data", + "description": "Premium data endpoint" + }, + "accepts": [ + { + "scheme": "confidential", + "network": "eip155:84532", + "amount": "1000000", + "asset": "0xUSDC...", + "payTo": "0xResourceServer...", + "maxTimeoutSeconds": 300, + "extra": { + "confidentialToken": "0xMercesContract...", + "eip712Domain": { + "name": "Merces", + "version": "1" + }, + "mpcPks": [ + ["", ""], + ["", ""], + ["", ""] + ] + } + } + ] +} +``` + +| Field | Type | Description | +|---|---|---| +| `x402Version` | `number` | Always `2` | +| `scheme` | `string` | Always `"confidential"` | +| `network` | `string` | CAIP-2 chain identifier, e.g. `"eip155:84532"` | +| `amount` | `string` | Required payment in token base units (e.g. USDC with 6 decimals) | +| `asset` | `string` | ERC-20 token contract address | +| `payTo` | `string` | Resource server's receiving wallet address | +| `maxTimeoutSeconds` | `number` | Maximum age of a valid payment signature in seconds | +| `extra.confidentialToken` | `string` | Merces contract address | +| `extra.eip712Domain` | `object` | EIP-712 domain name and version for signing | +| `extra.mpcPks` | `[[x,y], ...]` | BabyJubJub public keys of the three MPC operators | + +### PaymentPayload (client → server) + +The client encodes this object as base64 and sends it in the `PAYMENT-SIGNATURE` header of its +retried request. + +```json +{ + "x402Version": 2, + "resource": { "url": "/api/premium-data" }, + "accepted": { + "scheme": "confidential", + "network": "eip155:84532", + "amount": "1000000", + "asset": "0xUSDC...", + "payTo": "0xResourceServer...", + "maxTimeoutSeconds": 300, + "extra": { "...": "..." } + }, + "payload": { + "signature": "0x", + "authorization": { + "from": "0xClient...", + "to": "0xResourceServer...", + "amountCommitment": "", + "beta": "", + "ciphertexts": ["", "", "", "", "", ""], + "senderPk": ["", ""], + "nonce": "0x<32-bytes>", + "deadline": "", + "proof": { + "pi_a": ["", "", "1"], + "pi_b": [["", ""], ["", ""], ["1", "0"]], + "pi_c": ["", "", "1"] + } + } + } +} +``` + +| Field | Type | Description | +|---|---|---| +| `payload.signature` | `0x...` | EIP-712 signature over the authorization struct | +| `authorization.from` | `address` | Client's wallet address (token owner) | +| `authorization.to` | `address` | Resource server's wallet address (recipient) | +| `authorization.amountCommitment` | `Fr` | Poseidon2 commitment to `(amount, blindingFactor)` | +| `authorization.beta` | `Fr` | Public input derived during proof generation | +| `authorization.ciphertexts` | `Fr[6]` | Six BN254 field elements: two encrypted shares per MPC operator | +| `authorization.senderPk` | `[x, y]` | Ephemeral BabyJubJub public key used for ECDH encryption | +| `authorization.nonce` | `bytes32` | Unique 32-byte nonce for replay protection | +| `authorization.deadline` | `uint` | Unix timestamp after which the signature is invalid | +| `authorization.proof` | `Groth16Proof` | Groth16 proof in snarkjs format | + +### EIP-712 typed data + +The client signs the following typed data. The `verifyingContract` is the Merces contract address +provided in `extra.confidentialToken`. + +```json +{ + "domain": { + "name": "Merces", + "version": "1", + "chainId": 84532, + "verifyingContract": "0xMercesContract..." + }, + "types": { + "TransferFromAuthorization": [ + { "name": "sender", "type": "address" }, + { "name": "receiver", "type": "address" }, + { "name": "amountCommitment", "type": "uint256" }, + { "name": "ciphertextHash", "type": "bytes32" }, + { "name": "beta", "type": "uint256" }, + { "name": "nonce", "type": "uint256" }, + { "name": "deadline", "type": "uint256" } + ] + }, + "primaryType": "TransferFromAuthorization" +} +``` + +`ciphertextHash` is `keccak256(abi.encode(ciphertexts, senderPk))`. + +### Facilitator API + +#### POST /verify + +Called by the resource server before serving content. + +**Request:** + +```json +{ + "x402Version": 2, + "paymentPayload": { "...": "..." }, + "paymentRequirements": { "...": "..." } +} +``` + +**Response (success):** + +```json +{ "isValid": true, "payer": "0xClient..." } +``` + +**Response (failure):** + +```json +{ "isValid": false, "invalidReason": "insufficient_funds" } +``` + +#### POST /settle + +Called by the resource server after content has been served. + +**Request:** Same structure as `/verify`. + +**Response:** + +```json +{ + "success": true, + "transaction": "0xTxHash...", + "network": "eip155:84532" +} +``` + +### ZK circuit + +The Groth16 proof is generated over the BN254 curve and proves four simultaneous claims: + +| Claim | Description | +|---|---| +| Commitment correctness | `amountCommitment = Poseidon2([amount, blindingFactor])` | +| Share validity | Three additive shares sum to `amount` modulo the BN254 scalar field order | +| Encryption correctness | Each share is correctly encrypted to the stated MPC operator key via BabyJubJub ECDH | +| Range | `amount` fits in 80 bits | + +**Public inputs (15 elements):** + +| Index | Value | +|---|---| +| 0 | `beta` | +| 1–2 | `senderPk.x`, `senderPk.y` | +| 3 | `amountCommitment` | +| 4–9 | `ciphertexts[0..5]` | +| 10–11 | `mpcPk[0].x`, `mpcPk[0].y` | +| 12–13 | `mpcPk[1].x`, `mpcPk[1].y` | +| 14–15 | `mpcPk[2].x`, `mpcPk[2].y` | + +**Private inputs:** `amount`, `blindingFactor`, three plaintext shares, three blinding shares, +BabyJubJub ephemeral secret key. + +--- + +## Privacy & trust model + +### What is protected + +| Data | Standard x402 | Confidential x402 | How | +|---|---|---|---| +| Transfer amounts | Plaintext in `transferWithAuthorization` | Poseidon2 commitment on-chain | Real amount secret-shared across MPC network | +| Account balances | Public via ERC-20 `balanceOf()` | Only a commitment stored on-chain | Actual balances held as secret shares by MPC operators | +| Spending patterns | Full payment history enables behaviour profiling | Observers can count payments but cannot sum amounts | Amounts hidden; only frequency and counterparties visible | +| Price discrimination evidence | On-chain proof of what each user paid | No on-chain evidence of negotiated price | Resource server holds client payment data off-chain | + +### What is not protected + +**On-chain:** + +| Leaked data | Source | Impact | +|---|---|---| +| Sender address | `ActionQuery.sender` | Anyone can see who sends payments | +| Receiver address | `ActionQuery.receiver` | Anyone can see who receives payments | +| Payment frequency and timing | `transferFrom()` call events | Observers can count API calls and when they occur | +| Nonce consumption | `usedNonces` mapping | Number of nonces reveals payment count per sender | +| Sender–receiver graph | Aggregated from all transfers | Can map which clients use which APIs | + +**HTTP layer:** + +| Leaked data | Who can see it | +|---|---| +| Required payment amount | Resource server (sets it); transmitted over TLS to client | +| API endpoint path | Resource server, facilitator | +| Client wallet address | Resource server, facilitator | + +The amount in the `PaymentRequired` response is visible to the client over TLS but is not written +to the blockchain. A passive observer without TLS access cannot learn the amount. + +### Trust model + +**MPC network** + +Privacy of payment amounts and balances depends on the MPC operators not colluding. The current +deployment uses **3-of-3 additive secret sharing**: all three operators must cooperate to +reconstruct any amount or balance. If even one operator is honest, no amount is revealed. +TACEO operates all three nodes in the current testnet deployment. + +**Facilitator** + +The facilitator is a **liveness dependency, not a privacy dependency**. It can refuse to verify +or settle payments, and it can observe which addresses are paying which resource servers. It +cannot learn payment amounts or balances, forge valid proofs or signatures, or steal funds. + +**Merces contract** + +The contract is the trust anchor for correctness. It verifies the client's Groth16 proof before +enqueuing any transfer, verifies the MPC's proof before committing balance updates, and enforces +nonce uniqueness and deadline expiry. + + +### Roadmap to stronger privacy + +The current `confidential` scheme hides amounts and balances. Sender and receiver addresses remain +visible on-chain. Future versions will include an enhanced variant that additionally hide +the sender–receiver relationship, building on Merces' existing support for fully private transactions. diff --git a/docs/finance-solutions/x402/quickstart.mdx b/docs/finance-solutions/x402/quickstart.mdx new file mode 100644 index 0000000..9abf736 --- /dev/null +++ b/docs/finance-solutions/x402/quickstart.mdx @@ -0,0 +1,181 @@ +--- +sidebar_position: 3 +title: Quickstart +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +# Quickstart + +This guide gets you making a confidential payment in under five minutes using TACEO's hosted +infrastructure — no contract deployment, no facilitator setup required. + +You will: +1. Fund a new wallet with test tokens from the faucet. +2. Send a request to the TACEO resource server. +3. Watch the payment go through automatically. + +## Prerequisites + +- Node.js 18+ (TypeScript) or Rust 1.90+ (Rust) +- A wallet private key (or generate one — instructions below) + +## Step 1 — Install the package + + + + +```bash +npm install @taceolabs/taceo-merces1-x402-js +``` + + + + +Add the following to your `Cargo.toml`: + +```toml +[dependencies] +taceo-merces1-x402 = "1.0" +tokio = { version = "1", features = ["macros", "rt-multi-thread"] } +alloy = { version = "2", default-features = false, features = ["signers"] } +``` + + + + +## Step 2 — Get test tokens from the faucet + +Each new wallet needs to be funded before it can make confidential payments. The faucet deposits +1,000 test tokens and enforces a 24-hour cooldown per address. + +```bash +curl -X POST https://faucet.merces.taceo.io/claim/ +``` + +Replace `` with your Ethereum wallet address. If you don't have one yet, +generate a throwaway key: + + + + +```typescript +import { privateKeyToAccount, generatePrivateKey } from 'viem/accounts'; + +const privateKey = generatePrivateKey(); +const account = privateKeyToAccount(privateKey); + +console.log('Private key:', privateKey); +console.log('Address:', account.address); +``` + + + + +```rust +use alloy::signers::local::PrivateKeySigner; + +let signer = PrivateKeySigner::random(); +println!("Private key: {}", signer.credential().to_bytes().to_string()); +println!("Address: {}", signer.address()); +``` + + + + +:::warning Keep your private key safe +Even on testnet, never commit private keys to source control. Use environment variables or a +secrets manager. +::: + +## Step 3 — Send a confidential payment + +The client library intercepts the `402 Payment Required` response, constructs the proof, and +retries the request automatically. Your application code makes a normal HTTP GET — the payment +is invisible to it. + + + + +```typescript +import { privateKeyToAccount } from 'viem/accounts'; +import { x402Client, wrapFetchWithPayment } from '@x402/fetch'; +import { ConfidentialEvmScheme } from '@taceolabs/taceo-merces1-x402-js/client'; + +const privateKey = process.env.PRIVATE_KEY as `0x${string}`; +const signer = privateKeyToAccount(privateKey); + +// Register the confidential scheme +const client = new x402Client(); +client.register('eip155:*', new ConfidentialEvmScheme(signer)); + +// Wrap fetch — payments are handled automatically +const fetchWithPayment = wrapFetchWithPayment(fetch, client); + +// Make the request as normal +const response = await fetchWithPayment( + 'https://resource.merces.taceo.io/api/protected', + { method: 'GET' } +); + +console.log('Status:', response.status); +console.log('Body:', await response.text()); +``` + + + + +```rust +use alloy::signers::local::PrivateKeySigner; +use reqwest::Client; +use taceo_merces1_x402::V2Eip155ConfidentialClient; +use x402_reqwest::{ReqwestWithPayments, ReqwestWithPaymentsBuild, X402Client}; + +#[tokio::main] +async fn main() -> eyre::Result<()> { + let private_key = std::env::var("PRIVATE_KEY")?; + let signer: PrivateKeySigner = private_key.parse()?; + + // Register the confidential scheme + let x402_client = X402Client::new() + .register(V2Eip155ConfidentialClient::new(signer)); + + // Wrap reqwest — payments are handled automatically + let http_client = Client::new() + .with_payments(x402_client) + .build(); + + // Make the request as normal + let response = http_client + .get("https://resource.merces.taceo.io/api/protected") + .send() + .await?; + + println!("Status: {}", response.status()); + println!("Body: {}", response.text().await?); + + Ok(()) +} +``` + + + + +## What happens under the hood + +When `fetchWithPayment` (or the wrapped `reqwest` client) receives a `402` response: + +1. It reads the `PaymentRequired` payload from the response body. +2. The `ConfidentialEvmScheme` generates a Groth16 ZK proof (~800ms) and constructs the signed + payment payload. +3. The original request is retried with a `PAYMENT-SIGNATURE` header. +4. The TACEO resource server forwards the payment to the TACEO facilitator for verification. +5. On success, the server returns `200 OK` with the response body. +6. Settlement happens asynchronously in the background. + +## Next steps + +- **Understand the full protocol in detail** → [How it works](../how-it-works) +- **Add confidential x402 payments to your own API** → [Integration guide](../integration-guide) + From 9c5e25307c3913be0dc29f4e675cf908a36ea423 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20G=C3=B6tz?= Date: Mon, 4 May 2026 13:02:21 +0200 Subject: [PATCH 03/25] adding missing files --- .vscode/settings.json | 2 + docs/solutions/finance/index.mdx | 6 - docs/solutions/finance/x402.mdx | 1 - docs/solutions/overview.mdx | 1 - docusaurus.config.ts | 14 + package-lock.json | 1482 ++++++++++++++++++++++++++++-- package.json | 2 + sidebars.ts | 18 +- 8 files changed, 1420 insertions(+), 106 deletions(-) create mode 100644 .vscode/settings.json delete mode 100644 docs/solutions/finance/index.mdx delete mode 100644 docs/solutions/finance/x402.mdx delete mode 100644 docs/solutions/overview.mdx diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..7a73a41 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,2 @@ +{ +} \ No newline at end of file diff --git a/docs/solutions/finance/index.mdx b/docs/solutions/finance/index.mdx deleted file mode 100644 index 87d29d0..0000000 --- a/docs/solutions/finance/index.mdx +++ /dev/null @@ -1,6 +0,0 @@ -Here's where we guide you through the financial solutions -- payments -- x402 -- yield -- compliance -etc... \ No newline at end of file diff --git a/docs/solutions/finance/x402.mdx b/docs/solutions/finance/x402.mdx deleted file mode 100644 index 283c1e9..0000000 --- a/docs/solutions/finance/x402.mdx +++ /dev/null @@ -1 +0,0 @@ -Here's a bit about confidential x402 \ No newline at end of file diff --git a/docs/solutions/overview.mdx b/docs/solutions/overview.mdx deleted file mode 100644 index 4141725..0000000 --- a/docs/solutions/overview.mdx +++ /dev/null @@ -1 +0,0 @@ -Here are some things about our Solutions. They cover the Finance and Identity verticals \ No newline at end of file diff --git a/docusaurus.config.ts b/docusaurus.config.ts index 49242f3..5d808df 100644 --- a/docusaurus.config.ts +++ b/docusaurus.config.ts @@ -24,6 +24,10 @@ const config: Config = { onBrokenLinks: "throw", onBrokenMarkdownLinks: "throw", + markdown: { + mermaid: true, + }, + scripts: [ { src: "https://cdn.matomo.cloud/taceo.matomo.cloud/container_v2uCJC8k.js", @@ -37,6 +41,7 @@ const config: Config = { plugins: [ require.resolve("docusaurus-lunr-search"), + require.resolve("docusaurus-plugin-image-zoom"), [ require.resolve("@docusaurus/plugin-client-redirects"), { @@ -51,6 +56,8 @@ const config: Config = { ], ], + themes: ['@docusaurus/theme-mermaid'], + // Even if you don't use internationalization, you can use this field to set // useful metadata like html lang. For example, if your site is Chinese, you // may want to replace "en" with "zh-Hans". @@ -182,6 +189,13 @@ const config: Config = { theme: prismThemes.github, darkTheme: prismThemes.dracula, }, + zoom: { + selector: '.markdown img, .docusaurus-mermaid-container svg', + background: { + light: 'rgb(255, 255, 255)', + dark: 'rgb(50, 50, 50)', + }, + }, } satisfies Preset.ThemeConfig, }; diff --git a/package-lock.json b/package-lock.json index 469df3c..e49156c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,10 +14,12 @@ "@docusaurus/core": "3.8.1", "@docusaurus/plugin-client-redirects": "^3.8.1", "@docusaurus/preset-classic": "3.8.1", + "@docusaurus/theme-mermaid": "^3.8.1", "@mdx-js/react": "^3.1.0", "algoliasearch": "^5.34.1", "clsx": "^2.0.0", "docusaurus-lunr-search": "^3.6.0", + "docusaurus-plugin-image-zoom": "^3.0.1", "prism-react-renderer": "^2.3.0", "react": "^18.0.0", "react-dom": "^18.0.0", @@ -301,6 +303,19 @@ "node": ">= 14.0.0" } }, + "node_modules/@antfu/install-pkg": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@antfu/install-pkg/-/install-pkg-1.1.0.tgz", + "integrity": "sha512-MGQsmw10ZyI+EJo45CdSER4zEb+p31LpDAFp2Z3gkSd1yqVZGi0Ebx++YTEMonJy4oChEMLsxZ64j8FH6sSqtQ==", + "license": "MIT", + "dependencies": { + "package-manager-detector": "^1.3.0", + "tinyexec": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, "node_modules/@babel/code-frame": { "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", @@ -2001,6 +2016,49 @@ "node": ">=6.9.0" } }, + "node_modules/@braintree/sanitize-url": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/@braintree/sanitize-url/-/sanitize-url-7.1.2.tgz", + "integrity": "sha512-jigsZK+sMF/cuiB7sERuo9V7N9jx+dhmHHnQyDSVdpZwVutaBu7WvNYqMDLSgFgfB30n452TP3vjDAvFC973mA==", + "license": "MIT" + }, + "node_modules/@chevrotain/cst-dts-gen": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/@chevrotain/cst-dts-gen/-/cst-dts-gen-12.0.0.tgz", + "integrity": "sha512-fSL4KXjTl7cDgf0B5Rip9Q05BOrYvkJV/RrBTE/bKDN096E4hN/ySpcBK5B24T76dlQ2i32Zc3PAE27jFnFrKg==", + "license": "Apache-2.0", + "dependencies": { + "@chevrotain/gast": "12.0.0", + "@chevrotain/types": "12.0.0" + } + }, + "node_modules/@chevrotain/gast": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/@chevrotain/gast/-/gast-12.0.0.tgz", + "integrity": "sha512-1ne/m3XsIT8aEdrvT33so0GUC+wkctpUPK6zU9IlOyJLUbR0rg4G7ZiApiJbggpgPir9ERy3FRjT6T7lpgetnQ==", + "license": "Apache-2.0", + "dependencies": { + "@chevrotain/types": "12.0.0" + } + }, + "node_modules/@chevrotain/regexp-to-ast": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/@chevrotain/regexp-to-ast/-/regexp-to-ast-12.0.0.tgz", + "integrity": "sha512-p+EW9MaJwgaHguhoqwOtx/FwuGr+DnNn857sXWOi/mClXIkPGl3rn7hGNWvo31HA3vyeQxjqe+H36yZJwYU8cA==", + "license": "Apache-2.0" + }, + "node_modules/@chevrotain/types": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/@chevrotain/types/-/types-12.0.0.tgz", + "integrity": "sha512-S+04vjFQKeuYw0/eW3U52LkAHQsB1ASxsPGsLPUyQgrZ2iNNibQrsidruDzjEX2JYfespXMG0eZmXlhA6z7nWA==", + "license": "Apache-2.0" + }, + "node_modules/@chevrotain/utils": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/@chevrotain/utils/-/utils-12.0.0.tgz", + "integrity": "sha512-lB59uJoaGIfOOL9knQqQRfhl9g7x8/wqFkp13zTdkRu1huG9kg6IJs1O8hqj9rs6h7orGxHJUKb+mX3rPbWGhA==", + "license": "Apache-2.0" + }, "node_modules/@colors/colors": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", @@ -3869,6 +3927,28 @@ "react-dom": "^18.0.0 || ^19.0.0" } }, + "node_modules/@docusaurus/theme-mermaid": { + "version": "3.8.1", + "resolved": "https://registry.npmjs.org/@docusaurus/theme-mermaid/-/theme-mermaid-3.8.1.tgz", + "integrity": "sha512-IWYqjyTPjkNnHsFFu9+4YkeXS7PD1xI3Bn2shOhBq+f95mgDfWInkpfBN4aYvx4fTT67Am6cPtohRdwh4Tidtg==", + "license": "MIT", + "dependencies": { + "@docusaurus/core": "3.8.1", + "@docusaurus/module-type-aliases": "3.8.1", + "@docusaurus/theme-common": "3.8.1", + "@docusaurus/types": "3.8.1", + "@docusaurus/utils-validation": "3.8.1", + "mermaid": ">=11.6.0", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=18.0" + }, + "peerDependencies": { + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + } + }, "node_modules/@docusaurus/theme-search-algolia": { "version": "3.8.1", "resolved": "https://registry.npmjs.org/@docusaurus/theme-search-algolia/-/theme-search-algolia-3.8.1.tgz", @@ -4034,6 +4114,23 @@ "@hapi/hoek": "^9.0.0" } }, + "node_modules/@iconify/types": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@iconify/types/-/types-2.0.0.tgz", + "integrity": "sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==", + "license": "MIT" + }, + "node_modules/@iconify/utils": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@iconify/utils/-/utils-3.1.1.tgz", + "integrity": "sha512-MwzoDtw9rO1x+qfgLTV/IVXsHDBqeYZoMIQC8SfxfYSlaSUG+oWiAcoiB1yajAda6mqblm4/1/w2E8tRu7a7Tw==", + "license": "MIT", + "dependencies": { + "@antfu/install-pkg": "^1.1.0", + "@iconify/types": "^2.0.0", + "mlly": "^1.8.2" + } + }, "node_modules/@jest/schemas": { "version": "29.6.3", "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", @@ -4178,6 +4275,15 @@ "react": ">=16" } }, + "node_modules/@mermaid-js/parser": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@mermaid-js/parser/-/parser-1.1.0.tgz", + "integrity": "sha512-gxK9ZX2+Fex5zu8LhRQoMeMPEHbc73UKZ0FQ54YrQtUxE1VVhMwzeNtKRPAu5aXks4FasbMe4xB4bWrmq6Jlxw==", + "license": "MIT", + "dependencies": { + "langium": "^4.0.0" + } + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -4626,6 +4732,259 @@ "@types/node": "*" } }, + "node_modules/@types/d3": { + "version": "7.4.3", + "resolved": "https://registry.npmjs.org/@types/d3/-/d3-7.4.3.tgz", + "integrity": "sha512-lZXZ9ckh5R8uiFVt8ogUNf+pIrK4EsWrx2Np75WvF/eTpJ0FMHNhjXk8CKEx/+gpHbNQyJWehbFaTvqmHWB3ww==", + "license": "MIT", + "dependencies": { + "@types/d3-array": "*", + "@types/d3-axis": "*", + "@types/d3-brush": "*", + "@types/d3-chord": "*", + "@types/d3-color": "*", + "@types/d3-contour": "*", + "@types/d3-delaunay": "*", + "@types/d3-dispatch": "*", + "@types/d3-drag": "*", + "@types/d3-dsv": "*", + "@types/d3-ease": "*", + "@types/d3-fetch": "*", + "@types/d3-force": "*", + "@types/d3-format": "*", + "@types/d3-geo": "*", + "@types/d3-hierarchy": "*", + "@types/d3-interpolate": "*", + "@types/d3-path": "*", + "@types/d3-polygon": "*", + "@types/d3-quadtree": "*", + "@types/d3-random": "*", + "@types/d3-scale": "*", + "@types/d3-scale-chromatic": "*", + "@types/d3-selection": "*", + "@types/d3-shape": "*", + "@types/d3-time": "*", + "@types/d3-time-format": "*", + "@types/d3-timer": "*", + "@types/d3-transition": "*", + "@types/d3-zoom": "*" + } + }, + "node_modules/@types/d3-array": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.2.2.tgz", + "integrity": "sha512-hOLWVbm7uRza0BYXpIIW5pxfrKe0W+D5lrFiAEYR+pb6w3N2SwSMaJbXdUfSEv+dT4MfHBLtn5js0LAWaO6otw==", + "license": "MIT" + }, + "node_modules/@types/d3-axis": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@types/d3-axis/-/d3-axis-3.0.6.tgz", + "integrity": "sha512-pYeijfZuBd87T0hGn0FO1vQ/cgLk6E1ALJjfkC0oJ8cbwkZl3TpgS8bVBLZN+2jjGgg38epgxb2zmoGtSfvgMw==", + "license": "MIT", + "dependencies": { + "@types/d3-selection": "*" + } + }, + "node_modules/@types/d3-brush": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@types/d3-brush/-/d3-brush-3.0.6.tgz", + "integrity": "sha512-nH60IZNNxEcrh6L1ZSMNA28rj27ut/2ZmI3r96Zd+1jrZD++zD3LsMIjWlvg4AYrHn/Pqz4CF3veCxGjtbqt7A==", + "license": "MIT", + "dependencies": { + "@types/d3-selection": "*" + } + }, + "node_modules/@types/d3-chord": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@types/d3-chord/-/d3-chord-3.0.6.tgz", + "integrity": "sha512-LFYWWd8nwfwEmTZG9PfQxd17HbNPksHBiJHaKuY1XeqscXacsS2tyoo6OdRsjf+NQYeB6XrNL3a25E3gH69lcg==", + "license": "MIT" + }, + "node_modules/@types/d3-color": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-3.1.3.tgz", + "integrity": "sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==", + "license": "MIT" + }, + "node_modules/@types/d3-contour": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@types/d3-contour/-/d3-contour-3.0.6.tgz", + "integrity": "sha512-BjzLgXGnCWjUSYGfH1cpdo41/hgdWETu4YxpezoztawmqsvCeep+8QGfiY6YbDvfgHz/DkjeIkkZVJavB4a3rg==", + "license": "MIT", + "dependencies": { + "@types/d3-array": "*", + "@types/geojson": "*" + } + }, + "node_modules/@types/d3-delaunay": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-delaunay/-/d3-delaunay-6.0.4.tgz", + "integrity": "sha512-ZMaSKu4THYCU6sV64Lhg6qjf1orxBthaC161plr5KuPHo3CNm8DTHiLw/5Eq2b6TsNP0W0iJrUOFscY6Q450Hw==", + "license": "MIT" + }, + "node_modules/@types/d3-dispatch": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/@types/d3-dispatch/-/d3-dispatch-3.0.7.tgz", + "integrity": "sha512-5o9OIAdKkhN1QItV2oqaE5KMIiXAvDWBDPrD85e58Qlz1c1kI/J0NcqbEG88CoTwJrYe7ntUCVfeUl2UJKbWgA==", + "license": "MIT" + }, + "node_modules/@types/d3-drag": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/@types/d3-drag/-/d3-drag-3.0.7.tgz", + "integrity": "sha512-HE3jVKlzU9AaMazNufooRJ5ZpWmLIoc90A37WU2JMmeq28w1FQqCZswHZ3xR+SuxYftzHq6WU6KJHvqxKzTxxQ==", + "license": "MIT", + "dependencies": { + "@types/d3-selection": "*" + } + }, + "node_modules/@types/d3-dsv": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/@types/d3-dsv/-/d3-dsv-3.0.7.tgz", + "integrity": "sha512-n6QBF9/+XASqcKK6waudgL0pf/S5XHPPI8APyMLLUHd8NqouBGLsU8MgtO7NINGtPBtk9Kko/W4ea0oAspwh9g==", + "license": "MIT" + }, + "node_modules/@types/d3-ease": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-ease/-/d3-ease-3.0.2.tgz", + "integrity": "sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==", + "license": "MIT" + }, + "node_modules/@types/d3-fetch": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/@types/d3-fetch/-/d3-fetch-3.0.7.tgz", + "integrity": "sha512-fTAfNmxSb9SOWNB9IoG5c8Hg6R+AzUHDRlsXsDZsNp6sxAEOP0tkP3gKkNSO/qmHPoBFTxNrjDprVHDQDvo5aA==", + "license": "MIT", + "dependencies": { + "@types/d3-dsv": "*" + } + }, + "node_modules/@types/d3-force": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@types/d3-force/-/d3-force-3.0.10.tgz", + "integrity": "sha512-ZYeSaCF3p73RdOKcjj+swRlZfnYpK1EbaDiYICEEp5Q6sUiqFaFQ9qgoshp5CzIyyb/yD09kD9o2zEltCexlgw==", + "license": "MIT" + }, + "node_modules/@types/d3-format": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-format/-/d3-format-3.0.4.tgz", + "integrity": "sha512-fALi2aI6shfg7vM5KiR1wNJnZ7r6UuggVqtDA+xiEdPZQwy/trcQaHnwShLuLdta2rTymCNpxYTiMZX/e09F4g==", + "license": "MIT" + }, + "node_modules/@types/d3-geo": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@types/d3-geo/-/d3-geo-3.1.0.tgz", + "integrity": "sha512-856sckF0oP/diXtS4jNsiQw/UuK5fQG8l/a9VVLeSouf1/PPbBE1i1W852zVwKwYCBkFJJB7nCFTbk6UMEXBOQ==", + "license": "MIT", + "dependencies": { + "@types/geojson": "*" + } + }, + "node_modules/@types/d3-hierarchy": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/@types/d3-hierarchy/-/d3-hierarchy-3.1.7.tgz", + "integrity": "sha512-tJFtNoYBtRtkNysX1Xq4sxtjK8YgoWUNpIiUee0/jHGRwqvzYxkq0hGVbbOGSz+JgFxxRu4K8nb3YpG3CMARtg==", + "license": "MIT" + }, + "node_modules/@types/d3-interpolate": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz", + "integrity": "sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==", + "license": "MIT", + "dependencies": { + "@types/d3-color": "*" + } + }, + "node_modules/@types/d3-path": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.1.1.tgz", + "integrity": "sha512-VMZBYyQvbGmWyWVea0EHs/BwLgxc+MKi1zLDCONksozI4YJMcTt8ZEuIR4Sb1MMTE8MMW49v0IwI5+b7RmfWlg==", + "license": "MIT" + }, + "node_modules/@types/d3-polygon": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-polygon/-/d3-polygon-3.0.2.tgz", + "integrity": "sha512-ZuWOtMaHCkN9xoeEMr1ubW2nGWsp4nIql+OPQRstu4ypeZ+zk3YKqQT0CXVe/PYqrKpZAi+J9mTs05TKwjXSRA==", + "license": "MIT" + }, + "node_modules/@types/d3-quadtree": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@types/d3-quadtree/-/d3-quadtree-3.0.6.tgz", + "integrity": "sha512-oUzyO1/Zm6rsxKRHA1vH0NEDG58HrT5icx/azi9MF1TWdtttWl0UIUsjEQBBh+SIkrpd21ZjEv7ptxWys1ncsg==", + "license": "MIT" + }, + "node_modules/@types/d3-random": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/d3-random/-/d3-random-3.0.3.tgz", + "integrity": "sha512-Imagg1vJ3y76Y2ea0871wpabqp613+8/r0mCLEBfdtqC7xMSfj9idOnmBYyMoULfHePJyxMAw3nWhJxzc+LFwQ==", + "license": "MIT" + }, + "node_modules/@types/d3-scale": { + "version": "4.0.9", + "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.9.tgz", + "integrity": "sha512-dLmtwB8zkAeO/juAMfnV+sItKjlsw2lKdZVVy6LRr0cBmegxSABiLEpGVmSJJ8O08i4+sGR6qQtb6WtuwJdvVw==", + "license": "MIT", + "dependencies": { + "@types/d3-time": "*" + } + }, + "node_modules/@types/d3-scale-chromatic": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@types/d3-scale-chromatic/-/d3-scale-chromatic-3.1.0.tgz", + "integrity": "sha512-iWMJgwkK7yTRmWqRB5plb1kadXyQ5Sj8V/zYlFGMUBbIPKQScw+Dku9cAAMgJG+z5GYDoMjWGLVOvjghDEFnKQ==", + "license": "MIT" + }, + "node_modules/@types/d3-selection": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/@types/d3-selection/-/d3-selection-3.0.11.tgz", + "integrity": "sha512-bhAXu23DJWsrI45xafYpkQ4NtcKMwWnAC/vKrd2l+nxMFuvOT3XMYTIj2opv8vq8AO5Yh7Qac/nSeP/3zjTK0w==", + "license": "MIT" + }, + "node_modules/@types/d3-shape": { + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.1.8.tgz", + "integrity": "sha512-lae0iWfcDeR7qt7rA88BNiqdvPS5pFVPpo5OfjElwNaT2yyekbM0C9vK+yqBqEmHr6lDkRnYNoTBYlAgJa7a4w==", + "license": "MIT", + "dependencies": { + "@types/d3-path": "*" + } + }, + "node_modules/@types/d3-time": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.4.tgz", + "integrity": "sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g==", + "license": "MIT" + }, + "node_modules/@types/d3-time-format": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@types/d3-time-format/-/d3-time-format-4.0.3.tgz", + "integrity": "sha512-5xg9rC+wWL8kdDj153qZcsJ0FWiFt0J5RB6LYUNZjwSnesfblqrI/bJ1wBdJ8OQfncgbJG5+2F+qfqnqyzYxyg==", + "license": "MIT" + }, + "node_modules/@types/d3-timer": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-timer/-/d3-timer-3.0.2.tgz", + "integrity": "sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==", + "license": "MIT" + }, + "node_modules/@types/d3-transition": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/@types/d3-transition/-/d3-transition-3.0.9.tgz", + "integrity": "sha512-uZS5shfxzO3rGlu0cC3bjmMFKsXv+SmZZcgp0KD22ts4uGXp5EVYGzu/0YdwZeKmddhcAccYtREJKkPfXkZuCg==", + "license": "MIT", + "dependencies": { + "@types/d3-selection": "*" + } + }, + "node_modules/@types/d3-zoom": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/@types/d3-zoom/-/d3-zoom-3.0.8.tgz", + "integrity": "sha512-iqMC4/YlFCSlO8+2Ii1GGGliCAY4XdeG748w5vQUbevlbDu0zSjH/+jojorQVBK/se0j6DUFNPBGSqD3YWYnDw==", + "license": "MIT", + "dependencies": { + "@types/d3-interpolate": "*", + "@types/d3-selection": "*" + } + }, "node_modules/@types/debug": { "version": "4.1.12", "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", @@ -4706,6 +5065,12 @@ "@types/send": "*" } }, + "node_modules/@types/geojson": { + "version": "7946.0.16", + "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.16.tgz", + "integrity": "sha512-6C8nqWur3j98U6+lXDfTUWIfgvZU+EumvpHKcYjujKH7woYyLj2sUmff0tRhrqM7BohUw7Pz3ZB1jj2gW9Fvmg==", + "license": "MIT" + }, "node_modules/@types/gtag.js": { "version": "0.0.12", "resolved": "https://registry.npmjs.org/@types/gtag.js/-/gtag.js-0.0.12.tgz", @@ -4954,6 +5319,13 @@ "@types/node": "*" } }, + "node_modules/@types/trusted-types": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz", + "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==", + "license": "MIT", + "optional": true + }, "node_modules/@types/unist": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", @@ -4990,6 +5362,16 @@ "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==", "license": "ISC" }, + "node_modules/@upsetjs/venn.js": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@upsetjs/venn.js/-/venn.js-2.0.0.tgz", + "integrity": "sha512-WbBhLrooyePuQ1VZxrJjtLvTc4NVfpOyKx0sKqioq9bX1C1m7Jgykkn8gLrtwumBioXIqam8DLxp88Adbue6Hw==", + "license": "MIT", + "optionalDependencies": { + "d3-selection": "^3.0.0", + "d3-transition": "^3.0.1" + } + }, "node_modules/@webassemblyjs/ast": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz", @@ -5198,9 +5580,9 @@ } }, "node_modules/acorn": { - "version": "8.15.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", - "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", + "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", "license": "MIT", "bin": { "acorn": "bin/acorn" @@ -6081,6 +6463,34 @@ "url": "https://github.com/sponsors/fb55" } }, + "node_modules/chevrotain": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/chevrotain/-/chevrotain-12.0.0.tgz", + "integrity": "sha512-csJvb+6kEiQaqo1woTdSAuOWdN0WTLIydkKrBnS+V5gZz0oqBrp4kQ35519QgK6TpBThiG3V1vNSHlIkv4AglQ==", + "license": "Apache-2.0", + "dependencies": { + "@chevrotain/cst-dts-gen": "12.0.0", + "@chevrotain/gast": "12.0.0", + "@chevrotain/regexp-to-ast": "12.0.0", + "@chevrotain/types": "12.0.0", + "@chevrotain/utils": "12.0.0" + }, + "engines": { + "node": ">=22.0.0" + } + }, + "node_modules/chevrotain-allstar": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/chevrotain-allstar/-/chevrotain-allstar-0.4.2.tgz", + "integrity": "sha512-J3WoNdejJDlmUR0XXgmJK2GnCYKp2eWHnaG1fGkvnBVQw9Y6piP4Q30ETz47bfvPTeaN/DV0V5jqLDgX4PCygg==", + "license": "MIT", + "dependencies": { + "lodash-es": "^4.18.1" + }, + "peerDependencies": { + "chevrotain": "^12.0.0" + } + }, "node_modules/chokidar": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", @@ -6381,6 +6791,12 @@ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", "license": "MIT" }, + "node_modules/confbox": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.8.tgz", + "integrity": "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==", + "license": "MIT" + }, "node_modules/config-chain": { "version": "1.1.13", "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz", @@ -6593,6 +7009,15 @@ "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", "license": "MIT" }, + "node_modules/cose-base": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/cose-base/-/cose-base-1.0.3.tgz", + "integrity": "sha512-s9whTXInMSgAp/NVXVNuVxVKzGH2qck3aQlVHxDCdAEPgtMKwc4Wq6/QKhgdEdgbLSi9rBTAcPoRa6JpiG4ksg==", + "license": "MIT", + "dependencies": { + "layout-base": "^1.0.0" + } + }, "node_modules/cosmiconfig": { "version": "8.3.6", "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz", @@ -6985,103 +7410,629 @@ "engines": { "node": "^14 || ^16 || >=18.0" }, - "peerDependencies": { - "postcss": "^8.4.31" + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/cssnano-preset-default": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-6.1.2.tgz", + "integrity": "sha512-1C0C+eNaeN8OcHQa193aRgYexyJtU8XwbdieEjClw+J9d94E41LwT6ivKH0WT+fYwYWB0Zp3I3IZ7tI/BbUbrg==", + "license": "MIT", + "dependencies": { + "browserslist": "^4.23.0", + "css-declaration-sorter": "^7.2.0", + "cssnano-utils": "^4.0.2", + "postcss-calc": "^9.0.1", + "postcss-colormin": "^6.1.0", + "postcss-convert-values": "^6.1.0", + "postcss-discard-comments": "^6.0.2", + "postcss-discard-duplicates": "^6.0.3", + "postcss-discard-empty": "^6.0.3", + "postcss-discard-overridden": "^6.0.2", + "postcss-merge-longhand": "^6.0.5", + "postcss-merge-rules": "^6.1.1", + "postcss-minify-font-values": "^6.1.0", + "postcss-minify-gradients": "^6.0.3", + "postcss-minify-params": "^6.1.0", + "postcss-minify-selectors": "^6.0.4", + "postcss-normalize-charset": "^6.0.2", + "postcss-normalize-display-values": "^6.0.2", + "postcss-normalize-positions": "^6.0.2", + "postcss-normalize-repeat-style": "^6.0.2", + "postcss-normalize-string": "^6.0.2", + "postcss-normalize-timing-functions": "^6.0.2", + "postcss-normalize-unicode": "^6.1.0", + "postcss-normalize-url": "^6.0.2", + "postcss-normalize-whitespace": "^6.0.2", + "postcss-ordered-values": "^6.0.2", + "postcss-reduce-initial": "^6.1.0", + "postcss-reduce-transforms": "^6.0.2", + "postcss-svgo": "^6.0.3", + "postcss-unique-selectors": "^6.0.4" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/cssnano-utils": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-4.0.2.tgz", + "integrity": "sha512-ZR1jHg+wZ8o4c3zqf1SIUSTIvm/9mU343FMR6Obe/unskbvpGhZOo1J6d/r8D1pzkRQYuwbcH3hToOuoA2G7oQ==", + "license": "MIT", + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/csso": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/csso/-/csso-5.0.5.tgz", + "integrity": "sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==", + "license": "MIT", + "dependencies": { + "css-tree": "~2.2.0" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/csso/node_modules/css-tree": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.2.1.tgz", + "integrity": "sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==", + "license": "MIT", + "dependencies": { + "mdn-data": "2.0.28", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/csso/node_modules/mdn-data": { + "version": "2.0.28", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.28.tgz", + "integrity": "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==", + "license": "CC0-1.0" + }, + "node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", + "license": "MIT" + }, + "node_modules/cytoscape": { + "version": "3.33.3", + "resolved": "https://registry.npmjs.org/cytoscape/-/cytoscape-3.33.3.tgz", + "integrity": "sha512-Gej7U+OKR+LZ8kvX7rb2HhCYJ0IhvEFsnkud4SB1PR+BUY/TsSO0dmOW59WEVLu51b1Rm+gQRKoz4bLYxGSZ2g==", + "license": "MIT", + "engines": { + "node": ">=0.10" + } + }, + "node_modules/cytoscape-cose-bilkent": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cytoscape-cose-bilkent/-/cytoscape-cose-bilkent-4.1.0.tgz", + "integrity": "sha512-wgQlVIUJF13Quxiv5e1gstZ08rnZj2XaLHGoFMYXz7SkNfCDOOteKBE6SYRfA9WxxI/iBc3ajfDoc6hb/MRAHQ==", + "license": "MIT", + "dependencies": { + "cose-base": "^1.0.0" + }, + "peerDependencies": { + "cytoscape": "^3.2.0" + } + }, + "node_modules/cytoscape-fcose": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cytoscape-fcose/-/cytoscape-fcose-2.2.0.tgz", + "integrity": "sha512-ki1/VuRIHFCzxWNrsshHYPs6L7TvLu3DL+TyIGEsRcvVERmxokbf5Gdk7mFxZnTdiGtnA4cfSmjZJMviqSuZrQ==", + "license": "MIT", + "dependencies": { + "cose-base": "^2.2.0" + }, + "peerDependencies": { + "cytoscape": "^3.2.0" + } + }, + "node_modules/cytoscape-fcose/node_modules/cose-base": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cose-base/-/cose-base-2.2.0.tgz", + "integrity": "sha512-AzlgcsCbUMymkADOJtQm3wO9S3ltPfYOFD5033keQn9NJzIbtnZj+UdBJe7DYml/8TdbtHJW3j58SOnKhWY/5g==", + "license": "MIT", + "dependencies": { + "layout-base": "^2.0.0" + } + }, + "node_modules/cytoscape-fcose/node_modules/layout-base": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/layout-base/-/layout-base-2.0.1.tgz", + "integrity": "sha512-dp3s92+uNI1hWIpPGH3jK2kxE2lMjdXdr+DH8ynZHpd6PUlH6x6cbuXnoMmiNumznqaNO31xu9e79F0uuZ0JFg==", + "license": "MIT" + }, + "node_modules/d3": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/d3/-/d3-7.9.0.tgz", + "integrity": "sha512-e1U46jVP+w7Iut8Jt8ri1YsPOvFpg46k+K8TpCb0P+zjCkjkPnV7WzfDJzMHy1LnA+wj5pLT1wjO901gLXeEhA==", + "license": "ISC", + "dependencies": { + "d3-array": "3", + "d3-axis": "3", + "d3-brush": "3", + "d3-chord": "3", + "d3-color": "3", + "d3-contour": "4", + "d3-delaunay": "6", + "d3-dispatch": "3", + "d3-drag": "3", + "d3-dsv": "3", + "d3-ease": "3", + "d3-fetch": "3", + "d3-force": "3", + "d3-format": "3", + "d3-geo": "3", + "d3-hierarchy": "3", + "d3-interpolate": "3", + "d3-path": "3", + "d3-polygon": "3", + "d3-quadtree": "3", + "d3-random": "3", + "d3-scale": "4", + "d3-scale-chromatic": "3", + "d3-selection": "3", + "d3-shape": "3", + "d3-time": "3", + "d3-time-format": "4", + "d3-timer": "3", + "d3-transition": "3", + "d3-zoom": "3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-array": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz", + "integrity": "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==", + "license": "ISC", + "dependencies": { + "internmap": "1 - 2" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-axis": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-axis/-/d3-axis-3.0.0.tgz", + "integrity": "sha512-IH5tgjV4jE/GhHkRV0HiVYPDtvfjHQlQfJHs0usq7M30XcSBvOotpmH1IgkcXsO/5gEQZD43B//fc7SRT5S+xw==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-brush": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-brush/-/d3-brush-3.0.0.tgz", + "integrity": "sha512-ALnjWlVYkXsVIGlOsuWH1+3udkYFI48Ljihfnh8FZPF2QS9o+PzGLBslO0PjzVoHLZ2KCVgAM8NVkXPJB2aNnQ==", + "license": "ISC", + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-drag": "2 - 3", + "d3-interpolate": "1 - 3", + "d3-selection": "3", + "d3-transition": "3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-chord": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-chord/-/d3-chord-3.0.1.tgz", + "integrity": "sha512-VE5S6TNa+j8msksl7HwjxMHDM2yNK3XCkusIlpX5kwauBfXuyLAtNg9jCp/iHH61tgI4sb6R/EIMWCqEIdjT/g==", + "license": "ISC", + "dependencies": { + "d3-path": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-color": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz", + "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-contour": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/d3-contour/-/d3-contour-4.0.2.tgz", + "integrity": "sha512-4EzFTRIikzs47RGmdxbeUvLWtGedDUNkTcmzoeyg4sP/dvCexO47AaQL7VKy/gul85TOxw+IBgA8US2xwbToNA==", + "license": "ISC", + "dependencies": { + "d3-array": "^3.2.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-delaunay": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/d3-delaunay/-/d3-delaunay-6.0.4.tgz", + "integrity": "sha512-mdjtIZ1XLAM8bm/hx3WwjfHt6Sggek7qH043O8KEjDXN40xi3vx/6pYSVTwLjEgiXQTbvaouWKynLBiUZ6SK6A==", + "license": "ISC", + "dependencies": { + "delaunator": "5" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-dispatch": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-3.0.1.tgz", + "integrity": "sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-drag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-3.0.0.tgz", + "integrity": "sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==", + "license": "ISC", + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-selection": "3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-dsv": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-dsv/-/d3-dsv-3.0.1.tgz", + "integrity": "sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q==", + "license": "ISC", + "dependencies": { + "commander": "7", + "iconv-lite": "0.6", + "rw": "1" + }, + "bin": { + "csv2json": "bin/dsv2json.js", + "csv2tsv": "bin/dsv2dsv.js", + "dsv2dsv": "bin/dsv2dsv.js", + "dsv2json": "bin/dsv2json.js", + "json2csv": "bin/json2dsv.js", + "json2dsv": "bin/json2dsv.js", + "json2tsv": "bin/json2dsv.js", + "tsv2csv": "bin/dsv2dsv.js", + "tsv2json": "bin/dsv2json.js" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-dsv/node_modules/commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, + "node_modules/d3-dsv/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/d3-ease": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz", + "integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-fetch": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-fetch/-/d3-fetch-3.0.1.tgz", + "integrity": "sha512-kpkQIM20n3oLVBKGg6oHrUchHM3xODkTzjMoj7aWQFq5QEM+R6E4WkzT5+tojDY7yjez8KgCBRoj4aEr99Fdqw==", + "license": "ISC", + "dependencies": { + "d3-dsv": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-force": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-force/-/d3-force-3.0.0.tgz", + "integrity": "sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg==", + "license": "ISC", + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-quadtree": "1 - 3", + "d3-timer": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-format": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.2.tgz", + "integrity": "sha512-AJDdYOdnyRDV5b6ArilzCPPwc1ejkHcoyFarqlPqT7zRYjhavcT3uSrqcMvsgh2CgoPbK3RCwyHaVyxYcP2Arg==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-geo": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/d3-geo/-/d3-geo-3.1.1.tgz", + "integrity": "sha512-637ln3gXKXOwhalDzinUgY83KzNWZRKbYubaG+fGVuc/dxO64RRljtCTnf5ecMyE1RIdtqpkVcq0IbtU2S8j2Q==", + "license": "ISC", + "dependencies": { + "d3-array": "2.5.0 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-hierarchy": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-3.1.2.tgz", + "integrity": "sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-interpolate": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz", + "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==", + "license": "ISC", + "dependencies": { + "d3-color": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-path": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz", + "integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-polygon": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-polygon/-/d3-polygon-3.0.1.tgz", + "integrity": "sha512-3vbA7vXYwfe1SYhED++fPUQlWSYTTGmFmQiany/gdbiWgU/iEyQzyymwL9SkJjFFuCS4902BSzewVGsHHmHtXg==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-quadtree": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-quadtree/-/d3-quadtree-3.0.1.tgz", + "integrity": "sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-random": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-random/-/d3-random-3.0.1.tgz", + "integrity": "sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-sankey": { + "version": "0.12.3", + "resolved": "https://registry.npmjs.org/d3-sankey/-/d3-sankey-0.12.3.tgz", + "integrity": "sha512-nQhsBRmM19Ax5xEIPLMY9ZmJ/cDvd1BG3UVvt5h3WRxKg5zGRbvnteTyWAbzeSvlh3tW7ZEmq4VwR5mB3tutmQ==", + "license": "BSD-3-Clause", + "dependencies": { + "d3-array": "1 - 2", + "d3-shape": "^1.2.0" + } + }, + "node_modules/d3-sankey/node_modules/d3-array": { + "version": "2.12.1", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-2.12.1.tgz", + "integrity": "sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ==", + "license": "BSD-3-Clause", + "dependencies": { + "internmap": "^1.0.0" + } + }, + "node_modules/d3-sankey/node_modules/d3-path": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-1.0.9.tgz", + "integrity": "sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg==", + "license": "BSD-3-Clause" + }, + "node_modules/d3-sankey/node_modules/d3-shape": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-1.3.7.tgz", + "integrity": "sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw==", + "license": "BSD-3-Clause", + "dependencies": { + "d3-path": "1" + } + }, + "node_modules/d3-sankey/node_modules/internmap": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/internmap/-/internmap-1.0.1.tgz", + "integrity": "sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw==", + "license": "ISC" + }, + "node_modules/d3-scale": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz", + "integrity": "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==", + "license": "ISC", + "dependencies": { + "d3-array": "2.10.0 - 3", + "d3-format": "1 - 3", + "d3-interpolate": "1.2.0 - 3", + "d3-time": "2.1.1 - 3", + "d3-time-format": "2 - 4" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-scale-chromatic": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-scale-chromatic/-/d3-scale-chromatic-3.1.0.tgz", + "integrity": "sha512-A3s5PWiZ9YCXFye1o246KoscMWqf8BsD9eRiJ3He7C9OBaxKhAd5TFCdEx/7VbKtxxTsu//1mMJFrEt572cEyQ==", + "license": "ISC", + "dependencies": { + "d3-color": "1 - 3", + "d3-interpolate": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-selection": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz", + "integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-shape": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz", + "integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==", + "license": "ISC", + "dependencies": { + "d3-path": "^3.1.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-time": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-3.1.0.tgz", + "integrity": "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==", + "license": "ISC", + "dependencies": { + "d3-array": "2 - 3" + }, + "engines": { + "node": ">=12" } }, - "node_modules/cssnano-preset-default": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-6.1.2.tgz", - "integrity": "sha512-1C0C+eNaeN8OcHQa193aRgYexyJtU8XwbdieEjClw+J9d94E41LwT6ivKH0WT+fYwYWB0Zp3I3IZ7tI/BbUbrg==", - "license": "MIT", + "node_modules/d3-time-format": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz", + "integrity": "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==", + "license": "ISC", "dependencies": { - "browserslist": "^4.23.0", - "css-declaration-sorter": "^7.2.0", - "cssnano-utils": "^4.0.2", - "postcss-calc": "^9.0.1", - "postcss-colormin": "^6.1.0", - "postcss-convert-values": "^6.1.0", - "postcss-discard-comments": "^6.0.2", - "postcss-discard-duplicates": "^6.0.3", - "postcss-discard-empty": "^6.0.3", - "postcss-discard-overridden": "^6.0.2", - "postcss-merge-longhand": "^6.0.5", - "postcss-merge-rules": "^6.1.1", - "postcss-minify-font-values": "^6.1.0", - "postcss-minify-gradients": "^6.0.3", - "postcss-minify-params": "^6.1.0", - "postcss-minify-selectors": "^6.0.4", - "postcss-normalize-charset": "^6.0.2", - "postcss-normalize-display-values": "^6.0.2", - "postcss-normalize-positions": "^6.0.2", - "postcss-normalize-repeat-style": "^6.0.2", - "postcss-normalize-string": "^6.0.2", - "postcss-normalize-timing-functions": "^6.0.2", - "postcss-normalize-unicode": "^6.1.0", - "postcss-normalize-url": "^6.0.2", - "postcss-normalize-whitespace": "^6.0.2", - "postcss-ordered-values": "^6.0.2", - "postcss-reduce-initial": "^6.1.0", - "postcss-reduce-transforms": "^6.0.2", - "postcss-svgo": "^6.0.3", - "postcss-unique-selectors": "^6.0.4" + "d3-time": "1 - 3" }, "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" + "node": ">=12" } }, - "node_modules/cssnano-utils": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-4.0.2.tgz", - "integrity": "sha512-ZR1jHg+wZ8o4c3zqf1SIUSTIvm/9mU343FMR6Obe/unskbvpGhZOo1J6d/r8D1pzkRQYuwbcH3hToOuoA2G7oQ==", - "license": "MIT", + "node_modules/d3-timer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz", + "integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==", + "license": "ISC", "engines": { - "node": "^14 || ^16 || >=18.0" - }, - "peerDependencies": { - "postcss": "^8.4.31" + "node": ">=12" } }, - "node_modules/csso": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/csso/-/csso-5.0.5.tgz", - "integrity": "sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==", - "license": "MIT", + "node_modules/d3-transition": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-transition/-/d3-transition-3.0.1.tgz", + "integrity": "sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==", + "license": "ISC", "dependencies": { - "css-tree": "~2.2.0" + "d3-color": "1 - 3", + "d3-dispatch": "1 - 3", + "d3-ease": "1 - 3", + "d3-interpolate": "1 - 3", + "d3-timer": "1 - 3" }, "engines": { - "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", - "npm": ">=7.0.0" + "node": ">=12" + }, + "peerDependencies": { + "d3-selection": "2 - 3" } }, - "node_modules/csso/node_modules/css-tree": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.2.1.tgz", - "integrity": "sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==", - "license": "MIT", + "node_modules/d3-zoom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-zoom/-/d3-zoom-3.0.0.tgz", + "integrity": "sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==", + "license": "ISC", "dependencies": { - "mdn-data": "2.0.28", - "source-map-js": "^1.0.1" + "d3-dispatch": "1 - 3", + "d3-drag": "2 - 3", + "d3-interpolate": "1 - 3", + "d3-selection": "2 - 3", + "d3-transition": "2 - 3" }, "engines": { - "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", - "npm": ">=7.0.0" + "node": ">=12" } }, - "node_modules/csso/node_modules/mdn-data": { - "version": "2.0.28", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.28.tgz", - "integrity": "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==", - "license": "CC0-1.0" + "node_modules/dagre-d3-es": { + "version": "7.0.14", + "resolved": "https://registry.npmjs.org/dagre-d3-es/-/dagre-d3-es-7.0.14.tgz", + "integrity": "sha512-P4rFMVq9ESWqmOgK+dlXvOtLwYg0i7u0HBGJER0LZDJT2VHIPAMZ/riPxqJceWMStH5+E61QxFra9kIS3AqdMg==", + "license": "MIT", + "dependencies": { + "d3": "^7.9.0", + "lodash-es": "^4.17.21" + } }, - "node_modules/csstype": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", - "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", + "node_modules/dayjs": { + "version": "1.11.20", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.20.tgz", + "integrity": "sha512-YbwwqR/uYpeoP4pu043q+LTDLFBLApUP6VxRihdfNTqu4ubqMlGDLd6ErXhEgsyvY0K6nCs7nggYumAN+9uEuQ==", "license": "MIT" }, "node_modules/debounce": { @@ -7229,6 +8180,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/delaunator": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/delaunator/-/delaunator-5.1.0.tgz", + "integrity": "sha512-AGrQ4QSgssa1NGmWmLPqN5NY2KajF5MqxetNEO+o0n3ZwZZeTmt7bBnvzHWrmkZFxGgr4HdyFgelzgi06otLuQ==", + "license": "ISC", + "dependencies": { + "robust-predicates": "^3.0.2" + } + }, "node_modules/depd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", @@ -7456,6 +8416,19 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/docusaurus-plugin-image-zoom": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/docusaurus-plugin-image-zoom/-/docusaurus-plugin-image-zoom-3.0.1.tgz", + "integrity": "sha512-mQrqA99VpoMQJNbi02qkWAMVNC4+kwc6zLLMNzraHAJlwn+HrlUmZSEDcTwgn+H4herYNxHKxveE2WsYy73eGw==", + "license": "MIT", + "dependencies": { + "medium-zoom": "^1.1.0", + "validate-peer-dependencies": "^2.2.0" + }, + "peerDependencies": { + "@docusaurus/theme-classic": ">=3.0.0" + } + }, "node_modules/dom-converter": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz", @@ -7506,6 +8479,15 @@ "url": "https://github.com/fb55/domhandler?sponsor=1" } }, + "node_modules/dompurify": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.4.1.tgz", + "integrity": "sha512-JahakDAIg1gyOm7dlgWSDjV4n7Ip2PKR55NIT6jrMfIgLFgWo81vdr1/QGqWtFNRqXP9UV71oVePtjqS2ebnPw==", + "license": "(MPL-2.0 OR Apache-2.0)", + "optionalDependencies": { + "@types/trusted-types": "^2.0.7" + } + }, "node_modules/domutils": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz", @@ -8820,6 +9802,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/hachure-fill": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/hachure-fill/-/hachure-fill-0.5.2.tgz", + "integrity": "sha512-3GKBOn+m2LX9iq+JC1064cSFprJY4jL1jCXTcpnfER5HYE2l/4EfWSGzkPa/ZDBmYI0ZOEj5VHV/eKnPGkHuOg==", + "license": "MIT" + }, "node_modules/handle-thing": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", @@ -9874,6 +10862,15 @@ "integrity": "sha512-0aO8FkhNZlj/ZIbNi7Lxxr12obT7cL1moPfE4tg1LkX7LlLfC6DeX4l2ZEud1ukP9jNQyNnfzQVqwbwmAATY4Q==", "license": "MIT" }, + "node_modules/internmap": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz", + "integrity": "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, "node_modules/invariant": { "version": "2.2.4", "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", @@ -10348,9 +11345,9 @@ } }, "node_modules/katex": { - "version": "0.16.22", - "resolved": "https://registry.npmjs.org/katex/-/katex-0.16.22.tgz", - "integrity": "sha512-XCHRdUw4lf3SKBaJe4EvgqIuWwkPSo9XoeO8GjQW94Bp7TWv9hNhzZjZ+OH9yf1UmLygb7DIT5GSFQiyt16zYg==", + "version": "0.16.45", + "resolved": "https://registry.npmjs.org/katex/-/katex-0.16.45.tgz", + "integrity": "sha512-pQpZbdBu7wCTmQUh7ufPmLr0pFoObnGUoL/yhtwJDgmmQpbkg/0HSVti25Fu4rmd1oCR6NGWe9vqTWuWv3GcNA==", "funding": [ "https://opencollective.com/katex", "https://github.com/sponsors/katex" @@ -10381,6 +11378,11 @@ "json-buffer": "3.0.1" } }, + "node_modules/khroma": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/khroma/-/khroma-2.1.0.tgz", + "integrity": "sha512-Ls993zuzfayK269Svk9hzpeGUKob/sIgZzyHYdjQoAdQetRKpOLj+k/QQQ/6Qi0Yz65mlROrfd+Ev+1+7dz9Kw==" + }, "node_modules/kind-of": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", @@ -10399,6 +11401,24 @@ "node": ">=6" } }, + "node_modules/langium": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/langium/-/langium-4.2.2.tgz", + "integrity": "sha512-JUshTRAfHI4/MF9dH2WupvjSXyn8JBuUEWazB8ZVJUtXutT0doDlAv1XKbZ1Pb5sMexa8FF4CFBc0iiul7gbUQ==", + "license": "MIT", + "dependencies": { + "@chevrotain/regexp-to-ast": "~12.0.0", + "chevrotain": "~12.0.0", + "chevrotain-allstar": "~0.4.1", + "vscode-languageserver": "~9.0.1", + "vscode-languageserver-textdocument": "~1.0.11", + "vscode-uri": "~3.1.0" + }, + "engines": { + "node": ">=20.10.0", + "npm": ">=10.2.3" + } + }, "node_modules/latest-version": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-7.0.0.tgz", @@ -10424,6 +11444,12 @@ "shell-quote": "^1.8.3" } }, + "node_modules/layout-base": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/layout-base/-/layout-base-1.0.2.tgz", + "integrity": "sha512-8h2oVEZNktL4BH2JCOI90iD1yXwL6iNW7KcCKT2QZgQJR2vbqDsldCTPRU9NifTCqHZci57XvQQ15YTu+sTYPg==", + "license": "MIT" + }, "node_modules/leven": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", @@ -10495,6 +11521,12 @@ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "license": "MIT" }, + "node_modules/lodash-es": { + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.18.1.tgz", + "integrity": "sha512-J8xewKD/Gk22OZbhpOVSwcs60zhd95ESDwezOFuA3/099925PdHJ7OFHNTGtajL3AlZkykD32HykiMo+BIBI8A==", + "license": "MIT" + }, "node_modules/lodash.debounce": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", @@ -10605,6 +11637,18 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/marked": { + "version": "16.4.2", + "resolved": "https://registry.npmjs.org/marked/-/marked-16.4.2.tgz", + "integrity": "sha512-TI3V8YYWvkVf3KJe1dRkpnjs68JUPyEa5vjKrp1XEEJUAOaQc+Qj+L1qWbPd0SJuAdQkFU0h73sXXqwDYxsiDA==", + "license": "MIT", + "bin": { + "marked": "bin/marked.js" + }, + "engines": { + "node": ">= 20" + } + }, "node_modules/math-intrinsics": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", @@ -11086,6 +12130,12 @@ "node": ">= 0.6" } }, + "node_modules/medium-zoom": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/medium-zoom/-/medium-zoom-1.1.0.tgz", + "integrity": "sha512-ewyDsp7k4InCUp3jRmwHBRFGyjBimKps/AJLjRSox+2q/2H4p/PNpQf+pwONWlJiOudkBXtbdmVbFjqyybfTmQ==", + "license": "MIT" + }, "node_modules/memfs": { "version": "3.5.3", "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.5.3.tgz", @@ -11122,6 +12172,48 @@ "node": ">= 8" } }, + "node_modules/mermaid": { + "version": "11.14.0", + "resolved": "https://registry.npmjs.org/mermaid/-/mermaid-11.14.0.tgz", + "integrity": "sha512-GSGloRsBs+JINmmhl0JDwjpuezCsHB4WGI4NASHxL3fHo3o/BRXTxhDLKnln8/Q0lRFRyDdEjmk1/d5Sn1Xz8g==", + "license": "MIT", + "dependencies": { + "@braintree/sanitize-url": "^7.1.1", + "@iconify/utils": "^3.0.2", + "@mermaid-js/parser": "^1.1.0", + "@types/d3": "^7.4.3", + "@upsetjs/venn.js": "^2.0.0", + "cytoscape": "^3.33.1", + "cytoscape-cose-bilkent": "^4.1.0", + "cytoscape-fcose": "^2.2.0", + "d3": "^7.9.0", + "d3-sankey": "^0.12.3", + "dagre-d3-es": "7.0.14", + "dayjs": "^1.11.19", + "dompurify": "^3.3.1", + "katex": "^0.16.25", + "khroma": "^2.1.0", + "lodash-es": "^4.17.23", + "marked": "^16.3.0", + "roughjs": "^4.6.6", + "stylis": "^4.3.6", + "ts-dedent": "^2.2.0", + "uuid": "^11.1.0" + } + }, + "node_modules/mermaid/node_modules/uuid": { + "version": "11.1.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-11.1.1.tgz", + "integrity": "sha512-vIYxrBCC/N/K+Js3qSN88go7kIfNPssr/hHCesKCQNAjmgvYS2oqr69kIufEG+O4+PfezOH4EbIeHCfFov8ZgQ==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "bin": { + "uuid": "dist/esm/bin/uuid" + } + }, "node_modules/methods": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", @@ -13084,9 +14176,9 @@ "license": "ISC" }, "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" @@ -13114,6 +14206,18 @@ "node": "*" } }, + "node_modules/mlly": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.8.2.tgz", + "integrity": "sha512-d+ObxMQFmbt10sretNDytwt85VrbkhhUA/JBGm1MPaWJ65Cl4wOgLaB1NYvJSZ0Ef03MMEU/0xpPMXUIQ29UfA==", + "license": "MIT", + "dependencies": { + "acorn": "^8.16.0", + "pathe": "^2.0.3", + "pkg-types": "^1.3.1", + "ufo": "^1.6.3" + } + }, "node_modules/mrmime": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.1.tgz", @@ -13613,6 +14717,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/package-manager-detector": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/package-manager-detector/-/package-manager-detector-1.6.0.tgz", + "integrity": "sha512-61A5ThoTiDG/C8s8UMZwSorAGwMJ0ERVGj2OjoW5pAalsNOg15+iQiPzrLJ4jhZ1HJzmC2PIHT2oEiH3R5fzNA==", + "license": "MIT" + }, "node_modules/param-case": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", @@ -13740,6 +14850,12 @@ "tslib": "^2.0.3" } }, + "node_modules/path-data-parser": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/path-data-parser/-/path-data-parser-0.1.0.tgz", + "integrity": "sha512-NOnmBpt5Y2RWbuv0LMzsayp3lVylAHLPUTut412ZA3l+C4uw4ZVkQbjShYCQ8TCpUMdPapr4YjUqLYD6v68j+w==", + "license": "MIT" + }, "node_modules/path-exists": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz", @@ -13779,6 +14895,27 @@ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "license": "MIT" }, + "node_modules/path-root": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/path-root/-/path-root-0.1.1.tgz", + "integrity": "sha512-QLcPegTHF11axjfojBIoDygmS2E3Lf+8+jI6wOVmNVenrKSo3mFdSGiIgdSHenczw3wPtlVMQaFVwGmM7BJdtg==", + "license": "MIT", + "dependencies": { + "path-root-regex": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-root-regex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/path-root-regex/-/path-root-regex-0.1.2.tgz", + "integrity": "sha512-4GlJ6rZDhQZFE0DPVKh0e9jmZ5egZfxTkp7bcRDuPlJXbAwhxcl2dINPUAsjLdejqaLsCeg8axcLjIbvBjN4pQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/path-to-regexp": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.9.0.tgz", @@ -13797,6 +14934,12 @@ "node": ">=8" } }, + "node_modules/pathe": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", + "license": "MIT" + }, "node_modules/picocolors": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", @@ -13830,6 +14973,33 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/pkg-types": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.3.1.tgz", + "integrity": "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==", + "license": "MIT", + "dependencies": { + "confbox": "^0.1.8", + "mlly": "^1.7.4", + "pathe": "^2.0.1" + } + }, + "node_modules/points-on-curve": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/points-on-curve/-/points-on-curve-0.2.0.tgz", + "integrity": "sha512-0mYKnYYe9ZcqMCWhUjItv/oHjvgEsfKvnUTg8sAtnHr3GVy7rGkXCb6d5cSyqrWqL4k81b9CPg3urd+T7aop3A==", + "license": "MIT" + }, + "node_modules/points-on-path": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/points-on-path/-/points-on-path-0.2.1.tgz", + "integrity": "sha512-25ClnWWuw7JbWZcgqY/gJ4FQWadKxGWk+3kR/7kD0tCaDtPPMj7oHu2ToLaVhfpnHrZzYby2w6tUA0eOIuUg8g==", + "license": "MIT", + "dependencies": { + "path-data-parser": "0.1.0", + "points-on-curve": "0.2.0" + } + }, "node_modules/postcss": { "version": "8.5.6", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", @@ -15618,9 +16788,9 @@ } }, "node_modules/react-loadable-ssr-addon-v5-slorber": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/react-loadable-ssr-addon-v5-slorber/-/react-loadable-ssr-addon-v5-slorber-1.0.1.tgz", - "integrity": "sha512-lq3Lyw1lGku8zUEJPDxsNm1AfYHBrO9Y1+olAYwpUJ2IGFBskM0DMKok97A6LWUpHm+o7IvQBOWu9MLenp9Z+A==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/react-loadable-ssr-addon-v5-slorber/-/react-loadable-ssr-addon-v5-slorber-1.0.3.tgz", + "integrity": "sha512-GXfh9VLwB5ERaCsU6RULh7tkemeX15aNh6wuMEBtfdyMa7fFG8TXrhXlx1SoEK2Ty/l6XIkzzYIQmyaWW3JgdQ==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.10.3" @@ -16425,6 +17595,18 @@ "node": ">=4" } }, + "node_modules/resolve-package-path": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/resolve-package-path/-/resolve-package-path-4.0.3.tgz", + "integrity": "sha512-SRpNAPW4kewOaNUt8VPqhJ0UMxawMwzJD8V7m1cJfdSTK9ieZwS6K7Dabsm4bmLFM96Z5Y/UznrpG5kt1im8yA==", + "license": "MIT", + "dependencies": { + "path-root": "^0.1.1" + }, + "engines": { + "node": ">= 12" + } + }, "node_modules/resolve-pathname": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/resolve-pathname/-/resolve-pathname-3.0.0.tgz", @@ -16481,6 +17663,24 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/robust-predicates": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/robust-predicates/-/robust-predicates-3.0.3.tgz", + "integrity": "sha512-NS3levdsRIUOmiJ8FZWCP7LG3QpJyrs/TE0Zpf1yvZu8cAJJ6QMW92H1c7kWpdIHo8RvmLxN/o2JXTKHp74lUA==", + "license": "Unlicense" + }, + "node_modules/roughjs": { + "version": "4.6.6", + "resolved": "https://registry.npmjs.org/roughjs/-/roughjs-4.6.6.tgz", + "integrity": "sha512-ZUz/69+SYpFN/g/lUlo2FXcIjRkSu3nDarreVdGGndHEBJ6cXPdKguS8JGxwj5HA5xIbVKSmLgr5b3AWxtRfvQ==", + "license": "MIT", + "dependencies": { + "hachure-fill": "^0.5.2", + "path-data-parser": "^0.1.0", + "points-on-curve": "^0.2.0", + "points-on-path": "^0.2.1" + } + }, "node_modules/rtlcss": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/rtlcss/-/rtlcss-4.3.0.tgz", @@ -16522,6 +17722,12 @@ "queue-microtask": "^1.2.2" } }, + "node_modules/rw": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz", + "integrity": "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==", + "license": "BSD-3-Clause" + }, "node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -16720,15 +17926,15 @@ } }, "node_modules/serve-handler": { - "version": "6.1.6", - "resolved": "https://registry.npmjs.org/serve-handler/-/serve-handler-6.1.6.tgz", - "integrity": "sha512-x5RL9Y2p5+Sh3D38Fh9i/iQ5ZK+e4xuXRd/pGbM4D13tgo/MGwbttUk8emytcr1YYzBYs+apnUngBDFYfpjPuQ==", + "version": "6.1.7", + "resolved": "https://registry.npmjs.org/serve-handler/-/serve-handler-6.1.7.tgz", + "integrity": "sha512-CinAq1xWb0vR3twAv9evEU8cNWkXCb9kd5ePAHUKJBkOsUpR1wt/CvGdeca7vqumL1U5cSaeVQ6zZMxiJ3yWsg==", "license": "MIT", "dependencies": { "bytes": "3.0.0", "content-disposition": "0.5.2", "mime-types": "2.1.18", - "minimatch": "3.1.2", + "minimatch": "3.1.5", "path-is-inside": "1.0.2", "path-to-regexp": "3.3.0", "range-parser": "1.2.0" @@ -17348,6 +18554,12 @@ "postcss": "^8.4.31" } }, + "node_modules/stylis": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.4.0.tgz", + "integrity": "sha512-5Z9ZpRzfuH6l/UAvCPAPUo3665Nk2wLaZU3x+TLHKVzIz33+sbJqbtrYoC3KD4/uVOr2Zp+L0LySezP9OHV9yA==", + "license": "MIT" + }, "node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -17530,6 +18742,15 @@ "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==", "license": "MIT" }, + "node_modules/tinyexec": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.1.2.tgz", + "integrity": "sha512-dAqSqE/RabpBKI8+h26GfLq6Vb3JVXs30XYQjdMjaj/c2tS8IYYMbIzP599KtRj7c57/wYApb3QjgRgXmrCukA==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, "node_modules/tinypool": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.1.1.tgz", @@ -17652,6 +18873,15 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/ts-dedent": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/ts-dedent/-/ts-dedent-2.2.0.tgz", + "integrity": "sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ==", + "license": "MIT", + "engines": { + "node": ">=6.10" + } + }, "node_modules/tslib": { "version": "2.8.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", @@ -17727,6 +18957,12 @@ "node": ">=14.17" } }, + "node_modules/ufo": { + "version": "1.6.4", + "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.6.4.tgz", + "integrity": "sha512-JFNbkD1Svwe0KvGi8GOeLcP4kAWQ609twvCdcHxq1oSL8svv39ZuSvajcD8B+5D0eL4+s1Is2D/O6KN3qcTeRA==", + "license": "MIT" + }, "node_modules/undici-types": { "version": "7.12.0", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.12.0.tgz", @@ -18214,6 +19450,19 @@ "uuid": "dist/bin/uuid" } }, + "node_modules/validate-peer-dependencies": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/validate-peer-dependencies/-/validate-peer-dependencies-2.2.0.tgz", + "integrity": "sha512-8X1OWlERjiUY6P6tdeU9E0EwO8RA3bahoOVG7ulOZT5MqgNDUO/BQoVjYiHPcNe+v8glsboZRIw9iToMAA2zAA==", + "license": "MIT", + "dependencies": { + "resolve-package-path": "^4.0.3", + "semver": "^7.3.8" + }, + "engines": { + "node": ">= 12" + } + }, "node_modules/value-equal": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/value-equal/-/value-equal-1.0.1.tgz", @@ -18271,6 +19520,55 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/vscode-jsonrpc": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-8.2.0.tgz", + "integrity": "sha512-C+r0eKJUIfiDIfwJhria30+TYWPtuHJXHtI7J0YlOmKAo7ogxP20T0zxB7HZQIFhIyvoBPwWskjxrvAtfjyZfA==", + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/vscode-languageserver": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-9.0.1.tgz", + "integrity": "sha512-woByF3PDpkHFUreUa7Hos7+pUWdeWMXRd26+ZX2A8cFx6v/JPTtd4/uN0/jB6XQHYaOlHbio03NTHCqrgG5n7g==", + "license": "MIT", + "dependencies": { + "vscode-languageserver-protocol": "3.17.5" + }, + "bin": { + "installServerIntoExtension": "bin/installServerIntoExtension" + } + }, + "node_modules/vscode-languageserver-protocol": { + "version": "3.17.5", + "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.5.tgz", + "integrity": "sha512-mb1bvRJN8SVznADSGWM9u/b07H7Ecg0I3OgXDuLdn307rl/J3A9YD6/eYOssqhecL27hK1IPZAsaqh00i/Jljg==", + "license": "MIT", + "dependencies": { + "vscode-jsonrpc": "8.2.0", + "vscode-languageserver-types": "3.17.5" + } + }, + "node_modules/vscode-languageserver-textdocument": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.12.tgz", + "integrity": "sha512-cxWNPesCnQCcMPeenjKKsOCKQZ/L6Tv19DTRIGuLWe32lyzWhihGVJ/rcckZXJxfdKCFvRLS3fpBIsV/ZGX4zA==", + "license": "MIT" + }, + "node_modules/vscode-languageserver-types": { + "version": "3.17.5", + "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.17.5.tgz", + "integrity": "sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg==", + "license": "MIT" + }, + "node_modules/vscode-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.1.0.tgz", + "integrity": "sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ==", + "license": "MIT" + }, "node_modules/watchpack": { "version": "2.4.4", "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.4.tgz", diff --git a/package.json b/package.json index db8bde2..d913a34 100644 --- a/package.json +++ b/package.json @@ -21,10 +21,12 @@ "@docusaurus/core": "3.8.1", "@docusaurus/plugin-client-redirects": "^3.8.1", "@docusaurus/preset-classic": "3.8.1", + "@docusaurus/theme-mermaid": "^3.8.1", "@mdx-js/react": "^3.1.0", "algoliasearch": "^5.34.1", "clsx": "^2.0.0", "docusaurus-lunr-search": "^3.6.0", + "docusaurus-plugin-image-zoom": "^3.0.1", "prism-react-renderer": "^2.3.0", "react": "^18.0.0", "react-dom": "^18.0.0", diff --git a/sidebars.ts b/sidebars.ts index 1c7b405..1383973 100644 --- a/sidebars.ts +++ b/sidebars.ts @@ -68,19 +68,25 @@ const sidebars: SidebarsConfig = { "taceo-proof/dev/bestpractice", ], }, - ["solutions/finance/x402"], ], }, { type: "category", - label: "TACEO Solutions", - link: { type: "doc", id: "solutions/overview" }, + label: "Finance Solutions", + link: { type: "doc", id: "finance-solutions/overview" }, items: [ { type: "category", - label: "Finance", - link: { type: "doc", id: "solutions/finance/index" }, - items: ["solutions/finance/x402"], + label: "Confidential x402", + link: { type: "generated-index", title:"Confidential x402", slug: "finance-solutions/x402/", description: "Confidential x402 is a privacy extension to the x402 payment protocol that hides payment amounts and balances on-chain using ZK proofs and MPC — without changing how you write HTTP clients or servers." }, + items: [ + "finance-solutions/x402/introduction", + "finance-solutions/x402/quickstart", + "finance-solutions/x402/how-it-works", + "finance-solutions/x402/integration-guide", + "finance-solutions/x402/protocol-reference", + "finance-solutions/x402/network-and-contracts", + ], }, ], }, From 1000ca5f4bfc507745f7f7460001a3646058c5c2 Mon Sep 17 00:00:00 2001 From: Fabian Gruber Date: Mon, 4 May 2026 14:42:39 +0200 Subject: [PATCH 04/25] fix: sync docusaurus versions --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index d913a34..4b86d54 100644 --- a/package.json +++ b/package.json @@ -19,9 +19,9 @@ "@algolia/autocomplete-shared": "^1.19.2", "@algolia/client-search": "^5.34.1", "@docusaurus/core": "3.8.1", - "@docusaurus/plugin-client-redirects": "^3.8.1", + "@docusaurus/plugin-client-redirects": "3.8.1", "@docusaurus/preset-classic": "3.8.1", - "@docusaurus/theme-mermaid": "^3.8.1", + "@docusaurus/theme-mermaid": "3.8.1", "@mdx-js/react": "^3.1.0", "algoliasearch": "^5.34.1", "clsx": "^2.0.0", From 340ce4bc3d94a8065cd5efb860c3377ce4c11a45 Mon Sep 17 00:00:00 2001 From: Fabian Gruber Date: Tue, 5 May 2026 08:26:51 +0200 Subject: [PATCH 05/25] fix: update deps in code examples, fix would be compiler error --- docs/finance-solutions/x402/integration-guide.mdx | 11 ++++++----- docs/finance-solutions/x402/quickstart.mdx | 13 ++++++++----- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/docs/finance-solutions/x402/integration-guide.mdx b/docs/finance-solutions/x402/integration-guide.mdx index 38c330c..66d67bf 100644 --- a/docs/finance-solutions/x402/integration-guide.mdx +++ b/docs/finance-solutions/x402/integration-guide.mdx @@ -26,13 +26,14 @@ npm install @taceolabs/taceo-merces1-x402-js @x402/fetch viem ```toml [dependencies] -taceo-merces1-x402 = "1.0" -x402-reqwest = "1.4" -x402-axum = "1.4" -reqwest = { version = "0.13", default-features = false, features = ["json", "rustls"] } -alloy = { version = "2", default-features = false, features = ["signers", "primitives"] } +alloy = "2" +eyre = "0.6" axum = "0.8" +reqwest = { version = "0.13", features = ["json", "rustls"] } +taceo-merces1-x402 = "0.1" tokio = { version = "1", features = ["macros", "rt-multi-thread"] } +x402-axum = "1" +x402-reqwest = "1" ``` diff --git a/docs/finance-solutions/x402/quickstart.mdx b/docs/finance-solutions/x402/quickstart.mdx index 9abf736..efd24b1 100644 --- a/docs/finance-solutions/x402/quickstart.mdx +++ b/docs/finance-solutions/x402/quickstart.mdx @@ -27,7 +27,7 @@ You will: ```bash -npm install @taceolabs/taceo-merces1-x402-js +npm install @taceolabs/taceo-merces1-x402-js @x402/fetch viem ``` @@ -37,9 +37,12 @@ Add the following to your `Cargo.toml`: ```toml [dependencies] -taceo-merces1-x402 = "1.0" +alloy = "2" +eyre = "0.6" +reqwest = "0.13" +taceo-merces1-x402 = "0.1" tokio = { version = "1", features = ["macros", "rt-multi-thread"] } -alloy = { version = "2", default-features = false, features = ["signers"] } +x402-reqwest = "1" ``` @@ -74,10 +77,10 @@ console.log('Address:', account.address); ```rust -use alloy::signers::local::PrivateKeySigner; +use alloy::{hex, signers::local::PrivateKeySigner}; let signer = PrivateKeySigner::random(); -println!("Private key: {}", signer.credential().to_bytes().to_string()); +println!("Private key: {}", hex::encode(signer.credential().to_bytes())); println!("Address: {}", signer.address()); ``` From 734bd1dc8d1e9b2e903e23e5a1878f12c7c478ab Mon Sep 17 00:00:00 2001 From: usigo Date: Tue, 5 May 2026 14:15:31 +0200 Subject: [PATCH 06/25] Update docs/finance-solutions/x402/introduction.mdx Co-authored-by: Fabian <49373262+fabian1409@users.noreply.github.com> --- docs/finance-solutions/x402/introduction.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/finance-solutions/x402/introduction.mdx b/docs/finance-solutions/x402/introduction.mdx index baa5158..7a53937 100644 --- a/docs/finance-solutions/x402/introduction.mdx +++ b/docs/finance-solutions/x402/introduction.mdx @@ -24,7 +24,7 @@ This works for flat-rate APIs, but breaks down the moment pricing becomes dynami - **Per-customer deals are impossible to keep confidential.** Volume discounts, enterprise rates, and promotional pricing are all public record. - **AI agents reveal their economic strategy.** Spending patterns across API providers expose which - data sources an agent values by much budget it allocates. + data sources an agent values by how much budget it allocates. ## How Confidential x402 addresses this From 66d696e9c6d0cfef64982e2c2a79829615b69542 Mon Sep 17 00:00:00 2001 From: usigo Date: Tue, 5 May 2026 14:26:40 +0200 Subject: [PATCH 07/25] Update docs/finance-solutions/x402/how-it-works.mdx Co-authored-by: Fabian <49373262+fabian1409@users.noreply.github.com> --- docs/finance-solutions/x402/how-it-works.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/finance-solutions/x402/how-it-works.mdx b/docs/finance-solutions/x402/how-it-works.mdx index c7a97ce..cc1e07d 100644 --- a/docs/finance-solutions/x402/how-it-works.mdx +++ b/docs/finance-solutions/x402/how-it-works.mdx @@ -10,7 +10,7 @@ role and walks through a full payment end-to-end. ## Components -**Client** — the agent or application making the API request. It holds the secret key to the spending wallet, generates +**Client** — the agent or application making the API request. It holds the private key to the spending wallet, generates the ZK proof, and constructs the payment payload. The client library handles all cryptographic operations; the client application only needs to register the scheme and make HTTP requests as normal. From 5a741138688910eb4c511012918800b1b6c90ffb Mon Sep 17 00:00:00 2001 From: usigo Date: Tue, 5 May 2026 14:40:07 +0200 Subject: [PATCH 08/25] Update docs/finance-solutions/x402/how-it-works.mdx Co-authored-by: Fabian <49373262+fabian1409@users.noreply.github.com> --- docs/finance-solutions/x402/how-it-works.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/finance-solutions/x402/how-it-works.mdx b/docs/finance-solutions/x402/how-it-works.mdx index cc1e07d..8d71909 100644 --- a/docs/finance-solutions/x402/how-it-works.mdx +++ b/docs/finance-solutions/x402/how-it-works.mdx @@ -95,7 +95,7 @@ The client builds the payment payload locally. No network calls are required for - Each share is correctly encrypted to the stated operator key. - The amount fits in 80 bits. 6. Sign the full payload with **EIP-712** — binding sender, receiver, commitment, ciphertexts, nonce, and deadline. -7. Re-send the original request with a `PAYMENT` header containing the encoded payload. +7. Re-send the original request with a `PAYMENT-SIGNATURE` header containing the encoded payload. ### Phase 3 — Verification From 8fa1d3a1e3138b43280698372b470674ccaf956e Mon Sep 17 00:00:00 2001 From: usigo Date: Tue, 5 May 2026 14:40:23 +0200 Subject: [PATCH 09/25] Update docs/finance-solutions/x402/how-it-works.mdx Co-authored-by: Fabian <49373262+fabian1409@users.noreply.github.com> --- docs/finance-solutions/x402/how-it-works.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/finance-solutions/x402/how-it-works.mdx b/docs/finance-solutions/x402/how-it-works.mdx index 8d71909..8305e9d 100644 --- a/docs/finance-solutions/x402/how-it-works.mdx +++ b/docs/finance-solutions/x402/how-it-works.mdx @@ -77,7 +77,7 @@ sequenceDiagram The client sends an unauthenticated HTTP request to a protected endpoint. The resource server checks its configuration, finds no valid payment attached, and responds with `HTTP 402 Payment -Required`. The response body contains a base64-encoded `PaymentRequired` payload advertising the +Required`. The response has a `PAYMENT-REQUIRED` header, containing the base64-encoded `PaymentRequired` payload advertising the `confidential` scheme, the required token and amount, the recipient address, and the MPC network's current public keys. From a9efb01676458994872a78b84c77fcd0dd97e8d7 Mon Sep 17 00:00:00 2001 From: usigo Date: Tue, 5 May 2026 14:40:47 +0200 Subject: [PATCH 10/25] Update docs/finance-solutions/x402/how-it-works.mdx Co-authored-by: Fabian <49373262+fabian1409@users.noreply.github.com> --- docs/finance-solutions/x402/how-it-works.mdx | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/finance-solutions/x402/how-it-works.mdx b/docs/finance-solutions/x402/how-it-works.mdx index 8305e9d..bbd0ff1 100644 --- a/docs/finance-solutions/x402/how-it-works.mdx +++ b/docs/finance-solutions/x402/how-it-works.mdx @@ -106,6 +106,7 @@ endpoint. The facilitator runs a series of checks: - **Recipient match** — `payload.to` equals the resource server's address. - **Deadline** — the payment has not expired. - **Nonce** — not already used on-chain. +- **Amount commitment match** — random blinding factor `r` and `amount` produce the provided commitment - **Signature** — the EIP-712 signature recovers to the claimed sender. - **ZK proof** — the Groth16 proof is valid against 15 public signals (sender key, commitment, ciphertexts, MPC keys). - **Balance** — the facilitator queries all three MPC nodes; they collectively confirm the sender holds sufficient funds without revealing the balance to anyone. From 47ff9544fc3c11877773a05ddbadac0b4dcb24a8 Mon Sep 17 00:00:00 2001 From: usigo Date: Tue, 5 May 2026 14:46:40 +0200 Subject: [PATCH 11/25] Update docs/finance-solutions/x402/how-it-works.mdx Co-authored-by: Fabian <49373262+fabian1409@users.noreply.github.com> --- docs/finance-solutions/x402/how-it-works.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/finance-solutions/x402/how-it-works.mdx b/docs/finance-solutions/x402/how-it-works.mdx index bbd0ff1..5c8e08f 100644 --- a/docs/finance-solutions/x402/how-it-works.mdx +++ b/docs/finance-solutions/x402/how-it-works.mdx @@ -111,7 +111,7 @@ endpoint. The facilitator runs a series of checks: - **ZK proof** — the Groth16 proof is valid against 15 public signals (sender key, commitment, ciphertexts, MPC keys). - **Balance** — the facilitator queries all three MPC nodes; they collectively confirm the sender holds sufficient funds without revealing the balance to anyone. -If all checks pass, the facilitator returns `{ valid: true }` to the resource server. +If all checks pass, the facilitator returns `{ isValid: true }` to the resource server. ### Phase 4 — Content delivery & settlement From 34b78b43f84bac1ba2a2c73d174fc2cc11fe2168 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20G=C3=B6tz?= Date: Tue, 5 May 2026 14:48:32 +0200 Subject: [PATCH 12/25] addressed Fabian's comments --- docs/finance-solutions/x402/how-it-works.mdx | 19 +-- .../x402/integration-guide.mdx | 114 +----------------- docs/finance-solutions/x402/introduction.mdx | 3 +- .../x402/protocol-reference.mdx | 4 +- docs/finance-solutions/x402/quickstart.mdx | 30 +---- 5 files changed, 16 insertions(+), 154 deletions(-) diff --git a/docs/finance-solutions/x402/how-it-works.mdx b/docs/finance-solutions/x402/how-it-works.mdx index 5c8e08f..f7529bb 100644 --- a/docs/finance-solutions/x402/how-it-works.mdx +++ b/docs/finance-solutions/x402/how-it-works.mdx @@ -20,7 +20,7 @@ payment payloads to the facilitator for verification, and serves content on succ advertising `scheme: "confidential"` in its payment requirements, it behaves identically to a standard x402 resource server. -**Facilitator** — an off-chain service that verifies payment proofs and routes settlements. It +**Facilitator** — an off-chain service that verifies payment proofs and triggers settlements. It checks the ZK proof, validates the EIP-712 signature, queries the MPC network for balance sufficiency, and submits the settlement transaction on-chain. TACEO operates a facilitator that can be used directly. @@ -48,7 +48,7 @@ sequenceDiagram C->>R: GET /api/ R-->>C: 402 + PaymentRequired (scheme: confidential) - Note over C: Generate commitment, secret shares,
ciphertexts, EIP-712 signature,
Groth16 proof (~800ms) + Note over C: Generate commitment, secret shares,
ciphertexts, EIP-712 signature,
Groth16 proof C->>R: GET /api/ + PAYMENT @@ -60,14 +60,14 @@ sequenceDiagram F-->>R: isValid: true R->>F: POST /settle note over F: do verification (as in /verify route) - F-->>R: success: true - R-->>C: 200 + content F->>X: transferFrom() Note over X: verify Groth16 proof on-chain via ClientTransferVerifier X-->>F: action_index Note over M: read_queue, decrypt, update bal, gen proof M->>X: processMPC Note over X: verify proof, update comms + F-->>R: success: true + R-->>C: 200 + content ``` @@ -115,9 +115,6 @@ If all checks pass, the facilitator returns `{ isValid: true }` to the resource ### Phase 4 — Content delivery & settlement -On a valid response, the resource server immediately returns `HTTP 200` with the requested content. -Settlement is asynchronous — the client already has its response. - The resource server then calls the facilitator's `/settle` endpoint. The facilitator calls `transferFrom()` on the Merces contract, passing the proof and ciphertexts. The contract verifies the proof on-chain and enqueues a transfer action. @@ -127,12 +124,16 @@ amount, verifies the commitment, updates both parties' balance commitments, and ZK proof that the update is correct. It calls `processMPC()` on the contract, which verifies the proof and commits the new balance state. +On a valid response, the resource server returns `HTTP 200` with the requested content. + +:::info Asynchronous Settlement +Alternatively, content delivery can already take places simultaneously to the settlement. +::: ## Performance | Operation | Cost | |---|---| -| Proof generation (client) | ~800ms | -| Off-chain proof verification (facilitator) | ~13ms | +| Proof generation (client) | ~800ms (SnarkJS) / ~60ms (Rust) | | On-chain proof verification | ~300,000 gas | diff --git a/docs/finance-solutions/x402/integration-guide.mdx b/docs/finance-solutions/x402/integration-guide.mdx index 66d67bf..e14ab37 100644 --- a/docs/finance-solutions/x402/integration-guide.mdx +++ b/docs/finance-solutions/x402/integration-guide.mdx @@ -126,118 +126,9 @@ println!("Body: {}", response.text().await?); When the server responds with `402`, the client handles it invisibly: parses the `PaymentRequired` -payload, generates the Groth16 ZK proof (~800ms), retries the request with a `PAYMENT-SIGNATURE` +payload, generates the Groth16 ZK proof, retries the request with a `PAYMENT-SIGNATURE` header, and returns the final `200 OK` to your code. -### Restrict to specific networks - -By default, the scheme registers for all EIP-155 chains (`eip155:*`). To restrict to a specific -chain: - - - - -```typescript -import { registerConfidentialEvmScheme } from '@taceolabs/taceo-merces1-x402-js/client'; - -registerConfidentialEvmScheme(client, { - signer, - networks: ['eip155:84532'], // Base Sepolia only -}); -``` - - - - -The Rust client selects the scheme based on the `network` field in the server's `PaymentRequired` -response. No additional configuration is needed to restrict by chain. - - - - -### Check your private balance - -Your Merces balance is secret-shared across three MPC nodes and never appears on-chain in -plaintext. The client queries all three nodes and reconstructs the balance locally. - - - - -```typescript -import { Client } from '@taceolabs/taceo-merces1-client-js'; -import { createWalletClient, createPublicClient, http } from 'viem'; -import { baseSepolia } from 'viem/chains'; -import { privateKeyToAccount } from 'viem/accounts'; - -const account = privateKeyToAccount(process.env.PRIVATE_KEY as `0x${string}`); - -const merces = new Client({ - nodeUrls: [ - 'https://node0.merces.taceo.io', - 'https://node1.merces.taceo.io', - 'https://node2.merces.taceo.io', - ], - contractAddress: '0xTODO', - token: { type: 'ERC20', address: '0xTODO' }, - walletClient: createWalletClient({ account, chain: baseSepolia, transport: http() }), - publicClient: createPublicClient({ chain: baseSepolia, transport: http() }), -}); - -const balance = await merces.getPrivateBalance(); -console.log('Private balance:', balance.toString()); -``` - - - - -Balance queries are handled internally by the facilitator during payment verification. Direct -balance reads are not exposed in the current Rust client — use the TypeScript client or the -faucet API if you need to inspect balances during development. - - - - -:::info Funding your wallet -Use the [faucet](../quickstart/#step-2--get-test-tokens-from-the-faucet) to top up your Merces balance with test tokens. -::: - -### Error handling - - - - -```typescript -import { - InsufficientBalanceError, - ProofError, -} from '@taceolabs/taceo-merces1-client-js'; - -try { - const response = await fetchWithPayment(url, { method: 'GET' }); -} catch (err) { - if (err instanceof InsufficientBalanceError) { - console.error('Top up your Merces balance via the faucet.'); - } else if (err instanceof ProofError) { - console.error('ZK proof generation failed:', err.message); - } else { - throw err; - } -} -``` - - - - -```rust -match http_client.get(url).send().await { - Ok(response) => println!("Status: {}", response.status()), - Err(e) => eprintln!("Payment or request failed: {e}"), -} -``` - - - - --- ## Server @@ -347,8 +238,7 @@ When a request arrives without a valid `PAYMENT-SIGNATURE` header: 2. When the client retries with a payment, the middleware forwards it to the facilitator's `/verify` endpoint. 3. If verification succeeds, the request is forwarded to your handler. -4. After your handler responds, the middleware calls `/settle` asynchronously. Your handler is - not blocked by settlement. +4. After your handler responds, the middleware calls `/settle` asynchronously. ### Protecting multiple routes diff --git a/docs/finance-solutions/x402/introduction.mdx b/docs/finance-solutions/x402/introduction.mdx index 7a53937..aac2c4c 100644 --- a/docs/finance-solutions/x402/introduction.mdx +++ b/docs/finance-solutions/x402/introduction.mdx @@ -49,10 +49,9 @@ To run a full x402 confidential payment cycle TACEO operates all required compon | Component | Description | |---|---| | **Resource server** | Endpoint that responds with a x402 payment request when called | -| **MPC network** | 3-party network that secret-shares balances and processes transfers | +| **MPC network** | 3-party network that holds secret-shared balances and processes transfers | | **Facilitator** | Off-chain service that verifies payment proofs and settles transactions | | **Merces contract** | Holds balance commitments and verifies ZK proofs on-chain | -| **Faucet** | Funds new wallets with test tokens so that clients can start paying immediately | See [Network & Contracts](../network-and-contracts) for addresses and endpoints. diff --git a/docs/finance-solutions/x402/protocol-reference.mdx b/docs/finance-solutions/x402/protocol-reference.mdx index 6daadc2..ae86cf6 100644 --- a/docs/finance-solutions/x402/protocol-reference.mdx +++ b/docs/finance-solutions/x402/protocol-reference.mdx @@ -242,7 +242,7 @@ BabyJubJub ephemeral secret key. | Leaked data | Who can see it | |---|---| -| Required payment amount | Resource server (sets it); transmitted over TLS to client | +| Required payment amount | Resource server (sets it), facilitator; transmitted over TLS to client | | API endpoint path | Resource server, facilitator | | Client wallet address | Resource server, facilitator | @@ -262,7 +262,7 @@ TACEO operates all three nodes in the current testnet deployment. The facilitator is a **liveness dependency, not a privacy dependency**. It can refuse to verify or settle payments, and it can observe which addresses are paying which resource servers. It -cannot learn payment amounts or balances, forge valid proofs or signatures, or steal funds. +cannot learn balances, forge valid proofs or signatures, or steal funds. **Merces contract** diff --git a/docs/finance-solutions/x402/quickstart.mdx b/docs/finance-solutions/x402/quickstart.mdx index efd24b1..52ef3cf 100644 --- a/docs/finance-solutions/x402/quickstart.mdx +++ b/docs/finance-solutions/x402/quickstart.mdx @@ -57,35 +57,7 @@ Each new wallet needs to be funded before it can make confidential payments. The curl -X POST https://faucet.merces.taceo.io/claim/ ``` -Replace `` with your Ethereum wallet address. If you don't have one yet, -generate a throwaway key: - - - -```typescript -import { privateKeyToAccount, generatePrivateKey } from 'viem/accounts'; - -const privateKey = generatePrivateKey(); -const account = privateKeyToAccount(privateKey); - -console.log('Private key:', privateKey); -console.log('Address:', account.address); -``` - - - - -```rust -use alloy::{hex, signers::local::PrivateKeySigner}; - -let signer = PrivateKeySigner::random(); -println!("Private key: {}", hex::encode(signer.credential().to_bytes())); -println!("Address: {}", signer.address()); -``` - - - :::warning Keep your private key safe Even on testnet, never commit private keys to source control. Use environment variables or a @@ -170,7 +142,7 @@ async fn main() -> eyre::Result<()> { When `fetchWithPayment` (or the wrapped `reqwest` client) receives a `402` response: 1. It reads the `PaymentRequired` payload from the response body. -2. The `ConfidentialEvmScheme` generates a Groth16 ZK proof (~800ms) and constructs the signed +2. The `ConfidentialEvmScheme` generates a Groth16 ZK proof (~800ms in Rust / ~60ms in SnarkJS) and constructs the signed payment payload. 3. The original request is retried with a `PAYMENT-SIGNATURE` header. 4. The TACEO resource server forwards the payment to the TACEO facilitator for verification. From 7e4df599de15f6065a5cc7d41d9ef282b8a4dd10 Mon Sep 17 00:00:00 2001 From: Fabian Gruber Date: Tue, 5 May 2026 16:54:27 +0200 Subject: [PATCH 13/25] update gas costs --- docs/finance-solutions/x402/how-it-works.mdx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/finance-solutions/x402/how-it-works.mdx b/docs/finance-solutions/x402/how-it-works.mdx index f7529bb..6c4c3ff 100644 --- a/docs/finance-solutions/x402/how-it-works.mdx +++ b/docs/finance-solutions/x402/how-it-works.mdx @@ -135,5 +135,6 @@ Alternatively, content delivery can already take places simultaneously to the se | Operation | Cost | |---|---| | Proof generation (client) | ~800ms (SnarkJS) / ~60ms (Rust) | -| On-chain proof verification | ~300,000 gas | +| On-chain proof verification (client proof) | ~800,000 gas | +| On-chain proof verification (server proof) | ~1,100,000 gas | From 6e904360f1c465ba7d253c05e373d930b1432b4c Mon Sep 17 00:00:00 2001 From: Fabian Gruber Date: Thu, 7 May 2026 11:31:35 +0200 Subject: [PATCH 14/25] update json examples --- docs/finance-solutions/x402/protocol-reference.mdx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/finance-solutions/x402/protocol-reference.mdx b/docs/finance-solutions/x402/protocol-reference.mdx index ae86cf6..e30b4b7 100644 --- a/docs/finance-solutions/x402/protocol-reference.mdx +++ b/docs/finance-solutions/x402/protocol-reference.mdx @@ -85,6 +85,7 @@ retried request. "from": "0xClient...", "to": "0xResourceServer...", "amountCommitment": "", + "amountR": "", "beta": "", "ciphertexts": ["", "", "", "", "", ""], "senderPk": ["", ""], @@ -93,7 +94,9 @@ retried request. "proof": { "pi_a": ["", "", "1"], "pi_b": [["", ""], ["", ""], ["1", "0"]], - "pi_c": ["", "", "1"] + "pi_c": ["", "", "1"], + "protocol": "groth16", + "curve": "bn254" } } } @@ -106,6 +109,7 @@ retried request. | `authorization.from` | `address` | Client's wallet address (token owner) | | `authorization.to` | `address` | Resource server's wallet address (recipient) | | `authorization.amountCommitment` | `Fr` | Poseidon2 commitment to `(amount, blindingFactor)` | +| `authorization.amountR` | `Fr` | `blindingFactor` for amount commitment | | `authorization.beta` | `Fr` | Public input derived during proof generation | | `authorization.ciphertexts` | `Fr[6]` | Six BN254 field elements: two encrypted shares per MPC operator | | `authorization.senderPk` | `[x, y]` | Ephemeral BabyJubJub public key used for ECDH encryption | From 8c30c1a0b47269d16ac1ce3a0954a6bad0fdddcf Mon Sep 17 00:00:00 2001 From: ais Date: Fri, 8 May 2026 14:45:39 +0200 Subject: [PATCH 15/25] ais pass, adding pages around finance solutions, general updates throughout, and llm files --- .../compliance/introduction.mdx | 114 ++++++ docs/finance-solutions/overview.mdx | 159 +++++++- .../payments/introduction.mdx | 123 ++++++ docs/finance-solutions/x402/how-it-works.mdx | 50 +-- .../x402/integration-guide.mdx | 2 +- docs/finance-solutions/x402/introduction.mdx | 24 +- .../x402/network-and-contracts.mdx | 2 +- .../x402/protocol-reference.mdx | 10 +- docs/finance-solutions/x402/quickstart.mdx | 16 +- docs/finance-solutions/yield/introduction.mdx | 59 +++ docs/index.mdx | 123 +++--- docs/taceo-network/governance.mdx | 2 +- docs/taceo-network/network.mdx | 2 +- docs/taceo-oprf/concepts.mdx | 2 +- docs/taceo-oprf/use-cases.mdx | 2 +- docs/taceo-proof/dev/bestpractice.mdx | 4 +- docs/taceo-proof/dev/blueprints.mdx | 6 +- docs/taceo-proof/ops/onboarding.mdx | 4 +- docs/taceo-proof/ops/ops-scaling.mdx | 2 +- docs/taceo-proof/ops/security.md | 2 +- docs/taceo-proof/overview.mdx | 2 +- docs/use-cases/defi.md | 6 +- docs/use-cases/finance.mdx | 59 ++- docusaurus.config.ts | 15 +- package-lock.json | 4 +- sidebars.ts | 48 +-- src/css/custom.css | 63 +++ src/pages/index.module.css | 367 ++++++------------ src/pages/index.tsx | 218 ++++++----- static/fonts/neue-100.woff2 | Bin 0 -> 51864 bytes static/fonts/neue-300.woff2 | Bin 0 -> 23508 bytes static/fonts/neue-400.woff2 | Bin 0 -> 23516 bytes static/fonts/neue-500.woff2 | Bin 0 -> 24876 bytes static/fonts/neue-700.woff2 | Bin 0 -> 23548 bytes static/llms.txt | 54 +++ static/robots.txt | 29 ++ 36 files changed, 1040 insertions(+), 533 deletions(-) create mode 100644 docs/finance-solutions/compliance/introduction.mdx create mode 100644 docs/finance-solutions/payments/introduction.mdx create mode 100644 docs/finance-solutions/yield/introduction.mdx create mode 100644 static/fonts/neue-100.woff2 create mode 100644 static/fonts/neue-300.woff2 create mode 100644 static/fonts/neue-400.woff2 create mode 100644 static/fonts/neue-500.woff2 create mode 100644 static/fonts/neue-700.woff2 create mode 100644 static/llms.txt create mode 100644 static/robots.txt diff --git a/docs/finance-solutions/compliance/introduction.mdx b/docs/finance-solutions/compliance/introduction.mdx new file mode 100644 index 0000000..17d19cd --- /dev/null +++ b/docs/finance-solutions/compliance/introduction.mdx @@ -0,0 +1,114 @@ +--- +title: Introduction +sidebar_label: Compliance +--- + +# Privacy-Preserving Compliance + +Compliance on Merces is a set of primitives that let regulated entities enforce KYC, AML, sanctions +screening, and Travel Rule obligations **without exposing plaintext user data**, not to the +application, not to a third-party screening engine, and not to TACEO. Compliance is built into the +payment flow at the protocol layer, not bolted on as a separate surveillance system. + +:::tip Compliance is the wedge, not the tax +Private payments cannot scale in regulated jurisdictions without compliance. The standard answer +(run KYC and monitoring on plaintext, ship PII to third-party screening engines, and log everything) +is fundamentally incompatible with privacy. Privacy-preserving compliance is what makes private +rails shippable in regulated markets at all. +::: + +## The core mechanism: selective disclosure via MPC + +By default, every Merces transaction is encrypted. The TACEO Network maintains the transaction +graph in encrypted form; only the parties involved in a transfer see its full details. No +plaintext sits anywhere in the system. + +When an authorized party (a regulator, compliance team, or other entity with reveal rights) +submits a decryption request for a specific account, the MPC network nodes **jointly approve and +perform the decryption**. The result is the transaction history for that account, returned in +plaintext. Decryption requests are scoped: they expose the selected data and nothing else. + +This same pattern underlies every Merces compliance primitive. An application or policy authority +queries the TACEO Network about a user, and the network returns a verifiable answer without +disclosing the underlying data. Sanctions screens, allowlist checks, and AML audits all share +this shape. + +ZK-only approaches give you selective disclosure but struggle with persistent identity state, +auditability, and lawful disclosure paths. MPC adds the missing pieces: stateful attestations, +multi-party authorization for reveals, and the ability to enforce policies that depend on data the +user themselves doesn't hold. + +:::note Public testnet vs. production +On the [public Plasma testnet demo](https://merces.taceo.io/compliance), anyone can try the +decryption flow. In production deployments, access is restricted to explicitly authorized +entities by policy and contract configuration. +::: + +## Compliance primitives + +| Primitive | What it does | Status | +|---|---|---| +| **Selective disclosure (decryption requests)** | Authorized parties submit decryption requests for a specific account. MPC nodes jointly approve and decrypt, returning that account's transaction history in plaintext. Same flow used for AML audits and lawful disclosure. | Live on Plasma testnet ([compliance dashboard](https://merces.taceo.io/compliance)) | +| **Wallet registration and blocklist** | Wallets must be registered in the Merces contract before transacting. Optional KYC or policy checks can be enforced at registration. Registered wallets can later be restricted or added to a blocklist by the administrator, blocking transfers to or from those accounts. | Live on Plasma testnet | +| **Programmable reveal rules** | Per-token or per-jurisdiction policies defining who can decrypt what, under which conditions | In active design | +| **Proof-of-compliance bundles** | Composable attestations a user can present (e.g. "KYC'd by issuer X, not on list Y, under threshold Z") | In active design | +| **MPKYC** | MPC-based KYC: licensed providers attest to a user once; downstream apps query the attestation without seeing the underlying PII | Design / proposal stage | +| **Travel Rule selective disclosure** | VASP-to-VASP information exchange that satisfies FATF Travel Rule without putting counterparty data on a public ledger | Design / proposal stage | + +## TACEO doesn't replace KYC. It makes KYC privacy-preserving. + +The compliance decision still belongs to a licensed provider, a KYC vendor, a screening engine, a +VASP's compliance team. What changes is **where the plaintext lives** and **who sees it**. + +In the standard model, every application that needs a compliance signal pulls the user's full +identity profile, hands it to a third-party API, and stores the result in a database. Each new +integration is another copy of the user's data and another surveillance vector. + +In the Merces model, the licensed provider attests to a property of the user **once**, into the +TACEO Network. Downstream applications query the attestation and receive a verifiable yes/no, no +data shared, no copies created, no per-integration breach surface. + +## The identity proof point + +The MPC architecture that powers Merces compliance is built on the same cryptographic foundation +TACEO co-architected for [World](https://world.org/)'s iris-code system, deployed in production +at global scale as a GDPR regulatory remediation for biometric data. The protocol underneath +Merces compliance is the same kind of system, applied to financial flows. + +## Who it's for + +| Audience | How they use it | +|---|---| +| **Fintechs and stablecoin issuers integrating Merces** | Compliance is built into the payment flow they're already shipping | +| **VASPs and regulated entities** | Satisfy AML, KYC, sanctions, and Travel Rule obligations on private rails without standing up surveillance infrastructure | +| **Licensed KYC and screening providers** | Issue privacy-preserving attestations on top of existing diligence work, expanding their reach without expanding their data exposure | +| **Compliance and policy teams** | Auditable, scoped lawful disclosure paths that don't require the application to hold plaintext | + +## Status + +Compliance primitives sit at mixed maturity: + +- **Selective disclosure** is live on Plasma testnet, exposed through the + [compliance dashboard at merces.taceo.io/compliance](https://merces.taceo.io/compliance). MPC + nodes jointly approve and perform the decryption when an authorized party submits a request. + AML audits run through this same flow. +- **Wallet registration and blocklisting** are live on Plasma. Wallets must be registered in the + Merces contract before transacting; the administrator can restrict or blocklist registered + wallets. Optional KYC or policy checks can be wired in at the registration step. +- **Programmable reveal rules and proof-of-compliance bundles** are in active design, shaped by + ongoing work with regulated partners. +- **MPKYC and Travel Rule selective disclosure** are at design / proposal stage. The use cases + are defined; the implementations are being worked through. +- **The cryptographic foundation TACEO co-architected** is in production at global scale via + World's iris-code deployment. + +The product framing, *privacy and compliance can coexist with no trade-off needed*, is the +position we are taking publicly and shipping toward. + +## Going deeper + +| Goal | Start here | +|---|---| +| Try the compliance dashboard | [merces.taceo.io/compliance](https://merces.taceo.io/compliance) | +| Understand the underlying transfer protocol | [How it works](../x402/how-it-works) | +| Talk through a regulated deployment | [Email the team](mailto:hello@taceo.io) | diff --git a/docs/finance-solutions/overview.mdx b/docs/finance-solutions/overview.mdx index a273dac..b03bd8b 100644 --- a/docs/finance-solutions/overview.mdx +++ b/docs/finance-solutions/overview.mdx @@ -1,8 +1,151 @@ -Here are some things about our Solutions. They cover the Finance and Identity verticals - -Here's where we guide you through the financial solutions -- payments -- x402 -- yield -- compliance -etc... \ No newline at end of file +--- +title: Finance Solutions Overview +description: Private onchain finance, powered by Merces +--- + +# Finance Solutions on the TACEO Network + +Public blockchains expose everything by default: balances, counterparties, amounts, transaction +flows. That's a dealbreaker for real financial operations. TACEO's finance solutions let +developers, institutions, and AI agents move value on the chains they already use without +putting their business on a public ledger. + +Our finance offering is one privacy solution, **Merces**, with multiple features on top. Merces +is TACEO's confidential token transfer protocol. It wraps existing ERC-20 tokens (such as USDC) +into a shielded form. Balances are held as secret shares across the TACEO Network, state +transitions are verified onchain via CoSNARKs, and no single party (including TACEO) sees what +anyone holds or sends. Compliance primitives are built into the protocol, not bolted on top. + +:::tip What is Merces? +Merces is an integrable privacy layer for the chain you already use. Two things set it apart: + +- **We come to you.** Merces deploys on the EVM chain you already use. No migration, no new asset. +- **Solutions, not primitives.** A payment system you can plug into a stablecoin or fintech + product, not raw cryptographic building blocks you have to assemble. + +Canonical write-up: [core.taceo.io/articles/merces-onchain-finance](https://core.taceo.io/articles/merces-onchain-finance/). +::: + +## What's available today + +Merces ships two privacy modes, selectable per transaction, plus compliance and integrations on top. + +| Capability | What it does | Status | +|---|---|---| +| **Confidential payments** | Hide amounts and balances. Sender and receiver visible. | Live on Arc and Base testnets. Demo: [merces-dashboard.taceo.io/arc](https://merces-dashboard.taceo.io/arc). | +| **Fully private payments** | Hide amounts, balances, sender, and receiver. | Live on Plasma testnet. Demo: [merces.taceo.io](https://merces.taceo.io). | +| **Compliance dashboard** | Selective disclosure to authorized auditors. | Live on Plasma testnet alongside the private payments deployment. | +| **Confidential x402** | HTTP-embedded confidential payments. | Live on Base testnet. | + +The confidential payments network has processed ~5M demo transactions across Arc and Base testnets, sustaining ~300 TPS with single-digit-cents gas per transfer on L2. Mainnet deployment is in progress. + +## Features + +
+ +
+ +### Private Payments + +Shielded ERC-20 transfers on the EVM chain you already use. Users get a private virtual account +alongside their normal public wallet. + +**Best fit:** + +- Payroll, treasury, and B2B settlement that can't be public +- Stablecoin issuers and fintechs offering confidential accounts +- White-labeled privacy rails inside an existing product + +[Learn more →](/docs/finance-solutions/payments/introduction) + +
+ +
+ +### Confidential x402 + +The HTTP 402 Payment Required protocol with hidden amounts. Drop-in privacy for x402 clients +and servers, no application code changes. + +**Best fit:** + +- Paid APIs with dynamic or negotiated pricing +- AI agents transacting across providers without leaking strategy +- Per-customer deals you can't put on a public ledger + +[Learn more →](/docs/finance-solutions/x402/introduction) + +
+ +
+ +### Compliance + +Privacy-preserving KYC, AML, sanctions, and Travel Rule. Selective disclosure via MPC, not +surveillance infrastructure. + +**Best fit:** + +- VASPs and regulated entities on private payment rails +- Fintechs integrating Merces who need compliance in the flow +- KYC providers issuing privacy-preserving attestations + +[Learn more →](/docs/finance-solutions/compliance/introduction) + +
+ +
+ +## Coming Soon + +
+ +
+ +### Private Yield + +**In active development.** + +Compliant private yield on Ethereum. Earn on shielded balances without exposing positions, +counterparties, or strategy. Designed for regulated deployment from day one. + +[Learn more →](/docs/finance-solutions/yield/introduction) + +
+ +
+ +### Private DeFi + +**On the roadmap.** + +Confidential swaps, dark pools, and approvals. Brings the shielded-balance model to swap +routers, intent flows, and DeFi composability, so traders and LPs aren't forced to broadcast +strategy to the rest of the market. + +
+ +
+ +## Going deeper + +| Goal | Start here | +|---|---| +| Add private payments to your product | [Private Payments](/docs/finance-solutions/payments/introduction) | +| Hide payment amounts on a paid API | [Confidential x402 Quickstart](/docs/finance-solutions/x402/quickstart) | +| Understand the compliance story | [Compliance](/docs/finance-solutions/compliance/introduction) | +| Read the protocol paper | [Escudero et al., IACR ePrint 2026/850](https://eprint.iacr.org/2026/850) | +| Browse the source | [github.com/TaceoLabs](https://github.com/TaceoLabs) | + +--- + +**Looking for a design partner slot?** We're working with a small group of stablecoin issuers, +fintechs, and payment infrastructure teams shipping private rails to production. +[Email the team](mailto:hello@taceo.io?subject=Merces%20design%20partner). General questions go +in [Discord](https://taceo.io/discord). diff --git a/docs/finance-solutions/payments/introduction.mdx b/docs/finance-solutions/payments/introduction.mdx new file mode 100644 index 0000000..498427e --- /dev/null +++ b/docs/finance-solutions/payments/introduction.mdx @@ -0,0 +1,123 @@ +--- +title: Introduction +sidebar_label: Private Payments +--- + +# Private Payments + +Private Payments is the core capability of [Merces](https://core.taceo.io/articles/merces-onchain-finance/), +TACEO's confidential token transfer protocol. It lets users send and receive ERC-20 tokens on a +public EVM chain, with two privacy modes that callers select per transaction. + +The integration model is API/SDK: stablecoin issuers, fintechs, and payment infrastructure builders +white-label Merces into their products. End users never see TACEO. + +:::tip Live infrastructure +Merces is live across multiple testnets today. + +- **Confidential mode** on Arc and Base testnets. Demo: [merces-dashboard.taceo.io/arc](https://merces-dashboard.taceo.io/arc). +- **Fully private mode and the compliance dashboard** on Plasma testnet. Demo: [merces.taceo.io](https://merces.taceo.io). + +The confidential network has processed ~5M demo transactions sustaining ~300 TPS, with single-digit-cents gas per transfer on L2. +::: + +## The problem with public rails + +Public blockchains expose everything by default: balances, counterparties, amounts, transaction +flows. For real financial operations this is a non-starter. + +- **Payroll** broadcasts every employee's salary to the world. +- **Treasury** moves reveal cash position, runway, and operational tempo. +- **B2B settlement** exposes customer relationships, deal sizes, and pricing structure. +- **Consumer payments** turn every wallet into a public spending diary. + +Existing privacy approaches force a trade-off. Privacy-first L1s require migrating off the chain +you've already chosen. Cryptographic toolkits hand you raw primitives and leave assembly to you. +Neither is a path most issuers, fintechs, or institutions can take to production. + +## Two privacy modes + +Merces supports two modes for transfers, selectable per transaction: + +| Mode | What's hidden | What's visible | Use when | +|---|---|---|---| +| **Confidential** | Amounts, balances, transfer history | Sender and receiver wallet addresses | You want to hide pricing or amounts but settle to known counterparty wallets. The basis for [Confidential x402](../x402/introduction). | +| **Fully private** | Amounts, balances, sender, and receiver | Nothing identifying about the transfer | You need full transaction-graph privacy: consumer payments, sensitive treasury moves, regulated user flows. | + +Both modes share the same Merces protocol, the same secret-shared balance model, and the same +compliance primitives. Callers pick the mode for each transfer. + +## How Merces works + +Merces wraps existing ERC-20 tokens (such as USDC) into a shielded form that lives alongside the +public token on the same chain. Users gain a **private virtual account** without leaving their +existing wallet, RPC, or chain. + +Three properties make this work: + +1. **Balances are held as secret shares** across the TACEO Network's MPC operators. No single + party, including TACEO, ever sees a plaintext balance or amount. +2. **State transitions are verified onchain via CoSNARKs.** Both the client's spending proof and + the MPC network's balance update proof are checked by the Merces contract before any commitment + moves. +3. **The chain stays the chain.** Merces deploys as a contract on the EVM you already use. There's + no bridge, no new consensus, no migration. + +For a step-by-step walk through the cryptographic flow (commitments, secret shares, Groth16 +proofs, EIP-712 signing, and the MPC settlement loop), see +[How it works](../x402/how-it-works), which uses the x402 payment as the worked example but +documents the underlying Merces protocol. + +## What you get + +| Capability | Status | +|---|---| +| Confidential transfers (amounts hidden, addresses visible) | Live on Arc and Base testnets | +| Fully private transfers (amounts and addresses hidden) | Live on Plasma testnet | +| Per-transaction mode selection | Live on Plasma testnet | +| Compliance dashboard with selective disclosure | Live on Plasma testnet (see [Compliance](../compliance/introduction)) | +| `transferWithAuthorization` (basis for [Confidential x402](../x402/introduction)) | Live on Base testnet | +| Allowlists at the contract layer | Live on testnet | +| Private yield | In development (see [Private Yield](../yield/introduction)) | +| Private DeFi (swaps, dark pools, approvals) | On the roadmap | +| Mainnet deployment | Shipping toward production | + +## Privacy assumptions + +In **confidential mode**, Merces hides balances, transfer amounts, and the state of the virtual +account. Sender and receiver wallet addresses remain visible onchain. + +In **fully private mode**, Merces additionally hides sender and receiver. A gateway service +abstracts gas payment and submitter identity so the transaction graph itself stays opaque. + +In both modes, no single party (including TACEO) ever sees a plaintext balance or amount. +Balances are held as MPC secret shares; reveals require explicit authorization through the +compliance flow. + +For a full privacy analysis at the protocol level, see the x402 +[Protocol reference](../x402/protocol-reference#privacy--trust-model). + +## Who it's for + +| Audience | What Merces gives them | +|---|---| +| **Stablecoin issuers** | Privacy as a feature for issued tokens, without forking the asset | +| **Fintechs and neobanks** | A confidential rail under existing user accounts | +| **Payment infrastructure builders** | An SDK-integrable shielded ledger on the EVM they already target | +| **Institutions and treasuries** | Confidential settlement on public rails for payroll, vendor payments, and intra-org transfers | +| **AI agents and agent platforms** | Spending that doesn't broadcast strategy across paid endpoints | + +## Get started + +| Goal | Start here | +|---|---| +| Try confidential payments in a browser | [merces-dashboard.taceo.io/arc](https://merces-dashboard.taceo.io/arc) | +| Try fully private payments and the compliance dashboard | [merces.taceo.io](https://merces.taceo.io) | +| See it run end-to-end with a real (test) payment via x402 | [Confidential x402 Quickstart](../x402/quickstart) | +| Understand the protocol architecture | [How it works](../x402/how-it-works) | +| Look up addresses and endpoints | [Network & Contracts](../x402/network-and-contracts) | +| Read the underlying paper | [Escudero et al., IACR ePrint 2026/850](https://eprint.iacr.org/2026/850) | +| Browse source | [github.com/TaceoLabs](https://github.com/TaceoLabs) | + +For production access, integration support, or a deeper conversation about a specific use case, +[email the team](mailto:hello@taceo.io). diff --git a/docs/finance-solutions/x402/how-it-works.mdx b/docs/finance-solutions/x402/how-it-works.mdx index 6c4c3ff..bb0981d 100644 --- a/docs/finance-solutions/x402/how-it-works.mdx +++ b/docs/finance-solutions/x402/how-it-works.mdx @@ -10,28 +10,28 @@ role and walks through a full payment end-to-end. ## Components -**Client** — the agent or application making the API request. It holds the private key to the spending wallet, generates +**Client.** The agent or application making the API request. It holds the private key to the spending wallet, generates the ZK proof, and constructs the payment payload. The client library handles all cryptographic operations; the client application only needs to register the scheme and make HTTP requests as normal. -**Resource server** — the API provider. It issues `402 Payment Required` responses, forwards +**Resource server.** The API provider. It issues `402 Payment Required` responses, forwards payment payloads to the facilitator for verification, and serves content on success. Apart from advertising `scheme: "confidential"` in its payment requirements, it behaves identically to a standard x402 resource server. -**Facilitator** — an off-chain service that verifies payment proofs and triggers settlements. It +**Facilitator.** An offchain service that verifies payment proofs and triggers settlements. It checks the ZK proof, validates the EIP-712 signature, queries the MPC network for balance -sufficiency, and submits the settlement transaction on-chain. TACEO operates a facilitator that can be +sufficiency, and submits the settlement transaction onchain. TACEO operates a facilitator that can be used directly. -**MPC network** — a committee of three operators that collectively hold secret-shared balances. No +**MPC network.** A committee of three operators that collectively hold secret-shared balances. No single operator ever sees a plaintext balance or payment amount. The network answers yes/no affordability queries during verification and processes transfers during settlement. -**Merces contract** — Stores balances in encryped form (i.e., commitments), verifies -the client's Groth16 proof on-chain during `transferFrom`, enqueues transfer actions for the MPC +**Merces contract.** Stores balances in encryped form (i.e., commitments), verifies +the client's Groth16 proof onchain during `transferFrom`, enqueues transfer actions for the MPC network, and verifies the MPC's proof when the balance update is finalised. ## Sequence diagram @@ -61,7 +61,7 @@ sequenceDiagram R->>F: POST /settle note over F: do verification (as in /verify route) F->>X: transferFrom() - Note over X: verify Groth16 proof on-chain via ClientTransferVerifier + Note over X: verify Groth16 proof onchain via ClientTransferVerifier X-->>F: action_index Note over M: read_queue, decrypt, update bal, gen proof M->>X: processMPC @@ -73,7 +73,7 @@ sequenceDiagram ## Payment flow -### Phase 1 — Discovery +### Phase 1: Discovery The client sends an unauthenticated HTTP request to a protected endpoint. The resource server checks its configuration, finds no valid payment attached, and responds with `HTTP 402 Payment @@ -81,43 +81,43 @@ Required`. The response has a `PAYMENT-REQUIRED` header, containing the base64- `confidential` scheme, the required token and amount, the recipient address, and the MPC network's current public keys. -### Phase 2 — Payment construction +### Phase 2: Payment construction The client builds the payment payload locally. No network calls are required for this step. 1. Generate a random blinding factor `r`. 2. Compute a **Poseidon2 commitment** to the amount: `commit(amount, r)`. -3. Split the amount into three additive secret shares — one per MPC operator. +3. Split the amount into three additive secret shares, one per MPC operator. 4. Encrypt each share to the corresponding operator's BabyJubJub public key using ECDH. 5. Generate a **Groth16 ZK proof** that proves all of the above is consistent: - The commitment is the hash of the true amount and blinding factor. - The three shares sum to the committed amount. - Each share is correctly encrypted to the stated operator key. - The amount fits in 80 bits. -6. Sign the full payload with **EIP-712** — binding sender, receiver, commitment, ciphertexts, nonce, and deadline. +6. Sign the full payload with **EIP-712.** Binding sender, receiver, commitment, ciphertexts, nonce, and deadline. 7. Re-send the original request with a `PAYMENT-SIGNATURE` header containing the encoded payload. -### Phase 3 — Verification +### Phase 3: Verification The resource server decodes the payment signature and forwards it to the facilitator's `/verify` endpoint. The facilitator runs a series of checks: -- **Schema match** — the accepted scheme matches `"confidential"`. -- **Recipient match** — `payload.to` equals the resource server's address. -- **Deadline** — the payment has not expired. -- **Nonce** — not already used on-chain. -- **Amount commitment match** — random blinding factor `r` and `amount` produce the provided commitment -- **Signature** — the EIP-712 signature recovers to the claimed sender. -- **ZK proof** — the Groth16 proof is valid against 15 public signals (sender key, commitment, ciphertexts, MPC keys). -- **Balance** — the facilitator queries all three MPC nodes; they collectively confirm the sender holds sufficient funds without revealing the balance to anyone. +- **Schema match.** The accepted scheme matches `"confidential"`. +- **Recipient match.** `payload.to` equals the resource server's address. +- **Deadline.** The payment has not expired. +- **Nonce.** Not already used onchain. +- **Amount commitment match.** Random blinding factor `r` and `amount` produce the provided commitment +- **Signature.** The EIP-712 signature recovers to the claimed sender. +- **ZK proof.** The Groth16 proof is valid against 15 public signals (sender key, commitment, ciphertexts, MPC keys). +- **Balance.** The facilitator queries all three MPC nodes; they collectively confirm the sender holds sufficient funds without revealing the balance to anyone. If all checks pass, the facilitator returns `{ isValid: true }` to the resource server. -### Phase 4 — Content delivery & settlement +### Phase 4: Content delivery & settlement The resource server then calls the facilitator's `/settle` endpoint. The facilitator calls `transferFrom()` on the Merces contract, passing the proof and ciphertexts. The contract verifies -the proof on-chain and enqueues a transfer action. +the proof onchain and enqueues a transfer action. The MPC network picks up the queued action, decrypts the secret shares to recover the actual amount, verifies the commitment, updates both parties' balance commitments, and generates a second @@ -135,6 +135,6 @@ Alternatively, content delivery can already take places simultaneously to the se | Operation | Cost | |---|---| | Proof generation (client) | ~800ms (SnarkJS) / ~60ms (Rust) | -| On-chain proof verification (client proof) | ~800,000 gas | -| On-chain proof verification (server proof) | ~1,100,000 gas | +| Onchain proof verification (client proof) | ~800,000 gas | +| Onchain proof verification (server proof) | ~1,100,000 gas | diff --git a/docs/finance-solutions/x402/integration-guide.mdx b/docs/finance-solutions/x402/integration-guide.mdx index e14ab37..905002e 100644 --- a/docs/finance-solutions/x402/integration-guide.mdx +++ b/docs/finance-solutions/x402/integration-guide.mdx @@ -45,7 +45,7 @@ x402-reqwest = "1" The client library intercepts any `402 Payment Required` response, constructs the ZK proof and signed payment payload, and retries the request automatically. Your application code makes a -normal HTTP request — the payment is invisible to it. +normal HTTP request, the payment is invisible to it. ### Register the scheme diff --git a/docs/finance-solutions/x402/introduction.mdx b/docs/finance-solutions/x402/introduction.mdx index aac2c4c..7ade6dc 100644 --- a/docs/finance-solutions/x402/introduction.mdx +++ b/docs/finance-solutions/x402/introduction.mdx @@ -5,9 +5,9 @@ title: Introduction # Confidential x402 Confidential x402 is a privacy extension to the x402 payment protocol that -hides payment amounts from public view while keeping the full payment flow on-chain and verifiable. +hides payment amounts from public view while keeping the full payment flow onchain and verifiable. -:::info What is x402? +:::tip What is x402? x402 is an open HTTP payment protocol for machine-to-machine payments. A resource server responds with HTTP `402 Payment Required` when a request lacks a valid payment. The client attaches a signed payment to its next request, the server verifies it, and access is granted. @@ -16,7 +16,7 @@ See the [x402 documentation](https://x402.org) for the full protocol specificati ## The problem with public payments -Standard x402 settles payments as plain ERC-20 token transfers — every amount is visible on-chain. +Standard x402 settles payments as plain ERC-20 token transfers, every amount is visible onchain. This works for flat-rate APIs, but breaks down the moment pricing becomes dynamic: - **Competitors can read your pricing strategy off the blockchain.** Every `transferWithAuthorization` @@ -37,12 +37,12 @@ transfer system. Instead of transferring a plaintext amount, the client: 3. Generates a Groth16 ZK proof that the commitment and ciphertexts are consistent. 4. Signs the payload with EIP-712 for replay protection. -The on-chain contract verifies the proof and updates balance commitments — without any plaintext -amount ever appearing on-chain. The MPC network holds balances as secret shares, so no single +The onchain contract verifies the proof and updates balance commitments, without any plaintext +amount ever appearing onchain. The MPC network holds balances as secret shares, so no single party learns what anyone has or spends. -## Get started +## Components To run a full x402 confidential payment cycle TACEO operates all required components: @@ -50,8 +50,8 @@ To run a full x402 confidential payment cycle TACEO operates all required compon |---|---| | **Resource server** | Endpoint that responds with a x402 payment request when called | | **MPC network** | 3-party network that holds secret-shared balances and processes transfers | -| **Facilitator** | Off-chain service that verifies payment proofs and settles transactions | -| **Merces contract** | Holds balance commitments and verifies ZK proofs on-chain | +| **Facilitator** | Offchain service that verifies payment proofs and settles transactions | +| **Merces contract** | Holds balance commitments and verifies ZK proofs onchain | See [Network & Contracts](../network-and-contracts) for addresses and endpoints. @@ -59,12 +59,14 @@ See [Network & Contracts](../network-and-contracts) for addresses and endpoints. ## Privacy assumptions Confidential x402 hides **payment amounts** and **account balances**. It does not hide sender or -receiver addresses, payment frequency, or the sender–receiver relationship. For a full privacy +receiver addresses, payment frequency, or the sender-receiver relationship. For a full privacy analysis, see [Privacy & Trust Model](../protocol-reference/#privacy--trust-model). :::info[Private Payments] -The current payment model is built on confidential transfers i.e., intentionally leaking the involved wallet addresses. -An upgrade to **fully private payments** is planned in upcoming versions of the protocol +Confidential x402 uses Merces' **confidential mode** (amounts hidden, addresses visible). +Merces also supports a **fully private mode** that hides sender and receiver addresses as well, +live on Plasma testnet today. Exposing fully private mode through the x402 scheme is planned +for an upcoming version. ::: ## Where to go next diff --git a/docs/finance-solutions/x402/network-and-contracts.mdx b/docs/finance-solutions/x402/network-and-contracts.mdx index 6f4378e..8a0d30f 100644 --- a/docs/finance-solutions/x402/network-and-contracts.mdx +++ b/docs/finance-solutions/x402/network-and-contracts.mdx @@ -61,7 +61,7 @@ curl -X POST https://faucet.merces.taceo.io/claim/0xYourWalletAddress |---|---| | `200 OK` | Tokens deposited successfully | | `429 Too Many Requests` | Address already claimed within the last 24 hours | -| `500 Internal Server Error` | Faucet encountered an error — try again shortly | +| `500 Internal Server Error` | Faucet encountered an error, try again shortly | ## MPC public keys diff --git a/docs/finance-solutions/x402/protocol-reference.mdx b/docs/finance-solutions/x402/protocol-reference.mdx index e30b4b7..95de7d6 100644 --- a/docs/finance-solutions/x402/protocol-reference.mdx +++ b/docs/finance-solutions/x402/protocol-reference.mdx @@ -225,14 +225,14 @@ BabyJubJub ephemeral secret key. | Data | Standard x402 | Confidential x402 | How | |---|---|---|---| -| Transfer amounts | Plaintext in `transferWithAuthorization` | Poseidon2 commitment on-chain | Real amount secret-shared across MPC network | -| Account balances | Public via ERC-20 `balanceOf()` | Only a commitment stored on-chain | Actual balances held as secret shares by MPC operators | +| Transfer amounts | Plaintext in `transferWithAuthorization` | Poseidon2 commitment onchain | Real amount secret-shared across MPC network | +| Account balances | Public via ERC-20 `balanceOf()` | Only a commitment stored onchain | Actual balances held as secret shares by MPC operators | | Spending patterns | Full payment history enables behaviour profiling | Observers can count payments but cannot sum amounts | Amounts hidden; only frequency and counterparties visible | -| Price discrimination evidence | On-chain proof of what each user paid | No on-chain evidence of negotiated price | Resource server holds client payment data off-chain | +| Price discrimination evidence | Onchain proof of what each user paid | No onchain evidence of negotiated price | Resource server holds client payment data offchain | ### What is not protected -**On-chain:** +**Onchain:** | Leaked data | Source | Impact | |---|---|---| @@ -278,5 +278,5 @@ nonce uniqueness and deadline expiry. ### Roadmap to stronger privacy The current `confidential` scheme hides amounts and balances. Sender and receiver addresses remain -visible on-chain. Future versions will include an enhanced variant that additionally hide +visible onchain. Future versions will include an enhanced variant that additionally hide the sender–receiver relationship, building on Merces' existing support for fully private transactions. diff --git a/docs/finance-solutions/x402/quickstart.mdx b/docs/finance-solutions/x402/quickstart.mdx index 52ef3cf..bd704d2 100644 --- a/docs/finance-solutions/x402/quickstart.mdx +++ b/docs/finance-solutions/x402/quickstart.mdx @@ -9,7 +9,7 @@ import TabItem from '@theme/TabItem'; # Quickstart This guide gets you making a confidential payment in under five minutes using TACEO's hosted -infrastructure — no contract deployment, no facilitator setup required. +infrastructure, no contract deployment, no facilitator setup required. You will: 1. Fund a new wallet with test tokens from the faucet. @@ -19,9 +19,9 @@ You will: ## Prerequisites - Node.js 18+ (TypeScript) or Rust 1.90+ (Rust) -- A wallet private key (or generate one — instructions below) +- A wallet private key (or generate one, instructions below) -## Step 1 — Install the package +## Step 1: Install the package @@ -48,7 +48,7 @@ x402-reqwest = "1" -## Step 2 — Get test tokens from the faucet +## Step 2: Get test tokens from the faucet Each new wallet needs to be funded before it can make confidential payments. The faucet deposits 1,000 test tokens and enforces a 24-hour cooldown per address. @@ -64,10 +64,10 @@ Even on testnet, never commit private keys to source control. Use environment va secrets manager. ::: -## Step 3 — Send a confidential payment +## Step 3: Send a confidential payment The client library intercepts the `402 Payment Required` response, constructs the proof, and -retries the request automatically. Your application code makes a normal HTTP GET — the payment +retries the request automatically. Your application code makes a normal HTTP GET, the payment is invisible to it. @@ -85,7 +85,7 @@ const signer = privateKeyToAccount(privateKey); const client = new x402Client(); client.register('eip155:*', new ConfidentialEvmScheme(signer)); -// Wrap fetch — payments are handled automatically +// Wrap fetch, payments are handled automatically const fetchWithPayment = wrapFetchWithPayment(fetch, client); // Make the request as normal @@ -116,7 +116,7 @@ async fn main() -> eyre::Result<()> { let x402_client = X402Client::new() .register(V2Eip155ConfidentialClient::new(signer)); - // Wrap reqwest — payments are handled automatically + // Wrap reqwest, payments are handled automatically let http_client = Client::new() .with_payments(x402_client) .build(); diff --git a/docs/finance-solutions/yield/introduction.mdx b/docs/finance-solutions/yield/introduction.mdx new file mode 100644 index 0000000..b7b92ff --- /dev/null +++ b/docs/finance-solutions/yield/introduction.mdx @@ -0,0 +1,59 @@ +--- +title: Introduction +sidebar_label: Private Yield +--- + +# Private Yield + +Private Yield brings compliant, confidential yield to Ethereum, built on top of +[Merces](../payments/introduction). Users earn on shielded balances without exposing positions, +counterparty relationships, or strategy onchain, and without giving up the regulatory posture +required to operate in real markets. + +:::info Coming soon +Private Yield is in active development. The capability extends Merces from a confidential transfer +system into a confidential earning system, while keeping the same integration model and the same +compliance primitives. +::: + +## Why this is hard today + +Public DeFi yield broadcasts every position. Anyone can read a wallet's allocations, infer +strategy, copy or front-run trades, and reconstruct counterparty graphs. For institutions, +treasuries, and any user that values strategic privacy, that exposure is the reason they aren't +onchain at all. + +The two existing paths each fail in their own way: + +- **Move to a private chain.** Forces migration off Ethereum and away from the assets, liquidity, + and integrations that matter. +- **Use a privacy mixer.** Obscures flows but doesn't compose with regulated counterparties or + give institutions a defensible compliance story. + +## What we're building + +Private Yield uses the same Merces shielded-balance model as +[Private Payments](../payments/introduction) and [Confidential x402](../x402/introduction): +balances held as secret shares across the TACEO Network, state transitions verified onchain via +CoSNARKs, compliance primitives built into the protocol layer. + +The yield layer adds the ability for shielded balances to participate in earning strategies, +without revealing positions, without leaving Ethereum, and without compromising the compliance +guarantees that make these rails deployable in regulated markets. + +## What's planned + +- Yield on shielded ERC-20 balances (starting with USDC) +- Allowlists and reveal rules carried through from Merces' [Compliance](../compliance/introduction) + layer +- The same SDK integration model as Private Payments, issuers and fintechs can offer yield + inside their existing product surface + +## Stay in the loop + +Private Yield is shipping toward public testnet. To get early access, integration support, or to +discuss a specific use case, [email the team](mailto:hello@taceo.io) or +[join Discord](https://taceo.io/discord). + +In the meantime, the foundation is already live, see [Private Payments](../payments/introduction) +to understand the transfer system this builds on. diff --git a/docs/index.mdx b/docs/index.mdx index edab7ae..cdfb7d8 100644 --- a/docs/index.mdx +++ b/docs/index.mdx @@ -2,99 +2,110 @@ id: index title: Welcome to TACEO slug: / -description: Start here to understand TACEO Network, privacy services, and developer tooling +description: Private onchain finance, integrable privacy services, and the TACEO Network that powers them --- import Link from "@docusaurus/Link"; # Welcome to TACEO -TACEO provides private execution infrastructure for applications that need to compute on sensitive data without exposing inputs. +TACEO provides a privacy layer for applications that need to compute on +sensitive data without exposing inputs. Our **finance solutions** sit on top of **integrable +privacy services**, all powered by the **TACEO Network**, a production MPC network already +running at global scale. -This documentation is organized around three areas: the **TACEO Network**, **production privacy services** such as TACEO:OPRF and TACEO:Proof, and **developer tooling** for collaborative zero-knowledge workflows (coSNARKs). +We're best known for our identity work: TACEO Network is a privacy backbone for +global-scale identity systems, with services used by **World** and **zkPassport**. We're now bringing +the same stack to onchain finance through **Merces**. -If you are new, start by choosing the path that best matches your goal. This page is designed to help you get oriented quickly and then move into the right part of the documentation. +## Build private payments on the chain you already use -## Choose your path +
-
+### **Finance Solutions** -
- -**Understand how the TACEO Network works** - +Private payments on the EVM chains you already use, built on Merces. Merces wraps ERC-20s like USDC into shielded balances, with compliance primitives at the protocol layer. -
+**Live on Arc, Base, and Plasma testnets.** ~5M demo transactions, ~300 TPS, single-digit-cents gas on L2. Mainnet deployment in progress. The MPC protocol underneath is the same one TACEO co-architected for World's iris-code system, in production at global scale. -**Best for:** Potential customers, partners, and technical stakeholders +**Looking for design partners.** Stablecoin issuers, fintechs, and payment infrastructure teams shipping private rails to production. Talk to us. -Learn how the network enables verifiable collaboration over encrypted data, what security assumptions it relies on, and why private execution matters for real applications. +{/* prettier-ignore */} +
+ Read Finance Solutions + Try the Quickstart + Become a Design Partner +
-**Start here:** +
-1. **[Read Network Overview](/docs/taceo-network/)** - Understand the motivation and system model -2. **[Review Architecture](/docs/taceo-network/network#taceo-network-how-it-works)** - See how the network operates +## Other paths -**Next steps:** Explore the [Security Model](/docs/taceo-network/node-operators#security-model) and [Network Governance](/docs/taceo-network/governance) +
-
-
+
-
- -**Add privacy services to my application** - +### **Privacy Services** -
+_OPRF, Proof, OMap_ -**Best for:** Application developers, product teams, and technical founders +Production-ready privacy primitives you can call directly: privacy-preserving nullifiers +(TACEO:OPRF), private proof delegation (TACEO:Proof), and confidential shared state (TACEO:OMap). -Use TACEO services when you want production-ready privacy primitives in your application, such as privacy-preserving nullifiers with TACEO:OPRF or private proof delegation with TACEO:Proof. +**Use this if you are:** an application developer adding a single privacy feature without taking +on a full payment system. -**Start here:** +{/* prettier-ignore */} +Explore Services -1. **[Get an overview of the TACEO Services](/docs/services/overview)** - Compare TACEO:OPRF, TACEO:Proof and see upcoming services -2. **[Explore TACEO:OPRF](/docs/taceo-oprf/overview)** - Understand privacy-preserving nullifiers and OPRFs -3. **[Explore TACEO:Proof](/docs/taceo-proof/overview)** - Understand private proof delegation +
-**Next steps:** [Email us for production access](mailto:hello@taceo.io) and [join Discord](https://taceo.io/discord) for technical support +
-
-
+### **TACEO Network** -
- -**Experiment with collaborative SNARKs** - +_The MPC network underneath_ -
+Understand how the network enables verifiable collaboration over encrypted data, the security +model, and governance. The same MPC foundation TACEO co-architected for World's iris-code +system runs in production at global scale. -**Best for:** Crypto developers, researchers, and privacy-tech experimenters +**Use this if you are:** a partner, technical stakeholder, or potential node operator evaluating +the foundation everything else builds on. -Experiment with coCircom and coNoir to run collaborative zero-knowledge workflows in an MPC setting. These tools are intended for developers exploring custom circuits and coSNARK-based systems. +{/* prettier-ignore */} +Explore the Network -**Start here:** +
-1. **[CoSNARKs Overview](/docs/overview)** - Understand collaborative zero-knowledge proofs -2. **[Install Tools](/docs/getting-started/install)** - Set up coCircom or coNoir locally -3. **[Run an Example](/docs/getting-started/quick-start-co-circom)** - Try your first collaborative circuit +
-**Next steps:** Explore [examples](/docs/examples/) and [network configuration](/docs/network-config/) +### **Collaborative SNARKs** -**Note:** These tools are currently for experimentation and development. They require running your own MPC environment and are not the same as using TACEO’s managed services. +_coCircom, coNoir_ -
-
+Experiment with collaborative zero-knowledge workflows in an MPC setting. Run custom circuits and +coSNARK-based systems locally. Distinct from TACEO's managed services. + +**Use this if you are:** a crypto developer, researcher, or privacy-tech experimenter. + +{/* prettier-ignore */} +Experiment
-## What is available today +
-- **TACEO Network documentation** explains the system architecture, security model, and application context -- **TACEO:OPRF** and **TACEO:Proof** are the main service entry points for teams looking to integrate privacy features -- **Developer tooling** is available for teams exploring MPC-based proving workflows +## Where TACEO is today -This means some parts of the docs describe production-oriented services, while others describe lower-level or experimental developer workflows. If you are evaluating TACEO for an application, the services section is usually the right place to begin. +- **Finance Solutions.** Merces is live on Arc, Base, and Plasma testnets with ~5M demo transactions, ~300 TPS, and single-digit-cents gas on L2. Mainnet deployment in progress. +- **Privacy Services.** TACEO:OPRF and TACEO:Proof are in production for partners including World and zkPassport. +- **TACEO Network.** The MPC infrastructure underpinning all of the above is built on the same foundation TACEO co-architected for World's iris-code system, in production at global scale. ## Learning Resources @@ -125,10 +136,10 @@ New to privacy-preserving computation? Start here:
  • - Identity & Uniqueness + Finance
  • - Finance + Identity & Uniqueness
  • More Use Cases @@ -180,4 +191,4 @@ New to privacy-preserving computation? Start here: --- -**Ready to dive deeper?** Use the sidebar to explore the TACEO Network, Services, and Developer Tools sections. +**Ready to dive deeper?** Use the sidebar to explore Finance Solutions, Services, the TACEO Network, and Developer Tools. diff --git a/docs/taceo-network/governance.mdx b/docs/taceo-network/governance.mdx index fd04654..1ef37ba 100644 --- a/docs/taceo-network/governance.mdx +++ b/docs/taceo-network/governance.mdx @@ -15,7 +15,7 @@ Current governance responsibilities include: Applications using the network are involved in upgrade coordination for the services they depend on. -Major changes are coordinated through an off-chain process with production integrators so service evolution is aligned with real workload requirements. +Major changes are coordinated through an offchain process with production integrators so service evolution is aligned with real workload requirements. ## Node participation diff --git a/docs/taceo-network/network.mdx b/docs/taceo-network/network.mdx index 7312cb6..6cca413 100644 --- a/docs/taceo-network/network.mdx +++ b/docs/taceo-network/network.mdx @@ -35,7 +35,7 @@ Requests generally follow the same high-level flow: An application sends a request through a TACEO service API, for example proof generation, OPRF evaluation, or private state updates. 2. **Service coordination** - The request is handled by a specific service instance. Each instance has its own cryptographic keys, committee configuration, and operational policy, which can be handled by traditional off-chain processes or an on-chain smart contract. + The request is handled by a specific service instance. Each instance has its own cryptographic keys, committee configuration, and operational policy, which can be handled by traditional offchain processes or an onchain smart contract. 3. **Distributed MPC execution** A committee of MPC nodes executes the protocol over encrypted or secret-shared inputs. It also optionally generates a coSNARK of the correct execution of the protocol. diff --git a/docs/taceo-oprf/concepts.mdx b/docs/taceo-oprf/concepts.mdx index 8f3bf58..d1a7ce6 100644 --- a/docs/taceo-oprf/concepts.mdx +++ b/docs/taceo-oprf/concepts.mdx @@ -41,7 +41,7 @@ TACEO:OPRF builds on the OPRF design with threshold security: The TACEO:OPRF architecture consists of: 1. Independent OPRF nodes that hold shares of the OPRF secret key(s) -2. On-chain public registry of corresponding OPRF public keys +2. Onchain public registry of corresponding OPRF public keys 3. Authorized accounts that can trigger secure key generation ![TACEO_OPRF.png](TACEO_OPRF.png) diff --git a/docs/taceo-oprf/use-cases.mdx b/docs/taceo-oprf/use-cases.mdx index cec9338..45c69fb 100644 --- a/docs/taceo-oprf/use-cases.mdx +++ b/docs/taceo-oprf/use-cases.mdx @@ -42,7 +42,7 @@ DeFi protocols need to pay referral fees and track user activity, but current me ### Current Surveillance Model - Referral tracking requires linking wallets to referrers - Fee distribution exposes user trading patterns -- On-chain analysis reveals complete transaction history +- Onchain analysis reveals complete transaction history ### TACEO:OPRF Solution diff --git a/docs/taceo-proof/dev/bestpractice.mdx b/docs/taceo-proof/dev/bestpractice.mdx index f3147a5..04dfa7b 100644 --- a/docs/taceo-proof/dev/bestpractice.mdx +++ b/docs/taceo-proof/dev/bestpractice.mdx @@ -57,13 +57,13 @@ The choice depends on your use case. Here’s what to consider: **Use Shamir when...** * You’ve already **computed the extended witness** locally and can take the increased upload. -* You want **stronger security guarantees**—the protocol still falls under the assumptions in the referenced paper, resulting in a notion of active security. +* You want **stronger security guarantees**, the protocol still falls under the assumptions in the referenced paper, resulting in a notion of active security. * You’re okay with slightly larger uploads and minimal performance gains in return for stricter protocol guarantees. ### Handling proof latencies & fallbacks When scheduling a coSNARK execution, there are a few practical steps and strategies to help reduce latency and improve robustness in case of failures. - - You can **cache** the used **node operators** temporarily if you're planning to submit additional proofs soon after. Just be aware that **node operators can go offline** — if a cached key is stale, your request will fail at scheduling time. + - You can **cache** the used **node operators** temporarily if you're planning to submit additional proofs soon after. Just be aware that **node operators can go offline.** If a cached key is stale, your request will fail at scheduling time. This reduces them amount of API calls to schedule a coSNARK job to just 1! - After encrypting your input shares for the selected providers, you include the corresponding Node Provider IDs and submit the job. diff --git a/docs/taceo-proof/dev/blueprints.mdx b/docs/taceo-proof/dev/blueprints.mdx index afa2c5c..4ca986d 100644 --- a/docs/taceo-proof/dev/blueprints.mdx +++ b/docs/taceo-proof/dev/blueprints.mdx @@ -1,5 +1,5 @@ # Blueprints and Vouchers -At the heart of TACEO:Proof are *blueprints* — registered circuit definitions that specify everything the network needs to generate a coSNARK proof. A blueprint contains the circuit, proving key, and verification key, and it defines how the proof will be computed. +At the heart of TACEO:Proof are *blueprints*, registered circuit definitions that specify everything the network needs to generate a coSNARK proof. A blueprint contains the circuit, proving key, and verification key, and it defines how the proof will be computed. Developers and projects that want to delegate private proof generation to the network can register on TACEO:Proof and upload their own blueprints. We currently support the following blueprint types: @@ -22,14 +22,14 @@ Registered users can upload and manage blueprints either through our API or the Blueprints can be either public or restricted: -* Public blueprints can be used by any user who knows the identifier—no additional authorization needed. +* Public blueprints can be used by any user who knows the identifier, no additional authorization needed. * Restricted blueprints require a voucher, issued by the blueprint creator, to schedule jobs. This allows for fine-grained access control over who can generate proofs. Vouchers serve as short-lived, verifiable permits. They authorize the use of a specific blueprint and can include additional constraints such as usage limits or expiration. ### Getting and using vouchers -To use a **restricted blueprint**, users must first obtain **a voucher** from the blueprint creator. This process involves an out-of-band authentication step—TACEO:Proof does not manage or enforce this interaction. It’s entirely up to the application or project to decide how users are verified and approved. +To use a **restricted blueprint**, users must first obtain **a voucher** from the blueprint creator. This process involves an out-of-band authentication step, TACEO:Proof does not manage or enforce this interaction. It’s entirely up to the application or project to decide how users are verified and approved. Once a user is deemed eligible, the blueprint creator authenticates with the CCL using their credentials. The CCL then issues a signed voucher, which is returned to the user. diff --git a/docs/taceo-proof/ops/onboarding.mdx b/docs/taceo-proof/ops/onboarding.mdx index c7fe18c..56f6b14 100644 --- a/docs/taceo-proof/ops/onboarding.mdx +++ b/docs/taceo-proof/ops/onboarding.mdx @@ -1,10 +1,10 @@ # Onboarding as a Node Provider for TACEO:Proof -TACEO:Proof is currently in the early stages of decentralization. At this time, we operate a permissioned network with a vetted set of node operators. However, we're actively expanding, and if you're interested in joining as a Node Provider, we’d love to hear from you—reach [out here](mailto:office@taceo.io). +TACEO:Proof is currently in the early stages of decentralization. At this time, we operate a permissioned network with a vetted set of node operators. However, we're actively expanding, and if you're interested in joining as a Node Provider, we’d love to hear from you, reach [out here](mailto:office@taceo.io). ## Hardware & Network Prerequisites To ensure reliable performance, we expect node operators to be able to run **multiple CSEs** in parallel. Running only a single CSE introduces bottlenecks: all jobs assigned to your node would have to queue behind that one instance, slowing down the entire network. -Since we’re still using a permissioned set of node operators, we can’t tackle throughput by sheer amount of online nodes. That’s why your setup should support **horizontal scaling**—multiple CSEs running simultaneously. +Since we’re still using a permissioned set of node operators, we can’t tackle throughput by sheer amount of online nodes. That’s why your setup should support **horizontal scaling**, multiple CSEs running simultaneously. ### Performance Requirements Each CSE should be able to execute our [Groth16 prover](https://github.com/TaceoLabs/co-snarks/tree/main/co-circom/co-groth16) for a circuit of size $2^{16}$ **in under one second**. This is our current baseline for acceptable latency and throughput. diff --git a/docs/taceo-proof/ops/ops-scaling.mdx b/docs/taceo-proof/ops/ops-scaling.mdx index 483fc7a..9bd57a8 100644 --- a/docs/taceo-proof/ops/ops-scaling.mdx +++ b/docs/taceo-proof/ops/ops-scaling.mdx @@ -23,7 +23,7 @@ While we don’t ingest logs or metrics, your CSE _does_ send minimal runtime me These are used solely for **job-level tracing and auditing**, not continuous telemetry. ## Auto-Recovery & Failover -Each CSE instance is **stateless** and identified by your secret key phrase. From TACEO:Proof’s perspective, **restarting your CSE creates a fresh logical instance**—there’s no persistent session management required. +Each CSE instance is **stateless** and identified by your secret key phrase. From TACEO:Proof’s perspective, **restarting your CSE creates a fresh logical instance**, there’s no persistent session management required. If you’re using our official Docker image, it comes preconfigured with: ```yaml diff --git a/docs/taceo-proof/ops/security.md b/docs/taceo-proof/ops/security.md index a5ef9b5..e13f0c7 100644 --- a/docs/taceo-proof/ops/security.md +++ b/docs/taceo-proof/ops/security.md @@ -8,7 +8,7 @@ Every Node Provider is assigned a unique **key phrase**, which serves as the see * A **signing key** (used to authenticate messages and proofs) The public parts of these keys are uploaded during initial registration with the TACEO:Proof network. -> ⚠️ TACEO will never ask for your key phrase. Do not share your key phrase with _anyone_—not even someone claiming to represent TACEO. +> ⚠️ TACEO will never ask for your key phrase. Do not share your key phrase with _anyone_, not even someone claiming to represent TACEO. The CSE binary enforces a minimum entropy requirement for key phrases to help prevent weak seeds. However, it is your responsibility to: * Keep the key phrase **strictly local** to your machine. diff --git a/docs/taceo-proof/overview.mdx b/docs/taceo-proof/overview.mdx index ef2425e..0e1d4db 100644 --- a/docs/taceo-proof/overview.mdx +++ b/docs/taceo-proof/overview.mdx @@ -40,7 +40,7 @@ Clients submit encrypted input shares and a short-lived voucher, and receive bac You receive the node operators with their ids, encryption keys and verification keys. You should request a new set of node operators for each coSNARK job to decrease waiting times. We do not recommend to use the same node operators over a longer period of time. - But you may **cache** them temporarily if you're planning to submit additional proofs soon after. Just be aware that **node operators can go offline** — if a cached key is stale, your request will fail at scheduling time. + But you may **cache** them temporarily if you're planning to submit additional proofs soon after. Just be aware that **node operators can go offline.** If a cached key is stale, your request will fail at scheduling time. > 💡 If you're submitting multiple proofs at once, you can reuse the same set of node operators across jobs. This reduces the number of HTTP calls and enables you to encrypt in parallel. diff --git a/docs/use-cases/defi.md b/docs/use-cases/defi.md index 5ac4833..ee292a3 100644 --- a/docs/use-cases/defi.md +++ b/docs/use-cases/defi.md @@ -1,11 +1,11 @@ # DeFi -Decentralized Finance (DeFi) is transforming the traditional financial landscape by offering open, permissionless, and transparent services. However, privacy and security remain significant challenges. Public on-chain information relating to a user’s financial records, trade intentions or identity could be misused in a sense that the user ends up with worse terms and economic disadvantages. +Decentralized Finance (DeFi) is transforming the traditional financial landscape by offering open, permissionless, and transparent services. However, privacy and security remain significant challenges. Public onchain information relating to a user’s financial records, trade intentions or identity could be misused in a sense that the user ends up with worse terms and economic disadvantages. -For instance, publishing a large limit order on-chain immediately reveals the intention of a user to sell or buy a certain asset in high quantities. Market participants know how to use this new piece of information to their advantage. Traditional finance faced the same issue with public stock markets. As a response they introduced so-called Dark Pools, which keep the price impact for large quantity trades as low as possible by matching trades privately. +For instance, publishing a large limit order onchain immediately reveals the intention of a user to sell or buy a certain asset in high quantities. Market participants know how to use this new piece of information to their advantage. Traditional finance faced the same issue with public stock markets. As a response they introduced so-called Dark Pools, which keep the price impact for large quantity trades as low as possible by matching trades privately. In TradFi Dark Pools work because market participations trust a central entity to run the service. Blockchains aim for getting rid of these types of intermediaries. However, running a Dark Pool via a public Smart Contract would not work, since all sensitive information would immediately be leaked. We need to make sure that sensitive information (e.g. Limit order: I want to buy 10 BTC @ price $100k) is kept private. Yet, at some point multiple private inputs need to be combined so that a buy order can be matched with a sell order. -co-SNARKs have the ability to compute on multiple, encrypted user inputs, while not leaking any information about the inputs itself. For the example of on-chain Dark Pools, users could submit their desire to trade large quantities in an encrypted form to the MPC network, which processes and match trades with each other. Market participants don't get any information headstart they could use for their very own advantage and users get the best price possible. +co-SNARKs have the ability to compute on multiple, encrypted user inputs, while not leaking any information about the inputs itself. For the example of onchain Dark Pools, users could submit their desire to trade large quantities in an encrypted form to the MPC network, which processes and match trades with each other. Market participants don't get any information headstart they could use for their very own advantage and users get the best price possible. diff --git a/docs/use-cases/finance.mdx b/docs/use-cases/finance.mdx index 2ca8446..748ad06 100644 --- a/docs/use-cases/finance.mdx +++ b/docs/use-cases/finance.mdx @@ -1,24 +1,55 @@ -# Private onchain accounts for payroll, treasury, and B2B payments +--- +title: Finance +description: Confidential payments, treasury, and B2B settlement on the chains you already use +--- -Onchain financial systems offer transparency and programmability, but this transparency comes at a cost. Public transaction data exposes balances, counterparties, and intent, which can be exploited or make systems unusable for real-world financial operations. +# Confidential payments, treasury, and B2B settlement on public chains -For instance, executing payroll, treasury transfers, or large trades on public infrastructure reveals sensitive financial information. This creates risks ranging from front-running to operational exposure, and prevents many institutions from adopting onchain rails. +Onchain financial systems offer transparency and programmability, but that transparency comes at +a cost. Public transaction data exposes balances, counterparties, and intent, which can be +exploited, and which makes onchain rails unusable for most real-world financial operations. -Traditional finance solves this through private accounts and restricted data access, but relies on centralized intermediaries. +Executing payroll, treasury transfers, vendor payments, or large trades on a public ledger reveals +sensitive financial information by default. This creates risks that range from front-running and +copy-trading to operational exposure of business relationships, deal sizes, and pricing strategy. +For most institutions, it's the reason they aren't on public rails at all. -We need onchain financial infrastructure where balances, transactions, and counterparties remain private by default, while still enabling verifiable execution and settlement. +Traditional finance solves this through private accounts and restricted data access, but relies +on centralized intermediaries. The challenge is to get the same confidentiality guarantees on a +public, programmable chain, without giving up settlement guarantees or compliance posture. -TACEO enables this through **private shared state services (e.g. TACEO:OMap)**, which allow encrypted balances and financial data to be updated and queried without being revealed. Transactions are executed across the MPC network, ensuring correctness while keeping all sensitive inputs hidden. +## TACEO's answer: Merces -This model is particularly relevant for stablecoin-based financial flows (USDC), where confidentiality of balances and transfers is required for real-world usage. It also aligns with emerging standards such as x402, where payments are embedded directly into application-layer interactions (e.g. HTTP requests), enabling programmable financial flows across services. +TACEO addresses this through **[Merces](/docs/finance-solutions/payments/introduction)**, a +confidential token transfer protocol that wraps existing ERC-20 tokens (e.g. USDC) into shielded +balances on the EVM chain you already use. Balances are held as secret shares across the +[TACEO Network](/docs/taceo-network/), state transitions are verified onchain via CoSNARKs, and +no single party, including TACEO, sees what anyone holds or sends. -Selective disclosure can be added when required, enabling compliance or auditing without compromising baseline privacy. +Merces is a complete, integrable privacy layer rather than a new chain or a raw cryptographic +toolkit. Stablecoin issuers, fintechs, and payment infrastructure builders white-label it into +their products; end users never see TACEO. -This allows financial applications to combine the programmability and settlement guarantees of blockchains with the privacy properties of traditional financial systems. +This model is particularly relevant for stablecoin-based financial flows, where confidentiality +of balances and transfers is required for real-world usage. It also aligns with emerging standards +such as **[x402](/docs/finance-solutions/x402/introduction)**, which embeds payments directly into +HTTP request flows and enables confidential machine-to-machine and AI-agent payments. -Examples of this can be found in [Merces](https://merces-dashboard.taceo.io/arc). +**[Compliance](/docs/finance-solutions/compliance/introduction)** is built into the protocol, not +bolted on top: allowlists, AML hooks, programmable reveal rules, and selective-disclosure +attestations let regulated entities meet KYC, sanctions, and Travel Rule obligations without +running surveillance infrastructure. -Next steps: -- [TACEO Services Overview](/docs/services/overview) -- [TACEO:OPRF for identity controls](/docs/use-cases/identity) -- [Learn more about OMAP](https://core.taceo.io/articles/taceo-omap/) \ No newline at end of file +This lets financial applications combine the programmability and settlement guarantees of public +blockchains with the privacy properties of traditional financial systems. + +A live demo runs at [merces.taceo.io](https://merces.taceo.io). + +## Where to go next + +- **[Finance Solutions overview](/docs/finance-solutions/overview).** The full product section +- **[Private Payments](/docs/finance-solutions/payments/introduction).** Merces in depth +- **[Confidential x402](/docs/finance-solutions/x402/introduction).** Payments over HTTP +- **[Privacy-preserving Compliance](/docs/finance-solutions/compliance/introduction).** KYC, AML, and selective disclosure +- **[TACEO:OPRF for identity controls](/docs/use-cases/identity).** Companion identity primitive +- **[Merces: Onchain Finance](https://core.taceo.io/articles/merces-onchain-finance/).** Long-form write-up diff --git a/docusaurus.config.ts b/docusaurus.config.ts index 5d808df..a9c2867 100644 --- a/docusaurus.config.ts +++ b/docusaurus.config.ts @@ -6,7 +6,8 @@ import rehypeKatex from "rehype-katex"; const config: Config = { title: "TACEO Documentation", - tagline: "MPC and coSNARKs for Proof Delegation and Private Shared State", + tagline: + "Private onchain finance, integrable privacy services, and the network underneath.", favicon: "img/favicon.png", // Set the production url of your site here @@ -131,21 +132,21 @@ const config: Config = { title: "Docs", items: [ { - label: "TACEO Network", - to: "/docs/taceo-network/", + label: "Finance Solutions", + to: "/docs/finance-solutions/overview", }, { label: "Privacy Services", to: "/docs/services/overview", }, + { + label: "TACEO Network", + to: "/docs/taceo-network/", + }, { label: "Developer Tools", to: "/docs/overview", }, - // { - // label: "Infrastructure", - // to: "/docs/taceo-proof/ops/onboarding", - // }, ], }, { diff --git a/package-lock.json b/package-lock.json index e49156c..49d3be4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,9 +12,9 @@ "@algolia/autocomplete-shared": "^1.19.2", "@algolia/client-search": "^5.34.1", "@docusaurus/core": "3.8.1", - "@docusaurus/plugin-client-redirects": "^3.8.1", + "@docusaurus/plugin-client-redirects": "3.8.1", "@docusaurus/preset-classic": "3.8.1", - "@docusaurus/theme-mermaid": "^3.8.1", + "@docusaurus/theme-mermaid": "3.8.1", "@mdx-js/react": "^3.1.0", "algoliasearch": "^5.34.1", "clsx": "^2.0.0", diff --git a/sidebars.ts b/sidebars.ts index 1383973..853f3a2 100644 --- a/sidebars.ts +++ b/sidebars.ts @@ -16,13 +16,26 @@ const sidebars: SidebarsConfig = { "index", { type: "category", - label: "TACEO Network", - link: { type: "doc", id: "taceo-network/index" }, + label: "Finance Solutions", + collapsed: false, + link: { type: "doc", id: "finance-solutions/overview" }, items: [ - "taceo-network/network", - "taceo-network/node-operators", - "taceo-network/governance", - "taceo-network/roadmap", + "finance-solutions/payments/introduction", + { + type: "category", + label: "Confidential x402", + link: { type: "generated-index", title:"Confidential x402", slug: "finance-solutions/x402/", description: "Confidential x402 is a privacy extension to the x402 payment protocol that hides payment amounts and balances onchain using ZK proofs and MPC, without changing how you write HTTP clients or servers." }, + items: [ + "finance-solutions/x402/introduction", + "finance-solutions/x402/quickstart", + "finance-solutions/x402/how-it-works", + "finance-solutions/x402/integration-guide", + "finance-solutions/x402/protocol-reference", + "finance-solutions/x402/network-and-contracts", + ], + }, + "finance-solutions/compliance/introduction", + "finance-solutions/yield/introduction", ], }, { @@ -70,24 +83,15 @@ const sidebars: SidebarsConfig = { }, ], }, - { + { type: "category", - label: "Finance Solutions", - link: { type: "doc", id: "finance-solutions/overview" }, + label: "TACEO Network", + link: { type: "doc", id: "taceo-network/index" }, items: [ - { - type: "category", - label: "Confidential x402", - link: { type: "generated-index", title:"Confidential x402", slug: "finance-solutions/x402/", description: "Confidential x402 is a privacy extension to the x402 payment protocol that hides payment amounts and balances on-chain using ZK proofs and MPC — without changing how you write HTTP clients or servers." }, - items: [ - "finance-solutions/x402/introduction", - "finance-solutions/x402/quickstart", - "finance-solutions/x402/how-it-works", - "finance-solutions/x402/integration-guide", - "finance-solutions/x402/protocol-reference", - "finance-solutions/x402/network-and-contracts", - ], - }, + "taceo-network/network", + "taceo-network/node-operators", + "taceo-network/governance", + "taceo-network/roadmap", ], }, { diff --git a/src/css/custom.css b/src/css/custom.css index 759eb0d..45b3f10 100644 --- a/src/css/custom.css +++ b/src/css/custom.css @@ -8,6 +8,58 @@ --ifm-color-primary-lightest: #066b75; --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.1); --ifm-background-color: #f1f0ec; + --taceo-green: #52ffc5; + --taceo-cream: #f1f0ec; + --font-ppneue: "ppneue", sans-serif; +} + +/* TACEO brand font (ppneue), loaded globally, applied only on the marketing + landing page (src/pages/index.tsx → .homepage-layout). */ +@font-face { + font-family: "ppneue"; + src: url("/fonts/neue-100.woff2") format("woff2"); + font-weight: 100; + font-style: normal; + font-display: swap; +} +@font-face { + font-family: "ppneue"; + src: url("/fonts/neue-300.woff2") format("woff2"); + font-weight: 300; + font-style: normal; + font-display: swap; +} +@font-face { + font-family: "ppneue"; + src: url("/fonts/neue-400.woff2") format("woff2"); + font-weight: 400; + font-style: normal; + font-display: swap; +} +@font-face { + font-family: "ppneue"; + src: url("/fonts/neue-500.woff2") format("woff2"); + font-weight: 500; + font-style: normal; + font-display: swap; +} +@font-face { + font-family: "ppneue"; + src: url("/fonts/neue-700.woff2") format("woff2"); + font-weight: 700; + font-style: normal; + font-display: swap; +} + +/* Apply ppneue across the marketing landing page only. */ +.homepage-layout, +.homepage-layout h1, +.homepage-layout h2, +.homepage-layout h3, +.homepage-layout h4, +.homepage-layout p, +.homepage-layout a { + font-family: var(--font-ppneue); } /* Light mode styling */ @@ -285,6 +337,17 @@ html:not([data-theme="dark"]) .main-wrapper { background-color: rgba(40, 167, 69, 0.1); } +.service-card-warning { + padding: 2rem; + border: 2px solid var(--ifm-color-warning); + border-radius: 12px; + background-color: rgba(255, 193, 7, 0.08); +} + +[data-theme="dark"] .service-card-warning { + background-color: rgba(255, 193, 7, 0.1); +} + .service-card-muted { padding: 2rem; border: 1px solid var(--ifm-color-emphasis-400); diff --git a/src/pages/index.module.css b/src/pages/index.module.css index 0091ea8..5c0c839 100644 --- a/src/pages/index.module.css +++ b/src/pages/index.module.css @@ -1,6 +1,9 @@ /** * CSS files with the .module.css suffix will be treated as CSS modules * and scoped locally. + * + * Brand source: aligned with /Users/ais/Documents/www.taceo.io + * (ppneue font, mint #52ffc5, cream #f1f0ec, 0.5px borders, ultra-thin headings) */ /* ─── Page wrapper ─────────────────────────────────────────────────────────── */ @@ -9,57 +12,55 @@ padding: 4rem 0 6rem; } -/* ─── Hero ──────────────────────────────────────────────────────────────────── */ +/* ─── Hero (docs-style page header) ─────────────────────────────────────────── */ .hero { text-align: center; - margin-bottom: 4rem; - padding-bottom: 3rem; + margin-bottom: 3rem; + padding: 1.5rem 0 2rem; border-bottom: 0.5px solid var(--ifm-color-emphasis-300); } .heroTitle { - font-size: 3.5rem !important; - font-weight: 100 !important; - line-height: 1.15 !important; - margin-bottom: 1.2rem !important; - letter-spacing: -0.01em; -} - -.heroSubtitle { - font-size: 1.3rem !important; + font-size: 2.4rem !important; font-weight: 300 !important; - color: var(--ifm-color-emphasis-700) !important; + line-height: 1.25 !important; margin-bottom: 0.6rem !important; - line-height: 1.5 !important; + letter-spacing: -0.01em; } -.heroTagline { +.heroSubtitle { font-size: 1rem !important; font-weight: 400 !important; - color: var(--ifm-color-emphasis-600) !important; - margin-bottom: 2.5rem !important; - line-height: 1.6 !important; + color: var(--ifm-color-emphasis-700) !important; + margin-bottom: 1.5rem !important; + line-height: 1.5 !important; + max-width: 42rem; + margin-left: auto !important; + margin-right: auto !important; } .heroLinks { display: flex; - gap: 2.5rem; + gap: 2rem; justify-content: center; flex-wrap: wrap; } -.heroLink { +/* ─── Animated arrow link (marketing-site signature) ────────────────────────── */ + +.arrowLink { position: relative; - font-size: 1.1rem !important; + display: inline-block; + font-size: 1rem !important; font-weight: 400 !important; + color: inherit !important; text-decoration: none !important; padding: 0.4rem 0; - display: inline-block; - color: inherit !important; + white-space: nowrap; } -.heroLink::after { +.arrowLink::after { content: ""; position: absolute; width: 100%; @@ -70,20 +71,54 @@ transition: height 0.2s ease; } -.heroLink:hover { +.arrowLink:hover { text-decoration: none !important; } -.heroLink:hover::after { +.arrowLink:hover::after { height: 1.5px; } -.heroLinkPrimary { - color: #52ffc5 !important; +.arrowLink .arrowLeft, +.arrowLink .arrowRight { + display: inline-block; + transition: margin 0.25s ease, max-width 0.25s ease, opacity 0.2s ease; + overflow: hidden; + vertical-align: middle; +} + +/* Default: right arrow visible, left arrow collapsed */ +.arrowLink .arrowLeft { + max-width: 0; + margin-right: 0; + opacity: 0; +} + +.arrowLink .arrowRight { + max-width: 1.5em; + margin-left: 0.5rem; + opacity: 1; } -.heroLinkPrimary::after { - background-color: #52ffc5; +/* Hover: arrows swap sides */ +.arrowLink:hover .arrowLeft { + max-width: 1.5em; + margin-right: 0.5rem; + opacity: 1; +} + +.arrowLink:hover .arrowRight { + max-width: 0; + margin-left: 0; + opacity: 0; +} + +.arrowLinkPrimary { + color: var(--ifm-color-primary) !important; +} + +[data-theme="dark"] .arrowLinkPrimary { + color: var(--taceo-green) !important; } /* ─── Section titles ────────────────────────────────────────────────────────── */ @@ -107,8 +142,9 @@ } .journeyCard { + position: relative; border: 0.5px solid var(--ifm-color-emphasis-400); - padding: 2rem 1.8rem; + padding: 2rem 1.8rem 2rem 2.6rem; display: flex; flex-direction: column; justify-content: space-between; @@ -119,23 +155,48 @@ border-color: var(--ifm-color-emphasis-700); } +/* Rotated mint bar, accent motif from the marketing site's network cards */ +.journeyCard::before { + content: ""; + position: absolute; + top: 1.8rem; + left: 0.6rem; + width: 1.2rem; + height: 0.5rem; + background-color: var(--taceo-green); + transform: rotate(-45deg); + transform-origin: center; +} + +.journeyCardLead { + border: 0.5px solid var(--ifm-color-primary); + background-color: rgba(82, 255, 197, 0.04); +} + +[data-theme="dark"] .journeyCardLead { + border-color: var(--taceo-green); + background-color: rgba(82, 255, 197, 0.06); +} + .journeyStatus { - font-size: 0.9rem !important; - color: #05525a !important; + font-size: 0.85rem !important; + color: var(--ifm-color-primary) !important; font-weight: 400; margin-bottom: 0.8rem; - letter-spacing: 0.03em; + letter-spacing: 0.06em; text-transform: uppercase; } + [data-theme="dark"] .journeyStatus { - color: #52ffc5 !important; + color: var(--taceo-green) !important; } .journeyCardTitle { - font-size: 1.3rem !important; + font-size: 1.4rem !important; font-weight: 300 !important; - line-height: 1.4 !important; + line-height: 1.35 !important; margin-bottom: 1rem !important; + letter-spacing: -0.01em; } .journeyCardDesc { @@ -146,6 +207,13 @@ margin-bottom: 1.5rem !important; } +.journeyCardCtas { + display: flex; + flex-direction: column; + gap: 0.5rem; + margin-top: auto; +} + /* ─── Quick links ────────────────────────────────────────────────────────────── */ .quickLinksSection { @@ -156,9 +224,9 @@ .quickLinksGrid { display: grid; - grid-template-columns: repeat(3, 1fr); + grid-template-columns: repeat(4, 1fr); gap: 1.5rem; - max-width: 800px; + max-width: 1100px; margin: 0 auto; } @@ -203,195 +271,9 @@ flex-wrap: wrap; } -/* ─── Network card section (legacy classes kept for reference) ──────────────── */ -.network { - position: relative; - z-index: 1; - background-color: var(--taceo-foreground); - padding: 3rem 0 6rem 0; -} - -.networkTitle { - font-weight: 100 !important; - color: var(--taceo-background) !important; - font-size: 3.5rem !important; - line-height: 4rem !important; - text-align: center; - margin-bottom: 2rem !important; -} - -.networkDescription { - font-size: 1.2rem !important; - color: var(--taceo-background) !important; - font-weight: 400 !important; - line-height: 1.4rem !important; - max-width: 50rem; - margin: 0 auto; - text-align: center; - padding-bottom: 4rem; -} - -.networkGrid { - position: relative; - display: grid; - grid-template-columns: repeat(3, 1fr); - align-items: stretch; - max-width: 1200px; - margin: 0 auto; - gap: 2.5rem; - padding: 0 1.5rem; -} - -.networkCard { - height: 100%; - position: relative; -} - -.networkCard::after { - display: none; -} - -.networkCard:first-child::after { - display: none; -} - -.networkCardInner { - position: relative; - border: 1px solid #000000; - padding: 1.5rem 1.2rem; - height: 100%; - display: grid; - grid-template-columns: repeat(12, 1fr); - gap: 1.5rem; - align-items: flex-start; -} - -.networkIcon { - grid-column: span 2; - display: flex; - align-items: flex-start; - padding-top: 1rem; -} - -.networkIconBar { - width: 100%; - height: 0.8rem; - background-color: #52ffc5; - transform: rotate(-45deg); -} - -.networkContent { - grid-column: span 10; - display: flex; - flex-direction: column; - justify-content: space-between; - height: 100%; -} - -.networkCardTitle { - color: var(--taceo-background) !important; - font-weight: 300 !important; - font-size: 1.8rem !important; - line-height: 1.2 !important; - margin-bottom: 1.5rem !important; -} - -.networkStatus { - font-size: 1.1rem !important; - color: var(--taceo-green) !important; - font-weight: 400; - margin-bottom: 1.2rem; -} - -.networkCardDescription { - font-size: 1.1rem !important; - color: var(--taceo-background) !important; - font-weight: 400 !important; - line-height: 1.4rem !important; - margin-bottom: 1.5rem; -} - -.networkLinkWrapper { - margin-top: auto; -} - -.networkLink { - position: relative; - color: inherit !important; - font-weight: 400 !important; - font-size: 1rem !important; - text-decoration: none !important; - padding: 0.4rem 0; - display: inline-block; -} - -.networkLink::after { - content: ""; - position: absolute; - width: 100%; - height: 1px; - bottom: 0; - left: 0; - background-color: currentColor; - transition: height 0.2s ease; -} - -.networkLink:hover { - text-decoration: none !important; -} - -.networkLink:hover::after { - height: 2px; -} - -/* Dark mode overrides */ -[data-theme="dark"] .network { - background-color: var(--ifm-background-color); -} - -[data-theme="dark"] .networkCardInner { - border: 1px solid #f1f0ec; -} - -[data-theme="dark"] .networkTitle, -[data-theme="dark"] .networkDescription, -[data-theme="dark"] .networkCardTitle, -[data-theme="dark"] .networkCardDescription, -[data-theme="dark"] .networkLink { - color: #f1f0ec !important; -} - -[data-theme="dark"] .networkStatus { - color: var(--ifm-color-primary) !important; -} - -[data-theme="dark"] .networkLink::after { - background-color: #f1f0ec; -} - -[data-theme="dark"] .networkLink:hover::after { - background-color: #f1f0ec; -} - -/* Responsive Design */ -@media screen and (max-width: 1200px) { - .networkGrid { - padding: 0 1rem; - gap: 2rem; - } -} +/* ─── Responsive ─────────────────────────────────────────────────────────────── */ @media screen and (max-width: 996px) { - .networkTitle { - font-size: 2.8rem !important; - line-height: 3.2rem !important; - } - - .heroTitle { - font-size: 2.6rem !important; - } - - .networkGrid, .journeyGrid, .quickLinksGrid { grid-template-columns: 1fr !important; @@ -401,48 +283,15 @@ } @media screen and (max-width: 768px) { - .networkTitle { - font-size: 2.2rem !important; - line-height: 2.6rem !important; - } - - .heroTitle { - font-size: 2rem !important; - } - .heroLinks, .ctaLinks { gap: 1.5rem; } - .networkGrid, .journeyGrid, .quickLinksGrid { grid-template-columns: 1fr !important; gap: 1.2rem; padding: 0; } - - .networkCardInner { - grid-template-columns: auto 1fr; - text-align: left; - padding: 1.2rem 1rem; - gap: 1rem; - } - - .networkIcon { - grid-column: 1; - display: flex; - align-items: flex-start; - padding-top: 1rem; - width: 3rem; - } - - .networkContent { - grid-column: 2; - display: flex; - flex-direction: column; - justify-content: space-between; - height: 100%; - } } diff --git a/src/pages/index.tsx b/src/pages/index.tsx index 4cf7a12..ecf20e4 100644 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -4,24 +4,73 @@ import Layout from "@theme/Layout"; import styles from "./index.module.css"; +interface ArrowLinkProps { + to: string; + label: string; + className?: string; +} + +function ArrowLink({ to, label, className }: ArrowLinkProps) { + return ( + + →  + {label} +  → + + ); +} + +interface JourneyCardProps { + status: string; + title: string; + description: string; + ctas: { to: string; label: string }[]; + lead?: boolean; +} + +function JourneyCard({ + status, + title, + description, + ctas, + lead = false, +}: JourneyCardProps) { + return ( +
    +
    +
    {status}
    +

    {title}

    +

    {description}

    +
    +
    + {ctas.map((cta) => ( + + ))} +
    +
    + ); +} + function GuidanceSection() { return (
    {/* ── Hero ── */}
    -

    TACEO Network

    +

    TACEO Documentation

    - Private execution layer for digital rails. -

    -

    - The TACEO Network and services enable computation over sensitive - data without exposing inputs. + In production for global-scale identity. Now powering private + onchain finance through Merces.

    - - Browse Documentation - + +
    @@ -29,55 +78,46 @@ function GuidanceSection() {

    What do you want to accomplish?

    -
    -
    -
    Learn the fundamentals
    -

    - I want to understand TACEO Network -

    -

    - Understand how distributed privacy-preserving computation works - and why it matters. -

    -
    - - Explore Network - -
    + -
    -
    -
    - Production ready services -
    -

    - I want to add privacy services to my app -

    -

    - Integrate TACEO:OPRF for privacy-preserving nullifiers or - TACEO:Proof for private proof delegation. -

    -
    - - Browse Services - -
    + -
    -
    -
    Developer tools
    -

    - I want to experiment with CoSNARKs -

    -

    - Build collaborative zero-knowledge circuits using Co-Circom and - Co-Noir tooling. -

    -
    - - Start Building - -
    +
    {/* ── Quick Links ── */} @@ -87,49 +127,39 @@ function GuidanceSection() {

    New to Privacy Tech?

    - - Secure Multiparty Computation - - + - CoSNARKs Primer - + label="CoSNARKs primer" + />

    Real Applications

    - - Identity - - - Finance - - - More Use Cases - + + + +
    +
    +
    +

    Developer Tools

    +
    + +

    Get In Touch

    - - Discord - - - Email - + label="Join Discord" + /> +
    @@ -139,15 +169,9 @@ function GuidanceSection() {

    Looking for something else?

    - - Visit Website - - - Read our News - - - Ask Questions - + + +
@@ -160,7 +184,7 @@ export default function Home() { return (
diff --git a/static/fonts/neue-100.woff2 b/static/fonts/neue-100.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..0634733f79aad671a1ce4991bd762f1006d9c7c6 GIT binary patch literal 51864 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

=U%# zen(YQw5qB)rly8aS9jc^MIlR;obV@q682|*RFSh1!lrL?B0im^wC7tb%DeqVBW*N|nevJ_2!f~e?GC&Y*` z&QH~B*|RqqCo}hr!BI1eHCCc=#+hxr3Fez{snnk zREK7JkoSJG-N@H_v>g5Qx71*REt6=L)fQVK$!e>uv&kkKY_Y|9d+f2%A&0DT*kLPk z9Gg~v!r{MUccDl$OT5|U=w+_CdYEUPp5~kH7Yi&x4EEc5t51=5xXAQqx zP-_UFDc>J#$`gEauG4Sos7AomhXnl?=>ORti)YS=opcaDG2<0#Yry?O!zUG;+^+{h zxA!Z){oAXJ+7dRn)l002ingCWjpTht$R6Mw$bj)PzN;u5lCG1)W|`xr;Vc??p}OK4 zPX@c)QHCr#DoN3T*j@mUizdoxJZqm7>H1C#`gxrBE2JhPVyRes_h%l(^%*-5J!e+S zc|&6fT?dNAmKdc%(x;aYVC}FrhTN9at2oX=R+7q+z$(M!DDs$;m)X9M_uk-gmRLp- z2ZFp{bS$5{M9UbFSWFs4$joay`$eTjza;;W$Tlaj@!WfN12__UxX0}dtE5a? zDZIlBv~gD!$D%F5zG&m|=rX4>oo-wLVP3Z(4>One%58RC_6_~3lJ5i=g6PqVmyG?U z+#5P6OedvTY#YCy+9&wwN{AHLR+pf_dY@jPTA6kwC4#i^Jb?%9!wy3RN{3R|fu%N= zCAgV9Fip_D{Q|Mt#S^d@HQXG!fX~t>epRLpvo*Z!2v4ndwN%unPTw2LDnoi7wuS3Qe|PurZo{FT0;N@S6ezZhTL-QHymK{{ zTLj$JwsJ=JA&q^Fy?ra$LF@*5UM%XI$V+DC#@6eLBF~}7PPFr^`pY5*VekAGv36c! zVfUL(zJ9yK*Glip3C9jFh%6CXHRN4HX}~U#^^w1|3!vT(0>cY?5pYH`70HN5-rwhL{;pa(>pN-0GuoCR}w? z6|)A1Z`J*nUAc|{aCfn#y?jt!xv@5qPs%3{_C-~EEfq&j#Vp%21 z%1yT8G_nxm5_!pyyZtS_tOaWgoKCK#utwIcPtEQN7Xde=vTFZut>de;vsMSadblc$ zAKTi+o7R5wrDRNM7S=0j*)bX0;4#IpSF})I<9uskd;3WRuekl6GVm8Z&q7jr*Np-A z%=U3}K_d0eSEi(Dxs6gjsrDu25q!(Lo zU&%hRUtftK2xy4h22qFjXO2!(3x;Z7o4nK;Vot9MTrFQv5sA2B*j0C6G& zQp`;xh`eqM!E|t2gz&Y;`yL9yn5f`A9Haqxevi|#!pr$12r#dB$YCC_BOZyiBO$gr z(Y@?;c`AHhNX$bDW=z-IDuJSn0Sh7IIa}jT!qLKj*m{t~q`w$HJV2Z+w%w56W2zu( zOR3G}a@#7@Xmcn%z#I~XYqLvYZYQyeh+28@U64wJkxkb8U#47)X+=a8lA<-O%if{lrU9gxe*v$p) z6owGJ(;2duB tj5B9OuvIq;1p*UFkk>(6G&dq@1{pOm)}&!e7f7wMW{JgoePuqw0s!aFlx+Y2 literal 0 HcmV?d00001 diff --git a/static/fonts/neue-300.woff2 b/static/fonts/neue-300.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..ebac434a5b1e2d6fe0b316021cac3eee7f10c6a8 GIT binary patch literal 23508 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 TA?Z%btXbJzd*H{>tE!U#5J!f_ literal 0 HcmV?d00001 diff --git a/static/fonts/neue-400.woff2 b/static/fonts/neue-400.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..bd23f87e3190d79d21308bf5c5eb655c611787ba GIT binary patch literal 23516 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 literal 0 HcmV?d00001 diff --git a/static/fonts/neue-700.woff2 b/static/fonts/neue-700.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..077769c90d42a50529819a03830270c315ecbc81 GIT binary patch literal 23548 zcmV(q?09&j80RR9100000000000000000000 z0000DfwM~*ffyU`Bpint24Db<00A}vBm;{q1O^3%A_pKF&ZZ@7n}+aE-hlDjt}I`g zxPTpd!rc->QIK+@kZ$f#E6)D^gye>ZqW?fl?Ar9tDTT7yU17OQZ!fyp=q`hvR-?NL zSD{c}hC=Plj8NRDjHvX^^a)pEro!`aXY;&alL<$eaDs!T4F_LdD1)ff_^$H@@9?G% zHFoqa`vyBDQ!*ugt>6cD81NCps|98xD+uCJV*PBc^j5bk7{shlI2lhTf|Ll#_@6HV z;}$+@PQAmE+y31hAmbPU2M8RTh@uFJaHb;SMA4m@+7dM?SLRyz&BnH6HpaHS{WgE! z=3l$9emKgYsJ&0?o|*mO0%S*>L`fv&aTFRAg~ciK8HGeBgbn#o1Z$Div-iXrS$HN* zniC@~*Z=G}A^A!^qG4K!wco3Z+0mc-Spb3%? zxrt*D5^OUP#&kveWGX9DYi%E~P{cx%L{h6{h7gIAtc@z3-o#G*&8`16-Ge!pz!rWH zJ&?0yD_N+jJRjj&wgG|$_`YR)IaT|L$ODo|gT`DMZ%2*%@@ZrN+%C$w=S-@BF)X2_6)(yHz6Q@X?$ygKVoD16u)c*%;f!TdfM<$uxCx~Xw@UwIBS^u%)!A*YR)hbhv}0 zI~-`DP&NQkHb_Z+ELK8FvcF7PaW7L!=~HPeu9RFz`}s?*U-JKbN-2H%$yVx?VauF( z>t&cSY-_58R(SsZ?^C|n_$l_mLjlW*a0n(!PKFNi1Ij8E>z#=!@`0sTzi*mSt!qP0 zP-qD2m4{z!AXBb{8TF14bdbd~seI*L&k51_=)ERV6bKM17$w{@=9%tDiV!+!Hy zfV%#=T;VKGFcK8BU*6dqm6>4|uKf+M-e)bL#GUNJr^@Vp2a1UM$xWn4RzerL5JFcv z@276>L9aej-E-l$9gxeBl|@ko4F85u20%gl&nE>O8}jj%78Y4qlm8y-Ke?d)V}m~> z_>ueh=iZ`ED1ZMQ3i&(OyYlz`b-z60rqVeZAZ|D?GM@Ye2@xSdn$gB_C|2tmb1b&P zCOaH)(s`Hkdg^C?da2)VFhqxh%2cT}M5{KF&2XFrmRM`EGiLoYCcyUgPG3 zC1tJo6%Jr7EQ&n735YpSiBD!mXMBn?Ew!1Elj+EClu?I|J-&DoNiz8m;Zna)~I;GQE*BNbWcLzIBU2R?Ha{W!TSgd@j9T=djqi`tLlqW)P~B9n{-b%gFL-PUHlJ%s<0o6;*n**D88Y9#7H#va z?NzneCD-q9D7xB0_lpDkwdilNz8BT!D9G~A5l2CkM^BtsXOo~`r*wkenBK#wJ6{W# zX5rw8a$y&X^1|TKthVA@nVZW81F3S`Z2a74#&-M?N~JYh6ISbN%`&#>S{RIOzr|wq zzl9y${<{%<+&&z|FP$#!x7hRGp*SQ1S%PJZsA3Ql^c7-5c~6-Mz$z+Kh*a*?)J%V% zitk3~)ncfCQqblD+SDLWi451|c}ycFv1qrjriII0442)p@41cMsZR~H`BL|dGYkG? zf#o#BKVQU3ueio*;gt%;2OoT^-=%h-oSsw9G$QV5IixeTevqP4XVrA4XD*kAb%CJ zo$3nrnqv(tcjk<-wIG9EWcH|OKRkXuKp*@k^&j+XfCz*dqsVOMywBHI)16|Y^X<{4 zUpxRloX}V^E=`%6mMAir=~%LwV2JRkm5QKrGCWm9UDJ`wCC>INJiT0~t?us2#fL9e96{rM$Dj&EwuwGe(gV!sW zV}y+C*ARST5ZwDGRx^BP!)`mQ&}#ei>G3sAnAfN7%|C(X8)w)`o}v@)mc{9#GX|CV z%pl30HPx-`iI`-}iO<@ErI|_Hoqtyr!F2qtnA8Y&NsnZTiS zVwh{nfX&QYqxEvx(S~YSS8qL86U&I=_W9riLa{-MzXRo6Q!xzsor_Sc)c)-mi-=`Wx}Enf zN{y2Ag5p$>rNl+V)c)4XL{T)-Izh(><~hhw1Vwc(rMa)}s2?uoDmW-GNVu%CgRa!H6a zgPWQteXy+vHXRuuyS>_tGCo|@*`>umjc<0#8WHM=EFh|#0o2e<7i?rH%Yt3}8wjrm zcC=R_!Dzar)@tV?w0$8Un*c7c9zZE7087;%XpB~OA3pdnn1 z4v3HsO#m`s75eQTni8h zYp^(>Oqy>fwORGr8FI)F+=HX+;n5whA`+y^*PmX2Af`}LQ?ck60T@pJ2mA64w(REw zt^p1FuPMPeaCAU{`M?u`^Ii=md1n#uCIWmhj->g$BQUMfehR2gho2I7*S}px_RHH{ zM=WmqqK7Vy(&!rrVThj$+vx~fl_~>ekcE|{La4DCsCU*(@C8o_Bp0)@EQHp{%2^Wy zX*oi+9Snlu7t|lNd)HZi&M%bB|4*{=Yr&EELtT?x)+$+{5cbfGQ*?){<;zxLh5>-e zzD}~=0S9Zei9-%sz>B&Cws53YysfRxc6@Z#!BNNROP;C8E% z*T4vuU2)a5{xoaRMu^akXm>^jVa%?l;YM1*JH^fP#JH7#+j@MPQ8&HrSSnUr=UwD( zR%~|V(@wm5Ik@jZP9EmcO#*v2^y?$BnKQ*&w8ToI`$0%Vm~21#$dTO8y1kKYq;$0s0!5fPK{AT<$7geo;;*c!p|QE(BOA&SWHL>VuSg%tzS zeA950Xi%z5onrN((ba+!n1b3X3OS*6+HDg>uTjE#qr&=r#9>vx=<K;3ne#3(JgaRw{lmOwB2siwYI!7RhNxz;Ltcub=n+L;=1837r(q! zZ^3R&-tgwn{}ONf)!veC^`>9R^)b7{DWTb?{StO z%T~)lOR7cn|B{fBpe$riE=gE$8E8%C`mXibraSeP7M0e%sSRw+?yc7@+S_a~iOF9g zr_t$#6i?qMimIr0wNrs{&>Z(H_r{M}eAND^}?SKKV~>C{Bw_g|`@Rd6&5z7v#d+aJSNBOHDbJzaIFiM}O^ey~A_C9zsH1 z*b?Y41Oh#%U=^-G!UOz+6P~~;cn81PclLN`;e2-fhXAJ-@eAkSKccDg(R{x2nOnnB z!(OAdhwRa{M^UXFJvY`mSnE>Hzl{~Ox7WVX>-XOO>Fv{dW}Toq@pa1TH1z4*$G7h8 zdgJT89+B#Ium9Qx%70Nr3zGCg-;`t~*V%E$o7|lfIFBdsEB~>D3;ZX46_tUoL|Kso z36o@*C~u+>mpqgo!7;`>r8IsY=!;72Nz3SvA)(BZEy&E;H3vCGcyg4_Ac9eHHw0E>PNOiwoA8T=oP$U;5jD z4VOR|e?{OF=uQt95^s|QG=sY781LdX(0K^0A`gW2*7mTM{>S?)tysb50^4dA-*XT@ zPXY3L6rekFqg(~&WEXRA!JLMAT^f3mR_3lckmI|2dzdG2g6QO>F<+PH&%3LckLHk} zu+%nR)!|z0kDo4wVZo2@`58A?cVJpDU)z7VWFC_Cz`Vx;Nqu!3E65w_%6kbkOMu@8 z4Fu36R4nXav2x8TmQur83k4O3LVeT=b?Ud3*4R_f7z!rHHZKV z6*Tt{N?@lB_D~HVcAtRLw~GBz{HEZ*04;2G`5vjJy0gijy{;fugVc>DymKG3hJuhl z1)eF}c`z<6@1U44kFWsK)ZF*ho-JFX4X+c%w5%JfyC?QXYM~w7T(A2IdEoy{>s#Y0 zzt5$&(qYqvg+lHQ>eI6L4kQv`hb;qp?%EK^S;7b(U4#ljvCD3(EZiqwB`#9TMgVXso*I(|Y8XE?U7sJ?HiR@mJ zsjr5JEnrv-Nh_VJ&Iihi0-NJy-QAA;jW)IAow<`CzZSJu;1#aUget1GHutHgFwT!a zPId{pd#ES$KOF&j=Thd$w@VG|?hG$kTpKi83s91WgC2b9KZSLG1Nko^_giBF%sE}s z?6Mb-8k*q>GiVW?4oSu^MoX)Dl->u8qpTu&56j-M@ZMq5^(x-sl+*PI5Y!b-BTx?P zV=aw}Unt~*Ez?P{5=YOhh`AVl^Sx*Qjmz-PC(T)~yo@!~}bjE3c- zA*y2N@516(>K;k&Ith&c$tXg@yI`Uq6KagA5?{YJiXbiw=Tp1{aN8SI$< z3UZCHpRvh;9IrxlL(Z-|-(1-=dbyrI8e0iX({BArz^xt3JbxdZuVn(em-RR-JM0rd)0 zEa$t|NYJ~t)krpiMrZ^R4D9ewU>LR&Xa_ar1ZGMI!wgeX#Biyd^Dv;Ey+W%c(q#8S zd*rfkd&Z4a-~+JK8Y;sYJ6NGvtB#tuVagr%Z~kvFRkJDma9WA@bTf2j>K%(jh& zMk5FH*S}L~DP9C>#maT*iV<$J?=3F|#E# zcn;>97+mrG{K4lV5z&$PPkngd%gPi;95*WqHg818EPgN7R8|=9U@Ccjd;ZAR6~Eif2ScJQwEEScCZpyH(8Q6Sf%^Z$)&kD#xPn;VM%lMmLVC*tpKT99AylYmkLetxY_BsAKE? z<8me-ipv)+H_%jTmTD;OqptyomD-6tEV{0O%(R7IbQ?MyD98y-oO+$(F%*ns2x!EZ zE#FL8X9)!b*24QrFR*8$SbW8Impg@1tFsp-Y6)*K-zKLOZslaLQ%+YwgAvd?MEl?} z#Bcf!J1~7IM{db?)~T$psKsRDLj;`@3-U%s-Z^41*X-iNVNP)>C<#*RT10 zaLSDxgPhJcuc!-`)E|7!@~5GCN-rWrACzNW)!3YaMWpv{-MjzRyT$hWy2e^gUfEp( zGnv%6l72ch8_OP?8z8!b;ksNlV4Qq&|Nee`Su34u4P3qvz6W6h_qq@C{R}&i34b5#@KuMO@P|2v7AyXzlxtsHk)~chM-gWi|{RxAr>rCH4ca10rTw zX^oUf%<~eOGOvzP2T<%_b?4>2Ltq35c_+5J2Cxv#8x5hxPC4blUT8ejRwC4vzvc)>B4qUb6h5`n{d)LX%Rwhc%@2Rjy1YrMgyY2O4y2cTL>pd$zSrnAGt2$= zeW_3bTTa6q*>% zo2tT4@MxqxN<-IoBPQB*BIml=LBsSG?v0gj)F_o992}bT>IUkc?k4}6k0m_ABAAM| zR9+%sxhqEbT9-dfwJ^I9?UC?>_S3Mdg**Fz(Y6{Qs@cbQ8ItVFCEyGFc-SlSuq%`X zcz8EzaL3;tfE=C6Mv;4}y6l&jj;?wzcQTCOTu>lpH3ZJ}F|IzVm*OJW4n1i1IE#v= zk%9VRrXl#p(rzZ2S5c$5(y_jl11p<$DnN9VhM_BVN;|DPzb}CPFaZt|{4*t=AApa< z`(n>fKO6}9dRI7q(&EhQf~@ce>>HVh(HL?AVgu{PKVV-l*MthU?BH=QmuNP0Gd>dq z5ThW&K{4;1)@iU?lbo9;`Otp5?g{y?TXO257My*PZMD66GPtI98V{m{=4gVZg-~Yk|1@uZowl6AHvz&4sSg`CUD=H z$rPmM(ha}C$`h-gvq^&$&ZBr^UahR~1&xjm2D;AC*m@@n)bme#x_l7rKKGtqO385O z2<)+UgoehPT(F)#m0?RvlH~6qsg7<=>2m7CPy8(?e^{#>8J?UP*;`SuXKxiD|CVRD zoLM8jC8MJf_VU-9JURh#^b=@6;;22;rxM5rQLI-bH2T=s8eoHR4h^MfV$CF==`AzK zIDCweh6eeBhVj^!r7&Tj<7p?onBhz#3Q(@XvI+ef%Cd20RN~;9+z9UNY-=QoNs0QW zg7Cc$Ef;U$fCKBYcat=Hh(-bZpu0widOe%(gwQNNdgcV67-VQ)g0P&VrpN*ZNJI7` zZG!d7mh!G9A^-i2%K}T6H$(Dhfy>fSi)Qze`AE_5eY@aRfY@1BSyba=U0#T)!{H>z zu=bB40HM_xn+v&T<-u^Ew-MlO_xI1fQ`m@@mBU|KR@TpsXXJL0*~G@COr?q1KfR!y z*48d3y6^D^-IRI(2kD>opcA#(+fOl?6DVm8kaCUdq9c+&$ZVq51XARQA&UG`u>Uv8 zuC>)DTDOl0LTabUSnyX&pgd+0FJB}WrkN;m;B*aAehcW$&J|R=&Q66m4nZB*gKpgh zD1kL}sI-_Vw-WZQHCmTD+%T}W=RO{<^RjH!#@!L*^x3#5o?@@BFP$h-XI`+HIl;hM7U1>*ckRHWkNB1eLnMRRK zHFWxc|KL=B=!(i!YB|hwRlI=F{&MR^wC)vQa29G8rWOZ^Mx$qrV2H0s5m_=YH_6)< z<6;%vN|kgkCa$3h4MwzF@DgZnz?&t<%@jhkeJFjjJ={m@WRwWmC2gv7MhmfgR4z5r zpno9)Q3dt`^?*HAMl6b01#Mmyj%SU3YSGo_;|$^M=IGXpyIFWz zO3Tb!gKmHYcm>(p@{x19`gfu=(N<^w{R|;srj?B98o8{fe#hg^hg2#@CROA~vU^o^ zBZ5uZiUa(J<*p~?K{?Rf5P83bBm8dv6rkona#cqr$Bdi0h1{a$Eg0Qu$U$29pFlgE zGHPrs=dqkfYYAgOhJ}h@JB2c9YZRP?sIa;|k!qAKtNuJmH#90nfn*e+!3G#>HPR)! zL9+G{pKMI|2&Z`XGUYr&R3zzodq;AYtF6{@UDjc;g*^dHn1oCr*jG3zfnuS5#o!xa zoseCN9doI3+PYa0(lcQ@32`+DpZmAVz%_(DB*oJxoYU)hi35^Llj%`wmoIZaxCbK9J%qlg@>rsm#oxstk## zdY%lP>}hlk0UNuY%|~Zd=bif-h#mh!@PaGSJ2M^flw zkQeujtg8>T0HoU$n-J3swU1uUd+zbUgs^7qW6$BJO91lf%0_gMtC`{1d7j@$yx9dO zXcbaD1#g+es&gv7=J$eCY{0ZZY_CKW7CcZKV_xP-+{k$e6QtD{)aa8qzQZi=cGB}} z%%2Z3G-M!Ga$Y{lGaZYNf%MStgYeLOJE%$&cL8%y@~kc5U9reKE#bhk-WQR(@oRG` zqiKIisiRMT$hDdyNsIgwxTs@)s;2mbFeoF*UyNVB3#`s=0BQMuDoL!Fi*^tUAlK=Q z2;JDtAiG@#_(!H@5sRn{kyy5H!@dob?2dLP$1<7W8G6s^@F<*v>H5VPlD+E5XE6e= z4cWmMcd3b|TtPbsacM-wifXrC4^-Qm^=wF0u2=`;P*vqX_OT*{4xin)5iOzXN;y}% zFXBL^36TwW9c1#Q%P{s&GcQFusQ%h$HKLce;am0PQi!oFJPD!hyCKMy8VT_Zjj-T% zY}L8khfp5MAPlMw8nAi-a=|6g6UYwX7F98HQ_K>&JmM9M-5w#Ch?iqBbSdV&@SLKy z6r7Vks;?&%JcYtp$zh#6c+5i_>V2HZCZhiOJZkH$Eg@{H0#$aBel> zED`$sQaND{;71=8;Mq{Ze&C1gmLE$UbcweveGk<4^oel!@5E(owEoN<;1f|UdW zZl&95lU;v1`LNVDig3XT}O;e3|uKGN=#LDlw-p#W)M&#u`;qENIlps=|x_xDW{Wng+$A&JpHc|g+K$ssBt|GcI5I?2ofm&!g#4$N`g0RaDX!XH)L?)D=dDM@~a;ynw2UIPW2#rWuq63bw5@oM|*F+jxqcIt{Hu zu8Wt$V)*WRu75y;q>fmyljM0GNGw_wK5yAv-un_~m%sgqM35?)>r{B{Wjbb^bZ)=` zO-`51Fwh-xBJUtNgJ*Wba-fT=QOM6mbPR-P?Kw!^I8Q-zg&7Jir^|iceY_bb=$a$~q&$6YfJ7m(5oGNc+QFS^MZ<{CZg z4@+LyJ?Z&!*W|(c3!WJBzM|Lcs;Q!hjI)~zZK{sR&ijBGQnM808ZvJ%uVZSDPiEkv zg52`^^?us_z{6pDEF)wy)w!4NdYxHD4V!+C9)d>DBBEmDW;=z?nT{HTD&xVARYp0S z?V!QPWFU{eVOr`Y69?sKf8hd1k1*IALCOl6vt;W4^6nNaM4UuDNF_Nt?eVYxu7;Pj z2pXt75C5qgP*Kt}Ck+Jl7rKC$o0L>WTq8$}dgIxW3zb!B-hEmf_v+H#08`XX{=h8k z17XNv3dpc@FaQ&f3k`ZCdTFc8v!BU8+&>uPh*58BpG}*z{hfhVIArfgTOYUcmqhR` zYTb9Y_LnDQmmi1nXke2000k%=_PyHauc=OfZ4t8`r#EHha&@F@Yu4 zOn+#-30aC>m6sS7=tK%nyo;~_g(DE((|D!_O_+G;#4b9ptc?)R%ZomCc%#kpF?&#* z@Y7hkb_`s?IIgKc^)M={sAppZa~#&dfF+8pdLa8MiwCG9hqCSeL`4_;71QyB;q&(S zYB!H)s)rC3&`RGDiq^CfP$DmEc)SI-{^|vxn>k2x01<73ka~z#8->IBvXSJTtQ>wa z+kJ8 zFS1dXco<>GMQ&@DIq}urip|W`j}ZRinHT{t>b&v=aNw`L{Ne4s&Wsbkxo+pSk|#VV z4@Ls@5S0ex#R)PZcvDE6V$|4Ax7cmOm;!5@VB`h|#jP!i(m^6C4al;|@}kfjSkjfI zJkE^Cn%Bg0^1#^WkXxzR4VQrI0j#$bL-k+Kxx0)f8z2rXuXAXT*sng+F~1U@HRcvGdL)$kq1 zQ5=pt^f9WVs59XjxsyK7OzX{}3i!2;5B52sk`1 zBLY3=)}5YfSDoUmTO{H)h@9k<2QOq11eF|THXngFo-YzGx6zke$I8-KjN%_qgCGb} z5EyB-Qvvc%xgxw>cDvKHf=JuUr>8zZU$MT zG1cpqrw!MvzU5(V8MYYIlz7{A(W9S{6WyqkF)=phyxD&7qB$>9QkWk@sA=d{(Wp@8 z%F?X!%9UA3a$>gR&7={j;I3XJcN@r)NrSTBkXVeame}ZL+Dy!{PsVH-dFop@;KKzr zu)szK>;q{O8)$CSh4qvi>IAPH_Gy!aFbC)5eyMoNR*CraHzc0*b574yBKg^sh!bP6 zkB@D|#-0g*Hdw1Yx3=U+yD~$oGGU0wdnm2#men5`1{4RUIdhCxQR2fuZfpCH!*Big zoo0^e=&zMz>y;d<{QX!7z;mfcb0vd;T3EgG48T64vYB`~thnT57lsXgN&Y{s^r%zmg=IH&fa-reERH$Q`_VcZ(Yu^ z|Jt;@kO?bon=O^V22-q`s>h~cJXJ85e(#IKhHfp4jV2+nf6CnG5>cw9*yXeu7rjzm zLe>Sa!l3;t=wJ_YN^Wyb%dS)50`-#BC0|{za!CcMMlS}RI2vx+paXk=I#&VQ=-rP) z^|O1&lwxg*RHR0*54qy=ce#3#G#Im!gUu#&I?de12XyN^9HKu&uOF|C6gxw%o;L@U zrbHE*P%1TbPnb_i$1KkN@{Co*p zsirl%(!k7|C3TTvgn?j?&AB|#&PuQvJyjEVu=ajVZq~y+vu#>Fy<2h}(3v;DP<$C! zg*YRR=_-U(&R@#qqgt|!Sy}YGvislnjbhx|R|8La5T(G<9M-TQB`6VkJ)|(y@S|d1 zDq*f+%kOKbF_i}V4zV~!d4qszs)BWCN^CXk%T&5m7F2ULOKE#OjE!A3Xp5^8o;7@5 zQY)71d=NnnYjapaHw}u3e!8NdSN!7;GdW}CXa<|sKNtkM;I?LU4*ka7d zk(bA_r-5P1a`Lx@F#dj)TB2rZ<@1M@u}tQwAgFS6$v;Zm1Wr6=17A&AWiM=_||??OWx?6Q+hvF7)aq8W@7mXI*jS1ocIf)es1OoLeBuZ3OXc~BJ~5R`4a4u zW`Kq;s1g&plGz_<4O6SUs*tWS!iVhT*WV&)lb1f4hK>0~%_$ryS=8t{<~QPdVLU#z z8oVC8-D;jsph&dyOy0iErDMCF?m)!$a>w~BY_|hOQR_R&!`` zTpm1SlUq>fgrsJaKC3PdZ5JhDO&`rnqG?``jxWZpA6tN z-AeZAHT43B?|<}uH>LiSgEU2sm+mdhIT*nb_{rl`@4^t~GiKhxD(`JpegW?s8ggDG zP=o{ZRX*NfZ;avhYjJh;v(NqFnByrW-G$uJ_@nzP$&|C*`qfNfqLYu77P8A`l`1Om zlpY^+tEpk4*78R!T-L@Og_czNeNZ3kSI5`(@Me}Bq{-w=&)KsRo>Tq_@%HUC;#eZ% z?Gz`ydWAgrJrs$PvPyhQ&HJ3>Z;P4gFJub*$^KA#ylI8Z}`r*t)W44W@o4aEL%1EoHm1;VWp|HYkn2b zOpq(ze?)1eh6f%<*7}k8cFbHeb8*eEk)=bBIgvnaD)J5WQg(4-T}mUCk0K}z;SW`Q zif8!&teBMs#R6MK#=36rCoulNA$r%`mi_@Y8KFP0$vlrWd2eu!(nPPQ9)ArR=GF(o z)FhAY&P*DrZL@kTRENhn4z?b`^LqF+`#=3OM8n7=(&~Z0xXQ*>J$PrT=%qF?*iP~0 z!3QV>q8w6zCvsqI3oBT#hVjZ5Y@xx^r8Sn@ka6Tt4cRq?v2W4o&$0&`UCmt>aLz>W z+E0gVXfW8=l9iT=7Yy02dcvxq@AGCThlP_uNc-7K3&%?E+*&4zc&7J^Z#i+2oe~|N zT!bCWRT)S5!5NNDUK!l+gKS;qgl&=dfvqS$TUJpe=47seW{mfL=Z{1itYNl^#WBK} znlWxu7Qq;{DbCa=ay-SV@d&HXVVc(WpkaoxwGdWA>mj_OXOr~17Wu=dj9iG-P3}PqwU0IZ;ntW81q8c^>S66uQu2+>F#9p(Sy2G zcQomBWk;Oc;B~+m%2RUTN%#y5_p{-_QG;;E=FA43%h95mfV(D*x%_K3$XF^@4MCI? z0XIewi>^~#4Y8!w;f(-q)-wA6)5Wy3X$#&&9C>o&j8|fej9P5(A@Ff^5GH z=u-?47N4R;!3O~3GaOLFXeNmo+1n^SLfypp77*D2fPyNo2g(;a^|V~*aQ#TlqI6gx z57z}T#2Mlchd97p&3)K~rfE+G1+nkYSnvE-+MVC1yzyLS5tkOtBFUkcnFProk0ys1 zmPXU5Sra@iS(|x2>Bw27%&3d$|3}x9;Q1-@o4G+tdWV>i9DvhVgxfVM8eL)2@bq8H zE}FQJ$jn~6PJRbl-|Fo3;6Ll{DmJ6+Q@L_Q?Af-Bv3Gs(bgedA$PoInq}{p372OGi zcG>O`GgN#jz|6V0tMbz%3NZp2lpMU}_LS3+@q%rF7nHsQSz% z78iL^#&l6x#6*SI5S2T4a{HSsN7I8$hNUE!U;%~>uy+cuEdcDF!gXQ(-YFk#UUs|e z*ed4kTuQr|{Pmfi@*(VA)n{bCg7iFM5f>toEN^gq`hTN^5#sxs=jK?gR;AVD(n+N{ zvLvZon$F>A$=oEXwVdRv*I8ZMg=JEyv`(5%B+sS|qSyx_?^O_BONrWL9%r?j$CG)! zJmCszq!tWb_J+n*`$^&b=}1s)UlvuuiXCaFjDh!8VU5k$Q7~`+Cvw%ueHDP)BUzNL z&iLs&qnNN~fOBxMK@;YyTP?X7RmzHgfV;y~8Z6~1Wiezi>Ve}!y?5MX`NtIy#<#VE zfX@|3jZN`Y#a7L6Zh*Q-cw?=S>+L+eYc5L!iNZ7}k=03NYX0=gZJ67VIh4@rXixZ~ zcr&6vqJlIe@LY1(l zOD4zg&nfa3{e6hZyEeH2Tng(e2ia%_YMTurNh-NVEj$C+iT8r)LxO}Wvok+3B?O~& zPUsb1)<27vcv%~2RWgZH{C!b4iXKwEenUVqQW?!eZL{XP%A5) zZv6nA**d2w1Y7eXsk@8rBv3L83uQwBO}j9A%G^->HRoDj-3CES*JL@zkmRAOxM! zTH8ipXU@jdp0|2_bANk%*S9fKh7W;>k?K8(P5t)Wsn)jJK3T5d(4Nq?A?QYrl6Toq zy%Ci9c~5mQMo(ZzZ8tJ5J_YE((LS{;WQ;?}xGU8Md`ZsVaOze#YY`p5kjDWkf;A>! zU?>lRR0eB0^W^tFu?VK10x&9-Re-`uC2@ry_wv(c0Hfrj8ZbbPp9%PP$gCkxH)8ID z?l6N{e}&pHkpxn?oy(ZORMvALObo@k%@@1P=g6uDDyVzX(H$I*p&NJ@0~=)UMmh@5 z40)4mygV>oS~Y&Ym(YV416`sR*OVoX#WEI=ohQ?6=e!5@X9X1-M}GK=QRh?=tDqY( zshTV0>q*Lzp(UV+|L_^lZGL8cexx)uW{+qak#!LiCwpFK_D|r6Q>w#XhgyiB4c!cK zC6~|)?GB$0FKce}T)2-3y*>V5(ca<*K>g33Wy`MScbh+ZzMjR4OR#cri=I6`8?z(-2)J|^@_^m!_+S$g5f0lr<5#}RTNiOW|os>TdO7w>=~ze4%3N@ z->1sBM7wjkSHHj$U<^`G=@myyIJwg)zeCNrV{iV__ZzVnzX|`AzeC;do|<<#c*n48 zVCxV{bn{p$i)6gE0Va$@`^5z(&VVEW5_*tC(oE;nOKcWUh`gjl-+NA2m!NjD=_`gU zYh$%(ofxEkxnt{l3?HBPq%1qlDb-gH%I{oRn6jB=3XoeNDz{!)yLx9DyDD>U0jAZx z>c`zD2$PyJD(%1gJi?Pu@4Wrfm1=95me9FN(`Mg!mgkI&qTKRj9aLU6dC8Em9iJV_ zydJZ*TEqtB?JI7?5|gu@@4ll;)*0}G<(>V8N}vOF_NK4&Sx?kK1rth8LKR5Xxpps- zETPz{not*&72{k|K}`FpSO;^FbN3{e!eoAWS!m@8rTHHb8a4h_c27GzhciJ76diGl2gTMvk=<6O(1jyRqOebS_3r3>$m(5rIaD@L9 z^is@xa${e3946I=Yb4skw0rLzx!_NrPkg3+P*Nb`m1lE$NyR#tMd6wO1<7xmy%K> zFC+2*{lf!%j%PqLXca8YFzl9zA&`0kBg3?zTAh0k6ibZvX4vPJf&#0*sLjh<4@@Ym*X@iL+>N)62R{4GF1DchQqrLCQt7F#;2ObRGaP_F{41L zC)4KzhT76Xn;5o_@=>Ey|w$)6>|^oGrn%$O!{AGM?}>7iLu1EPstMiILS&Woe0S zXguStJ*)tmeVCfBr{zj|?TfJ`gh*8TC`pE1hQrhfAY!xHF3jpRKrfTpnTi0q_J+f- zm%U<6y$ZH+35;jPvve^4JT7L7&U6VNB7lgtSO+|_upZKJod2gv_n{oss9v!Z06Yh< z);+YXV2k)h^NRCU_|Cyi)WHd;JzLZF>6^w+x=(KwZz$x`u|+W5&9(13Kky3y^DjFJ z?D1@NGt-;2Y3z#q9#GZ_=1z{8vfY!MrKRzGW!*$5pDe$urCNH0tZ_>R18M9AG7@1R{m(g-~XdNU>~?2c6GS0 zS_vjP;$8sS1cm6>e5;(RR-4Xo^bgvYRA+Yl$)y}La_10UW%X@L6FREJZR-4Xw6FS_ zdbWv{+8Ij0W?I%JY|^H0$Bc8#xy60D%K8r+5QJhbNnU9(6jnrOIhs^;^)2m438i+n zihe8~8ktbd)Bov#$ViU^vb*N2o>u)gh)49o|hy2(W- zVV=%=DUi8)4%4HoHs(VR!#kLBuvP>mc7UpJP_!mpYRt zhbXY7M9-Aq!8tZ>_sG(Ph0^36Jd5EyUyJ|9geD9iXPh=r0#FI=^)~TXJb4Rn&1K7q zFTbMg7%*UA-gP_w)IQu>?_t=EyK=FxFq*Ja-!3$t!UAZ~twP^--(~xTMrWto-?gy+ zrAT6y%Tc@@cC0s;ZFBZvTte`SuEbAHntiG1XZ_j`=GpY@wepsn?v=!AG<1SoSo;-l zoWA>Bz(}k@+^b*LGx>Fed3=QT`|s`EK)^2gf0sqSH~%7~vj5K4ITm;Cz`pd|+X3P& z#deL7Sd+s01x3Au1^D0AQvhhfTk`2%UV|Zm?*ri;iKErrYXaA`6lQj_4xn7MOn}AMrQqhGiK20lK)U`BFI_;n^TtoRA~tD}v$tS@ z`}v&ZTQa~T(sGjRZ*VN{(t$0s{N4fb%|C?Ngj=0$7ZOYDR74tRR+VwvJqC$w0)a0_ z8WK+Z4m>4X&STK(h`_8dZ6on9_1b$m;jQk6R}vfzI?9lhbViZG;!01{4xFY0!JdU z-QfX&b(U)z+~@}L>p-#op|42-2r%r@xbEO<;s<*c*ZNa7nRO3{3zaq@n<-CF0oNNS zE5puO0l~=BtykdIGyF zMz%!=r54N{$zanMw90(^`ME)h1tcE8RGJqS=w?1x4*g2?SVN}cy;>ST?U{?EV~~he z2Rx(4?)QzJm!i}R+x~ve@9l1;lGA9ykyw(QB%l2VEt-dIU|~kUeHvk?@DK)MMJP-2 zfq^~e2>S7~B+yRqx|Id2zBq!J&>#w$AdNb_>H32_?z)!8Qd&#U^(}bpr*+B|VXGJx zOenEB@9>fRX?m5wGJ%qQl@gyu&CKU^(BIN!P8papAhalK-0tf&o005W= zCIn%Duqi+YdXPZDAR){k7V#j7@<9qs1}V}GGD`=@QY%1K*$A@PPLSPBf}C{~LZC1dY$8+~ zVl-S5Zg@OIhUwf%$(~NK6m1{ucg#80^m^pQ?)Q_oyXd8lqt9JTffABa_qwl3GbD>R zDYA^`R94vse+>Y@0D$b{ABH@BDX5icIOKFl7I7=1+eqtb|4|&@ITyuUliiBFfwchQQXq{o zC>NAbEz^spamBb^T)_1X_r_45SbFg*hePdav0E@Jonw=72*SW}a*IJi4`EPzt%&e$ zwI~}pvy7>gNH%9IW5b=(=Or!z5vrxbke!~-wd8Y!^|c~HWDRTB zi_;F`TI#?aZZplb$%&+%ZJwP*dcjkJb9C?dym=`|dX|b%pcE|~9w%}OB?ZXjh4RAU z#t>i&_4+JmP~O4$lg#04Jl~Wrr-fBLhSJ0O3@l8UbW0#9h_v1j*l2Bh1f@DgSV8=C zRMvA^!3;fV9x;5KDpG)DL__y;Is>(K@gUd?5fQOb5fPClN48M(aW(D3A(f8Xdk@Yd zH$jjdMI)=Hxi8QH45c}gopxlTn7eF~gxt0aV931)D$cQ*AW@J@U=pRI+xbD#0Z+1U zIswdio@1N^ieed2c$%c<%1t36^X2=T$OBA!pNKfD4`N<$w)&{Cs;46jnaS>03P17;V1$DzP_^?^$?M@W))M!Q)Gb>@(d zUMEtogu??&N!?c%nLUEVi&RA-6>Abmf~TpBgVsh&8zAO{0BxvBu7%WoV_ zUW!ggCt;BFoCDePkRF;cp@PZOhZ8gFMk_m=NShPopMFC5b#L*;jhIfSi3 zyotm(tqfybJybFp+;AK-iZrP?uIf;tb%F;_grm3i9WULDF68-ew!gjhGHS>S{Vm($ zT0h4vXC<`3Y)h~$P}kW}5c=wvp3gP%Ws>5gYbSt~5}N=JaeR~r;epu|hwX7Q&-o^+u7*ZK2~h+E{5(L*tkBgwtc2JhNa zf<{lplx`NesL2na|9#S+7+N8)QXa(zavWpiS0PDCf@^mfJWnc(O=vF?3Xa%4kvdV$+fOa|RbCeaAF_Y9~^VOqZ3VL&}7|>cAr;JZ7y_LDDCS z2^rCqON~=g8*?|nu((-fH%e^hEgj_$!E?WJIXB-J8-&yn17mnHD!p+jQWvUZk1W2R zYJV;(;71g1DkjKj#8gL25^+TaxTDl1(llbVc_-o)E$w;yD28_-YydP#@#wLl;jL18Lt));n#2)-TV(#0x zQKG=*n@atRb*U5vA&q65Z^k-mfeVs3*K~~qtS^+#$QA^FP!aPYDk&j+rslvXfUC#T#kC44+`s+hHxxnBV^ zMtEB#@K}-u)xeuzj57-bu)Z>=*IZ(~FbklJUi#QlVVTcUie~ch7#GW4KkV*Q*qP8K zH~Ug8r%49R;+7XCSZ4U>LwST?ffg~}x1Y3=b;h3jXVRIBE-R|0l7`co z%sS0nD&57A&$qSK*^v1+5lF$tYfWKTUjUZEo8m^I^@Xm4wm9rirF+%XAK@^0?^@eWI$pk2j} z=o7pMuOoNOXTzUSK)6xWH)ZZ6*fO0!WkYK_+Q7WU*ky* zfS1z9K~A@03+77iL?6I`KJ*Pz0JwQbK?;HxE}-nMFvJ23_t6)hTP|eL)8(1655-59 zXF_yL&?UZGmHTAuN(xI1WB|o!s9R4 zF-|W><~$5wfP?!GnGL0XWjF0hA0G>v{t7bKRrJN@+@Ud;3jlFx%q61&hYbjj6iGCI z$)%`8--Qx^0l)(`-^M37cS_ecwehikZi`-tIwe7{);Pvdi1@UiM9qV${J{ozl4`P)DK z^`Dnsd*iK7Tm}tCfkaC5P$8jOKP?OyX|$;Qqn*%uAAHnr$Y);y&_FcE4WdIV2!+@X z2jW6J-Q@$JBvmGE6foFtegnWCUV=cxP)Z3B6`10TYrgYT6VeBt_?JGejI?n(Fb@zG z0N6%j$x$K8%qEqaElsmds<2b4v|p<7N~-ows^OAq4M=sq8b5S+pdkby&=|D{G$m9- z^X~R&O^!35Ev$waJ)nVwy<|8mdeulen;F@a#3D96bC_2i_H341Jia-)2&}f2+Il-^ z?6Oag18y4OwqK0|K?H*uiUJ}FSfP}CGHuXWhVAxHEQg=ZXEZ{zG4eE;WuB#0+2ybc`1M@{J(EwoE9xKeo+pX9(kdgPwMPX3J}LyI2nq%_ zbQ@=Yo>p~eD3eNsCJQE$Rs^L`2oN6F@8M?1CJMPk;I;Qi2Y?$|2Neb2FpH6Kre!Qc z##z>(`qDU)8$Jf=`80?QkXQ@>I8*}cLI8~u0<^dx;1(|gE%y*^@l8}{T*KT3*WKjp_T1ijJf!g*_Z67q=P4%Bd*(-4KlxRF*UuNqprNt5w~_Oh zfH1;{1ZOkFqrk949UVb}qGL804^p0#2uj3*XBPJGinxN!>2>Uu>`@id~4j7?1 z6oNtELY4?(P*983R-#i2fk29J-hyc>Am~LupTKfbUQ(QL8bmV`8;2V%E*^J$0>U*5 z#leV(iAjiwd5}iRKQeMS1to%tHw_JMJibv8Lq$bZy6uj~nr-n8J({5787>9}1J*2x z9U-?sVE%j{5EN8C__(;-Y558GIbAtJH#ofL1!9&uuuGuDz+C$SiUC6>!U!`$SOf%E z&I=*_^7h&32GlPk zS6I-S8w_+*6bKqOCVTKQmqkgbXm=OxFGZH|oXXUojr4fnx9kuslXEswKKjf2CH^A+ zWWO^~h*-;?k`x*R_dM`*gw-rt0oJC@aOg9>;6chj^(Fb@d{$p5&!q^LZzGGL2EZ;& zk3-0HT)2>ft+I|X4t1M#W&h-JU$*1uz1xwpU2#iTwxhZr*f z0HA9h+Re$2zP_DA1mbWHGWJ!^m zpnB|}T@Z&K?EejMB{I+mK1YG5;B`xUhz|M z$9Eoi>Y1Mc&;=pL2LPxTc*HECj8mmfjap3_wV7*?`4(7hy*1W4;E-;I9dW|9?&@`? zQ)3k>F_L##xz>SE#yH*rm9WI+r&=#ndH|p^>huRdCjbBd0Gb^)=u;Z?0O&9P+5j=Z zM*z?;*~B}U0HT$(fBoWy^Mg{anwJHk00018=52i0kO2x0Fey0=Uw-^qMFJq&7-NmM zs%(p#XjydIQ0!W}tFE#obWQbPnraI0kmf9Lw zZl>G`gpQyHzrGE9Gh6Y2Focv)5GullFc4-Uj@a+1@?4{WRY&!%>I0QjrBL~+?5cd# zB=4TDBLD=0E%rI+m=n&r7(gNw`lvO)5r!FUk{RY%VtFLFkz4_?7GWa%`ZV}Wo8mn& zPe=$kLHP5B`Ip}J`#$Gtt+?C6Cfz*_pPOz>y~O(YkKvc__rHLjfBtz7@<253)2Y0Y z13&GG1zk}2$BO_we+@vYEbU<}S^>~G0Cd4eQYsGm+2K%N8qA9#>X?&~w3MeNb!kgu zS^)q60Kbvm^aJ2`Glc1d-@N$Va{&O$zv?B)KgnrsOb=~FT5u)|NMp2cO@ z1EXNdm$8h=ZODU^Kl^h67SRH@Yn!O##1R?P8mE}uHFc`CA`5FZYSw0auGBAGZ#A1~ ztlNTzooEYjT>aL51bXhYAGoQ9s7BX-qm{cExV|AY3uZRlVloRUbdZ?G(=uLGP+88~ zN;(_pZKSn||2d;=$P)Q;b-Q3Yh1$bxpD=rc+b`BJF^-CNQnGVWU6A6ubeD{DMTX0= z-7?xuS#HR4U%rPXxX0lEr#>ZKC{^xf6@E3%FEU+~<94^^>4G!aBD-;tO)CD(rya~K3#2`%u8>ZP%jgpQ~rymhjLOwN6y1Q-VRV}~K z5#(i8#7i>%C-O!_ZSdGGR_%qh+!6 zdCnt2a~dJL94+nvS%)gIV;(2N`&Oo_yz8uB4$or@xQ+WYcp?Xoh|@9cx{!_y(PYD!X<#!B_LSf;p14l|0!$ann9Uzlygq@tR%-It~T!>=Ro zHPMGiVECy275hk_2)+wGHNR#fKj5!SNpQgU@;QaCXH*5TuOBJve_|S>y8A@;FA@F6 zo+%}3aPs>|dBZdg)`@GDwd_UFGpIlY=qUh*;+%^^vEpF}n>Y-kP=^t6zF`W!xGa&|d zqWHxo(eiChitmb7alo;kreVABuTr7v>!`4e?w47q$br+R_!oX6vkA`rH7etpee&kJ z*6>%gtPssGBxO%DZ5{fVT}Ch{GanO3h7sIH3O&P;qcxOi%~ha!SQwof+Sa4BoVE6% z1=h1@6#8rY&4rtv!!a=`X*oZmpQq(mHZ&Q3$dmANYJLE>k{SSC!{3w-4J|JufQahEL0{Jhfh HMQIHH@hpcl literal 0 HcmV?d00001 diff --git a/static/llms.txt b/static/llms.txt new file mode 100644 index 0000000..a982f27 --- /dev/null +++ b/static/llms.txt @@ -0,0 +1,54 @@ +# TACEO Documentation + +> Private execution layer on the chains you already use. Merces ships private onchain finance with two privacy modes (confidential and fully private, selectable per transaction), plus integrable privacy services (OPRF, Proof) and the production MPC network beneath. TACEO co-architected the protocol behind World's iris-code system at global scale, and is now bringing the same foundation to onchain payments. + +TACEO is best known for the privacy-preserving identity infrastructure used by World and zkPassport. The same MPC and coSNARK stack now underpins Merces, our confidential token transfer protocol live on Arc, Base, and Plasma testnets. + +## Finance Solutions + +- [Finance Solutions Overview](https://docs.taceo.io/docs/finance-solutions/overview): Private onchain finance powered by Merces. Two privacy modes selectable per transaction, plus compliance and integrations. +- [Private Payments](https://docs.taceo.io/docs/finance-solutions/payments/introduction): Shielded ERC-20 transfers on the EVM chain you already use. Confidential mode (amounts hidden, addresses visible) live on Arc and Base; fully private mode (addresses also hidden) live on Plasma. +- [Confidential x402](https://docs.taceo.io/docs/finance-solutions/x402/introduction): HTTP-embedded confidential payments using the x402 protocol with hidden amounts. Live on Base testnet. +- [Confidential x402 Quickstart](https://docs.taceo.io/docs/finance-solutions/x402/quickstart): Make a confidential x402 payment in under five minutes using TACEO's hosted infrastructure. TypeScript and Rust examples. +- [Confidential x402 How it works](https://docs.taceo.io/docs/finance-solutions/x402/how-it-works): Component-by-component walkthrough of a confidential x402 payment with sequence diagram and performance numbers. +- [Confidential x402 Integration guide](https://docs.taceo.io/docs/finance-solutions/x402/integration-guide): Add the confidential payment scheme to your own client and server (TypeScript and Rust). +- [Confidential x402 Protocol reference](https://docs.taceo.io/docs/finance-solutions/x402/protocol-reference): Wire format, EIP-712 typed data, ZK circuit details, privacy and trust model. +- [Confidential x402 Network and contracts](https://docs.taceo.io/docs/finance-solutions/x402/network-and-contracts): Deployed contract addresses, hosted endpoints, faucet API, MPC public keys. +- [Compliance](https://docs.taceo.io/docs/finance-solutions/compliance/introduction): Privacy-preserving KYC, AML, sanctions, and Travel Rule via selective disclosure. Compliance dashboard live on Plasma testnet. +- [Private Yield](https://docs.taceo.io/docs/finance-solutions/yield/introduction): Compliant private yield on Ethereum. In active development. + +## Privacy Services + +- [Privacy Services Overview](https://docs.taceo.io/docs/services/overview): Compare TACEO:OPRF, TACEO:Proof, and upcoming services. +- [TACEO:OPRF](https://docs.taceo.io/docs/taceo-oprf/overview): Privacy-preserving nullifiers via oblivious pseudorandom functions. In production via World ID and zkPassport. +- [TACEO:Proof](https://docs.taceo.io/docs/taceo-proof/overview): Private proof delegation for ZK proofs without exposing witness data to any single party. + +## TACEO Network + +- [Network Overview](https://docs.taceo.io/docs/taceo-network/): The MPC network underpinning Merces and the privacy services. +- [Node Operators](https://docs.taceo.io/docs/taceo-network/node-operators): How to run a TACEO node, hardware requirements, security model. +- [Governance](https://docs.taceo.io/docs/taceo-network/governance): Network governance model and decision-making process. +- [Roadmap](https://docs.taceo.io/docs/taceo-network/roadmap): TACEO Network development plan. + +## Developer Tools (coSNARKs) + +- [Collaborative SNARKs Overview](https://docs.taceo.io/docs/overview): coCircom and coNoir, tools for building MPC-based zero-knowledge circuits. +- [coCircom Quickstart](https://docs.taceo.io/docs/getting-started/quick-start-co-circom): First collaborative Circom circuit. +- [coNoir Quickstart](https://docs.taceo.io/docs/getting-started/quick-start-co-noir): First collaborative Noir circuit. + +## Use Cases + +- [Finance](https://docs.taceo.io/docs/use-cases/finance): Confidential payments, treasury, and B2B settlement on public chains. +- [Identity](https://docs.taceo.io/docs/use-cases/identity): Privacy-preserving identity and uniqueness checks. +- [Compliance](https://docs.taceo.io/docs/use-cases/compliance): Privacy-preserving compliance for regulated entities. + +## Optional + +- [Merces: Onchain Finance](https://core.taceo.io/articles/merces-onchain-finance/): Canonical positioning piece for Merces. +- [Merces deep-dive](https://core.taceo.io/articles/merces-deep-dive/): Technical detail on the two privacy modes, compliance dashboard, and Plasma deployment. +- [Confidential transfers demo writeup](https://core.taceo.io/articles/confidential-token-transfers-demo/): The original Merces I confidential payments demo on Arc and Base. +- [IACR ePrint 2026/850](https://eprint.iacr.org/2026/850): Escudero et al., "Merces: Confidential Token Transfers via MPC and CoSNARKs." +- [TACEO on GitHub](https://github.com/TaceoLabs): All TACEO open source repositories. +- [Demo: confidential payments (Arc, Base)](https://merces-dashboard.taceo.io/arc): Live demo of Merces confidential mode. +- [Demo: fully private payments and compliance (Plasma)](https://merces.taceo.io): Live demo of Merces fully private mode and compliance dashboard. +- [Compliance dashboard](https://merces.taceo.io/compliance): Live selective-disclosure dashboard for authorized auditors on Plasma testnet. diff --git a/static/robots.txt b/static/robots.txt new file mode 100644 index 0000000..0e47042 --- /dev/null +++ b/static/robots.txt @@ -0,0 +1,29 @@ +# TACEO Documentation +# https://docs.taceo.io + +User-agent: * +Allow: / + +# Explicit allowance for major AI crawlers (already covered by User-agent: * +# but listed explicitly so policy is unambiguous if a future change tightens +# the default). +User-agent: GPTBot +Allow: / + +User-agent: ClaudeBot +Allow: / + +User-agent: PerplexityBot +Allow: / + +User-agent: Google-Extended +Allow: / + +User-agent: Applebot-Extended +Allow: / + +User-agent: CCBot +Allow: / + +Sitemap: https://docs.taceo.io/sitemap.xml +Sitemap: https://docs.taceo.io/llms.txt From 330a64c6d5f37481c14af5f421d3ab1c64221582 Mon Sep 17 00:00:00 2001 From: ais Date: Fri, 8 May 2026 14:56:17 +0200 Subject: [PATCH 16/25] oops, broken links --- .../compliance/introduction.mdx | 2 +- .../payments/introduction.mdx | 18 +++++++++--------- docs/finance-solutions/yield/introduction.mdx | 8 ++++---- static/llms.txt | 2 +- 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/docs/finance-solutions/compliance/introduction.mdx b/docs/finance-solutions/compliance/introduction.mdx index 17d19cd..cd5fbfc 100644 --- a/docs/finance-solutions/compliance/introduction.mdx +++ b/docs/finance-solutions/compliance/introduction.mdx @@ -110,5 +110,5 @@ position we are taking publicly and shipping toward. | Goal | Start here | |---|---| | Try the compliance dashboard | [merces.taceo.io/compliance](https://merces.taceo.io/compliance) | -| Understand the underlying transfer protocol | [How it works](../x402/how-it-works) | +| Understand the underlying transfer protocol | [How it works](/docs/finance-solutions/x402/how-it-works) | | Talk through a regulated deployment | [Email the team](mailto:hello@taceo.io) | diff --git a/docs/finance-solutions/payments/introduction.mdx b/docs/finance-solutions/payments/introduction.mdx index 498427e..a079889 100644 --- a/docs/finance-solutions/payments/introduction.mdx +++ b/docs/finance-solutions/payments/introduction.mdx @@ -41,7 +41,7 @@ Merces supports two modes for transfers, selectable per transaction: | Mode | What's hidden | What's visible | Use when | |---|---|---|---| -| **Confidential** | Amounts, balances, transfer history | Sender and receiver wallet addresses | You want to hide pricing or amounts but settle to known counterparty wallets. The basis for [Confidential x402](../x402/introduction). | +| **Confidential** | Amounts, balances, transfer history | Sender and receiver wallet addresses | You want to hide pricing or amounts but settle to known counterparty wallets. The basis for [Confidential x402](/docs/finance-solutions/x402/introduction). | | **Fully private** | Amounts, balances, sender, and receiver | Nothing identifying about the transfer | You need full transaction-graph privacy: consumer payments, sensitive treasury moves, regulated user flows. | Both modes share the same Merces protocol, the same secret-shared balance model, and the same @@ -65,7 +65,7 @@ Three properties make this work: For a step-by-step walk through the cryptographic flow (commitments, secret shares, Groth16 proofs, EIP-712 signing, and the MPC settlement loop), see -[How it works](../x402/how-it-works), which uses the x402 payment as the worked example but +[How it works](/docs/finance-solutions/x402/how-it-works), which uses the x402 payment as the worked example but documents the underlying Merces protocol. ## What you get @@ -75,10 +75,10 @@ documents the underlying Merces protocol. | Confidential transfers (amounts hidden, addresses visible) | Live on Arc and Base testnets | | Fully private transfers (amounts and addresses hidden) | Live on Plasma testnet | | Per-transaction mode selection | Live on Plasma testnet | -| Compliance dashboard with selective disclosure | Live on Plasma testnet (see [Compliance](../compliance/introduction)) | -| `transferWithAuthorization` (basis for [Confidential x402](../x402/introduction)) | Live on Base testnet | +| Compliance dashboard with selective disclosure | Live on Plasma testnet (see [Compliance](/docs/finance-solutions/compliance/introduction)) | +| `transferWithAuthorization` (basis for [Confidential x402](/docs/finance-solutions/x402/introduction)) | Live on Base testnet | | Allowlists at the contract layer | Live on testnet | -| Private yield | In development (see [Private Yield](../yield/introduction)) | +| Private yield | In development (see [Private Yield](/docs/finance-solutions/yield/introduction)) | | Private DeFi (swaps, dark pools, approvals) | On the roadmap | | Mainnet deployment | Shipping toward production | @@ -95,7 +95,7 @@ Balances are held as MPC secret shares; reveals require explicit authorization t compliance flow. For a full privacy analysis at the protocol level, see the x402 -[Protocol reference](../x402/protocol-reference#privacy--trust-model). +[Protocol reference](/docs/finance-solutions/x402/protocol-reference#privacy--trust-model). ## Who it's for @@ -113,9 +113,9 @@ For a full privacy analysis at the protocol level, see the x402 |---|---| | Try confidential payments in a browser | [merces-dashboard.taceo.io/arc](https://merces-dashboard.taceo.io/arc) | | Try fully private payments and the compliance dashboard | [merces.taceo.io](https://merces.taceo.io) | -| See it run end-to-end with a real (test) payment via x402 | [Confidential x402 Quickstart](../x402/quickstart) | -| Understand the protocol architecture | [How it works](../x402/how-it-works) | -| Look up addresses and endpoints | [Network & Contracts](../x402/network-and-contracts) | +| See it run end-to-end with a real (test) payment via x402 | [Confidential x402 Quickstart](/docs/finance-solutions/x402/quickstart) | +| Understand the protocol architecture | [How it works](/docs/finance-solutions/x402/how-it-works) | +| Look up addresses and endpoints | [Network & Contracts](/docs/finance-solutions/x402/network-and-contracts) | | Read the underlying paper | [Escudero et al., IACR ePrint 2026/850](https://eprint.iacr.org/2026/850) | | Browse source | [github.com/TaceoLabs](https://github.com/TaceoLabs) | diff --git a/docs/finance-solutions/yield/introduction.mdx b/docs/finance-solutions/yield/introduction.mdx index b7b92ff..e4603fc 100644 --- a/docs/finance-solutions/yield/introduction.mdx +++ b/docs/finance-solutions/yield/introduction.mdx @@ -6,7 +6,7 @@ sidebar_label: Private Yield # Private Yield Private Yield brings compliant, confidential yield to Ethereum, built on top of -[Merces](../payments/introduction). Users earn on shielded balances without exposing positions, +[Merces](/docs/finance-solutions/payments/introduction). Users earn on shielded balances without exposing positions, counterparty relationships, or strategy onchain, and without giving up the regulatory posture required to operate in real markets. @@ -33,7 +33,7 @@ The two existing paths each fail in their own way: ## What we're building Private Yield uses the same Merces shielded-balance model as -[Private Payments](../payments/introduction) and [Confidential x402](../x402/introduction): +[Private Payments](/docs/finance-solutions/payments/introduction) and [Confidential x402](/docs/finance-solutions/x402/introduction): balances held as secret shares across the TACEO Network, state transitions verified onchain via CoSNARKs, compliance primitives built into the protocol layer. @@ -44,7 +44,7 @@ guarantees that make these rails deployable in regulated markets. ## What's planned - Yield on shielded ERC-20 balances (starting with USDC) -- Allowlists and reveal rules carried through from Merces' [Compliance](../compliance/introduction) +- Allowlists and reveal rules carried through from Merces' [Compliance](/docs/finance-solutions/compliance/introduction) layer - The same SDK integration model as Private Payments, issuers and fintechs can offer yield inside their existing product surface @@ -55,5 +55,5 @@ Private Yield is shipping toward public testnet. To get early access, integratio discuss a specific use case, [email the team](mailto:hello@taceo.io) or [join Discord](https://taceo.io/discord). -In the meantime, the foundation is already live, see [Private Payments](../payments/introduction) +In the meantime, the foundation is already live, see [Private Payments](/docs/finance-solutions/payments/introduction) to understand the transfer system this builds on. diff --git a/static/llms.txt b/static/llms.txt index a982f27..3a8ea70 100644 --- a/static/llms.txt +++ b/static/llms.txt @@ -1,6 +1,6 @@ # TACEO Documentation -> Private execution layer on the chains you already use. Merces ships private onchain finance with two privacy modes (confidential and fully private, selectable per transaction), plus integrable privacy services (OPRF, Proof) and the production MPC network beneath. TACEO co-architected the protocol behind World's iris-code system at global scale, and is now bringing the same foundation to onchain payments. +> Privacy layer on the chains you already use. Merces ships private onchain finance with two privacy modes (confidential and fully private, selectable per transaction), plus integrable privacy services (OPRF, Proof) and the production MPC network beneath. TACEO co-architected the protocol behind World's iris-code system at global scale, and is now bringing the same foundation to onchain payments. TACEO is best known for the privacy-preserving identity infrastructure used by World and zkPassport. The same MPC and coSNARK stack now underpins Merces, our confidential token transfer protocol live on Arc, Base, and Plasma testnets. From 61594b26fb390fd9e259b712e477112caf261857 Mon Sep 17 00:00:00 2001 From: Fabian Gruber Date: Mon, 11 May 2026 11:12:52 +0200 Subject: [PATCH 17/25] update x402 package names and examples --- docs/finance-solutions/x402/integration-guide.mdx | 14 +++++++------- docs/finance-solutions/x402/quickstart.mdx | 10 +++++----- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/docs/finance-solutions/x402/integration-guide.mdx b/docs/finance-solutions/x402/integration-guide.mdx index 905002e..9fff035 100644 --- a/docs/finance-solutions/x402/integration-guide.mdx +++ b/docs/finance-solutions/x402/integration-guide.mdx @@ -18,7 +18,7 @@ start with the [Quickstart](../quickstart) instead. ```bash -npm install @taceolabs/taceo-merces1-x402-js @x402/fetch viem +npm install @taceo/confidential-x402 @x402/fetch viem ``` @@ -30,7 +30,7 @@ alloy = "2" eyre = "0.6" axum = "0.8" reqwest = { version = "0.13", features = ["json", "rustls"] } -taceo-merces1-x402 = "0.1" +taceo-merces1-x402 = { git = "https://github.com/TaceoLabs/merces1-x402.git", version = "0.1", features = ["server", "client"] } tokio = { version = "1", features = ["macros", "rt-multi-thread"] } x402-axum = "1" x402-reqwest = "1" @@ -55,7 +55,7 @@ normal HTTP request, the payment is invisible to it. ```typescript import { privateKeyToAccount } from 'viem/accounts'; import { x402Client, wrapFetchWithPayment } from '@x402/fetch'; -import { ConfidentialEvmScheme } from '@taceolabs/taceo-merces1-x402-js/client'; +import { ConfidentialEvmScheme } from '@taceo/confidential-x402/client'; const signer = privateKeyToAccount(process.env.PRIVATE_KEY as `0x${string}`); @@ -149,7 +149,7 @@ confidential USDC. import express from 'express'; import { paymentMiddleware, x402ResourceServer } from '@x402/express'; import { HTTPFacilitatorClient } from '@x402/core/server'; -import { ConfidentialEvmScheme } from '@taceolabs/taceo-merces1-x402-js/server'; +import { ConfidentialEvmScheme } from '@taceo/confidential-x402/server'; const app = express(); @@ -182,7 +182,7 @@ app.get('/api/protected', (req, res) => { res.json({ message: 'Payment verified. Here is your data.' }); }); -app.listen(8081, () => console.log('Listening on http://localhost:8081')); +app.listen(8080, () => console.log('Listening on http://localhost:8080')); ``` @@ -213,8 +213,8 @@ async fn main() -> eyre::Result<()> { ), ); - let listener = tokio::net::TcpListener::bind("0.0.0.0:8081").await?; - println!("Listening on http://0.0.0.0:8081"); + let listener = tokio::net::TcpListener::bind("0.0.0.0:8080").await?; + println!("Listening on http://0.0.0.0:8080"); axum::serve(listener, app).await?; Ok(()) diff --git a/docs/finance-solutions/x402/quickstart.mdx b/docs/finance-solutions/x402/quickstart.mdx index bd704d2..b76eacb 100644 --- a/docs/finance-solutions/x402/quickstart.mdx +++ b/docs/finance-solutions/x402/quickstart.mdx @@ -18,8 +18,8 @@ You will: ## Prerequisites -- Node.js 18+ (TypeScript) or Rust 1.90+ (Rust) -- A wallet private key (or generate one, instructions below) +- Node.js 20+ (TypeScript) or Rust 1.91+ (Rust) +- A wallet private key ## Step 1: Install the package @@ -27,7 +27,7 @@ You will: ```bash -npm install @taceolabs/taceo-merces1-x402-js @x402/fetch viem +npm install @taceo/confidential-x402 @x402/fetch viem ``` @@ -40,7 +40,7 @@ Add the following to your `Cargo.toml`: alloy = "2" eyre = "0.6" reqwest = "0.13" -taceo-merces1-x402 = "0.1" +taceo-merces1-x402 = { git = "https://github.com/TaceoLabs/merces1-x402.git", version = "0.1", features = ["server", "client"] } tokio = { version = "1", features = ["macros", "rt-multi-thread"] } x402-reqwest = "1" ``` @@ -76,7 +76,7 @@ is invisible to it. ```typescript import { privateKeyToAccount } from 'viem/accounts'; import { x402Client, wrapFetchWithPayment } from '@x402/fetch'; -import { ConfidentialEvmScheme } from '@taceolabs/taceo-merces1-x402-js/client'; +import { ConfidentialEvmScheme } from '@taceo/confidential-x402/client'; const privateKey = process.env.PRIVATE_KEY as `0x${string}`; const signer = privateKeyToAccount(privateKey); From 3dd3e034f210c76be98d38dafb3318f7c47ec425 Mon Sep 17 00:00:00 2001 From: Fabian Gruber Date: Mon, 11 May 2026 15:39:30 +0200 Subject: [PATCH 18/25] align perf section with blogs --- docs/finance-solutions/x402/how-it-works.mdx | 6 +++--- docs/finance-solutions/x402/quickstart.mdx | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/finance-solutions/x402/how-it-works.mdx b/docs/finance-solutions/x402/how-it-works.mdx index bb0981d..c33014c 100644 --- a/docs/finance-solutions/x402/how-it-works.mdx +++ b/docs/finance-solutions/x402/how-it-works.mdx @@ -134,7 +134,7 @@ Alternatively, content delivery can already take places simultaneously to the se | Operation | Cost | |---|---| -| Proof generation (client) | ~800ms (SnarkJS) / ~60ms (Rust) | -| Onchain proof verification (client proof) | ~800,000 gas | -| Onchain proof verification (server proof) | ~1,100,000 gas | +| Proof generation (client) | ~400ms (SnarkJS) / ~60ms (Rust) | +| Offchain verification | ~3ms | +| Onchain verification | ~300,000 gas | diff --git a/docs/finance-solutions/x402/quickstart.mdx b/docs/finance-solutions/x402/quickstart.mdx index b76eacb..1e054f8 100644 --- a/docs/finance-solutions/x402/quickstart.mdx +++ b/docs/finance-solutions/x402/quickstart.mdx @@ -142,7 +142,7 @@ async fn main() -> eyre::Result<()> { When `fetchWithPayment` (or the wrapped `reqwest` client) receives a `402` response: 1. It reads the `PaymentRequired` payload from the response body. -2. The `ConfidentialEvmScheme` generates a Groth16 ZK proof (~800ms in Rust / ~60ms in SnarkJS) and constructs the signed +2. The `ConfidentialEvmScheme` generates a Groth16 ZK proof (~60ms in Rust / ~400ms in SnarkJS) and constructs the signed payment payload. 3. The original request is retried with a `PAYMENT-SIGNATURE` header. 4. The TACEO resource server forwards the payment to the TACEO facilitator for verification. From 875d5caa18f6d9e652848c76f38565f95823f937 Mon Sep 17 00:00:00 2001 From: Fabian Gruber Date: Mon, 11 May 2026 15:39:47 +0200 Subject: [PATCH 19/25] fix secret-sharing section --- docs/finance-solutions/x402/protocol-reference.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/finance-solutions/x402/protocol-reference.mdx b/docs/finance-solutions/x402/protocol-reference.mdx index 95de7d6..c3684e0 100644 --- a/docs/finance-solutions/x402/protocol-reference.mdx +++ b/docs/finance-solutions/x402/protocol-reference.mdx @@ -258,8 +258,8 @@ to the blockchain. A passive observer without TLS access cannot learn the amount **MPC network** Privacy of payment amounts and balances depends on the MPC operators not colluding. The current -deployment uses **3-of-3 additive secret sharing**: all three operators must cooperate to -reconstruct any amount or balance. If even one operator is honest, no amount is revealed. +deployment uses **REP3 secret sharing**: where a majority of operators must cooperate to +reconstruct any amount or balance. If two operators are honest, no amount is revealed. TACEO operates all three nodes in the current testnet deployment. **Facilitator** From 42467c48cdcec65054398074ecae3424c2b64dda Mon Sep 17 00:00:00 2001 From: Fabian Gruber Date: Mon, 11 May 2026 15:40:19 +0200 Subject: [PATCH 20/25] update contracts and urls --- .../x402/network-and-contracts.mdx | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/docs/finance-solutions/x402/network-and-contracts.mdx b/docs/finance-solutions/x402/network-and-contracts.mdx index 8a0d30f..0b5ac52 100644 --- a/docs/finance-solutions/x402/network-and-contracts.mdx +++ b/docs/finance-solutions/x402/network-and-contracts.mdx @@ -17,8 +17,8 @@ or real funds. | Contract | Address | |---|---| -| Merces Contract | `0xTODO` | -| Confidential USDC token | `0xTODO` | +| Merces Contract | `0x7F73402cB6AF7Ffa446e2D463701e3eA89C95f8f` | +| Confidential USDC token | `0x6AA4dd47444154A1E4424D08622EF6e96bf66de6` | Contract source code is available in the [merces1-x402 GitHub repository](https://github.com/TaceoLabs/merces1-x402). @@ -27,12 +27,12 @@ Contract source code is available in the | Service | URL | |---|---| -| Faucet | `https://faucet.merces.taceo.io` | -| Facilitator | `https://facilitator.merces.taceo.io` | -| Resource server (test) | `https://resource.merces.taceo.io` | -| MPC node 0 | `https://node0.merces.taceo.io` | -| MPC node 1 | `https://node1.merces.taceo.io` | -| MPC node 2 | `https://node2.merces.taceo.io` | +| Faucet | `https://faucet.merces1.taceo.io` | +| Facilitator | `https://x402-facilitator.merces1.taceo.io` | +| Resource server (test) | `https://x402-server.merces1.taceo.io` | +| MPC node 0 | `https://node0.merces1.taceo.io` | +| MPC node 1 | `https://node1.merces1.taceo.io` | +| MPC node 2 | `https://node2.merces1.taceo.io` | ## Chain details @@ -52,7 +52,7 @@ claim per 24 hours. **Endpoint:** `POST /claim/{address}` ```bash -curl -X POST https://faucet.merces.taceo.io/claim/0xYourWalletAddress +curl -X POST https://faucet.merces1.taceo.io/claim/0xYourWalletAddress ``` **Responses:** @@ -72,7 +72,7 @@ not need to configure them manually. To fetch them directly: ```bash -curl https://facilitator.merces.taceo.io/supported +curl https://x402-facilitator.merces1.taceo.io/supported ``` The response includes the current MPC public keys alongside the supported scheme, network, and From c892eff67f95fa2ac2c1829071002b9464925da1 Mon Sep 17 00:00:00 2001 From: ais Date: Mon, 11 May 2026 18:12:10 +0200 Subject: [PATCH 21/25] shielded to private --- docs/finance-solutions/overview.mdx | 8 ++++---- docs/finance-solutions/payments/introduction.mdx | 4 ++-- docs/finance-solutions/yield/introduction.mdx | 8 ++++---- docs/index.mdx | 2 +- docs/use-cases/ai.md | 2 +- docs/use-cases/finance.mdx | 2 +- src/pages/index.tsx | 2 +- static/llms.txt | 2 +- 8 files changed, 15 insertions(+), 15 deletions(-) diff --git a/docs/finance-solutions/overview.mdx b/docs/finance-solutions/overview.mdx index b03bd8b..1032ba1 100644 --- a/docs/finance-solutions/overview.mdx +++ b/docs/finance-solutions/overview.mdx @@ -12,7 +12,7 @@ putting their business on a public ledger. Our finance offering is one privacy solution, **Merces**, with multiple features on top. Merces is TACEO's confidential token transfer protocol. It wraps existing ERC-20 tokens (such as USDC) -into a shielded form. Balances are held as secret shares across the TACEO Network, state +into a private form. Balances are held as secret shares across the TACEO Network, state transitions are verified onchain via CoSNARKs, and no single party (including TACEO) sees what anyone holds or sends. Compliance primitives are built into the protocol, not bolted on top. @@ -47,7 +47,7 @@ The confidential payments network has processed ~5M demo transactions across Arc ### Private Payments -Shielded ERC-20 transfers on the EVM chain you already use. Users get a private virtual account +Private ERC-20 transfers on the EVM chain you already use. Users get a private virtual account alongside their normal public wallet. **Best fit:** @@ -106,7 +106,7 @@ surveillance infrastructure. **In active development.** -Compliant private yield on Ethereum. Earn on shielded balances without exposing positions, +Compliant private yield on Ethereum. Earn on private balances without exposing positions, counterparties, or strategy. Designed for regulated deployment from day one. [Learn more →](/docs/finance-solutions/yield/introduction) @@ -125,7 +125,7 @@ counterparties, or strategy. Designed for regulated deployment from day one. **On the roadmap.** -Confidential swaps, dark pools, and approvals. Brings the shielded-balance model to swap +Confidential swaps, dark pools, and approvals. Brings the private-balance model to swap routers, intent flows, and DeFi composability, so traders and LPs aren't forced to broadcast strategy to the rest of the market. diff --git a/docs/finance-solutions/payments/introduction.mdx b/docs/finance-solutions/payments/introduction.mdx index a079889..450c8b4 100644 --- a/docs/finance-solutions/payments/introduction.mdx +++ b/docs/finance-solutions/payments/introduction.mdx @@ -49,7 +49,7 @@ compliance primitives. Callers pick the mode for each transfer. ## How Merces works -Merces wraps existing ERC-20 tokens (such as USDC) into a shielded form that lives alongside the +Merces wraps existing ERC-20 tokens (such as USDC) into a private form that lives alongside the public token on the same chain. Users gain a **private virtual account** without leaving their existing wallet, RPC, or chain. @@ -103,7 +103,7 @@ For a full privacy analysis at the protocol level, see the x402 |---|---| | **Stablecoin issuers** | Privacy as a feature for issued tokens, without forking the asset | | **Fintechs and neobanks** | A confidential rail under existing user accounts | -| **Payment infrastructure builders** | An SDK-integrable shielded ledger on the EVM they already target | +| **Payment infrastructure builders** | An SDK-integrable private ledger on the EVM they already target | | **Institutions and treasuries** | Confidential settlement on public rails for payroll, vendor payments, and intra-org transfers | | **AI agents and agent platforms** | Spending that doesn't broadcast strategy across paid endpoints | diff --git a/docs/finance-solutions/yield/introduction.mdx b/docs/finance-solutions/yield/introduction.mdx index e4603fc..8fb928e 100644 --- a/docs/finance-solutions/yield/introduction.mdx +++ b/docs/finance-solutions/yield/introduction.mdx @@ -6,7 +6,7 @@ sidebar_label: Private Yield # Private Yield Private Yield brings compliant, confidential yield to Ethereum, built on top of -[Merces](/docs/finance-solutions/payments/introduction). Users earn on shielded balances without exposing positions, +[Merces](/docs/finance-solutions/payments/introduction). Users earn on private balances without exposing positions, counterparty relationships, or strategy onchain, and without giving up the regulatory posture required to operate in real markets. @@ -32,18 +32,18 @@ The two existing paths each fail in their own way: ## What we're building -Private Yield uses the same Merces shielded-balance model as +Private Yield uses the same Merces private-balance model as [Private Payments](/docs/finance-solutions/payments/introduction) and [Confidential x402](/docs/finance-solutions/x402/introduction): balances held as secret shares across the TACEO Network, state transitions verified onchain via CoSNARKs, compliance primitives built into the protocol layer. -The yield layer adds the ability for shielded balances to participate in earning strategies, +The yield layer adds the ability for private balances to participate in earning strategies, without revealing positions, without leaving Ethereum, and without compromising the compliance guarantees that make these rails deployable in regulated markets. ## What's planned -- Yield on shielded ERC-20 balances (starting with USDC) +- Yield on private ERC-20 balances (starting with USDC) - Allowlists and reveal rules carried through from Merces' [Compliance](/docs/finance-solutions/compliance/introduction) layer - The same SDK integration model as Private Payments, issuers and fintechs can offer yield diff --git a/docs/index.mdx b/docs/index.mdx index cdfb7d8..2b3adcb 100644 --- a/docs/index.mdx +++ b/docs/index.mdx @@ -24,7 +24,7 @@ the same stack to onchain finance through **Merces**. ### **Finance Solutions** -Private payments on the EVM chains you already use, built on Merces. Merces wraps ERC-20s like USDC into shielded balances, with compliance primitives at the protocol layer. +Private payments on the EVM chains you already use, built on Merces. Merces wraps ERC-20s like USDC into private balances, with compliance primitives at the protocol layer. **Live on Arc, Base, and Plasma testnets.** ~5M demo transactions, ~300 TPS, single-digit-cents gas on L2. Mainnet deployment in progress. The MPC protocol underneath is the same one TACEO co-architected for World's iris-code system, in production at global scale. diff --git a/docs/use-cases/ai.md b/docs/use-cases/ai.md index c178d2b..84b6ff3 100644 --- a/docs/use-cases/ai.md +++ b/docs/use-cases/ai.md @@ -4,6 +4,6 @@ Bringing AI to Blockchains was an - until yet - unfulfilled promise. Verified of A premise for ZK-powered ML inference is: the one who runs the actual computation and generates the ZK proof must have all data at its hand. As long as this entity is the same as the one who owns IP rights for the (trained) model and user inputs contain no sensitive information, ZK is sufficient. -In cases where users send prompts to the ML model, which shouldn’t be shared with anyone additional encryption techniques need to be added to ZK. With co-SNARKS user inputs can be fully shielded from AI service providers, while not restricting them in offering their services. +In cases where users send prompts to the ML model, which shouldn’t be shared with anyone additional encryption techniques need to be added to ZK. With co-SNARKS user inputs can be fully private from AI service providers, while not restricting them in offering their services. In general, ZK proof generation is hardware intense and often requires specialized equipment. ZK cloud providers or proof markets offer proof computations as a service. As a side effect, all data needs to be shared with the prover, which could leak proprietary IP, like model weights. Co-SNARKS could mitigate this issue by splitting up the sensitive data (e.g. model weights) in secret shares and distributing them among the MPC network. diff --git a/docs/use-cases/finance.mdx b/docs/use-cases/finance.mdx index 748ad06..bf0e461 100644 --- a/docs/use-cases/finance.mdx +++ b/docs/use-cases/finance.mdx @@ -21,7 +21,7 @@ public, programmable chain, without giving up settlement guarantees or complianc ## TACEO's answer: Merces TACEO addresses this through **[Merces](/docs/finance-solutions/payments/introduction)**, a -confidential token transfer protocol that wraps existing ERC-20 tokens (e.g. USDC) into shielded +confidential token transfer protocol that wraps existing ERC-20 tokens (e.g. USDC) into private balances on the EVM chain you already use. Balances are held as secret shares across the [TACEO Network](/docs/taceo-network/), state transitions are verified onchain via CoSNARKs, and no single party, including TACEO, sees what anyone holds or sends. diff --git a/src/pages/index.tsx b/src/pages/index.tsx index ecf20e4..2074c38 100644 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -82,7 +82,7 @@ function GuidanceSection() { lead status="Private onchain finance" title="Build private payments on the chain you already use" - description="Merces wraps existing ERC-20 tokens (USDC and others) into shielded balances. Private payments, x402, and compliance primitives are live on testnet. Private yield is in active development." + description="Merces wraps existing ERC-20 tokens (USDC and others) into private balances. Private payments, x402, and compliance primitives are live on testnet. Private yield is in active development." ctas={[ { to: "/docs/finance-solutions/overview", diff --git a/static/llms.txt b/static/llms.txt index 3a8ea70..88fae90 100644 --- a/static/llms.txt +++ b/static/llms.txt @@ -7,7 +7,7 @@ TACEO is best known for the privacy-preserving identity infrastructure used by W ## Finance Solutions - [Finance Solutions Overview](https://docs.taceo.io/docs/finance-solutions/overview): Private onchain finance powered by Merces. Two privacy modes selectable per transaction, plus compliance and integrations. -- [Private Payments](https://docs.taceo.io/docs/finance-solutions/payments/introduction): Shielded ERC-20 transfers on the EVM chain you already use. Confidential mode (amounts hidden, addresses visible) live on Arc and Base; fully private mode (addresses also hidden) live on Plasma. +- [Private Payments](https://docs.taceo.io/docs/finance-solutions/payments/introduction): Private ERC-20 transfers on the EVM chain you already use. Confidential mode (amounts hidden, addresses visible) live on Arc and Base; fully private mode (addresses also hidden) live on Plasma. - [Confidential x402](https://docs.taceo.io/docs/finance-solutions/x402/introduction): HTTP-embedded confidential payments using the x402 protocol with hidden amounts. Live on Base testnet. - [Confidential x402 Quickstart](https://docs.taceo.io/docs/finance-solutions/x402/quickstart): Make a confidential x402 payment in under five minutes using TACEO's hosted infrastructure. TypeScript and Rust examples. - [Confidential x402 How it works](https://docs.taceo.io/docs/finance-solutions/x402/how-it-works): Component-by-component walkthrough of a confidential x402 payment with sequence diagram and performance numbers. From 838fd20bfb67efb33b289b750eb8558f9a3ca9dc Mon Sep 17 00:00:00 2001 From: ais Date: Mon, 11 May 2026 18:18:18 +0200 Subject: [PATCH 22/25] reference app --- docs/finance-solutions/compliance/introduction.mdx | 2 +- docs/finance-solutions/overview.mdx | 4 ++-- docs/finance-solutions/payments/introduction.mdx | 4 ++-- docs/use-cases/finance.mdx | 2 +- static/llms.txt | 6 +++--- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/finance-solutions/compliance/introduction.mdx b/docs/finance-solutions/compliance/introduction.mdx index cd5fbfc..e7ad66e 100644 --- a/docs/finance-solutions/compliance/introduction.mdx +++ b/docs/finance-solutions/compliance/introduction.mdx @@ -39,7 +39,7 @@ multi-party authorization for reveals, and the ability to enforce policies that user themselves doesn't hold. :::note Public testnet vs. production -On the [public Plasma testnet demo](https://merces.taceo.io/compliance), anyone can try the +On the [public Plasma testnet reference app](https://merces.taceo.io/compliance), anyone can try the decryption flow. In production deployments, access is restricted to explicitly authorized entities by policy and contract configuration. ::: diff --git a/docs/finance-solutions/overview.mdx b/docs/finance-solutions/overview.mdx index 1032ba1..d8c72f2 100644 --- a/docs/finance-solutions/overview.mdx +++ b/docs/finance-solutions/overview.mdx @@ -32,8 +32,8 @@ Merces ships two privacy modes, selectable per transaction, plus compliance and | Capability | What it does | Status | |---|---|---| -| **Confidential payments** | Hide amounts and balances. Sender and receiver visible. | Live on Arc and Base testnets. Demo: [merces-dashboard.taceo.io/arc](https://merces-dashboard.taceo.io/arc). | -| **Fully private payments** | Hide amounts, balances, sender, and receiver. | Live on Plasma testnet. Demo: [merces.taceo.io](https://merces.taceo.io). | +| **Confidential payments** | Hide amounts and balances. Sender and receiver visible. | Live on Arc and Base testnets. Reference Implementation: [merces-dashboard.taceo.io/arc](https://merces-dashboard.taceo.io/arc). | +| **Fully private payments** | Hide amounts, balances, sender, and receiver. | Live on Plasma testnet. Reference App: [merces.taceo.io](https://merces.taceo.io). | | **Compliance dashboard** | Selective disclosure to authorized auditors. | Live on Plasma testnet alongside the private payments deployment. | | **Confidential x402** | HTTP-embedded confidential payments. | Live on Base testnet. | diff --git a/docs/finance-solutions/payments/introduction.mdx b/docs/finance-solutions/payments/introduction.mdx index 450c8b4..91d1faf 100644 --- a/docs/finance-solutions/payments/introduction.mdx +++ b/docs/finance-solutions/payments/introduction.mdx @@ -15,8 +15,8 @@ white-label Merces into their products. End users never see TACEO. :::tip Live infrastructure Merces is live across multiple testnets today. -- **Confidential mode** on Arc and Base testnets. Demo: [merces-dashboard.taceo.io/arc](https://merces-dashboard.taceo.io/arc). -- **Fully private mode and the compliance dashboard** on Plasma testnet. Demo: [merces.taceo.io](https://merces.taceo.io). +- **Confidential mode** on Arc and Base testnets. Reference Implementation: [merces-dashboard.taceo.io/arc](https://merces-dashboard.taceo.io/arc). +- **Fully private mode and the compliance dashboard** on Plasma testnet. Referenece App: [merces.taceo.io](https://merces.taceo.io). The confidential network has processed ~5M demo transactions sustaining ~300 TPS, with single-digit-cents gas per transfer on L2. ::: diff --git a/docs/use-cases/finance.mdx b/docs/use-cases/finance.mdx index bf0e461..6b2df90 100644 --- a/docs/use-cases/finance.mdx +++ b/docs/use-cases/finance.mdx @@ -43,7 +43,7 @@ running surveillance infrastructure. This lets financial applications combine the programmability and settlement guarantees of public blockchains with the privacy properties of traditional financial systems. -A live demo runs at [merces.taceo.io](https://merces.taceo.io). +A live reference app runs at [merces.taceo.io](https://merces.taceo.io). ## Where to go next diff --git a/static/llms.txt b/static/llms.txt index 88fae90..3d4323e 100644 --- a/static/llms.txt +++ b/static/llms.txt @@ -46,9 +46,9 @@ TACEO is best known for the privacy-preserving identity infrastructure used by W - [Merces: Onchain Finance](https://core.taceo.io/articles/merces-onchain-finance/): Canonical positioning piece for Merces. - [Merces deep-dive](https://core.taceo.io/articles/merces-deep-dive/): Technical detail on the two privacy modes, compliance dashboard, and Plasma deployment. -- [Confidential transfers demo writeup](https://core.taceo.io/articles/confidential-token-transfers-demo/): The original Merces I confidential payments demo on Arc and Base. +- [Confidential transfers writeup](https://core.taceo.io/articles/confidential-token-transfers-demo/): The original Merces I confidential payments demo on Arc and Base. - [IACR ePrint 2026/850](https://eprint.iacr.org/2026/850): Escudero et al., "Merces: Confidential Token Transfers via MPC and CoSNARKs." - [TACEO on GitHub](https://github.com/TaceoLabs): All TACEO open source repositories. -- [Demo: confidential payments (Arc, Base)](https://merces-dashboard.taceo.io/arc): Live demo of Merces confidential mode. -- [Demo: fully private payments and compliance (Plasma)](https://merces.taceo.io): Live demo of Merces fully private mode and compliance dashboard. +- [Confidential payments (Arc, Base)](https://merces-dashboard.taceo.io/arc): Live demo of Merces confidential mode. +- [Fully private payments and compliance (Plasma)](https://merces.taceo.io): Live demo of Merces fully private mode and compliance dashboard. - [Compliance dashboard](https://merces.taceo.io/compliance): Live selective-disclosure dashboard for authorized auditors on Plasma testnet. From 2bfad6b4418eba7299df50e111aa9ba215210081 Mon Sep 17 00:00:00 2001 From: ais Date: Mon, 11 May 2026 19:00:39 +0200 Subject: [PATCH 23/25] sign --- docs/index.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/index.mdx b/docs/index.mdx index 2b3adcb..789af3c 100644 --- a/docs/index.mdx +++ b/docs/index.mdx @@ -26,7 +26,7 @@ the same stack to onchain finance through **Merces**. Private payments on the EVM chains you already use, built on Merces. Merces wraps ERC-20s like USDC into private balances, with compliance primitives at the protocol layer. -**Live on Arc, Base, and Plasma testnets.** ~5M demo transactions, ~300 TPS, single-digit-cents gas on L2. Mainnet deployment in progress. The MPC protocol underneath is the same one TACEO co-architected for World's iris-code system, in production at global scale. +**Live on Arc, Base, and Plasma testnets.** ~5M demo transactions, ~300 TPS, sub-cent gas on L2. Mainnet deployment in progress. The MPC protocol underneath is the same one TACEO co-architected for World's iris-code system, in production at global scale. **Looking for design partners.** Stablecoin issuers, fintechs, and payment infrastructure teams shipping private rails to production. Talk to us. From dcfc19d4c323f9efe3907f34491582e760b2a5f7 Mon Sep 17 00:00:00 2001 From: Fabian Gruber Date: Mon, 11 May 2026 19:10:23 +0200 Subject: [PATCH 24/25] fix more wrong facilitator urls --- docs/finance-solutions/x402/integration-guide.mdx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/finance-solutions/x402/integration-guide.mdx b/docs/finance-solutions/x402/integration-guide.mdx index 9fff035..279d119 100644 --- a/docs/finance-solutions/x402/integration-guide.mdx +++ b/docs/finance-solutions/x402/integration-guide.mdx @@ -154,7 +154,7 @@ import { ConfidentialEvmScheme } from '@taceo/confidential-x402/server'; const app = express(); const facilitatorClient = new HTTPFacilitatorClient({ - url: 'https://facilitator.merces.taceo.io', + url: 'https://x402-facilitator.merces1.taceo.io', }); app.use( @@ -199,7 +199,7 @@ use x402_axum::X402Middleware; async fn main() -> eyre::Result<()> { let pay_to = Address::from_str(&std::env::var("WALLET_ADDRESS")?)?; let facilitator_url = std::env::var("FACILITATOR_URL") - .unwrap_or("https://facilitator.merces.taceo.io".to_string()); + .unwrap_or("https://x402-facilitator.merces1.taceo.io".to_string()); let usdc = ConfidentialUSDC::base_sepolia(); let x402 = X402Middleware::new(&facilitator_url); @@ -287,7 +287,7 @@ let app = Router::new() | `network` | CAIP-2 chain ID, e.g. `"eip155:84532"` for Base Sepolia | | `payTo` | Your wallet address that receives payments | | `asset` | Token contract address (provided by the TACEO facilitator automatically) | -| Facilitator URL | `https://facilitator.merces.taceo.io` for TACEO's hosted facilitator | +| Facilitator URL | `https://x402-facilitator.merces1.taceo.io` for TACEO's hosted facilitator | :::info Receiving payments Payments are credited to your `payTo` address as confidential Merces balance. To withdraw tokens From 5427415dd7351dcdaaf8f70c97b453871ff847a5 Mon Sep 17 00:00:00 2001 From: ais Date: Mon, 11 May 2026 19:33:39 +0200 Subject: [PATCH 25/25] update mermaid --- docs/finance-solutions/x402/how-it-works.mdx | 50 ++++++++------------ 1 file changed, 20 insertions(+), 30 deletions(-) diff --git a/docs/finance-solutions/x402/how-it-works.mdx b/docs/finance-solutions/x402/how-it-works.mdx index c33014c..f0fb643 100644 --- a/docs/finance-solutions/x402/how-it-works.mdx +++ b/docs/finance-solutions/x402/how-it-works.mdx @@ -38,36 +38,26 @@ network, and verifies the MPC's proof when the balance update is finalised. ```mermaid sequenceDiagram - participant C as Client - participant R as Resource Server - participant F as Facilitator - participant X as Merces Contract - participant M as MPC Network - - - C->>R: GET /api/ - R-->>C: 402 + PaymentRequired (scheme: confidential) - - Note over C: Generate commitment, secret shares,
ciphertexts, EIP-712 signature,
Groth16 proof - - C->>R: GET /api/ + PAYMENT - - R->>F: POST /verify - X-->>F: commitment - Note over F: verify commitment, signature and client proof - F->>M: enough balance? + Signature - M-->>F: yes/no - F-->>R: isValid: true - R->>F: POST /settle - note over F: do verification (as in /verify route) - F->>X: transferFrom() - Note over X: verify Groth16 proof onchain via ClientTransferVerifier - X-->>F: action_index - Note over M: read_queue, decrypt, update bal, gen proof - M->>X: processMPC - Note over X: verify proof, update comms - F-->>R: success: true - R-->>C: 200 + content + Client->>Resource Server: GET /api + Resource Server-->>Client: 402 + PayReq + Note over Client: compute commitment, create ciphertext, create typed 712 data and sign + Note over Client: generate Groth16 ZK proof (~800ms), compute commitment, create ciphertext, sign EIP-712 + Client->>Resource Server: GET + PAYMENT + Resource Server->>Facilitator: POST /verify + Note over Facilitator: verify client proof + Facilitator->>MPC Network: validBalance? + MPC Network-->>Facilitator: yes/no + Facilitator-->>Resource Server: isValid: true + Resource Server->>Facilitator: POST /settle + Facilitator->>Contract: transferFrom() + Note over Contract: verify Groth16 proof onchain via ClientTransferVerifier + Contract-->>MPC Network: action_index + Note over MPC Network: read_queue, decrypt, update bal, gen proof + MPC Network->>Contract: processMPC + Note over Contract: verify proof, update comms + Contract-->>Facilitator: tx_hash, isValid? + Facilitator-->>Resource Server: success: true + Resource Server-->>Client: 200 + content ```