{"version":3,"sources":["../src/chains/stacks/StacksSigner.ts","../src/chains/stacks/StacksAddressUtils.ts","../src/chains/stacks/StacksClient.ts","../src/chains/stacks/StacksPostConditions.ts"],"sourcesContent":["/**\n * Veridex Protocol SDK - Stacks Signature Format Conversion\n *\n * Converts WebAuthn/Passkey signatures to Clarity-compatible formats.\n *\n * Key conversions:\n * - WebAuthn DER-encoded signature → 64-byte compact (buff 64) for secp256r1-verify\n * - Uncompressed pubkey (x, y) → 33-byte compressed (buff 33)\n * - Session key signing via secp256k1 → 65-byte recoverable (buff 65)\n */\n\n// ============================================================================\n// Constants\n// ============================================================================\n\n/** secp256r1 curve order (P-256) */\nconst P256_ORDER = BigInt(\n    '0xFFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551'\n);\n\n/** secp256r1 half-order for low-S normalization */\nconst P256_HALF_ORDER = P256_ORDER / 2n;\n\n// ============================================================================\n// Public Key Compression\n// ============================================================================\n\n/**\n * Compress a P-256 public key from (x, y) coordinates to 33-byte compressed format.\n * The prefix byte is 0x02 if y is even, 0x03 if y is odd.\n *\n * @param x - P-256 public key X coordinate\n * @param y - P-256 public key Y coordinate\n * @returns 33-byte compressed public key\n */\nexport function compressPublicKey(x: bigint, y: bigint): Uint8Array {\n    const prefix = y % 2n === 0n ? 0x02 : 0x03;\n    const xBytes = bigintToBytes(x, 32);\n    const compressed = new Uint8Array(33);\n    compressed[0] = prefix;\n    compressed.set(xBytes, 1);\n    return compressed;\n}\n\n// ============================================================================\n// Signature Conversion\n// ============================================================================\n\n/**\n * Convert (r, s) bigint pair to 64-byte compact signature for secp256r1-verify.\n * Applies low-S normalization (required by Clarity's secp256r1-verify).\n *\n * @param r - Signature r component\n * @param s - Signature s component\n * @returns 64-byte compact signature buffer\n */\nexport function rsToCompactSignature(r: bigint, s: bigint): Uint8Array {\n    // Low-S normalization: if s > half-order, use order - s\n    const normalizedS = s > P256_HALF_ORDER ? P256_ORDER - s : s;\n\n    const compact = new Uint8Array(64);\n    compact.set(bigintToBytes(r, 32), 0);\n    compact.set(bigintToBytes(normalizedS, 32), 32);\n    return compact;\n}\n\n/**\n * Parse a DER-encoded ECDSA signature into (r, s) components.\n * WebAuthn signatures are typically DER-encoded.\n *\n * DER format: 0x30 [total-len] 0x02 [r-len] [r] 0x02 [s-len] [s]\n *\n * @param der - DER-encoded signature bytes\n * @returns Object with r and s as bigints\n */\nexport function parseDERSignature(der: Uint8Array): { r: bigint; s: bigint } {\n    if (der[0] !== 0x30) {\n        throw new Error('Invalid DER signature: expected SEQUENCE tag 0x30');\n    }\n\n    let offset = 2; // Skip SEQUENCE tag and length\n\n    // Parse r\n    if (der[offset] !== 0x02) {\n        throw new Error('Invalid DER signature: expected INTEGER tag 0x02 for r');\n    }\n    offset++;\n    const rLen = der[offset]!;\n    offset++;\n    const rBytes = der.slice(offset, offset + rLen);\n    offset += rLen;\n\n    // Parse s\n    if (der[offset] !== 0x02) {\n        throw new Error('Invalid DER signature: expected INTEGER tag 0x02 for s');\n    }\n    offset++;\n    const sLen = der[offset]!;\n    offset++;\n    const sBytes = der.slice(offset, offset + sLen);\n\n    return {\n        r: bytesToBigint(rBytes),\n        s: bytesToBigint(sBytes),\n    };\n}\n\n/**\n * Convert a DER-encoded signature to 64-byte compact format.\n * Combines DER parsing with compact encoding and low-S normalization.\n *\n * @param der - DER-encoded signature bytes\n * @returns 64-byte compact signature buffer\n */\nexport function derToCompactSignature(der: Uint8Array): Uint8Array {\n    const { r, s } = parseDERSignature(der);\n    return rsToCompactSignature(r, s);\n}\n\n// ============================================================================\n// Key Hash Computation\n// ============================================================================\n\n/**\n * Compute the key hash (SHA-256 of compressed public key).\n * This matches the Clarity contract's `(sha256 compressed-pubkey)`.\n *\n * @param compressedPubkey - 33-byte compressed public key\n * @returns 32-byte key hash as hex string (with 0x prefix)\n */\nexport async function computeKeyHash(compressedPubkey: Uint8Array): Promise<string> {\n    const hashBuffer = await globalThis.crypto.subtle.digest('SHA-256', compressedPubkey.buffer as ArrayBuffer);\n    const hashArray = new Uint8Array(hashBuffer);\n    return '0x' + bytesToHex(hashArray);\n}\n\n/**\n * Compute the key hash from (x, y) public key coordinates.\n * Compresses the key first, then SHA-256 hashes it.\n *\n * @param x - P-256 public key X coordinate\n * @param y - P-256 public key Y coordinate\n * @returns 32-byte key hash as hex string (with 0x prefix)\n */\nexport async function computeKeyHashFromCoords(x: bigint, y: bigint): Promise<string> {\n    const compressed = compressPublicKey(x, y);\n    return computeKeyHash(compressed);\n}\n\n// ============================================================================\n// Message Hash Construction\n// ============================================================================\n\n/**\n * Build a registration message hash.\n * Format: SHA-256(\"veridex:register:<nonce>\")\n *\n * @param nonce - Registration nonce (typically 0 for first registration)\n * @returns 32-byte message hash\n */\nexport async function buildRegistrationHash(nonce: number): Promise<Uint8Array> {\n    const message = `veridex:register:${nonce}`;\n    const encoded = new TextEncoder().encode(message);\n    const hashBuffer = await globalThis.crypto.subtle.digest('SHA-256', encoded.buffer as ArrayBuffer);\n    return new Uint8Array(hashBuffer);\n}\n\n/**\n * Build a session registration message hash.\n * Format: SHA-256(\"veridex:session:<session-key-hash>:<duration>:<max-value>:<nonce>\")\n *\n * @param sessionKeyHash - Hex string of session key hash\n * @param duration - Session duration in blocks\n * @param maxValue - Maximum spending value in microSTX\n * @param nonce - Identity nonce\n * @returns 32-byte message hash\n */\nexport async function buildSessionRegistrationHash(\n    sessionKeyHash: string,\n    duration: number,\n    maxValue: bigint,\n    nonce: number\n): Promise<Uint8Array> {\n    const cleanHash = sessionKeyHash.replace('0x', '');\n    const message = `veridex:session:${cleanHash}:${duration}:${maxValue}:${nonce}`;\n    const encoded = new TextEncoder().encode(message);\n    const hashBuffer = await globalThis.crypto.subtle.digest('SHA-256', encoded.buffer as ArrayBuffer);\n    return new Uint8Array(hashBuffer);\n}\n\n/**\n * Build a session revocation message hash.\n * Format: SHA-256(\"veridex:revoke:<session-hash>:<nonce>\")\n *\n * @param sessionHash - Hex string of session hash to revoke\n * @param nonce - Identity nonce\n * @returns 32-byte message hash\n */\nexport async function buildRevocationHash(\n    sessionHash: string,\n    nonce: number\n): Promise<Uint8Array> {\n    const cleanHash = sessionHash.replace('0x', '');\n    const message = `veridex:revoke:${cleanHash}:${nonce}`;\n    const encoded = new TextEncoder().encode(message);\n    const hashBuffer = await globalThis.crypto.subtle.digest('SHA-256', encoded.buffer as ArrayBuffer);\n    return new Uint8Array(hashBuffer);\n}\n\n/**\n * Build an execute action message hash.\n * Format: SHA-256(\"veridex:execute:<action-type>:<amount>:<recipient>:<nonce>\")\n *\n * @param actionType - Action type (1=STX transfer, 2=sBTC transfer)\n * @param amount - Amount in base units\n * @param recipient - Stacks principal address\n * @param nonce - Identity nonce\n * @returns 32-byte message hash\n */\nexport async function buildExecuteHash(\n    actionType: number,\n    amount: bigint,\n    recipient: string,\n    nonce: number\n): Promise<Uint8Array> {\n    const message = `veridex:execute:${actionType}:${amount}:${recipient}:${nonce}`;\n    const encoded = new TextEncoder().encode(message);\n    const hashBuffer = await globalThis.crypto.subtle.digest('SHA-256', encoded.buffer as ArrayBuffer);\n    return new Uint8Array(hashBuffer);\n}\n\n/**\n * Build a withdrawal message hash.\n * Format: SHA-256(\"veridex:withdraw:<amount>:<recipient>:<nonce>\")\n *\n * @param amount - Amount in microSTX\n * @param recipient - Stacks principal address\n * @param nonce - Identity nonce (from spoke contract, not used for passkey withdrawals but kept for consistency)\n * @returns 32-byte message hash\n */\nexport async function buildWithdrawalHash(\n    amount: bigint,\n    recipient: string,\n    nonce: number\n): Promise<Uint8Array> {\n    const message = `veridex:withdraw:${amount}:${recipient}:${nonce}`;\n    const encoded = new TextEncoder().encode(message);\n    const hashBuffer = await globalThis.crypto.subtle.digest('SHA-256', encoded.buffer as ArrayBuffer);\n    return new Uint8Array(hashBuffer);\n}\n\n// ============================================================================\n// Internal Helpers\n// ============================================================================\n\n/**\n * Convert a bigint to a fixed-length byte array (big-endian).\n */\nfunction bigintToBytes(value: bigint, length: number): Uint8Array {\n    const hex = value.toString(16).padStart(length * 2, '0');\n    const bytes = new Uint8Array(length);\n    for (let i = 0; i < length; i++) {\n        bytes[i] = parseInt(hex.slice(i * 2, i * 2 + 2), 16);\n    }\n    return bytes;\n}\n\n/**\n * Convert a byte array to a bigint (big-endian).\n * Handles leading zero bytes (positive integers in DER encoding).\n */\nfunction bytesToBigint(bytes: Uint8Array): bigint {\n    // Skip leading zero bytes (DER positive integer padding)\n    let start = 0;\n    while (start < bytes.length - 1 && bytes[start] === 0) {\n        start++;\n    }\n    let result = 0n;\n    for (let i = start; i < bytes.length; i++) {\n        result = (result << 8n) | BigInt(bytes[i]!);\n    }\n    return result;\n}\n\n/**\n * Convert a byte array to a hex string (no prefix).\n */\nexport function bytesToHex(bytes: Uint8Array): string {\n    return Array.from(bytes)\n        .map((b) => b.toString(16).padStart(2, '0'))\n        .join('');\n}\n\n/**\n * Convert a hex string to a byte array.\n */\nexport function hexToBytes(hex: string): Uint8Array {\n    const clean = hex.replace('0x', '');\n    const bytes = new Uint8Array(clean.length / 2);\n    for (let i = 0; i < bytes.length; i++) {\n        bytes[i] = parseInt(clean.slice(i * 2, i * 2 + 2), 16);\n    }\n    return bytes;\n}\n","/**\n * Veridex Protocol SDK - Stacks Address Utilities\n *\n * Validates and manipulates Stacks principal addresses.\n * Stacks uses c32check encoding for addresses.\n *\n * Address formats:\n * - Standard principal: SP/ST + 33 chars (mainnet/testnet)\n * - Contract principal: SP/ST + 33 chars + \".\" + contract-name\n */\n\n// ============================================================================\n// Constants\n// ============================================================================\n\n/** Stacks mainnet address prefix */\nexport const STACKS_MAINNET_PREFIX = 'SP';\n\n/** Stacks testnet address prefix */\nexport const STACKS_TESTNET_PREFIX = 'ST';\n\n/** c32 character set used by Stacks addresses */\nconst C32_ALPHABET = '0123456789ABCDEFGHJKMNPQRSTVWXYZ';\n\n// ============================================================================\n// Validation\n// ============================================================================\n\n/**\n * Validate a Stacks principal address (standard or contract).\n *\n * @param address - Address to validate\n * @returns true if the address is a valid Stacks principal\n */\nexport function isValidStacksPrincipal(address: string): boolean {\n    if (!address || typeof address !== 'string') {\n        return false;\n    }\n\n    // Check for contract principal (address.contract-name)\n    const parts = address.split('.');\n    if (parts.length > 2) {\n        return false;\n    }\n\n    const standardPart = parts[0]!;\n    const contractName = parts[1];\n\n    // Validate standard principal part\n    if (!isValidStandardPrincipal(standardPart)) {\n        return false;\n    }\n\n    // Validate contract name if present\n    if (contractName !== undefined) {\n        if (!isValidContractName(contractName)) {\n            return false;\n        }\n    }\n\n    return true;\n}\n\n/**\n * Validate a standard Stacks principal (not contract).\n *\n * @param address - Standard principal address\n * @returns true if valid\n */\nexport function isValidStandardPrincipal(address: string): boolean {\n    if (!address || address.length < 5) {\n        return false;\n    }\n\n    // Must start with SP (mainnet) or ST (testnet)\n    const prefix = address.slice(0, 2);\n    if (prefix !== STACKS_MAINNET_PREFIX && prefix !== STACKS_TESTNET_PREFIX) {\n        return false;\n    }\n\n    // Standard principals are typically 41 characters (SP/ST + 39 c32 chars)\n    // but can vary slightly. Check reasonable bounds.\n    if (address.length < 38 || address.length > 42) {\n        return false;\n    }\n\n    // Verify all characters after prefix are valid c32\n    const body = address.slice(1).toUpperCase();\n    for (const char of body) {\n        if (!C32_ALPHABET.includes(char)) {\n            return false;\n        }\n    }\n\n    return true;\n}\n\n/**\n * Validate a Clarity contract name.\n * Contract names must be 1-128 chars, alphanumeric + hyphens, starting with alpha.\n *\n * @param name - Contract name to validate\n * @returns true if valid\n */\nexport function isValidContractName(name: string): boolean {\n    if (!name || name.length === 0 || name.length > 128) {\n        return false;\n    }\n\n    // Must start with a letter\n    if (!/^[a-zA-Z]/.test(name)) {\n        return false;\n    }\n\n    // Only alphanumeric and hyphens\n    if (!/^[a-zA-Z][a-zA-Z0-9-]*$/.test(name)) {\n        return false;\n    }\n\n    return true;\n}\n\n// ============================================================================\n// Address Utilities\n// ============================================================================\n\n/**\n * Get the network type from a Stacks address.\n *\n * @param address - Stacks principal address\n * @returns 'mainnet' or 'testnet'\n */\nexport function getNetworkFromAddress(address: string): 'mainnet' | 'testnet' {\n    const prefix = address.slice(0, 2);\n    if (prefix === STACKS_MAINNET_PREFIX) {\n        return 'mainnet';\n    }\n    return 'testnet';\n}\n\n/**\n * Build a contract principal from deployer address and contract name.\n *\n * @param deployerAddress - Standard principal of the deployer\n * @param contractName - Name of the contract\n * @returns Contract principal in \"address.contract-name\" format\n */\nexport function getContractPrincipal(\n    deployerAddress: string,\n    contractName: string\n): string {\n    if (!isValidStandardPrincipal(deployerAddress)) {\n        throw new Error(`Invalid deployer address: ${deployerAddress}`);\n    }\n    if (!isValidContractName(contractName)) {\n        throw new Error(`Invalid contract name: ${contractName}`);\n    }\n    return `${deployerAddress}.${contractName}`;\n}\n\n/**\n * Parse a contract principal into deployer address and contract name.\n *\n * @param contractPrincipal - Full contract principal (e.g., \"ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM.veridex-spoke\")\n * @returns Object with address and contractName\n */\nexport function parseContractPrincipal(contractPrincipal: string): {\n    address: string;\n    contractName: string;\n} {\n    const dotIndex = contractPrincipal.indexOf('.');\n    if (dotIndex === -1) {\n        throw new Error(\n            `Not a contract principal: ${contractPrincipal}. Expected format: address.contract-name`\n        );\n    }\n\n    return {\n        address: contractPrincipal.slice(0, dotIndex),\n        contractName: contractPrincipal.slice(dotIndex + 1),\n    };\n}\n\n/**\n * Check if an address is a contract principal.\n *\n * @param address - Address to check\n * @returns true if the address contains a contract name\n */\nexport function isContractPrincipal(address: string): boolean {\n    return address.includes('.');\n}\n\n/**\n * Get the explorer URL for a Stacks transaction.\n *\n * @param txId - Transaction ID (hex string)\n * @param network - 'mainnet' or 'testnet'\n * @returns Full explorer URL\n */\nexport function getStacksExplorerTxUrl(\n    txId: string,\n    network: 'mainnet' | 'testnet' = 'testnet'\n): string {\n    const cleanTxId = txId.startsWith('0x') ? txId : `0x${txId}`;\n    const chainParam = network === 'testnet' ? '&chain=testnet' : '';\n    return `https://explorer.hiro.so/txid/${cleanTxId}?${chainParam}`;\n}\n\n/**\n * Get the explorer URL for a Stacks address.\n *\n * @param address - Stacks principal address\n * @param network - 'mainnet' or 'testnet'\n * @returns Full explorer URL\n */\nexport function getStacksExplorerAddressUrl(\n    address: string,\n    network: 'mainnet' | 'testnet' = 'testnet'\n): string {\n    const chainParam = network === 'testnet' ? '?chain=testnet' : '';\n    return `https://explorer.hiro.so/address/${address}${chainParam}`;\n}\n","/**\n * Veridex Protocol SDK - Stacks Chain Client\n *\n * Production-grade implementation of ChainClient interface for Stacks.\n * Supports direct relay with native sponsored transactions.\n *\n * Security:\n * - Native secp256r1-verify for Passkey (P-256) validation\n * - Native secp256k1-verify for session key validation\n * - Protocol-level Post-Conditions for spending safety\n * - Nonce-based replay protection\n * - Block-height based session expiry\n *\n * Architecture:\n * - Phase 1: Direct relay (relayer sponsors Stacks transactions)\n * - Phase 2: Wormhole cross-chain messaging (VAA + CCQ)\n * - Vaults are map-based (Clarity doesn't support factory patterns)\n * - All identities stored in veridex-spoke.clar\n * - STX/sBTC custody in veridex-vault.clar (direct) + veridex-vault-vaa.clar (cross-chain)\n * - Guardian signature verification in veridex-wormhole-verifier.clar\n */\n\nimport type { SessionKey } from '../../sessions/types.js';\nimport type {\n    ChainClient,\n    ChainConfig,\n    TransferParams,\n    ExecuteParams,\n    BridgeParams,\n    DispatchResult,\n    WebAuthnSignature,\n    VaultCreationResult,\n    RegisterSessionParams,\n    RevokeSessionParams,\n    SessionValidationResult,\n} from '../../core/types.js';\nimport { encodeTransferAction, encodeExecuteAction, encodeBridgeAction } from '../../payload.js';\nimport {\n    compressPublicKey,\n    rsToCompactSignature,\n    computeKeyHashFromCoords,\n    bytesToHex,\n    hexToBytes,\n} from './StacksSigner.js';\nimport {\n    parseContractPrincipal,\n    isContractPrincipal,\n} from './StacksAddressUtils.js';\n\n// ============================================================================\n// Constants\n// ============================================================================\n\n/** Stacks action types matching veridex-spoke.clar constants */\nexport const STACKS_ACTION_TYPES = {\n    TRANSFER_STX: 1,\n    TRANSFER_SBTC: 2,\n    CONTRACT_CALL: 3,\n} as const;\n\n/** Default Hiro API endpoints */\nconst HIRO_API = {\n    testnet: 'https://api.testnet.hiro.so',\n    mainnet: 'https://api.hiro.so',\n} as const;\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface StacksClientConfig {\n    /** Wormhole chain ID (60 for Stacks) */\n    wormholeChainId: number;\n    /** Stacks RPC URL (Hiro API) */\n    rpcUrl: string;\n    /** Spoke contract principal (e.g., \"ST1PQHQKV...veridex-spoke\") */\n    spokeContractAddress?: string;\n    /** Vault contract principal (e.g., \"ST1PQHQKV...veridex-vault\") */\n    vaultContractAddress?: string;\n    /** Wormhole verifier contract principal (Phase 2) */\n    wormholeVerifierAddress?: string;\n    /** VAA-authorized vault contract principal (Phase 2) */\n    vaultVaaContractAddress?: string;\n    /** Network type */\n    network?: 'mainnet' | 'testnet';\n    /** Hub RPC URL for cross-chain session management */\n    hubRpcUrl?: string;\n    /** Hub contract address for cross-chain session management */\n    hubContractAddress?: string;\n}\n\n/** Parsed contract principal */\ninterface ContractId {\n    address: string;\n    name: string;\n}\n\n// ============================================================================\n// StacksClient\n// ============================================================================\n\nexport class StacksClient implements ChainClient {\n    private config: ChainConfig;\n    private rpcUrl: string;\n    private spokeContract: ContractId | null;\n    private vaultContract: ContractId | null;\n    private wormholeVerifierContract: ContractId | null;\n    private vaultVaaContract: ContractId | null;\n    private networkType: 'mainnet' | 'testnet';\n\n    constructor(clientConfig: StacksClientConfig) {\n        this.networkType = clientConfig.network || 'testnet';\n        this.rpcUrl = clientConfig.rpcUrl || HIRO_API[this.networkType];\n\n        // Parse spoke contract principal\n        if (clientConfig.spokeContractAddress && isContractPrincipal(clientConfig.spokeContractAddress)) {\n            const parsed = parseContractPrincipal(clientConfig.spokeContractAddress);\n            this.spokeContract = { address: parsed.address, name: parsed.contractName };\n        } else {\n            this.spokeContract = null;\n        }\n\n        // Parse vault contract principal\n        if (clientConfig.vaultContractAddress && isContractPrincipal(clientConfig.vaultContractAddress)) {\n            const parsed = parseContractPrincipal(clientConfig.vaultContractAddress);\n            this.vaultContract = { address: parsed.address, name: parsed.contractName };\n        } else {\n            this.vaultContract = null;\n        }\n\n        // Parse wormhole verifier contract principal (Phase 2)\n        if (clientConfig.wormholeVerifierAddress && isContractPrincipal(clientConfig.wormholeVerifierAddress)) {\n            const parsed = parseContractPrincipal(clientConfig.wormholeVerifierAddress);\n            this.wormholeVerifierContract = { address: parsed.address, name: parsed.contractName };\n        } else {\n            this.wormholeVerifierContract = null;\n        }\n\n        // Parse vault-vaa contract principal (Phase 2)\n        if (clientConfig.vaultVaaContractAddress && isContractPrincipal(clientConfig.vaultVaaContractAddress)) {\n            const parsed = parseContractPrincipal(clientConfig.vaultVaaContractAddress);\n            this.vaultVaaContract = { address: parsed.address, name: parsed.contractName };\n        } else {\n            this.vaultVaaContract = null;\n        }\n\n        // If spoke is set but vault is not, derive vault from same deployer\n        if (this.spokeContract && !this.vaultContract) {\n            this.vaultContract = {\n                address: this.spokeContract.address,\n                name: 'veridex-vault',\n            };\n        }\n\n        // Auto-derive Phase 2 contracts from spoke deployer if not explicitly set\n        if (this.spokeContract && !this.wormholeVerifierContract) {\n            this.wormholeVerifierContract = {\n                address: this.spokeContract.address,\n                name: 'veridex-wormhole-verifier',\n            };\n        }\n        if (this.spokeContract && !this.vaultVaaContract) {\n            this.vaultVaaContract = {\n                address: this.spokeContract.address,\n                name: 'veridex-vault-vaa',\n            };\n        }\n\n        this.config = {\n            name: `Stacks ${this.networkType}`,\n            chainId: this.networkType === 'mainnet' ? 1 : 2147483648,\n            wormholeChainId: clientConfig.wormholeChainId,\n            rpcUrl: this.rpcUrl,\n            explorerUrl: this.networkType === 'testnet'\n                ? 'https://explorer.hiro.so/?chain=testnet'\n                : 'https://explorer.hiro.so',\n            isEvm: false,\n            contracts: {\n                hub: clientConfig.spokeContractAddress,\n                wormholeCoreBridge: '',\n                wormholeVerifier: this.wormholeVerifierContract\n                    ? `${this.wormholeVerifierContract.address}.${this.wormholeVerifierContract.name}`\n                    : undefined,\n                vaultVaa: this.vaultVaaContract\n                    ? `${this.vaultVaaContract.address}.${this.vaultVaaContract.name}`\n                    : undefined,\n            },\n        };\n    }\n\n    // ========================================================================\n    // ChainClient Interface - Configuration\n    // ========================================================================\n\n    getConfig(): ChainConfig {\n        return this.config;\n    }\n\n    // ========================================================================\n    // ChainClient Interface - Nonce & Fees\n    // ========================================================================\n\n    /**\n     * Get the current nonce for a user identity from the spoke contract.\n     * Calls the read-only function `get-nonce` on veridex-spoke.\n     */\n    async getNonce(userKeyHash: string): Promise<bigint> {\n        if (!this.spokeContract) {\n            return 0n;\n        }\n\n        try {\n            const result = await this.callReadOnly(\n                this.spokeContract.address,\n                this.spokeContract.name,\n                'get-nonce',\n                [`0x${userKeyHash.replace('0x', '')}`]\n            );\n\n            // Result is (ok uint) or (err uint)\n            if (result && result.value !== undefined) {\n                return BigInt(result.value);\n            }\n            return 0n;\n        } catch {\n            return 0n;\n        }\n    }\n\n    /**\n     * Get the Wormhole message fee.\n     * Phase 1: No Wormhole integration, returns 0.\n     */\n    async getMessageFee(): Promise<bigint> {\n        return 0n;\n    }\n\n    // ========================================================================\n    // ChainClient Interface - Payload Building\n    // ========================================================================\n\n    async buildTransferPayload(params: TransferParams): Promise<string> {\n        return encodeTransferAction(params.token, params.recipient, params.amount);\n    }\n\n    async buildExecutePayload(params: ExecuteParams): Promise<string> {\n        return encodeExecuteAction(params.target, params.value, params.data);\n    }\n\n    async buildBridgePayload(params: BridgeParams): Promise<string> {\n        return encodeBridgeAction(params.token, params.amount, params.destinationChain, params.recipient);\n    }\n\n    // ========================================================================\n    // ChainClient Interface - Dispatch\n    // ========================================================================\n\n    /**\n     * Direct dispatch is not supported on Stacks in Phase 1.\n     * Stacks actions are executed via sponsored transactions through the relayer.\n     */\n    async dispatch(\n        _signature: WebAuthnSignature,\n        _publicKeyX: bigint,\n        _publicKeyY: bigint,\n        _targetChain: number,\n        _actionPayload: string,\n        _nonce: bigint,\n        _signer: unknown\n    ): Promise<DispatchResult> {\n        throw new Error(\n            'Direct dispatch not supported on Stacks in Phase 1. ' +\n            'Use dispatchGasless() to route through the relayer, which sponsors Stacks transactions. ' +\n            'Phase 2 will add Wormhole cross-chain dispatch support.'\n        );\n    }\n\n    /**\n     * Dispatch an action via the relayer (gasless/sponsored).\n     *\n     * Flow:\n     * 1. User signs action with Passkey (on client)\n     * 2. SDK submits to relayer with targetChain=60 (Stacks)\n     * 3. Relayer builds Clarity contract-call transaction\n     * 4. Relayer sponsors the transaction (pays STX gas)\n     * 5. Relayer broadcasts to Stacks network\n     * 6. Transaction confirmed on Stacks\n     */\n    async dispatchGasless(\n        signature: WebAuthnSignature,\n        publicKeyX: bigint,\n        publicKeyY: bigint,\n        targetChain: number,\n        actionPayload: string,\n        nonce: bigint,\n        relayerUrl: string\n    ): Promise<DispatchResult> {\n        const keyHash = await computeKeyHashFromCoords(publicKeyX, publicKeyY);\n        const compressedPubkey = compressPublicKey(publicKeyX, publicKeyY);\n        const compactSig = rsToCompactSignature(signature.r, signature.s);\n\n        const request = {\n            signature: {\n                r: '0x' + signature.r.toString(16).padStart(64, '0'),\n                s: '0x' + signature.s.toString(16).padStart(64, '0'),\n                authenticatorData: signature.authenticatorData,\n                clientDataJSON: signature.clientDataJSON,\n                challengeIndex: signature.challengeIndex,\n                typeIndex: signature.typeIndex,\n            },\n            publicKeyX: '0x' + publicKeyX.toString(16).padStart(64, '0'),\n            publicKeyY: '0x' + publicKeyY.toString(16).padStart(64, '0'),\n            compressedPubkey: '0x' + bytesToHex(compressedPubkey),\n            compactSignature: '0x' + bytesToHex(compactSig),\n            targetChain,\n            actionPayload,\n            userNonce: Number(nonce),\n        };\n\n        const response = await fetch(`${relayerUrl}/api/v1/submit`, {\n            method: 'POST',\n            headers: { 'Content-Type': 'application/json' },\n            body: JSON.stringify(request),\n        });\n\n        if (!response.ok) {\n            const errorText = await response.text().catch(() => 'Unknown error');\n            throw new Error(\n                `Relayer submission failed: ${response.status} ${response.statusText}. ` +\n                `Error: ${errorText}`\n            );\n        }\n\n        const result = await response.json() as Record<string, unknown>;\n\n        return {\n            transactionHash: (result.transactionHash ?? result.txHash ?? result.hubTxHash ?? '') as string,\n            sequence: BigInt((result.sequence as string | number) || 0),\n            userKeyHash: keyHash,\n            targetChain,\n        };\n    }\n\n    // ========================================================================\n    // ChainClient Interface - Vault Management\n    // ========================================================================\n\n    /**\n     * Get vault address for a user.\n     * On Stacks, vaults are map-based within the vault contract.\n     * The \"vault address\" is the vault contract principal itself.\n     */\n    async getVaultAddress(userKeyHash: string): Promise<string | null> {\n        if (!this.vaultContract) {\n            return null;\n        }\n\n        // Check if identity exists in spoke contract\n        const exists = await this.vaultExists(userKeyHash);\n        if (!exists) {\n            return null;\n        }\n\n        return `${this.vaultContract.address}.${this.vaultContract.name}`;\n    }\n\n    /**\n     * Compute vault address deterministically.\n     * On Stacks, all vaults live in the same contract (map-based).\n     */\n    computeVaultAddress(_userKeyHash: string): string {\n        if (!this.vaultContract) {\n            throw new Error('Vault contract not configured');\n        }\n        return `${this.vaultContract.address}.${this.vaultContract.name}`;\n    }\n\n    /**\n     * Check if a vault (identity) exists for a user.\n     * Queries the spoke contract's `identity-exists` read-only function.\n     */\n    async vaultExists(userKeyHash: string): Promise<boolean> {\n        if (!this.spokeContract) {\n            return false;\n        }\n\n        try {\n            const result = await this.callReadOnly(\n                this.spokeContract.address,\n                this.spokeContract.name,\n                'identity-exists',\n                [`0x${userKeyHash.replace('0x', '')}`]\n            );\n\n            return result === true || result?.value === true;\n        } catch {\n            return false;\n        }\n    }\n\n    /**\n     * Create a vault (register identity) on Stacks.\n     * Must be done via Hub dispatch or relayer in Phase 1.\n     */\n    async createVault(userKeyHash: string, _signer: unknown): Promise<VaultCreationResult> {\n        throw new Error(\n            'Vault creation on Stacks requires Passkey signature verification. ' +\n            'Use createVaultViaRelayer() for sponsored identity registration, ' +\n            'or call register-identity directly with a signed Stacks transaction. ' +\n            `KeyHash=${userKeyHash}`\n        );\n    }\n\n    /**\n     * Create a vault with a sponsor wallet.\n     * On Stacks, this registers an identity via sponsored transaction.\n     */\n    async createVaultSponsored?(\n        userKeyHash: string,\n        _sponsorPrivateKey: string,\n        _rpcUrl?: string\n    ): Promise<VaultCreationResult> {\n        throw new Error(\n            'Sponsored vault creation on Stacks requires the user to sign with their Passkey. ' +\n            'Use createVaultViaRelayer() which handles the sponsored transaction flow. ' +\n            `KeyHash=${userKeyHash}`\n        );\n    }\n\n    /**\n     * Create a vault via the relayer (sponsored/gasless).\n     * The relayer will sponsor the register-identity transaction.\n     */\n    async createVaultViaRelayer(\n        userKeyHash: string,\n        relayerUrl: string\n    ): Promise<VaultCreationResult> {\n        const response = await fetch(`${relayerUrl}/api/v1/stacks/vault`, {\n            method: 'POST',\n            headers: { 'Content-Type': 'application/json' },\n            body: JSON.stringify({\n                userKeyHash,\n                chainId: this.config.wormholeChainId,\n            }),\n        });\n\n        const result = await response.json() as Record<string, unknown>;\n\n        if (!response.ok || !result.success) {\n            throw new Error((result.error as string) || 'Failed to create vault via relayer');\n        }\n\n        return {\n            address: (result.vaultAddress as string) || this.computeVaultAddress(userKeyHash),\n            transactionHash: (result.transactionHash as string) || '',\n            blockNumber: 0,\n            gasUsed: 0n,\n            alreadyExisted: (result.alreadyExists as boolean) || false,\n            sponsoredBy: 'relayer',\n        };\n    }\n\n    async estimateVaultCreationGas(_userKeyHash: string): Promise<bigint> {\n        // Stacks fees are typically 0.001-0.01 STX for contract calls\n        return 10000n; // 0.01 STX in microSTX\n    }\n\n    getFactoryAddress(): string | undefined {\n        return undefined; // No factory pattern on Stacks\n    }\n\n    getImplementationAddress(): string | undefined {\n        return undefined;\n    }\n\n    // ========================================================================\n    // Stacks-Specific: Balance Queries\n    // ========================================================================\n\n    /**\n     * Get native STX balance for an address.\n     */\n    async getNativeBalance(address: string): Promise<bigint> {\n        try {\n            const response = await fetch(\n                `${this.rpcUrl}/v2/accounts/${address}?proof=0`\n            );\n            if (!response.ok) {\n                return 0n;\n            }\n            const data = await response.json() as Record<string, string>;\n            return BigInt(data.balance || '0');\n        } catch {\n            return 0n;\n        }\n    }\n\n    /**\n     * Get vault STX balance for an identity.\n     * Queries the vault contract's `get-stx-balance` read-only function.\n     */\n    async getVaultStxBalance(keyHash: string): Promise<bigint> {\n        if (!this.vaultContract) {\n            return 0n;\n        }\n\n        try {\n            const result = await this.callReadOnly(\n                this.vaultContract.address,\n                this.vaultContract.name,\n                'get-stx-balance',\n                [`0x${keyHash.replace('0x', '')}`]\n            );\n\n            if (result && result.value !== undefined) {\n                return BigInt(result.value);\n            }\n            return 0n;\n        } catch {\n            return 0n;\n        }\n    }\n\n    /**\n     * Get vault sBTC balance for an identity.\n     */\n    async getVaultSbtcBalance(keyHash: string): Promise<bigint> {\n        if (!this.vaultContract) {\n            return 0n;\n        }\n\n        try {\n            const result = await this.callReadOnly(\n                this.vaultContract.address,\n                this.vaultContract.name,\n                'get-sbtc-balance',\n                [`0x${keyHash.replace('0x', '')}`]\n            );\n\n            if (result && result.value !== undefined) {\n                return BigInt(result.value);\n            }\n            return 0n;\n        } catch {\n            return 0n;\n        }\n    }\n\n    // ========================================================================\n    // Stacks-Specific: Identity & Session Queries\n    // ========================================================================\n\n    /**\n     * Get identity info from the spoke contract.\n     */\n    async getIdentity(keyHash: string): Promise<{\n        compressedPubkey: string;\n        owner: string;\n        nonce: bigint;\n        createdAt: bigint;\n    } | null> {\n        if (!this.spokeContract) {\n            return null;\n        }\n\n        try {\n            const result = await this.callReadOnly(\n                this.spokeContract.address,\n                this.spokeContract.name,\n                'get-identity',\n                [`0x${keyHash.replace('0x', '')}`]\n            );\n\n            if (!result || result.value === undefined) {\n                return null;\n            }\n\n            const val = result.value;\n            return {\n                compressedPubkey: val['compressed-pubkey']?.value || '',\n                owner: val.owner?.value || '',\n                nonce: BigInt(val.nonce?.value || 0),\n                createdAt: BigInt(val['created-at']?.value || 0),\n            };\n        } catch {\n            return null;\n        }\n    }\n\n    /**\n     * Get session info from the spoke contract.\n     */\n    async getSession(keyHash: string, sessionHash: string): Promise<{\n        sessionPubkey: string;\n        expiry: bigint;\n        maxValue: bigint;\n        spent: bigint;\n        revoked: boolean;\n        createdAt: bigint;\n    } | null> {\n        if (!this.spokeContract) {\n            return null;\n        }\n\n        try {\n            const cleanKeyHash = `0x${keyHash.replace('0x', '')}`;\n            const cleanSessionHash = `0x${sessionHash.replace('0x', '')}`;\n\n            const result = await this.callReadOnly(\n                this.spokeContract.address,\n                this.spokeContract.name,\n                'get-session',\n                [cleanKeyHash, cleanSessionHash]\n            );\n\n            if (!result || result.value === undefined) {\n                return null;\n            }\n\n            const val = result.value;\n            return {\n                sessionPubkey: val['session-pubkey']?.value || '',\n                expiry: BigInt(val.expiry?.value || 0),\n                maxValue: BigInt(val['max-value']?.value || 0),\n                spent: BigInt(val.spent?.value || 0),\n                revoked: val.revoked?.value === true,\n                createdAt: BigInt(val['created-at']?.value || 0),\n            };\n        } catch {\n            return null;\n        }\n    }\n\n    /**\n     * Check if a session is currently active.\n     */\n    async checkSessionActive(keyHash: string, sessionHash: string): Promise<boolean> {\n        if (!this.spokeContract) {\n            return false;\n        }\n\n        try {\n            const cleanKeyHash = `0x${keyHash.replace('0x', '')}`;\n            const cleanSessionHash = `0x${sessionHash.replace('0x', '')}`;\n\n            const result = await this.callReadOnly(\n                this.spokeContract.address,\n                this.spokeContract.name,\n                'is-session-active',\n                [cleanKeyHash, cleanSessionHash]\n            );\n\n            return result?.value === true;\n        } catch {\n            return false;\n        }\n    }\n\n    /**\n     * Get remaining spending budget for a session.\n     */\n    async getRemainingBudget(keyHash: string, sessionHash: string): Promise<bigint> {\n        if (!this.spokeContract) {\n            return 0n;\n        }\n\n        try {\n            const cleanKeyHash = `0x${keyHash.replace('0x', '')}`;\n            const cleanSessionHash = `0x${sessionHash.replace('0x', '')}`;\n\n            const result = await this.callReadOnly(\n                this.spokeContract.address,\n                this.spokeContract.name,\n                'get-remaining-budget',\n                [cleanKeyHash, cleanSessionHash]\n            );\n\n            if (result && result.value !== undefined) {\n                return BigInt(result.value);\n            }\n            return 0n;\n        } catch {\n            return 0n;\n        }\n    }\n\n    // ========================================================================\n    // Stacks-Specific: Protocol Status\n    // ========================================================================\n\n    /**\n     * Check if the spoke contract is paused.\n     */\n    async isProtocolPaused(): Promise<boolean> {\n        if (!this.spokeContract) {\n            return false;\n        }\n\n        try {\n            const result = await this.callReadOnly(\n                this.spokeContract.address,\n                this.spokeContract.name,\n                'is-paused',\n                []\n            );\n\n            return result === true || result?.value === true;\n        } catch {\n            return false;\n        }\n    }\n\n    /**\n     * Get global identity count.\n     */\n    async getIdentityCount(): Promise<bigint> {\n        if (!this.spokeContract) {\n            return 0n;\n        }\n\n        try {\n            const result = await this.callReadOnly(\n                this.spokeContract.address,\n                this.spokeContract.name,\n                'get-identity-count',\n                []\n            );\n\n            return BigInt(result?.value || result || 0);\n        } catch {\n            return 0n;\n        }\n    }\n\n    /**\n     * Get total STX deposited across all vaults.\n     */\n    async getTotalStxDeposited(): Promise<bigint> {\n        if (!this.vaultContract) {\n            return 0n;\n        }\n\n        try {\n            const result = await this.callReadOnly(\n                this.vaultContract.address,\n                this.vaultContract.name,\n                'get-total-stx-deposited',\n                []\n            );\n\n            return BigInt(result?.value || result || 0);\n        } catch {\n            return 0n;\n        }\n    }\n\n    // ========================================================================\n    // Session Management (Issue #13)\n    // ========================================================================\n\n    /**\n     * Register a session key on the Stacks spoke.\n     * On Stacks, sessions are managed directly on the spoke contract\n     * (unlike EVM spokes where sessions are on the Hub).\n     */\n    async registerSession(_params: RegisterSessionParams): Promise<void> {\n        throw new Error(\n            'Session registration on Stacks requires a Passkey signature. ' +\n            'Build a register-session transaction with the Passkey signature, ' +\n            'then submit via the relayer for sponsored execution.'\n        );\n    }\n\n    /**\n     * Revoke a session key on the Stacks spoke.\n     */\n    async revokeSession(_params: RevokeSessionParams): Promise<void> {\n        throw new Error(\n            'Session revocation on Stacks requires a Passkey signature. ' +\n            'Build a revoke-session transaction with the Passkey signature, ' +\n            'then submit via the relayer for sponsored execution.'\n        );\n    }\n\n    /**\n     * Check if a session is active.\n     */\n    async isSessionActive(\n        userKeyHash: string,\n        sessionKeyHash: string\n    ): Promise<SessionValidationResult> {\n        const active = await this.checkSessionActive(userKeyHash, sessionKeyHash);\n        const session = await this.getSession(userKeyHash, sessionKeyHash);\n\n        return {\n            isActive: active,\n            expiry: session ? Number(session.expiry) : 0,\n            maxValue: session?.maxValue ?? 0n,\n            chainScopes: [this.config.wormholeChainId],\n        };\n    }\n\n    /**\n     * Get all sessions for a user.\n     * Note: Clarity maps don't support enumeration, so this requires\n     * off-chain indexing or event log parsing.\n     */\n    async getUserSessions(_userKeyHash: string): Promise<SessionKey[]> {\n        throw new Error(\n            'Enumerating all sessions is not supported on Stacks (Clarity maps are not iterable). ' +\n            'Use checkSessionActive() with a known session hash, or query the Stacks event log ' +\n            'for \"session-registered\" print events via the Hiro API.'\n        );\n    }\n\n    // ========================================================================\n    // Stacks-Specific: Transaction Status\n    // ========================================================================\n\n    /**\n     * Get the status of a Stacks transaction.\n     */\n    async getTransactionStatus(txId: string): Promise<{\n        status: 'pending' | 'success' | 'failed' | 'not_found';\n        blockHeight?: number;\n        error?: string;\n    }> {\n        try {\n            const cleanTxId = txId.startsWith('0x') ? txId : `0x${txId}`;\n            const response = await fetch(\n                `${this.rpcUrl}/extended/v1/tx/${cleanTxId}`\n            );\n\n            if (!response.ok) {\n                return { status: 'not_found' };\n            }\n\n            const data = await response.json() as Record<string, unknown>;\n            const txStatus = data.tx_status as string;\n\n            if (txStatus === 'success') {\n                return {\n                    status: 'success',\n                    blockHeight: data.block_height as number,\n                };\n            }\n\n            if (txStatus === 'pending') {\n                return { status: 'pending' };\n            }\n\n            if (txStatus === 'abort_by_response' || txStatus === 'abort_by_post_condition') {\n                return {\n                    status: 'failed',\n                    error: `Transaction aborted: ${txStatus}`,\n                };\n            }\n\n            return { status: 'pending' };\n        } catch {\n            return { status: 'not_found' };\n        }\n    }\n\n    /**\n     * Wait for a transaction to be confirmed.\n     *\n     * @param txId - Transaction ID\n     * @param maxAttempts - Maximum polling attempts (default: 60)\n     * @param pollIntervalMs - Polling interval in milliseconds (default: 5000)\n     */\n    async waitForConfirmation(\n        txId: string,\n        maxAttempts: number = 60,\n        pollIntervalMs: number = 5000\n    ): Promise<{ confirmed: boolean; blockHeight?: number }> {\n        for (let i = 0; i < maxAttempts; i++) {\n            const status = await this.getTransactionStatus(txId);\n\n            if (status.status === 'success') {\n                return { confirmed: true, blockHeight: status.blockHeight };\n            }\n\n            if (status.status === 'failed') {\n                throw new Error(`Transaction failed: ${status.error}`);\n            }\n\n            await new Promise((resolve) => setTimeout(resolve, pollIntervalMs));\n        }\n\n        return { confirmed: false };\n    }\n\n    // ========================================================================\n    // Stacks-Specific: Network Info\n    // ========================================================================\n\n    /**\n     * Get Stacks network info (block height, network version, etc.).\n     */\n    async getNetworkInfo(): Promise<{\n        networkId: number;\n        stacksBlockHeight: number;\n        burnBlockHeight: number;\n        serverVersion: string;\n    }> {\n        const response = await fetch(`${this.rpcUrl}/v2/info`);\n        if (!response.ok) {\n            throw new Error(`Failed to get Stacks network info: ${response.statusText}`);\n        }\n\n        const data = await response.json() as Record<string, unknown>;\n        return {\n            networkId: data.network_id as number,\n            stacksBlockHeight: data.stacks_tip_height as number,\n            burnBlockHeight: data.burn_block_height as number,\n            serverVersion: data.server_version as string,\n        };\n    }\n\n    /**\n     * Get the current Stacks block height.\n     * Used for session expiry calculations.\n     */\n    async getCurrentBlockHeight(): Promise<number> {\n        const info = await this.getNetworkInfo();\n        return info.stacksBlockHeight;\n    }\n\n    // ========================================================================\n    // Internal: Read-Only Contract Calls via Hiro API\n    // ========================================================================\n\n    /**\n     * Call a read-only Clarity function via the Hiro API.\n     * Uses the /v2/contracts/call-read endpoint.\n     */\n    private async callReadOnly(\n        contractAddress: string,\n        contractName: string,\n        functionName: string,\n        args: string[]\n    ): Promise<any> {\n        const url = `${this.rpcUrl}/v2/contracts/call-read/${contractAddress}/${contractName}/${functionName}`;\n\n        const response = await fetch(url, {\n            method: 'POST',\n            headers: { 'Content-Type': 'application/json' },\n            body: JSON.stringify({\n                sender: contractAddress,\n                arguments: args,\n            }),\n        });\n\n        if (!response.ok) {\n            const errorText = await response.text().catch(() => 'Unknown error');\n            throw new Error(\n                `Read-only call failed: ${contractAddress}.${contractName}::${functionName} - ` +\n                `${response.status}: ${errorText}`\n            );\n        }\n\n        const data = await response.json() as Record<string, unknown>;\n\n        if (!data.okay) {\n            throw new Error(\n                `Read-only call returned error: ${contractAddress}.${contractName}::${functionName} - ` +\n                `${data.cause || 'Unknown cause'}`\n            );\n        }\n\n        // Parse the Clarity value from the hex result\n        return this.parseClarityValue(data.result as string);\n    }\n\n    /**\n     * Parse a hex-encoded Clarity value from the API response.\n     * This is a simplified parser for common Clarity types.\n     */\n    private parseClarityValue(hex: string): any {\n        if (!hex || hex === '0x') {\n            return null;\n        }\n\n        const bytes = hexToBytes(hex);\n        if (bytes.length === 0) {\n            return null;\n        }\n\n        const typeId = bytes[0];\n\n        switch (typeId) {\n            // int (0x00)\n            case 0x00: {\n                let value = 0n;\n                for (let i = 1; i < 17 && i < bytes.length; i++) {\n                    value = (value << 8n) | BigInt(bytes[i]!);\n                }\n                return { value };\n            }\n            // uint (0x01)\n            case 0x01: {\n                let value = 0n;\n                for (let i = 1; i < 17 && i < bytes.length; i++) {\n                    value = (value << 8n) | BigInt(bytes[i]!);\n                }\n                return { value };\n            }\n            // buffer (0x02)\n            case 0x02: {\n                const len = (bytes[1]! << 24) | (bytes[2]! << 16) | (bytes[3]! << 8) | bytes[4]!;\n                const bufValue = bytes.slice(5, 5 + len);\n                return { value: '0x' + bytesToHex(bufValue) };\n            }\n            // bool true (0x03)\n            case 0x03:\n                return true;\n            // bool false (0x04)\n            case 0x04:\n                return false;\n            // optional none (0x09)\n            case 0x09:\n                return null;\n            // optional some (0x0a)\n            case 0x0a:\n                return this.parseClarityValue('0x' + bytesToHex(bytes.slice(1)));\n            // response ok (0x07)\n            case 0x07:\n                return this.parseClarityValue('0x' + bytesToHex(bytes.slice(1)));\n            // response err (0x08)\n            case 0x08: {\n                const errVal = this.parseClarityValue('0x' + bytesToHex(bytes.slice(1)));\n                throw new Error(`Clarity error: ${JSON.stringify(errVal)}`);\n            }\n            // tuple (0x0c)\n            case 0x0c: {\n                // Simplified tuple parsing - return raw for now\n                return { value: hex };\n            }\n            default:\n                return { value: hex };\n        }\n    }\n}\n","/**\n * Veridex Protocol SDK - Stacks Post-Condition Builder\n *\n * Stacks Post-Conditions are a unique protocol-level safety feature.\n * They enforce spending constraints at the blockchain level, independent\n * of smart contract logic. This provides a third layer of protection:\n *\n * 1. SDK-level spending limits (off-chain, first check)\n * 2. Contract-level spending limits (on-chain, enforced in veridex-spoke sessions)\n * 3. Protocol-level Post-Conditions (Stacks-native, attached by SDK at tx broadcast)\n *\n * Post-conditions are attached to transactions before broadcast and are\n * validated by the Stacks node itself — they cannot be bypassed by contracts.\n */\n\nimport { isContractPrincipal, parseContractPrincipal } from './StacksAddressUtils.js';\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/** Post-condition comparison type */\nexport type PostConditionComparison =\n    | 'eq'    // Exactly equal\n    | 'gte'   // Greater than or equal\n    | 'lte'   // Less than or equal\n    | 'gt'    // Greater than\n    | 'lt';   // Less than\n\n/** STX post-condition */\nexport interface StxPostCondition {\n    type: 'stx';\n    principal: string;\n    comparison: PostConditionComparison;\n    amount: bigint;\n}\n\n/** Fungible token post-condition */\nexport interface FtPostCondition {\n    type: 'ft';\n    principal: string;\n    comparison: PostConditionComparison;\n    amount: bigint;\n    contractAddress: string;\n    contractName: string;\n    tokenName: string;\n}\n\n/** Non-fungible token post-condition */\nexport interface NftPostCondition {\n    type: 'nft';\n    principal: string;\n    contractAddress: string;\n    contractName: string;\n    tokenName: string;\n    assetId: string;\n    owns: boolean;\n}\n\nexport type PostCondition = StxPostCondition | FtPostCondition | NftPostCondition;\n\n// ============================================================================\n// Builder\n// ============================================================================\n\n/**\n * Build STX transfer post-conditions for vault withdrawals.\n * Ensures the contract sends exactly the specified amount.\n *\n * @param contractPrincipal - The vault contract principal (e.g., \"ST1PQHQKV...veridex-vault\")\n * @param amount - Exact amount in microSTX\n * @returns Array of post-conditions to attach to the transaction\n */\nexport function buildStxWithdrawalPostConditions(\n    contractPrincipal: string,\n    amount: bigint\n): StxPostCondition[] {\n    return [\n        {\n            type: 'stx',\n            principal: contractPrincipal,\n            comparison: 'eq',\n            amount,\n        },\n    ];\n}\n\n/**\n * Build STX deposit post-conditions.\n * Ensures the sender sends exactly the specified amount to the vault.\n *\n * @param senderPrincipal - The depositor's principal address\n * @param amount - Exact amount in microSTX\n * @returns Array of post-conditions\n */\nexport function buildStxDepositPostConditions(\n    senderPrincipal: string,\n    amount: bigint\n): StxPostCondition[] {\n    return [\n        {\n            type: 'stx',\n            principal: senderPrincipal,\n            comparison: 'eq',\n            amount,\n        },\n    ];\n}\n\n/**\n * Build sBTC transfer post-conditions for vault withdrawals.\n *\n * @param contractPrincipal - The vault contract principal\n * @param amount - Exact amount in satoshis\n * @param sbtcContractAddress - sBTC token contract deployer address\n * @param sbtcContractName - sBTC token contract name (default: 'sbtc-token')\n * @returns Array of post-conditions\n */\nexport function buildSbtcWithdrawalPostConditions(\n    contractPrincipal: string,\n    amount: bigint,\n    sbtcContractAddress: string = 'SM3VDXK3WZZSA84XXFKAFAF15NNZX32CTSG82JFQ4',\n    sbtcContractName: string = 'sbtc-token'\n): FtPostCondition[] {\n    return [\n        {\n            type: 'ft',\n            principal: contractPrincipal,\n            comparison: 'eq',\n            amount,\n            contractAddress: sbtcContractAddress,\n            contractName: sbtcContractName,\n            tokenName: 'sbtc-token',\n        },\n    ];\n}\n\n/**\n * Build post-conditions for a session-authorized execute action.\n * Combines STX or sBTC post-conditions based on action type.\n *\n * @param actionType - 1 = STX transfer, 2 = sBTC transfer\n * @param contractPrincipal - The spoke/vault contract principal\n * @param amount - Amount in base units\n * @returns Array of post-conditions\n */\nexport function buildExecutePostConditions(\n    actionType: number,\n    contractPrincipal: string,\n    amount: bigint\n): PostCondition[] {\n    switch (actionType) {\n        case 1: // ACTION-TRANSFER-STX\n            return buildStxWithdrawalPostConditions(contractPrincipal, amount);\n        case 2: // ACTION-TRANSFER-SBTC\n            return buildSbtcWithdrawalPostConditions(contractPrincipal, amount);\n        default:\n            return [];\n    }\n}\n\n/**\n * Validate that a set of post-conditions is present and reasonable.\n * Used to reject transactions that lack post-conditions for asset transfers.\n *\n * @param postConditions - Array of post-conditions to validate\n * @param expectedAmount - Expected transfer amount\n * @returns Validation result with error message if invalid\n */\nexport function validatePostConditions(\n    postConditions: PostCondition[],\n    expectedAmount: bigint\n): { valid: boolean; error?: string } {\n    if (postConditions.length === 0) {\n        return {\n            valid: false,\n            error: 'No post-conditions attached. Asset transfers require post-conditions for safety.',\n        };\n    }\n\n    // Check that at least one post-condition matches the expected amount\n    const hasMatchingAmount = postConditions.some((pc) => {\n        if (pc.type === 'stx' || pc.type === 'ft') {\n            return pc.amount === expectedAmount && pc.comparison === 'eq';\n        }\n        return false;\n    });\n\n    if (!hasMatchingAmount) {\n        return {\n            valid: false,\n            error: `No post-condition matches expected amount ${expectedAmount}. Ensure exact-match post-conditions are attached.`,\n        };\n    }\n\n    return { valid: true };\n}\n\n/**\n * Get the contract address and name from a principal for post-condition construction.\n * Handles both standard and contract principals.\n *\n * @param principal - Stacks principal (standard or contract)\n * @returns Object with address and optional contractName\n */\nexport function principalForPostCondition(principal: string): {\n    address: string;\n    contractName?: string;\n} {\n    if (isContractPrincipal(principal)) {\n        const parsed = parseContractPrincipal(principal);\n        return { address: parsed.address, contractName: parsed.contractName };\n    }\n    return { address: principal };\n}\n"],"mappings":"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","names":[]}