{"version":3,"sources":["../src/attestation/constants.ts","../src/attestation/verifier.ts","../src/client.ts"],"names":["ATTESTATION_CONSTANTS","MAX_ATTESTATION_AGE","NitroAttestationVerifier","config","wasmInitialized","strictCertValidation","maxAge","ensureWasmInitialized","init","error","Error","message","verify","attestationDocBase64","expectedChallenge","expectedNonce","expectedPcrs","PCRs","empty","pcr8","expectedPcr8","isValid","validateAttestationDocPcrs","valid","errors","timestamp","Date","now","userData","getUserData","userDataString","TextDecoder","decode","includes","String","extractedNonceRaw","getNonce","extractedNonce","nonceString","atob","binaryString","Uint8Array","length","i","charCodeAt","decodedBuffer","Buffer","from","decodeError","isWindow","globalThis","window","WebSocketImpl","WebSocket","ForwardMPCClient","EventEmitter","ws","url","options","attestationVerifier","isConnected","messageId","pendingRequests","Map","sharedSecret","decapsulationKey","connectionId","handshakeNonce","reconnectAttempts","reconnectInterval","connectionTimeout","heartbeatInterval","attestationConfig","connect","Promise","resolve","reject","timeout","setTimeout","onopen","clearTimeout","emit","onerror","_error","onmessage","event","handleMessage","data","onclose","cleanup","on","toString","disconnect","close","request","clear","fill","ensureWsConnection","handshake","parsed","JSON","parse","requestId","deserializeMessage","stringify","has","get","delete","type","errorMsg","endsWith","responseData","getData","sendRequest","messageWithId","set","serializedMessage","serializeMessage","send","encode","encoded","messageRegistry","result","either","isLeft","right","encapsulationKey","generateMlKem768Keypair","nonceBytes","randomBytes","HandshakeV1RequestMessage","challenge","nonce","response","encapsulatedSharedSecret","cipherText","hexToBytes","decapsulateMlKem768","attestationDoc","verifyAttestationDocument","catch","signMessage","params","messageToSign","cleanHex","startsWith","slice","encryptedKeyshare","encryptKeyshare","keyshare","signingAlgo","SignMessageV1RequestMessage","relayDomain","hashAlgo","derivationPath","tweak","roomUuid","connected","challengeHash","sha256","Array","map","b","padStart","join"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * AWS Nitro Security Module (NSM) Root Certificate\n * This is the official AWS root certificate used to verify attestation documents\n */\nexport const AWS_NITRO_ROOT_CERTIFICATE = `-----BEGIN CERTIFICATE-----\nMIICETCCAZagAwIBAgIRAPkxdWgbkK/hHUbMtOTn+FYwCgYIKoZIzj0EAwMwSTEL\nMAkGA1UEBhMCVVMxDzANBgNVBAoMBkFtYXpvbjEMMAoGA1UECwwDQVdTMRswGQYD\nVQQDDBJhd3Mubml0cm8tZW5jbGF2ZXMwHhcNMTkxMDI4MTMyODA1WhcNNDkxMDI4\nMTQyODA1WjBJMQswCQYDVQQGEwJVUzEPMA0GA1UECgwGQW1hem9uMQwwCgYDVQQL\nDANBV1MxGzAZBgNVBAMMEmF3cy5uaXRyby1lbmNsYXZlczB2MBAGByqGSM49AgEG\nBSuBBAAiA2IABPwCVOumCMHzaHDimtqQvkY4MpJzbolL//Zy2YlES1BR5TSksfbb\n48C8WBoyt7F2Bw7eEtaaP+ohG2bnUs990d0JX28TcPQXCEPZ3BABIeTPYwEoCWZE\nh8l5YoQwTcU/9KNCMEAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUkCW1DdkF\nR+eWw5b6cp3PmanfS5YwDgYDVR0PAQH/BAQDAgGGMAoGCCqGSM49BAMDA2kAMGYC\nMQCjfy+Rocm9Xue4YnwWmNJVA44fA0P5W2OpYow9OYCVRaEevL8uO1XYru5xtMPW\nrfMCMQCi85sWBbJwKKXdS6BptQFuZbT73o/gBh1qUxl/nNr12UO8Yfwr6wPLb+6N\nIwLz3/Y=\n-----END CERTIFICATE-----`;\n\n/**\n * Expected PCR values for different environments\n */\nexport const EXPECTED_PCR_VALUES = {\n  // Production PCR8 values would be set based on actual enclave builds\n  // These would be configured via environment variables in production\n  // Development values should be set in the application configuration, not here\n} as const;\n\n/**\n * Attestation document validation constants\n */\nexport const ATTESTATION_CONSTANTS = {\n  // Maximum age of attestation document in milliseconds\n  MAX_ATTESTATION_AGE: 5 * 60 * 1000, // 5 minutes\n\n  // Expected digest algorithm\n  EXPECTED_DIGEST: 'SHA384',\n\n  // Expected module ID pattern\n  MODULE_ID_PATTERN: /^i-[0-9a-f]{8,17}-enc[0-9a-f]{8,17}$/,\n\n  // PCR indices that must be present\n  REQUIRED_PCRS: [0, 1, 2, 8] as const,\n} as const;\n","import {\n  AttestationVerificationResult,\n  AttestationVerificationConfig,\n} from './types';\nimport { ATTESTATION_CONSTANTS } from './constants';\n\n// Import Evervault WASM attestation bindings\nimport init, {\n  validateAttestationDocPcrs,\n  PCRs,\n  getUserData,\n  getNonce,\n} from '@evervault/wasm-attestation-bindings';\n\n/**\n * Nitro Enclave Attestation Document Verifier\n * Uses Evervault's official WASM attestation bindings\n * Optimized for client-side usage with hex string input\n */\nexport class NitroAttestationVerifier {\n  private readonly config: AttestationVerificationConfig;\n  private wasmInitialized = false;\n\n  constructor(config: AttestationVerificationConfig) {\n    this.config = {\n      strictCertValidation: true,\n      maxAge: ATTESTATION_CONSTANTS.MAX_ATTESTATION_AGE,\n      ...config,\n    };\n  }\n\n  /**\n   * Initialize WASM module if not already initialized\n   */\n  private async ensureWasmInitialized(): Promise<void> {\n    if (!this.wasmInitialized) {\n      try {\n        // Initialize WASM module - in browser, this will automatically load the .wasm file\n        await init();\n        this.wasmInitialized = true;\n      } catch (error) {\n        throw new Error(\n          `Failed to initialize WASM module: ${error instanceof Error ? error.message : 'Unknown error'}`\n        );\n      }\n    }\n  }\n\n  /**\n   * Verify an attestation document using Evervault WASM bindings\n   * Accepts base64-encoded attestation document directly\n   *\n   * @param attestationDocBase64 - Base64-encoded attestation document\n   * @param expectedChallenge - Expected challenge (ciphertext hash)\n   * @param expectedNonce - Expected nonce (REQUIRED for security)\n   */\n  async verify(\n    attestationDocBase64: string,\n    expectedChallenge: string,\n    expectedNonce: Uint8Array\n  ): Promise<AttestationVerificationResult> {\n    try {\n      // Ensure WASM module is initialized\n      await this.ensureWasmInitialized();\n\n      // Create PCRs container with expected values\n      const expectedPcrs = PCRs.empty();\n      expectedPcrs.pcr8 = this.config.expectedPcr8;\n\n      // Use Evervault WASM bindings to verify the attestation document (already in base64)\n      const isValid = validateAttestationDocPcrs(attestationDocBase64, [\n        expectedPcrs,\n      ]);\n\n      if (!isValid) {\n        return {\n          valid: false,\n          errors: ['Attestation document PCR verification failed'],\n          timestamp: Date.now(),\n        };\n      }\n\n      // Verify challenge (ciphertext hash) if provided\n      if (expectedChallenge) {\n        try {\n          const userData = getUserData(attestationDocBase64);\n          if (!userData) {\n            return {\n              valid: false,\n              errors: ['No user data found in attestation document'],\n              timestamp: Date.now(),\n            };\n          }\n\n          // Convert user data to string and verify it contains the expected challenge\n          const userDataString = new TextDecoder('utf-8').decode(userData);\n\n          // The challenge should be the hex-encoded hash of the ciphertext\n          // Verify that the attestation document's user data contains this challenge\n          if (!userDataString.includes(expectedChallenge)) {\n            return {\n              valid: false,\n              errors: [\n                'Ciphertext hash verification failed - challenge not found in attestation user data',\n              ],\n              timestamp: Date.now(),\n            };\n          }\n        } catch (error) {\n          return {\n            valid: false,\n            errors: [\n              `Failed to extract or verify ciphertext hash: ${error instanceof Error ? error.message : String(error)}`,\n            ],\n            timestamp: Date.now(),\n          };\n        }\n      }\n\n      // Verify nonce (REQUIRED for security - prevents replay attacks)\n      try {\n        // Use WASM getNonce function to extract nonce from attestation document\n        const extractedNonceRaw = getNonce(attestationDocBase64);\n\n        if (!extractedNonceRaw) {\n          return {\n            valid: false,\n            errors: ['No nonce found in attestation document'],\n            timestamp: Date.now(),\n          };\n        }\n\n        // The attestation document stores the nonce as a base64-encoded string\n        // We need to decode it back to the original bytes\n        let extractedNonce: Uint8Array;\n        try {\n          // Convert to string and decode from base64 (cross-platform)\n          const nonceString = new TextDecoder().decode(extractedNonceRaw);\n\n          // Browser-compatible base64 decoding\n          if (typeof atob !== 'undefined') {\n            // Browser environment\n            const binaryString = atob(nonceString);\n            extractedNonce = new Uint8Array(binaryString.length);\n            for (let i = 0; i < binaryString.length; i++) {\n              extractedNonce[i] = binaryString.charCodeAt(i);\n            }\n          } else {\n            // Node.js environment\n            const decodedBuffer = Buffer.from(nonceString, 'base64');\n            extractedNonce = new Uint8Array(decodedBuffer);\n          }\n        } catch (decodeError) {\n          return {\n            valid: false,\n            errors: [\n              `Failed to decode nonce from base64: ${decodeError instanceof Error ? decodeError.message : String(decodeError)}`,\n            ],\n            timestamp: Date.now(),\n          };\n        }\n\n        // Compare nonces byte-for-byte\n        if (extractedNonce.length !== expectedNonce.length) {\n          return {\n            valid: false,\n            errors: [\n              `Nonce length mismatch: expected ${expectedNonce.length} bytes, got ${extractedNonce.length} bytes`,\n            ],\n            timestamp: Date.now(),\n          };\n        }\n\n        for (let i = 0; i < expectedNonce.length; i++) {\n          if (extractedNonce[i] !== expectedNonce[i]) {\n            return {\n              valid: false,\n              errors: ['Nonce verification failed - nonce mismatch'],\n              timestamp: Date.now(),\n            };\n          }\n        }\n      } catch (error) {\n        return {\n          valid: false,\n          errors: [\n            `Failed to extract or verify nonce: ${error instanceof Error ? error.message : String(error)}`,\n          ],\n          timestamp: Date.now(),\n        };\n      }\n\n      return {\n        valid: true,\n        errors: [],\n        timestamp: Date.now(),\n      };\n    } catch (error) {\n      return {\n        valid: false,\n        errors: [\n          `Attestation verification error: ${error instanceof Error ? error.message : String(error)}`,\n        ],\n        timestamp: Date.now(),\n      };\n    }\n  }\n}\n","// Browser/Node.js compatibility\nimport { EventEmitter } from 'eventemitter3';\nimport * as ws from 'ws';\n\nconst isWindow =\n  typeof globalThis !== 'undefined' &&\n  typeof (globalThis as any).window !== 'undefined';\nconst WebSocketImpl = isWindow ? (globalThis as any).WebSocket : ws.WebSocket;\n\nimport {\n  BaseWebSocketMessage,\n  ErrorResponse,\n} from '@dynamic-labs-wallet/forward-mpc-shared';\nimport {\n  HandshakeV1RequestMessage,\n  SignMessageV1RequestMessage,\n  messageRegistry,\n  HashAlgorithm,\n  generateMlKem768Keypair,\n  decapsulateMlKem768,\n  encryptKeyshare,\n  type SigningAlgorithmName,\n} from '@dynamic-labs-wallet/forward-mpc-shared';\nimport { NitroAttestationVerifier } from './attestation';\nimport { AttestationVerificationConfig } from './attestation/types';\nimport { sha256 } from '@noble/hashes/sha2.js';\nimport { hexToBytes, randomBytes } from '@noble/hashes/utils.js';\nimport { either } from 'fp-ts';\nimport { SigningAlgorithm } from '@dynamic-labs-wallet/core';\n\nexport interface ForwardMPCClientOptions {\n  reconnectAttempts?: number;\n  reconnectInterval?: number;\n  connectionTimeout?: number;\n  heartbeatInterval?: number;\n  attestationConfig?: AttestationVerificationConfig;\n  attestationVerifier?: any; // Allow custom verifier (mock or real)\n}\n\nexport interface ClientEvents {\n  connected: () => void;\n  disconnected: () => void;\n  error: (error: Error) => void;\n  message: (message: BaseWebSocketMessage) => void;\n}\n\nexport class ForwardMPCClient extends EventEmitter {\n  private ws: any = null;\n  private url: string;\n  private options: Required<\n    Omit<ForwardMPCClientOptions, 'attestationVerifier' | 'attestationConfig'>\n  > & {\n    attestationVerifier?: any;\n    attestationConfig?: AttestationVerificationConfig;\n  };\n  private attestationVerifier: any | null = null; // Can be NitroAttestationVerifier or mock\n  private isConnected = false;\n  private messageId = 0;\n  private pendingRequests = new Map<\n    string,\n    {\n      resolve: (value: any) => void;\n      reject: (error: Error) => void;\n      timeout: NodeJS.Timeout;\n    }\n  >();\n  private sharedSecret: Uint8Array | null = null;\n  private decapsulationKey: Uint8Array | null = null;\n  private connectionId: string;\n  private handshakeNonce: Uint8Array | null = null;\n\n  constructor(url: string, options: ForwardMPCClientOptions = {}) {\n    super();\n\n    this.url = url;\n    this.connectionId = ''; // Will be set by server during handshake\n    this.options = {\n      reconnectAttempts: options.reconnectAttempts ?? 3,\n      reconnectInterval: options.reconnectInterval ?? 1000,\n      connectionTimeout: options.connectionTimeout ?? 10000,\n      heartbeatInterval: options.heartbeatInterval ?? 30000,\n      attestationConfig: options.attestationConfig,\n      attestationVerifier: options.attestationVerifier,\n    };\n\n    // Initialize attestation verifier - use custom verifier if provided, otherwise create from config\n    if (options.attestationVerifier) {\n      this.attestationVerifier = options.attestationVerifier;\n    } else if (this.options.attestationConfig) {\n      this.attestationVerifier = new NitroAttestationVerifier(\n        this.options.attestationConfig\n      );\n    }\n  }\n\n  async connect(): Promise<void> {\n    return new Promise((resolve, reject) => {\n      if (this.isConnected) {\n        resolve();\n        return;\n      }\n\n      const timeout = setTimeout(() => {\n        reject(new Error('Connection timeout'));\n      }, this.options.connectionTimeout);\n\n      this.ws = new WebSocketImpl(this.url);\n\n      // Handle both browser and Node.js WebSocket APIs\n      if (isWindow) {\n        // Browser WebSocket API\n        this.ws.onopen = () => {\n          clearTimeout(timeout);\n          this.isConnected = true;\n          this.emit('connected');\n          resolve();\n        };\n\n        this.ws.onerror = (_error: any) => {\n          clearTimeout(timeout);\n          this.emit('error', new Error('WebSocket error'));\n          reject(new Error('WebSocket error'));\n        };\n\n        this.ws.onmessage = (event: any) => {\n          this.handleMessage(event.data);\n        };\n\n        this.ws.onclose = () => {\n          this.isConnected = false;\n          this.emit('disconnected');\n          this.cleanup();\n        };\n      } else {\n        // Node.js WebSocket API\n        this.ws.on('open', () => {\n          clearTimeout(timeout);\n          this.isConnected = true;\n          this.emit('connected');\n          resolve();\n        });\n\n        this.ws.on('error', (error: any) => {\n          clearTimeout(timeout);\n          this.emit('error', error);\n          reject(error);\n        });\n\n        this.ws.on('message', (data: any) => {\n          this.handleMessage(data.toString());\n        });\n\n        this.ws.on('close', () => {\n          this.isConnected = false;\n          this.emit('disconnected');\n          this.cleanup();\n        });\n      }\n    });\n  }\n\n  disconnect(): void {\n    if (this.ws) {\n      this.ws.close();\n      this.ws = null;\n    }\n    this.cleanup();\n  }\n\n  private cleanup(): void {\n    // Reject all pending requests\n    for (const [, request] of this.pendingRequests) {\n      clearTimeout(request.timeout);\n      request.reject(new Error('Connection closed'));\n    }\n    this.pendingRequests.clear();\n\n    // Clear sensitive cryptographic material\n    if (this.sharedSecret) {\n      this.sharedSecret.fill(0);\n      this.sharedSecret = null;\n    }\n    if (this.decapsulationKey) {\n      this.decapsulationKey.fill(0);\n      this.decapsulationKey = null;\n    }\n    if (this.handshakeNonce) {\n      this.handshakeNonce.fill(0);\n      this.handshakeNonce = null;\n    }\n\n    // Clear connection ID\n    this.connectionId = '';\n  }\n\n  /**\n   * Ensures the WebSocket connection is active and handshake is completed.\n   * Automatically connects and performs handshake if needed.\n   * @returns Object containing the shared secret and connection ID\n   * @throws Error if connection or handshake fails\n   */\n  async ensureWsConnection(): Promise<{\n    sharedSecret: Uint8Array;\n    connectionId: string;\n  }> {\n    // Check if we need to connect\n    if (!this.isConnected || !this.ws) {\n      await this.connect();\n    }\n\n    // Check if we need to perform handshake\n    if (!this.sharedSecret || !this.connectionId) {\n      await this.handshake();\n    }\n\n    // Final validation - should never happen but defensive check\n    if (!this.sharedSecret || !this.connectionId) {\n      throw new Error('Failed to establish connection and handshake');\n    }\n\n    return {\n      sharedSecret: this.sharedSecret,\n      connectionId: this.connectionId,\n    };\n  }\n\n  private handleMessage(data: string): void {\n    try {\n      // Parse the raw message first to extract requestId\n      const parsed = JSON.parse(data);\n      const requestId = parsed.requestId;\n\n      // Remove requestId from the message before deserializing\n      if (requestId) {\n        delete parsed.requestId;\n      }\n\n      // Now deserialize the message without requestId\n      const message = this.deserializeMessage(JSON.stringify(parsed));\n\n      // Check if this is a response to a pending request\n      if (requestId && this.pendingRequests.has(requestId)) {\n        const request = this.pendingRequests.get(requestId)!;\n        this.pendingRequests.delete(requestId);\n        clearTimeout(request.timeout);\n\n        // Handle unified response format with embedded errors\n        if (message.type === 'error') {\n          // Legacy error response format\n          const errorMsg = message as ErrorResponse;\n          request.reject(new Error(errorMsg.error.message));\n        } else if (message.type.endsWith('_response')) {\n          // Check if the response contains an error field\n          const responseData = (message as any).getData\n            ? (message as any).getData()\n            : message;\n          if (responseData.error) {\n            request.reject(new Error(responseData.error.message));\n          } else {\n            request.resolve(message);\n          }\n        } else {\n          request.resolve(message);\n        }\n        return;\n      }\n\n      this.emit('message', message);\n    } catch (error) {\n      this.emit('error', new Error(`Failed to parse message: ${error}`));\n    }\n  }\n\n  private sendRequest<T>(message: any): Promise<T> {\n    return new Promise((resolve, reject) => {\n      if (!this.isConnected || !this.ws) {\n        reject(new Error('Not connected'));\n        return;\n      }\n\n      const requestId = `req_${++this.messageId}_${Date.now()}`;\n      // Add requestId to message (works for both objects and Message instances)\n      const messageWithId = message;\n      messageWithId.requestId = requestId;\n\n      const timeout = setTimeout(() => {\n        this.pendingRequests.delete(requestId);\n        reject(new Error('Request timeout'));\n      }, 30000); // 30 second timeout for attestation verification\n\n      this.pendingRequests.set(requestId, { resolve, reject, timeout });\n\n      try {\n        // Use custom serializer that encodes using io-ts schemas\n        const serializedMessage = this.serializeMessage(messageWithId);\n        this.ws.send(serializedMessage);\n      } catch (error) {\n        this.pendingRequests.delete(requestId);\n        clearTimeout(timeout);\n        reject(error);\n      }\n    });\n  }\n\n  private serializeMessage(message: any): string {\n    try {\n      // If it's a Message class instance, use its encode method\n      if (message && typeof message.encode === 'function') {\n        const encoded = message.encode();\n        // Add requestId if present\n        if (message.requestId) {\n          encoded.requestId = message.requestId;\n        }\n        return JSON.stringify(encoded);\n      }\n\n      // Fallback to regular JSON for other objects\n      return JSON.stringify(message);\n    } catch (error) {\n      throw new Error(\n        `Failed to serialize message: ${\n          error instanceof Error ? error.message : String(error)\n        }`\n      );\n    }\n  }\n\n  private deserializeMessage(data: string): any {\n    try {\n      const parsed = JSON.parse(data);\n\n      // Check if messageRegistry exists and has decode method\n      if (!messageRegistry) {\n        throw new Error('messageRegistry is undefined');\n      }\n\n      if (typeof messageRegistry.decode !== 'function') {\n        throw new Error('messageRegistry.decode is not a function');\n      }\n\n      // Use message registry to decode\n      const result = messageRegistry.decode(parsed);\n      if (either.isLeft(result)) {\n        // If registry can't decode it, return as-is (might be error response, etc.)\n        return parsed;\n      }\n\n      return result.right;\n    } catch (error) {\n      throw new Error(\n        `Failed to deserialize message: ${\n          error instanceof Error ? error.message : String(error)\n        }`\n      );\n    }\n  }\n\n  async handshake(): Promise<any> {\n    // Generate ML-KEM-768 keypair and use encapsulation key as challenge\n    const { encapsulationKey, decapsulationKey } = generateMlKem768Keypair();\n\n    // Store decapsulation key for later use\n    this.decapsulationKey = decapsulationKey;\n\n    // Generate a cryptographically secure nonce for attestation\n    const nonceBytes = randomBytes(32); // 256-bit nonce\n\n    // Store original bytes for verification\n    this.handshakeNonce = nonceBytes;\n\n    const request = new HandshakeV1RequestMessage({\n      challenge: encapsulationKey, // ML-KEM-768 encapsulation key (will be encoded to hex by the message class)\n      nonce: nonceBytes, // User data nonce for attestation document\n    });\n\n    const response = await this.sendRequest<any>(request);\n\n    // Extract shared secret from response using ML-KEM decapsulation\n    const responseData = response.getData();\n    if (\n      responseData.encapsulatedSharedSecret &&\n      responseData.connectionId &&\n      this.decapsulationKey\n    ) {\n      // Use the server's connection ID for consistent key derivation\n      this.connectionId = responseData.connectionId;\n\n      // Convert hex string back to bytes for decapsulation\n      const cipherText = hexToBytes(responseData.encapsulatedSharedSecret);\n\n      // Perform ML-KEM decapsulation to derive shared secret\n      this.sharedSecret = decapsulateMlKem768(\n        this.decapsulationKey,\n        cipherText\n      );\n    }\n\n    // Verify attestation document asynchronously (don't block handshake completion)\n    if (\n      this.attestationVerifier &&\n      responseData.attestationDoc &&\n      responseData.encapsulatedSharedSecret\n    ) {\n      // Run verification in background, don't await it\n      // Convert hex string back to bytes for challenge verification\n      const cipherText = hexToBytes(responseData.encapsulatedSharedSecret);\n      this.verifyAttestationDocument(\n        responseData.attestationDoc,\n        cipherText\n      ).catch((error) => {\n        // Emit error but don't fail the handshake\n        this.emit(\n          'error',\n          new Error(\n            `Background attestation verification failed: ${error.message}`\n          )\n        );\n      });\n    }\n\n    return response;\n  }\n\n  async signMessage(params: {\n    keyshare: any; // Keyshare object from Dynamic Wallet SDK\n    message: Uint8Array | string; // Message to sign (supports hex string or Uint8Array)\n    relayDomain: string;\n    signingAlgo: SigningAlgorithm;\n    hashAlgo?: HashAlgorithm;\n    derivationPath?: Uint32Array;\n    tweak?: Uint8Array;\n    roomUuid: string; // MPC room UUID for signing ceremony\n  }): Promise<any> {\n    // Ensure connection is active and handshake is completed (auto-connect if needed)\n    const { sharedSecret, connectionId } = await this.ensureWsConnection();\n\n    // Convert hex string to Uint8Array if needed\n    let messageToSign: Uint8Array;\n    if (typeof params.message === 'string') {\n      // Handle hex strings (with or without 0x prefix)\n      const cleanHex = params.message.startsWith('0x')\n        ? params.message.slice(2)\n        : params.message;\n      messageToSign = hexToBytes(cleanHex);\n    } else {\n      // Already a Uint8Array\n      messageToSign = params.message;\n    }\n\n    // Encrypt the keyshare using AES-256-GCM\n    const encryptedKeyshare = await encryptKeyshare(\n      params.keyshare,\n      sharedSecret,\n      connectionId,\n      params.signingAlgo as unknown as SigningAlgorithmName\n    );\n\n    const request = new SignMessageV1RequestMessage({\n      relayDomain: params.relayDomain,\n      signingAlgo: params.signingAlgo,\n      hashAlgo: params.hashAlgo,\n      derivationPath: params.derivationPath,\n      tweak: params.tweak,\n      keyshare: encryptedKeyshare,\n      message: messageToSign, // Always pass Uint8Array to the message class\n      roomUuid: params.roomUuid,\n    });\n\n    return this.sendRequest<any>(request);\n  }\n\n  get connected(): boolean {\n    return this.isConnected;\n  }\n\n  /**\n   * Generate a unique connection ID\n   */\n\n  /**\n   * Verify attestation document from handshake response\n   * Uses base64-encoded attestation document directly\n   */\n  private async verifyAttestationDocument(\n    attestationDocBase64: string,\n    cipherText: Uint8Array\n  ): Promise<void> {\n    if (!this.attestationVerifier) {\n      return; // No verifier configured\n    }\n\n    try {\n      // Generate the expected challenge (hash of cipher text from ML-KEM encapsulation)\n      const challengeHash = sha256(cipherText);\n      const expectedChallenge = Array.from(challengeHash)\n        .map((b: number) => b.toString(16).padStart(2, '0'))\n        .join('');\n\n      // Verify the attestation document directly with base64 string (no conversion needed!)\n      // Nonce is required for security (prevents replay attacks)\n      if (!this.handshakeNonce) {\n        throw new Error(\n          'Nonce not found - handshake may not have completed properly'\n        );\n      }\n\n      const result = await this.attestationVerifier.verify(\n        attestationDocBase64,\n        expectedChallenge,\n        this.handshakeNonce\n      );\n\n      if (!result.valid) {\n        const errorMsg = `Attestation verification failed: ${result.errors.join(\n          ', '\n        )}`;\n        this.emit('error', new Error(errorMsg));\n        throw new Error(errorMsg);\n      }\n\n      // Emit success event with verification result\n      this.emit('message', {\n        type: 'attestation-verified',\n        timestamp: Date.now(),\n        data: result,\n      } as any);\n    } catch (error) {\n      const errorMsg = `Attestation verification error: ${\n        error instanceof Error ? error.message : String(error)\n      }`;\n      this.emit('error', new Error(errorMsg));\n      throw new Error(errorMsg);\n    }\n  }\n}\n"]}