{"version":3,"sources":["../src/core/proof.ts","../src/core/poseidon.ts","../src/core/identity.ts","../src/core/client.ts","../src/core/asp-list.ts"],"names":["DEFAULT_TREE_DEPTH","MerkleTree","getDefaultHashFunction","hashTwo","ASP_REGISTRY_HUB_ABI"],"mappings":"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","file":"chunk-DAH6YYDZ.cjs","sourcesContent":["/**\n * Membership Proof Generation\n *\n * Generate ZK-ready membership proofs for ASP trees.\n *\n * Two proof-shape conventions live here:\n *\n * - **LeanIMT (SNARK / BLS12-381 side, default).** Dynamic depth with\n *   zero-sibling propagation. `verifyMembershipProof` mirrors the\n *   convention: when `pathElements[i] === 0n`, skip the hash and\n *   propagate `current`. The verifying circuit on the SNARK side\n *   replays the same rule, so zero-padding extra levels is a no-op.\n * - **Always-hash, fixed-depth (STARK / Poseidon31 side).** No\n *   propagation; every level hashes regardless of the sibling. The\n *   in-trace AIR (`Poseidon31MerklePathEval` at `ASP_TREE_DEPTH = 20`)\n *   uses this convention, so a LeanIMT proof must be transformed via\n *   `padLeanIMTProofToDepth` before being fed to the prover.\n *\n * Default hash: Poseidon over BLS12-381 (128-bit security) for the\n * LeanIMT path; Poseidon31 over M31 for the always-hash path.\n */\n\nimport type { IHashFunction } from './hash/interface.js'\nimport { getDefaultHashFunction } from './hash/index.js'\nimport { hashTwo as poseidon31HashTwo } from './hash/poseidon31.js'\nimport { MerkleTree, DEFAULT_TREE_DEPTH } from './tree.js'\nimport type { MembershipProof } from './types.js'\n\n/**\n * Pad LeanIMT proof arrays to a fixed depth.\n * Extra levels get zero siblings — `verifyMembershipProof` and the\n * SNARK circuit both treat zero-sibling levels as propagation no-ops,\n * so extending a short proof with zeros leaves verification semantics\n * unchanged. **NOT for STARK paths** — see `padLeanIMTProofToDepth`.\n */\nfunction padProof(\n  elements: bigint[],\n  indices: number[],\n  targetDepth: number\n): { elements: bigint[]; indices: number[] } {\n  const padElements = [...elements, ...Array(Math.max(0, targetDepth - elements.length)).fill(0n) as bigint[]]\n  const padIndices = [...indices, ...Array(Math.max(0, targetDepth - indices.length)).fill(0) as number[]]\n  return {\n    elements: padElements.slice(0, targetDepth),\n    indices: padIndices.slice(0, targetDepth),\n  }\n}\n\n/**\n * Generate a membership proof for a single-member tree.\n *\n * With LeanIMT single-child optimization, a single-leaf tree\n * has root = leaf, and all path elements are 0.\n */\nexport function generateSingleMemberProof(\n  identity: bigint,\n  treeDepth: number = DEFAULT_TREE_DEPTH\n): MembershipProof {\n  return {\n    root: identity,\n    pathElements: Array(treeDepth).fill(0n) as bigint[],\n    pathIndices: Array(treeDepth).fill(0) as number[],\n  }\n}\n\n/**\n * Generate a membership proof for a multi-member tree.\n *\n * @param identity - The identity to prove membership for\n * @param allMembers - All members in the tree\n * @param treeDepth - Target tree depth for padding (default: 20)\n * @param hashFn - Hash function to use (default: Poseidon-BLS12-381)\n */\nexport async function generateMultiMemberProof(\n  identity: bigint,\n  allMembers: bigint[],\n  treeDepth: number = DEFAULT_TREE_DEPTH,\n  hashFn?: IHashFunction\n): Promise<MembershipProof> {\n  if (allMembers.length <= 1) {\n    return generateSingleMemberProof(identity, treeDepth)\n  }\n\n  const tree = new MerkleTree(treeDepth, hashFn)\n  for (const member of allMembers) {\n    tree.insert(member)\n  }\n\n  const index = tree.indexOf(identity)\n  if (index === -1) {\n    throw new Error(`Identity not found in member list (${allMembers.length} members)`)\n  }\n\n  const proof = await tree.getProof(index)\n  const padded = padProof(proof.pathElements, proof.pathIndices, treeDepth)\n\n  return {\n    root: proof.root,\n    pathElements: padded.elements,\n    pathIndices: padded.indices,\n  }\n}\n\n/**\n * Generate a membership proof, automatically choosing single or multi-member mode.\n *\n * @param identity - The identity to prove membership for\n * @param members - All members in the tree\n * @param treeDepth - Target tree depth for padding (default: 20)\n * @param hashFn - Hash function to use (default: Poseidon-BLS12-381)\n */\nexport async function generateMembershipProof(\n  identity: bigint,\n  members?: bigint[],\n  treeDepth: number = DEFAULT_TREE_DEPTH,\n  hashFn?: IHashFunction\n): Promise<MembershipProof> {\n  if (!members || members.length === 0) {\n    return generateSingleMemberProof(identity, treeDepth)\n  }\n  return generateMultiMemberProof(identity, members, treeDepth, hashFn)\n}\n\n/**\n * Compute the Merkle root for a set of members.\n */\nexport async function computeMerkleRoot(\n  members: bigint[],\n  treeDepth: number = DEFAULT_TREE_DEPTH,\n  hashFn?: IHashFunction\n): Promise<bigint> {\n  if (members.length === 0) return 0n\n  if (members.length === 1) return members[0]!\n  const tree = new MerkleTree(treeDepth, hashFn)\n  for (const member of members) {\n    tree.insert(member)\n  }\n  return tree.getRoot()\n}\n\n/**\n * Verify a membership proof locally.\n *\n * @param identity - The identity to verify\n * @param proof - The membership proof to check\n * @param hashFn - Hash function to use (default: Poseidon-BLS12-381)\n */\nexport async function verifyMembershipProof(\n  identity: bigint,\n  proof: MembershipProof,\n  hashFn?: IHashFunction\n): Promise<boolean> {\n  const hash = hashFn ?? getDefaultHashFunction()\n\n  let current = identity\n\n  for (let i = 0; i < proof.pathElements.length; i++) {\n    const sibling = proof.pathElements[i] ?? 0n\n    const index = proof.pathIndices[i] ?? 0\n\n    if (sibling === 0n) {\n      continue\n    }\n\n    if (index === 0) {\n      current = await hash.hash2(current, sibling)\n    } else {\n      current = await hash.hash2(sibling, current)\n    }\n  }\n\n  return current === proof.root\n}\n\n// ---------------------------------------------------------------------------\n// STARK / always-hash conversion\n// ---------------------------------------------------------------------------\n\n/**\n * Padded path + AIR-shape root produced by [`padLeanIMTProofToDepth`].\n *\n * `root` is the AIR-shape root: the value an always-hash verifier of\n * `targetDepth` levels lands on after starting from the leaf and\n * processing `pathElements` / `pathIndices`. Crucially this is **not**\n * (in general) the LeanIMT root, because the always-hash semantics\n * differs from LeanIMT propagation:\n *\n *   - When the LeanIMT proof carries a zero sibling at level `i`, the\n *     LeanIMT root computation skips the hash and propagates `current`.\n *   - The AIR (and `verifyMerklePath`) hashes anyway. Once you replay\n *     a LeanIMT proof through always-hash semantics, the resulting\n *     root differs from the LeanIMT root the moment any sibling was\n *     zero or the dynamic LeanIMT depth was below `targetDepth`.\n *\n * The on-chain pool's `pub_asp_root` is whatever the AIR computes, so\n * this `root` is what the asp-whitelist must publish for STARK paths.\n * The `pathElements` / `pathIndices` fields satisfy the contract\n * `verifyMerklePath(leaf, pathElements, pathIndices) === root`.\n */\nexport interface AIRShapeProof {\n  /** Path siblings at the AIR's fixed depth. Length equals `targetDepth`. */\n  pathElements: bigint[]\n  /**\n   * Path index bits, one per level. Length equals `targetDepth`.\n   * Bigint to match the in-circuit M31 representation that\n   * `verifyMerklePath` consumes.\n   */\n  pathIndices: bigint[]\n  /**\n   * AIR-shape root: the value `verifyMerklePath` recovers given\n   * `(leaf, pathElements, pathIndices)`. Differs from the input\n   * LeanIMT root whenever propagation kicked in.\n   */\n  root: bigint\n}\n\n/**\n * **TRANSITIONAL — not the long-term canonical tree model.** This is\n * a compatibility shim for adapting LeanIMT proofs (the SDK's existing\n * `MerkleTree` shape) to the always-hash Poseidon31 AIR until the\n * STARK-side tree itself is rebuilt under always-hash semantics\n * (`AlwaysHashMerkleTree`, planned). The helper's per-leaf output is\n * self-consistent, but in sparsely-populated LeanIMT trees different\n * leaves produce different roots, so it cannot back a single\n * `pub_asp_root` shared by every member — see the limitation note\n * below before reaching for it in production paths.\n *\n * Transform a LeanIMT proof into a self-consistent, always-hash,\n * fixed-depth proof the in-trace Poseidon31 ASP-Merkle AIR can\n * consume.\n *\n * Algorithm (proof of correctness sits inline in\n * `pad-lean-imt-proof-to-depth.test.ts`):\n *\n *   1. **Strip propagation levels.** Drop every `(sibling = 0n,\n *      indexBit)` pair from the input — those are LeanIMT no-ops that\n *      the AIR has no analogue for. Keep the relative order of the\n *      surviving non-zero levels.\n *   2. **Replay survivors through always-hash.** Walking from the\n *      leaf, fold each kept level through the supplied `hashTwoFn`\n *      (default: Poseidon31 `hashTwo`) using the level's `indexBit`.\n *   3. **Extend with a zero-hash chain to `targetDepth`.** For every\n *      remaining level, append `(sibling = 0n, indexBit = 0n)` and\n *      fold `current = hashTwoFn(current, 0n)`. The output's\n *      `pathElements`/`pathIndices` are length `targetDepth`; the\n *      final `current` is the AIR-shape root the prover will see.\n *\n * `verifyMerklePath(leaf, output.pathElements, output.pathIndices)`\n * is guaranteed by construction to return `output.root`.\n *\n * # Limitation: cross-leaf root agreement\n *\n * In a sparsely-populated LeanIMT tree (`leafCount` not a power of\n * two), different leaves carry different numbers of propagation\n * levels in their proofs. Stripping then padding produces depth-20\n * proofs that all self-verify but **land on different roots across\n * leaves**. Concretely, for a 5-leaf tree the leftmost leaf has 3\n * non-zero LeanIMT levels (3 real hashes + 17 zero pads = 20), while\n * the rightmost has 1 (1 real hash + 19 zero pads = 20). The two\n * roots differ.\n *\n * This is fine for verifying *one* membership proof end-to-end (the\n * AIR replays exactly what this helper computed), but it means the\n * asp-whitelist cannot use the LeanIMT-then-pad shape to publish a\n * single `pub_asp_root` shared by every member. That requires\n * building the tree itself under always-hash semantics — every\n * internal node hashes regardless, empty subtrees represented by\n * precomputed `ZSR(k)` values. Tracked as a Phase 7 follow-up.\n *\n * Until that follow-up lands, downstream consumers should call this\n * helper only when:\n *   - The LeanIMT proof has no zero siblings (the `leafCount` is a\n *     power of two and the leaf sits in the dense subtree), OR\n *   - They are operating against a single-membership root produced\n *     for that specific leaf (i.e., not a globally-published one).\n *\n * @param leaf — The leaf value the proof attests membership for.\n * @param pathElements — Sibling at each LeanIMT level.\n * @param pathIndices — Side bit at each LeanIMT level (0 = current is\n *   left, 1 = current is right). Accepted as `number[]` (the\n *   `MerkleTree.getProof()` shape) or `bigint[]`.\n * @param targetDepth — The AIR's fixed depth (e.g. `20` for ASP-Merkle,\n *   `32` for state-Merkle).\n * @param hashTwoFn — Pair-hash override. Defaults to the Poseidon31\n *   `hashTwo` that the AIR's chain primitive uses. Override only for\n *   unit tests or alternative AIRs.\n * @throws if `pathElements.length` exceeds `targetDepth` (a LeanIMT\n *   path strictly longer than the AIR depth has nowhere to go) or if\n *   `pathElements.length !== pathIndices.length`.\n */\nexport function padLeanIMTProofToDepth(\n  leaf: bigint,\n  pathElements: bigint[],\n  pathIndices: readonly (number | bigint)[],\n  targetDepth: number,\n  hashTwoFn: (left: bigint, right: bigint) => bigint = poseidon31HashTwo\n): AIRShapeProof {\n  if (pathElements.length !== pathIndices.length) {\n    throw new Error(\n      `padLeanIMTProofToDepth: pathElements (${pathElements.length}) vs pathIndices (${pathIndices.length}) length mismatch`\n    )\n  }\n  if (pathElements.length > targetDepth) {\n    throw new Error(\n      `padLeanIMTProofToDepth: input depth (${pathElements.length}) exceeds targetDepth (${targetDepth}) — the LeanIMT tree is taller than the AIR can verify`\n    )\n  }\n\n  const outElements: bigint[] = []\n  const outIndices: bigint[] = []\n  let current = leaf\n\n  // Pass 1: strip zero-sibling levels, replay survivors through always-hash.\n  for (let i = 0; i < pathElements.length; i++) {\n    const sibling = pathElements[i]!\n    if (sibling === 0n) {\n      // LeanIMT propagation level — the AIR has no representation for\n      // it because it always hashes. Drop the level entirely.\n      continue\n    }\n    const idxRaw = pathIndices[i]!\n    const idx = typeof idxRaw === 'bigint' ? idxRaw : BigInt(idxRaw)\n    if (idx !== 0n && idx !== 1n) {\n      throw new Error(\n        `padLeanIMTProofToDepth: pathIndices[${i}] = ${idx} must be 0 or 1`\n      )\n    }\n    outElements.push(sibling)\n    outIndices.push(idx)\n    current = idx === 0n ? hashTwoFn(current, sibling) : hashTwoFn(sibling, current)\n  }\n\n  // Pass 2: zero-pad to targetDepth using always-hash. Each padded\n  // level uses indexBit = 0 by convention (current goes on the left).\n  while (outElements.length < targetDepth) {\n    outElements.push(0n)\n    outIndices.push(0n)\n    current = hashTwoFn(current, 0n)\n  }\n\n  return {\n    pathElements: outElements,\n    pathIndices: outIndices,\n    root: current,\n  }\n}\n\n","/**\n * Poseidon Hash Utilities\n *\n * Wrapper around circomlibjs Poseidon hash implementation.\n * Used for Merkle tree hashing and identity derivation.\n */\n\n// circomlibjs types (not exported by the library)\ntype PoseidonFn = {\n  (inputs: bigint[]): Uint8Array\n  F: {\n    toObject: (val: Uint8Array) => bigint\n    e: (val: bigint) => unknown\n  }\n}\n\n// Lazily initialized Poseidon instance\nlet poseidonInstance: PoseidonFn | null = null\n\n/**\n * BN254 field prime (same as used in Circom/snarkjs)\n */\nexport const FIELD_PRIME = 21888242871839275222246405745257275088548364400416034343698204186575808495617n\n\n/**\n * Initialize Poseidon hash function (lazy loading)\n */\nasync function initPoseidon(): Promise<PoseidonFn> {\n  if (!poseidonInstance) {\n    const { buildPoseidon } = await import('circomlibjs')\n    poseidonInstance = await buildPoseidon() as PoseidonFn\n  }\n  return poseidonInstance!\n}\n\n/**\n * Compute Poseidon hash of inputs\n *\n * @param inputs - Array of field elements to hash (up to 16 elements)\n * @returns Hash as bigint\n */\nexport async function poseidon(inputs: bigint[]): Promise<bigint> {\n  const poseidonFn = await initPoseidon()\n  const hash = poseidonFn(inputs)\n  return poseidonFn.F.toObject(hash)\n}\n\n/**\n * Check if a value is within the BN254 field\n */\nexport function isValidFieldElement(value: bigint): boolean {\n  return value >= 0n && value < FIELD_PRIME\n}\n","/**\n * Identity Derivation\n *\n * Utilities for computing ZK-friendly identity commitments\n * from various key formats.\n */\n\nimport { poseidon } from './poseidon.js'\n\n/**\n * Compute a Poseidon-based identity commitment from a BabyJubJub public key.\n *\n * This is the standard identity format for SNARK circuits.\n *\n * @param pubKeyX - X coordinate of the BabyJubJub public key\n * @param pubKeyY - Y coordinate of the BabyJubJub public key\n * @returns Identity commitment as Poseidon(pubKeyX, pubKeyY)\n */\nexport async function computeIdentityFromBabyJubJub(\n  pubKeyX: bigint,\n  pubKeyY: bigint\n): Promise<bigint> {\n  return poseidon([pubKeyX, pubKeyY])\n}\n\n/**\n * Compute an identity commitment from an Ethereum address.\n *\n * For simple allowlists where the identity is just the address.\n * The address is cast to a field element (uint160 fits in BN254 field).\n *\n * @param address - Ethereum address (hex string)\n * @returns Address as bigint\n */\nexport function computeIdentityFromAddress(address: `0x${string}`): bigint {\n  return BigInt(address)\n}\n\n/**\n * Compute a Poseidon-hashed identity from a secret.\n *\n * Similar to Semaphore v4's identity model: identity = hash(secret).\n *\n * @param secret - A secret value known only to the user\n * @returns Identity commitment as Poseidon(secret)\n */\nexport async function computeIdentityFromSecret(secret: bigint): Promise<bigint> {\n  return poseidon([secret])\n}\n","/**\n * ASP Client\n *\n * High-level API for interacting with the ASP system.\n * Orchestrates between providers (off-chain storage) and\n * the blockchain (on-chain registry).\n */\n\nimport { generateMembershipProof } from './proof.js'\nimport type { IHashFunction } from './hash/interface.js'\nimport type {\n  ASPClientConfig,\n  IASPProvider,\n  MembershipProof,\n  RegisterASPOptions,\n  PublishRootOptions,\n} from './types.js'\nimport { ASP_REGISTRY_HUB_ABI } from '../contracts/abi/ASPRegistryHub.js'\n\n/**\n * ASP Client instance\n */\nexport class ASPClient {\n  private readonly provider: IASPProvider\n  private readonly publicClient: any // viem PublicClient\n  private readonly registryAddress: `0x${string}`\n  private readonly hashFn: IHashFunction | undefined\n  private aspId: bigint | undefined\n\n  constructor(config: ASPClientConfig) {\n    this.provider = config.provider\n    this.publicClient = config.publicClient\n    this.registryAddress = config.registryAddress\n    this.aspId = config.aspId\n    this.hashFn = config.hashFunction\n  }\n\n  /**\n   * Register a new ASP on-chain\n   */\n  async register(options: RegisterASPOptions): Promise<bigint> {\n    const walletClient = options.walletClient as any\n\n    const hash = await walletClient.writeContract({\n      address: this.registryAddress,\n      abi: ASP_REGISTRY_HUB_ABI,\n      functionName: 'registerASP',\n      args: [options.name],\n    })\n\n    // Wait for receipt to get the ASP ID from events\n    const receipt = await this.publicClient.waitForTransactionReceipt({ hash })\n\n    // Extract ASP ID from ASPRegistered event\n    for (const log of receipt.logs) {\n      try {\n        // ASPRegistered(uint256 indexed aspId, address indexed operator, string name)\n        // The aspId is the first indexed topic\n        if (log.topics[1]) {\n          this.aspId = BigInt(log.topics[1])\n          return this.aspId\n        }\n      } catch {\n        continue\n      }\n    }\n\n    throw new Error('Failed to extract ASP ID from transaction receipt')\n  }\n\n  /**\n   * Get the current ASP ID\n   */\n  getASPId(): bigint | undefined {\n    return this.aspId\n  }\n\n  /**\n   * Set the ASP ID (for existing registrations)\n   */\n  setASPId(aspId: bigint): void {\n    this.aspId = aspId\n  }\n\n  /**\n   * Add a member identity to the tree\n   */\n  async addMember(identity: bigint): Promise<void> {\n    await this.provider.addMember(identity)\n  }\n\n  /**\n   * Remove a member identity from the tree\n   */\n  async removeMember(identity: bigint): Promise<void> {\n    await this.provider.removeMember(identity)\n  }\n\n  /**\n   * Get all members\n   */\n  async getMembers(): Promise<bigint[]> {\n    return this.provider.getMembers()\n  }\n\n  /**\n   * Check if an identity is a member\n   */\n  async hasMember(identity: bigint): Promise<boolean> {\n    return this.provider.hasMember(identity)\n  }\n\n  /**\n   * Get the current Merkle root from the provider\n   */\n  async getRoot(): Promise<bigint> {\n    return this.provider.getRoot()\n  }\n\n  /**\n   * Generate a membership proof for an identity\n   */\n  async generateProof(identity: bigint): Promise<MembershipProof> {\n    const members = await this.provider.getMembers()\n    return generateMembershipProof(identity, members, this.provider.treeDepth, this.hashFn)\n  }\n\n  /**\n   * Publish the current Merkle root on-chain\n   */\n  async publishRoot(options: PublishRootOptions): Promise<`0x${string}`> {\n    if (!this.aspId) {\n      throw new Error('ASP not registered. Call register() first or set aspId.')\n    }\n\n    const root = await this.provider.getRoot()\n    const walletClient = options.walletClient as any\n\n    const hash = await walletClient.writeContract({\n      address: this.registryAddress,\n      abi: ASP_REGISTRY_HUB_ABI,\n      functionName: 'updateRoot',\n      args: [this.aspId, root],\n    })\n\n    return hash as `0x${string}`\n  }\n\n  /**\n   * Publish a STARK-side Merkle root on-chain.\n   *\n   * The STARK side maintains a parallel tree (typically over the same\n   * membership set) using a STARK-friendly hash (e.g., Poseidon31). The\n   * root is supplied by the caller because the SNARK provider doesn't\n   * compute it — the caller is expected to manage a `MerkleTree` with a\n   * `PoseidonM31` hash and pass its root here.\n   *\n   * Operators MUST publish in lock-step with the SNARK root so both\n   * proof systems stay aligned (an attacker who can update only one of\n   * the two roots can keep the other stale and bypass compliance on\n   * one path).\n   */\n  async publishStarkRoot(\n    starkRoot: bigint,\n    options: PublishRootOptions,\n  ): Promise<`0x${string}`> {\n    if (!this.aspId) {\n      throw new Error('ASP not registered. Call register() first or set aspId.')\n    }\n\n    const walletClient = options.walletClient as any\n\n    const hash = await walletClient.writeContract({\n      address: this.registryAddress,\n      abi: ASP_REGISTRY_HUB_ABI,\n      functionName: 'updateStarkRoot',\n      args: [this.aspId, starkRoot],\n    })\n\n    return hash as `0x${string}`\n  }\n\n  /**\n   * Check if a root is valid on-chain (current or historical)\n   */\n  async isValidRoot(root: bigint): Promise<boolean> {\n    if (!this.aspId) return false\n\n    return this.publicClient.readContract({\n      address: this.registryAddress,\n      abi: ASP_REGISTRY_HUB_ABI,\n      functionName: 'isValidASPRoot',\n      args: [this.aspId, root],\n    }) as Promise<boolean>\n  }\n\n  /**\n   * Check if a STARK-side root is valid on-chain (current or historical).\n   */\n  async isValidStarkRoot(starkRoot: bigint): Promise<boolean> {\n    if (!this.aspId) return false\n\n    return this.publicClient.readContract({\n      address: this.registryAddress,\n      abi: ASP_REGISTRY_HUB_ABI,\n      functionName: 'isValidSTARKRoot',\n      args: [this.aspId, starkRoot],\n    }) as Promise<boolean>\n  }\n\n  /**\n   * Get the current on-chain root\n   */\n  async getCurrentOnChainRoot(): Promise<bigint> {\n    if (!this.aspId) return 0n\n\n    return this.publicClient.readContract({\n      address: this.registryAddress,\n      abi: ASP_REGISTRY_HUB_ABI,\n      functionName: 'getCurrentRoot',\n      args: [this.aspId],\n    }) as Promise<bigint>\n  }\n\n  /**\n   * Get the current on-chain STARK root.\n   */\n  async getCurrentOnChainStarkRoot(): Promise<bigint> {\n    if (!this.aspId) return 0n\n\n    return this.publicClient.readContract({\n      address: this.registryAddress,\n      abi: ASP_REGISTRY_HUB_ABI,\n      functionName: 'getCurrentStarkRoot',\n      args: [this.aspId],\n    }) as Promise<bigint>\n  }\n\n  /**\n   * Get the provider\n   */\n  getProvider(): IASPProvider {\n    return this.provider\n  }\n}\n\n/**\n * Create a new ASP client\n */\nexport function createASPClient(config: ASPClientConfig): ASPClient {\n  return new ASPClient(config)\n}\n","/**\n * ASP List — Types and Utilities\n *\n * An ASP list is a curated registry of Association Set Providers for a specific chain,\n * similar to Uniswap's token lists. Platform operators maintain their own ASP lists\n * to control which compliance providers their users can choose from.\n *\n * UPC provides the types and loader — the lists themselves are maintained by consumers.\n */\n\n// ============ Types ============\n\n/**\n * ASP type classification\n */\nexport type ASPType =\n  | 'auto-whitelist'       // Automatically adds members (e.g., on token mint/shield)\n  | 'kyc'                  // Requires KYC verification\n  | 'sanctions'            // Sanctions screening (OFAC, etc.)\n  | 'accredited-investor'  // Accredited investor verification\n  | 'custom'               // Custom attestation logic\n\n/**\n * Security level of an ASP\n */\nexport type ASPSecurityLevel =\n  | 'demo'          // For testing only — no real compliance checks\n  | 'production'    // Real compliance checks, suitable for production\n  | 'institutional' // Audited, documented ceremony, institutional grade\n\n/**\n * A single ASP entry in the list\n */\nexport interface ASPEntry {\n  /** On-chain ASP identifier (from ASPRegistryHub.registerASP()) */\n  aspId: number\n  /** Chain ID this ASP operates on */\n  chainId: number\n  /** Human-readable name */\n  name: string\n  /** Type of compliance check */\n  type: ASPType\n  /** Description of what this ASP verifies */\n  description: string\n  /** Operator address (who manages the Merkle tree) */\n  operator: `0x${string}`\n  /** ASPRegistryHub contract address */\n  registryAddress: `0x${string}`\n  /**\n   * URL to fetch membership proofs.\n   * Expected endpoints:\n   *   GET {proofEndpoint}/{address} → { root, pathElements, pathIndices }\n   *   GET {proofEndpoint}/../root   → { root }\n   *   GET {proofEndpoint}/../status → { memberCount, ... }\n   */\n  proofEndpoint: string\n  /**\n   * URL for user registration (null for auto-whitelist ASPs).\n   * For KYC ASPs, this links to the verification portal.\n   */\n  registrationUrl: string | null\n  /** Security level */\n  securityLevel: ASPSecurityLevel\n  /** Whether this ASP is currently active */\n  active: boolean\n  /** Optional logo URL */\n  logoUrl?: string\n}\n\n/**\n * ASP list for a specific chain\n */\nexport interface ASPList {\n  /** List name */\n  name: string\n  /** Chain ID */\n  chainId: number\n  /** Semantic version */\n  version: string\n  /** Last update date (ISO 8601) */\n  updatedAt: string\n  /** ASP entries */\n  asps: ASPEntry[]\n}\n\n// ============ Loader ============\n\n/**\n * Load an ASP list from a JSON object.\n * Validates the structure and returns typed entries.\n */\nexport function parseASPList(json: unknown): ASPList {\n  const list = json as ASPList\n  if (!list.asps || !Array.isArray(list.asps)) {\n    throw new Error('Invalid ASP list: missing \"asps\" array')\n  }\n  if (typeof list.chainId !== 'number') {\n    throw new Error('Invalid ASP list: missing \"chainId\"')\n  }\n  return list\n}\n\n/**\n * Filter an ASP list to only active entries\n */\nexport function getActiveASPs(list: ASPList): ASPEntry[] {\n  return list.asps.filter(asp => asp.active)\n}\n\n/**\n * Find an ASP by ID in a list\n */\nexport function findASPById(list: ASPList, aspId: number): ASPEntry | undefined {\n  return list.asps.find(asp => asp.aspId === aspId)\n}\n\n/**\n * Fetch a membership proof from an ASP's proof endpoint\n */\nexport async function fetchASPProof(\n  asp: ASPEntry,\n  address: `0x${string}`\n): Promise<{\n  root: bigint\n  pathElements: bigint[]\n  pathIndices: number[]\n}> {\n  const res = await fetch(`${asp.proofEndpoint}/${address}`)\n  if (!res.ok) {\n    if (res.status === 404) {\n      throw new Error(`Address ${address} not found in ASP \"${asp.name}\" (aspId: ${asp.aspId})`)\n    }\n    throw new Error(`Failed to fetch proof from ASP \"${asp.name}\": ${res.status} ${res.statusText}`)\n  }\n\n  const data = await res.json() as {\n    root: string\n    pathElements: string[]\n    pathIndices: number[]\n  }\n\n  return {\n    root: BigInt(data.root),\n    pathElements: data.pathElements.map(e => BigInt(e)),\n    pathIndices: data.pathIndices,\n  }\n}\n"]}