@permissionless-technologies/upp-sdk 0.5.7 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chunk-2GKW4UCQ.js +234 -0
- package/dist/chunk-2GKW4UCQ.js.map +1 -0
- package/dist/chunk-36LLQN63.js +83 -0
- package/dist/chunk-36LLQN63.js.map +1 -0
- package/dist/{chunk-C3HXJ5A6.cjs → chunk-47FETLYV.cjs} +17 -3
- package/dist/chunk-47FETLYV.cjs.map +1 -0
- package/dist/{chunk-2NKFTLPD.js → chunk-7GDDA5VR.js} +17 -3
- package/dist/chunk-7GDDA5VR.js.map +1 -0
- package/dist/chunk-CCWMVO3H.cjs +249 -0
- package/dist/chunk-CCWMVO3H.cjs.map +1 -0
- package/dist/{chunk-OG6TNEAT.js → chunk-D6C2OOOC.js} +2 -2
- package/dist/{chunk-OG6TNEAT.js.map → chunk-D6C2OOOC.js.map} +1 -1
- package/dist/{chunk-TKUOY2PQ.cjs → chunk-IETMGF5J.cjs} +2 -2
- package/dist/{chunk-TKUOY2PQ.cjs.map → chunk-IETMGF5J.cjs.map} +1 -1
- package/dist/{chunk-NGXEIUQ6.cjs → chunk-MZDCTYGM.cjs} +4 -4
- package/dist/{chunk-NGXEIUQ6.cjs.map → chunk-MZDCTYGM.cjs.map} +1 -1
- package/dist/{chunk-N2VHE47N.js → chunk-PJBEE2OI.js} +16 -16
- package/dist/{chunk-N2VHE47N.js.map → chunk-PJBEE2OI.js.map} +1 -1
- package/dist/chunk-PXCVNAWP.cjs +91 -0
- package/dist/chunk-PXCVNAWP.cjs.map +1 -0
- package/dist/{chunk-A6IYQ7UF.js → chunk-QYF2A5SO.js} +3 -3
- package/dist/{chunk-A6IYQ7UF.js.map → chunk-QYF2A5SO.js.map} +1 -1
- package/dist/{chunk-Y3VL3LOE.cjs → chunk-SEAXI5UO.cjs} +16 -16
- package/dist/{chunk-Y3VL3LOE.cjs.map → chunk-SEAXI5UO.cjs.map} +1 -1
- package/dist/core/index.cjs +60 -60
- package/dist/core/index.d.cts +2 -2
- package/dist/core/index.d.ts +2 -2
- package/dist/core/index.js +4 -4
- package/dist/{index-B31tBTbC.d.ts → index-B03HwFbO.d.ts} +15 -4
- package/dist/{index-CzmvOht6.d.cts → index-BSaHIJzn.d.cts} +15 -4
- package/dist/{index-a_f935pS.d.cts → index-BafRK5nW.d.cts} +10 -1
- package/dist/{index-2eL8ZLD0.d.ts → index-DndOuerz.d.ts} +10 -1
- package/dist/index.cjs +155 -126
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +5 -4
- package/dist/index.d.ts +5 -4
- package/dist/index.js +8 -7
- package/dist/index.js.map +1 -1
- package/dist/indexer/index.cjs +11 -11
- package/dist/indexer/index.d.cts +6 -5
- package/dist/indexer/index.d.ts +6 -5
- package/dist/indexer/index.js +1 -1
- package/dist/keys/index.cjs +56 -27
- package/dist/keys/index.d.cts +33 -3
- package/dist/keys/index.d.ts +33 -3
- package/dist/keys/index.js +2 -1
- package/dist/passkey-Df4lrhN5.d.cts +77 -0
- package/dist/passkey-ZnoYRP-r.d.ts +77 -0
- package/dist/react/index.cjs +236 -65
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.d.cts +18 -2
- package/dist/react/index.d.ts +18 -2
- package/dist/react/index.js +182 -26
- package/dist/react/index.js.map +1 -1
- package/dist/{transfer-27GZNGCI.js → transfer-7PPJAS3X.js} +3 -3
- package/dist/{transfer-27GZNGCI.js.map → transfer-7PPJAS3X.js.map} +1 -1
- package/dist/{transfer-TJNDCZF2.cjs → transfer-ZZ263JLF.cjs} +10 -10
- package/dist/{transfer-TJNDCZF2.cjs.map → transfer-ZZ263JLF.cjs.map} +1 -1
- package/dist/{types-CJSbxv4q.d.cts → types-9MmVALxO.d.cts} +1 -1
- package/dist/{types-mLybMxNR.d.ts → types-CI4nEY9S.d.ts} +1 -1
- package/dist/utils/index.cjs +21 -21
- package/dist/utils/index.js +1 -1
- package/package.json +1 -1
- package/src/deployments/31337.json +14 -14
- package/dist/chunk-2NKFTLPD.js.map +0 -1
- package/dist/chunk-C3HXJ5A6.cjs.map +0 -1
- package/dist/chunk-FTEXUSHR.js +0 -150
- package/dist/chunk-FTEXUSHR.js.map +0 -1
- package/dist/chunk-LKXC3OQT.cjs +0 -165
- package/dist/chunk-LKXC3OQT.cjs.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/core/client.ts","../src/core/types.ts","../src/core/note.ts","../src/core/index.ts","../src/core/verify.ts"],"names":["init_stealth"],"mappings":"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","file":"chunk-NGXEIUQ6.cjs","sourcesContent":["/**\n * Main UPP Client\n *\n * Provides high-level API for interacting with the Universal Private Pool.\n */\n\nimport type { Address, PublicClient, WalletClient } from 'viem'\nimport type {\n ShieldParams,\n TransferParams,\n MergeParams,\n WithdrawParams,\n Note,\n} from './types.js'\n\n/**\n * UPP Client configuration\n */\nexport interface UPPClientConfig {\n /** Viem public client for reading chain state */\n publicClient: PublicClient\n /** Viem wallet client for sending transactions */\n walletClient: WalletClient\n /** Universal Private Pool contract address */\n poolAddress: Address\n /** ASP Registry Hub contract address */\n aspHubAddress: Address\n /** Chain ID (optional, derived from clients if not provided) */\n chainId?: number\n}\n\n/**\n * UPP Client interface\n */\nexport interface UPPClient {\n /** Shield tokens into the private pool */\n shield(params: ShieldParams): Promise<{ commitment: `0x${string}`; note: Note }>\n\n /** Transfer tokens privately */\n transfer(params: TransferParams): Promise<{ nullifier: `0x${string}`; changeNote?: Note }>\n\n /** Merge multiple notes into one */\n merge(params: MergeParams): Promise<{ commitment: `0x${string}`; note: Note }>\n\n /** Withdraw tokens from the private pool */\n withdraw(params: WithdrawParams): Promise<{ txHash: `0x${string}` }>\n\n /** Scan for notes belonging to a viewing key */\n scanNotes(viewingKey: `0x${string}`): Promise<Note[]>\n\n /** Get the current state root */\n getStateRoot(): Promise<bigint>\n\n /** Check if a nullifier has been spent */\n isNullifierSpent(nullifier: `0x${string}`): Promise<boolean>\n}\n\n/**\n * Create a UPP client instance\n *\n * @example\n * ```ts\n * import { createUPPClient } from '@upp/sdk'\n * import { createPublicClient, createWalletClient, http } from 'viem'\n * import { sepolia } from 'viem/chains'\n *\n * const publicClient = createPublicClient({\n * chain: sepolia,\n * transport: http(),\n * })\n *\n * const walletClient = createWalletClient({\n * chain: sepolia,\n * transport: http(),\n * })\n *\n * const client = createUPPClient({\n * publicClient,\n * walletClient,\n * poolAddress: '0x...',\n * aspHubAddress: '0x...',\n * })\n * ```\n */\nexport function createUPPClient(_config: UPPClientConfig): UPPClient {\n // TODO: Implement client\n throw new Error('Not implemented')\n}\n","/**\n * Core type definitions for UPP SDK\n */\n\nimport type { Address, Hex } from 'viem'\n\n/**\n * Note version - increment when note structure changes\n */\nexport const NOTE_VERSION = 5\n\n// =========================================================================\n// Shielded Note Types (stored in NoteStore, used across React hooks)\n// =========================================================================\n\n/** Note lifecycle status */\nexport type NoteStatus = 'pending' | 'confirmed' | 'spent'\n\n/** Which proof system created/guards a note */\nexport type ProofSystem = 'snark' | 'stark'\n\n/**\n * A shielded note (UTXO) - Post-quantum hash-based\n *\n * Commitment = Poseidon(amount, ownerHash, blinding, origin, token)\n * where ownerHash = Poseidon(spendingSecret)\n */\nexport interface ShieldedNote {\n /** Amount of tokens */\n amount: bigint\n /** Random blinding factor */\n blinding: bigint\n /** Commitment hash (hex) */\n commitment: string\n /** Spending secret for this note (hex) - proves ownership via hash preimage */\n ownerSecret: string\n /** Owner hash = Poseidon(ownerSecret) - what's committed on-chain (hex) */\n ownerHash: string\n /** Position in Merkle tree */\n leafIndex: number\n /** Origin address (original depositor) as hex */\n origin: string\n /** Token address as hex */\n token: string\n /** Transaction hash */\n txHash?: string\n /** Note status */\n status: NoteStatus\n /** Timestamp */\n timestamp: number\n /** Which proof system created this note (defaults to 'snark' for legacy notes) */\n proofSystem?: ProofSystem\n /** Block number where note was created (from IndexedNote) */\n blockNumber?: number\n /** Ephemeral public key X (R.x — used as viewing key nonce, for ECDH-based notes) */\n ephemeralX?: string\n /** Ephemeral public key Y (R.y, for ECDH-based notes) */\n ephemeralY?: string\n}\n\n/**\n * A private note in the Universal Private Pool\n */\nexport interface Note {\n /** Note format version */\n version: number\n /** Token amount (in wei) */\n amount: bigint\n /** Random blinding factor */\n blinding: bigint\n /** Current origin - who is responsible for these funds (updated on merge) */\n origin: Address\n /** Sender - who sent this specific note (for payment attribution) */\n sender: Address\n /** ERC20 token address */\n token: Address\n /** Optional memo/message */\n memo?: string\n /** Timestamp when note was created */\n timestamp?: number\n}\n\n/**\n * Encrypted note data stored on-chain (post-quantum, hash-based)\n */\nexport interface EncryptedNote {\n /** AES-GCM encrypted note data */\n ciphertext: Hex\n /** AES-GCM nonce */\n nonce: Hex\n}\n\n/**\n * Stealth meta-address (hash-based, post-quantum)\n * Published once, used by senders to encrypt notes to the recipient\n */\nexport interface StealthMetaAddress {\n /** Owner hash = Poseidon(spendingSecret) */\n ownerHash: bigint\n /** Viewing hash = Poseidon(viewingSecret) */\n viewingHash: bigint\n}\n\n/**\n * One-time address for a specific transaction (simplified for hash-based system)\n */\nexport interface StealthAddress {\n /** Owner hash for this note */\n ownerHash: bigint\n /** Search tag for efficient scanning */\n searchTag?: bigint\n}\n\n/**\n * On-chain merge record for audit trail\n */\nexport interface MergeRecord {\n /** Output commitment (the merged note) */\n outputCommitment: Hex\n /** First input nullifier */\n nullifier1: Hex\n /** Second input nullifier */\n nullifier2: Hex\n /** Who performed the merge (new origin) */\n merger: Address\n /** Token that was merged */\n token: Address\n /** Block timestamp */\n timestamp: number\n}\n\n/**\n * ASP (Association Set Provider) root\n */\nexport interface ASPRoot {\n /** Merkle root of approved addresses */\n root: bigint\n /** IPFS hash for off-chain data */\n ipfsHash: Hex\n /** When this root was published */\n timestamp: number\n /** Number of addresses in the set */\n leafCount: number\n}\n\n/**\n * Shield operation parameters\n */\nexport interface ShieldParams {\n /** ERC20 token to shield */\n token: Address\n /** Amount to shield (in wei) */\n amount: bigint\n /** Optional: recipient owner hash (defaults to self) */\n recipientOwnerHash?: bigint\n /** Optional: memo to include in note */\n memo?: string\n}\n\n/**\n * Transfer operation parameters\n */\nexport interface TransferParams {\n /** Note to spend */\n note: Note\n /** Recipient stealth address */\n recipient: StealthAddress\n /** Amount to send (remainder goes back to sender as change) */\n amount: bigint\n /** Optional: memo to include */\n memo?: string\n}\n\n/**\n * Merge operation parameters\n */\nexport interface MergeParams {\n /** Notes to merge (must be same token) */\n notes: [Note, Note]\n /** Optional: memo for the merged note */\n memo?: string\n}\n\n/**\n * Withdraw operation parameters\n */\nexport interface WithdrawParams {\n /** Note to withdraw */\n note: Note\n /** Amount to withdraw */\n amount: bigint\n /** Recipient address for the tokens */\n recipient: Address\n /** ASP ID to use for compliance check */\n aspId?: number\n /** Use ragequit (origin withdrawing own funds) */\n ragequit?: boolean\n}\n\n/**\n * Proof for ZK operations\n */\nexport interface Proof {\n /** Proof data (format depends on proof system: Groth16 has pi_a/pi_b/pi_c, PLONK has A/B/C/Z/T1-T3/evals/Wxi/Wxiw) */\n proof: Record<string, any>\n /** Public signals */\n publicSignals: string[]\n}\n\n/**\n * Note commitment (hash)\n */\nexport type Commitment = Hex\n\n/**\n * Nullifier (spent note identifier)\n */\nexport type Nullifier = Hex\n\n// =========================================================================\n// STARK Note Types (M31/Keccak-based, post-quantum)\n// =========================================================================\n\nimport type { M31Digest } from '../utils/keccak-m31.js'\n\n// STARK_AMOUNT_SCALE moved to utils/stark.ts\nexport { STARK_AMOUNT_SCALE } from '../utils/stark.js'\n\n/**\n * A private STARK note in the Universal Private Pool.\n *\n * All field values are M31 elements (< 2^31 - 1).\n * Commitment = keccak_m31(amount, ownerHash[0..4], blinding, origin, token).\n */\nexport interface StarkNote {\n /** Amount in STARK units (actual wei = amount * STARK_AMOUNT_SCALE) */\n amount: bigint\n /** Owner hash = keccak_m31(starkSecret) — 4 M31 elements */\n ownerHash: M31Digest\n /** Random blinding factor (M31) */\n blinding: bigint\n /** Origin address encoded as M31 (lower 31 bits of address) */\n origin: bigint\n /** Token address encoded as M31 (lower 31 bits of address) */\n token: bigint\n /** The leaf index in the STARK Keccak Merkle tree (set after shielding) */\n leafIndex?: number\n /** The commitment digest (set after computation) */\n commitment?: M31Digest\n /** Optional memo */\n memo?: string\n /** Timestamp when note was created */\n timestamp?: number\n}\n\n/**\n * STARK stealth meta-address (M31/Keccak-based)\n * Published once, used by senders to encrypt notes to the recipient\n */\nexport interface StarkStealthMetaAddress {\n /** Owner hash = keccak_m31(starkSecret) — 4 M31 elements */\n ownerHash: M31Digest\n /** Viewing hash = keccak_m31(starkViewingSecret) — 4 M31 elements */\n viewingHash: M31Digest\n}\n\n/**\n * STARK proof for ZK operations (serialized Circle STARK proof)\n */\nexport interface StarkProof {\n /** Raw serialized Stwo Circle STARK proof bytes */\n proofBytes: Hex\n /** Public inputs seed (keccak256 of public parameters) */\n publicInputsSeed: Hex\n}\n","/**\n * Note management utilities\n *\n * Create, encrypt, and decrypt private notes.\n */\n\nimport type { Address, Hex } from 'viem'\nimport type { Note, EncryptedNote } from './types.js'\nimport { NOTE_VERSION } from './types.js'\n\n/**\n * Parameters for creating a new note\n */\nexport interface CreateNoteParams {\n /** Token amount */\n amount: bigint\n /** ERC20 token address */\n token: Address\n /** Origin address (who is responsible) */\n origin: Address\n /** Sender address */\n sender: Address\n /** Optional memo */\n memo?: string\n /** Optional blinding factor (generated if not provided) */\n blinding?: bigint\n}\n\n/**\n * Create a new private note\n *\n * @example\n * ```ts\n * const note = createNote({\n * amount: 1000n * 10n ** 18n,\n * token: '0x...',\n * origin: '0xMyAddress...',\n * sender: '0xMyAddress...',\n * memo: 'Payment for services',\n * })\n * ```\n */\nexport function createNote(params: CreateNoteParams): Note {\n const { amount, token, origin, sender, memo, blinding } = params\n\n // Generate random blinding factor if not provided\n const noteBlinding = blinding ?? generateRandomBlinding()\n\n return {\n version: NOTE_VERSION,\n amount,\n blinding: noteBlinding,\n origin,\n sender,\n token,\n memo,\n timestamp: Math.floor(Date.now() / 1000),\n }\n}\n\n/**\n * Encrypt a note for a recipient\n *\n * @param note - The note to encrypt\n * @param sharedSecret - ECDH shared secret with recipient\n * @returns Encrypted note data\n */\nexport function encryptNote(_note: Note, _sharedSecret: Uint8Array): EncryptedNote {\n // TODO: Implement AES-GCM encryption\n throw new Error('Not implemented')\n}\n\n/**\n * Decrypt a received note\n *\n * @param encrypted - The encrypted note data\n * @param sharedSecret - ECDH shared secret\n * @returns Decrypted note or null if decryption fails\n */\nexport function decryptNote(_encrypted: EncryptedNote, _sharedSecret: Uint8Array): Note | null {\n // TODO: Implement AES-GCM decryption\n throw new Error('Not implemented')\n}\n\n/**\n * Compute the commitment hash for a note\n *\n * commitment = Poseidon(amount, blinding, origin, token)\n */\nexport function computeCommitment(_note: Note): Hex {\n // TODO: Implement Poseidon hash\n throw new Error('Not implemented')\n}\n\n/**\n * Compute the nullifier for spending a note\n *\n * nullifier = Poseidon(blinding, leafIndex)\n */\nexport function computeNullifier(_note: Note, _leafIndex: bigint): Hex {\n // TODO: Implement nullifier computation\n throw new Error('Not implemented')\n}\n\n/**\n * Generate a random blinding factor\n */\nfunction generateRandomBlinding(): bigint {\n // TODO: Use crypto.getRandomValues for secure randomness\n const bytes = new Uint8Array(31) // 31 bytes to stay in field\n crypto.getRandomValues(bytes)\n return BigInt('0x' + Array.from(bytes).map(b => b.toString(16).padStart(2, '0')).join(''))\n}\n","/**\n * Core UPP SDK functionality\n */\n\nexport { createUPPClient } from './client.js'\nexport type { UPPClient, UPPClientConfig } from './client.js'\n\nexport { createNote, encryptNote, decryptNote } from './note.js'\n\n// Stealth address utilities (post-quantum, hash-based)\nexport {\n STEALTH_ADDRESS_PREFIX,\n ADDRESS_VERSION,\n encodeStealthAddress,\n decodeStealthAddress,\n isValidStealthAddress,\n generateStealthAddress,\n createOneTimeKeys,\n verifyOwnership,\n computeNoteEncryptionKey,\n // STARK stealth addresses (0zs prefix)\n STARK_STEALTH_ADDRESS_PREFIX,\n STARK_ADDRESS_VERSION,\n encodeStarkStealthAddress,\n decodeStarkStealthAddress,\n isValidStarkStealthAddress,\n generateStarkStealthAddress,\n detectAddressType,\n} from './stealth.js'\n\n// Proof generation (UPP circuits)\nexport {\n generateUPPProof,\n formatProofForContract,\n getUPPCircuitArtifacts,\n STATE_TREE_DEPTH,\n ASP_TREE_DEPTH,\n} from './proof.js'\n\n// Proof worker (off-main-thread proving)\nexport {\n ProofWorkerManager,\n generateUPPProofAsync,\n} from './proof-worker.js'\nexport type {\n ProofWorkerRequest,\n ProofWorkerResponse,\n} from './proof-worker.js'\n\n// Circuit artifact cache (IndexedDB-based, with download progress)\nexport {\n CircuitArtifactCache,\n CIRCUIT_VERSION,\n CIRCUIT_CDN_BASE,\n} from './circuit-cache.js'\nexport type {\n DownloadProgress,\n ResolvedCircuitArtifacts,\n CircuitCacheStatus,\n} from './circuit-cache.js'\nexport type {\n UPPCircuitType,\n UPPTransferCircuitInputs,\n UPPWithdrawCircuitInputs,\n UPPCircuitInputs,\n CircuitArtifacts,\n ProofResult,\n PlonkProvingStage,\n} from './proof.js'\n\n// Legacy stealth proof exports (deprecated)\nexport {\n generateProof,\n verifyProof,\n generateStealthProof,\n getStealthCircuitArtifacts,\n} from './proof.js'\nexport type {\n CircuitType,\n StealthCircuitType,\n StealthCircuitInputs,\n Stealth1x2CircuitInputs,\n Stealth2x2CircuitInputs,\n} from './proof.js'\n\n// Deployment verification\nexport {\n checkImplementation,\n verifyDeployment,\n} from './verify.js'\nexport type {\n VerificationCheck,\n VerificationResult,\n} from './verify.js'\n\n// Types (explicit named exports to avoid tsup DTS NamespaceFixer conflicts)\n// Note: STARK_AMOUNT_SCALE is exported from utils/stark.ts (canonical location)\nexport {\n NOTE_VERSION,\n} from './types.js'\nexport type {\n NoteStatus,\n ProofSystem,\n ShieldedNote,\n Note,\n EncryptedNote,\n StealthMetaAddress,\n StealthAddress,\n MergeRecord,\n ASPRoot,\n ShieldParams,\n TransferParams,\n MergeParams,\n WithdrawParams,\n Proof,\n Commitment,\n Nullifier,\n StarkNote,\n StarkStealthMetaAddress,\n StarkProof,\n} from './types.js'\n\n// Swap order book module\nexport {\n computeGiveAmount,\n computeTakeAmount,\n computeRate,\n formatRate,\n computeCancelKeyHash,\n generateCancelSecret,\n filterOrdersByASP,\n filterOrdersByTokenPair,\n isFillerASPAccepted,\n isOrderActive,\n computeTotalBuyAmount,\n computeFillPercentage,\n storeCancelSecret,\n getCancelSecret,\n removeCancelSecret,\n getOwnOrderIds,\n RATE_PRECISION,\n SWAP_EVENTS_ABI,\n SWAP_ORDER_PLACED_EVENT,\n SWAP_ORDER_FILLED_EVENT,\n SWAP_ORDER_CLAIMED_EVENT,\n SWAP_ORDER_CANCELLED_EVENT,\n} from './swap.js'\nexport type {\n SwapOrder,\n SwapOrderParams,\n SwapFillParams,\n SwapOrderEvent,\n SwapFillEvent,\n} from './swap.js'\n\n// Account adapter (pluggable key source + persistence)\nexport { DirectAccountAdapter, StorableAccountAdapter } from './account.js'\nexport type { IAccountAdapter } from './account.js'\n\n// ASP provider (pluggable compliance)\nexport type { IASPProvider, ASPMembershipProof } from './asp-provider.js'\n\n// Note store (single source of truth for note state)\nexport { NoteStore } from './note-store.js'\nexport type { INoteStore } from './note-store.js'\n\n// New core modules — importable directly via deep paths:\n// import { createHashBasedNote } from '@permissionless-technologies/upp-sdk/core/note-crypto'\n// import { selectOptimalCircuit } from '@permissionless-technologies/upp-sdk/core/circuit-selector'\n// etc.\n// Not re-exported from the barrel to avoid tsup DTS NamespaceFixer limits.\n\n// ASP (Association Set Provider) module\nexport {\n computeSingleOriginASPRoot,\n generateSingleOriginASPProof,\n verifyASPProof,\n DEMO_ASP_ID,\n DEMO_ASP_NAME,\n createDemoASPRoot,\n // Multi-origin ASP tree\n buildASPTree,\n computeMultiOriginASPRoot,\n generateMultiOriginASPProof,\n generateASPProof,\n} from './asp.js'\nexport type { ASPProof } from './asp.js'\n\n// Transfer module\nexport {\n syncMerkleTree,\n getMerkleProofsForNotes,\n computeNullifier,\n buildUPPTransferCircuitInputs,\n buildTransfer,\n formatOutputForContract,\n} from './transfer.js'\nexport type {\n TransferStage,\n SpendableNote,\n MerkleProofWithNote,\n TransferContext,\n TransferBuildResult,\n NoteWithAmount,\n} from './transfer.js'\n","/**\n * UPP Deployment Verification — Check on-chain state matches deployment config.\n *\n * Verifies:\n * 1. Bytecode exists at proxy and implementation addresses\n * 2. UUPS proxy implementation slots point to expected implementations\n *\n * Use `verifyDeployment()` for comprehensive checks, or `checkImplementation()`\n * for a lightweight proxy-vs-expected check suitable for UI warnings.\n */\n\nimport type { Address, PublicClient } from 'viem'\nimport type { DeploymentConfig } from '../deployments/index.js'\n\n/** ERC-1967 implementation storage slot: keccak256(\"eip1967.proxy.implementation\") - 1 */\nconst ERC1967_IMPL_SLOT =\n '0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc' as const\n\nexport interface VerificationCheck {\n name: string\n passed: boolean\n expected?: string\n actual?: string\n}\n\nexport interface VerificationResult {\n chainId: number\n checks: VerificationCheck[]\n passed: number\n failed: number\n allPassed: boolean\n}\n\n/**\n * Lightweight check: does the on-chain proxy point to the expected implementation?\n *\n * Returns `true` if the implementation matches, `false` if it doesn't or can't be read.\n * Use this in UI code to warn users about outdated deployments.\n *\n * @example\n * ```ts\n * import { checkImplementation, getDeploymentOrThrow } from '@permissionless-technologies/upp-sdk'\n *\n * const deployment = getDeploymentOrThrow(11155111)\n * const ok = await checkImplementation(publicClient, deployment, 'UniversalPrivatePool')\n * if (!ok) {\n * console.warn('Pool implementation has been upgraded — SDK may be outdated')\n * }\n * ```\n */\nexport async function checkImplementation(\n publicClient: PublicClient,\n deployment: DeploymentConfig,\n contract: 'UniversalPrivatePool' | 'ASPRegistryHub',\n): Promise<boolean> {\n const proxyAddress = deployment[contract]\n const expectedImpl = deployment.implementations?.[contract]\n\n if (!proxyAddress || !expectedImpl) return false\n\n try {\n const implSlot = await publicClient.getStorageAt({\n address: proxyAddress,\n slot: ERC1967_IMPL_SLOT,\n })\n const actualImpl = ('0x' + (implSlot ?? '0x').slice(26)).toLowerCase()\n return actualImpl === expectedImpl.toLowerCase()\n } catch {\n return false\n }\n}\n\n/**\n * Full deployment verification — checks bytecode existence and proxy implementations.\n *\n * @example\n * ```ts\n * const result = await verifyDeployment(publicClient, deployment)\n * if (!result.allPassed) {\n * for (const check of result.checks.filter(c => !c.passed)) {\n * console.error(`FAIL: ${check.name}`, check.expected, check.actual)\n * }\n * }\n * ```\n */\nexport async function verifyDeployment(\n publicClient: PublicClient,\n deployment: DeploymentConfig,\n): Promise<VerificationResult> {\n const checks: VerificationCheck[] = []\n\n // 1. Bytecode existence — proxy addresses\n await _verifyBytecode(publicClient, checks, 'UniversalPrivatePool (proxy)', deployment.UniversalPrivatePool)\n await _verifyBytecode(publicClient, checks, 'ASPRegistryHub (proxy)', deployment.ASPRegistryHub)\n\n // 1b. Bytecode existence — implementation addresses (if known)\n if (deployment.implementations?.UniversalPrivatePool) {\n await _verifyBytecode(publicClient, checks, 'UniversalPrivatePool (impl)', deployment.implementations.UniversalPrivatePool)\n }\n if (deployment.implementations?.ASPRegistryHub) {\n await _verifyBytecode(publicClient, checks, 'ASPRegistryHub (impl)', deployment.implementations.ASPRegistryHub)\n }\n\n // 2. Proxy implementation slots (ERC-1967)\n if (deployment.implementations?.UniversalPrivatePool) {\n await _verifyProxyImpl(\n publicClient, checks,\n 'UniversalPrivatePool',\n deployment.UniversalPrivatePool,\n deployment.implementations.UniversalPrivatePool,\n )\n }\n if (deployment.implementations?.ASPRegistryHub) {\n await _verifyProxyImpl(\n publicClient, checks,\n 'ASPRegistryHub',\n deployment.ASPRegistryHub,\n deployment.implementations.ASPRegistryHub,\n )\n }\n\n // 3. Bytecode existence — verifiers\n for (const [name, addr] of Object.entries(deployment.verifiers)) {\n if (addr) {\n await _verifyBytecode(publicClient, checks, `Verifier: ${name}`, addr as Address)\n }\n }\n\n const passed = checks.filter((c) => c.passed).length\n const failed = checks.filter((c) => !c.passed).length\n\n return {\n chainId: deployment.chainId,\n checks,\n passed,\n failed,\n allPassed: failed === 0,\n }\n}\n\n// ─── Internal helpers ─────────────────────────────────────────────\n\nasync function _verifyBytecode(\n client: PublicClient,\n checks: VerificationCheck[],\n name: string,\n address: Address,\n): Promise<void> {\n try {\n const code = await client.getCode({ address })\n const exists = code !== undefined && code !== '0x' && code.length > 2\n checks.push({ name: `${name} bytecode exists`, passed: exists })\n } catch {\n checks.push({ name: `${name} bytecode exists`, passed: false })\n }\n}\n\nasync function _verifyProxyImpl(\n client: PublicClient,\n checks: VerificationCheck[],\n name: string,\n proxyAddress: Address,\n expectedImpl: Address,\n): Promise<void> {\n try {\n const implSlot = await client.getStorageAt({\n address: proxyAddress,\n slot: ERC1967_IMPL_SLOT,\n })\n const actualImpl = ('0x' + (implSlot ?? '0x').slice(26)).toLowerCase() as Address\n const expected = expectedImpl.toLowerCase()\n checks.push({\n name: `${name} proxy -> impl`,\n passed: actualImpl === expected,\n expected: expectedImpl,\n actual: actualImpl as string,\n })\n } catch {\n checks.push({ name: `${name} proxy -> impl`, passed: false, expected: expectedImpl })\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/core/client.ts","../src/core/types.ts","../src/core/note.ts","../src/core/index.ts","../src/core/verify.ts"],"names":["init_stealth"],"mappings":";;;;;AAoFO,SAAS,gBAAgB,OAAA,EAAqC;AAEnE,EAAA,MAAM,IAAI,MAAM,iBAAiB,CAAA;AACnC;;;AC9EO,IAAM,YAAA,GAAe;;;ACiCrB,SAAS,WAAW,MAAA,EAAgC;AACzD,EAAA,MAAM,EAAE,MAAA,EAAQ,KAAA,EAAO,QAAQ,MAAA,EAAQ,IAAA,EAAM,UAAS,GAAI,MAAA;AAG1D,EAAA,MAAM,YAAA,GAAe,YAAY,sBAAA,EAAuB;AAExD,EAAA,OAAO;AAAA,IACL,OAAA,EAAS,YAAA;AAAA,IACT,MAAA;AAAA,IACA,QAAA,EAAU,YAAA;AAAA,IACV,MAAA;AAAA,IACA,MAAA;AAAA,IACA,KAAA;AAAA,IACA,IAAA;AAAA,IACA,WAAW,IAAA,CAAK,KAAA,CAAM,IAAA,CAAK,GAAA,KAAQ,GAAI;AAAA,GACzC;AACF;AASO,SAAS,WAAA,CAAY,OAAa,aAAA,EAA0C;AAEjF,EAAA,MAAM,IAAI,MAAM,iBAAiB,CAAA;AACnC;AASO,SAAS,WAAA,CAAY,YAA2B,aAAA,EAAwC;AAE7F,EAAA,MAAM,IAAI,MAAM,iBAAiB,CAAA;AACnC;AAyBA,SAAS,sBAAA,GAAiC;AAExC,EAAA,MAAM,KAAA,GAAQ,IAAI,UAAA,CAAW,EAAE,CAAA;AAC/B,EAAA,MAAA,CAAO,gBAAgB,KAAK,CAAA;AAC5B,EAAA,OAAO,OAAO,IAAA,GAAO,KAAA,CAAM,KAAK,KAAK,CAAA,CAAE,IAAI,CAAA,CAAA,KAAK,CAAA,CAAE,SAAS,EAAE,CAAA,CAAE,SAAS,CAAA,EAAG,GAAG,CAAC,CAAA,CAAE,IAAA,CAAK,EAAE,CAAC,CAAA;AAC3F;;;ACtGAA,8BAAA,EAAA;;;ACKA,IAAM,iBAAA,GACJ,oEAAA;AAkCF,eAAsB,mBAAA,CACpB,YAAA,EACA,UAAA,EACA,QAAA,EACkB;AAClB,EAAA,MAAM,YAAA,GAAe,WAAW,QAAQ,CAAA;AACxC,EAAA,MAAM,YAAA,GAAe,UAAA,CAAW,eAAA,GAAkB,QAAQ,CAAA;AAE1D,EAAA,IAAI,CAAC,YAAA,IAAgB,CAAC,YAAA,EAAc,OAAO,KAAA;AAE3C,EAAA,IAAI;AACF,IAAA,MAAM,QAAA,GAAW,MAAM,YAAA,CAAa,YAAA,CAAa;AAAA,MAC/C,OAAA,EAAS,YAAA;AAAA,MACT,IAAA,EAAM;AAAA,KACP,CAAA;AACD,IAAA,MAAM,cAAc,IAAA,GAAA,CAAQ,QAAA,IAAY,MAAM,KAAA,CAAM,EAAE,GAAG,WAAA,EAAY;AACrE,IAAA,OAAO,UAAA,KAAe,aAAa,WAAA,EAAY;AAAA,EACjD,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,KAAA;AAAA,EACT;AACF;AAeA,eAAsB,gBAAA,CACpB,cACA,UAAA,EAC6B;AAC7B,EAAA,MAAM,SAA8B,EAAC;AAGrC,EAAA,MAAM,eAAA,CAAgB,YAAA,EAAc,MAAA,EAAQ,8BAAA,EAAgC,WAAW,oBAAoB,CAAA;AAC3G,EAAA,MAAM,eAAA,CAAgB,YAAA,EAAc,MAAA,EAAQ,wBAAA,EAA0B,WAAW,cAAc,CAAA;AAG/F,EAAA,IAAI,UAAA,CAAW,iBAAiB,oBAAA,EAAsB;AACpD,IAAA,MAAM,gBAAgB,YAAA,EAAc,MAAA,EAAQ,6BAAA,EAA+B,UAAA,CAAW,gBAAgB,oBAAoB,CAAA;AAAA,EAC5H;AACA,EAAA,IAAI,UAAA,CAAW,iBAAiB,cAAA,EAAgB;AAC9C,IAAA,MAAM,gBAAgB,YAAA,EAAc,MAAA,EAAQ,uBAAA,EAAyB,UAAA,CAAW,gBAAgB,cAAc,CAAA;AAAA,EAChH;AAGA,EAAA,IAAI,UAAA,CAAW,iBAAiB,oBAAA,EAAsB;AACpD,IAAA,MAAM,gBAAA;AAAA,MACJ,YAAA;AAAA,MAAc,MAAA;AAAA,MACd,sBAAA;AAAA,MACA,UAAA,CAAW,oBAAA;AAAA,MACX,WAAW,eAAA,CAAgB;AAAA,KAC7B;AAAA,EACF;AACA,EAAA,IAAI,UAAA,CAAW,iBAAiB,cAAA,EAAgB;AAC9C,IAAA,MAAM,gBAAA;AAAA,MACJ,YAAA;AAAA,MAAc,MAAA;AAAA,MACd,gBAAA;AAAA,MACA,UAAA,CAAW,cAAA;AAAA,MACX,WAAW,eAAA,CAAgB;AAAA,KAC7B;AAAA,EACF;AAGA,EAAA,KAAA,MAAW,CAAC,MAAM,IAAI,CAAA,IAAK,OAAO,OAAA,CAAQ,UAAA,CAAW,SAAS,CAAA,EAAG;AAC/D,IAAA,IAAI,IAAA,EAAM;AACR,MAAA,MAAM,gBAAgB,YAAA,EAAc,MAAA,EAAQ,CAAA,UAAA,EAAa,IAAI,IAAI,IAAe,CAAA;AAAA,IAClF;AAAA,EACF;AAEA,EAAA,MAAM,SAAS,MAAA,CAAO,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,CAAE,MAAM,CAAA,CAAE,MAAA;AAC9C,EAAA,MAAM,MAAA,GAAS,OAAO,MAAA,CAAO,CAAC,MAAM,CAAC,CAAA,CAAE,MAAM,CAAA,CAAE,MAAA;AAE/C,EAAA,OAAO;AAAA,IACL,SAAS,UAAA,CAAW,OAAA;AAAA,IACpB,MAAA;AAAA,IACA,MAAA;AAAA,IACA,MAAA;AAAA,IACA,WAAW,MAAA,KAAW;AAAA,GACxB;AACF;AAIA,eAAe,eAAA,CACb,MAAA,EACA,MAAA,EACA,IAAA,EACA,OAAA,EACe;AACf,EAAA,IAAI;AACF,IAAA,MAAM,OAAO,MAAM,MAAA,CAAO,OAAA,CAAQ,EAAE,SAAS,CAAA;AAC7C,IAAA,MAAM,SAAS,IAAA,KAAS,KAAA,CAAA,IAAa,IAAA,KAAS,IAAA,IAAQ,KAAK,MAAA,GAAS,CAAA;AACpE,IAAA,MAAA,CAAO,IAAA,CAAK,EAAE,IAAA,EAAM,CAAA,EAAG,IAAI,CAAA,gBAAA,CAAA,EAAoB,MAAA,EAAQ,QAAQ,CAAA;AAAA,EACjE,CAAA,CAAA,MAAQ;AACN,IAAA,MAAA,CAAO,IAAA,CAAK,EAAE,IAAA,EAAM,CAAA,EAAG,IAAI,CAAA,gBAAA,CAAA,EAAoB,MAAA,EAAQ,OAAO,CAAA;AAAA,EAChE;AACF;AAEA,eAAe,gBAAA,CACb,MAAA,EACA,MAAA,EACA,IAAA,EACA,cACA,YAAA,EACe;AACf,EAAA,IAAI;AACF,IAAA,MAAM,QAAA,GAAW,MAAM,MAAA,CAAO,YAAA,CAAa;AAAA,MACzC,OAAA,EAAS,YAAA;AAAA,MACT,IAAA,EAAM;AAAA,KACP,CAAA;AACD,IAAA,MAAM,cAAc,IAAA,GAAA,CAAQ,QAAA,IAAY,MAAM,KAAA,CAAM,EAAE,GAAG,WAAA,EAAY;AACrE,IAAA,MAAM,QAAA,GAAW,aAAa,WAAA,EAAY;AAC1C,IAAA,MAAA,CAAO,IAAA,CAAK;AAAA,MACV,IAAA,EAAM,GAAG,IAAI,CAAA,cAAA,CAAA;AAAA,MACb,QAAQ,UAAA,KAAe,QAAA;AAAA,MACvB,QAAA,EAAU,YAAA;AAAA,MACV,MAAA,EAAQ;AAAA,KACT,CAAA;AAAA,EACH,CAAA,CAAA,MAAQ;AACN,IAAA,MAAA,CAAO,IAAA,CAAK,EAAE,IAAA,EAAM,CAAA,EAAG,IAAI,kBAAkB,MAAA,EAAQ,KAAA,EAAO,QAAA,EAAU,YAAA,EAAc,CAAA;AAAA,EACtF;AACF","file":"chunk-MZDCTYGM.cjs","sourcesContent":["/**\n * Main UPP Client\n *\n * Provides high-level API for interacting with the Universal Private Pool.\n */\n\nimport type { Address, PublicClient, WalletClient } from 'viem'\nimport type {\n ShieldParams,\n TransferParams,\n MergeParams,\n WithdrawParams,\n Note,\n} from './types.js'\n\n/**\n * UPP Client configuration\n */\nexport interface UPPClientConfig {\n /** Viem public client for reading chain state */\n publicClient: PublicClient\n /** Viem wallet client for sending transactions */\n walletClient: WalletClient\n /** Universal Private Pool contract address */\n poolAddress: Address\n /** ASP Registry Hub contract address */\n aspHubAddress: Address\n /** Chain ID (optional, derived from clients if not provided) */\n chainId?: number\n}\n\n/**\n * UPP Client interface\n */\nexport interface UPPClient {\n /** Shield tokens into the private pool */\n shield(params: ShieldParams): Promise<{ commitment: `0x${string}`; note: Note }>\n\n /** Transfer tokens privately */\n transfer(params: TransferParams): Promise<{ nullifier: `0x${string}`; changeNote?: Note }>\n\n /** Merge multiple notes into one */\n merge(params: MergeParams): Promise<{ commitment: `0x${string}`; note: Note }>\n\n /** Withdraw tokens from the private pool */\n withdraw(params: WithdrawParams): Promise<{ txHash: `0x${string}` }>\n\n /** Scan for notes belonging to a viewing key */\n scanNotes(viewingKey: `0x${string}`): Promise<Note[]>\n\n /** Get the current state root */\n getStateRoot(): Promise<bigint>\n\n /** Check if a nullifier has been spent */\n isNullifierSpent(nullifier: `0x${string}`): Promise<boolean>\n}\n\n/**\n * Create a UPP client instance\n *\n * @example\n * ```ts\n * import { createUPPClient } from '@upp/sdk'\n * import { createPublicClient, createWalletClient, http } from 'viem'\n * import { sepolia } from 'viem/chains'\n *\n * const publicClient = createPublicClient({\n * chain: sepolia,\n * transport: http(),\n * })\n *\n * const walletClient = createWalletClient({\n * chain: sepolia,\n * transport: http(),\n * })\n *\n * const client = createUPPClient({\n * publicClient,\n * walletClient,\n * poolAddress: '0x...',\n * aspHubAddress: '0x...',\n * })\n * ```\n */\nexport function createUPPClient(_config: UPPClientConfig): UPPClient {\n // TODO: Implement client\n throw new Error('Not implemented')\n}\n","/**\n * Core type definitions for UPP SDK\n */\n\nimport type { Address, Hex } from 'viem'\n\n/**\n * Note version - increment when note structure changes\n */\nexport const NOTE_VERSION = 5\n\n// =========================================================================\n// Shielded Note Types (stored in NoteStore, used across React hooks)\n// =========================================================================\n\n/** Note lifecycle status */\nexport type NoteStatus = 'pending' | 'confirmed' | 'spent'\n\n/** Which proof system created/guards a note */\nexport type ProofSystem = 'snark' | 'stark'\n\n/**\n * A shielded note (UTXO) - Post-quantum hash-based\n *\n * Commitment = Poseidon(amount, ownerHash, blinding, origin, token)\n * where ownerHash = Poseidon(spendingSecret)\n */\nexport interface ShieldedNote {\n /** Amount of tokens */\n amount: bigint\n /** Random blinding factor */\n blinding: bigint\n /** Commitment hash (hex) */\n commitment: string\n /** Spending secret for this note (hex) - proves ownership via hash preimage */\n ownerSecret: string\n /** Owner hash = Poseidon(ownerSecret) - what's committed on-chain (hex) */\n ownerHash: string\n /** Position in Merkle tree */\n leafIndex: number\n /** Origin address (original depositor) as hex */\n origin: string\n /** Token address as hex */\n token: string\n /** Transaction hash */\n txHash?: string\n /** Note status */\n status: NoteStatus\n /** Timestamp */\n timestamp: number\n /** Which proof system created this note (defaults to 'snark' for legacy notes) */\n proofSystem?: ProofSystem\n /** Block number where note was created (from IndexedNote) */\n blockNumber?: number\n /** Ephemeral public key X (R.x — used as viewing key nonce, for ECDH-based notes) */\n ephemeralX?: string\n /** Ephemeral public key Y (R.y, for ECDH-based notes) */\n ephemeralY?: string\n}\n\n/**\n * A private note in the Universal Private Pool\n */\nexport interface Note {\n /** Note format version */\n version: number\n /** Token amount (in wei) */\n amount: bigint\n /** Random blinding factor */\n blinding: bigint\n /** Current origin - who is responsible for these funds (updated on merge) */\n origin: Address\n /** Sender - who sent this specific note (for payment attribution) */\n sender: Address\n /** ERC20 token address */\n token: Address\n /** Optional memo/message */\n memo?: string\n /** Timestamp when note was created */\n timestamp?: number\n}\n\n/**\n * Encrypted note data stored on-chain (post-quantum, hash-based)\n */\nexport interface EncryptedNote {\n /** AES-GCM encrypted note data */\n ciphertext: Hex\n /** AES-GCM nonce */\n nonce: Hex\n}\n\n/**\n * Stealth meta-address (hash-based, post-quantum)\n * Published once, used by senders to encrypt notes to the recipient\n */\nexport interface StealthMetaAddress {\n /** Owner hash = Poseidon(spendingSecret) */\n ownerHash: bigint\n /** Viewing hash = Poseidon(viewingSecret) */\n viewingHash: bigint\n}\n\n/**\n * One-time address for a specific transaction (simplified for hash-based system)\n */\nexport interface StealthAddress {\n /** Owner hash for this note */\n ownerHash: bigint\n /** Search tag for efficient scanning */\n searchTag?: bigint\n}\n\n/**\n * On-chain merge record for audit trail\n */\nexport interface MergeRecord {\n /** Output commitment (the merged note) */\n outputCommitment: Hex\n /** First input nullifier */\n nullifier1: Hex\n /** Second input nullifier */\n nullifier2: Hex\n /** Who performed the merge (new origin) */\n merger: Address\n /** Token that was merged */\n token: Address\n /** Block timestamp */\n timestamp: number\n}\n\n/**\n * ASP (Association Set Provider) root\n */\nexport interface ASPRoot {\n /** Merkle root of approved addresses */\n root: bigint\n /** IPFS hash for off-chain data */\n ipfsHash: Hex\n /** When this root was published */\n timestamp: number\n /** Number of addresses in the set */\n leafCount: number\n}\n\n/**\n * Shield operation parameters\n */\nexport interface ShieldParams {\n /** ERC20 token to shield */\n token: Address\n /** Amount to shield (in wei) */\n amount: bigint\n /** Optional: recipient owner hash (defaults to self) */\n recipientOwnerHash?: bigint\n /** Optional: memo to include in note */\n memo?: string\n}\n\n/**\n * Transfer operation parameters\n */\nexport interface TransferParams {\n /** Note to spend */\n note: Note\n /** Recipient stealth address */\n recipient: StealthAddress\n /** Amount to send (remainder goes back to sender as change) */\n amount: bigint\n /** Optional: memo to include */\n memo?: string\n}\n\n/**\n * Merge operation parameters\n */\nexport interface MergeParams {\n /** Notes to merge (must be same token) */\n notes: [Note, Note]\n /** Optional: memo for the merged note */\n memo?: string\n}\n\n/**\n * Withdraw operation parameters\n */\nexport interface WithdrawParams {\n /** Note to withdraw */\n note: Note\n /** Amount to withdraw */\n amount: bigint\n /** Recipient address for the tokens */\n recipient: Address\n /** ASP ID to use for compliance check */\n aspId?: number\n /** Use ragequit (origin withdrawing own funds) */\n ragequit?: boolean\n}\n\n/**\n * Proof for ZK operations\n */\nexport interface Proof {\n /** Proof data (format depends on proof system: Groth16 has pi_a/pi_b/pi_c, PLONK has A/B/C/Z/T1-T3/evals/Wxi/Wxiw) */\n proof: Record<string, any>\n /** Public signals */\n publicSignals: string[]\n}\n\n/**\n * Note commitment (hash)\n */\nexport type Commitment = Hex\n\n/**\n * Nullifier (spent note identifier)\n */\nexport type Nullifier = Hex\n\n// =========================================================================\n// STARK Note Types (M31/Keccak-based, post-quantum)\n// =========================================================================\n\nimport type { M31Digest } from '../utils/keccak-m31.js'\n\n// STARK_AMOUNT_SCALE moved to utils/stark.ts\nexport { STARK_AMOUNT_SCALE } from '../utils/stark.js'\n\n/**\n * A private STARK note in the Universal Private Pool.\n *\n * All field values are M31 elements (< 2^31 - 1).\n * Commitment = keccak_m31(amount, ownerHash[0..4], blinding, origin, token).\n */\nexport interface StarkNote {\n /** Amount in STARK units (actual wei = amount * STARK_AMOUNT_SCALE) */\n amount: bigint\n /** Owner hash = keccak_m31(starkSecret) — 4 M31 elements */\n ownerHash: M31Digest\n /** Random blinding factor (M31) */\n blinding: bigint\n /** Origin address encoded as M31 (lower 31 bits of address) */\n origin: bigint\n /** Token address encoded as M31 (lower 31 bits of address) */\n token: bigint\n /** The leaf index in the STARK Keccak Merkle tree (set after shielding) */\n leafIndex?: number\n /** The commitment digest (set after computation) */\n commitment?: M31Digest\n /** Optional memo */\n memo?: string\n /** Timestamp when note was created */\n timestamp?: number\n}\n\n/**\n * STARK stealth meta-address (M31/Keccak-based)\n * Published once, used by senders to encrypt notes to the recipient\n */\nexport interface StarkStealthMetaAddress {\n /** Owner hash = keccak_m31(starkSecret) — 4 M31 elements */\n ownerHash: M31Digest\n /** Viewing hash = keccak_m31(starkViewingSecret) — 4 M31 elements */\n viewingHash: M31Digest\n}\n\n/**\n * STARK proof for ZK operations (serialized Circle STARK proof)\n */\nexport interface StarkProof {\n /** Raw serialized Stwo Circle STARK proof bytes */\n proofBytes: Hex\n /** Public inputs seed (keccak256 of public parameters) */\n publicInputsSeed: Hex\n}\n","/**\n * Note management utilities\n *\n * Create, encrypt, and decrypt private notes.\n */\n\nimport type { Address, Hex } from 'viem'\nimport type { Note, EncryptedNote } from './types.js'\nimport { NOTE_VERSION } from './types.js'\n\n/**\n * Parameters for creating a new note\n */\nexport interface CreateNoteParams {\n /** Token amount */\n amount: bigint\n /** ERC20 token address */\n token: Address\n /** Origin address (who is responsible) */\n origin: Address\n /** Sender address */\n sender: Address\n /** Optional memo */\n memo?: string\n /** Optional blinding factor (generated if not provided) */\n blinding?: bigint\n}\n\n/**\n * Create a new private note\n *\n * @example\n * ```ts\n * const note = createNote({\n * amount: 1000n * 10n ** 18n,\n * token: '0x...',\n * origin: '0xMyAddress...',\n * sender: '0xMyAddress...',\n * memo: 'Payment for services',\n * })\n * ```\n */\nexport function createNote(params: CreateNoteParams): Note {\n const { amount, token, origin, sender, memo, blinding } = params\n\n // Generate random blinding factor if not provided\n const noteBlinding = blinding ?? generateRandomBlinding()\n\n return {\n version: NOTE_VERSION,\n amount,\n blinding: noteBlinding,\n origin,\n sender,\n token,\n memo,\n timestamp: Math.floor(Date.now() / 1000),\n }\n}\n\n/**\n * Encrypt a note for a recipient\n *\n * @param note - The note to encrypt\n * @param sharedSecret - ECDH shared secret with recipient\n * @returns Encrypted note data\n */\nexport function encryptNote(_note: Note, _sharedSecret: Uint8Array): EncryptedNote {\n // TODO: Implement AES-GCM encryption\n throw new Error('Not implemented')\n}\n\n/**\n * Decrypt a received note\n *\n * @param encrypted - The encrypted note data\n * @param sharedSecret - ECDH shared secret\n * @returns Decrypted note or null if decryption fails\n */\nexport function decryptNote(_encrypted: EncryptedNote, _sharedSecret: Uint8Array): Note | null {\n // TODO: Implement AES-GCM decryption\n throw new Error('Not implemented')\n}\n\n/**\n * Compute the commitment hash for a note\n *\n * commitment = Poseidon(amount, blinding, origin, token)\n */\nexport function computeCommitment(_note: Note): Hex {\n // TODO: Implement Poseidon hash\n throw new Error('Not implemented')\n}\n\n/**\n * Compute the nullifier for spending a note\n *\n * nullifier = Poseidon(blinding, leafIndex)\n */\nexport function computeNullifier(_note: Note, _leafIndex: bigint): Hex {\n // TODO: Implement nullifier computation\n throw new Error('Not implemented')\n}\n\n/**\n * Generate a random blinding factor\n */\nfunction generateRandomBlinding(): bigint {\n // TODO: Use crypto.getRandomValues for secure randomness\n const bytes = new Uint8Array(31) // 31 bytes to stay in field\n crypto.getRandomValues(bytes)\n return BigInt('0x' + Array.from(bytes).map(b => b.toString(16).padStart(2, '0')).join(''))\n}\n","/**\n * Core UPP SDK functionality\n */\n\nexport { createUPPClient } from './client.js'\nexport type { UPPClient, UPPClientConfig } from './client.js'\n\nexport { createNote, encryptNote, decryptNote } from './note.js'\n\n// Stealth address utilities (post-quantum, hash-based)\nexport {\n STEALTH_ADDRESS_PREFIX,\n ADDRESS_VERSION,\n encodeStealthAddress,\n decodeStealthAddress,\n isValidStealthAddress,\n generateStealthAddress,\n createOneTimeKeys,\n verifyOwnership,\n computeNoteEncryptionKey,\n // STARK stealth addresses (0zs prefix)\n STARK_STEALTH_ADDRESS_PREFIX,\n STARK_ADDRESS_VERSION,\n encodeStarkStealthAddress,\n decodeStarkStealthAddress,\n isValidStarkStealthAddress,\n generateStarkStealthAddress,\n detectAddressType,\n} from './stealth.js'\n\n// Proof generation (UPP circuits)\nexport {\n generateUPPProof,\n formatProofForContract,\n getUPPCircuitArtifacts,\n STATE_TREE_DEPTH,\n ASP_TREE_DEPTH,\n} from './proof.js'\n\n// Proof worker (off-main-thread proving)\nexport {\n ProofWorkerManager,\n generateUPPProofAsync,\n} from './proof-worker.js'\nexport type {\n ProofWorkerRequest,\n ProofWorkerResponse,\n} from './proof-worker.js'\n\n// Circuit artifact cache (IndexedDB-based, with download progress)\nexport {\n CircuitArtifactCache,\n CIRCUIT_VERSION,\n CIRCUIT_CDN_BASE,\n} from './circuit-cache.js'\nexport type {\n DownloadProgress,\n ResolvedCircuitArtifacts,\n CircuitCacheStatus,\n} from './circuit-cache.js'\nexport type {\n UPPCircuitType,\n UPPTransferCircuitInputs,\n UPPWithdrawCircuitInputs,\n UPPCircuitInputs,\n CircuitArtifacts,\n ProofResult,\n PlonkProvingStage,\n} from './proof.js'\n\n// Legacy stealth proof exports (deprecated)\nexport {\n generateProof,\n verifyProof,\n generateStealthProof,\n getStealthCircuitArtifacts,\n} from './proof.js'\nexport type {\n CircuitType,\n StealthCircuitType,\n StealthCircuitInputs,\n Stealth1x2CircuitInputs,\n Stealth2x2CircuitInputs,\n} from './proof.js'\n\n// Deployment verification\nexport {\n checkImplementation,\n verifyDeployment,\n} from './verify.js'\nexport type {\n VerificationCheck,\n VerificationResult,\n} from './verify.js'\n\n// Types (explicit named exports to avoid tsup DTS NamespaceFixer conflicts)\n// Note: STARK_AMOUNT_SCALE is exported from utils/stark.ts (canonical location)\nexport {\n NOTE_VERSION,\n} from './types.js'\nexport type {\n NoteStatus,\n ProofSystem,\n ShieldedNote,\n Note,\n EncryptedNote,\n StealthMetaAddress,\n StealthAddress,\n MergeRecord,\n ASPRoot,\n ShieldParams,\n TransferParams,\n MergeParams,\n WithdrawParams,\n Proof,\n Commitment,\n Nullifier,\n StarkNote,\n StarkStealthMetaAddress,\n StarkProof,\n} from './types.js'\n\n// Swap order book module\nexport {\n computeGiveAmount,\n computeTakeAmount,\n computeRate,\n formatRate,\n computeCancelKeyHash,\n generateCancelSecret,\n filterOrdersByASP,\n filterOrdersByTokenPair,\n isFillerASPAccepted,\n isOrderActive,\n computeTotalBuyAmount,\n computeFillPercentage,\n storeCancelSecret,\n getCancelSecret,\n removeCancelSecret,\n getOwnOrderIds,\n RATE_PRECISION,\n SWAP_EVENTS_ABI,\n SWAP_ORDER_PLACED_EVENT,\n SWAP_ORDER_FILLED_EVENT,\n SWAP_ORDER_CLAIMED_EVENT,\n SWAP_ORDER_CANCELLED_EVENT,\n} from './swap.js'\nexport type {\n SwapOrder,\n SwapOrderParams,\n SwapFillParams,\n SwapOrderEvent,\n SwapFillEvent,\n} from './swap.js'\n\n// Account adapter (pluggable key source + persistence)\nexport { DirectAccountAdapter, StorableAccountAdapter } from './account.js'\nexport type { IAccountAdapter } from './account.js'\n\n// ASP provider (pluggable compliance)\nexport type { IASPProvider, ASPMembershipProof } from './asp-provider.js'\n\n// Note store (single source of truth for note state)\nexport { NoteStore } from './note-store.js'\nexport type { INoteStore } from './note-store.js'\n\n// New core modules — importable directly via deep paths:\n// import { createHashBasedNote } from '@permissionless-technologies/upp-sdk/core/note-crypto'\n// import { selectOptimalCircuit } from '@permissionless-technologies/upp-sdk/core/circuit-selector'\n// etc.\n// Not re-exported from the barrel to avoid tsup DTS NamespaceFixer limits.\n\n// ASP (Association Set Provider) module\nexport {\n computeSingleOriginASPRoot,\n generateSingleOriginASPProof,\n verifyASPProof,\n DEMO_ASP_ID,\n DEMO_ASP_NAME,\n createDemoASPRoot,\n // Multi-origin ASP tree\n buildASPTree,\n computeMultiOriginASPRoot,\n generateMultiOriginASPProof,\n generateASPProof,\n} from './asp.js'\nexport type { ASPProof } from './asp.js'\n\n// Transfer module\nexport {\n syncMerkleTree,\n getMerkleProofsForNotes,\n computeNullifier,\n buildUPPTransferCircuitInputs,\n buildTransfer,\n formatOutputForContract,\n} from './transfer.js'\nexport type {\n TransferStage,\n SpendableNote,\n MerkleProofWithNote,\n TransferContext,\n TransferBuildResult,\n NoteWithAmount,\n} from './transfer.js'\n","/**\n * UPP Deployment Verification — Check on-chain state matches deployment config.\n *\n * Verifies:\n * 1. Bytecode exists at proxy and implementation addresses\n * 2. UUPS proxy implementation slots point to expected implementations\n *\n * Use `verifyDeployment()` for comprehensive checks, or `checkImplementation()`\n * for a lightweight proxy-vs-expected check suitable for UI warnings.\n */\n\nimport type { Address, PublicClient } from 'viem'\nimport type { DeploymentConfig } from '../deployments/index.js'\n\n/** ERC-1967 implementation storage slot: keccak256(\"eip1967.proxy.implementation\") - 1 */\nconst ERC1967_IMPL_SLOT =\n '0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc' as const\n\nexport interface VerificationCheck {\n name: string\n passed: boolean\n expected?: string\n actual?: string\n}\n\nexport interface VerificationResult {\n chainId: number\n checks: VerificationCheck[]\n passed: number\n failed: number\n allPassed: boolean\n}\n\n/**\n * Lightweight check: does the on-chain proxy point to the expected implementation?\n *\n * Returns `true` if the implementation matches, `false` if it doesn't or can't be read.\n * Use this in UI code to warn users about outdated deployments.\n *\n * @example\n * ```ts\n * import { checkImplementation, getDeploymentOrThrow } from '@permissionless-technologies/upp-sdk'\n *\n * const deployment = getDeploymentOrThrow(11155111)\n * const ok = await checkImplementation(publicClient, deployment, 'UniversalPrivatePool')\n * if (!ok) {\n * console.warn('Pool implementation has been upgraded — SDK may be outdated')\n * }\n * ```\n */\nexport async function checkImplementation(\n publicClient: PublicClient,\n deployment: DeploymentConfig,\n contract: 'UniversalPrivatePool' | 'ASPRegistryHub',\n): Promise<boolean> {\n const proxyAddress = deployment[contract]\n const expectedImpl = deployment.implementations?.[contract]\n\n if (!proxyAddress || !expectedImpl) return false\n\n try {\n const implSlot = await publicClient.getStorageAt({\n address: proxyAddress,\n slot: ERC1967_IMPL_SLOT,\n })\n const actualImpl = ('0x' + (implSlot ?? '0x').slice(26)).toLowerCase()\n return actualImpl === expectedImpl.toLowerCase()\n } catch {\n return false\n }\n}\n\n/**\n * Full deployment verification — checks bytecode existence and proxy implementations.\n *\n * @example\n * ```ts\n * const result = await verifyDeployment(publicClient, deployment)\n * if (!result.allPassed) {\n * for (const check of result.checks.filter(c => !c.passed)) {\n * console.error(`FAIL: ${check.name}`, check.expected, check.actual)\n * }\n * }\n * ```\n */\nexport async function verifyDeployment(\n publicClient: PublicClient,\n deployment: DeploymentConfig,\n): Promise<VerificationResult> {\n const checks: VerificationCheck[] = []\n\n // 1. Bytecode existence — proxy addresses\n await _verifyBytecode(publicClient, checks, 'UniversalPrivatePool (proxy)', deployment.UniversalPrivatePool)\n await _verifyBytecode(publicClient, checks, 'ASPRegistryHub (proxy)', deployment.ASPRegistryHub)\n\n // 1b. Bytecode existence — implementation addresses (if known)\n if (deployment.implementations?.UniversalPrivatePool) {\n await _verifyBytecode(publicClient, checks, 'UniversalPrivatePool (impl)', deployment.implementations.UniversalPrivatePool)\n }\n if (deployment.implementations?.ASPRegistryHub) {\n await _verifyBytecode(publicClient, checks, 'ASPRegistryHub (impl)', deployment.implementations.ASPRegistryHub)\n }\n\n // 2. Proxy implementation slots (ERC-1967)\n if (deployment.implementations?.UniversalPrivatePool) {\n await _verifyProxyImpl(\n publicClient, checks,\n 'UniversalPrivatePool',\n deployment.UniversalPrivatePool,\n deployment.implementations.UniversalPrivatePool,\n )\n }\n if (deployment.implementations?.ASPRegistryHub) {\n await _verifyProxyImpl(\n publicClient, checks,\n 'ASPRegistryHub',\n deployment.ASPRegistryHub,\n deployment.implementations.ASPRegistryHub,\n )\n }\n\n // 3. Bytecode existence — verifiers\n for (const [name, addr] of Object.entries(deployment.verifiers)) {\n if (addr) {\n await _verifyBytecode(publicClient, checks, `Verifier: ${name}`, addr as Address)\n }\n }\n\n const passed = checks.filter((c) => c.passed).length\n const failed = checks.filter((c) => !c.passed).length\n\n return {\n chainId: deployment.chainId,\n checks,\n passed,\n failed,\n allPassed: failed === 0,\n }\n}\n\n// ─── Internal helpers ─────────────────────────────────────────────\n\nasync function _verifyBytecode(\n client: PublicClient,\n checks: VerificationCheck[],\n name: string,\n address: Address,\n): Promise<void> {\n try {\n const code = await client.getCode({ address })\n const exists = code !== undefined && code !== '0x' && code.length > 2\n checks.push({ name: `${name} bytecode exists`, passed: exists })\n } catch {\n checks.push({ name: `${name} bytecode exists`, passed: false })\n }\n}\n\nasync function _verifyProxyImpl(\n client: PublicClient,\n checks: VerificationCheck[],\n name: string,\n proxyAddress: Address,\n expectedImpl: Address,\n): Promise<void> {\n try {\n const implSlot = await client.getStorageAt({\n address: proxyAddress,\n slot: ERC1967_IMPL_SLOT,\n })\n const actualImpl = ('0x' + (implSlot ?? '0x').slice(26)).toLowerCase() as Address\n const expected = expectedImpl.toLowerCase()\n checks.push({\n name: `${name} proxy -> impl`,\n passed: actualImpl === expected,\n expected: expectedImpl,\n actual: actualImpl as string,\n })\n } catch {\n checks.push({ name: `${name} proxy -> impl`, passed: false, expected: expectedImpl })\n }\n}\n"]}
|
|
@@ -8,8 +8,8 @@ import { encodePacked, toHex } from 'viem';
|
|
|
8
8
|
var __default = {
|
|
9
9
|
contracts: {
|
|
10
10
|
ASPRegistryHub: "0x9708CfDCa7AA4d282888B43f70ff11Fc869431f1",
|
|
11
|
-
UniversalPrivatePool: "
|
|
12
|
-
UPPSwapModule: "
|
|
11
|
+
UniversalPrivatePool: "0x0e6664FcfD0CF1daa3E909d5C1293C2afe27FBac",
|
|
12
|
+
UPPSwapModule: "0x55417f64da1770D9edc795Cf9c878a114016C013"
|
|
13
13
|
},
|
|
14
14
|
implementations: {
|
|
15
15
|
ASPRegistryHub: "0xdcD8A9D39E4305187A45Bf9208A83233D2654e87",
|
|
@@ -17,25 +17,25 @@ var __default = {
|
|
|
17
17
|
UPPSwapModule: "0xd81a856940FaC8B24875855F26087c532B80BABc"
|
|
18
18
|
},
|
|
19
19
|
verifiers: {
|
|
20
|
-
Transfer: "
|
|
21
|
-
Merge: "
|
|
22
|
-
Withdraw: "
|
|
23
|
-
JoinSplit: "
|
|
24
|
-
MergeTransfer2x2: "
|
|
25
|
-
MergeTransfer4x2: "
|
|
20
|
+
Transfer: "0x9b79ea6d519Ac317A6D360Ec45D04FB03cDb5965",
|
|
21
|
+
Merge: "0x4f296AC081C3d218211E8537f417506888F96b9B",
|
|
22
|
+
Withdraw: "0x85Cbcd93Ff1926cFd1b24586Cd8DF1a1D01B8e06",
|
|
23
|
+
JoinSplit: "0xd924ff7E01dAC1077A4FF90301D37d46A7Cd2388",
|
|
24
|
+
MergeTransfer2x2: "0x90Ec10bFdf69697961A895cE8A5Ae3d1012A2211",
|
|
25
|
+
MergeTransfer4x2: "0x0E2db3122000406f143c424b4e749b331b35E370"
|
|
26
26
|
},
|
|
27
27
|
starkVerifiers: {
|
|
28
|
-
WithdrawVerifier: "
|
|
29
|
-
TransferVerifier: "
|
|
28
|
+
WithdrawVerifier: "0x85554083b691219C1F2556bA52D4fDEe5d76a01f",
|
|
29
|
+
TransferVerifier: "0x2a88C3373cD7D7CAc90420515614d5C43777A00c"
|
|
30
30
|
},
|
|
31
31
|
testTokens: {
|
|
32
|
-
TestStableToken: "
|
|
33
|
-
TestStableToken2: "
|
|
32
|
+
TestStableToken: "0x45e6D4230064F9dd806330dA9D92639f8665D9bf",
|
|
33
|
+
TestStableToken2: "0xCC8eFf4Ad952dE82990264D5ADB32Fc9399ECb64"
|
|
34
34
|
},
|
|
35
35
|
metadata: {
|
|
36
36
|
chainId: 31337,
|
|
37
|
-
deployBlock:
|
|
38
|
-
deployTimestamp:
|
|
37
|
+
deployBlock: 10631967,
|
|
38
|
+
deployTimestamp: 1775847275,
|
|
39
39
|
deployer: "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266"
|
|
40
40
|
}
|
|
41
41
|
};
|
|
@@ -431,5 +431,5 @@ function formatOutputForContract(note) {
|
|
|
431
431
|
}
|
|
432
432
|
|
|
433
433
|
export { buildTransfer, buildUPPTransferCircuitInputs, buildWithdrawCircuitInputs, computeNullifier, formatOutputForContract, getDeployment, getDeploymentOrThrow, getMerkleProofsForNotes, getSupportedChainIds, getTokenAddress, hasDeployment, packNoteData, padToDepth, registerDeployment, syncMerkleTree };
|
|
434
|
-
//# sourceMappingURL=chunk-
|
|
435
|
-
//# sourceMappingURL=chunk-
|
|
434
|
+
//# sourceMappingURL=chunk-PJBEE2OI.js.map
|
|
435
|
+
//# sourceMappingURL=chunk-PJBEE2OI.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/deployments/31337.json","../src/deployments/11155111.json","../src/deployments/index.ts","../src/core/transfer.ts","../src/core/note-packing.ts"],"names":["__default"],"mappings":"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","file":"chunk-N2VHE47N.js","sourcesContent":["{\n \"contracts\": {\n \"ASPRegistryHub\": \"0x9708CfDCa7AA4d282888B43f70ff11Fc869431f1\",\n \"UniversalPrivatePool\": \"0x4bC6d44f8a706276216AA2d2F5F726939B945690\",\n \"UPPSwapModule\": \"0x3289135f1e5990BA93932924090BA9F6354EeBe0\"\n },\n \"implementations\": {\n \"ASPRegistryHub\": \"0xdcD8A9D39E4305187A45Bf9208A83233D2654e87\",\n \"UniversalPrivatePool\": \"0xB99A51eFb2fdF83243C383a5CDdF803D8dDFc5ea\",\n \"UPPSwapModule\": \"0xd81a856940FaC8B24875855F26087c532B80BABc\"\n },\n \"verifiers\": {\n \"Transfer\": \"0xFF1574526DC526c0ca271cFF6541e0e28f1547cB\",\n \"Merge\": \"0x9E111a0d8c99b86738bCeBf5aFC0Db159244C7b7\",\n \"Withdraw\": \"0x4D8397464bF23B3b38E31636f94FC4C1A7139a44\",\n \"JoinSplit\": \"0x311788765A9C37AbBe2522EE7dE25Da41724aD75\",\n \"MergeTransfer2x2\": \"0x6bC3217Cc933c55EFf5951f4022c8a9dDB4F4023\",\n \"MergeTransfer4x2\": \"0xD4aA8Dc4B38673142C9b082b57c193eBB3690C37\"\n },\n \"starkVerifiers\": {\n \"WithdrawVerifier\": \"0xa131A62B7AF5C81BfbdbA708750Fc378e3353B42\",\n \"TransferVerifier\": \"0x6aB434B061D3EaAfF7d704DCcd2d137966212daC\"\n },\n \"testTokens\": {\n \"TestStableToken\": \"0x10a1a550AC27b94dD9aEA65f097177de02f67cAf\",\n \"TestStableToken2\": \"0x2Fe988cea5E2683EBCFF0Ba1861002FBB265b695\"\n },\n \"metadata\": {\n \"chainId\": 31337,\n \"deployBlock\": 10567272,\n \"deployTimestamp\": 1775043000,\n \"deployer\": \"0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266\"\n }\n}","{\n \"contracts\": {\n \"ASPRegistryHub\": \"0xA85d9766C794B97d1463Ba6D5734a27C65A958Da\",\n \"UniversalPrivatePool\": \"0xD493b0651C285a60cae3c45035D0Fd58AC274BC9\",\n \"UPPSwapModule\": \"0x5a626e9b119A6f8DF1Dcc161F5b95Da9F93dB963\"\n },\n \"implementations\": {\n \"ASPRegistryHub\": \"0xdcD8A9D39E4305187A45Bf9208A83233D2654e87\",\n \"UniversalPrivatePool\": \"0xB99A51eFb2fdF83243C383a5CDdF803D8dDFc5ea\",\n \"UPPSwapModule\": \"0xd81a856940FaC8B24875855F26087c532B80BABc\"\n },\n \"verifiers\": {\n \"Transfer\": \"0x3755b4fA8Ee882311aB8FaB8Fd5BFecc355fF35B\",\n \"Merge\": \"0xE115B76eAff5Ba63F8018c182BF7824af7fC7431\",\n \"Withdraw\": \"0xB7FC84975066493fD3962c3c79e4c073BeaD090a\",\n \"JoinSplit\": \"0xFF2c3c620C6047da8d53e137C573E4738D2005e0\",\n \"MergeTransfer2x2\": \"0x347301A2DC42Cbf1386509f716a24d677D8599c8\",\n \"MergeTransfer4x2\": \"0x7F5cc8a714Ae9461B95EFDcaA85494F4251ebc0F\"\n },\n \"starkVerifiers\": {\n \"WithdrawVerifier\": \"0xB8C307D74dAeBe816839BB891b16aCfc01253241\",\n \"TransferVerifier\": \"0x172960000Eed4A280Ac6cAecD318aBF2E0517734\"\n },\n \"testTokens\": {\n \"TestStableToken\": \"0x8369F7dBdd1835410d421D1dD732346106ebc872\",\n \"TestStableToken2\": \"0xE721b1746be10C5D751a6cc44748F00654630Cb7\"\n },\n \"metadata\": {\n \"chainId\": 11155111,\n \"deployBlock\": 10560423,\n \"deployTimestamp\": 1774958844,\n \"deployer\": \"0xdEadDEADb916b00D02f4f2db062Fb2C47fe0689b\"\n }\n}","/**\n * Deployment Configuration Loader\n *\n * Loads contract addresses based on chain ID.\n * Built-in: Anvil (31337) and Sepolia (11155111).\n * Custom chains can be registered at runtime via registerDeployment().\n */\n\nimport type { Address } from \"viem\";\n\n/**\n * Verifier contract addresses\n */\nexport interface VerifierAddresses {\n Transfer: Address;\n Merge: Address;\n Withdraw: Address;\n JoinSplit?: Address;\n MergeTransfer2x2?: Address;\n MergeTransfer4x2?: Address;\n /** @deprecated Use `Transfer` */\n TransferVerifier?: Address;\n /** @deprecated Use `Merge` */\n MergeVerifier?: Address;\n /** @deprecated Use `Withdraw` */\n WithdrawVerifier?: Address;\n}\n\n/**\n * STARK verifier contract addresses\n */\nexport interface StarkVerifierAddresses {\n CircleStarkVerifier?: Address;\n}\n\n/**\n * Implementation addresses for UUPS proxies (for upgrade verification)\n */\nexport interface ImplementationAddresses {\n UniversalPrivatePool?: Address;\n ASPRegistryHub?: Address;\n UPPSwapModule?: Address;\n}\n\n/**\n * Deployment configuration for a chain\n */\nexport interface DeploymentConfig {\n /** Universal Private Pool contract address (proxy) */\n UniversalPrivatePool: Address;\n /** ASP Registry Hub contract address (proxy) */\n ASPRegistryHub: Address;\n /** UPP Swap Module contract address (proxy) */\n UPPSwapModule?: Address;\n /** Implementation addresses for UUPS proxies */\n implementations?: ImplementationAddresses;\n /** Test token address (local/testnet) */\n TestToken?: Address;\n /** Test token 2 address — bonding curve token (local/testnet) */\n TestToken2?: Address;\n /** Verifier contract addresses */\n verifiers: VerifierAddresses;\n /** STARK verifier contract addresses */\n starkVerifiers?: StarkVerifierAddresses;\n /** Chain ID */\n chainId: number;\n /** Block number when contracts were deployed (for efficient scanning) */\n deployBlock: number;\n /** Timestamp when contracts were deployed */\n deployTimestamp?: number;\n}\n\n/**\n * Raw JSON file format (without chainId, which is added dynamically)\n */\ninterface DeploymentJSON {\n contracts?: {\n UniversalPrivatePool?: string;\n ASPRegistryHub?: string;\n UPPSwapModule?: string;\n };\n implementations?: {\n UniversalPrivatePool?: string;\n ASPRegistryHub?: string;\n UPPSwapModule?: string;\n };\n testTokens?: {\n TestStableToken?: string;\n TestStableToken2?: string;\n };\n verifiers?: {\n Transfer?: string;\n Merge?: string;\n Withdraw?: string;\n JoinSplit?: string;\n MergeTransfer2x2?: string;\n MergeTransfer4x2?: string;\n TransferVerifier?: string;\n MergeVerifier?: string;\n WithdrawVerifier?: string;\n JoinSplitVerifier?: string;\n MergeTransfer2x2Verifier?: string;\n MergeTransfer4x2Verifier?: string;\n };\n starkVerifiers?: {\n CircleStarkVerifier?: string;\n WithdrawVerifier?: string;\n TransferVerifier?: string;\n };\n metadata?: {\n chainId?: number;\n deployBlock?: number;\n deployTimestamp?: number;\n };\n}\n\n/**\n * Parse raw deployment JSON into typed config\n */\nfunction parseDeployment(\n json: DeploymentJSON,\n chainId: number\n): DeploymentConfig {\n const contracts = json.contracts || {};\n const verifs = json.verifiers || {};\n const testTokens = json.testTokens || {};\n\n return {\n UniversalPrivatePool: contracts.UniversalPrivatePool as Address,\n ASPRegistryHub: contracts.ASPRegistryHub as Address,\n UPPSwapModule: contracts.UPPSwapModule as Address | undefined,\n implementations: json.implementations\n ? {\n UniversalPrivatePool: json.implementations.UniversalPrivatePool as Address | undefined,\n ASPRegistryHub: json.implementations.ASPRegistryHub as Address | undefined,\n UPPSwapModule: json.implementations.UPPSwapModule as Address | undefined,\n }\n : undefined,\n TestToken: testTokens.TestStableToken as Address | undefined,\n TestToken2: testTokens.TestStableToken2 as Address | undefined,\n verifiers: {\n Transfer: (verifs.Transfer || verifs.TransferVerifier) as Address,\n Merge: (verifs.Merge || verifs.MergeVerifier) as Address,\n Withdraw: (verifs.Withdraw || verifs.WithdrawVerifier) as Address,\n JoinSplit: (verifs.JoinSplit || verifs.JoinSplitVerifier) as Address | undefined,\n MergeTransfer2x2: (verifs.MergeTransfer2x2 || verifs.MergeTransfer2x2Verifier) as Address | undefined,\n MergeTransfer4x2: (verifs.MergeTransfer4x2 || verifs.MergeTransfer4x2Verifier) as Address | undefined,\n },\n starkVerifiers: json.starkVerifiers\n ? {\n CircleStarkVerifier: json.starkVerifiers.CircleStarkVerifier as Address | undefined,\n }\n : undefined,\n chainId,\n deployBlock: json.metadata?.deployBlock ?? 0,\n deployTimestamp: json.metadata?.deployTimestamp,\n };\n}\n\n// Import deployment configs\n// These will be updated by the extract-deployment.js script\nimport anvil from \"./31337.json\" with { type: \"json\" };\nimport sepolia from \"./11155111.json\" with { type: \"json\" };\n\nconst deployments: Record<number, DeploymentConfig> = {\n 31337: parseDeployment(anvil as unknown as DeploymentJSON, 31337),\n 11155111: parseDeployment(sepolia as unknown as DeploymentJSON, 11155111),\n};\n\n/**\n * Get deployment config for a chain\n *\n * @param chainId - Chain ID to get deployment for\n * @returns Deployment config or null if not found\n *\n * @example\n * ```ts\n * const deployment = getDeployment(31337)\n * if (deployment) {\n * console.log('Pool address:', deployment.UniversalPrivatePool)\n * }\n * ```\n */\nexport function getDeployment(chainId: number): DeploymentConfig | null {\n return deployments[chainId] ?? null;\n}\n\n/**\n * Get deployment config or throw if not found\n *\n * @param chainId - Chain ID to get deployment for\n * @returns Deployment config\n * @throws Error if deployment not found\n */\nexport function getDeploymentOrThrow(chainId: number): DeploymentConfig {\n const deployment = getDeployment(chainId);\n if (!deployment) {\n throw new Error(\n `No deployment found for chain ${chainId}. ` +\n `Supported chains: ${Object.keys(deployments).join(\", \")}`\n );\n }\n return deployment;\n}\n\n/**\n * Check if a chain has a deployment\n */\nexport function hasDeployment(chainId: number): boolean {\n return chainId in deployments;\n}\n\n/**\n * Get all supported chain IDs\n */\nexport function getSupportedChainIds(): number[] {\n return Object.keys(deployments).map(Number);\n}\n\n/**\n * Get the token address for a chain\n */\nexport function getTokenAddress(chainId: number): Address | null {\n const deployment = getDeployment(chainId);\n if (!deployment) return null;\n return deployment.TestToken ?? null;\n}\n\n/**\n * Register a deployment for a custom chain at runtime.\n *\n * Use this when deploying your own pool on a chain not built into the SDK.\n * Overrides any existing deployment for the same chainId.\n *\n * @example\n * ```ts\n * registerDeployment(8453, {\n * UniversalPrivatePool: '0x...',\n * ASPRegistryHub: '0x...',\n * verifiers: { Transfer: '0x...', Merge: '0x...', Withdraw: '0x...' },\n * chainId: 8453,\n * deployBlock: 12345678,\n * })\n * ```\n */\nexport function registerDeployment(chainId: number, config: DeploymentConfig): void {\n deployments[chainId] = { ...config, chainId };\n}\n","/**\n * Transfer Module\n *\n * Core logic for building and executing UPP transfers.\n * This module is framework-agnostic (no React).\n */\n\nimport { toHex, type Address, type Hex, type PublicClient } from 'viem'\nimport { getDeployment } from '../deployments/index.js'\nimport { buildMerkleTree, type MerkleProof } from '../utils/merkle.js'\nimport { poseidon, computeOwnerHash as poseidonOwnerHash, computeNoteCommitment } from '../utils/poseidon.js'\nimport {\n generateUPPProof,\n formatPlonkProofForContract,\n STATE_TREE_DEPTH,\n ASP_TREE_DEPTH,\n type UPPCircuitType,\n type UPPTransferCircuitInputs,\n type PlonkProofStruct,\n} from './proof.js'\nimport { generateASPProof, type ASPProof } from './asp.js'\nimport type { NoteCreationResult } from '../react/use-upp-account.js'\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Transfer stage for progress tracking\n */\nexport type TransferStage =\n | 'selecting_notes'\n | 'syncing_merkle'\n | 'creating_outputs'\n | 'generating_proof'\n | 'submitting_tx'\n | 'confirming'\n\n/**\n * A shielded note with all data needed for spending\n *\n * Post-quantum: uses ownerSecret/ownerHash instead of BabyJubJub one-time keys.\n * Ownership is proven via hash preimage: Poseidon(ownerSecret) == ownerHash.\n */\nexport interface SpendableNote {\n amount: bigint\n blinding: bigint\n commitment: string\n /** Owner secret (hash preimage for ownership proof) */\n ownerSecret: string\n /** Owner hash = Poseidon(ownerSecret) - committed in the note */\n ownerHash: string\n leafIndex: number\n /** Origin address (depositor) - required for UPP circuits */\n origin: bigint\n /** Token address - required for UPP circuits */\n token: bigint\n}\n\n/**\n * Merkle proof with associated note\n */\nexport interface MerkleProofWithNote {\n proof: MerkleProof\n note: SpendableNote\n}\n\n/**\n * Transfer context (dependencies)\n */\nexport interface TransferContext {\n /** viem PublicClient for RPC calls */\n publicClient: PublicClient\n /** Contract address */\n contractAddress: Address\n /** Chain ID */\n chainId: number\n /** Circuit base URL (default: '/circuits/') */\n circuitBaseUrl?: string\n /** ASP ID to use (default: DEMO_ASP_ID) */\n aspId?: bigint\n /** All approved origins in the ASP tree (enables multi-origin proofs) */\n aspApprovedOrigins?: bigint[]\n}\n\n/**\n * Transfer result\n */\nexport interface TransferBuildResult {\n /** Circuit type used */\n circuit: UPPCircuitType\n /** Formatted PLONK proof for contract */\n proof: {\n proofStruct: PlonkProofStruct\n publicSignals: bigint[]\n }\n /** Public signals from proof */\n publicSignals: string[]\n /** State tree root */\n stateRoot: bigint\n /** ASP tree root */\n aspRoot: bigint\n /** Nullifier hash */\n nullifier: bigint\n /** Output commitment 1 */\n outputCommitment1: bigint\n /** Output commitment 2 */\n outputCommitment2: bigint\n /** Token address */\n token: bigint\n /** Recipient output */\n recipientOutput: NoteCreationResult\n /** Change output */\n changeOutput: NoteCreationResult\n /** Notes that will be spent */\n spentNotes: SpendableNote[]\n}\n\n// ============================================================================\n// Constants\n// ============================================================================\n\n/** Chunk size for paginated RPC queries on testnets */\nconst RPC_CHUNK_SIZE = 9000n\n\n/**\n * Pad an array to the state tree depth (32 levels)\n * @param arr - Array to pad\n * @param padValue - Value to use for padding (default: '0')\n * @returns Padded array of length STATE_TREE_DEPTH\n */\nfunction padToStateTreeDepth<T>(arr: T[], padValue: T): T[] {\n if (arr.length >= STATE_TREE_DEPTH) {\n return arr.slice(0, STATE_TREE_DEPTH)\n }\n return [...arr, ...Array(STATE_TREE_DEPTH - arr.length).fill(padValue)]\n}\n\n/**\n * Pad an array to the ASP tree depth (20 levels)\n * @param arr - Array to pad\n * @param padValue - Value to use for padding (default: '0')\n * @returns Padded array of length ASP_TREE_DEPTH\n */\nfunction padToASPTreeDepth<T>(arr: T[], padValue: T): T[] {\n if (arr.length >= ASP_TREE_DEPTH) {\n return arr.slice(0, ASP_TREE_DEPTH)\n }\n return [...arr, ...Array(ASP_TREE_DEPTH - arr.length).fill(padValue)]\n}\n\n/**\n * CommitmentInserted event — emitted by _insertLeaf() for ALL leaf insertions\n * (shield, transfer, merge, swap fill, swap claim, swap cancel).\n * This is the single canonical event for Merkle tree reconstruction.\n */\nconst COMMITMENT_INSERTED_EVENT = {\n type: 'event' as const,\n name: 'CommitmentInserted',\n inputs: [\n { type: 'bytes32', name: 'commitment', indexed: true },\n { type: 'uint256', name: 'leafIndex' },\n { type: 'uint256', name: 'timestamp' },\n ],\n}\n\n// ============================================================================\n// Merkle Tree Functions\n// ============================================================================\n\n/**\n * Fetch all commitments from the contract and build a Merkle tree\n *\n * @param publicClient - viem PublicClient\n * @param contractAddress - Contract address\n * @returns Object with tree and leaves array\n */\nexport async function syncMerkleTree(\n publicClient: PublicClient,\n contractAddress: Address\n): Promise<{ tree: ReturnType<typeof buildMerkleTree>; leaves: bigint[] }> {\n const currentBlock = await publicClient.getBlockNumber()\n const chainId = await publicClient.getChainId()\n\n // Use CommitmentInserted events — the canonical event emitted by _insertLeaf()\n // for ALL operations (shield, transfer, merge, swap fill/claim/cancel).\n // Each event has an explicit leafIndex, so ordering is deterministic.\n let commitmentLogs: any[] = []\n\n if (chainId === 31337) {\n // Anvil - single query is fine\n commitmentLogs = await publicClient.getLogs({\n address: contractAddress,\n event: COMMITMENT_INSERTED_EVENT,\n fromBlock: 0n,\n })\n } else {\n // Testnet/mainnet - paginate to avoid RPC limits\n const deployment = getDeployment(chainId)\n let fromBlock = deployment?.deployBlock ? BigInt(deployment.deployBlock) : 0n\n console.log(`[syncMerkleTree] Chain ${chainId}: scanning from block ${fromBlock} to ${currentBlock}`)\n\n while (fromBlock <= currentBlock) {\n const toBlock =\n fromBlock + RPC_CHUNK_SIZE > currentBlock ? currentBlock : fromBlock + RPC_CHUNK_SIZE\n const chunk = await publicClient.getLogs({\n address: contractAddress,\n event: COMMITMENT_INSERTED_EVENT,\n fromBlock,\n toBlock,\n })\n commitmentLogs = commitmentLogs.concat(chunk)\n fromBlock = toBlock + 1n\n }\n }\n\n // Sort by explicit leafIndex (most reliable), falling back to block+logIndex\n commitmentLogs.sort((a: any, b: any) => {\n const idxA = Number(a.args.leafIndex!)\n const idxB = Number(b.args.leafIndex!)\n return idxA - idxB\n })\n\n // Build leaves array using the explicit leafIndex from each event\n const leaves: bigint[] = []\n for (const log of commitmentLogs) {\n const leafIndex = Number(log.args.leafIndex!)\n const commitment = BigInt(log.args.commitment!)\n\n if (leaves.length !== leafIndex) {\n console.warn(\n `[syncMerkleTree] WARNING: Expected leafIndex ${leaves.length} but event has ${leafIndex}. ` +\n `This may indicate missed events or reorg.`\n )\n }\n leaves.push(commitment)\n }\n\n const tree = buildMerkleTree(leaves)\n\n // Debug: compare our root with on-chain root\n const ourRoot = await tree.getRoot()\n const onChainRoot = (await publicClient.readContract({\n address: contractAddress,\n abi: [\n {\n type: 'function',\n name: 'getMerkleRoot',\n inputs: [],\n outputs: [{ type: 'uint256' }],\n stateMutability: 'view',\n },\n ],\n functionName: 'getMerkleRoot',\n })) as bigint\n\n console.log(`[syncMerkleTree] Leaves count: ${leaves.length}`)\n console.log(`[syncMerkleTree] Tree depth: ${tree.depth}`)\n console.log(`[syncMerkleTree] Our computed root: ${ourRoot}`)\n console.log(`[syncMerkleTree] On-chain root: ${onChainRoot}`)\n console.log(`[syncMerkleTree] Roots match: ${ourRoot === onChainRoot}`)\n\n if (ourRoot !== onChainRoot) {\n console.log(`[syncMerkleTree] WARNING: Root mismatch!`)\n console.log(\n `[syncMerkleTree] Leaves:`,\n leaves.map((l) => '0x' + l.toString(16))\n )\n }\n\n return { tree, leaves }\n}\n\n/**\n * Get Merkle proofs for a set of notes\n *\n * @param notes - Notes to get proofs for\n * @param leaves - All leaves in the tree\n * @param tree - Merkle tree instance\n * @returns Array of proofs with associated notes\n */\nexport async function getMerkleProofsForNotes(\n notes: SpendableNote[],\n leaves: bigint[],\n tree: ReturnType<typeof buildMerkleTree>\n): Promise<MerkleProofWithNote[]> {\n const { verifyMerkleProof } = await import('../utils/merkle.js')\n const proofs: MerkleProofWithNote[] = []\n\n for (const note of notes) {\n const commitmentBI = BigInt(note.commitment)\n const leafIndex = leaves.findIndex((l) => l === commitmentBI)\n\n console.log(`[getMerkleProofsForNotes] Note commitment: ${note.commitment}`)\n console.log(`[getMerkleProofsForNotes] Note commitment as BigInt: ${commitmentBI}`)\n console.log(`[getMerkleProofsForNotes] Found at leafIndex: ${leafIndex}`)\n console.log(`[getMerkleProofsForNotes] Note's stored leafIndex: ${note.leafIndex}`)\n\n if (leafIndex === -1) {\n console.log(`[getMerkleProofsForNotes] Leaves in tree:`, leaves.map((l) => l.toString()))\n throw new Error(`Note ${note.commitment.slice(0, 10)}... not found on-chain`)\n }\n\n const proof = await tree.getProof(leafIndex)\n\n console.log(`[getMerkleProofsForNotes] Proof root: ${proof.root}`)\n console.log(`[getMerkleProofsForNotes] Proof leafIndex: ${proof.leafIndex}`)\n console.log(`[getMerkleProofsForNotes] PathElements:`, proof.pathElements.map((e) => e.toString()))\n console.log(`[getMerkleProofsForNotes] PathIndices:`, proof.pathIndices)\n\n // Verify the proof locally before returning\n const isValid = await verifyMerkleProof(commitmentBI, proof)\n console.log(`[getMerkleProofsForNotes] Local proof verification: ${isValid}`)\n\n if (!isValid) {\n console.error(`[getMerkleProofsForNotes] WARNING: Merkle proof is invalid!`)\n }\n\n proofs.push({ proof, note: { ...note, leafIndex } })\n }\n\n return proofs\n}\n\n// ============================================================================\n// Circuit Input Building\n// ============================================================================\n\n/**\n * Compute nullifier for a UPP note (BLS12-381)\n *\n * nullifier = Poseidon(ownerSecret, leafIndex, commitment)\n *\n * @param ownerSecret - Owner secret (hash preimage)\n * @param leafIndex - Leaf index in Merkle tree\n * @param commitment - Note commitment\n * @returns Nullifier as bigint\n */\nexport async function computeNullifier(\n ownerSecret: bigint,\n leafIndex: number,\n commitment: bigint\n): Promise<bigint> {\n return await poseidon([ownerSecret, BigInt(leafIndex), commitment])\n}\n\n/**\n * Note with amount for circuit building\n */\nexport interface NoteWithAmount extends NoteCreationResult {\n amount: bigint\n}\n\n/**\n * Build circuit inputs for UPP transfer (1-in-2-out)\n *\n * @param noteProof - Merkle proof for input note\n * @param aspProof - ASP membership proof for input note's origin\n * @param recipientNote - Output note for recipient\n * @param changeNote - Output note for change\n * @returns UPP transfer circuit inputs\n */\nexport async function buildUPPTransferCircuitInputs(\n noteProof: MerkleProofWithNote,\n aspProof: ASPProof,\n recipientNote: NoteWithAmount,\n changeNote: NoteWithAmount\n): Promise<UPPTransferCircuitInputs> {\n const { proof, note } = noteProof\n\n // Compute owner hash from secret (hash-based ownership)\n const inputOwnerHash = poseidonOwnerHash(BigInt(note.ownerSecret))\n\n // Verify input commitment locally\n // BLS12-381 commitment: Poseidon(amount, ownerHash, blinding, origin, token)\n const localInputCommitment = computeNoteCommitment(\n note.amount,\n inputOwnerHash,\n note.blinding,\n note.origin,\n note.token,\n )\n\n const storedCommitment = BigInt(note.commitment)\n if (localInputCommitment !== storedCommitment) {\n console.error(`[buildUPPTransferCircuitInputs] COMMITMENT MISMATCH`)\n console.error(` amount: ${note.amount}, ownerHash: ${inputOwnerHash}`)\n console.error(` blinding: ${note.blinding}, origin: ${note.origin}, token: ${note.token}`)\n console.error(` local=${localInputCommitment}, stored=${storedCommitment}`)\n throw new Error(\n `Note commitment mismatch — this note was created with an outdated commitment formula. ` +\n `Clear your shielded account (localStorage) and re-shield tokens.`\n )\n }\n\n const nullifier = await computeNullifier(\n BigInt(note.ownerSecret),\n proof.leafIndex,\n BigInt(note.commitment)\n )\n\n return {\n // Public inputs\n stateRoot: String(proof.root),\n aspRoot: String(aspProof.aspRoot),\n nullifier: String(nullifier),\n outputCommitment1: String(recipientNote.commitment),\n outputCommitment2: String(changeNote.commitment),\n token: String(note.token),\n\n // Private inputs - Input Note\n inputAmount: String(note.amount),\n inputOneTimeSecret: String(BigInt(note.ownerSecret)),\n inputBlinding: String(note.blinding),\n inputOrigin: String(note.origin),\n inputLeafIndex: String(proof.leafIndex),\n inputPathElements: padToStateTreeDepth(proof.pathElements.map((e) => String(e)), '0'),\n inputPathIndices: padToStateTreeDepth(proof.pathIndices.map(String), '0'),\n\n // Private inputs - ASP Membership Proof\n aspPathElements: padToASPTreeDepth(aspProof.aspPathElements.map((e) => String(e)), '0'),\n aspPathIndices: padToASPTreeDepth(aspProof.aspPathIndices.map(String), '0'),\n\n // Private inputs - Output Notes (hash-based ownership)\n outputAmount1: String(recipientNote.amount),\n outputOwnerHash1: String(recipientNote.ownerHash),\n outputBlinding1: String(recipientNote.blinding),\n\n outputAmount2: String(changeNote.amount),\n outputOwnerHash2: String(changeNote.ownerHash),\n outputBlinding2: String(changeNote.blinding),\n }\n}\n\n// ============================================================================\n// Withdraw Circuit Input Building\n// ============================================================================\n\nimport type { UPPWithdrawCircuitInputs } from './proof.js'\nimport { padToDepth } from './note-packing.js'\n\n/**\n * Parameters for building withdraw circuit inputs\n */\nexport interface BuildWithdrawInputsParams {\n /** The note being spent */\n selectedNote: SpendableNote\n /** Merkle proof for the note in the state tree */\n merkleProof: MerkleProof\n /** Public recipient address as bigint */\n recipient: bigint\n /** Token address as bigint */\n tokenAddress: bigint\n /** ASP root (0 for ragequit) */\n aspRoot: bigint\n /** ASP Merkle proof path elements (undefined for ragequit) */\n aspPathElements?: bigint[]\n /** ASP Merkle proof path indices (undefined for ragequit) */\n aspPathIndices?: number[]\n /** Whether this is a ragequit withdrawal */\n isRagequit: boolean\n}\n\n/**\n * Build withdraw circuit inputs from a note and its Merkle proof.\n *\n * Pure function extracted from useWithdraw hook for testability.\n * Verifies commitment integrity, computes nullifier, pads Merkle paths,\n * and constructs the exact signal layout expected by withdraw.circom.\n */\nexport async function buildWithdrawCircuitInputs(\n params: BuildWithdrawInputsParams,\n): Promise<UPPWithdrawCircuitInputs> {\n const {\n selectedNote,\n merkleProof,\n recipient,\n tokenAddress,\n aspRoot,\n aspPathElements,\n aspPathIndices,\n isRagequit,\n } = params\n\n // Use the ACTUAL leafIndex from the Merkle proof, not the stored one\n const actualLeafIndex = merkleProof.leafIndex\n\n // Verify commitment matches current formula before building proof\n const inputOwnerHash = poseidonOwnerHash(BigInt(selectedNote.ownerSecret))\n const localCommitment = computeNoteCommitment(\n selectedNote.amount,\n inputOwnerHash,\n selectedNote.blinding,\n selectedNote.origin,\n selectedNote.token,\n )\n const storedCommitment = BigInt(selectedNote.commitment)\n if (localCommitment !== storedCommitment) {\n throw new Error(\n `Note commitment mismatch — this note was created with an outdated commitment formula. ` +\n `Clear your shielded account (localStorage) and re-shield tokens.`\n )\n }\n\n // Compute nullifier: Poseidon(ownerSecret, leafIndex, commitment)\n const nullifier = await poseidon([\n BigInt(selectedNote.ownerSecret),\n BigInt(actualLeafIndex),\n storedCommitment,\n ])\n\n return {\n // Public inputs\n stateRoot: merkleProof.root.toString(),\n aspRoot: aspRoot.toString(),\n nullifier: nullifier.toString(),\n amount: selectedNote.amount.toString(),\n recipient: recipient.toString(),\n token: tokenAddress.toString(),\n isRagequit: isRagequit ? '1' : '0',\n\n // Private inputs - Input Note\n inputAmount: selectedNote.amount.toString(),\n inputOneTimeSecret: BigInt(selectedNote.ownerSecret).toString(),\n inputBlinding: selectedNote.blinding.toString(),\n inputOrigin: selectedNote.origin.toString(),\n inputLeafIndex: actualLeafIndex.toString(),\n inputPathElements: padToDepth(merkleProof.pathElements.map(String), '0', STATE_TREE_DEPTH),\n inputPathIndices: padToDepth(merkleProof.pathIndices.map(String), '0', STATE_TREE_DEPTH),\n\n // ASP membership proof — use real proof data when available, zeros for ragequit\n aspPathElements: aspPathElements\n ? padToDepth(aspPathElements.map(String), '0', ASP_TREE_DEPTH)\n : Array(ASP_TREE_DEPTH).fill('0'),\n aspPathIndices: aspPathIndices\n ? padToDepth(aspPathIndices.map(String), '0', ASP_TREE_DEPTH)\n : Array(ASP_TREE_DEPTH).fill('0'),\n }\n}\n\n// ============================================================================\n// Transfer Building\n// ============================================================================\n\nimport { DEMO_ASP_ID } from './asp.js'\n\n/**\n * Build a UPP transfer (proof + outputs)\n *\n * This prepares everything needed to submit the transaction.\n * UPP transfer is 1-in-2-out with ASP membership proof.\n *\n * @param ctx - Transfer context\n * @param selectedNote - Note to spend (UPP transfer uses exactly 1 input)\n * @param recipientNote - Output note for recipient\n * @param changeNote - Output note for change\n * @param onStageChange - Optional callback for stage updates\n * @returns Transfer build result with proof and outputs\n */\nexport async function buildTransfer(\n ctx: TransferContext,\n selectedNote: SpendableNote,\n recipientNote: NoteWithAmount,\n changeNote: NoteWithAmount,\n onStageChange?: (stage: TransferStage) => void\n): Promise<TransferBuildResult> {\n // 1. Sync Merkle tree\n onStageChange?.('syncing_merkle')\n const { tree, leaves } = await syncMerkleTree(ctx.publicClient, ctx.contractAddress)\n\n // 2. Get Merkle proof for note\n const noteProofs = await getMerkleProofsForNotes([selectedNote], leaves, tree)\n const noteProof = noteProofs[0]!\n\n // 3. Generate ASP proof for the note's origin\n const aspProof = await generateASPProof(\n ctx.aspId ?? DEMO_ASP_ID,\n selectedNote.origin,\n ctx.aspApprovedOrigins\n )\n\n // 4. Build circuit inputs and generate proof\n onStageChange?.('generating_proof')\n\n const circuitInputs = await buildUPPTransferCircuitInputs(\n noteProof,\n aspProof,\n recipientNote,\n changeNote\n )\n\n const { proof } = await generateUPPProof(\n 'transfer',\n circuitInputs,\n ctx.circuitBaseUrl ?? '/circuits/'\n )\n\n const formattedProof = await formatPlonkProofForContract(proof)\n\n return {\n circuit: 'transfer',\n proof: formattedProof,\n publicSignals: proof.publicSignals,\n stateRoot: BigInt(circuitInputs.stateRoot),\n aspRoot: BigInt(circuitInputs.aspRoot),\n nullifier: BigInt(circuitInputs.nullifier),\n outputCommitment1: BigInt(circuitInputs.outputCommitment1),\n outputCommitment2: BigInt(circuitInputs.outputCommitment2),\n token: BigInt(circuitInputs.token),\n recipientOutput: recipientNote,\n changeOutput: changeNote,\n spentNotes: [selectedNote],\n }\n}\n\n/**\n * Format output for contract call (post-quantum)\n */\nexport function formatOutputForContract(note: NoteCreationResult): {\n commitment: Hex\n searchTag: bigint\n ownerHash: bigint\n encryptedNote: Hex\n} {\n return {\n commitment: toHex(note.commitment, { size: 32 }),\n searchTag: note.searchTag,\n ownerHash: note.ownerHash,\n encryptedNote: note.encryptedNote as Hex,\n }\n}\n","/**\n * Note packing utilities — shared helpers for on-chain note data encoding\n *\n * Used by shield, transfer, and swap operations to pack encrypted note data\n * into the format expected by the UPP smart contracts.\n */\n\nimport { encodePacked, type Hex } from 'viem'\nimport type { NoteCreationResult } from './note-crypto.js'\n\n/**\n * Pack note data into bytes for on-chain storage (post-quantum format)\n *\n * Format: searchTag (8 bytes) + ownerHash (32 bytes) + encryptedNote (variable)\n * No ephemeral pubkey needed — encryption uses viewing secret directly.\n */\nexport function packNoteData(note: NoteCreationResult): Hex {\n return encodePacked(\n ['uint64', 'uint256', 'bytes'],\n [note.searchTag, note.ownerHash, note.encryptedNote as Hex]\n )\n}\n\n/**\n * Pad an array to a target depth (for Merkle proof paths)\n *\n * Used when building circuit inputs where the proof path must be\n * exactly STATE_TREE_DEPTH or ASP_TREE_DEPTH elements long.\n */\nexport function padToDepth<T>(arr: T[], padValue: T, depth: number): T[] {\n if (arr.length >= depth) return arr.slice(0, depth)\n return [...arr, ...Array(depth - arr.length).fill(padValue)]\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/deployments/31337.json","../src/deployments/11155111.json","../src/deployments/index.ts","../src/core/transfer.ts","../src/core/note-packing.ts"],"names":["__default"],"mappings":"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","file":"chunk-PJBEE2OI.js","sourcesContent":["{\n \"contracts\": {\n \"ASPRegistryHub\": \"0x9708CfDCa7AA4d282888B43f70ff11Fc869431f1\",\n \"UniversalPrivatePool\": \"0x0e6664FcfD0CF1daa3E909d5C1293C2afe27FBac\",\n \"UPPSwapModule\": \"0x55417f64da1770D9edc795Cf9c878a114016C013\"\n },\n \"implementations\": {\n \"ASPRegistryHub\": \"0xdcD8A9D39E4305187A45Bf9208A83233D2654e87\",\n \"UniversalPrivatePool\": \"0xB99A51eFb2fdF83243C383a5CDdF803D8dDFc5ea\",\n \"UPPSwapModule\": \"0xd81a856940FaC8B24875855F26087c532B80BABc\"\n },\n \"verifiers\": {\n \"Transfer\": \"0x9b79ea6d519Ac317A6D360Ec45D04FB03cDb5965\",\n \"Merge\": \"0x4f296AC081C3d218211E8537f417506888F96b9B\",\n \"Withdraw\": \"0x85Cbcd93Ff1926cFd1b24586Cd8DF1a1D01B8e06\",\n \"JoinSplit\": \"0xd924ff7E01dAC1077A4FF90301D37d46A7Cd2388\",\n \"MergeTransfer2x2\": \"0x90Ec10bFdf69697961A895cE8A5Ae3d1012A2211\",\n \"MergeTransfer4x2\": \"0x0E2db3122000406f143c424b4e749b331b35E370\"\n },\n \"starkVerifiers\": {\n \"WithdrawVerifier\": \"0x85554083b691219C1F2556bA52D4fDEe5d76a01f\",\n \"TransferVerifier\": \"0x2a88C3373cD7D7CAc90420515614d5C43777A00c\"\n },\n \"testTokens\": {\n \"TestStableToken\": \"0x45e6D4230064F9dd806330dA9D92639f8665D9bf\",\n \"TestStableToken2\": \"0xCC8eFf4Ad952dE82990264D5ADB32Fc9399ECb64\"\n },\n \"metadata\": {\n \"chainId\": 31337,\n \"deployBlock\": 10631967,\n \"deployTimestamp\": 1775847275,\n \"deployer\": \"0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266\"\n }\n}","{\n \"contracts\": {\n \"ASPRegistryHub\": \"0xA85d9766C794B97d1463Ba6D5734a27C65A958Da\",\n \"UniversalPrivatePool\": \"0xD493b0651C285a60cae3c45035D0Fd58AC274BC9\",\n \"UPPSwapModule\": \"0x5a626e9b119A6f8DF1Dcc161F5b95Da9F93dB963\"\n },\n \"implementations\": {\n \"ASPRegistryHub\": \"0xdcD8A9D39E4305187A45Bf9208A83233D2654e87\",\n \"UniversalPrivatePool\": \"0xB99A51eFb2fdF83243C383a5CDdF803D8dDFc5ea\",\n \"UPPSwapModule\": \"0xd81a856940FaC8B24875855F26087c532B80BABc\"\n },\n \"verifiers\": {\n \"Transfer\": \"0x3755b4fA8Ee882311aB8FaB8Fd5BFecc355fF35B\",\n \"Merge\": \"0xE115B76eAff5Ba63F8018c182BF7824af7fC7431\",\n \"Withdraw\": \"0xB7FC84975066493fD3962c3c79e4c073BeaD090a\",\n \"JoinSplit\": \"0xFF2c3c620C6047da8d53e137C573E4738D2005e0\",\n \"MergeTransfer2x2\": \"0x347301A2DC42Cbf1386509f716a24d677D8599c8\",\n \"MergeTransfer4x2\": \"0x7F5cc8a714Ae9461B95EFDcaA85494F4251ebc0F\"\n },\n \"starkVerifiers\": {\n \"WithdrawVerifier\": \"0xB8C307D74dAeBe816839BB891b16aCfc01253241\",\n \"TransferVerifier\": \"0x172960000Eed4A280Ac6cAecD318aBF2E0517734\"\n },\n \"testTokens\": {\n \"TestStableToken\": \"0x8369F7dBdd1835410d421D1dD732346106ebc872\",\n \"TestStableToken2\": \"0xE721b1746be10C5D751a6cc44748F00654630Cb7\"\n },\n \"metadata\": {\n \"chainId\": 11155111,\n \"deployBlock\": 10560423,\n \"deployTimestamp\": 1774958844,\n \"deployer\": \"0xdEadDEADb916b00D02f4f2db062Fb2C47fe0689b\"\n }\n}","/**\n * Deployment Configuration Loader\n *\n * Loads contract addresses based on chain ID.\n * Built-in: Anvil (31337) and Sepolia (11155111).\n * Custom chains can be registered at runtime via registerDeployment().\n */\n\nimport type { Address } from \"viem\";\n\n/**\n * Verifier contract addresses\n */\nexport interface VerifierAddresses {\n Transfer: Address;\n Merge: Address;\n Withdraw: Address;\n JoinSplit?: Address;\n MergeTransfer2x2?: Address;\n MergeTransfer4x2?: Address;\n /** @deprecated Use `Transfer` */\n TransferVerifier?: Address;\n /** @deprecated Use `Merge` */\n MergeVerifier?: Address;\n /** @deprecated Use `Withdraw` */\n WithdrawVerifier?: Address;\n}\n\n/**\n * STARK verifier contract addresses\n */\nexport interface StarkVerifierAddresses {\n CircleStarkVerifier?: Address;\n}\n\n/**\n * Implementation addresses for UUPS proxies (for upgrade verification)\n */\nexport interface ImplementationAddresses {\n UniversalPrivatePool?: Address;\n ASPRegistryHub?: Address;\n UPPSwapModule?: Address;\n}\n\n/**\n * Deployment configuration for a chain\n */\nexport interface DeploymentConfig {\n /** Universal Private Pool contract address (proxy) */\n UniversalPrivatePool: Address;\n /** ASP Registry Hub contract address (proxy) */\n ASPRegistryHub: Address;\n /** UPP Swap Module contract address (proxy) */\n UPPSwapModule?: Address;\n /** Implementation addresses for UUPS proxies */\n implementations?: ImplementationAddresses;\n /** Test token address (local/testnet) */\n TestToken?: Address;\n /** Test token 2 address — bonding curve token (local/testnet) */\n TestToken2?: Address;\n /** Verifier contract addresses */\n verifiers: VerifierAddresses;\n /** STARK verifier contract addresses */\n starkVerifiers?: StarkVerifierAddresses;\n /** Chain ID */\n chainId: number;\n /** Block number when contracts were deployed (for efficient scanning) */\n deployBlock: number;\n /** Timestamp when contracts were deployed */\n deployTimestamp?: number;\n}\n\n/**\n * Raw JSON file format (without chainId, which is added dynamically)\n */\ninterface DeploymentJSON {\n contracts?: {\n UniversalPrivatePool?: string;\n ASPRegistryHub?: string;\n UPPSwapModule?: string;\n };\n implementations?: {\n UniversalPrivatePool?: string;\n ASPRegistryHub?: string;\n UPPSwapModule?: string;\n };\n testTokens?: {\n TestStableToken?: string;\n TestStableToken2?: string;\n };\n verifiers?: {\n Transfer?: string;\n Merge?: string;\n Withdraw?: string;\n JoinSplit?: string;\n MergeTransfer2x2?: string;\n MergeTransfer4x2?: string;\n TransferVerifier?: string;\n MergeVerifier?: string;\n WithdrawVerifier?: string;\n JoinSplitVerifier?: string;\n MergeTransfer2x2Verifier?: string;\n MergeTransfer4x2Verifier?: string;\n };\n starkVerifiers?: {\n CircleStarkVerifier?: string;\n WithdrawVerifier?: string;\n TransferVerifier?: string;\n };\n metadata?: {\n chainId?: number;\n deployBlock?: number;\n deployTimestamp?: number;\n };\n}\n\n/**\n * Parse raw deployment JSON into typed config\n */\nfunction parseDeployment(\n json: DeploymentJSON,\n chainId: number\n): DeploymentConfig {\n const contracts = json.contracts || {};\n const verifs = json.verifiers || {};\n const testTokens = json.testTokens || {};\n\n return {\n UniversalPrivatePool: contracts.UniversalPrivatePool as Address,\n ASPRegistryHub: contracts.ASPRegistryHub as Address,\n UPPSwapModule: contracts.UPPSwapModule as Address | undefined,\n implementations: json.implementations\n ? {\n UniversalPrivatePool: json.implementations.UniversalPrivatePool as Address | undefined,\n ASPRegistryHub: json.implementations.ASPRegistryHub as Address | undefined,\n UPPSwapModule: json.implementations.UPPSwapModule as Address | undefined,\n }\n : undefined,\n TestToken: testTokens.TestStableToken as Address | undefined,\n TestToken2: testTokens.TestStableToken2 as Address | undefined,\n verifiers: {\n Transfer: (verifs.Transfer || verifs.TransferVerifier) as Address,\n Merge: (verifs.Merge || verifs.MergeVerifier) as Address,\n Withdraw: (verifs.Withdraw || verifs.WithdrawVerifier) as Address,\n JoinSplit: (verifs.JoinSplit || verifs.JoinSplitVerifier) as Address | undefined,\n MergeTransfer2x2: (verifs.MergeTransfer2x2 || verifs.MergeTransfer2x2Verifier) as Address | undefined,\n MergeTransfer4x2: (verifs.MergeTransfer4x2 || verifs.MergeTransfer4x2Verifier) as Address | undefined,\n },\n starkVerifiers: json.starkVerifiers\n ? {\n CircleStarkVerifier: json.starkVerifiers.CircleStarkVerifier as Address | undefined,\n }\n : undefined,\n chainId,\n deployBlock: json.metadata?.deployBlock ?? 0,\n deployTimestamp: json.metadata?.deployTimestamp,\n };\n}\n\n// Import deployment configs\n// These will be updated by the extract-deployment.js script\nimport anvil from \"./31337.json\" with { type: \"json\" };\nimport sepolia from \"./11155111.json\" with { type: \"json\" };\n\nconst deployments: Record<number, DeploymentConfig> = {\n 31337: parseDeployment(anvil as unknown as DeploymentJSON, 31337),\n 11155111: parseDeployment(sepolia as unknown as DeploymentJSON, 11155111),\n};\n\n/**\n * Get deployment config for a chain\n *\n * @param chainId - Chain ID to get deployment for\n * @returns Deployment config or null if not found\n *\n * @example\n * ```ts\n * const deployment = getDeployment(31337)\n * if (deployment) {\n * console.log('Pool address:', deployment.UniversalPrivatePool)\n * }\n * ```\n */\nexport function getDeployment(chainId: number): DeploymentConfig | null {\n return deployments[chainId] ?? null;\n}\n\n/**\n * Get deployment config or throw if not found\n *\n * @param chainId - Chain ID to get deployment for\n * @returns Deployment config\n * @throws Error if deployment not found\n */\nexport function getDeploymentOrThrow(chainId: number): DeploymentConfig {\n const deployment = getDeployment(chainId);\n if (!deployment) {\n throw new Error(\n `No deployment found for chain ${chainId}. ` +\n `Supported chains: ${Object.keys(deployments).join(\", \")}`\n );\n }\n return deployment;\n}\n\n/**\n * Check if a chain has a deployment\n */\nexport function hasDeployment(chainId: number): boolean {\n return chainId in deployments;\n}\n\n/**\n * Get all supported chain IDs\n */\nexport function getSupportedChainIds(): number[] {\n return Object.keys(deployments).map(Number);\n}\n\n/**\n * Get the token address for a chain\n */\nexport function getTokenAddress(chainId: number): Address | null {\n const deployment = getDeployment(chainId);\n if (!deployment) return null;\n return deployment.TestToken ?? null;\n}\n\n/**\n * Register a deployment for a custom chain at runtime.\n *\n * Use this when deploying your own pool on a chain not built into the SDK.\n * Overrides any existing deployment for the same chainId.\n *\n * @example\n * ```ts\n * registerDeployment(8453, {\n * UniversalPrivatePool: '0x...',\n * ASPRegistryHub: '0x...',\n * verifiers: { Transfer: '0x...', Merge: '0x...', Withdraw: '0x...' },\n * chainId: 8453,\n * deployBlock: 12345678,\n * })\n * ```\n */\nexport function registerDeployment(chainId: number, config: DeploymentConfig): void {\n deployments[chainId] = { ...config, chainId };\n}\n","/**\n * Transfer Module\n *\n * Core logic for building and executing UPP transfers.\n * This module is framework-agnostic (no React).\n */\n\nimport { toHex, type Address, type Hex, type PublicClient } from 'viem'\nimport { getDeployment } from '../deployments/index.js'\nimport { buildMerkleTree, type MerkleProof } from '../utils/merkle.js'\nimport { poseidon, computeOwnerHash as poseidonOwnerHash, computeNoteCommitment } from '../utils/poseidon.js'\nimport {\n generateUPPProof,\n formatPlonkProofForContract,\n STATE_TREE_DEPTH,\n ASP_TREE_DEPTH,\n type UPPCircuitType,\n type UPPTransferCircuitInputs,\n type PlonkProofStruct,\n} from './proof.js'\nimport { generateASPProof, type ASPProof } from './asp.js'\nimport type { NoteCreationResult } from '../react/use-upp-account.js'\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Transfer stage for progress tracking\n */\nexport type TransferStage =\n | 'selecting_notes'\n | 'syncing_merkle'\n | 'creating_outputs'\n | 'generating_proof'\n | 'submitting_tx'\n | 'confirming'\n\n/**\n * A shielded note with all data needed for spending\n *\n * Post-quantum: uses ownerSecret/ownerHash instead of BabyJubJub one-time keys.\n * Ownership is proven via hash preimage: Poseidon(ownerSecret) == ownerHash.\n */\nexport interface SpendableNote {\n amount: bigint\n blinding: bigint\n commitment: string\n /** Owner secret (hash preimage for ownership proof) */\n ownerSecret: string\n /** Owner hash = Poseidon(ownerSecret) - committed in the note */\n ownerHash: string\n leafIndex: number\n /** Origin address (depositor) - required for UPP circuits */\n origin: bigint\n /** Token address - required for UPP circuits */\n token: bigint\n}\n\n/**\n * Merkle proof with associated note\n */\nexport interface MerkleProofWithNote {\n proof: MerkleProof\n note: SpendableNote\n}\n\n/**\n * Transfer context (dependencies)\n */\nexport interface TransferContext {\n /** viem PublicClient for RPC calls */\n publicClient: PublicClient\n /** Contract address */\n contractAddress: Address\n /** Chain ID */\n chainId: number\n /** Circuit base URL (default: '/circuits/') */\n circuitBaseUrl?: string\n /** ASP ID to use (default: DEMO_ASP_ID) */\n aspId?: bigint\n /** All approved origins in the ASP tree (enables multi-origin proofs) */\n aspApprovedOrigins?: bigint[]\n}\n\n/**\n * Transfer result\n */\nexport interface TransferBuildResult {\n /** Circuit type used */\n circuit: UPPCircuitType\n /** Formatted PLONK proof for contract */\n proof: {\n proofStruct: PlonkProofStruct\n publicSignals: bigint[]\n }\n /** Public signals from proof */\n publicSignals: string[]\n /** State tree root */\n stateRoot: bigint\n /** ASP tree root */\n aspRoot: bigint\n /** Nullifier hash */\n nullifier: bigint\n /** Output commitment 1 */\n outputCommitment1: bigint\n /** Output commitment 2 */\n outputCommitment2: bigint\n /** Token address */\n token: bigint\n /** Recipient output */\n recipientOutput: NoteCreationResult\n /** Change output */\n changeOutput: NoteCreationResult\n /** Notes that will be spent */\n spentNotes: SpendableNote[]\n}\n\n// ============================================================================\n// Constants\n// ============================================================================\n\n/** Chunk size for paginated RPC queries on testnets */\nconst RPC_CHUNK_SIZE = 9000n\n\n/**\n * Pad an array to the state tree depth (32 levels)\n * @param arr - Array to pad\n * @param padValue - Value to use for padding (default: '0')\n * @returns Padded array of length STATE_TREE_DEPTH\n */\nfunction padToStateTreeDepth<T>(arr: T[], padValue: T): T[] {\n if (arr.length >= STATE_TREE_DEPTH) {\n return arr.slice(0, STATE_TREE_DEPTH)\n }\n return [...arr, ...Array(STATE_TREE_DEPTH - arr.length).fill(padValue)]\n}\n\n/**\n * Pad an array to the ASP tree depth (20 levels)\n * @param arr - Array to pad\n * @param padValue - Value to use for padding (default: '0')\n * @returns Padded array of length ASP_TREE_DEPTH\n */\nfunction padToASPTreeDepth<T>(arr: T[], padValue: T): T[] {\n if (arr.length >= ASP_TREE_DEPTH) {\n return arr.slice(0, ASP_TREE_DEPTH)\n }\n return [...arr, ...Array(ASP_TREE_DEPTH - arr.length).fill(padValue)]\n}\n\n/**\n * CommitmentInserted event — emitted by _insertLeaf() for ALL leaf insertions\n * (shield, transfer, merge, swap fill, swap claim, swap cancel).\n * This is the single canonical event for Merkle tree reconstruction.\n */\nconst COMMITMENT_INSERTED_EVENT = {\n type: 'event' as const,\n name: 'CommitmentInserted',\n inputs: [\n { type: 'bytes32', name: 'commitment', indexed: true },\n { type: 'uint256', name: 'leafIndex' },\n { type: 'uint256', name: 'timestamp' },\n ],\n}\n\n// ============================================================================\n// Merkle Tree Functions\n// ============================================================================\n\n/**\n * Fetch all commitments from the contract and build a Merkle tree\n *\n * @param publicClient - viem PublicClient\n * @param contractAddress - Contract address\n * @returns Object with tree and leaves array\n */\nexport async function syncMerkleTree(\n publicClient: PublicClient,\n contractAddress: Address\n): Promise<{ tree: ReturnType<typeof buildMerkleTree>; leaves: bigint[] }> {\n const currentBlock = await publicClient.getBlockNumber()\n const chainId = await publicClient.getChainId()\n\n // Use CommitmentInserted events — the canonical event emitted by _insertLeaf()\n // for ALL operations (shield, transfer, merge, swap fill/claim/cancel).\n // Each event has an explicit leafIndex, so ordering is deterministic.\n let commitmentLogs: any[] = []\n\n if (chainId === 31337) {\n // Anvil - single query is fine\n commitmentLogs = await publicClient.getLogs({\n address: contractAddress,\n event: COMMITMENT_INSERTED_EVENT,\n fromBlock: 0n,\n })\n } else {\n // Testnet/mainnet - paginate to avoid RPC limits\n const deployment = getDeployment(chainId)\n let fromBlock = deployment?.deployBlock ? BigInt(deployment.deployBlock) : 0n\n console.log(`[syncMerkleTree] Chain ${chainId}: scanning from block ${fromBlock} to ${currentBlock}`)\n\n while (fromBlock <= currentBlock) {\n const toBlock =\n fromBlock + RPC_CHUNK_SIZE > currentBlock ? currentBlock : fromBlock + RPC_CHUNK_SIZE\n const chunk = await publicClient.getLogs({\n address: contractAddress,\n event: COMMITMENT_INSERTED_EVENT,\n fromBlock,\n toBlock,\n })\n commitmentLogs = commitmentLogs.concat(chunk)\n fromBlock = toBlock + 1n\n }\n }\n\n // Sort by explicit leafIndex (most reliable), falling back to block+logIndex\n commitmentLogs.sort((a: any, b: any) => {\n const idxA = Number(a.args.leafIndex!)\n const idxB = Number(b.args.leafIndex!)\n return idxA - idxB\n })\n\n // Build leaves array using the explicit leafIndex from each event\n const leaves: bigint[] = []\n for (const log of commitmentLogs) {\n const leafIndex = Number(log.args.leafIndex!)\n const commitment = BigInt(log.args.commitment!)\n\n if (leaves.length !== leafIndex) {\n console.warn(\n `[syncMerkleTree] WARNING: Expected leafIndex ${leaves.length} but event has ${leafIndex}. ` +\n `This may indicate missed events or reorg.`\n )\n }\n leaves.push(commitment)\n }\n\n const tree = buildMerkleTree(leaves)\n\n // Debug: compare our root with on-chain root\n const ourRoot = await tree.getRoot()\n const onChainRoot = (await publicClient.readContract({\n address: contractAddress,\n abi: [\n {\n type: 'function',\n name: 'getMerkleRoot',\n inputs: [],\n outputs: [{ type: 'uint256' }],\n stateMutability: 'view',\n },\n ],\n functionName: 'getMerkleRoot',\n })) as bigint\n\n console.log(`[syncMerkleTree] Leaves count: ${leaves.length}`)\n console.log(`[syncMerkleTree] Tree depth: ${tree.depth}`)\n console.log(`[syncMerkleTree] Our computed root: ${ourRoot}`)\n console.log(`[syncMerkleTree] On-chain root: ${onChainRoot}`)\n console.log(`[syncMerkleTree] Roots match: ${ourRoot === onChainRoot}`)\n\n if (ourRoot !== onChainRoot) {\n console.log(`[syncMerkleTree] WARNING: Root mismatch!`)\n console.log(\n `[syncMerkleTree] Leaves:`,\n leaves.map((l) => '0x' + l.toString(16))\n )\n }\n\n return { tree, leaves }\n}\n\n/**\n * Get Merkle proofs for a set of notes\n *\n * @param notes - Notes to get proofs for\n * @param leaves - All leaves in the tree\n * @param tree - Merkle tree instance\n * @returns Array of proofs with associated notes\n */\nexport async function getMerkleProofsForNotes(\n notes: SpendableNote[],\n leaves: bigint[],\n tree: ReturnType<typeof buildMerkleTree>\n): Promise<MerkleProofWithNote[]> {\n const { verifyMerkleProof } = await import('../utils/merkle.js')\n const proofs: MerkleProofWithNote[] = []\n\n for (const note of notes) {\n const commitmentBI = BigInt(note.commitment)\n const leafIndex = leaves.findIndex((l) => l === commitmentBI)\n\n console.log(`[getMerkleProofsForNotes] Note commitment: ${note.commitment}`)\n console.log(`[getMerkleProofsForNotes] Note commitment as BigInt: ${commitmentBI}`)\n console.log(`[getMerkleProofsForNotes] Found at leafIndex: ${leafIndex}`)\n console.log(`[getMerkleProofsForNotes] Note's stored leafIndex: ${note.leafIndex}`)\n\n if (leafIndex === -1) {\n console.log(`[getMerkleProofsForNotes] Leaves in tree:`, leaves.map((l) => l.toString()))\n throw new Error(`Note ${note.commitment.slice(0, 10)}... not found on-chain`)\n }\n\n const proof = await tree.getProof(leafIndex)\n\n console.log(`[getMerkleProofsForNotes] Proof root: ${proof.root}`)\n console.log(`[getMerkleProofsForNotes] Proof leafIndex: ${proof.leafIndex}`)\n console.log(`[getMerkleProofsForNotes] PathElements:`, proof.pathElements.map((e) => e.toString()))\n console.log(`[getMerkleProofsForNotes] PathIndices:`, proof.pathIndices)\n\n // Verify the proof locally before returning\n const isValid = await verifyMerkleProof(commitmentBI, proof)\n console.log(`[getMerkleProofsForNotes] Local proof verification: ${isValid}`)\n\n if (!isValid) {\n console.error(`[getMerkleProofsForNotes] WARNING: Merkle proof is invalid!`)\n }\n\n proofs.push({ proof, note: { ...note, leafIndex } })\n }\n\n return proofs\n}\n\n// ============================================================================\n// Circuit Input Building\n// ============================================================================\n\n/**\n * Compute nullifier for a UPP note (BLS12-381)\n *\n * nullifier = Poseidon(ownerSecret, leafIndex, commitment)\n *\n * @param ownerSecret - Owner secret (hash preimage)\n * @param leafIndex - Leaf index in Merkle tree\n * @param commitment - Note commitment\n * @returns Nullifier as bigint\n */\nexport async function computeNullifier(\n ownerSecret: bigint,\n leafIndex: number,\n commitment: bigint\n): Promise<bigint> {\n return await poseidon([ownerSecret, BigInt(leafIndex), commitment])\n}\n\n/**\n * Note with amount for circuit building\n */\nexport interface NoteWithAmount extends NoteCreationResult {\n amount: bigint\n}\n\n/**\n * Build circuit inputs for UPP transfer (1-in-2-out)\n *\n * @param noteProof - Merkle proof for input note\n * @param aspProof - ASP membership proof for input note's origin\n * @param recipientNote - Output note for recipient\n * @param changeNote - Output note for change\n * @returns UPP transfer circuit inputs\n */\nexport async function buildUPPTransferCircuitInputs(\n noteProof: MerkleProofWithNote,\n aspProof: ASPProof,\n recipientNote: NoteWithAmount,\n changeNote: NoteWithAmount\n): Promise<UPPTransferCircuitInputs> {\n const { proof, note } = noteProof\n\n // Compute owner hash from secret (hash-based ownership)\n const inputOwnerHash = poseidonOwnerHash(BigInt(note.ownerSecret))\n\n // Verify input commitment locally\n // BLS12-381 commitment: Poseidon(amount, ownerHash, blinding, origin, token)\n const localInputCommitment = computeNoteCommitment(\n note.amount,\n inputOwnerHash,\n note.blinding,\n note.origin,\n note.token,\n )\n\n const storedCommitment = BigInt(note.commitment)\n if (localInputCommitment !== storedCommitment) {\n console.error(`[buildUPPTransferCircuitInputs] COMMITMENT MISMATCH`)\n console.error(` amount: ${note.amount}, ownerHash: ${inputOwnerHash}`)\n console.error(` blinding: ${note.blinding}, origin: ${note.origin}, token: ${note.token}`)\n console.error(` local=${localInputCommitment}, stored=${storedCommitment}`)\n throw new Error(\n `Note commitment mismatch — this note was created with an outdated commitment formula. ` +\n `Clear your shielded account (localStorage) and re-shield tokens.`\n )\n }\n\n const nullifier = await computeNullifier(\n BigInt(note.ownerSecret),\n proof.leafIndex,\n BigInt(note.commitment)\n )\n\n return {\n // Public inputs\n stateRoot: String(proof.root),\n aspRoot: String(aspProof.aspRoot),\n nullifier: String(nullifier),\n outputCommitment1: String(recipientNote.commitment),\n outputCommitment2: String(changeNote.commitment),\n token: String(note.token),\n\n // Private inputs - Input Note\n inputAmount: String(note.amount),\n inputOneTimeSecret: String(BigInt(note.ownerSecret)),\n inputBlinding: String(note.blinding),\n inputOrigin: String(note.origin),\n inputLeafIndex: String(proof.leafIndex),\n inputPathElements: padToStateTreeDepth(proof.pathElements.map((e) => String(e)), '0'),\n inputPathIndices: padToStateTreeDepth(proof.pathIndices.map(String), '0'),\n\n // Private inputs - ASP Membership Proof\n aspPathElements: padToASPTreeDepth(aspProof.aspPathElements.map((e) => String(e)), '0'),\n aspPathIndices: padToASPTreeDepth(aspProof.aspPathIndices.map(String), '0'),\n\n // Private inputs - Output Notes (hash-based ownership)\n outputAmount1: String(recipientNote.amount),\n outputOwnerHash1: String(recipientNote.ownerHash),\n outputBlinding1: String(recipientNote.blinding),\n\n outputAmount2: String(changeNote.amount),\n outputOwnerHash2: String(changeNote.ownerHash),\n outputBlinding2: String(changeNote.blinding),\n }\n}\n\n// ============================================================================\n// Withdraw Circuit Input Building\n// ============================================================================\n\nimport type { UPPWithdrawCircuitInputs } from './proof.js'\nimport { padToDepth } from './note-packing.js'\n\n/**\n * Parameters for building withdraw circuit inputs\n */\nexport interface BuildWithdrawInputsParams {\n /** The note being spent */\n selectedNote: SpendableNote\n /** Merkle proof for the note in the state tree */\n merkleProof: MerkleProof\n /** Public recipient address as bigint */\n recipient: bigint\n /** Token address as bigint */\n tokenAddress: bigint\n /** ASP root (0 for ragequit) */\n aspRoot: bigint\n /** ASP Merkle proof path elements (undefined for ragequit) */\n aspPathElements?: bigint[]\n /** ASP Merkle proof path indices (undefined for ragequit) */\n aspPathIndices?: number[]\n /** Whether this is a ragequit withdrawal */\n isRagequit: boolean\n}\n\n/**\n * Build withdraw circuit inputs from a note and its Merkle proof.\n *\n * Pure function extracted from useWithdraw hook for testability.\n * Verifies commitment integrity, computes nullifier, pads Merkle paths,\n * and constructs the exact signal layout expected by withdraw.circom.\n */\nexport async function buildWithdrawCircuitInputs(\n params: BuildWithdrawInputsParams,\n): Promise<UPPWithdrawCircuitInputs> {\n const {\n selectedNote,\n merkleProof,\n recipient,\n tokenAddress,\n aspRoot,\n aspPathElements,\n aspPathIndices,\n isRagequit,\n } = params\n\n // Use the ACTUAL leafIndex from the Merkle proof, not the stored one\n const actualLeafIndex = merkleProof.leafIndex\n\n // Verify commitment matches current formula before building proof\n const inputOwnerHash = poseidonOwnerHash(BigInt(selectedNote.ownerSecret))\n const localCommitment = computeNoteCommitment(\n selectedNote.amount,\n inputOwnerHash,\n selectedNote.blinding,\n selectedNote.origin,\n selectedNote.token,\n )\n const storedCommitment = BigInt(selectedNote.commitment)\n if (localCommitment !== storedCommitment) {\n throw new Error(\n `Note commitment mismatch — this note was created with an outdated commitment formula. ` +\n `Clear your shielded account (localStorage) and re-shield tokens.`\n )\n }\n\n // Compute nullifier: Poseidon(ownerSecret, leafIndex, commitment)\n const nullifier = await poseidon([\n BigInt(selectedNote.ownerSecret),\n BigInt(actualLeafIndex),\n storedCommitment,\n ])\n\n return {\n // Public inputs\n stateRoot: merkleProof.root.toString(),\n aspRoot: aspRoot.toString(),\n nullifier: nullifier.toString(),\n amount: selectedNote.amount.toString(),\n recipient: recipient.toString(),\n token: tokenAddress.toString(),\n isRagequit: isRagequit ? '1' : '0',\n\n // Private inputs - Input Note\n inputAmount: selectedNote.amount.toString(),\n inputOneTimeSecret: BigInt(selectedNote.ownerSecret).toString(),\n inputBlinding: selectedNote.blinding.toString(),\n inputOrigin: selectedNote.origin.toString(),\n inputLeafIndex: actualLeafIndex.toString(),\n inputPathElements: padToDepth(merkleProof.pathElements.map(String), '0', STATE_TREE_DEPTH),\n inputPathIndices: padToDepth(merkleProof.pathIndices.map(String), '0', STATE_TREE_DEPTH),\n\n // ASP membership proof — use real proof data when available, zeros for ragequit\n aspPathElements: aspPathElements\n ? padToDepth(aspPathElements.map(String), '0', ASP_TREE_DEPTH)\n : Array(ASP_TREE_DEPTH).fill('0'),\n aspPathIndices: aspPathIndices\n ? padToDepth(aspPathIndices.map(String), '0', ASP_TREE_DEPTH)\n : Array(ASP_TREE_DEPTH).fill('0'),\n }\n}\n\n// ============================================================================\n// Transfer Building\n// ============================================================================\n\nimport { DEMO_ASP_ID } from './asp.js'\n\n/**\n * Build a UPP transfer (proof + outputs)\n *\n * This prepares everything needed to submit the transaction.\n * UPP transfer is 1-in-2-out with ASP membership proof.\n *\n * @param ctx - Transfer context\n * @param selectedNote - Note to spend (UPP transfer uses exactly 1 input)\n * @param recipientNote - Output note for recipient\n * @param changeNote - Output note for change\n * @param onStageChange - Optional callback for stage updates\n * @returns Transfer build result with proof and outputs\n */\nexport async function buildTransfer(\n ctx: TransferContext,\n selectedNote: SpendableNote,\n recipientNote: NoteWithAmount,\n changeNote: NoteWithAmount,\n onStageChange?: (stage: TransferStage) => void\n): Promise<TransferBuildResult> {\n // 1. Sync Merkle tree\n onStageChange?.('syncing_merkle')\n const { tree, leaves } = await syncMerkleTree(ctx.publicClient, ctx.contractAddress)\n\n // 2. Get Merkle proof for note\n const noteProofs = await getMerkleProofsForNotes([selectedNote], leaves, tree)\n const noteProof = noteProofs[0]!\n\n // 3. Generate ASP proof for the note's origin\n const aspProof = await generateASPProof(\n ctx.aspId ?? DEMO_ASP_ID,\n selectedNote.origin,\n ctx.aspApprovedOrigins\n )\n\n // 4. Build circuit inputs and generate proof\n onStageChange?.('generating_proof')\n\n const circuitInputs = await buildUPPTransferCircuitInputs(\n noteProof,\n aspProof,\n recipientNote,\n changeNote\n )\n\n const { proof } = await generateUPPProof(\n 'transfer',\n circuitInputs,\n ctx.circuitBaseUrl ?? '/circuits/'\n )\n\n const formattedProof = await formatPlonkProofForContract(proof)\n\n return {\n circuit: 'transfer',\n proof: formattedProof,\n publicSignals: proof.publicSignals,\n stateRoot: BigInt(circuitInputs.stateRoot),\n aspRoot: BigInt(circuitInputs.aspRoot),\n nullifier: BigInt(circuitInputs.nullifier),\n outputCommitment1: BigInt(circuitInputs.outputCommitment1),\n outputCommitment2: BigInt(circuitInputs.outputCommitment2),\n token: BigInt(circuitInputs.token),\n recipientOutput: recipientNote,\n changeOutput: changeNote,\n spentNotes: [selectedNote],\n }\n}\n\n/**\n * Format output for contract call (post-quantum)\n */\nexport function formatOutputForContract(note: NoteCreationResult): {\n commitment: Hex\n searchTag: bigint\n ownerHash: bigint\n encryptedNote: Hex\n} {\n return {\n commitment: toHex(note.commitment, { size: 32 }),\n searchTag: note.searchTag,\n ownerHash: note.ownerHash,\n encryptedNote: note.encryptedNote as Hex,\n }\n}\n","/**\n * Note packing utilities — shared helpers for on-chain note data encoding\n *\n * Used by shield, transfer, and swap operations to pack encrypted note data\n * into the format expected by the UPP smart contracts.\n */\n\nimport { encodePacked, type Hex } from 'viem'\nimport type { NoteCreationResult } from './note-crypto.js'\n\n/**\n * Pack note data into bytes for on-chain storage (post-quantum format)\n *\n * Format: searchTag (8 bytes) + ownerHash (32 bytes) + encryptedNote (variable)\n * No ephemeral pubkey needed — encryption uses viewing secret directly.\n */\nexport function packNoteData(note: NoteCreationResult): Hex {\n return encodePacked(\n ['uint64', 'uint256', 'bytes'],\n [note.searchTag, note.ownerHash, note.encryptedNote as Hex]\n )\n}\n\n/**\n * Pad an array to a target depth (for Merkle proof paths)\n *\n * Used when building circuit inputs where the proof path must be\n * exactly STATE_TREE_DEPTH or ASP_TREE_DEPTH elements long.\n */\nexport function padToDepth<T>(arr: T[], padValue: T, depth: number): T[] {\n if (arr.length >= depth) return arr.slice(0, depth)\n return [...arr, ...Array(depth - arr.length).fill(padValue)]\n}\n"]}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var chunkXSJ5VVH4_cjs = require('./chunk-XSJ5VVH4.cjs');
|
|
4
|
+
var chunkBCSMUH4L_cjs = require('./chunk-BCSMUH4L.cjs');
|
|
5
|
+
var viem = require('viem');
|
|
6
|
+
|
|
7
|
+
chunkBCSMUH4L_cjs.init_crypto();
|
|
8
|
+
async function derivePerNoteKey(viewingSecret, nonce) {
|
|
9
|
+
const { poseidon } = await import('./poseidon-PUSGUIVZ.cjs');
|
|
10
|
+
const perNoteKey = await poseidon([viewingSecret, nonce]);
|
|
11
|
+
return viem.toHex(perNoteKey, { size: 32 });
|
|
12
|
+
}
|
|
13
|
+
async function derivePerNoteKeyFromKeys(keys, nonce) {
|
|
14
|
+
return derivePerNoteKey(keys.viewingSecret, nonce);
|
|
15
|
+
}
|
|
16
|
+
async function exportViewingKeysForAudit(keys, signerAddress, notes) {
|
|
17
|
+
const viewingKeys = [];
|
|
18
|
+
for (const note of notes) {
|
|
19
|
+
const decryptionKey = await derivePerNoteKey(keys.viewingSecret, note.nonce);
|
|
20
|
+
viewingKeys.push({
|
|
21
|
+
leafIndex: note.leafIndex,
|
|
22
|
+
nonce: note.nonce,
|
|
23
|
+
decryptionKey
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
return {
|
|
27
|
+
version: 4,
|
|
28
|
+
signerAddress,
|
|
29
|
+
viewingHash: keys.viewingHash,
|
|
30
|
+
viewingKeys,
|
|
31
|
+
instructions: `
|
|
32
|
+
This export contains per-note decryption keys for ${viewingKeys.length} UPP note(s).
|
|
33
|
+
|
|
34
|
+
To decrypt a note:
|
|
35
|
+
1. Find the viewingKey entry for the desired leafIndex
|
|
36
|
+
2. Retrieve the encrypted note from the blockchain (Shielded event at that leaf index)
|
|
37
|
+
3. Derive AES key: key = keccak256(decryptionKey)
|
|
38
|
+
4. Decrypt the note ciphertext with AES-GCM
|
|
39
|
+
|
|
40
|
+
These per-note keys ONLY allow decryption of the specified notes.
|
|
41
|
+
They do NOT reveal:
|
|
42
|
+
- The master viewing secret (protected by Poseidon one-wayness)
|
|
43
|
+
- Keys for any other notes
|
|
44
|
+
- The spending secret (cannot spend funds)
|
|
45
|
+
`.trim()
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
function validateAuditKeyExport(exportData) {
|
|
49
|
+
if (exportData.version !== 4) {
|
|
50
|
+
return { valid: false, error: `Unsupported version: ${exportData.version}. Expected version 4.` };
|
|
51
|
+
}
|
|
52
|
+
if (!exportData.signerAddress || !exportData.signerAddress.startsWith("0x")) {
|
|
53
|
+
return { valid: false, error: "Invalid signer address" };
|
|
54
|
+
}
|
|
55
|
+
if (exportData.viewingHash === void 0 || exportData.viewingHash === null) {
|
|
56
|
+
return { valid: false, error: "Missing viewing hash" };
|
|
57
|
+
}
|
|
58
|
+
if (!Array.isArray(exportData.viewingKeys) || exportData.viewingKeys.length === 0) {
|
|
59
|
+
return { valid: false, error: "No viewing keys in export" };
|
|
60
|
+
}
|
|
61
|
+
return { valid: true };
|
|
62
|
+
}
|
|
63
|
+
function getViewingKeyFromExport(exportData, leafIndex) {
|
|
64
|
+
const key = exportData.viewingKeys.find((k) => k.leafIndex === leafIndex);
|
|
65
|
+
return key ? key.decryptionKey : null;
|
|
66
|
+
}
|
|
67
|
+
function deriveStarkPerNoteKey(starkViewingSecret, nonce) {
|
|
68
|
+
const digest = chunkXSJ5VVH4_cjs.keccakM31([...starkViewingSecret, nonce]);
|
|
69
|
+
const bytes = new Uint8Array(16);
|
|
70
|
+
for (let i = 0; i < 4; i++) {
|
|
71
|
+
const val = Number(digest[i]);
|
|
72
|
+
bytes[i * 4] = val & 255;
|
|
73
|
+
bytes[i * 4 + 1] = val >> 8 & 255;
|
|
74
|
+
bytes[i * 4 + 2] = val >> 16 & 255;
|
|
75
|
+
bytes[i * 4 + 3] = val >> 24 & 255;
|
|
76
|
+
}
|
|
77
|
+
return viem.keccak256(chunkBCSMUH4L_cjs.bytesToHex(bytes));
|
|
78
|
+
}
|
|
79
|
+
function deriveStarkPerNoteKeyFromKeys(keys, nonce) {
|
|
80
|
+
return deriveStarkPerNoteKey(keys.starkViewingSecret, nonce);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
exports.derivePerNoteKey = derivePerNoteKey;
|
|
84
|
+
exports.derivePerNoteKeyFromKeys = derivePerNoteKeyFromKeys;
|
|
85
|
+
exports.deriveStarkPerNoteKey = deriveStarkPerNoteKey;
|
|
86
|
+
exports.deriveStarkPerNoteKeyFromKeys = deriveStarkPerNoteKeyFromKeys;
|
|
87
|
+
exports.exportViewingKeysForAudit = exportViewingKeysForAudit;
|
|
88
|
+
exports.getViewingKeyFromExport = getViewingKeyFromExport;
|
|
89
|
+
exports.validateAuditKeyExport = validateAuditKeyExport;
|
|
90
|
+
//# sourceMappingURL=chunk-PXCVNAWP.cjs.map
|
|
91
|
+
//# sourceMappingURL=chunk-PXCVNAWP.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/keys/viewing.ts"],"names":["init_crypto","toHex","keccakM31","keccak256","bytesToHex"],"mappings":"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","file":"chunk-PXCVNAWP.cjs","sourcesContent":["/**\n * Per-Transaction Viewing Key Derivation (Post-Quantum, Hash-Based)\n *\n * Implements hierarchical viewing keys using Poseidon hash instead of ECDH.\n *\n * Key Properties:\n * - Per-note decryption key: Poseidon(viewingSecret, nonce)\n * - AES key: keccak256(perNoteKey) for symmetric encryption\n *\n * Derivation:\n * perNoteKey = Poseidon(viewingSecret, nonce)\n * aesKey = keccak256(perNoteKey)\n *\n * SECURITY (v4):\n * Audit exports contain per-note decryption keys derived from viewingSecret + nonce.\n * This prevents master key recovery: knowing Poseidon(viewingSecret, nonce) doesn't\n * reveal viewingSecret due to the one-wayness of Poseidon.\n */\n\nimport type { Address, Hex } from 'viem'\nimport { keccak256, toHex } from 'viem'\nimport type {\n MasterKeys,\n StarkMasterKeys,\n TransactionViewingKey,\n AuditKeyExport,\n} from './types.js'\nimport { keccakM31, type M31Secret } from '../utils/keccak-m31.js'\nimport { bytesToHex } from '../utils/crypto.js'\n\n/**\n * Derive a per-note decryption key from master viewing secret and nonce\n *\n * @param viewingSecret - Master viewing secret\n * @param nonce - Unique per-note nonce\n * @returns Per-note decryption key as hex\n */\nexport async function derivePerNoteKey(\n viewingSecret: bigint,\n nonce: bigint\n): Promise<Hex> {\n const { poseidon } = await import('../utils/poseidon.js')\n const perNoteKey = await poseidon([viewingSecret, nonce])\n return toHex(perNoteKey, { size: 32 })\n}\n\n/**\n * Derive per-note key from MasterKeys convenience wrapper\n */\nexport async function derivePerNoteKeyFromKeys(\n keys: MasterKeys,\n nonce: bigint\n): Promise<Hex> {\n return derivePerNoteKey(keys.viewingSecret, nonce)\n}\n\n/**\n * Note reference for audit export\n */\nexport interface NoteReference {\n /** The Merkle leaf index (for locating the on-chain event) */\n leafIndex: number\n /** The nonce used in per-note key derivation */\n nonce: bigint\n}\n\n/**\n * Export viewing keys for specific notes\n *\n * Creates an export package that can be shared with an auditor.\n * The auditor can use these keys to decrypt the specified notes,\n * but cannot derive keys for other notes.\n *\n * @param keys - Master keys\n * @param signerAddress - The Ethereum address that signed to derive keys\n * @param notes - Array of note references (leafIndex + nonce) to export\n * @returns Audit key export package\n */\nexport async function exportViewingKeysForAudit(\n keys: MasterKeys,\n signerAddress: Address,\n notes: NoteReference[]\n): Promise<AuditKeyExport> {\n const viewingKeys: TransactionViewingKey[] = []\n\n for (const note of notes) {\n // Derive the per-note decryption key\n const decryptionKey = await derivePerNoteKey(keys.viewingSecret, note.nonce)\n\n viewingKeys.push({\n leafIndex: note.leafIndex,\n nonce: note.nonce,\n decryptionKey,\n })\n }\n\n return {\n version: 4,\n signerAddress,\n viewingHash: keys.viewingHash,\n viewingKeys,\n instructions: `\nThis export contains per-note decryption keys for ${viewingKeys.length} UPP note(s).\n\nTo decrypt a note:\n1. Find the viewingKey entry for the desired leafIndex\n2. Retrieve the encrypted note from the blockchain (Shielded event at that leaf index)\n3. Derive AES key: key = keccak256(decryptionKey)\n4. Decrypt the note ciphertext with AES-GCM\n\nThese per-note keys ONLY allow decryption of the specified notes.\nThey do NOT reveal:\n- The master viewing secret (protected by Poseidon one-wayness)\n- Keys for any other notes\n- The spending secret (cannot spend funds)\n `.trim(),\n }\n}\n\n/**\n * Validate an audit key export\n */\nexport function validateAuditKeyExport(\n exportData: AuditKeyExport\n): { valid: boolean; error?: string } {\n if (exportData.version !== 4) {\n return { valid: false, error: `Unsupported version: ${exportData.version}. Expected version 4.` }\n }\n\n if (!exportData.signerAddress || !exportData.signerAddress.startsWith('0x')) {\n return { valid: false, error: 'Invalid signer address' }\n }\n\n if (exportData.viewingHash === undefined || exportData.viewingHash === null) {\n return { valid: false, error: 'Missing viewing hash' }\n }\n\n if (!Array.isArray(exportData.viewingKeys) || exportData.viewingKeys.length === 0) {\n return { valid: false, error: 'No viewing keys in export' }\n }\n\n return { valid: true }\n}\n\n/**\n * Look up a decryption key from an audit export by leaf index\n *\n * Returns the per-note decryption key for direct use in AES-GCM decryption.\n * Derive AES key: keccak256(decryptionKey)\n */\nexport function getViewingKeyFromExport(\n exportData: AuditKeyExport,\n leafIndex: number\n): Hex | null {\n const key = exportData.viewingKeys.find(k => k.leafIndex === leafIndex)\n return key ? key.decryptionKey : null\n}\n\n// =========================================================================\n// STARK Per-Note Viewing Key Derivation (Keccak-based, no elliptic curves)\n// =========================================================================\n\n/**\n * Derive a STARK per-note decryption key from viewing secret and nonce.\n *\n * Uses keccak_m31 instead of Poseidon — purely symmetric, post-quantum safe.\n * The nonce is encoded as a single M31 element appended to the viewing secret.\n *\n * perNoteDigest = keccak_m31(viewingSecret[0..8], nonce)\n * aesKey = keccak256(perNoteDigest_packed_as_16_LE_bytes)\n *\n * @param starkViewingSecret - 8 M31 limbs (the master STARK viewing secret)\n * @param nonce - Per-note nonce (M31 range)\n * @returns 32-byte AES key as hex\n */\nexport function deriveStarkPerNoteKey(\n starkViewingSecret: M31Secret,\n nonce: bigint\n): Hex {\n // keccak_m31(viewingSecret[0..8], nonce) → 4 M31 elements\n const digest = keccakM31([...starkViewingSecret, nonce])\n\n // Pack digest as 16 bytes LE for AES key derivation\n const bytes = new Uint8Array(16)\n for (let i = 0; i < 4; i++) {\n const val = Number(digest[i]!)\n bytes[i * 4] = val & 0xff\n bytes[i * 4 + 1] = (val >> 8) & 0xff\n bytes[i * 4 + 2] = (val >> 16) & 0xff\n bytes[i * 4 + 3] = (val >> 24) & 0xff\n }\n\n // Derive 32-byte AES key via keccak256\n return keccak256(bytesToHex(bytes))\n}\n\n/**\n * Derive STARK per-note key from StarkMasterKeys convenience wrapper\n */\nexport function deriveStarkPerNoteKeyFromKeys(\n keys: StarkMasterKeys,\n nonce: bigint\n): Hex {\n return deriveStarkPerNoteKey(keys.starkViewingSecret, nonce)\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { init_stealth } from './chunk-
|
|
1
|
+
import { init_stealth } from './chunk-7GDDA5VR.js';
|
|
2
2
|
|
|
3
3
|
// src/core/client.ts
|
|
4
4
|
function createUPPClient(_config) {
|
|
@@ -127,5 +127,5 @@ async function _verifyProxyImpl(client, checks, name, proxyAddress, expectedImpl
|
|
|
127
127
|
}
|
|
128
128
|
|
|
129
129
|
export { NOTE_VERSION, checkImplementation, createNote, createUPPClient, decryptNote, encryptNote, verifyDeployment };
|
|
130
|
-
//# sourceMappingURL=chunk-
|
|
131
|
-
//# sourceMappingURL=chunk-
|
|
130
|
+
//# sourceMappingURL=chunk-QYF2A5SO.js.map
|
|
131
|
+
//# sourceMappingURL=chunk-QYF2A5SO.js.map
|