> ## Documentation Index
> Fetch the complete documentation index at: https://docs.walletwall.org/llms.txt
> Use this file to discover all available pages before exploring further.

# Stablecoin Vault & Vault Simulator

> Stablecoin Vault is WalletWall's flagship vault readiness and migration journey (vault.walletwall.org / /stablecoin-vault). The Vault Simulator (/vault) is the Sepolia testnet rehearsal detail route.

export const resolveProofGateMatrix = input => {
  const REHEARSAL = {
    not_configured: 'not_configured',
    rehearsal_metadata_missing: 'rehearsal_metadata_missing',
    unsupported_schema: 'unsupported_schema',
    unavailable: 'unavailable',
    rehearsal_ready: 'rehearsal_ready'
  };
  const PQ_STATE = {
    observed: 'observed',
    not_observed: 'not_observed'
  };
  const ARTIFACT = {
    not_configured: 'not_configured',
    available: 'available'
  };
  const PROOF_BLOCK = {
    gated: 'gated',
    unavailable: 'unavailable',
    not_generated: 'not_generated'
  };
  const FORBIDDEN_CHAINS = [1, 8453, 137, 10, 42161, 56, 43114];
  const ALLOWED_TESTNETS = [31337, 11155111, 84532];
  const RED_LINES = ['Quantum-secure or quantum-proof', 'Production quantum protection', 'ZK-verified wallet', 'Live SP1 proof (proving is gated in this app)', 'On-chain ML-DSA verification (no implementation exists)', 'Mainnet-ready or production-ready', 'Custody, fund protection, or guaranteed security', 'Yield, interest, or returns'];
  const CLAIMS = {
    pq_evidence: 'Read-only, hash-only PQ verifier evidence was observed',
    artifact_available: 'Static proof-artifact metadata is available for display',
    artifact_reproducible: 'A reproducible proof-artifact example is available',
    rehearsal_ready: 'Sepolia testnet rehearsal metadata is documented and metadata-safe',
    research_status: 'Research and testnet status only'
  };
  const rehearsalGate = cfg => {
    if (cfg.metadataConfigured === false) {
      return {
        state: REHEARSAL.not_configured,
        reasons: ['No rehearsal metadata is configured.']
      };
    }
    const reasons = [];
    if (FORBIDDEN_CHAINS.includes(cfg.chainId)) {
      reasons.push(`chainId ${cfg.chainId} is a mainnet chain ID.`);
    } else if (!ALLOWED_TESTNETS.includes(cfg.chainId)) {
      reasons.push(`chainId ${cfg.chainId} is not an allowed testnet/local chain ID.`);
    }
    if (cfg.tokenMode !== 'mock') reasons.push(`tokenMode "${cfg.tokenMode}" is not 'mock'.`);
    if (cfg.safetyGatesAllTrue === false) reasons.push('At least one required appGate is not true.');
    return reasons.length > 0 ? {
      state: REHEARSAL.unavailable,
      reasons
    } : {
      state: REHEARSAL.rehearsal_ready,
      reasons: []
    };
  };
  const pqEvidenceObserved = input?.pqEvidenceObserved === true;
  const artifactAvailable = input?.artifactAvailable === true;
  const artifactReproducible = input?.artifactReproducible === true;
  const chainId = input?.chainId ?? 11155111;
  const tokenMode = input?.tokenMode ?? 'mock';
  const safetyGatesAllTrue = input?.safetyGatesAllTrue !== false;
  const metadataConfigured = input?.metadataConfigured !== false;
  const sp1ProvingRequested = input?.sp1ProvingRequested === true;
  const onChainMldsaRequested = input?.onChainMldsaRequested === true;
  const productionAuditCompleted = input?.productionAuditCompleted === true;
  const mainnetDeploymentRequested = input?.mainnetDeploymentRequested === true;
  const rehearsal = rehearsalGate({
    chainId,
    tokenMode,
    safetyGatesAllTrue,
    metadataConfigured
  });
  const gates = Object.freeze({
    pqEvidence: pqEvidenceObserved ? PQ_STATE.observed : PQ_STATE.not_observed,
    proofArtifact: artifactAvailable ? ARTIFACT.available : ARTIFACT.not_configured,
    proofArtifactReproducible: artifactAvailable && artifactReproducible,
    rehearsal: rehearsal.state,
    proofBlockStatus: PROOF_BLOCK.gated,
    onChainMldsaVerification: 'absent',
    mainnetDeployment: 'blocked',
    productionAudit: productionAuditCompleted ? 'completed' : 'absent'
  });
  const supported = [CLAIMS.research_status];
  if (gates.pqEvidence === PQ_STATE.observed) {
    supported.push(CLAIMS.pq_evidence);
  }
  if (gates.proofArtifact === ARTIFACT.available) {
    supported.push(CLAIMS.artifact_available);
  }
  if (gates.proofArtifactReproducible) {
    supported.push(CLAIMS.artifact_reproducible);
  }
  if (gates.rehearsal === REHEARSAL.rehearsal_ready) {
    supported.push(CLAIMS.rehearsal_ready);
  }
  const unsupported = [];
  if (gates.pqEvidence !== PQ_STATE.observed) {
    unsupported.push('PQ verifier evidence observed');
  }
  if (gates.proofArtifact !== ARTIFACT.available) {
    unsupported.push('Proof-artifact metadata available for display');
  }
  if (!gates.proofArtifactReproducible) {
    unsupported.push('Reproducible proof-artifact example available');
  }
  if (gates.rehearsal !== REHEARSAL.rehearsal_ready) {
    unsupported.push('Testnet rehearsal metadata ready');
  }
  for (const claim of RED_LINES) unsupported.push(claim);
  const failClosedNotices = [];
  if (sp1ProvingRequested) {
    failClosedNotices.push('SP1 proving was requested, but this app pins proofBlockStatus to "gated". No proof is generated by or for this surface, so no live-proof claim is unlocked.');
  }
  if (onChainMldsaRequested) {
    failClosedNotices.push('On-chain ML-DSA verification was requested, but no implementation exists — the public reference records feasibility only. The gate stays "absent".');
  }
  if (mainnetDeploymentRequested) {
    failClosedNotices.push('Mainnet deployment was requested, but it is hard-blocked. Mainnet chain IDs can never resolve to a ready state.');
  }
  if (FORBIDDEN_CHAINS.includes(chainId)) {
    failClosedNotices.push(`chainId ${chainId} is a mainnet chain ID — the rehearsal gate fails closed to "unavailable" and is never shown as ready.`);
  }
  if (tokenMode !== 'mock') {
    failClosedNotices.push('A non-mock token mode fails closed. Only mock assets with no monetary value are ever in scope.');
  }
  if (productionAuditCompleted) {
    failClosedNotices.push('A completed audit is its own separate gate. It does not imply mainnet readiness, production protection, or any of the red-line claims below.');
  }
  return Object.freeze({
    gates,
    rehearsalReasons: rehearsal.reasons,
    supported: Object.freeze(supported),
    unsupported: Object.freeze(unsupported),
    failClosedNotices: Object.freeze(failClosedNotices)
  });
};

