{"version":3,"sources":["../src/chains/sui/SuiClient.ts"],"sourcesContent":["/**\n * Veridex Protocol SDK - Sui Chain Client\n *\n * Production-grade implementation of ChainClient interface for Sui.\n * Supports session management, query-based execution, and vault operations.\n *\n * Security:\n * - Native sui::ecdsa_k1::secp256k1_verify for signature validation\n * - CCQ-based session validation with 60s staleness window\n * - Replay protection via nonce verification\n *\n * Note: Sui is a spoke chain. Session registration/revocation happens on Hub.\n */\n\nimport { SuiClient as MystenSuiClient } from '@mysten/sui/client';\nimport { createHash } from 'crypto';\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';\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface SuiClientConfig {\n    wormholeChainId: number;\n    rpcUrl: string;\n    packageId: string; // Veridex Spoke package ID\n    wormholeCoreBridge: string;\n    tokenBridge?: string;\n    network?: 'mainnet' | 'testnet' | 'devnet';\n    hubRpcUrl?: string; // Hub chain RPC for session management\n    hubContractAddress?: string; // Hub contract for session management\n}\n\n// ============================================================================\n// SuiClient\n// ============================================================================\n\nexport class SuiClient implements ChainClient {\n    private config: ChainConfig;\n    private client: MystenSuiClient;\n    private packageId: string;\n    private hubRpcUrl?: string;\n    private hubContractAddress?: string;\n\n    constructor(config: SuiClientConfig) {\n        this.config = {\n            name: `Sui ${config.network || 'mainnet'}`,\n            chainId: 0,\n            wormholeChainId: config.wormholeChainId,\n            rpcUrl: config.rpcUrl,\n            explorerUrl: config.network === 'testnet'\n                ? 'https://suiscan.xyz/testnet'\n                : config.network === 'devnet'\n                    ? 'https://suiscan.xyz/devnet'\n                    : 'https://suiscan.xyz/mainnet',\n            isEvm: false,\n            contracts: {\n                hub: config.packageId,\n                wormholeCoreBridge: config.wormholeCoreBridge,\n                tokenBridge: config.tokenBridge,\n            },\n        };\n\n        this.client = new MystenSuiClient({ url: config.rpcUrl });\n        this.packageId = config.packageId;\n        this.hubRpcUrl = config.hubRpcUrl;\n        this.hubContractAddress = config.hubContractAddress;\n    }\n\n    getConfig(): ChainConfig {\n        return this.config;\n    }\n\n    async getNonce(_userKeyHash: string): Promise<bigint> {\n        // Nonce is managed on the Hub for cross-chain actions.\n        return 0n;\n    }\n\n    async getMessageFee(): Promise<bigint> {\n        // Wormhole fees for Sui are generally handled by relayer submission.\n        return 0n;\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    async dispatch(\n        signature: WebAuthnSignature,\n        publicKeyX: bigint,\n        publicKeyY: bigint,\n        targetChain: number,\n        actionPayload: string,\n        nonce: bigint,\n        signer: any\n    ): Promise<DispatchResult> {\n        void signature;\n        void publicKeyX;\n        void publicKeyY;\n        void targetChain;\n        void actionPayload;\n        void nonce;\n        void signer;\n        throw new Error(\n            'Direct dispatch not supported on Sui spoke chains. ' +\n            'Actions must be dispatched from the Hub (EVM) chain. '\n        );\n    }\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 = this.computeKeyHash(publicKeyX, publicKeyY);\n        const messageHash = this.buildMessageHash(keyHash, targetChain, actionPayload, nonce);\n\n        const request = {\n            messageHash,\n            r: '0x' + signature.r.toString(16).padStart(64, '0'),\n            s: '0x' + signature.s.toString(16).padStart(64, '0'),\n            publicKeyX: '0x' + publicKeyX.toString(16).padStart(64, '0'),\n            publicKeyY: '0x' + publicKeyY.toString(16).padStart(64, '0'),\n            targetChain,\n            actionPayload,\n            nonce: 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            throw new Error(`Relayer submission failed: ${response.status} ${response.statusText}`);\n        }\n\n        const result = await response.json();\n\n        return {\n            transactionHash: result.transactionHash ?? result.txHash,\n            sequence: BigInt(result.sequence || 0),\n            userKeyHash: keyHash,\n            targetChain,\n        };\n    }\n\n    async getVaultAddress(userKeyHash: string): Promise<string | null> {\n        // Sui vaults may be represented as shared objects on-chain; without registry object IDs,\n        // we return the deterministic address used by the SDK for receiving and balance display.\n        return this.computeVaultAddress(userKeyHash);\n    }\n\n    computeVaultAddress(userKeyHash: string): string {\n        // SDK convention: Sui addresses are 32-byte hex with 0x prefix.\n        const clean = userKeyHash.replace(/^0x/, '').padStart(64, '0');\n        return '0x' + clean;\n    }\n\n    async vaultExists(_userKeyHash: string): Promise<boolean> {\n        // Account addresses on Sui are implicit; treat as existing.\n        return true;\n    }\n\n    async createVault(userKeyHash: string, signer: any): Promise<VaultCreationResult> {\n        void signer;\n        throw new Error(\n            'Vault creation on Sui must be done via cross-chain message from Hub. ' +\n            `Use the Hub client to dispatch a vault creation action targeting Sui (chain ${this.config.wormholeChainId}). KeyHash=${userKeyHash}`\n        );\n    }\n\n    async createVaultSponsored?(userKeyHash: string, sponsorPrivateKey: string, rpcUrl?: string): Promise<VaultCreationResult> {\n        void userKeyHash;\n        void sponsorPrivateKey;\n        void rpcUrl;\n        throw new Error(\n            'Vault creation on Sui must be done via cross-chain message from Hub. ' +\n            'Use relayer gasless submission to create vault.'\n        );\n    }\n\n    /**\n     * Create a vault via the relayer (sponsored/gasless)\n     * This is the recommended way to create Sui vaults\n     * \n     * The relayer will dispatch a vault creation action from Hub to Sui spoke\n     */\n    async createVaultViaRelayer(\n        userKeyHash: string,\n        relayerUrl: string\n    ): Promise<VaultCreationResult> {\n        const response = await fetch(`${relayerUrl}/api/v1/sui/vault`, {\n            method: 'POST',\n            headers: {\n                'Content-Type': 'application/json',\n            },\n            body: JSON.stringify({\n                userKeyHash,\n                chainId: this.config.wormholeChainId,\n            }),\n        });\n\n        const result = await response.json();\n\n        if (!response.ok || !result.success) {\n            throw new Error(result.error || 'Failed to create vault via relayer');\n        }\n\n        return {\n            address: result.vaultAddress,\n            transactionHash: result.transactionHash || '',\n            blockNumber: 0,\n            gasUsed: 0n,\n            alreadyExisted: result.alreadyExists || false,\n            sponsoredBy: 'relayer',\n        };\n    }\n\n    /**\n     * Get vault info via relayer (includes existence check)\n     */\n    async getVaultViaRelayer(\n        userKeyHash: string,\n        relayerUrl: string\n    ): Promise<{ vaultAddress: string; exists: boolean }> {\n        const response = await fetch(\n            `${relayerUrl}/api/v1/sui/vault/${userKeyHash}?chainId=${this.config.wormholeChainId}`\n        );\n\n        if (!response.ok) {\n            throw new Error('Failed to get vault info from relayer');\n        }\n\n        const result = await response.json();\n        return {\n            vaultAddress: result.vaultAddress,\n            exists: result.exists,\n        };\n    }\n\n    async estimateVaultCreationGas(_userKeyHash: string): Promise<bigint> {\n        // Best-effort placeholder.\n        return 5_000n;\n    }\n\n    getFactoryAddress(): string | undefined {\n        return undefined;\n    }\n\n    getImplementationAddress(): string | undefined {\n        return undefined;\n    }\n\n    // ========================================================================\n    // Balance utilities (used by VeridexSDK multichain)\n    // ========================================================================\n\n    async getNativeBalance(address: string): Promise<bigint> {\n        const balance = await this.client.getBalance({ owner: address });\n        return BigInt(balance.totalBalance);\n    }\n\n    async getTokenBalance(coinType: string, ownerAddress: string): Promise<bigint> {\n        const balance = await this.client.getBalance({ owner: ownerAddress, coinType });\n        return BigInt(balance.totalBalance);\n    }\n\n    getClient(): MystenSuiClient {\n        return this.client;\n    }\n\n    getPackageId(): string {\n        return this.packageId;\n    }\n\n    // ========================================================================\n    // Session Management (Issue #13)\n    // ========================================================================\n\n    /**\n     * Register a session key on the Hub (must be called via Hub client)\n     * Sui spokes validate sessions via CCQ, but registration happens on Hub\n     * \n     * @throws Error - Session management must be done via Hub chain\n     */\n    async registerSession(_params: RegisterSessionParams): Promise<void> {\n        throw new Error(\n            'Session registration must be performed on the Hub chain (Base). ' +\n            'Use EVMClient connected to the Hub to call registerSession().'\n        );\n    }\n\n    /**\n     * Revoke a session key on the Hub (must be called via Hub client)\n     * \n     * @throws Error - Session management must be done via Hub chain\n     */\n    async revokeSession(_params: RevokeSessionParams): Promise<void> {\n        throw new Error(\n            'Session revocation must be performed on the Hub chain (Base). ' +\n            'Use EVMClient connected to the Hub to call revokeSession().'\n        );\n    }\n\n    /**\n     * Check if a session is active by querying the Hub\n     * This method queries the Hub contract directly for session validation\n     * \n     * @param userKeyHash - Hash of user's Passkey public key\n     * @param sessionKeyHash - Hash of session key to validate\n     * @returns Session validation result with expiry and limits\n     */\n    async isSessionActive(\n        _userKeyHash: string,\n        _sessionKeyHash: string\n    ): Promise<SessionValidationResult> {\n        if (!this.hubRpcUrl || !this.hubContractAddress) {\n            throw new Error(\n                'Hub configuration required for session validation. ' +\n                'Provide hubRpcUrl and hubContractAddress in SuiClientConfig.'\n            );\n        }\n\n        // Query Hub contract for session status\n        // This would normally use ethers.js to query the Hub contract\n        // For production, import ethers dynamically or pass Hub client\n        throw new Error(\n            'isSessionActive requires Hub client integration. ' +\n            'Use EVMClient.isSessionActive() on the Hub chain, ' +\n            'then pass the result to session execution on Sui.'\n        );\n    }\n\n    /**\n     * Get all sessions for a user from the Hub\n     * \n     * @param userKeyHash - Hash of user's Passkey public key\n     * @returns Array of all sessions (active and expired/revoked)\n     */\n    async getUserSessions(userKeyHash: string): Promise<SessionKey[]> {\n        if (!this.hubRpcUrl || !this.hubContractAddress) {\n            throw new Error(\n                'Hub configuration required for session queries. ' +\n                'Provide hubRpcUrl and hubContractAddress in SuiClientConfig.'\n            );\n        }\n\n        // Query Hub contract for user sessions\n        throw new Error(\n            'getUserSessions requires Hub client integration. ' +\n            'Use EVMClient.getUserSessions() on the Hub chain. ' +\n            `User: ${userKeyHash}`\n        );\n    }\n\n    // ========================================================================\n    // Query-Based Execution (Issue #9/#10)\n    // ========================================================================\n\n    /**\n     * Get user state from Hub (comprehensive state query)\n     * Returns key hash, nonce, and last action hash for CCQ validation\n     * \n     * @param userKeyHash - Hash of user's Passkey public key\n     * @returns User state with nonce and last action hash\n     */\n    async getUserState(userKeyHash: string): Promise<{\n        keyHash: string;\n        nonce: bigint;\n        lastActionHash: string;\n    }> {\n        if (!this.hubRpcUrl || !this.hubContractAddress) {\n            throw new Error(\n                'Hub configuration required for state queries. ' +\n                'Provide hubRpcUrl and hubContractAddress in SuiClientConfig.'\n            );\n        }\n\n        // Query Hub contract for user state\n        // This enables query-based execution with CCQ validation\n        throw new Error(\n            'getUserState requires Hub client integration. ' +\n            'Use EVMClient.getUserState() on the Hub chain. ' +\n            `User: ${userKeyHash}`\n        );\n    }\n\n    /**\n     * Get user's last action hash from Hub\n     * Used for optimistic execution and nonce validation\n     * \n     * @param userKeyHash - Hash of user's Passkey public key\n     * @returns Last action hash (zero hash if no actions)\n     */\n    async getUserLastActionHash(userKeyHash: string): Promise<string> {\n        if (!this.hubRpcUrl || !this.hubContractAddress) {\n            throw new Error(\n                'Hub configuration required for action hash queries. ' +\n                'Provide hubRpcUrl and hubContractAddress in SuiClientConfig.'\n            );\n        }\n\n        // Query Hub contract for last action hash\n        throw new Error(\n            'getUserLastActionHash requires Hub client integration. ' +\n            'Use EVMClient.getUserLastActionHash() on the Hub chain. ' +\n            `User: ${userKeyHash}`\n        );\n    }\n\n    /**\n     * Execute with query-based validation (faster than VAA, ~23s vs 60-90s)\n     * Uses Wormhole CCQ to validate Hub state, then executes on Sui\n     * \n     * @param params Query execution parameters with CCQ response\n     * @returns Dispatch result with transaction hash\n     * \n     * @remarks\n     * Query-based execution flow:\n     * 1. Query Hub state via Wormhole CCQ\n     * 2. Validate Guardian signatures on query response\n     * 3. Execute on Sui with validated state\n     * 4. Hub state must be < 60s stale (enforced by QueryVerifier)\n     */\n    async executeWithQuery(\n        _params: {\n            userKeyHash: string;\n            queryResponse: Uint8Array; // CCQ Guardian response\n            actionType: number;\n            actionPayload: Uint8Array;\n            relayerUrl?: string;\n        }\n    ): Promise<DispatchResult> {\n        throw new Error(\n            'Query-based execution on Sui requires relayer integration. ' +\n            'Use relayer API to submit query-validated transactions. ' +\n            'Relayer will call veridex_spoke::execute_with_query on Sui.'\n        );\n    }\n\n    // ========================================================================\n    // Internal helpers\n    // ========================================================================\n\n    private computeKeyHash(publicKeyX: bigint, publicKeyY: bigint): string {\n        const xHex = publicKeyX.toString(16).padStart(64, '0');\n        const yHex = publicKeyY.toString(16).padStart(64, '0');\n        const combined = Buffer.from(xHex + yHex, 'hex');\n        const hash = createHash('sha256').update(combined).digest('hex');\n        return '0x' + hash;\n    }\n\n    private buildMessageHash(keyHash: string, targetChain: number, actionPayload: string, nonce: bigint): string {\n        const keyHashBuffer = Buffer.from(keyHash.replace(/^0x/, ''), 'hex');\n        const targetChainBuffer = Buffer.alloc(2);\n        targetChainBuffer.writeUInt16BE(targetChain);\n        const payloadBuffer = Buffer.from(actionPayload.replace(/^0x/, ''), 'hex');\n        const nonceHex = nonce.toString(16).padStart(64, '0');\n        const nonceBuffer = Buffer.from(nonceHex, 'hex');\n\n        const combined = Buffer.concat([keyHashBuffer, targetChainBuffer, payloadBuffer, nonceBuffer]);\n        const hash = createHash('sha256').update(combined).digest('hex');\n        return '0x' + hash;\n    }\n\n    // ============================================================================\n    // Social Recovery Methods (Issue #23)\n    // ============================================================================\n    // \n    // Note: Social recovery is managed on the Hub chain (EVM).\n    // Sui spokes receive and execute recovery VAAs broadcast from the Hub.\n    // The relayer service handles submitting recovery transactions to Sui.\n    //\n    // SDK users should use EVMClient methods for guardian management and\n    // recovery initiation on the Hub chain.\n    // ============================================================================\n\n    /**\n     * Get vault object ID by owner key hash\n     * \n     * @param ownerKeyHash - Owner's passkey hash (32 bytes as hex)\n     * @param configObjectId - Shared Config object ID\n     * @param registryObjectId - Shared VaultRegistry object ID\n     * @returns Vault object ID or null if not found\n     */\n    async getVaultId(\n        _ownerKeyHash: string,\n        registryObjectId: string\n    ): Promise<string | null> {\n        try {\n            // Query the VaultRegistry table for the owner_key_hash\n            // The registry maps owner_key_hash -> vault ID\n            const registryObject = await this.client.getObject({\n                id: registryObjectId,\n                options: { showContent: true },\n            });\n\n            if (!registryObject.data?.content) {\n                return null;\n            }\n\n            // For a proper implementation, we'd need to query dynamic fields\n            // or use a Move view function. This is a placeholder showing the pattern.\n            console.warn('getVaultId requires dynamic field query - use Move view function');\n            return null;\n        } catch (error) {\n            console.error('Error getting vault ID:', error);\n            return null;\n        }\n    }\n\n    /**\n     * Get vault owner key hash from vault object\n     * \n     * @param vaultObjectId - Vault object ID\n     * @returns Owner key hash as hex string\n     */\n    async getVaultOwner(vaultObjectId: string): Promise<string | null> {\n        try {\n            const vaultObject = await this.client.getObject({\n                id: vaultObjectId,\n                options: { showContent: true },\n            });\n\n            if (!vaultObject.data?.content || vaultObject.data.content.dataType !== 'moveObject') {\n                return null;\n            }\n\n            const fields = vaultObject.data.content.fields as Record<string, unknown>;\n            const ownerKeyHash = fields['owner_key_hash'] as number[] | undefined;\n\n            if (!ownerKeyHash) {\n                return null;\n            }\n\n            // Convert byte array to hex string\n            return '0x' + Buffer.from(ownerKeyHash).toString('hex');\n        } catch (error) {\n            console.error('Error getting vault owner:', error);\n            return null;\n        }\n    }\n\n    /**\n     * Get authorized signers for a vault\n     * \n     * @param vaultObjectId - Vault object ID\n     * @returns Array of authorized signer key hashes\n     */\n    async getAuthorizedSigners(vaultObjectId: string): Promise<string[]> {\n        try {\n            const vaultObject = await this.client.getObject({\n                id: vaultObjectId,\n                options: { showContent: true },\n            });\n\n            if (!vaultObject.data?.content || vaultObject.data.content.dataType !== 'moveObject') {\n                return [];\n            }\n\n            const fields = vaultObject.data.content.fields as Record<string, unknown>;\n            const authorizedSigners = fields['authorized_signers'] as number[][] | undefined;\n\n            if (!authorizedSigners) {\n                return [];\n            }\n\n            // Convert each byte array to hex string\n            return authorizedSigners.map(signer => \n                '0x' + Buffer.from(signer).toString('hex')\n            );\n        } catch (error) {\n            console.error('Error getting authorized signers:', error);\n            return [];\n        }\n    }\n\n    /**\n     * Check if a VAA has been processed (for replay protection)\n     * \n     * @param vaaHash - VAA hash as hex string\n     * @param processedVaasObjectId - ProcessedVAAs shared object ID\n     * @returns Whether the VAA has been processed\n     */\n    async isVaaProcessed(\n        _vaaHash: string,\n        processedVaasObjectId: string\n    ): Promise<boolean> {\n        try {\n            const processedObject = await this.client.getObject({\n                id: processedVaasObjectId,\n                options: { showContent: true },\n            });\n\n            if (!processedObject.data?.content) {\n                return false;\n            }\n\n            // Would need to query dynamic field for vaaHash key\n            console.warn('isVaaProcessed requires dynamic field query');\n            return false;\n        } catch (error) {\n            console.error('Error checking VAA status:', error);\n            return false;\n        }\n    }\n\n    /**\n     * Check if protocol is paused\n     * \n     * @param configObjectId - Config shared object ID\n     * @returns Whether the protocol is paused\n     */\n    async isProtocolPaused(configObjectId: string): Promise<boolean> {\n        try {\n            const configObject = await this.client.getObject({\n                id: configObjectId,\n                options: { showContent: true },\n            });\n\n            if (!configObject.data?.content || configObject.data.content.dataType !== 'moveObject') {\n                return false;\n            }\n\n            const fields = configObject.data.content.fields as Record<string, unknown>;\n            return fields['paused'] === true;\n        } catch (error) {\n            console.error('Error checking pause status:', error);\n            return false;\n        }\n    }\n}\n"],"mappings":"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","names":[]}