{"version":3,"file":"index.mjs","sources":["../../src/signers/http.ts","../../src/signers/validation.ts","../../src/crypto/index.ts","../../src/signers/vault.ts"],"sourcesContent":["import type { SignerConfig } from '../types/signers';\n\nfunction sanitizeErrorMessage(status: number, text: string): string {\n  // Sanitize error messages to avoid leaking sensitive server information\n  let errorMessage = `Emblem signer error ${status}`;\n\n  if (status >= 500) {\n    errorMessage += ': Internal server error';\n  } else if (status === 401 || status === 403) {\n    errorMessage += ': Authentication failed';\n  } else if (status === 404) {\n    errorMessage += ': Resource not found';\n  } else if (status === 405) {\n    errorMessage += ': Method not allowed';\n  } else if (text) {\n    // For 4xx client errors, include limited error details\n    errorMessage += `: ${text.substring(0, 200)}`; // Limit to 200 chars\n  }\n\n  return errorMessage;\n}\n\nasync function resolveAuthHeaders(config: SignerConfig): Promise<Record<string, string>> {\n  // Priority: custom headers -> jwt/getJwt/sdk -> apiKey (deprecated)\n  if (typeof config.getAuthHeaders === 'function') {\n    const h = await config.getAuthHeaders();\n    if (h && typeof h === 'object') return h;\n  }\n\n  const tok =\n    config.jwt ??\n    (typeof config.getJwt === 'function' ? await config.getJwt() : undefined) ??\n    config.sdk?.getSession()?.authToken ??\n    undefined;\n\n  if (tok) {\n    return { Authorization: `Bearer ${tok}` };\n  }\n\n  // apiKey is deprecated but still supported as fallback\n  if (config.apiKey) {\n    return { 'x-api-key': config.apiKey };\n  }\n\n  throw new Error(\n    'No authentication available: provide jwt, getJwt(), getAuthHeaders(), sdk, or apiKey'\n  );\n}\n\nexport async function emblemPost<T = unknown>(\n  path: string,\n  body: unknown,\n  config: SignerConfig\n): Promise<T> {\n  const baseUrl = config.baseUrl ?? 'https://api.emblemvault.ai';\n  const authHeaders = await resolveAuthHeaders(config);\n  const res = await fetch(`${baseUrl}${path}`, {\n    method: 'POST',\n    headers: {\n      'content-type': 'application/json',\n      ...authHeaders,\n    },\n    body: JSON.stringify(body, (_key: string, value: unknown) =>\n      typeof value === 'bigint' ? value.toString() : value\n    ),\n  });\n\n  if (!res.ok) {\n    const text = await res.text().catch(() => '');\n    throw new Error(sanitizeErrorMessage(res.status, text));\n  }\n\n  return res.json() as Promise<T>;\n}\n\nexport async function emblemGet<T = unknown>(path: string, config: SignerConfig): Promise<T> {\n  const baseUrl = config.baseUrl ?? 'https://api.emblemvault.ai';\n  const authHeaders = await resolveAuthHeaders(config);\n  const res = await fetch(`${baseUrl}${path}`, {\n    method: 'GET',\n    headers: authHeaders,\n  });\n\n  if (!res.ok) {\n    const text = await res.text().catch(() => '');\n    throw new Error(sanitizeErrorMessage(res.status, text));\n  }\n\n  return res.json() as Promise<T>;\n}\n","import type { SignerConfig } from '../types/signers';\n\n/**\n * Environment detection utilities for warning about unsafe usage patterns\n */\n\n/**\n * Detect if code is running in a browser environment\n */\nexport function isBrowserEnvironment(): boolean {\n  return typeof window !== 'undefined' && typeof document !== 'undefined';\n}\n\n/**\n * Check if we're in a Node.js server environment\n */\nexport function isNodeEnvironment(): boolean {\n  return (\n    typeof process !== 'undefined' && process.versions != null && process.versions.node != null\n  );\n}\n\n/**\n * Validate baseUrl format\n */\nexport function validateBaseUrl(baseUrl?: string): void {\n  if (!baseUrl) return; // undefined is ok, will use default\n\n  if (!baseUrl.startsWith('http://') && !baseUrl.startsWith('https://')) {\n    throw new Error('baseUrl must be a valid HTTP(S) URL');\n  }\n\n  // Warn about http (not https)\n  if (\n    baseUrl.startsWith('http://') &&\n    !baseUrl.includes('localhost') &&\n    !baseUrl.includes('127.0.0.1')\n  ) {\n    console.warn(\n      '[Emblem Security Warning] baseUrl uses HTTP instead of HTTPS. This is insecure for production use.'\n    );\n  }\n}\n\n/**\n * Validate Ethereum address format\n */\nexport function validateEthereumAddress(address: string): void {\n  if (!address || typeof address !== 'string') {\n    throw new Error('Address is required');\n  }\n\n  if (!address.startsWith('0x')) {\n    throw new Error('Address must start with 0x');\n  }\n\n  if (!/^0x[0-9a-fA-F]{40}$/.test(address)) {\n    throw new Error('Invalid Ethereum address format');\n  }\n}\n\n/**\n * Validate vault ID\n */\nexport function validateVaultId(vaultId: string): void {\n  if (!vaultId || typeof vaultId !== 'string') {\n    throw new Error('vaultId is required');\n  }\n\n  if (vaultId.trim() === '') {\n    throw new Error('vaultId cannot be empty');\n  }\n}\n\n/**\n * Safe number conversion with bounds checking\n */\nexport function toSafeNumber(value: unknown, fieldName: string): number {\n  const num = Number(value);\n\n  if (!Number.isSafeInteger(num)) {\n    throw new Error(\n      `${fieldName} value ${value} exceeds safe integer range (max: ${Number.MAX_SAFE_INTEGER})`\n    );\n  }\n\n  return num;\n}\n\n/**\n * Extended config with security options\n */\nexport interface SignerSecurityConfig extends SignerConfig {\n  /**\n   * Enable debug logging for security-related checks\n   * @default false\n   */\n  debugSecurity?: boolean;\n}\n\n/**\n * Validate signer configuration\n */\nexport function validateSignerConfig(config: SignerSecurityConfig): void {\n  // Validate auth: require at least one method\n  const hasJwt = !!config.jwt;\n  const hasGetJwt = typeof config.getJwt === 'function';\n  const hasHeaders = typeof config.getAuthHeaders === 'function';\n  const hasSdk = !!config.sdk && typeof config.sdk.getSession === 'function';\n  const hasApiKey = !!config.apiKey;\n\n  if (!hasJwt && !hasGetJwt && !hasHeaders && !hasSdk && !hasApiKey) {\n    throw new Error('Authentication required: provide jwt, getJwt(), getAuthHeaders(), sdk, or apiKey');\n  }\n\n  // Validate baseUrl if provided\n  if (config.baseUrl) {\n    validateBaseUrl(config.baseUrl);\n  }\n\n  // Security audit logging\n  if (config.debugSecurity) {\n    console.log('[Emblem Security Debug]', {\n      environment: isBrowserEnvironment() ? 'browser' : 'node',\n      hasBaseUrl: !!config.baseUrl,\n      timestamp: new Date().toISOString(),\n    });\n  }\n}\n","import type { SignerConfig } from '../types/signers';\nimport type { EncryptConfig, EncryptResult, DecryptConfig } from './types';\nimport { emblemPost } from '../signers/http';\nimport { validateSignerConfig } from '../signers/validation';\nimport { fetchVaultInfo } from '../signers/vault';\n\nexport type { EncryptConfig, EncryptResult, DecryptConfig } from './types';\nexport type { DecryptResult, DecryptBinaryResult } from './types';\n\n/** Binary marker prefix used to distinguish binary data from plain text */\nconst BINARY_MARKER = 'b64:';\n\n/** Response shape from POST /encrypt */\ninterface EncryptApiResponse {\n  success: boolean;\n  ciphertext: string;\n  dataToEncryptHash: string;\n}\n\n/** Response shape from POST /decrypt */\ninterface DecryptApiResponse {\n  success: boolean;\n  decryptedString: string;\n}\n\n/**\n * Resolve vault address and tokenId from the signer config.\n * Uses fetchVaultInfo to retrieve the vault's EVM address and vaultId.\n */\nasync function resolveVaultDetails(\n  config: SignerConfig\n): Promise<{ address: string; tokenId: string }> {\n  const vaultInfo = await fetchVaultInfo(config);\n\n  if (!vaultInfo.evmAddress) {\n    throw new Error('Could not resolve vault EVM address');\n  }\n  if (!vaultInfo.vaultId) {\n    throw new Error('Could not resolve vault tokenId');\n  }\n\n  return {\n    address: vaultInfo.evmAddress,\n    tokenId: vaultInfo.vaultId,\n  };\n}\n\n/**\n * Encrypt a string using the Emblem encryption service.\n *\n * If `options.address` or `options.tokenId` are not provided, they will be\n * resolved automatically from the authenticated vault info.\n *\n * @param data - The plaintext string to encrypt\n * @param options - Encryption configuration including auth config\n * @returns The encrypted ciphertext and data hash (needed for decryption)\n */\nexport async function encrypt(data: string, options: EncryptConfig): Promise<EncryptResult> {\n  if (!data) {\n    throw new Error('Data to encrypt must be a non-empty string');\n  }\n  if (!options || !options.config) {\n    throw new Error('EncryptConfig with a valid config is required');\n  }\n\n  validateSignerConfig(options.config);\n\n  let { address, tokenId } = options;\n\n  // Resolve address/tokenId from vault if not explicitly provided\n  if (!address || !tokenId) {\n    const vaultDetails = await resolveVaultDetails(options.config);\n    address = address ?? vaultDetails.address;\n    tokenId = tokenId ?? vaultDetails.tokenId;\n  }\n\n  const response = await emblemPost<EncryptApiResponse>('/encrypt', {\n    text: data,\n    address,\n    tokenId,\n  }, options.config);\n\n  if (!response || !response.ciphertext || !response.dataToEncryptHash) {\n    throw new Error('Invalid encrypt response: missing ciphertext or dataToEncryptHash');\n  }\n\n  return {\n    ciphertext: response.ciphertext,\n    dataToEncryptHash: response.dataToEncryptHash,\n  };\n}\n\n/**\n * Encrypt binary data (Uint8Array) using the Emblem encryption service.\n *\n * The binary data is Base64-encoded with a marker prefix so that decryptBinary()\n * can distinguish it from plain text and decode it back to a Uint8Array.\n *\n * @param data - The binary data to encrypt\n * @param options - Encryption configuration including auth config\n * @returns The encrypted ciphertext and data hash (needed for decryption)\n */\nexport async function encryptBinary(\n  data: Uint8Array,\n  options: EncryptConfig\n): Promise<EncryptResult> {\n  if (!data || !(data instanceof Uint8Array)) {\n    throw new Error('Data must be a Uint8Array');\n  }\n\n  // Base64-encode the binary data and prepend the marker\n  const base64 = uint8ArrayToBase64(data);\n  const encoded = `${BINARY_MARKER}${base64}`;\n\n  return encrypt(encoded, options);\n}\n\n/**\n * Decrypt ciphertext using the Emblem decryption service.\n *\n * If `options.address` or `options.tokenId` are not provided, they will be\n * resolved automatically from the authenticated vault info.\n *\n * If the decrypted string starts with the binary marker (\"b64:\"), the marker is\n * stripped and the raw Base64 string is returned.\n *\n * @param options - Decryption configuration including ciphertext and hash\n * @returns The decrypted plaintext string\n */\nexport async function decrypt(options: DecryptConfig): Promise<string> {\n  if (!options || !options.config) {\n    throw new Error('DecryptConfig with a valid config is required');\n  }\n  if (!options.ciphertext) {\n    throw new Error('ciphertext is required for decryption');\n  }\n  if (!options.dataToEncryptHash) {\n    throw new Error('dataToEncryptHash is required for decryption');\n  }\n\n  validateSignerConfig(options.config);\n\n  let { address, tokenId } = options;\n\n  // Resolve address/tokenId from vault if not explicitly provided\n  if (!address || !tokenId) {\n    const vaultDetails = await resolveVaultDetails(options.config);\n    address = address ?? vaultDetails.address;\n    tokenId = tokenId ?? vaultDetails.tokenId;\n  }\n\n  const response = await emblemPost<DecryptApiResponse>('/decrypt', {\n    address,\n    tokenId,\n    ciphertext: options.ciphertext,\n    dataToEncryptHash: options.dataToEncryptHash,\n  }, options.config);\n\n  if (!response || typeof response.decryptedString !== 'string') {\n    throw new Error('Invalid decrypt response: missing decryptedString');\n  }\n\n  let result = response.decryptedString;\n\n  // Strip binary marker if present (for users who just want the base64 string)\n  if (result.startsWith(BINARY_MARKER)) {\n    result = result.slice(BINARY_MARKER.length);\n  }\n\n  return result;\n}\n\n/**\n * Decrypt ciphertext and return the result as a Uint8Array.\n *\n * If the decrypted data was originally encrypted with encryptBinary(), the\n * binary marker is detected and the Base64 payload is decoded back to bytes.\n * Otherwise the decrypted string is encoded as UTF-8 bytes as a fallback.\n *\n * @param options - Decryption configuration including ciphertext and hash\n * @returns The decrypted binary data as a Uint8Array\n */\nexport async function decryptBinary(options: DecryptConfig): Promise<Uint8Array> {\n  if (!options || !options.config) {\n    throw new Error('DecryptConfig with a valid config is required');\n  }\n  if (!options.ciphertext) {\n    throw new Error('ciphertext is required for decryption');\n  }\n  if (!options.dataToEncryptHash) {\n    throw new Error('dataToEncryptHash is required for decryption');\n  }\n\n  validateSignerConfig(options.config);\n\n  // Perform decryption using the raw API to check the marker ourselves\n  let { address, tokenId } = options;\n\n  if (!address || !tokenId) {\n    const vaultDetails = await resolveVaultDetails(options.config);\n    address = address ?? vaultDetails.address;\n    tokenId = tokenId ?? vaultDetails.tokenId;\n  }\n\n  const response = await emblemPost<DecryptApiResponse>('/decrypt', {\n    address,\n    tokenId,\n    ciphertext: options.ciphertext,\n    dataToEncryptHash: options.dataToEncryptHash,\n  }, options.config);\n\n  if (!response || typeof response.decryptedString !== 'string') {\n    throw new Error('Invalid decrypt response: missing decryptedString');\n  }\n\n  const decrypted = response.decryptedString;\n\n  // If the binary marker is present, decode the Base64 payload\n  if (decrypted.startsWith(BINARY_MARKER)) {\n    const base64 = decrypted.slice(BINARY_MARKER.length);\n    return base64ToUint8Array(base64);\n  }\n\n  // Fallback: encode the plain string as UTF-8 bytes\n  return new TextEncoder().encode(decrypted);\n}\n\n/* ------------------------------------------------------------------ */\n/*  Base64 helpers (environment-agnostic: works in Node and browsers)  */\n/* ------------------------------------------------------------------ */\n\nfunction uint8ArrayToBase64(bytes: Uint8Array): string {\n  // Use btoa if available (browsers + Node 16+)\n  if (typeof btoa === 'function') {\n    let binary = '';\n    for (let i = 0; i < bytes.length; i++) {\n      binary += String.fromCharCode(bytes[i]);\n    }\n    return btoa(binary);\n  }\n\n  // Node.js Buffer fallback\n  if (typeof Buffer !== 'undefined') {\n    return Buffer.from(bytes).toString('base64');\n  }\n\n  throw new Error('No Base64 encoding method available in this environment');\n}\n\nfunction base64ToUint8Array(base64: string): Uint8Array {\n  // Use atob if available (browsers + Node 16+)\n  if (typeof atob === 'function') {\n    const binary = atob(base64);\n    const bytes = new Uint8Array(binary.length);\n    for (let i = 0; i < binary.length; i++) {\n      bytes[i] = binary.charCodeAt(i);\n    }\n    return bytes;\n  }\n\n  // Node.js Buffer fallback\n  if (typeof Buffer !== 'undefined') {\n    const buf = Buffer.from(base64, 'base64');\n    return new Uint8Array(buf.buffer, buf.byteOffset, buf.byteLength);\n  }\n\n  throw new Error('No Base64 decoding method available in this environment');\n}\n","import type { SignerConfig, SignerVaultInfo, Hex } from '../types/signers';\nimport { emblemPost } from './http';\n\nexport async function fetchVaultInfo(config: SignerConfig): Promise<SignerVaultInfo> {\n  // Note: The server only supports POST for /vault/info\n  const data: Partial<{\n    vaultId: string;\n    address: string;\n    evmAddress: Hex;\n    created_by?: string;\n  }> = await emblemPost('/vault/info', {}, config);\n\n  // Validate required response data (vaultId + evmAddress are required for EVM)\n  if (!data || !data.vaultId || !data.evmAddress) {\n    throw new Error('Invalid vault info response: missing required fields');\n  }\n\n  if (!String(data.evmAddress).startsWith('0x')) {\n    throw new Error('Invalid evmAddress format in response');\n  }\n\n  return {\n    vaultId: data.vaultId,\n    tokenId: data.vaultId,\n    address: data.address || '', // Solana address may be absent; keep optional\n    evmAddress: data.evmAddress as Hex,\n    created_by: data.created_by,\n  };\n}\n"],"names":["async","emblemPost","path","body","config","baseUrl","authHeaders","getAuthHeaders","h","tok","jwt","getJwt","undefined","sdk","getSession","authToken","Authorization","apiKey","Error","resolveAuthHeaders","res","fetch","method","headers","JSON","stringify","_key","value","toString","ok","text","catch","status","errorMessage","substring","sanitizeErrorMessage","json","validateSignerConfig","hasJwt","hasGetJwt","hasHeaders","hasSdk","hasApiKey","startsWith","includes","console","warn","validateBaseUrl","debugSecurity","log","environment","window","document","hasBaseUrl","timestamp","Date","toISOString","BINARY_MARKER","resolveVaultDetails","vaultInfo","data","vaultId","evmAddress","String","tokenId","address","created_by","fetchVaultInfo","encrypt","options","vaultDetails","response","ciphertext","dataToEncryptHash","encryptBinary","Uint8Array","base64","bytes","btoa","binary","i","length","fromCharCode","Buffer","from","uint8ArrayToBase64","decrypt","decryptedString","result","slice","decryptBinary","decrypted","atob","charCodeAt","buf","buffer","byteOffset","byteLength","base64ToUint8Array","TextEncoder","encode"],"mappings":"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"}