export const ProofGateMatrix = ({idPrefix = 'pgm'}) => {
  const GATE_ROWS = [['pqEvidence', 'PQ evidence'], ['proofArtifact', 'Proof artifact status'], ['proofArtifactReproducible', 'Proof artifact reproducible'], ['rehearsal', 'Testnet rehearsal'], ['proofBlockStatus', 'SP1 proving'], ['onChainMldsaVerification', 'On-chain ML-DSA verification'], ['productionAudit', 'Production audit'], ['mainnetDeployment', 'Mainnet deployment']];
  const STYLES = `
.ww-pgm{--ww-pgm-bg:#FAFAF0;--ww-pgm-panel:#FFF7E8;--ww-pgm-ink:#2B2118;--ww-pgm-muted:#59646A;--ww-pgm-line:#B87333;--ww-pgm-line-soft:#D9C7B3;--ww-pgm-accent:#B84923;--ww-pgm-ok:#526246;--ww-pgm-warn:#8A5A1F;--ww-pgm-risk:#8F2F1D;}
@media (prefers-color-scheme:dark){.ww-pgm{--ww-pgm-bg:#1B1512;--ww-pgm-panel:#241C17;--ww-pgm-ink:#F2E9DF;--ww-pgm-muted:#A7B0B5;--ww-pgm-line:#8A5A1F;--ww-pgm-line-soft:#4A3B30;--ww-pgm-accent:#D9714B;--ww-pgm-ok:#9AAB89;--ww-pgm-warn:#D6A85A;--ww-pgm-risk:#E0836B;}}
.light .ww-pgm,:root.light .ww-pgm{--ww-pgm-bg:#FAFAF0;--ww-pgm-panel:#FFF7E8;--ww-pgm-ink:#2B2118;--ww-pgm-muted:#59646A;--ww-pgm-line:#B87333;--ww-pgm-line-soft:#D9C7B3;--ww-pgm-accent:#B84923;--ww-pgm-ok:#526246;--ww-pgm-warn:#8A5A1F;--ww-pgm-risk:#8F2F1D;}
.dark .ww-pgm,:root.dark .ww-pgm{--ww-pgm-bg:#1B1512;--ww-pgm-panel:#241C17;--ww-pgm-ink:#F2E9DF;--ww-pgm-muted:#A7B0B5;--ww-pgm-line:#8A5A1F;--ww-pgm-line-soft:#4A3B30;--ww-pgm-accent:#D9714B;--ww-pgm-ok:#9AAB89;--ww-pgm-warn:#D6A85A;--ww-pgm-risk:#E0836B;}
.ww-pgm{background:var(--ww-pgm-bg);color:var(--ww-pgm-ink);border:2px solid var(--ww-pgm-line);border-radius:4px;padding:1rem;font-size:0.875rem;line-height:1.5;}
.ww-pgm *{box-sizing:border-box;}
.ww-pgm-h{font-weight:600;font-size:0.75rem;letter-spacing:0.08em;text-transform:uppercase;color:var(--ww-pgm-muted);margin:0 0 0.5rem;}
.ww-pgm fieldset{border:1px solid var(--ww-pgm-line-soft);border-radius:3px;padding:0.6rem 0.75rem 0.75rem;margin:0 0 0.75rem;}
.ww-pgm legend{font-weight:600;font-size:0.8125rem;padding:0 0.35rem;color:var(--ww-pgm-accent);}
.ww-pgm-checks{display:grid;grid-template-columns:1fr;gap:0.4rem;}
@media (min-width:40rem){.ww-pgm-checks{grid-template-columns:1fr 1fr;}}
.ww-pgm-check{display:flex;align-items:flex-start;gap:0.45rem;}
.ww-pgm-check input{margin-top:0.25rem;flex:none;}
.ww-pgm-check input:focus-visible{outline:2px solid var(--ww-pgm-accent);outline-offset:2px;}
.ww-pgm-field{display:flex;flex-direction:column;gap:0.25rem;}
.ww-pgm-field label{font-weight:600;}
.ww-pgm-field select{width:100%;padding:0.4rem 0.5rem;border:1px solid var(--ww-pgm-line-soft);border-radius:3px;background:var(--ww-pgm-panel);color:var(--ww-pgm-ink);font:inherit;}
.ww-pgm-field select:focus-visible{outline:2px solid var(--ww-pgm-accent);outline-offset:2px;}
.ww-pgm-scroll{overflow-x:auto;}
.ww-pgm-table{width:100%;border-collapse:collapse;font-size:0.8125rem;}
.ww-pgm-table caption{text-align:left;font-weight:600;color:var(--ww-pgm-muted);padding-bottom:0.35rem;}
.ww-pgm-table th,.ww-pgm-table td{border-bottom:1px solid var(--ww-pgm-line-soft);padding:0.35rem 0.4rem;text-align:left;}
.ww-pgm-code{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:0.8125rem;background:var(--ww-pgm-bg);border:1px solid var(--ww-pgm-line-soft);border-radius:2px;padding:0.05rem 0.3rem;}
.ww-pgm-cols{display:grid;grid-template-columns:1fr;gap:0.75rem;margin-top:1rem;}
@media (min-width:48rem){.ww-pgm-cols{grid-template-columns:1fr 1fr;}}
.ww-pgm-col{border:1px solid var(--ww-pgm-line-soft);border-radius:3px;background:var(--ww-pgm-panel);padding:0.75rem;}
.ww-pgm-col[data-tone="ok"]{border-left:4px solid var(--ww-pgm-ok);}
.ww-pgm-col[data-tone="no"]{border-left:4px solid var(--ww-pgm-risk);}
.ww-pgm-col h4{margin:0 0 0.4rem;font-size:0.875rem;}
.ww-pgm-list{margin:0;padding-left:1.1rem;}
.ww-pgm-list li{margin:0.2rem 0;}
.ww-pgm-list[data-tone="no"] li{color:var(--ww-pgm-risk);}
.ww-pgm-notice{margin-top:0.75rem;border:1px solid var(--ww-pgm-warn);border-left:4px solid var(--ww-pgm-warn);border-radius:3px;padding:0.6rem;color:var(--ww-pgm-warn);}
.ww-pgm-notice ul{margin:0.3rem 0 0;padding-left:1.1rem;}
.ww-pgm-note{margin-top:0.75rem;padding-top:0.6rem;border-top:1px dashed var(--ww-pgm-line-soft);color:var(--ww-pgm-muted);font-size:0.8125rem;}
.ww-pgm-reset{margin-top:0.75rem;padding:0.35rem 0.7rem;border:1px solid var(--ww-pgm-line);border-radius:3px;background:transparent;color:var(--ww-pgm-ink);font:inherit;font-size:0.8125rem;cursor:pointer;}
.ww-pgm-reset:focus-visible{outline:2px solid var(--ww-pgm-accent);outline-offset:2px;}
`;
  const [pqEvidenceObserved, setPqEvidenceObserved] = useState(true);
  const [artifactAvailable, setArtifactAvailable] = useState(true);
  const [artifactReproducible, setArtifactReproducible] = useState(true);
  const [metadataConfigured, setMetadataConfigured] = useState(true);
  const [chainId, setChainId] = useState(11155111);
  const [tokenMode, setTokenMode] = useState('mock');
  const [safetyGatesAllTrue, setSafetyGatesAllTrue] = useState(true);
  const [sp1ProvingRequested, setSp1ProvingRequested] = useState(false);
  const [onChainMldsaRequested, setOnChainMldsaRequested] = useState(false);
  const [productionAuditCompleted, setProductionAuditCompleted] = useState(false);
  const [mainnetDeploymentRequested, setMainnetDeploymentRequested] = useState(false);
  const result = useMemo(() => resolveProofGateMatrix({
    pqEvidenceObserved,
    artifactAvailable,
    artifactReproducible,
    metadataConfigured,
    chainId,
    tokenMode,
    safetyGatesAllTrue,
    sp1ProvingRequested,
    onChainMldsaRequested,
    productionAuditCompleted,
    mainnetDeploymentRequested
  }), [pqEvidenceObserved, artifactAvailable, artifactReproducible, metadataConfigured, chainId, tokenMode, safetyGatesAllTrue, sp1ProvingRequested, onChainMldsaRequested, productionAuditCompleted, mainnetDeploymentRequested]);
  const reset = () => {
    setPqEvidenceObserved(true);
    setArtifactAvailable(true);
    setArtifactReproducible(true);
    setMetadataConfigured(true);
    setChainId(11155111);
    setTokenMode('mock');
    setSafetyGatesAllTrue(true);
    setSp1ProvingRequested(false);
    setOnChainMldsaRequested(false);
    setProductionAuditCompleted(false);
    setMainnetDeploymentRequested(false);
  };
  const evidenceChecks = [{
    name: 'pq',
    label: 'Read-only PQ verifier evidence observed',
    checked: pqEvidenceObserved,
    onChange: setPqEvidenceObserved
  }, {
    name: 'artifact',
    label: 'Proof artifact example available',
    checked: artifactAvailable,
    onChange: setArtifactAvailable
  }, {
    name: 'repro',
    label: 'Proof artifact reproducible',
    checked: artifactReproducible,
    onChange: setArtifactReproducible
  }, {
    name: 'audit',
    label: 'Production audit completed',
    checked: productionAuditCompleted,
    onChange: setProductionAuditCompleted
  }];
  const rehearsalChecks = [{
    name: 'meta',
    label: 'Rehearsal metadata configured',
    checked: metadataConfigured,
    onChange: setMetadataConfigured
  }, {
    name: 'gates',
    label: 'All required safety gates true',
    checked: safetyGatesAllTrue,
    onChange: setSafetyGatesAllTrue
  }];
  const pinnedChecks = [{
    name: 'sp1',
    label: 'Request SP1 proving active',
    checked: sp1ProvingRequested,
    onChange: setSp1ProvingRequested
  }, {
    name: 'mldsa',
    label: 'Request on-chain ML-DSA verification',
    checked: onChainMldsaRequested,
    onChange: setOnChainMldsaRequested
  }, {
    name: 'mainnet',
    label: 'Request mainnet deployment allowed',
    checked: mainnetDeploymentRequested,
    onChange: setMainnetDeploymentRequested
  }];
  return <div className="ww-pgm not-prose">
      <style>{STYLES}</style>

      <p className="ww-pgm-h">Proof gate matrix — educational claim boundaries, not a verifier</p>

      <fieldset>
        <legend>Evidence and artifact gates</legend>
        <div className="ww-pgm-checks">
          {evidenceChecks.map(check => <span className="ww-pgm-check" key={check.name}>
              <input id={`${idPrefix}-${check.name}`} type="checkbox" checked={check.checked} onChange={e => check.onChange(e.target.checked)} />
              <label htmlFor={`${idPrefix}-${check.name}`}>{check.label}</label>
            </span>)}
        </div>
      </fieldset>

      <fieldset>
        <legend>Testnet rehearsal gate</legend>
        <div className="ww-pgm-checks">
          {rehearsalChecks.map(check => <span className="ww-pgm-check" key={check.name}>
              <input id={`${idPrefix}-${check.name}`} type="checkbox" checked={check.checked} onChange={e => check.onChange(e.target.checked)} />
              <label htmlFor={`${idPrefix}-${check.name}`}>{check.label}</label>
            </span>)}
          <div className="ww-pgm-field">
            <label htmlFor={`${idPrefix}-chain`}>Chain</label>
            <select id={`${idPrefix}-chain`} value={chainId} onChange={e => setChainId(Number.parseInt(e.target.value, 10))}>
              <option value={11155111}>Sepolia testnet (11155111)</option>
              <option value={31337}>Local dev chain (31337)</option>
              <option value={1}>Ethereum mainnet (1) — must fail closed</option>
            </select>
          </div>
          <div className="ww-pgm-field">
            <label htmlFor={`${idPrefix}-token`}>Token mode</label>
            <select id={`${idPrefix}-token`} value={tokenMode} onChange={e => setTokenMode(e.target.value)}>
              <option value="mock">Mock assets only</option>
              <option value="real">Non-mock — must fail closed</option>
            </select>
          </div>
        </div>
      </fieldset>

      <fieldset>
        <legend>Hard-pinned gates — select one to watch it fail closed</legend>
        <div className="ww-pgm-checks">
          {pinnedChecks.map(check => <span className="ww-pgm-check" key={check.name}>
              <input id={`${idPrefix}-${check.name}`} type="checkbox" checked={check.checked} onChange={e => check.onChange(e.target.checked)} />
              <label htmlFor={`${idPrefix}-${check.name}`}>{check.label}</label>
            </span>)}
        </div>
      </fieldset>

      <div aria-live="polite">
        <div className="ww-pgm-scroll">
          <table className="ww-pgm-table">
            <caption>Resolved gate states — each derived from its own inputs only</caption>
            <thead>
              <tr>
                <th scope="col">Gate</th>
                <th scope="col">State</th>
              </tr>
            </thead>
            <tbody>
              {GATE_ROWS.map(([key, label]) => <tr key={key}>
                  <th scope="row">{label}</th>
                  <td>
                    <code className="ww-pgm-code">{String(result.gates[key])}</code>
                  </td>
                </tr>)}
            </tbody>
          </table>
        </div>

        {result.rehearsalReasons.length > 0 && <p className="ww-pgm-note">
            Rehearsal gate reasons: {result.rehearsalReasons.join(' ')}
          </p>}

        {result.failClosedNotices.length > 0 && <div className="ww-pgm-notice">
            <strong>Failed closed</strong>
            <ul>
              {result.failClosedNotices.map(notice => <li key={notice}>{notice}</li>)}
            </ul>
          </div>}

        <div className="ww-pgm-cols">
          <div className="ww-pgm-col" data-tone="ok">
            <h4>Claims supported by the selected state</h4>
            <ul className="ww-pgm-list">
              {result.supported.map(claim => <li key={claim}>{claim}</li>)}
            </ul>
          </div>
          <div className="ww-pgm-col" data-tone="no">
            <h4>Claims not supported by the selected state</h4>
            <ul className="ww-pgm-list" data-tone="no">
              {result.unsupported.map(claim => <li key={claim}>{claim}</li>)}
            </ul>
          </div>
        </div>
      </div>

      <p className="ww-pgm-note">
        Educational claim-boundary explorer only. No cryptography runs, no prover or contract is
        called, no repository is fetched, and no wallet is connected. The right-hand column is
        permanent: no combination of these controls can ever move a red-line claim into the
        supported column.
      </p>

      <button type="button" className="ww-pgm-reset" onClick={reset}>
        Reset to the documented testnet scenario
      </button>
    </div>;
};

