{"version":3,"file":"ethers.mjs","sources":["../../src/signers/http.ts","../../src/signers/validation.ts","../../src/signers/utils.ts","../../src/signers/vault.ts","../../src/signers/ethers.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 { Hex } from '../types/signers';\nimport { toSafeNumber } from './validation';\n\nexport function toHexIfBigInt(v: unknown): unknown {\n  return typeof v === 'bigint' ? '0x' + v.toString(16) : v;\n}\n\n/**\n * viem txs sometimes have bigint / hex / optional fields. Ethers serializers\n * accept hex strings for numeric fields. Normalize where helpful.\n */\nexport function normalizeTxForEmblem(tx: Record<string, unknown>): Record<string, unknown> {\n  const out: Record<string, unknown> = { ...tx };\n\n  if (out.value !== undefined) out.value = toHexIfBigInt(out.value);\n  if (out.gas !== undefined) {\n    out.gasLimit = toHexIfBigInt(out.gas);\n    delete out.gas;\n  }\n  if (out.gasLimit !== undefined) out.gasLimit = toHexIfBigInt(out.gasLimit);\n  if (out.gasPrice !== undefined) out.gasPrice = toHexIfBigInt(out.gasPrice);\n  if (out.maxFeePerGas !== undefined) out.maxFeePerGas = toHexIfBigInt(out.maxFeePerGas);\n  if (out.maxPriorityFeePerGas !== undefined)\n    out.maxPriorityFeePerGas = toHexIfBigInt(out.maxPriorityFeePerGas);\n  if (out.nonce !== undefined) out.nonce = toSafeNumber(out.nonce, 'nonce');\n  if (out.chainId !== undefined) out.chainId = toSafeNumber(out.chainId, 'chainId');\n\n  // Some backends only accept legacy fields; fold EIP-1559 into gasPrice and drop unsupported keys\n  if (out.maxFeePerGas !== undefined || out.maxPriorityFeePerGas !== undefined) {\n    if (out.gasPrice === undefined && out.maxFeePerGas !== undefined) {\n      out.gasPrice = out.maxFeePerGas;\n    }\n    delete out.maxFeePerGas;\n    delete out.maxPriorityFeePerGas;\n  }\n\n  // Remove fields commonly unsupported by legacy serializers\n  delete out.type;\n  delete out.accessList;\n  delete out.account;\n  delete out.chain;\n  delete out.from;\n\n  return out;\n}\n\nexport function isHexString(value: unknown): value is Hex {\n  return typeof value === 'string' && /^0x[0-9a-fA-F]*$/.test(value);\n}\n\nexport function bytesToHex(bytes: ArrayLike<number>): Hex {\n  let out = '0x';\n  for (let i = 0; i < bytes.length; i++) {\n    out += (bytes[i] as number).toString(16).padStart(2, '0');\n  }\n  return out as Hex;\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","import type { Hex, SignerConfig, SignerVaultInfo } from '../types/signers';\nimport { emblemPost } from './http';\nimport { bytesToHex, normalizeTxForEmblem } from './utils';\nimport { fetchVaultInfo } from './vault';\n\n// ethers v6 compatible interface (like solana pattern - no runtime dependency)\nexport interface EmblemEthersWallet {\n  getAddress(): Promise<string>;\n  signMessage(message: string | Uint8Array): Promise<string>;\n  signTypedData(\n    domain: unknown,\n    types: Record<string, Array<{ name: string; type: string }>>,\n    value: Record<string, unknown>\n  ): Promise<string>;\n  signTransaction(tx: unknown): Promise<string>;\n  sendTransaction(tx: unknown): Promise<unknown>;\n  connect(provider: unknown): EmblemEthersWallet;\n  provider: unknown;\n  // Additional methods\n  initialize(): Promise<void>;\n  getVaultId(): string;\n  setChainId(chainId: number): void;\n  getChainId(): number;\n  signAndBroadcast(transaction: unknown, waitForReceipt?: boolean): Promise<string>;\n}\n\nexport async function toEthersWallet(\n  config: SignerConfig,\n  provider?: unknown | null,\n  infoOverride?: SignerVaultInfo\n): Promise<EmblemEthersWallet> {\n  // Dynamic import - only loads ethers when this function is called\n  // String concatenation prevents bundlers from statically analyzing the import\n  // DO NOT CHANGE THIS PATTERN - using a literal import('ethers') breaks Next.js/Webpack builds\n  // when ethers is not installed. The variable indirection is intentional. - Shannon\n  let ethers: typeof import('ethers');\n  try {\n    const moduleName = 'ethers';\n    ethers = await import(/* @vite-ignore */ moduleName);\n  } catch {\n    throw new Error('ethers is required for toEthersWallet(). Install it with: npm install ethers');\n  }\n\n  const { AbstractSigner, resolveAddress } = ethers;\n  type AbstractProvider = import('ethers').AbstractProvider;\n  type TransactionRequest = import('ethers').TransactionRequest;\n  type TransactionResponse = import('ethers').TransactionResponse;\n  type TransactionLike = import('ethers').TransactionLike<string>;\n  type TypedDataDomain = import('ethers').TypedDataDomain;\n  type TypedDataField = import('ethers').TypedDataField;\n\n  const info = infoOverride ?? (await fetchVaultInfo(config));\n\n  // Class defined inside function after dynamic import\n  class EmblemEthersWalletImpl extends AbstractSigner {\n    private readonly _config: SignerConfig;\n    private _address: Hex | null = null;\n    private _vaultId: string | null = null;\n    private _chainId = 1;\n    private _initPromise?: Promise<void>;\n\n    constructor(\n      signerConfig: SignerConfig,\n      signerProvider?: AbstractProvider | null,\n      seed?: { address?: Hex; vaultId?: string; chainId?: number }\n    ) {\n      super(signerProvider ?? null);\n      this._config = signerConfig;\n      if (seed?.address) this._address = seed.address;\n      if (seed?.vaultId) this._vaultId = seed.vaultId;\n      if (seed?.chainId) this._chainId = seed.chainId;\n    }\n\n    async initialize(): Promise<void> {\n      if (this._initPromise) return this._initPromise;\n\n      this._initPromise = fetchVaultInfo(this._config)\n        .then((vaultInfo) => {\n          this._address = vaultInfo.evmAddress;\n          this._vaultId = vaultInfo.vaultId;\n        })\n        .catch((err) => {\n          this._initPromise = undefined;\n          throw err;\n        });\n\n      return this._initPromise;\n    }\n\n    async getAddress(): Promise<string> {\n      if (!this._address) await this.initialize();\n      return this._address!;\n    }\n\n    getVaultId(): string {\n      if (!this._vaultId) throw new Error('Wallet not initialized. Call initialize() first.');\n      return this._vaultId;\n    }\n\n    setChainId(chainId: number): void {\n      this._chainId = chainId;\n    }\n\n    getChainId(): number {\n      return this._chainId;\n    }\n\n    connect(newProvider: AbstractProvider): EmblemEthersWalletImpl {\n      if (!newProvider) throw new Error('Provider cannot be null');\n      return new EmblemEthersWalletImpl(this._config, newProvider, {\n        address: this._address ?? undefined,\n        vaultId: this._vaultId ?? undefined,\n        chainId: this._chainId,\n      });\n    }\n\n    async signMessage(message: string | Uint8Array): Promise<string> {\n      if (!this._vaultId) await this.initialize();\n      const payload = typeof message === 'string' ? message : bytesToHex(message);\n      const data = await emblemPost<{ signerAddress: string; signature: Hex }>(\n        '/sign-eth-message',\n        { vaultId: this._vaultId!, message: payload },\n        this._config\n      );\n      return data.signature;\n    }\n\n    async signTypedData(\n      domain: TypedDataDomain,\n      types: Record<string, Array<TypedDataField>>,\n      value: Record<string, unknown>\n    ): Promise<string> {\n      if (!this._vaultId) await this.initialize();\n      const cleanTypes = { ...types };\n      if (cleanTypes && (cleanTypes as Record<string, unknown>).EIP712Domain) {\n        delete (cleanTypes as Record<string, unknown>).EIP712Domain;\n      }\n      const data = await emblemPost<{ signerAddress: string; signature: Hex }>(\n        '/sign-typed-message',\n        { vaultId: this._vaultId!, domain, types: cleanTypes, message: value },\n        this._config\n      );\n      return data.signature;\n    }\n\n    async _signTypedData(\n      domain: TypedDataDomain,\n      types: Record<string, Array<TypedDataField>>,\n      value: Record<string, unknown>\n    ): Promise<string> {\n      return this.signTypedData(domain, types, value);\n    }\n\n    async signTransaction(tx: TransactionRequest): Promise<string> {\n      if (!this._vaultId) await this.initialize();\n      const from = (tx as Record<string, unknown>).from as string | undefined;\n      const addr = await this.getAddress();\n\n      if (from && from.toLowerCase() !== addr.toLowerCase()) {\n        throw new Error('transaction from does not match signer address');\n      }\n\n      const toSign = this.provider\n        ? ({ ...await this.populateTransaction(tx) } as Record<string, unknown>)\n        : ({ ...tx } as Record<string, unknown>);\n      if (toSign.from) delete toSign.from;\n      if (!('to' in toSign) || !toSign.to) {\n        throw new Error(\"Transaction must have a 'to' address\");\n      }\n      if (toSign.nonce === undefined || toSign.nonce === null) {\n        throw new Error('Transaction must have a nonce');\n      }\n      const normalized = normalizeTxForEmblem(toSign);\n      const resp = await emblemPost<{ signedTransaction: Hex }>(\n        '/sign-eth-tx',\n        { vaultId: this._vaultId!, transaction: normalized, options: { chainId: this._chainId } },\n        this._config\n      );\n      return resp.signedTransaction;\n    }\n\n    async sendTransaction(tx: TransactionRequest): Promise<TransactionResponse> {\n      if (!this.provider) throw new Error('Provider required to send transaction');\n      const signed = await this.signTransaction(tx);\n      return await this.provider.broadcastTransaction(signed);\n    }\n\n    async populateTransaction(transaction: TransactionRequest): Promise<TransactionLike> {\n      const tx = { ...transaction } as TransactionRequest;\n      if (!this.provider) throw new Error('Provider required to populate transaction');\n      const fromAddress = tx.from\n        ? await resolveAddress(tx.from, this.provider)\n        : await this.getAddress();\n\n      let chainId: bigint;\n      if (!tx.chainId) {\n        const network = await this.provider.getNetwork();\n        chainId = network.chainId;\n        this._chainId = Number(network.chainId);\n      } else {\n        chainId = BigInt(tx.chainId);\n        this._chainId = Number(tx.chainId);\n      }\n\n      const nonce =\n        tx.nonce != null\n          ? Number(tx.nonce)\n          : await this.provider.getTransactionCount(fromAddress, 'pending');\n      const toAddress = tx.to ? await resolveAddress(tx.to, this.provider) : null;\n      const value = tx.value ? BigInt(tx.value.toString()) : 0n;\n\n      let gasLimit: bigint;\n      if (!tx.gasLimit) {\n        try {\n          gasLimit = await this.provider.estimateGas({ ...tx, from: fromAddress });\n        } catch {\n          gasLimit = 21000n;\n        }\n      } else {\n        gasLimit = BigInt(tx.gasLimit.toString());\n      }\n\n      let gasPrice: bigint | null = null;\n      if (!tx.gasPrice && tx.type !== 2) {\n        const feeData = await this.provider.getFeeData();\n        gasPrice = feeData.gasPrice ?? null;\n      } else if (tx.gasPrice) {\n        gasPrice = BigInt(tx.gasPrice.toString());\n      }\n\n      const populated: TransactionLike = {\n        from: fromAddress,\n        to: toAddress,\n        value,\n        nonce,\n        gasLimit,\n        data: tx.data as string | undefined,\n        chainId,\n        type: tx.type || undefined,\n      };\n      if (gasPrice !== null) populated.gasPrice = gasPrice;\n      if (tx.maxFeePerGas) populated.maxFeePerGas = BigInt(tx.maxFeePerGas.toString());\n      if (tx.maxPriorityFeePerGas)\n        populated.maxPriorityFeePerGas = BigInt(tx.maxPriorityFeePerGas.toString());\n      return populated;\n    }\n\n    async signAndBroadcast(\n      transaction: TransactionRequest,\n      waitForReceipt: boolean = false\n    ): Promise<string> {\n      if (!this.provider) throw new Error('Provider required to send transaction');\n      const signed = await this.signTransaction(transaction);\n      const resp = await this.provider.broadcastTransaction(signed);\n      const hash = resp.hash as string;\n      if (waitForReceipt) {\n        await this.provider.waitForTransaction(hash);\n      }\n      return hash;\n    }\n  }\n\n  return new EmblemEthersWalletImpl(config, provider as AbstractProvider | null, {\n    address: info.evmAddress,\n    vaultId: info.vaultId,\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","toSafeNumber","fieldName","num","Number","isSafeInteger","MAX_SAFE_INTEGER","toHexIfBigInt","v","fetchVaultInfo","data","vaultId","evmAddress","String","startsWith","tokenId","address","created_by","toEthersWallet","provider","infoOverride","ethers","moduleName","import","AbstractSigner","resolveAddress","info","EmblemEthersWalletImpl","constructor","signerConfig","signerProvider","seed","super","this","_address","_vaultId","_chainId","_config","chainId","initialize","_initPromise","then","vaultInfo","err","getAddress","getVaultId","setChainId","getChainId","connect","newProvider","signMessage","message","payload","bytes","out","i","length","padStart","bytesToHex","signature","signTypedData","domain","types","cleanTypes","EIP712Domain","_signTypedData","signTransaction","tx","from","addr","toLowerCase","toSign","populateTransaction","to","nonce","normalized","gas","gasLimit","gasPrice","maxFeePerGas","maxPriorityFeePerGas","type","accessList","account","chain","normalizeTxForEmblem","transaction","options","signedTransaction","sendTransaction","signed","broadcastTransaction","fromAddress","BigInt","network","getNetwork","getTransactionCount","toAddress","estimateGas","getFeeData","populated","signAndBroadcast","waitForReceipt","hash","waitForTransaction"],"mappings":"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"}