# Stablecoin Vault & Vault Simulator

WalletWall ships two related but distinct vault surfaces. Keep them separate in all copy and docs.

<Tabs>
  <Tab title="Stablecoin Vault (flagship)">
    * **Route:** `/stablecoin-vault`
    * **Subdomain:** `vault.walletwall.org`
    * **Role:** Flagship vault readiness and migration journey — the destination the intelligence layer feeds
  </Tab>

  <Tab title="Vault Simulator">
    * **Route:** `/vault`
    * **Subdomain:** none — no subdomain, not a peer flagship product
    * **Role:** Sepolia testnet rehearsal detail — post-quantum authorization simulation, no mainnet, no custody
  </Tab>
</Tabs>

<Warning>
  Both surfaces are research prototypes. Neither involves real funds, real custody, mainnet deposits, or production-grade quantum verification. See the [Vault Boundaries & Disclosures](/vault/boundaries) page for the full statement.
</Warning>

***

## Stablecoin Vault (flagship)

The Stablecoin Vault is the destination the WalletWall intelligence layer feeds — the action layer a wallet arrives at once Quantum Intelligence, Stable Seer, and Holder Wall have assessed its readiness. It is reachable at `/stablecoin-vault` and at `vault.walletwall.org`.

The Stablecoin Vault surfaces a **readiness journey** with four outcomes:

| Recommendation        | When                                                          | What the app offers                                                                            |
| --------------------- | ------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- |
| **Monitor**           | Low exposure / low urgency; no action needed yet              | Keep watching; no simulator entry                                                              |
| **Prepare**           | Meaningful exposure; migration feasible but not urgent        | Show recommended migration path + readiness checklist; simulator offered as optional rehearsal |
| **Testnet Rehearsal** | Exposure + structure make the wallet a strong vault candidate | Prominent "Open the testnet vault simulator" entry                                             |
| **Not Enough Data**   | Insufficient signals to recommend                             | Provisional copy; **no** simulator entry; invite a fuller scan                                 |

These map onto existing Migration Readiness engine outputs (`monitor` / `plan` / `prioritize` urgency and the `vault-prototype` recommended path) — they are a presentation layer, not new math.

```mermaid theme={null}
flowchart TD
    accTitle: Stablecoin Vault four-outcome readiness journey
    accDescr: A wallet's readiness signals feed a presentation-layer verdict with four possible outcomes: Monitor, Prepare, Testnet Rehearsal, or Not Enough Data. Only Testnet Rehearsal, and optionally Prepare, surface an entry into the Vault Simulator; Monitor and Not Enough Data never do. This is a read-only assessment, not an action or transaction.
    R["Wallet readiness signals"]:::input --> V{"Readiness verdict"}:::decision
    V -->|"low exposure / low urgency"| M["Monitor<br/>keep watching, no simulator entry"]:::process
    V -->|"meaningful exposure, not urgent"| P["Prepare<br/>migration path + checklist;<br/>simulator optional"]:::process
    V -->|"exposure + structure = strong candidate"| T["Testnet Rehearsal<br/>prominent simulator entry"]:::output
    V -->|"insufficient signals"| N["Not Enough Data<br/>no simulator entry, invites fuller scan"]:::risk
    P -.->|"optional rehearsal entry"| S(["Vault Simulator<br/>/vault, Sepolia testnet"]):::external
    T -->|"testnet rehearsal entry"| S
    classDef input fill:#FAFAF0,stroke:#B87333,color:#2B2118,stroke-width:1.5px;
    classDef process fill:#B84923,stroke:#6B2412,color:#FFF7E8,stroke-width:1.5px;
    classDef decision fill:#D6A85A,stroke:#8A5A1F,color:#2B2118,stroke-width:1.5px;
    classDef output fill:#9AAB89,stroke:#526246,color:#172014,stroke-width:1.5px;
    classDef risk fill:#8F2F1D,stroke:#5E1D12,color:#FFF7E8,stroke-width:1.5px;
    classDef external fill:#A7B0B5,stroke:#59646A,color:#172014,stroke-width:1.5px;
```

*This diagram visualizes the table above; it adds no new inputs. The readiness assessment is read-only — Testnet Rehearsal (and optionally Prepare) is the only intended entry point into the Vault Simulator from the product journey; Monitor and Not Enough Data never surface a simulator entry.*

### Readiness signals

The readiness verdict is supported by four read-only **readiness signals**, kept as **separate gates** — none implies the others, and none is a protection guarantee:

<Columns cols={2}>
  <Card title="PQ Evidence" icon="fingerprint">
    A hash-only, read-only record that the open ML-DSA-65 verifier accepted a test vector. Not custody, not on-chain verification.
  </Card>

  <Card title="Testnet Rehearsal" icon="flask">
    Whether documented Sepolia/testnet simulator metadata is present and safe to surface — mock assets only.
  </Card>

  <Card title="Proof Artifact Status" icon="clipboard-check">
    Read-only metadata for a reproducible proof-artifact example **generated outside the app**. **SP1 proving remains gated** in this app.
  </Card>

  <Card title="ZK / SP1 disclosure" icon="circle-info">
    Research/disclosure status only — no ZK proof runs behind any readiness state. This is **not production quantum protection**.
  </Card>
</Columns>

These signals are read-only and **generated outside the app**: WalletWall does not fetch the reference repo at runtime, run SP1, or call any verifier service. See [PQ Evidence, Testnet Rehearsal & ZK/SP1 Status](/vault/pq-evidence-and-rehearsal) for the full statement.

### Handoffs into Stablecoin Vault

<Columns cols={3}>
  <Card title="Holder Wall → Stablecoin Vault" icon="wallet">
    When a valid EVM wallet is open in the Holder Wall drawer, the app can route to Stablecoin Vault readiness with the wallet address in context.
  </Card>

  <Card title="Quantum Intelligence → Stablecoin Vault" icon="atom">
    When Quantum Intelligence has assessed a wallet's signature and migration exposure, a Stablecoin Vault readiness link is surfaced if the `vault-prototype` path is recommended.
  </Card>

  <Card title="Stable Seer → Stablecoin Vault" icon="chart-line">
    Stable Seer's stablecoin exposure signals (peg health, concentration, flows) are inputs to the Stablecoin Vault readiness assessment.
  </Card>
</Columns>

### Stablecoin Vault → Vault Simulator

From the **Testnet Rehearsal** recommendation (and optionally **Prepare**), the Stablecoin Vault surfaces an entry into the Vault Simulator at `/vault`. This is the only intended entry point into the Vault Simulator from the product journey; the Vault Simulator is a technical detail, not a standalone flagship.

***

## Vault Simulator (Sepolia testnet detail)

The Vault Simulator is a **research prototype** that demonstrates a hybrid classical + post-quantum authorization model for Ethereum wallet migration. It is reachable at `/vault` only — it has no subdomain and is not a peer flagship product.

<Warning>
  The Vault Simulator is a research prototype. The readiness scanner is read-only. The connected dashboard is testnet-only and can request EIP-712 signatures and submit testnet transactions. The current verifier is not production-grade post-quantum verification, and no live native PQ precompile support is claimed.
</Warning>

### Current implementation boundary

The Vault Simulator's UI is a compatibility/prototype surface. The readiness scanner is read-only and the migration path panel is driven by the shared wallet-security profile when available, with a migration-only fallback. WalletWall does not store private keys, does not ask for seed phrases, and does not implement recovery flows in this UI.

The shared wallet-security orchestration layer supplies the security state, vault eligibility, and recovery readiness rendered in the Wallet Security and Migration Path panels. The canonical boundary and guarantees live in the [Key Management & Recovery Model](/security/key-management-recovery-model) — recovery flows are **not implemented yet**.

#### Which readiness signal is which

PQ evidence, proof artifact status, and testnet rehearsal are **separate gates** — a positive state in one never implies another. The matrix below makes that boundary interactive; the full explanation lives in [PQ Evidence, Testnet Rehearsal & ZK/SP1 Status](/vault/pq-evidence-and-rehearsal).

<ProofGateMatrix idPrefix="vault-gates" />

### Deployment status

Ethereum Sepolia is the validated active deployment:

| Field                  | Value                                                                |
| ---------------------- | -------------------------------------------------------------------- |
| Status                 | `active-testnet`                                                     |
| Chain ID               | `11155111`                                                           |
| Vault                  | `0x210ceD9C12AF27b10B06eB5506b24a51E11506E9`                         |
| Verifier               | `0x832E223c6D889A96bCFF434a609e8a5782C706e9`                         |
| Deploy transaction     | `0x8f15e6c99ee4ac789836716c75d26a8dc8df240dad731cbc8a7c9515e91cc3e1` |
| Live runtime           | `20,508` bytes                                                       |
| Reported source commit | `828bf219c0e2612fcd1aba5f085c4abeba29de88`                           |

<Warning>
  The reported source commit is absent from public Vault history, and current public HEAD recompiles to `22,138` runtime bytes, not the active deployment runtime of `20,508` bytes. This deployment is **not reproducible from public HEAD yet** — in the public repo its reproducibility is **remediation-gated** and recorded in a machine-checkable manifest (`deployments/reproducibility/walletwall-vault-sepolia.json`, enforced by `npm run validate:reproducibility`). The committed remediation path is to redeploy from public HEAD or publish the exact source tag and artifact manifest. Do not claim that current public HEAD reproduces the active Sepolia deployment.
</Warning>

The prior Sepolia deployment identified as `0x8c5B…CF24` is `deprecated` because it has a stale runtime and uses the incompatible legacy 32-byte PQ-key vault format. Do not use it for new vaults or reference it as active.

The public [Wallet-Wall/walletwall-vault](https://github.com/Wallet-Wall/walletwall-vault) repository owns contracts, security assumptions, verifier design, tests, and deployment records. The private app consumes pinned ABI, custom errors, events, EIP-712 schema, and deployment configuration only. No full public-repository mirror should be added.

The Stablecoin Vault page surfaces this trust state in a read-only **Vault Trust Status** panel. It reports the public reference path as `remediation-gated`, states that the active Sepolia deployment is not reproducible from public HEAD yet, lists the two remediation paths, and links to the public reproducibility manifest at `deployments/reproducibility/walletwall-vault-sepolia.json`. The panel is presentational only — it performs no runtime fetch, deploy, or transaction, implies no custody, deposits, wallet connection, or signing, and makes no mainnet-readiness claim.

### Page flow

#### Entry phase

The entry page explains the three concepts (Quantum Exposure, Migration Readiness, WalletWall Vault), shows the research disclosure, and presents a read-only scan form. Users can enter any Ethereum address or ENS name. A deep-link param `?vw=<address>` triggers the scan automatically on load. Scanning does not require a wallet connection, signature, or transaction.

The connected Vault dashboard is separate from the readiness scanner. It is testnet-only, with Ethereum Sepolia as the validated active deployment. Ethereum Mainnet and Base Mainnet writes remain blocked.

#### Result phase

After scanning, the result phase renders, top to bottom:

<Steps>
  <Step title="Score ring">
    Displays the vault readiness band (`unknown`, `weak`, `moderate`, `strong`, `resilient`) and the scanned address.
  </Step>

  <Step title="Research disclosure">
    Always visible; states the prototype is read-only in the scanner and does not store keys.
  </Step>

  <Step title="Quantum Vault Readiness Card">
    Recovery readiness breakdown, findings, recommendations, controls, and migration path panel.
  </Step>

  <Step title="Proof-of-Readiness Campaign Preview">
    Shows which readiness campaigns the scanned wallet is eligible for, and an evidence hash derived deterministically from the wallet's security profile signals.
  </Step>

  <Step title="Simulate: Authorization flow panel">
    Collapsed by default; see below.
  </Step>

  <Step title="Research repository link">
    Links to the WalletWall Vault GitHub repo.
  </Step>
</Steps>

The `← New scan` button resets to entry without navigating away.

### Recovery Readiness Score

The score is computed by the recovery-readiness scorer. It starts from a base of 62 and applies deltas for:

| Signal                                            | Effect |
| ------------------------------------------------- | ------ |
| Outgoing transactions (public key may be exposed) | −18    |
| Address reuse pattern                             | −8     |
| Very high value concentration (≥ \$1 M)           | −18    |
| High value concentration (≥ \$100 K)              | −12    |
| Dormant wallet with meaningful balance            | −10    |
| Sampled / partial data                            | −5     |
| Multisig / Safe detected                          | +18    |
| Timelock detected                                 | +12    |
| Guardian recovery detected                        | +10    |
| Fresh wallet pattern detected                     | +6     |

#### Score bands

| Band        | Score range                         |
| ----------- | ----------------------------------- |
| `resilient` | ≥ 90                                |
| `strong`    | 70–89                               |
| `moderate`  | 40–69                               |
| `weak`      | \< 40                               |
| `unknown`   | Insufficient data (score is `null`) |

When no wallet signals are available the score is `null` and status is `insufficient_data`. A heuristic-only baseline is never shown as wallet-specific intelligence.

### Simulate: Authorization flow panel

The Simulate: Authorization flow panel is a collapsible research illustration — **not** an interactive signing flow. It renders in the result phase below the Quantum Vault Readiness Card, collapsed by default.

It shows a static, deterministic narrative of what a hybrid ECDSA + ML-DSA authorization step would look like for this wallet. Steps are neutral-gray (not success/fail colored) and labeled as a conceptual illustration.

| Step                                                      | Content                                                                       |
| --------------------------------------------------------- | ----------------------------------------------------------------------------- |
| **Step 1 — Wallet classification**                        | Detected wallet type from `readiness.controls.multisig`                       |
| **Step 2 — Classical authorization (ECDSA)**              | Signer language derived from multisig status                                  |
| **Step 3 — Post-quantum authorization (ML-DSA FIPS 204)** | Always static — co-sign with new ML-DSA key pair (off-chain, conceptual only) |
| **Step 4 — On-chain verification (research placeholder)** | Always static — WalletWall Vault verifier contract, NOT production-grade      |

```mermaid theme={null}
%%{init: {'theme': 'base', 'themeVariables': {'actorBkg': '#B84923', 'actorBorder': '#6B2412', 'actorTextColor': '#FFF7E8', 'actorLineColor': '#8A5A1F', 'signalColor': '#2B2118', 'signalTextColor': '#2B2118', 'labelBoxBkgColor': '#A7B0B5', 'labelBoxBorderColor': '#59646A', 'labelTextColor': '#172014', 'loopTextColor': '#2B2118', 'noteBkgColor': '#D6A85A', 'noteBorderColor': '#8A5A1F', 'noteTextColor': '#2B2118', 'activationBkgColor': '#FAFAF0', 'activationBorderColor': '#B87333', 'sequenceNumberColor': '#FFF7E8'}}}%%
sequenceDiagram
    accTitle: Simulate Authorization flow panel — conceptual hybrid ECDSA plus ML-DSA illustration
    accDescr: A static, deterministic four-step narrative shown collapsed by default in the result phase. It illustrates wallet classification, a classical ECDSA step, a conceptual off-chain ML-DSA co-signature, and a research-placeholder on-chain verification step. No wallet connection, no signature request, and nothing is submitted on-chain.
    participant W as Scanned wallet (illustrative)
    participant P as Panel narrative
    participant E as Step 2: ECDSA (classical)
    participant M as Step 3: ML-DSA FIPS 204 (off-chain, conceptual)
    participant V as Step 4: Verifier contract (research placeholder)
    Note over W,V: Static, deterministic narrative — not an interactive signing flow
    W->>P: Step 1 — wallet classification (readiness.controls.multisig)
    P->>E: Step 2 — signer language derived from multisig status
    E->>M: Step 3 — conceptual co-sign with new ML-DSA key pair
    M->>V: Step 4 — WalletWall Vault verifier contract
    Note over V: NOT production-grade. Nothing submitted on-chain. No keys accessed.
```

*This renders the table above as a sequence, nothing more. Every step is illustration only — the panel is collapsed by default and colored neutral-gray rather than success/fail; it represents no real signature request, no key access, and no on-chain submission.*

Use careful labels such as "research simulation", "conceptual flow", "illustration", "not a real authorization", "no keys accessed", "nothing submitted on-chain", and "monitor only". Avoid absolute safety, recovery, or asset-control claims.

***

## Product registration

The product navigation registry defines the two surfaces (as of PR #1005). The Stablecoin Vault appears as item 05 in `PRODUCT_NAV_ITEMS`, the primary homepage journey. The Vault Simulator is a detail route and does not appear in the primary nav.

<AccordionGroup>
  <Accordion title="Registry definitions (source excerpt)" icon="code">
    ```js theme={null}
    // Flagship stablecoin vault — vault.walletwall.org / /stablecoin-vault
    stablecoinVault: {
      id: 'stablecoinVault',
      label: 'Stablecoin Vault',
      subdomain: 'vault',
      canonicalHost: 'vault.walletwall.org',
      legacyPath: '/stablecoin-vault',
      componentRoute: '/stablecoin-vault',
      canonicalPath: '/stablecoin-vault',
      description: 'Testnet research prototype — quantum-resistant stablecoin vault readiness journey',
      iconKey: 'vault',
    },

    // Vault Simulator — /vault only, no subdomain
    vault: {
      id: 'vault',
      label: 'Vault Simulator',
      subdomain: null,
      canonicalHost: null,
      legacyPath: '/vault',
      componentRoute: '/vault',
      canonicalPath: '/vault',
      description: 'Sepolia testnet vault simulator — post-quantum authorization rehearsal. No mainnet, no custody.',
      iconKey: 'vault',
    },
    ```
  </Accordion>
</AccordionGroup>

***

## Cryptographic research context

The vault prototype models hybrid authorization using:

* **ML-DSA (FIPS 204)** — formerly CRYSTALS-Dilithium; the primary post-quantum signature scheme.
* **SLH-DSA (FIPS 205)** — formerly SPHINCS+; referenced as related signature research.
* **ECDSA / secp256k1** — the current Ethereum signature scheme, retained in the hybrid flow.

The hybrid proof binds both an ECDSA signature and an ML-DSA signature to the migration transaction. The on-chain verifier is an architectural placeholder — it does not perform production-grade cryptographic verification.

Connected-dashboard withdrawals use EIP-712 typed-data signing. Before transaction submission, the app runs a `staticCall` preflight and surfaces decoded custom errors when revert data matches the pinned ABI. Mock PQ key and signature material is prototype/testnet-only.

***

## Approved framing

| Use                                | Do not use                          |
| ---------------------------------- | ----------------------------------- |
| Post-quantum migration research    | Quantum-proof                       |
| Hybrid authorization prototype     | Quantum-secure                      |
| Experimental migration path        | Protects real funds                 |
| Research-backed prototype          | Guaranteed quantum resistance       |
| Conceptual illustration            | Seed phrase recovery                |
| Not a real authorization           | Deploy vault now                    |
| Stablecoin Vault readiness journey | Vault is production-ready           |
| Vault Simulator (for /vault)       | vault.walletwall.org is a simulator |

***

## Related

<Columns cols={2}>
  <Card title="Quantum Intelligence" icon="atom" href="/features/quantum-intelligence">
    The scoring model and Dune feeds that power vault readiness.
  </Card>

  <Card title="Migration Readiness" icon="route" href="/concepts/migration-readiness">
    The four-tier engine behind the Stablecoin Vault recommendation.
  </Card>

  <Card title="Vault Boundaries & Disclosures" icon="shield-halved" href="/vault/boundaries">
    Full custody, testnet, and quantum-security boundary statements.
  </Card>

  <Card title="Open the Stablecoin Vault" icon="arrow-up-right-from-square" href="https://vault.walletwall.org">
    The flagship vault readiness and migration journey, at vault.walletwall.org.
  </Card>

  <Card title="WalletWall Vault research repository" icon="github" href="https://github.com/Wallet-Wall/walletwall-vault">
    Owns contracts, security assumptions, verifier design, tests, and deployment records.
  </Card>
</Columns>
