@reclaimprotocol/js-sdk 5.4.1 → 5.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +29 -1
- package/dist/index.js +44 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../package.json","../src/index.ts","../src/utils/interfaces.ts","../src/Reclaim.ts","../src/utils/errors.ts","../src/utils/logger.ts","../src/utils/validationUtils.ts","../src/utils/strings.ts","../src/utils/helper.ts","../src/utils/constants.ts","../src/utils/fetch.ts","../src/utils/sessionUtils.ts","../src/utils/proofUtils.ts","../src/witness.ts","../src/utils/modalUtils.ts","../src/utils/device.ts","../src/utils/attestationNonce.ts","../src/utils/providerUtils.ts","../src/utils/proofValidationUtils.ts","../src/utils/verifyTee.ts","../src/utils/verifyAttestorTee.ts","../src/utils/signatureUtils.ts"],"sourcesContent":["{\n \"name\": \"@reclaimprotocol/js-sdk\",\n \"version\": \"5.4.1\",\n \"description\": \"Designed to request proofs from the Reclaim protocol and manage the flow of claims and witness interactions.\",\n \"main\": \"dist/index.js\",\n \"types\": \"dist/index.d.ts\",\n \"keywords\": [\n \"reclaim\",\n \"protocol\",\n \"blockchain\",\n \"proof\",\n \"verification\",\n \"identity\",\n \"claims\",\n \"witness\",\n \"sdk\",\n \"javascript\",\n \"typescript\",\n \"decentralized\",\n \"web3\"\n ],\n \"files\": [\n \"dist\"\n ],\n \"tsup\": {\n \"entry\": [\n \"src/index.ts\"\n ],\n \"splitting\": false,\n \"sourcemap\": true,\n \"clean\": true\n },\n \"scripts\": {\n \"build\": \"sh scripts/build.sh\",\n \"prepare\": \"npm run build\",\n \"release\": \"release-it\",\n \"test\": \"jest\",\n \"test:watch\": \"jest --watch\",\n \"test:coverage\": \"jest --coverage\",\n \"commitlint\": \"commitlint --edit\"\n },\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"https://github.com/reclaimprotocol/reclaim-js-sdk\"\n },\n \"author\": \"ali <ali@creatoros.co>\",\n \"license\": \"See License in <https://github.com/reclaimprotocol/.github/blob/main/LICENSE>\",\n \"bugs\": {\n \"url\": \"https://github.com/reclaimprotocol/reclaim-js-sdk/issues\"\n },\n \"homepage\": \"https://github.com/reclaimprotocol/reclaim-js-sdk/\",\n \"publishConfig\": {\n \"registry\": \"https://registry.npmjs.org/\",\n \"access\": \"public\"\n },\n \"release-it\": {\n \"git\": {\n \"commitMessage\": \"chore: release ${version}\",\n \"tagName\": \"v${version}\"\n },\n \"npm\": {\n \"publish\": true,\n \"tag\": \"latest\"\n },\n \"github\": {\n \"release\": true\n },\n \"plugins\": {\n \"@release-it/conventional-changelog\": {\n \"preset\": \"angular\"\n }\n }\n },\n \"devDependencies\": {\n \"@commitlint/cli\": \"^17.7.1\",\n \"@commitlint/config-conventional\": \"^17.7.0\",\n \"@release-it/conventional-changelog\": \"10.0.6\",\n \"@types/jest\": \"^30.0.0\",\n \"@types/node-forge\": \"^1.3.14\",\n \"@types/qrcode\": \"^1.5.5\",\n \"@types/qs\": \"^6.9.11\",\n \"@types/url-parse\": \"^1.4.11\",\n \"@types/uuid\": \"^9.0.7\",\n \"jest\": \"^30.1.3\",\n \"jest-environment-jsdom\": \"^30.1.2\",\n \"qs\": \"^6.11.2\",\n \"release-it\": \"^19.2.4\",\n \"ts-jest\": \"^29.4.1\",\n \"tsup\": \"^8.0.1\",\n \"typescript\": \"^5.3.3\"\n },\n \"dependencies\": {\n \"canonicalize\": \"^2.0.0\",\n \"ethers\": \"^6.9.1\",\n \"fetch-retry\": \"^6.0.0\",\n \"node-forge\": \"^1.3.3\",\n \"qrcode\": \"^1.5.4\",\n \"url-parse\": \"^1.5.10\",\n \"uuid\": \"^9.0.1\"\n },\n \"overrides\": {\n \"@conventional-changelog/git-client\": \"^2.0.0\"\n }\n}","export * from './Reclaim';\nexport type * from './utils/interfaces';\nexport type * from './utils/types';\nexport * from './utils/proofUtils';\nexport type * from './utils/proofUtils';\nexport * from './utils/proofValidationUtils';\nexport type * from './utils/proofValidationUtils';\nexport * from './utils/providerUtils';\nexport type * from './utils/providerUtils';\nexport * from './utils/sessionUtils';\nexport type * from './utils/sessionUtils';\nexport { generateInitSignature } from './utils/signatureUtils';\nexport { generateAttestationNonce } from './utils/attestationNonce';\nexport * from './witness';\nexport type * from './witness';\nexport { verifyTeeAttestation, runTeeVerification } from './utils/verifyTee';\nexport type { TeeVerificationResult } from './utils/verifyTee';\nexport { verifyAttestorTeeAttestation } from './utils/verifyAttestorTee';\nexport type { AttestorTeeVerificationResult } from './utils/verifyAttestorTee';\nexport { TeeVerificationError } from './utils/errors';\n// Export device detection utilities for debugging (optional)\nexport {\n getDeviceType,\n getMobileDeviceType,\n isMobileDevice,\n isDesktopDevice,\n clearDeviceCache\n} from './utils/device';\n","export const SUPPORTED_TEE_ATTESTATION_VERSIONS = ['v2', 'v3'] as const;\n\nexport type TeeAttestationVersion = typeof SUPPORTED_TEE_ATTESTATION_VERSIONS[number];\n\nexport interface TeeAttestation {\n proof_version: TeeAttestationVersion;\n tee_provider: string;\n tee_technology: string;\n nonce: string;\n timestamp: string;\n workload: {\n container_name: string;\n image_digest: string;\n };\n verifier: {\n container_name: string;\n image_digest: string;\n };\n attestation: {\n token: string;\n };\n error?: {\n code: string;\n message: string;\n };\n}\n\n// Proof-related interfaces\nexport interface Proof {\n identifier: string;\n claimData: ProviderClaimData;\n signatures: string[];\n witnesses: WitnessData[];\n extractedParameterValues: any;\n /**\n * A JSON serializable object that is returned by the provider as additional data attached to proof.\n * This data is not verified or validated.\n */\n publicData?: any;\n taskId?: number;\n teeAttestation?: TeeAttestation;\n}\n\n// Extension Interactions\nexport const RECLAIM_EXTENSION_ACTIONS = {\n CHECK_EXTENSION: 'RECLAIM_EXTENSION_CHECK',\n EXTENSION_RESPONSE: 'RECLAIM_EXTENSION_RESPONSE',\n START_VERIFICATION: 'RECLAIM_START_VERIFICATION',\n STATUS_UPDATE: 'RECLAIM_STATUS_UPDATE',\n};\n\nexport interface ExtensionMessage {\n action: string;\n messageId: string;\n data?: any;\n extensionID?: string;\n}\n\nexport interface WitnessData {\n id: string;\n url: string;\n claimAttestation?: AttestorClaimAttestation;\n}\n\n/**\n * Attestation produced by an attestor running inside a Trusted Execution\n * Environment. Binds the attestor's signing key (and its signature over\n * the claim) to a hardware-backed enclave identity.\n *\n * Verified by `runAttestorTeeVerification`.\n */\nexport interface AttestorClaimAttestation {\n /** ETH address of the attestor whose enclave produced the attestation. Matches `WitnessData.id`. */\n attestor_address: string;\n /** Attestor signature over the claim. Must equal the corresponding entry in `Proof.signatures`. */\n claim_signature: string;\n /** Raw attestation report. For GCP Confidential Space, a JWT (header.payload.signature). */\n attestation_report: string;\n}\n\nexport interface ProviderClaimData {\n provider: string;\n parameters: string;\n owner: string;\n timestampS: number;\n context: string;\n identifier: string;\n epoch: number;\n}\n\n// Context and Beacon interfaces\nexport interface Context {\n contextAddress: string;\n contextMessage: string;\n reclaimSessionId: string;\n extractedParameters?: Record<string, string>;\n providerHash?: string;\n attestationNonce?: string;\n attestationNonceData?: {\n applicationId: string;\n sessionId: string;\n timestamp: string;\n attestationVersion?: TeeAttestationVersion;\n };\n}\n\nexport interface Beacon {\n getState(epoch?: number): Promise<BeaconState>;\n close?(): Promise<void>;\n}\n\nexport type BeaconState = {\n witnesses: WitnessData[];\n epoch: number;\n witnessesRequiredForClaim: number;\n nextEpochTimestampS: number;\n};\n\n/**\n * Information of the exact provider and its version used in the verification session.\n * \n * See also:\n * \n * * `ReclaimProofRequest.getProviderVersion()` - With a ReclaimProofRequest object, you can get the provider id & exact version of provider used in verification session.\n */\nexport interface ProviderVersionInfo {\n /**\n * The identifier of provider used in verifications that resulted in a proof\n * \n * See also:\n * \n * * `ReclaimProofRequest.getProviderVersion()` - With a ReclaimProofRequest object, you can get the provider id & exact version of provider used in verification session.\n */\n providerId: string;\n /**\n * The exact version of provider used in verifications that resulted in a proof.\n * \n * This cannot be a version constaint or version expression.\n * \n * See also:\n * \n * * `ReclaimProofRequest.getProviderVersion()` - With a ReclaimProofRequest object, you can get the provider id & exact version of provider used in verification session.\n */\n providerVersion: string;\n /**\n * List of allowed pre-release tags.\n * For example, if you are using AI, provide `['ai']` to allow AI patch versions of the provider.\n */\n allowedTags: string[];\n}\n","import {\n type Proof,\n type Context,\n RECLAIM_EXTENSION_ACTIONS,\n ExtensionMessage,\n ProviderVersionInfo,\n} from './utils/interfaces'\nimport {\n ProofRequestOptions,\n StartSessionParams,\n ProofPropertiesJSON,\n TemplateData,\n InitSessionResponse,\n ClaimCreationType,\n ModalOptions,\n ReclaimFlowLaunchOptions,\n type FlowHandle,\n HttpFormEntry,\n HttpRedirectionMethod,\n type VerifyProofResult,\n} from './utils/types'\nimport { SessionStatus, DeviceType } from './utils/types'\nimport { ethers } from 'ethers'\nimport canonicalize from 'canonicalize'\nimport {\n createVerifyProofResultSuccess,\n createVerifyProofResultFailure,\n replaceAll,\n scheduleIntervalEndingTask\n} from './utils/helper'\nimport { constants, setBackendBaseUrl } from './utils/constants'\nimport {\n SetContextError,\n GetAppCallbackUrlError,\n GetStatusUrlError,\n InitError,\n InvalidParamError,\n ProofNotVerifiedError,\n ProofSubmissionFailedError,\n ProviderFailedError,\n SessionNotStartedError,\n SetParamsError,\n SetSignatureError,\n SignatureGeneratingError,\n SignatureNotFoundError,\n ErrorDuringVerificationError,\n CallbackUrlRequiredError,\n ProofNotValidatedError,\n} from './utils/errors';\nimport { validateContext, validateFunctionParams, validateParameters, validateSignature, validateURL, validateModalOptions, validateFunctionParamsWithFn, validateRedirectionMethod, validateRedirectionBody } from './utils/validationUtils'\nimport { fetchStatusUrl, initSession, updateSession } from './utils/sessionUtils'\nimport { assertVerifiedProof, createLinkWithTemplateData, getAttestors } from './utils/proofUtils'\nimport { QRCodeModal } from './utils/modalUtils'\nimport loggerModule from './utils/logger';\nimport { getDeviceType, getMobileDeviceType } from './utils/device'\nimport { generateAttestationNonce } from './utils/attestationNonce'\nimport { canonicalStringify } from './utils/strings'\nimport { assertValidateProof, VerificationConfig } from './utils/proofValidationUtils'\nimport { runTeeVerification } from './utils/verifyTee'\nimport { runAttestorTeeVerification } from './utils/verifyAttestorTee'\nimport { fetchProviderHashRequirementsBy, ProviderHashRequirementsConfig } from './utils/providerUtils'\n\nconst logger = loggerModule.logger\n\nconst sdkVersion = require('../package.json').version;\nconst SDK_TEE_ATTESTATION_VERSION = 'v3' as const;\n\n/**\n * Verifies one or more Reclaim proofs by validating signatures, verifying witness information,\n * and performing content validation against the expected configuration.\n *\n * See also:\n *\n * * `ReclaimProofRequest.getProviderHashRequirements()` - To get the expected proof hash requirements for a proof request.\n * * `fetchProviderHashRequirementsBy()` - To get the expected proof hash requirements for a provider version by providing providerId and exactProviderVersionString.\n * * `getProviderHashRequirementsFromSpec()` - To get the expected proof hash requirements from a provider spec.\n * * All 3 functions above are alternatives of each other and result from these functions can be directly used as `config` parameter in this function for proof validation.\n *\n * Replay protection: this function is stateless. It verifies that a proof is cryptographically\n * bound to a specific `sessionId`/`applicationId` (via the `appSecret`-keyed attestation nonce\n * when `teeAttestation` is provided) but does not track which proofs have already been\n * verified. Callers must (a) verify the proof's `sessionId` matches a session they initiated\n * and (b) persist accepted `sessionId`s and reject duplicates. See the README's\n * \"Replay Protection\" section for details.\n *\n * @param proofOrProofs - A single proof object or an array of proof objects to be verified.\n * @param config - Verification configuration that specifies required hashes, allowed extra hashes, or disables content validation. Optionally includes `teeAttestation` to require TEE attestation verification.\n * @returns Verification result with `isVerified`, `isTeeAttestationVerified` (always boolean), extracted `data` from each proof, and optional `error` on failure. The application ID is derived from `appSecret` automatically.\n *\n * @example\n * ```typescript\n * // Fast and simple automatically fetched verification\n * const { isVerified, data } = await verifyProof(proof, request.getProviderVersion());\n *\n * // With TEE attestation verification (fails if TEE data is missing or invalid)\n * const { isVerified, isTeeAttestationVerified, data } = await verifyProof(proof, { ...request.getProviderVersion(), teeAttestation: { appSecret: APP_SECRET } });\n * \n * // Or, by manually providing the details:\n * \n * const { isVerified, data } = await verifyProof(proof, { \n * providerId: \"YOUR_PROVIDER_ID\", \n * // The exact provider version used in the session.\n * providerVersion: \"1.0.0\",\n * // Optionally provide tags. For example, this can be `['ai']` when you want to allow patches from ai.\n * allowedTags: [\"ai\"]\n * });\n * \n * // Validate a single proof against expected hash\n * const { isVerified, data } = await verifyProof(proof, { hashes: ['0xAbC...'] });\n * if (isVerified) {\n * console.log(data[0].context);\n * console.log(data[0].extractedParameters);\n * }\n *\n * // Validate multiple proofs\n * const { isVerified, data } = await verifyProof([proof1, proof2], {\n * hashes: ['0xAbC...', '0xF22..'],\n * });\n * \n * // Validate multiple proofs and handle optional matches or repeated proofs\n * const { isVerified, data } = await verifyProof([proof1, proof2, sameAsProof2], { \n * hashes: [\n * // A string hash is perfectly equivalent to { value: '...', required: true, multiple: true }\n * '0xStrict1...', \n * // An array 'value' means 1 proof can have any 1 matching hash from this list.\n * // 'multiple: true' (the default) means any proof matching this hash is allowed to appear multiple times in the list of proofs.\n * { value: ['0xOpt1..', '0xOpt2..'], multiple: true }, \n * // 'required: false' means there can be 0 proofs matching this hash. Such proofs may be optionally present. (Defaults to true).\n * { value: '0xE33..', required: false }\n * ],\n * });\n * ```\n */\nexport async function verifyProof(\n proofOrProofs: Proof | Proof[],\n config: VerificationConfig,\n): Promise<VerifyProofResult> {\n const proofs = Array.isArray(proofOrProofs) ? proofOrProofs : [proofOrProofs];\n try {\n if (proofs.length === 0) {\n throw new ProofNotValidatedError('No proofs provided');\n }\n\n if (!config) {\n throw new ProofNotValidatedError('Verification configuration is required for `verifyProof(proof, config)`');\n }\n\n const attestors = await getAttestors()\n for (const proof of proofs) {\n await assertVerifiedProof(proof, attestors)\n }\n\n await assertValidateProof(proofs, config);\n\n let isTeeAttestationVerified: boolean | undefined;\n let isAttestorTeeAttestationVerified: boolean | undefined;\n\n if (config.teeAttestation && 'dangerouslyDisableContentValidation' in config && config.dangerouslyDisableContentValidation) {\n logger.warn('teeAttestation is enabled but content validation is disabled — TEE attestation alone does not guarantee proof contents are valid');\n }\n\n if (config.teeAttestation) {\n await runTeeVerification(proofs, config.teeAttestation);\n isTeeAttestationVerified = true;\n }\n\n if (config.attestorTeeAttestation) {\n await runAttestorTeeVerification(proofs, config.attestorTeeAttestation);\n isAttestorTeeAttestationVerified = true;\n }\n\n return createVerifyProofResultSuccess(proofs, isTeeAttestationVerified, isAttestorTeeAttestationVerified);\n } catch (error) {\n logger.error('Error in validating proof:', error);\n const _error = error instanceof Error ? error : new Error(String(error));\n return createVerifyProofResultFailure(_error);\n }\n}\n\n/**\n * Transforms a Reclaim proof into a format suitable for on-chain verification\n *\n * @param proof - The proof object to transform\n * @returns Object containing claimInfo and signedClaim formatted for blockchain contracts\n *\n * @example\n * ```typescript\n * const { claimInfo, signedClaim } = transformForOnchain(proof);\n * // Use claimInfo and signedClaim with smart contract verification\n * ```\n */\nexport function transformForOnchain(proof: Proof): { claimInfo: any, signedClaim: any } {\n const claimInfoBuilder = new Map([\n ['context', proof.claimData.context],\n ['parameters', proof.claimData.parameters],\n ['provider', proof.claimData.provider],\n ]);\n const claimInfo = Object.fromEntries(claimInfoBuilder);\n const claimBuilder = new Map<string, number | string>([\n ['epoch', proof.claimData.epoch],\n ['identifier', proof.claimData.identifier],\n ['owner', proof.claimData.owner],\n ['timestampS', proof.claimData.timestampS],\n ]);\n const signedClaim = {\n claim: Object.fromEntries(claimBuilder),\n signatures: proof.signatures,\n };\n return { claimInfo, signedClaim };\n}\n\n// create a empty template data object to assign to templateData\nconst emptyTemplateData: TemplateData = {\n sessionId: '',\n providerId: '',\n applicationId: '',\n signature: '',\n timestamp: '',\n callbackUrl: '',\n context: '',\n parameters: {},\n redirectUrl: '',\n redirectUrlOptions: { method: 'GET' },\n cancelCallbackUrl: '',\n cancelRedirectUrl: '',\n cancelRedirectUrlOptions: { method: 'GET' },\n acceptAiProviders: false,\n sdkVersion: '',\n providerVersion: '',\n resolvedProviderVersion: '',\n jsonProofResponse: false,\n log: false\n}\nexport class ReclaimProofRequest {\n private applicationId: string;\n private signature?: string;\n private appCallbackUrl?: string;\n private sessionId: string;\n private options?: ProofRequestOptions;\n private context: Context = { contextAddress: '0x0', contextMessage: 'sample context', reclaimSessionId: '' };\n private attestationNonce?: string;\n private attestationNonceData?: Context['attestationNonceData'];\n private claimCreationType?: ClaimCreationType = ClaimCreationType.STANDALONE;\n private providerId: string;\n private resolvedProviderVersion?: string;\n private parameters: { [key: string]: string };\n private redirectUrl?: string;\n private redirectUrlOptions?: TemplateData['redirectUrlOptions'];\n private cancelCallbackUrl?: TemplateData['cancelCallbackUrl'];\n private cancelRedirectUrl?: TemplateData['cancelRedirectUrl'];\n private cancelRedirectUrlOptions?: TemplateData['cancelRedirectUrlOptions'];\n private intervals: Map<string, NodeJS.Timer> = new Map();\n private timeStamp: string;\n private sdkVersion: string;\n private jsonProofResponse: boolean = false;\n private lastFailureTime?: number;\n private templateData: TemplateData;\n private extensionID: string = \"reclaim-extension\";\n private customSharePageUrl?: string;\n private appSharePageUrl: string = constants.DEFAULT_APP_SHARE_PAGE_URL;\n private customAppClipUrl?: string;\n private portalTab?: Window | null;\n private portalIframe?: HTMLIFrameElement;\n private modalOptions?: ModalOptions;\n private modal?: QRCodeModal;\n private readonly FAILURE_TIMEOUT = 30 * 1000; // 30 seconds timeout, can be adjusted\n\n private constructor(applicationId: string, providerId: string, options?: ProofRequestOptions) {\n this.providerId = providerId;\n this.timeStamp = Date.now().toString();\n this.applicationId = applicationId;\n this.sessionId = \"\";\n // keep template data as empty object\n this.templateData = emptyTemplateData;\n this.parameters = {};\n\n if (!options) {\n options = {};\n }\n\n options.useBrowserExtension = options.useBrowserExtension ?? true;\n\n if (options?.log) {\n loggerModule.setLogLevel('info');\n } else {\n loggerModule.setLogLevel('silent');\n }\n\n if (options.useAppClip === undefined) {\n options.useAppClip = false;\n }\n\n // portalUrl is an alias for customSharePageUrl (portalUrl takes precedence)\n // When set, overrides both portal and app share page URLs\n const customUrl = options.portalUrl || options.customSharePageUrl;\n this.customSharePageUrl = customUrl || constants.DEFAULT_PORTAL_URL;\n if (customUrl && customUrl !== constants.DEFAULT_PORTAL_URL) {\n this.appSharePageUrl = customUrl;\n }\n options.customSharePageUrl = this.customSharePageUrl;\n\n if (options?.envUrl) {\n setBackendBaseUrl(options.envUrl);\n } else if (this.customSharePageUrl) {\n try {\n if (new URL(this.customSharePageUrl).hostname === 'eu.portal.reclaimprotocol.org') {\n setBackendBaseUrl('https://eu.api.reclaimprotocol.org');\n }\n } catch { /* invalid URL handled by validateURL in init */ }\n }\n\n if (options.extensionID) {\n this.extensionID = options.extensionID;\n }\n\n if (options?.customAppClipUrl) {\n this.customAppClipUrl = options.customAppClipUrl;\n }\n\n this.options = options;\n // Fetch sdk version from package.json\n this.sdkVersion = 'js-' + sdkVersion;\n logger.info(`Initializing client with applicationId: ${this.applicationId}`);\n }\n\n /**\n * Initializes a new Reclaim proof request instance with automatic signature generation and session creation.\n *\n * @param applicationId - Your Reclaim application ID\n * @param appSecret - Your application secret key for signing requests\n * @param providerId - The ID of the provider to use for proof generation\n * @param options - Optional configuration options for the proof request\n * @returns A fully initialized proof request instance\n * @throws {InitError} When initialization fails due to invalid parameters or session creation errors\n *\n * @example\n * ```typescript\n * const proofRequest = await ReclaimProofRequest.init(\n * 'your-app-id',\n * 'your-app-secret',\n * 'provider-id',\n * { portalUrl: 'https://portal.reclaimprotocol.org', log: true }\n * );\n * ```\n */\n static async init(applicationId: string, appSecret: string, providerId: string, options?: ProofRequestOptions): Promise<ReclaimProofRequest> {\n try {\n validateFunctionParams([\n { paramName: 'applicationId', input: applicationId, isString: true },\n { paramName: 'providerId', input: providerId, isString: true },\n { paramName: 'appSecret', input: appSecret, isString: true }\n ], 'the constructor')\n\n ReclaimProofRequest.validateInitOptions(options, 'the constructor')\n\n const proofRequestOptions = {\n ...options,\n acceptTeeAttestation: options?.acceptTeeAttestation ?? true\n };\n\n const proofRequestInstance = new ReclaimProofRequest(applicationId, providerId, proofRequestOptions)\n\n const signature = await proofRequestInstance.generateSignature(appSecret)\n proofRequestInstance.setSignature(signature)\n\n const data: InitSessionResponse = await initSession(providerId, applicationId, proofRequestInstance.timeStamp, signature, options?.providerVersion);\n proofRequestInstance.sessionId = data.sessionId\n proofRequestInstance.resolvedProviderVersion = data.resolvedProviderVersion\n proofRequestInstance.context.reclaimSessionId = data.sessionId\n\n if (proofRequestOptions.acceptTeeAttestation) {\n const attestationNonce = generateAttestationNonce(\n appSecret,\n applicationId,\n data.sessionId,\n proofRequestInstance.timeStamp\n )\n\n proofRequestInstance.setAttestationContext(attestationNonce, {\n applicationId,\n sessionId: data.sessionId,\n timestamp: proofRequestInstance.timeStamp,\n attestationVersion: SDK_TEE_ATTESTATION_VERSION\n })\n }\n\n return proofRequestInstance\n } catch (error) {\n console.error(error);\n logger.info('Failed to initialize ReclaimProofRequest', error as Error);\n throw new InitError('Failed to initialize ReclaimProofRequest', error as Error)\n }\n }\n\n /**\n * Initializes a new Reclaim proof request using a signature computed externally\n * (e.g. on a trusted backend), so `appSecret` never has to live on the client.\n *\n * The signature must be produced over `canonicalize({ providerId, timestamp })`\n * using the application's `appSecret` — see `generateInitSignature()` for the\n * exact algorithm. The same `timestamp` used at signing time must be passed here.\n *\n * TEE attestation: the attestation nonce depends on `sessionId`, which is only\n * known after the backend init call. To use TEE without exposing `appSecret`,\n * pass an async `getAttestationNonce` callback that derives the nonce on your\n * server using `generateAttestationNonce(appSecret, applicationId, sessionId, timestamp)`.\n * If `acceptTeeAttestation` is left enabled but no callback is provided, init throws.\n *\n * @param applicationId - Your Reclaim application ID\n * @param providerId - The ID of the provider to use for proof generation\n * @param sessionAuth - Pre-computed signature, the timestamp it was signed over,\n * and an optional async callback to compute the attestation nonce.\n * @param options - Optional configuration options for the proof request\n *\n * @example\n * ```typescript\n * // Backend (Node):\n * const timestamp = Date.now().toString();\n * const signature = await generateInitSignature(APP_SECRET, providerId, timestamp);\n * // ...return { signature, timestamp } to the client...\n *\n * // Client:\n * const proofRequest = await ReclaimProofRequest.initWithSignature(\n * applicationId,\n * providerId,\n * { signature, timestamp },\n * { acceptTeeAttestation: false }\n * );\n * ```\n */\n static async initWithSignature(\n applicationId: string,\n providerId: string,\n sessionAuth: {\n signature: string;\n timestamp: string;\n getAttestationNonce?: (sessionId: string) => Promise<string> | string;\n },\n options?: ProofRequestOptions\n ): Promise<ReclaimProofRequest> {\n try {\n validateFunctionParams([\n { paramName: 'applicationId', input: applicationId, isString: true },\n { paramName: 'providerId', input: providerId, isString: true },\n { paramName: 'signature', input: sessionAuth?.signature, isString: true },\n { paramName: 'timestamp', input: sessionAuth?.timestamp, isString: true }\n ], 'initWithSignature')\n\n ReclaimProofRequest.validateInitOptions(options, 'initWithSignature')\n\n const proofRequestOptions = {\n ...options,\n acceptTeeAttestation: options?.acceptTeeAttestation ?? true\n };\n\n if (proofRequestOptions.acceptTeeAttestation && !sessionAuth.getAttestationNonce) {\n throw new InvalidParamError(\n 'initWithSignature requires a `getAttestationNonce` callback when `acceptTeeAttestation` is enabled. ' +\n 'Either pass `acceptTeeAttestation: false`, or provide a callback that computes the nonce server-side ' +\n 'using `generateAttestationNonce(appSecret, applicationId, sessionId, timestamp)`.'\n )\n }\n\n const proofRequestInstance = new ReclaimProofRequest(applicationId, providerId, proofRequestOptions)\n proofRequestInstance.timeStamp = sessionAuth.timestamp\n proofRequestInstance.setSignature(sessionAuth.signature)\n\n const data: InitSessionResponse = await initSession(\n providerId,\n applicationId,\n sessionAuth.timestamp,\n sessionAuth.signature,\n options?.providerVersion\n );\n proofRequestInstance.sessionId = data.sessionId\n proofRequestInstance.resolvedProviderVersion = data.resolvedProviderVersion\n proofRequestInstance.context.reclaimSessionId = data.sessionId\n\n if (proofRequestOptions.acceptTeeAttestation && sessionAuth.getAttestationNonce) {\n const attestationNonce = await sessionAuth.getAttestationNonce(data.sessionId)\n validateFunctionParams(\n [{ input: attestationNonce, paramName: 'attestationNonce', isString: true }],\n 'initWithSignature'\n )\n proofRequestInstance.setAttestationContext(attestationNonce, {\n applicationId,\n sessionId: data.sessionId,\n timestamp: sessionAuth.timestamp,\n attestationVersion: SDK_TEE_ATTESTATION_VERSION\n })\n }\n\n return proofRequestInstance\n } catch (error) {\n console.error(error);\n logger.info('Failed to initialize ReclaimProofRequest with signature', error as Error);\n throw new InitError('Failed to initialize ReclaimProofRequest with signature', error as Error)\n }\n }\n\n /**\n * Creates a ReclaimProofRequest instance from a JSON string representation\n *\n * This method deserializes a previously exported proof request (via toJsonString) and reconstructs\n * the instance with all its properties. Useful for recreating requests on the frontend or across different contexts.\n *\n * @param jsonString - JSON string containing the serialized proof request data\n * @returns {Promise<ReclaimProofRequest>} - Reconstructed proof request instance\n * @throws {InvalidParamError} When JSON string is invalid or contains invalid parameters\n *\n * @example\n * ```typescript\n * const jsonString = proofRequest.toJsonString();\n * const reconstructed = await ReclaimProofRequest.fromJsonString(jsonString);\n * // Can also be used with InApp SDK's startVerificationFromJson method\n * ```\n */\n static async fromJsonString(jsonString: string): Promise<ReclaimProofRequest> {\n try {\n const {\n applicationId,\n providerId,\n sessionId,\n context,\n parameters,\n signature,\n redirectUrl,\n redirectUrlOptions,\n cancelCallbackUrl,\n cancelRedirectUrl,\n cancelRedirectUrlOptions,\n timeStamp,\n timestamp,\n appCallbackUrl,\n claimCreationType,\n options,\n sdkVersion,\n jsonProofResponse,\n resolvedProviderVersion,\n modalOptions\n }: ProofPropertiesJSON = JSON.parse(jsonString)\n\n // Prefer 'timestamp' over 'timeStamp' for backward compatibility (remove in future versions)\n const resolvedTimestamp = timestamp || timeStamp;\n\n validateFunctionParams([\n { input: applicationId, paramName: 'applicationId', isString: true },\n { input: providerId, paramName: 'providerId', isString: true },\n { input: signature, paramName: 'signature', isString: true },\n { input: sessionId, paramName: 'sessionId', isString: true },\n { input: resolvedTimestamp, paramName: 'timestamp', isString: true },\n { input: sdkVersion, paramName: 'sdkVersion', isString: true },\n ], 'fromJsonString');\n\n if (modalOptions) {\n validateModalOptions(modalOptions, 'fromJsonString', 'modalOptions.');\n }\n\n if (redirectUrl) {\n validateURL(redirectUrl, 'fromJsonString');\n }\n\n if (redirectUrlOptions) {\n validateRedirectionMethod(redirectUrlOptions.method, 'fromJsonString');\n validateRedirectionBody(redirectUrlOptions.body, 'fromJsonString');\n }\n\n if (appCallbackUrl) {\n validateURL(appCallbackUrl, 'fromJsonString');\n }\n\n if (cancelRedirectUrl) {\n validateURL(cancelRedirectUrl, 'fromJsonString');\n }\n\n if (cancelRedirectUrlOptions) {\n validateRedirectionMethod(cancelRedirectUrlOptions.method, 'fromJsonString');\n validateRedirectionBody(cancelRedirectUrlOptions.body, 'fromJsonString');\n }\n\n if (cancelCallbackUrl) {\n validateURL(cancelCallbackUrl, 'fromJsonString');\n }\n\n if (context) {\n validateContext(context);\n }\n\n if (parameters) {\n validateParameters(parameters);\n }\n\n if (claimCreationType) {\n validateFunctionParams([\n { input: claimCreationType, paramName: 'claimCreationType' }\n ], 'fromJsonString');\n }\n\n if (jsonProofResponse !== undefined) {\n validateFunctionParams([\n { input: jsonProofResponse, paramName: 'jsonProofResponse' }\n ], 'fromJsonString');\n }\n\n\n if (options?.providerVersion) {\n validateFunctionParams([\n { input: options.providerVersion, paramName: 'options.providerVersion', isString: true }\n ], 'fromJsonString');\n }\n\n if (resolvedProviderVersion) {\n validateFunctionParams([\n { input: resolvedProviderVersion, paramName: 'resolvedProviderVersion', isString: true }\n ], 'fromJsonString');\n }\n\n if (options?.preferredLocale) {\n validateFunctionParams([\n { paramName: 'options.preferredLocale', input: options.preferredLocale, isString: true }\n ], 'fromJsonString');\n validateFunctionParamsWithFn({\n paramName: 'options.preferredLocale', input: options.preferredLocale, isValid: () => {\n try {\n Intl.getCanonicalLocales(options.preferredLocale);\n return true;\n } catch (error) {\n logger.info('Failed to canonicalize locale', error);\n return false;\n }\n }\n }, 'fromJsonString');\n }\n const proofRequestInstance = new ReclaimProofRequest(applicationId, providerId, options);\n proofRequestInstance.sessionId = sessionId;\n proofRequestInstance.context = context;\n proofRequestInstance.setAttestationContext(context?.attestationNonce, context?.attestationNonceData);\n proofRequestInstance.parameters = parameters;\n proofRequestInstance.appCallbackUrl = appCallbackUrl;\n proofRequestInstance.redirectUrl = redirectUrl;\n proofRequestInstance.redirectUrlOptions = redirectUrlOptions;\n proofRequestInstance.timeStamp = resolvedTimestamp!\n proofRequestInstance.signature = signature\n proofRequestInstance.sdkVersion = sdkVersion;\n proofRequestInstance.resolvedProviderVersion = resolvedProviderVersion;\n proofRequestInstance.modalOptions = modalOptions;\n proofRequestInstance.jsonProofResponse = jsonProofResponse ?? false;\n proofRequestInstance.cancelCallbackUrl = cancelCallbackUrl;\n proofRequestInstance.cancelRedirectUrl = cancelRedirectUrl;\n proofRequestInstance.cancelRedirectUrlOptions = cancelRedirectUrlOptions;\n return proofRequestInstance\n } catch (error) {\n logger.info('Failed to parse JSON string in fromJsonString:', error);\n throw new InvalidParamError('Invalid JSON string provided to fromJsonString');\n }\n }\n\n /**\n * Sets a custom callback URL where proofs will be submitted via HTTP `POST`\n *\n * By default, proofs are sent as HTTP POST with `Content-Type` as `application/x-www-form-urlencoded`.\n * Pass function argument `jsonProofResponse` as `true` to send proofs with `Content-Type` as `application/json`.\n *\n * When a custom callback URL is set, proofs are sent to the custom URL *instead* of the Reclaim backend.\n * Consequently, the startSession `onSuccess` callback will be invoked with an empty array (`[]`)\n * instead of the proof data, as the proof is not available to the SDK in this flow.\n *\n * This verification session's id will be present in `X-Reclaim-Session-Id` header of the request.\n * The request URL will contain query param `allowAiWitness` with value `true` when AI Witness should be allowed by handler of the request.\n *\n * Note: InApp SDKs are unaffected by this property as they do not handle proof submission.\n *\n * @param url - The URL where proofs should be submitted via HTTP `POST`\n * @param jsonProofResponse - Optional. Set to true to submit proofs as `application/json`. Defaults to false\n * @throws {InvalidParamError} When URL is invalid\n *\n * @example\n * ```typescript\n * proofRequest.setAppCallbackUrl('https://your-backend.com/callback');\n * // Or with JSON format\n * proofRequest.setAppCallbackUrl('https://your-backend.com/callback', true);\n * ```\n */\n setAppCallbackUrl(url: string, jsonProofResponse?: boolean): void {\n validateURL(url, 'setAppCallbackUrl')\n this.appCallbackUrl = url\n this.jsonProofResponse = jsonProofResponse ?? false\n }\n\n /**\n * Sets a redirect URL where users will be redirected after successfully acquiring and submitting proof\n *\n * @param url - The URL where users should be redirected after successful proof generation\n * @param method - The redirection method that should be used for redirection. Allowed options: `GET`, and `POST`.\n * `POST` form redirection is only supported in Portal flow.\n * @param body - List of name-value pairs to be sent as the body of the form request.\n * `When `method` is set to `POST`, `body` will be sent with 'application/x-www-form-urlencoded' content type.\n * When `method` is set to `GET`, if `body` is set then `body` will be sent as query parameters.\n * Sending `body` on redirection is only supported in Portal flow.\n *\n * @throws {InvalidParamError} When URL is invalid\n *\n * @example\n * ```typescript\n * proofRequest.setRedirectUrl('https://your-app.com/success');\n * ```\n */\n setRedirectUrl(url: string, method: HttpRedirectionMethod = 'GET', body?: HttpFormEntry[] | undefined): void {\n validateURL(url, 'setRedirectUrl');\n validateRedirectionMethod(method, 'setRedirectUrl');\n validateRedirectionBody(body, 'setRedirectUrl');\n\n this.redirectUrl = url;\n this.redirectUrlOptions = { method: method || 'GET', body: body }\n }\n\n /**\n * Sets a custom callback URL where errors that abort the verification process will be submitted via HTTP POST\n *\n * Errors will be HTTP POSTed with `header 'Content-Type': 'application/json'`.\n * When a custom error callback URL is set, Reclaim will no longer receive errors upon submission,\n * and listeners on the startSession method will not be triggered. Your application must\n * coordinate with your backend to receive errors.\n *\n * This verification session's id will be present in `X-Reclaim-Session-Id` header of the request.\n *\n * Following is the data format which is sent as an HTTP POST request to the url with `Content-Type: application/json`:\n\n * ```json\n * {\n * \"type\": \"string\", // Name of the exception\n * \"message\": \"string\",\n * \"sessionId\": \"string\",\n * // context as canonicalized json string\n * \"context\": \"string\",\n * // Other fields with more details about error may be present\n * // [key: any]: any\n * }\n * ```\n *\n * For more details about response format, check out [official documentation of Error Callback URL](https://docs.reclaimprotocol.org/js-sdk/preparing-request#cancel-callback).\n *\n * @param url - The URL where errors should be submitted via HTTP POST\n * @throws {InvalidParamError} When URL is invalid\n *\n * @example\n * ```typescript\n * proofRequest.setCancelCallbackUrl('https://your-backend.com/error-callback');\n * ```\n *\n * @since 4.8.1\n *\n */\n setCancelCallbackUrl(url: string): void {\n validateURL(url, 'setCancelCallbackUrl')\n this.cancelCallbackUrl = url\n }\n\n /**\n * Sets an error redirect URL where users will be redirected after an error which aborts the verification process\n *\n * @param url - The URL where users should be redirected after an error which aborts the verification process\n * @param method - The redirection method that should be used for redirection. Allowed options: `GET`, and `POST`.\n * `POST` form redirection is only supported in Portal flow.\n * @param body - List of name-value pairs to be sent as the body of the form request.\n * When `method` is set to `POST`, `body` will be sent with 'application/x-www-form-urlencoded' content type.\n * When `method` is set to `GET`, if `body` is set then `body` will be sent as query parameters.\n * Sending `body` on redirection is only supported in Portal flow.\n * @throws {InvalidParamError} When URL is invalid\n *\n * @example\n * ```typescript\n * proofRequest.setCancelRedirectUrl('https://your-app.com/error');\n * ```\n *\n * @since 4.10.0\n *\n */\n setCancelRedirectUrl(url: string, method: HttpRedirectionMethod = 'GET', body?: HttpFormEntry[] | undefined): void {\n validateURL(url, 'setCancelRedirectUrl');\n validateRedirectionMethod(method, 'setCancelRedirectUrl');\n validateRedirectionBody(body, 'setCancelRedirectUrl');\n\n this.cancelRedirectUrl = url;\n this.cancelRedirectUrlOptions = { method: method || 'GET', body: body }\n }\n\n /**\n * Sets the claim creation type for the proof request\n *\n * @param claimCreationType - The type of claim creation (e.g., STANDALONE)\n *\n * @example\n * ```typescript\n * proofRequest.setClaimCreationType(ClaimCreationType.STANDALONE);\n * ```\n */\n setClaimCreationType(claimCreationType: ClaimCreationType): void {\n this.claimCreationType = claimCreationType;\n }\n\n /**\n * Sets custom options for the QR code modal display\n *\n * @param options - Modal configuration options including title, description, theme, etc.\n * @throws {SetParamsError} When modal options are invalid\n *\n * @example\n * ```typescript\n * proofRequest.setModalOptions({\n * title: 'Scan QR Code',\n * description: 'Scan with your mobile device',\n * darkTheme: true\n * });\n * ```\n */\n setModalOptions(options: ModalOptions): void {\n try {\n // Validate modal options\n validateModalOptions(options, 'setModalOptions');\n\n this.modalOptions = { ...this.modalOptions, ...options };\n logger.info('Modal options set successfully');\n } catch (error) {\n logger.info('Error setting modal options:', error);\n throw new SetParamsError('Error setting modal options', error as Error);\n }\n }\n\n /**\n * Sets additional context data to be stored with the claim\n *\n * This allows you to associate custom JSON serializable data with the proof claim.\n * The context can be retrieved and validated when verifying the proof.\n *\n * Also see [setContext] which is an alternate way to set context that has an address & message.\n *\n * [setContext] and [setJsonContext] overwrite each other. Each call replaces the existing context.\n *\n * @param context - Any additional data you want to store with the claim. Should be serializable to a JSON string.\n * @throws {SetContextError} When context parameters are invalid\n *\n * @example\n * ```typescript\n * proofRequest.setJsonContext({foo: 'bar'});\n * ```\n */\n setJsonContext(context: Record<string, any>) {\n try {\n validateFunctionParams([\n { input: context, paramName: 'context', isString: false }\n ], 'setJsonContext');\n // ensure context is canonically json serializable\n this.context = JSON.parse(canonicalStringify({ ...context, reclaimSessionId: this.sessionId }));\n this.applyAttestationContext();\n } catch (error) {\n logger.info(\"Error setting context\", error)\n throw new SetContextError(\"Error setting context\", error as Error)\n }\n }\n\n /**\n * Sets additional context data to be stored with the claim\n *\n * This allows you to associate custom data (address and message) with the proof claim.\n * The context can be retrieved and validated when verifying the proof.\n *\n * Also see [setJsonContext] which is an alternate way to set context that allows for custom JSON serializable data.\n *\n * [setContext] and [setJsonContext] overwrite each other. Each call replaces the existing context.\n *\n * @param address - Context address identifier\n * @param message - Additional data to associate with the address\n * @throws {SetContextError} When context parameters are invalid\n *\n * @example\n * ```typescript\n * proofRequest.setContext('0x1234...', 'User verification for premium access');\n * ```\n */\n setContext(address: string, message: string): void {\n try {\n validateFunctionParams([\n { input: address, paramName: 'address', isString: true },\n { input: message, paramName: 'message', isString: true }\n ], 'setContext');\n this.context = { contextAddress: address, contextMessage: message, reclaimSessionId: this.sessionId };\n this.applyAttestationContext();\n } catch (error) {\n logger.info(\"Error setting context\", error)\n throw new SetContextError(\"Error setting context\", error as Error)\n }\n }\n\n /**\n * @deprecated use setContext instead\n *\n * @param address\n * @param message additional data you want associated with the [address]\n */\n addContext(address: string, message: string): void {\n this.setContext(address, message);\n }\n\n /**\n * Sets provider-specific parameters for the proof request\n *\n * These parameters are passed to the provider and may include configuration options,\n * filters, or other provider-specific settings required for proof generation.\n *\n * @param params - Key-value pairs of parameters to set\n * @throws {SetParamsError} When parameters are invalid\n *\n * @example\n * ```typescript\n * proofRequest.setParams({\n * minFollowers: '1000',\n * platform: 'twitter'\n * });\n * ```\n */\n setParams(params: { [key: string]: string }): void {\n try {\n validateParameters(params);\n this.parameters = { ...this.parameters, ...params }\n } catch (error) {\n logger.info('Error Setting Params:', error);\n throw new SetParamsError(\"Error setting params\", error as Error)\n }\n }\n\n /**\n * Returns the currently configured app callback URL\n *\n * If no custom callback URL was set via setAppCallbackUrl(), this returns the default\n * Reclaim service callback URL with the current session ID.\n *\n * @returns The callback URL where proofs will be submitted\n * @throws {GetAppCallbackUrlError} When unable to retrieve the callback URL\n *\n * @example\n * ```typescript\n * const callbackUrl = proofRequest.getAppCallbackUrl();\n * console.log('Proofs will be sent to:', callbackUrl);\n * ```\n */\n getAppCallbackUrl(): string {\n try {\n validateFunctionParams([{ input: this.sessionId, paramName: 'sessionId', isString: true }], 'getAppCallbackUrl');\n return this.appCallbackUrl || `${constants.DEFAULT_RECLAIM_CALLBACK_URL}${this.sessionId}`\n } catch (error) {\n logger.info(\"Error getting app callback url\", error)\n throw new GetAppCallbackUrlError(\"Error getting app callback url\", error as Error)\n }\n }\n\n /**\n * Returns the currently configured cancel callback URL\n *\n * If no custom cancel callback URL was set via setCancelCallbackUrl(), this returns the default\n * Reclaim service cancel callback URL with the current session ID.\n *\n * @returns The cancel callback URL where proofs will be submitted\n * @throws {GetAppCallbackUrlError} When unable to retrieve the cancel callback URL\n *\n * @example\n * ```typescript\n * const callbackUrl = proofRequest.getCancelCallbackUrl();\n * console.log('Errors will be sent to:', callbackUrl);\n * ```\n */\n getCancelCallbackUrl(): string {\n try {\n validateFunctionParams([{ input: this.sessionId, paramName: 'sessionId', isString: true }], 'getCancelCallbackUrl');\n return this.cancelCallbackUrl || `${constants.DEFAULT_RECLAIM_CANCEL_CALLBACK_URL}${this.sessionId}`\n } catch (error) {\n logger.info(\"Error getting cancel callback url\", error)\n throw new GetAppCallbackUrlError(\"Error getting cancel callback url\", error as Error)\n }\n }\n\n /**\n * Returns the status URL for monitoring the current session\n *\n * This URL can be used to check the status of the proof request session.\n *\n * @returns The status monitoring URL for the current session\n * @throws {GetStatusUrlError} When unable to retrieve the status URL\n *\n * @example\n * ```typescript\n * const statusUrl = proofRequest.getStatusUrl();\n * // Use this URL to poll for session status updates\n * ```\n */\n getStatusUrl(): string {\n try {\n validateFunctionParams([{ input: this.sessionId, paramName: 'sessionId', isString: true }], 'getStatusUrl');\n return `${constants.DEFAULT_RECLAIM_STATUS_URL}${this.sessionId}`\n } catch (error) {\n logger.info(\"Error fetching Status Url\", error)\n throw new GetStatusUrlError(\"Error fetching status url\", error as Error)\n }\n }\n\n /**\n * Returns the session ID associated with this proof request\n *\n * The session ID is automatically generated during initialization and uniquely\n * identifies this proof request session.\n *\n * @returns The session ID string\n * @throws {SessionNotStartedError} When session ID is not set\n *\n * @example\n * ```typescript\n * const sessionId = proofRequest.getSessionId();\n * console.log('Session ID:', sessionId);\n * ```\n */\n getSessionId(): string {\n if (!this.sessionId) {\n throw new SessionNotStartedError(\"SessionId is not set\");\n }\n return this.sessionId;\n }\n\n private static validateInitOptions(options: ProofRequestOptions | undefined, caller: string): void {\n if (!options) return;\n if (options.acceptAiProviders) {\n validateFunctionParams([{ paramName: 'acceptAiProviders', input: options.acceptAiProviders }], caller)\n }\n if (options.providerVersion) {\n validateFunctionParams([{ paramName: 'providerVersion', input: options.providerVersion, isString: true }], caller)\n }\n if (options.log) {\n validateFunctionParams([{ paramName: 'log', input: options.log }], caller)\n }\n if (options.useAppClip) {\n validateFunctionParams([{ paramName: 'useAppClip', input: options.useAppClip }], caller)\n }\n if (options.device) {\n validateFunctionParams([{ paramName: 'device', input: options.device, isString: true }], caller)\n }\n if (options.useBrowserExtension) {\n validateFunctionParams([{ paramName: 'useBrowserExtension', input: options.useBrowserExtension }], caller)\n }\n if (options.extensionID) {\n validateFunctionParams([{ paramName: 'extensionID', input: options.extensionID, isString: true }], caller)\n }\n if (options.envUrl) {\n validateFunctionParams([{ paramName: 'envUrl', input: options.envUrl, isString: true }], caller)\n }\n if (options.portalUrl) {\n validateFunctionParams([{ paramName: 'portalUrl', input: options.portalUrl, isString: true }], caller)\n }\n if (options.customSharePageUrl) {\n validateFunctionParams([{ paramName: 'customSharePageUrl', input: options.customSharePageUrl, isString: true }], caller)\n }\n if (options.customAppClipUrl) {\n validateFunctionParams([{ paramName: 'customAppClipUrl', input: options.customAppClipUrl, isString: true }], caller)\n }\n if (options.preferredLocale) {\n validateFunctionParams([{ paramName: 'preferredLocale', input: options.preferredLocale, isString: true }], caller);\n validateFunctionParamsWithFn({\n paramName: 'preferredLocale', input: options.preferredLocale, isValid: () => {\n try {\n Intl.getCanonicalLocales(options.preferredLocale);\n return true;\n } catch (error) {\n logger.info('Failed to canonicalize locale', error);\n return false;\n }\n }\n }, caller);\n }\n }\n\n // Private helper methods\n private setSignature(signature: string): void {\n try {\n validateFunctionParams([{ input: signature, paramName: 'signature', isString: true }], 'setSignature');\n this.signature = signature;\n logger.info(`Signature set successfully for applicationId: ${this.applicationId}`);\n } catch (error) {\n logger.info(\"Error setting signature\", error)\n throw new SetSignatureError(\"Error setting signature\", error as Error)\n }\n }\n\n private async generateSignature(applicationSecret: string): Promise<string> {\n try {\n const wallet = new ethers.Wallet(applicationSecret)\n const canonicalData = canonicalize({ providerId: this.providerId, timestamp: this.timeStamp });\n\n\n if (!canonicalData) {\n throw new SignatureGeneratingError('Failed to canonicalize data for signing.');\n }\n\n const messageHash = ethers.keccak256(new TextEncoder().encode(canonicalData));\n\n return await wallet.signMessage(ethers.getBytes(messageHash));\n } catch (err) {\n logger.info(`Error generating proof request for applicationId: ${this.applicationId}, providerId: ${this.providerId}, timeStamp: ${this.timeStamp}`);\n throw new SignatureGeneratingError(`Error generating signature for applicationId: ${this.applicationId}`)\n }\n }\n\n private clearInterval(): void {\n if (this.sessionId && this.intervals.has(this.sessionId)) {\n clearInterval(this.intervals.get(this.sessionId) as NodeJS.Timeout)\n this.intervals.delete(this.sessionId)\n }\n }\n\n private setAttestationContext(nonce?: string, data?: Context['attestationNonceData']): void {\n if (!nonce || !data) {\n return;\n }\n this.attestationNonce = nonce;\n this.attestationNonceData = data;\n this.applyAttestationContext();\n }\n\n private applyAttestationContext(): void {\n if (!this.attestationNonce || !this.attestationNonceData) {\n return;\n }\n this.context = {\n ...this.context,\n attestationNonce: this.attestationNonce,\n attestationNonceData: this.attestationNonceData\n };\n }\n\n private encodeTemplateData(templateData: TemplateData): string {\n let template = encodeURIComponent(JSON.stringify(templateData));\n template = replaceAll(template, '(', '%28');\n template = replaceAll(template, ')', '%29');\n return template;\n }\n\n private buildSharePageUrl(template: string): string {\n return `${this.appSharePageUrl}/?template=${template}`;\n }\n\n private async openPortalTab(templateData: TemplateData, preOpenedTab?: Window | null): Promise<void> {\n // Use pre-opened tab if provided, otherwise open one now\n const newTab = preOpenedTab ?? window.open('about:blank', '_blank');\n const link = await createLinkWithTemplateData(templateData, this.customSharePageUrl);\n logger.info('Opening portal in new tab: ' + link);\n if (newTab) {\n this.portalTab = newTab;\n newTab.location = link;\n // Verify navigation actually happened; close blank tab if it didn't\n setTimeout(() => {\n try {\n if (newTab.location.href === 'about:blank') {\n newTab.close();\n this.portalTab = undefined;\n window.open(link, '_blank');\n }\n } catch (_) {\n // Cross-origin after navigation means it worked\n }\n }, 500);\n }\n }\n\n private closePortalTab(): void {\n try {\n this.portalTab?.close();\n } catch (_) {\n // Cross-origin — tab may have navigated away\n }\n this.portalTab = undefined;\n }\n\n private async embedPortalIframe(templateData: TemplateData, target: HTMLElement): Promise<void> {\n let link = await createLinkWithTemplateData(templateData, this.customSharePageUrl);\n // Signal to the portal that it's embedded — skip extension detection\n const separator = link.includes('?') ? '&' : '?';\n link = `${link}${separator}embedded=true`;\n logger.info('Embedding portal in iframe: ' + link);\n\n this.closeEmbeddedFlow();\n\n const iframe = document.createElement('iframe');\n iframe.src = link;\n iframe.style.width = '100%';\n iframe.style.height = '100%';\n iframe.style.border = 'none';\n iframe.setAttribute('allow', 'clipboard-write');\n iframe.setAttribute('sandbox', 'allow-scripts allow-same-origin allow-forms');\n\n target.appendChild(iframe);\n this.portalIframe = iframe;\n }\n\n /**\n * Closes the embedded portal iframe and stops the session polling.\n *\n * Call this to programmatically cancel the embedded verification flow\n * that was started with `triggerReclaimFlow({ target: element })`.\n * Also called automatically when verification succeeds or fails.\n *\n * @example\n * ```typescript\n * proofRequest.closeEmbeddedFlow();\n * ```\n */\n closeEmbeddedFlow(): void {\n if (this.portalIframe) {\n this.portalIframe.remove();\n this.portalIframe = undefined;\n }\n this.clearInterval();\n }\n\n /**\n * Exports the Reclaim proof verification request as a JSON string\n *\n * This serialized format can be sent to the frontend to recreate this request using\n * ReclaimProofRequest.fromJsonString() or any InApp SDK's startVerificationFromJson()\n * method to initiate the verification journey.\n *\n * @returns JSON string representation of the proof request. Note: The JSON includes both `timestamp` and `timeStamp` (deprecated) for backward compatibility.\n *\n * @example\n * ```typescript\n * const jsonString = proofRequest.toJsonString();\n * // Send to frontend or store for later use\n * // Can be reconstructed with: ReclaimProofRequest.fromJsonString(jsonString)\n * ```\n */\n toJsonString(): string {\n return JSON.stringify({\n applicationId: this.applicationId,\n providerId: this.providerId,\n sessionId: this.sessionId,\n context: this.context,\n appCallbackUrl: this.appCallbackUrl,\n claimCreationType: this.claimCreationType,\n parameters: this.parameters,\n signature: this.signature,\n redirectUrl: this.redirectUrl,\n redirectUrlOptions: this.redirectUrlOptions,\n cancelCallbackUrl: this.cancelCallbackUrl,\n cancelRedirectUrl: this.cancelRedirectUrl,\n cancelRedirectUrlOptions: this.cancelRedirectUrlOptions,\n timestamp: this.timeStamp, // New field with correct spelling\n timeStamp: this.timeStamp, // @deprecated: Remove in future versions\n options: this.options,\n sdkVersion: this.sdkVersion,\n jsonProofResponse: this.jsonProofResponse,\n resolvedProviderVersion: this.resolvedProviderVersion ?? '',\n modalOptions: this.modalOptions ? {\n title: this.modalOptions.title,\n description: this.modalOptions.description,\n extensionUrl: this.modalOptions.extensionUrl,\n darkTheme: this.modalOptions.darkTheme,\n modalPopupTimer: this.modalOptions.modalPopupTimer,\n showExtensionInstallButton: this.modalOptions.showExtensionInstallButton\n // onClose is intentionally excluded as functions cannot be serialized\n } : undefined\n })\n }\n\n /**\n * Validates signature and returns template data\n * @returns\n */\n private getTemplateData = (): TemplateData => {\n if (!this.signature) {\n throw new SignatureNotFoundError('Signature is not set.')\n }\n\n // When using a non-default regional portal, a custom callback URL is required\n const defaultHosts = ['share.reclaimprotocol.org', 'portal.reclaimprotocol.org'];\n if (this.customSharePageUrl) {\n try {\n const sharePageHost = new URL(this.customSharePageUrl).hostname;\n if (!defaultHosts.includes(sharePageHost) && !this.appCallbackUrl) {\n throw new CallbackUrlRequiredError(\n 'A custom callback URL is required when using a customSharePage url'\n );\n }\n } catch (e) {\n if (e instanceof CallbackUrlRequiredError) throw e;\n // If URL parsing fails, skip this check — URL validation elsewhere will catch it\n }\n }\n\n validateSignature(this.providerId, this.signature, this.applicationId, this.timeStamp)\n const templateData: TemplateData = {\n sessionId: this.sessionId,\n providerId: this.providerId,\n applicationId: this.applicationId,\n signature: this.signature,\n timestamp: this.timeStamp,\n callbackUrl: this.getAppCallbackUrl(),\n context: canonicalStringify(this.context),\n providerVersion: this.options?.providerVersion ?? '',\n resolvedProviderVersion: this.resolvedProviderVersion ?? '',\n parameters: this.parameters,\n redirectUrl: this.redirectUrl ?? '',\n redirectUrlOptions: this.redirectUrlOptions,\n cancelCallbackUrl: this.getCancelCallbackUrl(),\n cancelRedirectUrl: this.cancelRedirectUrl,\n cancelRedirectUrlOptions: this.cancelRedirectUrlOptions,\n acceptAiProviders: this.options?.acceptAiProviders ?? false,\n sdkVersion: this.sdkVersion,\n jsonProofResponse: this.jsonProofResponse,\n log: this.options?.log ?? false,\n canAutoSubmit: this.options?.canAutoSubmit ?? true,\n metadata: this.options?.metadata,\n preferredLocale: this.options?.preferredLocale,\n acceptTeeAttestation: this.options?.acceptTeeAttestation,\n teeAttestationVersion: this.context.attestationNonceData?.attestationVersion ?? SDK_TEE_ATTESTATION_VERSION,\n }\n\n return templateData;\n }\n\n /**\n * Generates and returns the request URL for proof verification.\n *\n * Defaults to portal mode. Pass `{ verificationMode: 'app' }` for native app flow URLs.\n *\n * - Portal mode (default): returns portal URL on all platforms\n * - App mode: returns share page URL on all platforms\n * - App mode + `useAppClip: true` on iOS: returns App Clip URL instead\n *\n * Falls back to `launchOptions` set at init time if not passed at call time.\n *\n * @param launchOptions - Optional launch configuration to override default behavior\n * @returns Promise<string> - The generated request URL\n * @throws {SignatureNotFoundError} When signature is not set\n *\n * @example\n * ```typescript\n * // Portal URL (default)\n * const url = await proofRequest.getRequestUrl();\n *\n * // Verifier app flow URL\n * const url = await proofRequest.getRequestUrl({ verificationMode: 'app' });\n * ```\n */\n async getRequestUrl(launchOptions?: ReclaimFlowLaunchOptions): Promise<string> {\n const options = { ...this.options?.launchOptions, ...launchOptions };\n const mode = options.verificationMode ?? 'portal';\n\n logger.info('Creating Request Url')\n if (!this.signature) {\n throw new SignatureNotFoundError('Signature is not set.')\n }\n\n try {\n const templateData = this.getTemplateData()\n await updateSession(this.sessionId, SessionStatus.SESSION_STARTED)\n\n if (mode === 'app') {\n const template = this.encodeTemplateData(templateData);\n\n // App Clip only if useAppClip is true and iOS\n if (this.options?.useAppClip && getDeviceType() === DeviceType.MOBILE && getMobileDeviceType() === DeviceType.IOS) {\n const appClipUrl = this.customAppClipUrl ? `${this.customAppClipUrl}&template=${template}` : `https://appclip.apple.com/id?p=org.reclaimprotocol.app.clip&template=${template}`;\n logger.info('App Clip Url created successfully: ' + appClipUrl);\n return appClipUrl;\n }\n\n // Share page for all other cases in app mode\n const sharePageUrl = await createLinkWithTemplateData(templateData, this.appSharePageUrl);\n logger.info('Share page Url created successfully: ' + sharePageUrl);\n return sharePageUrl;\n }\n\n // Portal mode (default)\n const link = await createLinkWithTemplateData(templateData, this.customSharePageUrl)\n logger.info('Request Url created successfully: ' + link);\n return link;\n } catch (error) {\n logger.info('Error creating Request Url:', error)\n throw error\n }\n }\n\n /**\n * Triggers the appropriate Reclaim verification flow based on device type and configuration.\n *\n * Defaults to portal mode (remote browser verification). Pass `{ verificationMode: 'app' }`\n * for verifier app flow via the share page.\n *\n * - **Embedded iframe**: Pass `{ target: element }` to embed the portal inside a DOM element instead of a new tab\n * - Desktop: browser extension takes priority in both modes\n * - Desktop portal mode (no extension): opens portal in new tab\n * - Desktop app mode (no extension): shows QR code modal with share page URL\n * - Mobile portal mode: opens portal in new tab\n * - Mobile app mode: opens share page (or App Clip on iOS if `useAppClip` is `true`)\n *\n * @param launchOptions - Optional launch configuration to override default behavior\n * @returns Promise<FlowHandle> - Handle to control the flow (close, access iframe)\n * @throws {SignatureNotFoundError} When signature is not set\n *\n * @example\n * ```typescript\n * // Portal flow (default) — opens in new tab\n * const handle = await proofRequest.triggerReclaimFlow();\n * handle.tab; // Window reference to the opened tab\n * handle.close(); // close tab and stop polling\n *\n * // Embed portal in an iframe inside a DOM element\n * const handle = await proofRequest.triggerReclaimFlow({ target: document.getElementById('reclaim-container') });\n * handle.iframe; // HTMLIFrameElement reference\n * handle.close(); // remove iframe and stop polling\n *\n * // Verifier app flow\n * await proofRequest.triggerReclaimFlow({ verificationMode: 'app' });\n *\n * // App Clip on iOS (requires useAppClip: true at init)\n * const request = await ReclaimProofRequest.init(APP_ID, SECRET, PROVIDER, { useAppClip: true });\n * await request.triggerReclaimFlow({ verificationMode: 'app' });\n *\n * // Can also set verificationMode at init time via launchOptions\n * const request = await ReclaimProofRequest.init(APP_ID, SECRET, PROVIDER, {\n * launchOptions: { verificationMode: 'app' }\n * });\n * await request.triggerReclaimFlow(); // uses 'app' mode from init\n * ```\n */\n async triggerReclaimFlow(launchOptions?: ReclaimFlowLaunchOptions): Promise<FlowHandle> {\n const options = { ...this.options?.launchOptions, ...launchOptions };\n const mode = options.verificationMode ?? 'portal';\n\n if (!this.signature) {\n throw new SignatureNotFoundError('Signature is not set.')\n }\n\n try {\n const templateData = this.getTemplateData()\n\n this.templateData = templateData;\n\n logger.info(`Triggering Reclaim flow (mode: ${mode})`);\n\n const deviceType = getDeviceType();\n updateSession(this.sessionId, SessionStatus.SESSION_STARTED)\n\n // Iframe embedding — takes priority when target element is provided\n if (launchOptions && 'target' in launchOptions && !launchOptions.target) {\n logger.warn('triggerReclaimFlow: target was provided but is null/undefined — falling back to default flow. Ensure the element exists in the DOM.');\n }\n if (launchOptions?.target && mode === 'portal') {\n await this.embedPortalIframe(templateData, launchOptions.target);\n return {\n close: () => this.closeEmbeddedFlow(),\n iframe: this.portalIframe!,\n };\n }\n\n if (deviceType === DeviceType.DESKTOP) {\n // Check extension first if enabled\n if (this.options?.useBrowserExtension) {\n const extensionAvailable = await this.isBrowserExtensionAvailable();\n if (extensionAvailable) {\n logger.info('Triggering browser extension flow');\n this.triggerBrowserExtensionFlow();\n return {\n close: () => { this.clearInterval(); },\n };\n }\n }\n\n // No extension — open tab/modal synchronously (click activation preserved\n // because extension check is skipped when useBrowserExtension is false,\n // and when it's true but unavailable, we proceed immediately)\n if (mode === 'portal') {\n await this.openPortalTab(templateData);\n } else {\n // App mode: QR code modal with share page URL\n logger.info('Showing QR code modal with share page URL');\n await this.showQRCodeModal();\n }\n } else if (deviceType === DeviceType.MOBILE) {\n if (mode === 'app') {\n // App Clip only if useAppClip is true and iOS\n if (this.options?.useAppClip && getMobileDeviceType() === DeviceType.IOS) {\n logger.info('Redirecting to iOS app clip');\n this.redirectToAppClip();\n } else {\n // Share page for Android and iOS without useAppClip\n logger.info('Redirecting to share page');\n await this.redirectToInstantApp(options);\n }\n } else {\n await this.openPortalTab(templateData);\n }\n }\n\n return {\n close: () => {\n this.closePortalTab();\n this.closeEmbeddedFlow();\n this.modal?.close();\n },\n tab: this.portalTab ?? undefined,\n };\n } catch (error) {\n logger.info('Error triggering Reclaim flow:', error);\n throw error;\n }\n }\n\n\n /**\n * Checks if the Reclaim browser extension is installed and available\n *\n * This method attempts to communicate with the browser extension to verify its availability.\n * It uses a timeout mechanism to quickly determine if the extension responds.\n *\n * @param timeout - Timeout in milliseconds to wait for extension response. Defaults to 200ms\n * @returns Promise<boolean> - True if extension is available, false otherwise\n *\n * @example\n * ```typescript\n * const hasExtension = await proofRequest.isBrowserExtensionAvailable();\n * if (hasExtension) {\n * console.log('Browser extension is installed');\n * }\n * ```\n */\n async isBrowserExtensionAvailable(timeout = 200): Promise<boolean> {\n try {\n return new Promise<boolean>((resolve) => {\n const messageId = `reclaim-check-${Date.now()}`;\n\n const timeoutId = setTimeout(() => {\n window.removeEventListener('message', messageListener);\n resolve(false);\n }, timeout);\n\n const messageListener = (event: MessageEvent) => {\n if (event.data?.action === RECLAIM_EXTENSION_ACTIONS.EXTENSION_RESPONSE &&\n event.data?.messageId === messageId) {\n clearTimeout(timeoutId);\n window.removeEventListener('message', messageListener);\n resolve(!!event.data.installed);\n }\n };\n\n window.addEventListener('message', messageListener);\n const message: ExtensionMessage = {\n action: RECLAIM_EXTENSION_ACTIONS.CHECK_EXTENSION,\n extensionID: this.extensionID,\n messageId: messageId\n }\n window.postMessage(message, '*');\n });\n } catch (error) {\n logger.info('Error checking Reclaim extension installed:', error);\n return false;\n }\n }\n\n private triggerBrowserExtensionFlow(): void {\n const message: ExtensionMessage = {\n action: RECLAIM_EXTENSION_ACTIONS.START_VERIFICATION,\n messageId: this.sessionId,\n data: this.templateData,\n extensionID: this.extensionID\n }\n window.postMessage(message, '*');\n logger.info('Browser extension flow triggered');\n }\n\n private async showQRCodeModal(): Promise<void> {\n try {\n const requestUrl = await createLinkWithTemplateData(this.templateData, this.appSharePageUrl);\n this.modal = new QRCodeModal(this.modalOptions);\n await this.modal.show(requestUrl);\n } catch (error) {\n logger.info('Error showing QR code modal:', error);\n throw error;\n }\n }\n\n private async redirectToInstantApp(options: ReclaimFlowLaunchOptions): Promise<void> {\n try {\n const template = this.encodeTemplateData(this.templateData);\n let instantAppUrl = this.buildSharePageUrl(template);\n logger.info('Redirecting to Android instant app: ' + instantAppUrl);\n\n const isDeferredDeeplinksFlowEnabled = options.canUseDeferredDeepLinksFlow ?? false;\n\n if (isDeferredDeeplinksFlowEnabled) {\n instantAppUrl = instantAppUrl.replace(\"/verifier\", \"/link\");\n\n // Construct Android intent deep link\n const deepLink = `intent://details?id=org.reclaimprotocol.app&url=${encodeURIComponent(\n instantAppUrl\n )}&template=${template}#Intent;scheme=market;action=android.intent.action.VIEW;package=com.android.vending;end;`;\n\n try {\n const requestUrl = instantAppUrl;\n\n let appInstalled = false;\n let timeoutId: string | number | NodeJS.Timeout | undefined;\n\n // Create hidden iframe to test deep link\n const iframe = document.createElement(\"iframe\");\n iframe.style.display = \"none\";\n iframe.style.width = \"1px\";\n iframe.style.height = \"1px\";\n document.body.appendChild(iframe);\n\n // Function to clean up\n const cleanup = () => {\n if (iframe.parentNode) {\n document.body.removeChild(iframe);\n }\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n };\n\n // If page becomes hidden, app opened successfully\n const onVisibilityChange = () => {\n if (document.hidden) {\n appInstalled = true;\n cleanup();\n // Open in main window since app is installed\n window.location.href = deepLink;\n }\n };\n\n // Listen for visibility change\n document.addEventListener(\"visibilitychange\", onVisibilityChange, { once: true });\n\n // Test reclaimverifier deep link in iframe\n iframe.src = deepLink.replace('intent:', 'reclaimverifier:');\n\n // After timeout, assume app not installed\n timeoutId = setTimeout(() => {\n document.removeEventListener(\"visibilitychange\", onVisibilityChange);\n cleanup();\n\n if (!appInstalled) {\n // App not installed - redirect to the store page to install the app\n window.navigator.clipboard.writeText(requestUrl).catch(() => {\n console.error(\"We can't access the clipboard. Please copy this link and open Reclaim Verifier app.\");\n });\n window.location.href = deepLink;\n }\n }, 1500);\n } catch (e) {\n // Final fallback → verifier\n window.location.href = instantAppUrl;\n }\n return;\n }\n\n // Redirect to instant app\n window.location.href = instantAppUrl;\n } catch (error) {\n logger.info('Error redirecting to instant app:', error);\n throw error;\n }\n }\n\n private redirectToAppClip(): void {\n try {\n const template = this.encodeTemplateData(this.templateData);\n const appClipUrl = this.customAppClipUrl ? `${this.customAppClipUrl}&template=${template}` : `https://appclip.apple.com/id?p=org.reclaimprotocol.app.clip&template=${template}`;\n logger.info('Redirecting to iOS app clip: ' + appClipUrl);\n const verifierUrl = `${this.appSharePageUrl}/?template=${template}`;\n\n // Redirect to app clip\n window.location.href = appClipUrl;\n\n setTimeout(() => {\n window.location.href = verifierUrl;\n // 5 second delay to allow app clip to launch\n }, 5 * 1000);\n } catch (error) {\n logger.info('Error redirecting to app clip:', error);\n throw error;\n }\n }\n\n /**\n * Returns the provider id and exact version of the provider that was used in the verification session of this request. \n * \n * This can be provided as a config parameter to the `verifyProof` function to verify the proof.\n * \n * See also:\n * * `verifyProof()` - Verifies a proof against the expected provider configuration.\n * * `getProviderHashRequirements()` - An alternative of this function to get the expected hashes for a provider version by providing providerId and exactProviderVersionString. The result can be provided in verifyProof function's `config` parameter for proof validation.\n * * `getProviderHashRequirementsFromSpec()` - An alternative of this function to get the expected hashes from a provider spec. The result can be provided in verifyProof function's `config` parameter for proof validation.\n */\n public getProviderVersion(): ProviderVersionInfo {\n // This should be exact version and not a version constraint/expression. This cannot be blank.\n const exactProviderVersionString = this.resolvedProviderVersion ?? '';\n return {\n providerId: this.providerId,\n providerVersion: exactProviderVersionString,\n allowedTags: this.options?.acceptAiProviders ? ['ai'] : [],\n }\n }\n\n /**\n * Fetches the provider config that was used for this session and returns the hash requirements\n * \n * See also:\n * * `verifyProof()` - Verifies a proof against the expected provider configuration.\n * * `fetchProviderHashRequirementsBy()` - An alternative of this function to get the expected hashes for a provider version by providing providerId and exactProviderVersionString. The result can be provided in verifyProof function's `config` parameter for proof validation.\n * * `getProviderHashRequirementsFromSpec()` - An alternative of this function to get the expected hashes from a provider spec. The result can be provided in verifyProof function's `config` parameter for proof validation.\n *\n * @returns A promise that resolves to a `ProviderHashRequirementsConfig` or `ProviderHashRequirementsConfig[]`\n */\n getProviderHashRequirements(proofs: Proof[], allowedTags: string[] | null | undefined): Promise<ProviderHashRequirementsConfig[]> {\n return fetchProviderHashRequirementsBy(this.providerId, this.resolvedProviderVersion ?? '', allowedTags, proofs);\n }\n\n /**\n * Starts the proof request session and monitors for proof submission\n *\n * This method begins polling the session status to detect when\n * a proof has been generated and submitted. It handles both default Reclaim callbacks\n * and custom callback URLs.\n *\n * For default callbacks: Verifies proofs automatically and passes them to onSuccess\n * For custom callbacks: Monitors submission status and notifies via onSuccess when complete.\n * In the custom-callback flow (where the SDK submits a proof to a provided callback URL),\n * onSuccess may be invoked with an empty array (onSuccess([])) when no proof is available\n * (this happens when a callback is set using setAppCallbackUrl where proof is sent to callback instead of reclaim backend).\n *\n * Please refer to the OnSuccess type signature ((proof?: Proof | Proof[]) => void)\n * and the startSession function source for more details.\n *\n * > [!TIP]\n * > **Best Practice:** When using `setAppCallbackUrl` and/or `setCancelCallbackUrl`, your backend receives the proof or cancellation details directly. We recommend your backend notifies the frontend (e.g. via WebSockets, SSE, or polling) to stop the verification process and handle the appropriate success/failure action. When a callback is set, `onSuccess` callback provided to `startSession` will have an empty array as its argument.\n *\n * @param onSuccess - Callback function invoked when proof is successfully submitted\n * @param onError - Callback function invoked when an error occurs during the session\n * @param verificationConfig - Optional configuration to customize proof verification\n * @returns Promise<void>\n * @throws {SessionNotStartedError} When session ID is not defined\n * @throws {ProofNotVerifiedError} When proof verification fails (default callback only)\n * @throws {ProofSubmissionFailedError} When proof submission fails (custom callback only)\n * @throws {ProviderFailedError} When proof generation fails with timeout\n *\n * @example\n * ```typescript\n * await proofRequest.startSession({\n * onSuccess: (proof) => {\n * console.log('Proof received:', proof);\n * },\n * onError: (error) => {\n * console.error('Error:', error);\n * }\n * });\n * ```\n */\n async startSession({ onSuccess, onError, verificationConfig }: StartSessionParams): Promise<void> {\n if (!this.sessionId) {\n const message = \"Session can't be started due to undefined value of sessionId\";\n logger.info(message);\n throw new SessionNotStartedError(message);\n }\n\n logger.info('Starting session');\n\n const sessionUpdatePollingInterval = 3 * 1000;\n const interval = setInterval(async () => {\n try {\n const statusUrlResponse = await fetchStatusUrl(this.sessionId);\n\n if (!statusUrlResponse.session) return;\n\n // Reset failure time if status is not PROOF_GENERATION_FAILED\n if (statusUrlResponse.session.statusV2 !== SessionStatus.PROOF_GENERATION_FAILED) {\n this.lastFailureTime = undefined;\n }\n\n // Check for failure timeout\n if (statusUrlResponse.session.statusV2 === SessionStatus.PROOF_GENERATION_FAILED) {\n const currentTime = Date.now();\n if (!this.lastFailureTime) {\n this.lastFailureTime = currentTime;\n } else if (currentTime - this.lastFailureTime >= this.FAILURE_TIMEOUT) {\n const errorMessage = statusUrlResponse.session.error?.message || 'Proof generation failed - timeout reached';\n throw new ProviderFailedError(errorMessage);\n }\n return; // Continue monitoring if under timeout\n }\n\n if (statusUrlResponse.session.statusV2 === SessionStatus.ERROR_SUBMISSION_FAILED || statusUrlResponse.session.statusV2 === SessionStatus.ERROR_SUBMITTED) {\n throw new ErrorDuringVerificationError();\n }\n\n const isDefaultCallbackUrl = this.getAppCallbackUrl() === `${constants.DEFAULT_RECLAIM_CALLBACK_URL}${this.sessionId}`;\n\n if (isDefaultCallbackUrl) {\n if (statusUrlResponse.session.proofs && statusUrlResponse.session.proofs.length > 0) {\n const proofs = statusUrlResponse.session.proofs;\n if (this.claimCreationType === ClaimCreationType.STANDALONE) {\n // Validate against the version the backend actually used for this\n // session, not the version resolved at init. AI patches created\n // mid-session shift the effective version; validating with the\n // init-time version yields UnknownProofsNotValidatedError for\n // proofs that are in fact valid against the AI patch.\n const sessionProviderVersion = statusUrlResponse.session.providerVersionString;\n const effectiveConfig: VerificationConfig = verificationConfig ?? {\n providerId: this.providerId,\n providerVersion: sessionProviderVersion || this.resolvedProviderVersion || '',\n allowedTags: this.options?.acceptAiProviders ? ['ai'] : [],\n };\n const result = await verifyProof(proofs, effectiveConfig);\n if (!result.isVerified) {\n logger.info(`Proofs not verified: count=${proofs?.length}`);\n throw new ProofNotVerifiedError(`Proofs not verified: count=${proofs?.length}`, result.error);\n }\n }\n // check if the proofs array has only one proof then send the proofs in onSuccess\n if (proofs.length === 1) {\n\n onSuccess(proofs[0]);\n } else {\n onSuccess(proofs);\n }\n this.clearInterval();\n this.modal?.close();\n this.closePortalTab();\n this.closeEmbeddedFlow();\n }\n } else {\n if (statusUrlResponse.session.statusV2 === SessionStatus.PROOF_SUBMISSION_FAILED) {\n const errorMessage = statusUrlResponse.session.error?.message || 'Proof submission failed';\n throw new ProofSubmissionFailedError(errorMessage);\n }\n if (statusUrlResponse.session.statusV2 === SessionStatus.PROOF_SUBMITTED ||\n statusUrlResponse.session.statusV2 === SessionStatus.AI_PROOF_SUBMITTED) {\n if (onSuccess) {\n // Proof submitted successfully to the custom callback url\n // We don't have proof, so we just return empty array\n // Before 4.10.1, this was a string message.\n onSuccess([]);\n }\n this.clearInterval();\n this.modal?.close();\n this.closePortalTab();\n this.closeEmbeddedFlow();\n }\n }\n } catch (e) {\n if (onError) {\n onError(e as Error);\n }\n this.clearInterval();\n this.modal?.close();\n this.closePortalTab();\n this.closeEmbeddedFlow();\n }\n }, sessionUpdatePollingInterval);\n\n this.intervals.set(this.sessionId, interval);\n scheduleIntervalEndingTask(this.sessionId, this.intervals, onError);\n }\n\n /**\n * Closes the QR code modal if it is currently open\n *\n * This method can be called to programmatically close the modal, for example,\n * when implementing custom UI behavior or cleanup logic.\n *\n * @example\n * ```typescript\n * // Close modal after some condition\n * proofRequest.closeModal();\n * ```\n */\n closeModal(): void {\n if (this.modal) {\n this.modal.close();\n logger.info('Modal closed by user');\n }\n }\n\n /**\n * Returns whether proofs will be submitted as JSON format\n *\n * @returns boolean - True if proofs are sent as application/json, false for application/x-www-form-urlencoded\n *\n * @example\n * ```typescript\n * const isJson = proofRequest.getJsonProofResponse();\n * console.log('JSON format:', isJson);\n * ```\n */\n getJsonProofResponse(): boolean {\n return this.jsonProofResponse;\n }\n}\n","function createErrorClass(name: string) {\n return class extends Error {\n constructor(message?: string, public innerError?: unknown) {\n // Include inner error message in the main message if available\n const fullMessage = innerError\n ? `${message || ''} caused by ${innerError && typeof innerError === 'object' && 'name' in innerError ? innerError.name : 'Error'}: ${innerError && typeof innerError === 'object' && 'message' in innerError ? innerError.message : String(innerError)}`\n : message;\n\n super(fullMessage);\n this.name = name;\n if (innerError) {\n this.stack += `\\nCaused by: ${innerError && typeof innerError === 'object' && 'stack' in innerError ? innerError.stack : String(innerError)}`;\n }\n }\n };\n}\n\nexport const TimeoutError = createErrorClass('TimeoutError');\nexport const ProofNotVerifiedError = createErrorClass('ProofNotVerifiedError');\nexport const ProofNotValidatedError = createErrorClass('ProofNotValidatedError');\nexport const InvalidRequestSpecError = createErrorClass('InvalidRequestSpecError');\nexport const UnknownProofsNotValidatedError = createErrorClass('UnknownProofsNotValidatedError');\nexport const SessionNotStartedError = createErrorClass('SessionNotStartedError');\nexport const ProviderNotFoundError = createErrorClass('ProviderNotFoundError');\nexport const SignatureGeneratingError = createErrorClass('SignatureGeneratingError');\nexport const SignatureNotFoundError = createErrorClass('SignatureNotFoundError');\nexport const InvalidSignatureError = createErrorClass('InvalidSignatureError');\nexport const UpdateSessionError = createErrorClass('UpdateSessionError');\nexport const InitSessionError = createErrorClass('InitSessionError');\nexport const ProviderFailedError = createErrorClass('ProviderFailedError');\nexport const InvalidParamError = createErrorClass('InvalidParamError');\nexport const ApplicationError = createErrorClass('ApplicationError');\nexport const InitError = createErrorClass('InitError');\nexport const BackendServerError = createErrorClass('BackendServerError');\nexport const GetStatusUrlError = createErrorClass('GetStatusUrlError');\nexport const NoProviderParamsError = createErrorClass('NoProviderParamsError');\nexport const SetParamsError = createErrorClass('SetParamsError');\nexport const SetContextError = createErrorClass('SetContextError');\nexport const SetSignatureError = createErrorClass('SetSignatureError');\nexport const GetAppCallbackUrlError = createErrorClass(\"GetAppCallbackUrlError\");\nexport const StatusUrlError = createErrorClass('StatusUrlError');\nexport const ProviderConfigFetchError = createErrorClass('ProviderConfigFetchError');\nexport const InavlidParametersError = createErrorClass('InavlidParametersError');\nexport const ProofSubmissionFailedError = createErrorClass('ProofSubmissionFailedError');\nexport const ErrorDuringVerificationError = createErrorClass('ErrorDuringVerificationError');\nexport const CallbackUrlRequiredError = createErrorClass('CallbackUrlRequiredError');\nexport const TeeVerificationError = createErrorClass('TeeVerificationError');\nexport const AttestorTeeVerificationError = createErrorClass('AttestorTeeVerificationError');\n","// Define the possible log levels\nexport type LogLevel = 'info' | 'warn' | 'error' | 'silent';\n\n// Define a simple logger class\nclass SimpleLogger {\n private level: LogLevel = 'info';\n\n setLevel(level: LogLevel) {\n this.level = level;\n }\n\n private shouldLog(messageLevel: LogLevel): boolean {\n const levels: LogLevel[] = ['error', 'warn', 'info', 'silent'];\n return levels.indexOf(this.level) >= levels.indexOf(messageLevel);\n }\n\n private log(level: LogLevel, message: string, ...args: any[]) {\n if (this.shouldLog(level) && this.level !== 'silent') {\n const logFunction = this.getLogFunction(level);\n console.log('current level', this.level);\n logFunction(`[${level.toUpperCase()}]`, message, ...args);\n }\n }\n\n private getLogFunction(level: LogLevel): (message?: any, ...optionalParams: any[]) => void {\n switch (level) {\n case 'error':\n return console.error;\n case 'warn':\n return console.warn;\n case 'info':\n return console.info;\n default:\n return () => {}; // No-op for 'silent'\n }\n }\n\n info(message: string, ...args: any[]) {\n this.log('info', message, ...args);\n }\n\n warn(message: string, ...args: any[]) {\n this.log('warn', message, ...args);\n }\n\n error(message: string, ...args: any[]) {\n this.log('error', message, ...args);\n }\n}\n\n// Create the logger instance\nconst logger = new SimpleLogger();\n\n// Function to set the log level\nexport function setLogLevel(level: LogLevel) {\n logger.setLevel(level);\n}\n\n// Export the logger instance and the setLogLevel function\nexport default {\n logger,\n setLogLevel\n};\n","import { ethers } from \"ethers\";\nimport { InavlidParametersError, InvalidParamError, InvalidSignatureError } from \"./errors\";\nimport canonicalize from 'canonicalize'\nimport { Context } from \"./interfaces\";\nimport loggerModule from './logger';\nimport { ProofRequestOptions, ModalOptions, HttpRedirectionMethod, HttpFormEntry } from \"./types\";\nimport { canonicalStringify } from \"./strings\";\nconst logger = loggerModule.logger;\n\n/**\n * Validates function parameters based on specified criteria\n * @param params - An array of objects containing input, paramName, and optional isString flag\n * @param functionName - The name of the function being validated\n * @throws InvalidParamError if any parameter fails validation\n */\nexport function validateFunctionParams(params: { input: any, paramName: string, isString?: boolean }[], functionName: string): void {\n params.forEach(({ input, paramName, isString }) => {\n if (input == null) {\n logger.info(`Validation failed: ${paramName} in ${functionName} is null or undefined`);\n throw new InvalidParamError(`${paramName} passed to ${functionName} must not be null or undefined.`);\n }\n if (isString && typeof input !== 'string') {\n logger.info(`Validation failed: ${paramName} in ${functionName} is not a string`);\n throw new InvalidParamError(`${paramName} passed to ${functionName} must be a string.`);\n }\n if (isString && input.trim() === '') {\n logger.info(`Validation failed: ${paramName} in ${functionName} is an empty string`);\n throw new InvalidParamError(`${paramName} passed to ${functionName} must not be an empty string.`);\n }\n });\n}\n\nexport function validateFunctionParamsWithFn(param: { input: any, paramName: string, isValid: () => boolean }, functionName: string): void {\n if (!param.isValid()) {\n logger.info(`Validation failed: ${param.paramName} in ${functionName} is not valid`);\n throw new InvalidParamError(`${param.paramName} passed to ${functionName} must be valid.`);\n }\n}\n\n\n// validate the parameters\n/** \n * Validates the parameters object\n * @param parameters - The parameters object to validate\n * @throws InavlidParametersError if the parameters object is not valid\n */\nexport function validateParameters(parameters: { [key: string]: string }): void {\n try {\n // check if the parameters is an object of key value pairs of string and string\n if (typeof parameters !== 'object' || parameters === null) {\n logger.info(`Parameters validation failed: Provided parameters is not an object`);\n throw new InavlidParametersError(`The provided parameters is not an object`);\n }\n // check each key and value in the parameters object\n for (const [key, value] of Object.entries(parameters)) {\n if (typeof key !== 'string' || typeof value !== 'string') {\n logger.info(`Parameters validation failed: Provided parameters is not an object of key value pairs of string and string`);\n throw new InavlidParametersError(`The provided parameters is not an object of key value pairs of string and string`);\n }\n }\n } catch (e) {\n logger.info(`Parameters validation failed: ${(e as Error).message}`);\n throw new InavlidParametersError(`Invalid parameters passed to validateParameters.`, e as Error);\n }\n}\n\n\n/**\n* Validates a URL string\n* @param url - The URL to validate\n* @param functionName - The name of the function calling this validation\n* @throws InvalidParamError if the URL is invalid or empty\n*/\nexport function validateURL(url: string, functionName: string): void {\n try {\n new URL(url);\n } catch (e) {\n logger.info(`URL validation failed for ${url} in ${functionName}: ${(e as Error).message}`);\n throw new InvalidParamError(`Invalid URL format ${url} passed to ${functionName}.`, e as Error);\n }\n}\n\n/**\n* Validates a URL string\n* @param url - The URL to validate\n* @param functionName - The name of the function calling this validation\n* @throws InvalidParamError if the URL is invalid or empty\n*/\nexport function validateRedirectionMethod(method: string | null | undefined, functionName: string): void {\n try {\n if (method === null || method === undefined) {\n return;\n }\n if (method !== 'GET' && method !== 'POST') {\n throw new Error(`Invalid redirection method ${method} passed to ${functionName}.`);\n }\n } catch (e) {\n logger.info(`Redirection method validation failed for ${method} in ${functionName}: ${(e as Error).message}`);\n throw new InvalidParamError(`Invalid redirection method ${method} passed to ${functionName}.`, e as Error);\n }\n}\n\n\n/**\n* Validates a URL string\n* @param url - The URL to validate\n* @param functionName - The name of the function calling this validation\n* @throws InvalidParamError if the URL is invalid or empty\n*/\nexport function validateRedirectionBody(records: HttpFormEntry[] | undefined | null, functionName: string): void {\n try {\n if (records === null || records === undefined) {\n return;\n }\n if (Array.isArray(records)) {\n for (const record of records) {\n if ('name' in record && record.name && typeof record.name === 'string') {\n if ('value' in record && typeof record.value === 'string') {\n continue;\n }\n }\n throw new Error('Record in form entries do not have a valid name and/or value');\n }\n } else {\n throw new Error('Redirection body must be an array of objects with name, and value');\n }\n } catch (e) {\n logger.info(`Redirection body validation failed for ${records} in ${functionName}: ${(e as Error).message}`);\n throw new InvalidParamError(`Invalid redirection body ${records} passed to ${functionName}.`, e as Error);\n }\n}\n\n/**\n* Validates a signature against the provided application ID\n* @param providerId - The ID of the provider\n* @param signature - The signature to validate\n* @param applicationId - The expected application ID\n* @param timestamp - The timestamp of the signature\n* @throws InvalidSignatureError if the signature is invalid or doesn't match the application ID\n*/\nexport function validateSignature(providerId: string, signature: string, applicationId: string, timestamp: string): void {\n try {\n logger.info(`Starting signature validation for providerId: ${providerId}, applicationId: ${applicationId}, timestamp: ${timestamp}`);\n\n const message = canonicalize({ providerId, timestamp });\n if (!message) {\n logger.info('Failed to canonicalize message for signature validation');\n throw new Error('Failed to canonicalize message');\n }\n const messageHash = ethers.keccak256(new TextEncoder().encode(message));\n let appId = ethers.verifyMessage(\n ethers.getBytes(messageHash),\n ethers.hexlify(signature)\n ).toLowerCase();\n\n if (ethers.getAddress(appId) !== ethers.getAddress(applicationId)) {\n logger.info(`Signature validation failed: Mismatch between derived appId (${appId}) and provided applicationId (${applicationId})`);\n throw new InvalidSignatureError(`Signature does not match the application id: ${appId}`);\n }\n\n logger.info(`Signature validated successfully for applicationId: ${applicationId}`);\n } catch (err) {\n logger.info(`Signature validation failed: ${(err as Error).message}`);\n if (err instanceof InvalidSignatureError) {\n throw err;\n }\n throw new InvalidSignatureError(`Failed to validate signature: ${(err as Error).message}`);\n }\n}\n\n/**\n * Validates the context object\n * @param context - The context object to validate\n * @throws InvalidParamError if the context object is not valid\n */\nexport function validateContext(context: Context | Record<string, any>): void {\n if (context && !('contextAddress' in context)) {\n try {\n validateFunctionParams([\n { input: context, paramName: 'context', isString: false }\n ], 'validateContext');\n // ensure context is canonically json serializable\n JSON.parse(canonicalStringify(context));\n return;\n } catch (e) {\n logger.info(`Context validation failed: Provided JSON serializable context is not valid`);\n throw new InvalidParamError(`The provided context is not valid`);\n }\n }\n if (!context.contextAddress) {\n logger.info(`Context validation failed: Provided context address in context is not valid`);\n throw new InvalidParamError(`The provided context address in context is not valid`);\n }\n\n if (!context.contextMessage) {\n logger.info(`Context validation failed: Provided context message in context is not valid`);\n throw new InvalidParamError(`The provided context message in context is not valid`);\n }\n\n validateFunctionParams([\n { input: context.contextAddress, paramName: 'contextAddress', isString: true },\n { input: context.contextMessage, paramName: 'contextMessage', isString: true }\n ], 'validateContext');\n}\n\n/**\n * Validates the options object\n * @param options - The options object to validate\n * @throws InvalidParamError if the options object is not valid\n */\nexport function validateOptions(options: ProofRequestOptions): void {\n if (options.acceptAiProviders && typeof options.acceptAiProviders !== 'boolean') {\n logger.info(`Options validation failed: Provided acceptAiProviders in options is not valid`);\n throw new InvalidParamError(`The provided acceptAiProviders in options is not valid`);\n }\n\n if (options.log && typeof options.log !== 'boolean') {\n logger.info(`Options validation failed: Provided log in options is not valid`);\n throw new InvalidParamError(`The provided log in options is not valid`);\n }\n\n if (options.providerVersion && typeof options.providerVersion !== 'string') {\n logger.info(`Options validation failed: Provided providerVersion in options is not valid`);\n throw new InvalidParamError(`The provided providerVersion in options is not valid`);\n }\n}\n\n/**\n * Validates the modalOptions object\n * @param modalOptions - The modalOptions object to validate\n * @param functionName - The name of the function calling this validation\n * @param paramPrefix - Optional prefix for parameter names (e.g., 'modalOptions.')\n * @throws InvalidParamError if the modalOptions object is not valid\n */\nexport function validateModalOptions(modalOptions: ModalOptions, functionName: string, paramPrefix: string = ''): void {\n if (modalOptions.title !== undefined) {\n validateFunctionParams([\n { input: modalOptions.title, paramName: `${paramPrefix}title`, isString: true }\n ], functionName);\n }\n\n if (modalOptions.description !== undefined) {\n validateFunctionParams([\n { input: modalOptions.description, paramName: `${paramPrefix}description`, isString: true }\n ], functionName);\n }\n\n if (modalOptions.extensionUrl !== undefined) {\n validateURL(modalOptions.extensionUrl, functionName);\n validateFunctionParams([\n { input: modalOptions.extensionUrl, paramName: `${paramPrefix}extensionUrl`, isString: true }\n ], functionName);\n }\n\n if (modalOptions.darkTheme !== undefined) {\n if (typeof modalOptions.darkTheme !== 'boolean') {\n throw new InvalidParamError(`${paramPrefix}darkTheme prop must be a boolean`);\n }\n validateFunctionParams([\n { input: modalOptions.darkTheme, paramName: `${paramPrefix}darkTheme` }\n ], functionName);\n }\n\n if (modalOptions.modalPopupTimer !== undefined) {\n if (typeof modalOptions.modalPopupTimer !== 'number' || modalOptions.modalPopupTimer <= 0 || !Number.isInteger(modalOptions.modalPopupTimer)) {\n throw new InvalidParamError(`${paramPrefix}modalPopupTimer prop must be a valid time in minutes`);\n }\n validateFunctionParams([\n { input: modalOptions.modalPopupTimer, paramName: `${paramPrefix}modalPopupTimer` }\n ], functionName);\n }\n\n if (modalOptions.showExtensionInstallButton !== undefined) {\n if (typeof modalOptions.showExtensionInstallButton !== 'boolean') {\n throw new InvalidParamError(`${paramPrefix}showExtensionInstallButton prop must be a boolean`);\n }\n validateFunctionParams([\n { input: modalOptions.showExtensionInstallButton, paramName: `${paramPrefix}showExtensionInstallButton` }\n ], functionName);\n }\n}\n\n\nexport function hashObject(o: any) {\n try {\n const canonicalData = canonicalStringify(o);\n\n const messageHash = ethers.keccak256(new TextEncoder().encode(canonicalData));\n\n return messageHash;\n\n } catch (e) {\n logger.info(`Failed to hash object: ${(e as Error).message}`);\n throw new Error(`Failed to hash object: ${(e as Error).message}`);\n }\n}\n\n","import canonicalize from \"canonicalize\"\n\n/**\n * Canonically stringifies an object, so that the same object will always\n * produce the same string despite the order of keys\n */\nexport function canonicalStringify(params: { [key: string]: any } | undefined) {\n\tif (!params) {\n\t\treturn ''\n\t}\n\n\t// have to cast as ESM isn't correctly typing this\n\treturn (canonicalize as unknown as ((p: unknown) => string))(params) || ''\n}","import { OnError, TrustedData, VerifyProofResultFailure, VerifyProofResultSuccess } from './types'\nimport { TimeoutError } from './errors'\nimport loggerModule from './logger'\nimport { hashObject } from './validationUtils';\nimport { Proof } from './interfaces';\nconst logger = loggerModule.logger\n\n/**\n * Escapes special characters in a string for use in a regular expression\n * @param string - The input string to escape\n * @returns The input string with special regex characters escaped\n */\nexport function escapeRegExp(string: string): string {\n return string.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&'); // $& means the whole matched string\n}\n\n/**\n * Replaces all occurrences of a substring in a string\n * @param str - The original string\n * @param find - The substring to find\n * @param replace - The string to replace the found substrings with\n * @returns A new string with all occurrences of 'find' replaced by 'replace'\n */\nexport function replaceAll(str: string, find: string, replace: string): string {\n if (find === '') return str;\n return str.replace(new RegExp(escapeRegExp(find), 'g'), replace);\n}\n\n/**\n * Schedules a task to end an interval after a specified timeout\n * @param sessionId - The ID of the current session\n * @param intervals - A Map containing the intervals\n * @param onFailureCallback - Callback function to be called on failure\n * @param timeout - Timeout in milliseconds (default: 10 minutes)\n */\nexport function scheduleIntervalEndingTask(\n sessionId: string,\n intervals: Map<string, NodeJS.Timer>,\n onFailureCallback: OnError,\n timeout: number = 1000 * 60 * 10\n): void {\n setTimeout(() => {\n if (intervals.has(sessionId)) {\n const message = 'Interval ended without receiving proofs'\n onFailureCallback(new TimeoutError(message))\n logger.info(message)\n clearInterval(intervals.get(sessionId) as NodeJS.Timeout)\n intervals.delete(sessionId)\n }\n }, timeout)\n}\n\nexport const createVerifyProofResultSuccess = (\n proofs: Proof[],\n isTeeAttestationVerified?: boolean,\n isAttestorTeeAttestationVerified?: boolean,\n): VerifyProofResultSuccess => {\n return {\n isVerified: true,\n isTeeAttestationVerified,\n isAttestorTeeAttestationVerified,\n error: undefined,\n data: proofs.map(createTrustedDataFromProofData),\n publicData: getPublicDataFromProofs(proofs),\n }\n}\n\n\nexport const createVerifyProofResultFailure = (\n error: Error,\n isTeeAttestationVerified?: boolean,\n isAttestorTeeAttestationVerified?: boolean,\n): VerifyProofResultFailure => {\n return {\n isVerified: false,\n isTeeAttestationVerified,\n isAttestorTeeAttestationVerified,\n error,\n data: [],\n publicData: [],\n }\n}\n\nexport function createTrustedDataFromProofData(proof: Proof): TrustedData {\n try {\n const context = JSON.parse(proof.claimData.context)\n const { extractedParameters, ...rest } = context\n return {\n context: rest,\n extractedParameters: extractedParameters ?? {},\n }\n } catch {\n return {\n context: {},\n extractedParameters: {},\n }\n }\n}\n\nexport function getPublicDataFromProofs(proofs: Proof[]): any[] {\n const data: any[] = [];\n const seenData = new Set<string>();\n for (const proof of proofs) {\n const publicData = proof.publicData;\n if (publicData === null || publicData === undefined) {\n continue;\n }\n try {\n const hash = hashObject(publicData);\n if (seenData.has(hash)) {\n continue;\n }\n seenData.add(hash);\n } catch (_) {\n // if hash fails, we still push the data\n }\n data.push(publicData);\n }\n return data;\n}\n","// Base URL for the backend API\nexport let BACKEND_BASE_URL = \"https://api.reclaimprotocol.org\";\n\nexport function setBackendBaseUrl(url: string) {\n BACKEND_BASE_URL = url;\n}\n\n// Constant values used throughout the application\nexport const constants = {\n // Default callback URL for Reclaim protocol\n get DEFAULT_RECLAIM_CALLBACK_URL() {\n return `${BACKEND_BASE_URL}/api/sdk/callback?callbackId=`;\n },\n\n // Default error callback URL for Reclaim protocol\n get DEFAULT_RECLAIM_CANCEL_CALLBACK_URL() {\n return `${BACKEND_BASE_URL}/api/sdk/error-callback?callbackId=`;\n },\n\n // Default status URL for Reclaim sessions\n get DEFAULT_RECLAIM_STATUS_URL() {\n return `${BACKEND_BASE_URL}/api/sdk/session/`;\n },\n\n // Default attestors URL for Reclaim sessions\n get DEFAULT_ATTESTORS_URL() {\n return `${BACKEND_BASE_URL}/api/attestors`\n },\n\n DEFAULT_PROVIDER_CONFIGS_URL(providerId: string, exactProviderVersionString: string | null | undefined, allowedTags: string[] | null | undefined) {\n return `${BACKEND_BASE_URL}/api/providers/${providerId}/configs?versionNumber=${exactProviderVersionString || ''}&allowedTags=${allowedTags?.join(',') || ''}`\n },\n\n // Default portal URL\n DEFAULT_PORTAL_URL: 'https://portal.reclaimprotocol.org',\n\n // Default sharepage URL\n DEFAULT_APP_SHARE_PAGE_URL: 'https://share.reclaimprotocol.org/verifier',\n\n // URL for sharing Reclaim templates\n RECLAIM_SHARE_URL: 'https://share.reclaimprotocol.org/verifier/?template=',\n\n // Chrome extension URL for Reclaim Protocol\n CHROME_EXTENSION_URL: 'https://chromewebstore.google.com/detail/reclaim-extension/oafieibbbcepkmenknelhmgaoahamdeh'\n};\n\n// GCP Confidential Space Root CA — pinned. Rotates infrequently\n// (current cert valid 2024-2034). Used to verify attestor TEE attestation JWTs.\nexport const GCP_CONFIDENTIAL_SPACE_ROOT_CA = `-----BEGIN CERTIFICATE-----\n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\nuyT5CnJulxSC5CT1\n-----END CERTIFICATE-----`;\n\n// Matches an `attestor_public_key:0x<40-hex>` entry in a GCP Confidential\n// Space attestation JWT's `eat_nonce` claim.\nexport const ATTESTOR_NONCE_PATTERN = /^attestor_public_key:0x([0-9a-fA-F]{40})$/;\n\n// Expected `iss` claim on GCP Confidential Space attestation JWTs.\nexport const GCP_CONFIDENTIAL_SPACE_ISSUER = 'https://confidentialcomputing.googleapis.com';\n","import fetchRetry from \"fetch-retry\";\n\nconst MAX_RETRIES = 3;\nconst MAX_RETRY_DELAY_MS = 60 * 1000;\n\nconst isHttpResponseStatusRetryable = (statusCode: number) => {\n return statusCode === 408 || statusCode === 429 || statusCode >= 500;\n};\n\nconst getRetryDelay = (response: Response | null | undefined): number | undefined => {\n const retryAfter = response?.headers.get('Retry-After');\n if (!retryAfter) {\n return undefined;\n }\n\n const trimmed = retryAfter.trim();\n\n if (/^\\d+$/.test(trimmed)) {\n return Math.min(parseInt(trimmed, 10) * 1000, MAX_RETRY_DELAY_MS);\n }\n\n const date = new Date(trimmed);\n if (!isNaN(date.getTime())) {\n return Math.min(Math.max(0, date.getTime() - Date.now()), MAX_RETRY_DELAY_MS);\n }\n\n return undefined;\n};\n\nexport const http = {\n get client() {\n return fetchRetry(globalThis.fetch, {\n retries: MAX_RETRIES,\n retryDelay: function (attempt, _, response) {\n const delay = getRetryDelay(response);\n if (delay !== undefined) {\n return delay;\n }\n // attempt starts at 0. \n // Returns: 1000ms, 2000ms, 4000ms\n return Math.pow(2, attempt) * 1000;\n },\n retryOn: (attempt, error, response) => {\n if (attempt >= MAX_RETRIES) {\n return false;\n }\n\n if (response && Number.isInteger(response.status)) {\n return isHttpResponseStatusRetryable(response.status);\n }\n\n return !!error && error.name !== 'AbortError';\n },\n })\n },\n}\n","import {\n InitSessionError,\n UpdateSessionError,\n StatusUrlError,\n ProviderConfigFetchError\n} from \"./errors\";\nimport { InitSessionResponse, ProviderConfigResponse, ProviderHashRequirementsResponse, SessionStatus, StatusUrlResponse } from \"./types\";\nimport { validateFunctionParams } from \"./validationUtils\";\nimport { BACKEND_BASE_URL, constants } from './constants';\nimport { http } from \"./fetch\";\nimport loggerModule from './logger';\n\nconst logger = loggerModule.logger;\n\n/**\n * Initializes a session with the provided parameters\n * @param providerId - The ID of the provider\n * @param appId - The ID of the application\n * @param timestamp - The timestamp of the request\n * @param signature - The signature for authentication\n * @returns A promise that resolves to an InitSessionResponse\n * @throws InitSessionError if the session initialization fails\n */\nexport async function initSession(\n providerId: string,\n appId: string,\n timestamp: string,\n signature: string,\n versionNumber?: string\n): Promise<InitSessionResponse> {\n logger.info(`Initializing session for providerId: ${providerId}, appId: ${appId}`);\n try {\n const response = await http.client(`${BACKEND_BASE_URL}/api/sdk/init/session/`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ providerId, appId, timestamp, signature, versionNumber })\n });\n\n const res = await response.json();\n\n if (!response.ok) {\n logger.info(`Session initialization failed: ${res.message || 'Unknown error'}`);\n throw new InitSessionError(res.message || `Error initializing session with providerId: ${providerId}`);\n }\n\n return res as InitSessionResponse;\n } catch (err) {\n logger.info(`Failed to initialize session for providerId: ${providerId}, appId: ${appId}`, err);\n throw err;\n }\n}\n\n/**\n * Updates the status of an existing session\n * @param sessionId - The ID of the session to update\n * @param status - The new status of the session\n * @returns A promise that resolves to the update response\n * @throws UpdateSessionError if the session update fails\n */\nexport async function updateSession(sessionId: string, status: SessionStatus) {\n logger.info(`Updating session status for sessionId: ${sessionId}, new status: ${status}`);\n validateFunctionParams(\n [{ input: sessionId, paramName: 'sessionId', isString: true }],\n 'updateSession'\n );\n\n try {\n const response = await http.client(`${BACKEND_BASE_URL}/api/sdk/update/session/`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ sessionId, status })\n });\n\n const res = await response.json();\n\n if (!response.ok) {\n const errorMessage = `Error updating session with sessionId: ${sessionId}. Status Code: ${response.status}`;\n logger.info(errorMessage, res);\n throw new UpdateSessionError(errorMessage);\n }\n\n logger.info(`Session status updated successfully for sessionId: ${sessionId}`);\n return res;\n } catch (err) {\n const errorMessage = `Failed to update session with sessionId: ${sessionId}`;\n logger.info(errorMessage, err);\n throw new UpdateSessionError(`Error updating session with sessionId: ${sessionId}`);\n }\n}\n\n/**\n * Fetches the status URL for a given session ID\n * @param sessionId - The ID of the session to fetch the status URL for\n * @returns A promise that resolves to a StatusUrlResponse\n * @throws StatusUrlError if the status URL fetch fails\n */\nexport async function fetchStatusUrl(sessionId: string): Promise<StatusUrlResponse> {\n validateFunctionParams(\n [{ input: sessionId, paramName: 'sessionId', isString: true }],\n 'fetchStatusUrl'\n );\n\n try {\n const response = await http.client(`${constants.DEFAULT_RECLAIM_STATUS_URL}${sessionId}`, {\n method: 'GET',\n headers: { 'Content-Type': 'application/json' }\n });\n\n const res = await response.json();\n\n if (!response.ok) {\n const errorMessage = `Error fetching status URL for sessionId: ${sessionId}. Status Code: ${response.status}`;\n logger.info(errorMessage, res);\n throw new StatusUrlError(errorMessage);\n }\n\n return res as StatusUrlResponse;\n } catch (err) {\n const errorMessage = `Failed to fetch status URL for sessionId: ${sessionId}`;\n logger.info(errorMessage, err);\n throw new StatusUrlError(`Error fetching status URL for sessionId: ${sessionId}`);\n }\n}\n\nexport async function fetchProviderConfigs(providerId: string, exactProviderVersionString: string | null | undefined, allowedTags: string[] | null | undefined): Promise<ProviderConfigResponse> {\n validateFunctionParams(\n [\n { input: providerId, paramName: 'providerId', isString: true },\n ],\n 'fetchProviderConfigs'\n );\n\n if (exactProviderVersionString != null && exactProviderVersionString != undefined) {\n validateFunctionParams(\n [\n { input: exactProviderVersionString, paramName: 'exactProviderVersionString', isString: true },\n ],\n 'fetchProviderConfigs'\n );\n }\n\n try {\n const response = await http.client(constants.DEFAULT_PROVIDER_CONFIGS_URL(providerId, exactProviderVersionString, allowedTags), {\n method: 'GET',\n headers: { 'Content-Type': 'application/json' }\n });\n\n const res = await response.json();\n\n if (!response.ok) {\n const errorMessage = `Error fetching provider config for providerId: ${providerId}, exactProviderVersionString: ${exactProviderVersionString}. Status Code: ${response.status}`;\n logger.info(errorMessage, res);\n throw new ProviderConfigFetchError(errorMessage);\n }\n\n return res as ProviderConfigResponse;\n } catch (err) {\n const errorMessage = `Failed to fetch provider config for providerId: ${providerId}, exactProviderVersionString: ${exactProviderVersionString}`;\n logger.info(errorMessage, err);\n throw new ProviderConfigFetchError(`Error fetching provider config for providerId: ${providerId}, exactProviderVersionString: ${exactProviderVersionString}`);\n }\n}\n","import { ethers } from \"ethers\";\nimport { SignedClaim, TemplateData } from \"./types\";\nimport { createSignDataForClaim } from \"../witness\";\nimport { BACKEND_BASE_URL, constants } from \"./constants\";\nimport { replaceAll } from \"./helper\";\nimport { validateURL } from \"./validationUtils\";\nimport { BackendServerError, ProofNotVerifiedError } from \"./errors\";\nimport loggerModule from './logger';\nimport { WitnessData, type Proof } from \"./interfaces\";\nimport { http } from \"./fetch\";\n\nconst logger = loggerModule.logger;\n\n/**\n * Retrieves a shortened URL for the given URL\n * @param url - The URL to be shortened\n * @returns A promise that resolves to the shortened URL, or the original URL if shortening fails\n */\nexport async function getShortenedUrl(url: string): Promise<string> {\n logger.info(`Attempting to shorten URL: ${url}`);\n try {\n validateURL(url, 'getShortenedUrl')\n const response = await http.client(`${BACKEND_BASE_URL}/api/sdk/shortener`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ fullUrl: url })\n })\n const res = await response.json()\n if (!response.ok) {\n logger.info(`Failed to shorten URL: status=${response.status}`);\n return url;\n }\n const shortenedVerificationUrl = res.result.shortUrl\n return shortenedVerificationUrl\n } catch (err) {\n logger.info(`Error shortening URL: ${url}, Error: ${err}`);\n return url\n }\n}\n\n/**\n * Creates a link with embedded template data\n * @param templateData - The data to be embedded in the link\n * @param sharePagePath - The path to the share page (optional)\n * @returns A promise that resolves to the created link (shortened if possible)\n */\nexport async function createLinkWithTemplateData(templateData: TemplateData, sharePagePath?: string): Promise<string> {\n let template = encodeURIComponent(JSON.stringify(templateData))\n template = replaceAll(template, '(', '%28')\n template = replaceAll(template, ')', '%29')\n const fullLink = sharePagePath ? `${sharePagePath}/?template=${template}` : `${constants.RECLAIM_SHARE_URL}${template}`\n try {\n const shortenedLink = await getShortenedUrl(fullLink)\n return shortenedLink;\n } catch (err) {\n logger.info(`Error creating link for sessionId: ${templateData.sessionId}, Error: ${err}`);\n return fullLink;\n }\n}\n\n/**\n * Retrieves the list of witnesses for a given claim\n */\nexport async function getAttestors(): Promise<WitnessData[]> {\n const response = await http.client(constants.DEFAULT_ATTESTORS_URL)\n if (!response.ok) {\n response.body?.cancel()\n throw new BackendServerError(\n `Failed to fetch witness addresses: ${response.status}`\n )\n }\n\n const { data } = await response.json() as {\n data: {\n address: string\n }[]\n }\n return data.map(wt => ({ id: wt.address, url: '' }))\n}\n\n/**\n * Recovers the signers' addresses from a signed claim\n * @param claim - The signed claim object\n * @param signatures - The signatures associated with the claim\n * @returns An array of recovered signer addresses\n */\nexport function recoverSignersOfSignedClaim({\n claim,\n signatures\n}: SignedClaim): string[] {\n const dataStr = createSignDataForClaim({ ...claim })\n const signers = signatures.map(signature =>\n ethers.verifyMessage(dataStr, ethers.hexlify(signature)).toLowerCase()\n )\n return signers;\n}\n\n/**\n * Asserts that the proof is verified by checking the signatures and witness information\n * @param proof - The proof to verify\n * @param attestors - The attestors to check against\n * @throws {ProofNotVerifiedError} When the proof is not verified\n */\nexport async function assertVerifiedProof(\n proof: Proof,\n attestors: WitnessData[]\n) {\n const signers = recoverSignersOfSignedClaim({\n claim: proof.claimData,\n signatures: proof.signatures\n .map(signature => ethers.getBytes(signature))\n })\n // ensure at least one signer is an attestor\n if (!attestors\n .some(attestor => signers.includes(attestor.id.toLowerCase()))) {\n throw new ProofNotVerifiedError('Identifier mismatch')\n }\n}\n\n","import { ethers } from 'ethers';\nimport type { ClaimID, ClaimInfo, CompleteClaimData, HashableHttpProviderClaimParams, HttpProviderClaimParams } from './utils/types';\nimport { canonicalStringify } from './utils/strings';\n\nexport function createSignDataForClaim(data: CompleteClaimData): string {\n const identifier: ClaimID = getIdentifierFromClaimInfo(data);\n const lines: string[] = [\n identifier,\n data.owner.toLowerCase(),\n data.timestampS.toString(),\n data.epoch.toString(),\n ];\n\n return lines.join('\\n');\n}\n\nexport function getIdentifierFromClaimInfo(info: ClaimInfo): ClaimID {\n // re-canonicalize context if it's not empty\n let canonicalContext = info.context || '';\n if (canonicalContext.length > 0) {\n try {\n const ctx = JSON.parse(canonicalContext);\n canonicalContext = canonicalStringify(ctx);\n } catch (e) {\n throw new Error('unable to parse non-empty context. Must be JSON');\n }\n }\n\n const str = `${info.provider}\\n${info.parameters}\\n${canonicalContext}`;\n return ethers.keccak256(strToUint8Array(str)).toLowerCase();\n}\n\n/**\n * Computes the cryptographic claim hash(es) for the HTTP provider payload parameters.\n * \n * If the parameters comprise solely of rigid/required rules (or represents an extracted \n * attested payload that enforces all its defined elements), this computes and returns a single deterministic string.\n *\n * **Combinatorial Hashes Intention:**\n * If the payload configuration defines optional elements (`isOptional: true` on ResponseMatchSpec),\n * a single rule configuration inherently encompasses multiple logical subset definitions. \n * Since cryptographic hashes strictly enforce exact data byte-by-byte, \n * this function recursively computes a hash for every mathematically valid permutation of the optional subsets \n * (inclusive and exclusive) so the validator can verify the proof against any of the legitimate subset match signatures.\n * \n * @param params - The HTTP provider claim configuration or extracted attested parameters.\n * @returns A single keccak256 hash string, or an array of hex-string hashes if parameter optionality generates combinations.\n */\nexport function hashProofClaimParams(params: HttpProviderClaimParams): string | string[] {\n const serializedParams = getProviderParamsAsCanonicalizedString(params);\n\n if (Array.isArray(serializedParams)) {\n return serializedParams.map(serialized =>\n ethers.keccak256(strToUint8Array(serialized)).toLowerCase()\n );\n }\n\n return ethers.keccak256(\n strToUint8Array(serializedParams)\n ).toLowerCase()\n}\n\nfunction strToUint8Array(str: string): Uint8Array {\n return new TextEncoder().encode(str);\n}\n\n/**\n * Computes canonicalized string(s) for the provided HTTP parameter payload.\n *\n * **Architectural Concept**:\n * In Reclaim, proof security revolves around generating a deterministic Hash based on the JSON stringified keys\n * of matched specifications (e.g. `responseMatches` and `responseRedactions`).\n * When processing a Provider Configuration containing `isOptional` rules, the protocol doesn't require users to generate a \n * proof that matched *all* of the rules. A client could inherently omit any optional rules from claim before\n * starting claim creation to make a valid proof if the server payload may not contain them.\n * \n * To ensure the eventual Proof's Hash safely validates against the parent template's Requirement Hash, logic here \n * loops $2^N$ times using bitmask computation (where N = number of rule pairs) and yields canonically sorted \n * permutations for every sub-set of optional combinations. \n * Any combination forcefully omitting a mathematically required (`isOptional: false`) rule is stripped out.\n * \n * Note: When a user successfully generates a proof, their attested parameter payload does not contain `isOptional` tags\n * because the client sending request to attestor omits rules where data may not be present in response, \n * producing exactly 1 deterministic configuration subset (what the user actually proved!).\n * \n * @param params - The structured parameters.\n * @returns Serialized string or array of strings.\n */\nexport function getProviderParamsAsCanonicalizedString(params: HttpProviderClaimParams): string[] {\n // redaction cannot be more than response match\n const pairsCount = params?.responseMatches?.length ?? 0;\n const validCanonicalizedStrings: string[] = [];\n\n // Total combinations: 2^pairsCount\n const totalCombinations = 1 << pairsCount;\n\n for (let i = 0; i < totalCombinations; i++) {\n let isValidCombination = true;\n let includedCount = 0;\n\n const currentMatches: HashableHttpProviderClaimParams['responseMatches'] = [];\n const currentRedactions: HashableHttpProviderClaimParams['responseRedactions'] = [];\n\n for (let j = 0; j < pairsCount; j++) {\n const isIncluded = (i & (1 << j)) !== 0;\n const match = params?.responseMatches?.[j];\n const redaction = params?.responseRedactions?.[j];\n\n if (isIncluded) {\n if (match) {\n currentMatches.push({\n value: match.value ?? '',\n // This needs to be explicitly specified and absence should cause error, but we're choosing to ignore it in this case\n type: match.type ?? 'contains',\n invert: match.invert || undefined,\n });\n }\n if (redaction) {\n currentRedactions.push({\n xPath: redaction.xPath ?? '',\n jsonPath: redaction.jsonPath ?? '',\n regex: redaction.regex ?? '',\n hash: redaction.hash || undefined,\n });\n }\n includedCount++;\n } else {\n if (match && !match.isOptional) {\n isValidCombination = false;\n break;\n }\n }\n }\n\n if (isValidCombination && includedCount > 0) {\n const filteredParams: HashableHttpProviderClaimParams = {\n url: params?.url ?? '',\n // METHOD needs to be explicitly specified and absence or unknown method should cause error, but we're choosing to ignore it in this case\n method: params?.method ?? 'GET',\n body: params?.body ?? '',\n responseMatches: currentMatches,\n responseRedactions: currentRedactions,\n };\n\n validCanonicalizedStrings.push(canonicalStringify(filteredParams));\n }\n }\n\n // If there are no rules initially, we still want to stringify the base params\n if (validCanonicalizedStrings.length === 0) {\n const filteredParams: HashableHttpProviderClaimParams = {\n url: params?.url ?? '',\n method: params?.method ?? 'GET',\n body: params?.body ?? '',\n responseMatches: [],\n responseRedactions: [],\n };\n return [canonicalStringify(filteredParams)];\n }\n\n return validCanonicalizedStrings;\n}\n","import QRCode from 'qrcode';\nimport loggerModule from './logger';\nimport { ModalOptions } from './types';\nimport { constants } from './constants';\nconst logger = loggerModule.logger;\n\nexport class QRCodeModal {\n private modalId: string;\n private options: ModalOptions;\n private autoCloseTimer?: NodeJS.Timeout;\n private countdownTimer?: NodeJS.Timeout;\n private countdownSeconds: number = 60;\n\n constructor(options: ModalOptions = {}) {\n this.modalId = 'reclaim-qr-modal';\n this.options = {\n title: 'Verify with Reclaim',\n description: 'Scan the QR code with your mobile device to complete verification',\n extensionUrl: constants.CHROME_EXTENSION_URL,\n darkTheme: false,\n modalPopupTimer: 1, // default to 1 minute\n showExtensionInstallButton: false, // default to false\n ...options\n };\n }\n\n async show(requestUrl: string): Promise<void> {\n try {\n // Remove existing modal if present\n this.close();\n\n // Create modal HTML\n const modalHTML = this.createModalHTML();\n\n // Add modal to DOM\n document.body.insertAdjacentHTML('beforeend', modalHTML);\n\n // Generate QR code\n await this.generateQRCode(requestUrl, 'reclaim-qr-code');\n\n // Add event listeners\n this.addEventListeners();\n\n // Start auto-close timer\n this.startAutoCloseTimer();\n\n } catch (error) {\n logger.info('Error showing QR code modal:', error);\n throw error;\n }\n }\n\n close(): void {\n // Clear timers\n if (this.autoCloseTimer) {\n clearTimeout(this.autoCloseTimer);\n this.autoCloseTimer = undefined;\n }\n if (this.countdownTimer) {\n clearInterval(this.countdownTimer);\n this.countdownTimer = undefined;\n }\n\n const modal = document.getElementById(this.modalId);\n if (modal) {\n modal.remove();\n }\n if (this.options.onClose) {\n this.options.onClose();\n }\n }\n\n private getThemeStyles() {\n const isDark = this.options.darkTheme;\n\n return {\n modalBackground: isDark ? 'rgba(0, 0, 0, 0.8)' : 'rgba(0, 0, 0, 0.5)',\n cardBackground: isDark ? '#1f2937' : 'white',\n titleColor: isDark ? '#f9fafb' : '#1f2937',\n textColor: isDark ? '#d1d5db' : '#6b7280',\n qrBackground: isDark ? '#374151' : '#f9fafb',\n tipBackground: isDark ? '#1e40af' : '#f0f9ff',\n tipBorder: isDark ? '#1e40af' : '#e0f2fe',\n tipTextColor: isDark ? '#dbeafe' : '#0369a1',\n buttonBackground: isDark ? '#374151' : '#f3f4f6',\n buttonColor: isDark ? '#f9fafb' : '#374151',\n buttonHoverBackground: isDark ? '#4b5563' : '#e5e7eb',\n countdownColor: isDark ? '#6b7280' : '#9ca3af',\n progressBackground: isDark ? '#4b5563' : '#e5e7eb',\n progressGradient: isDark\n ? 'linear-gradient(90deg, #3b82f6 0%, #2563eb 50%, #1d4ed8 100%)'\n : 'linear-gradient(90deg, #2563eb 0%, #1d4ed8 50%, #1e40af 100%)',\n linkColor: isDark ? '#60a5fa' : '#2563eb',\n extensionButtonBackground: isDark ? '#1e40af' : '#2563eb',\n extensionButtonHover: isDark ? '#1d4ed8' : '#1d4ed8'\n };\n }\n\n private createModalHTML(): string {\n const styles = this.getThemeStyles();\n\n return `\n <div id=\"${this.modalId}\" style=\"\n position: fixed;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n background-color: ${styles.modalBackground};\n display: flex;\n justify-content: center;\n align-items: center;\n z-index: 10000;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n \">\n <div style=\"\n background: ${styles.cardBackground};\n border-radius: 12px;\n padding: 32px;\n max-width: 400px;\n width: 90%;\n text-align: center;\n box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);\n position: relative;\n \">\n <button id=\"reclaim-close-modal\" style=\"\n position: absolute;\n top: 16px;\n right: 16px;\n background: none;\n border: none;\n cursor: pointer;\n padding: 4px;\n border-radius: 6px;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: background-color 0.2s;\n width: 32px;\n height: 32px;\n \"\n onmouseover=\"this.style.backgroundColor='${styles.buttonHoverBackground}'\"\n onmouseout=\"this.style.backgroundColor='transparent'\"\n title=\"Close modal\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M12 4L4 12M4 4L12 12\" stroke=\"${styles.buttonColor}\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n </button>\n \n <h2 style=\"\n margin: 0 0 16px 0;\n font-size: 24px;\n font-weight: 600;\n color: ${styles.titleColor};\n \">${this.options.title}</h2>\n \n <p style=\"\n margin: 0 0 24px 0;\n color: ${styles.textColor};\n font-size: 14px;\n line-height: 1.5;\n \">${this.options.description}</p>\n \n <div id=\"reclaim-qr-code\" style=\"\n margin: 0 auto 24px auto;\n background: ${styles.qrBackground};\n border-radius: 8px;\n display: inline-block;\n \"></div>\n \n ${this.options.showExtensionInstallButton ? `\n <div style=\"\n margin-bottom: 24px;\n padding: 16px;\n background: ${styles.tipBackground};\n border: 1px solid ${styles.tipBorder};\n border-radius: 8px;\n \">\n <p style=\"\n margin: 0 0 12px 0;\n font-size: 14px;\n color: ${styles.tipTextColor};\n font-weight: 500;\n \">💡 For a better experience</p>\n <p style=\"\n margin: 0 0 12px 0;\n font-size: 13px;\n color: ${styles.tipTextColor};\n line-height: 1.4;\n \">Install our browser extension for seamless verification without QR codes</p>\n <a href=\"${this.options.extensionUrl}\" \n target=\"_blank\" \n style=\"\n display: inline-block;\n background: ${styles.extensionButtonBackground};\n color: white;\n text-decoration: none;\n padding: 8px 16px;\n border-radius: 6px;\n font-size: 12px;\n font-weight: 500;\n transition: background-color 0.2s;\n \"\n onmouseover=\"this.style.backgroundColor='${styles.extensionButtonHover}'\"\n onmouseout=\"this.style.backgroundColor='${styles.extensionButtonBackground}'\">\n Install Extension\n </a>\n </div>` : ''}\n \n <div style=\"margin-top: 16px;\">\n <div id=\"reclaim-countdown\" style=\"\n font-size: 12px;\n color: ${styles.countdownColor};\n font-weight: 400;\n margin-bottom: 8px;\n \">Auto-close in 1:00</div>\n \n <div style=\"\n width: 100%;\n height: 4px;\n background-color: ${styles.progressBackground};\n border-radius: 2px;\n overflow: hidden;\n \">\n <div id=\"reclaim-progress-bar\" style=\"\n width: 100%;\n height: 100%;\n background: ${styles.progressGradient};\n border-radius: 2px;\n transition: width 1s linear;\n \"></div>\n </div>\n </div>\n </div>\n </div>\n `\n }\n\n private async generateQRCode(text: string, containerId: string): Promise<void> {\n try {\n const dataUrl = await QRCode.toDataURL(text, {\n width: 200,\n margin: 1,\n color: {\n dark: '#000000',\n light: '#ffffff'\n }\n });\n\n const container = document.getElementById(containerId);\n const styles = this.getThemeStyles();\n\n if (container) {\n container.innerHTML = `\n <img src=\"${dataUrl}\"\n alt=\"QR Code for Reclaim verification\"\n style=\"width: 200px; height: 200px; border-radius: 4px;\">\n <div style=\"display: none; padding: 20px; color: ${styles.textColor}; font-size: 14px;\">\n <a href=\"${text}\" target=\"_blank\" style=\"color: ${styles.linkColor}; text-decoration: underline;\">\n Click here to open verification link\n </a>\n </div>\n `;\n }\n } catch (error) {\n logger.info('Error generating QR code:', error);\n // Fallback to text link\n const container = document.getElementById(containerId);\n const styles = this.getThemeStyles();\n\n if (container) {\n container.innerHTML = `\n <div style=\"padding: 20px; color: ${styles.textColor}; font-size: 14px;\">\n <a href=\"${text}\" target=\"_blank\" style=\"color: ${styles.linkColor}; text-decoration: underline;\">\n Click here to open verification link\n </a>\n </div>\n `;\n }\n }\n }\n\n private addEventListeners(): void {\n const closeButton = document.getElementById('reclaim-close-modal');\n const modal = document.getElementById(this.modalId);\n\n const closeModal = () => {\n this.close();\n };\n\n if (closeButton) {\n closeButton.addEventListener('click', closeModal);\n }\n\n // Close on backdrop click\n if (modal) {\n modal.addEventListener('click', (e) => {\n if (e.target === modal) {\n closeModal();\n }\n });\n }\n\n // Close on escape key\n const handleEscape = (e: KeyboardEvent) => {\n if (e.key === 'Escape') {\n closeModal();\n document.removeEventListener('keydown', handleEscape);\n }\n };\n document.addEventListener('keydown', handleEscape);\n }\n\n private startAutoCloseTimer(): void {\n this.countdownSeconds = (this.options.modalPopupTimer || 1) * 60; // default to 1 minute\n\n // Update countdown display immediately\n this.updateCountdownDisplay();\n\n // Start countdown timer (updates every second)\n this.countdownTimer = setInterval(() => {\n this.countdownSeconds--;\n this.updateCountdownDisplay();\n\n if (this.countdownSeconds <= 0) {\n this.close();\n }\n }, 1000);\n\n // Set auto-close timer for the number of minutes specified in the options in milliseconds\n const autoCloseMs = (this.options.modalPopupTimer || 1) * 60 * 1000;\n this.autoCloseTimer = setTimeout(() => {\n this.close();\n }, autoCloseMs);\n }\n\n private updateCountdownDisplay(): void {\n const countdownElement = document.getElementById('reclaim-countdown');\n const progressBar = document.getElementById('reclaim-progress-bar');\n\n if (countdownElement) {\n const minutes = Math.floor(this.countdownSeconds / 60);\n const seconds = this.countdownSeconds % 60;\n const timeString = `${minutes}:${seconds.toString().padStart(2, '0')}`;\n countdownElement.textContent = `Auto-close in ${timeString}`;\n }\n\n if (progressBar) {\n // Calculate progress percentage (reverse: starts at 100%, goes to 0%)\n const totalSeconds = (this.options.modalPopupTimer || 1) * 60;\n const progressPercentage = (this.countdownSeconds / totalSeconds) * 100;\n progressBar.style.width = `${progressPercentage}%`;\n }\n }\n}","import { DeviceType } from \"./types\";\n\nconst navigatorDefined = typeof navigator !== 'undefined';\nconst windowDefined = typeof window !== 'undefined';\n\nconst userAgent = navigatorDefined ? navigator.userAgent.toLowerCase() : '';\nconst userAgentData = navigatorDefined ? (navigator as Navigator & {\n userAgentData?: {\n platform: string;\n brands?: { brand: string; version: string }[];\n }\n}).userAgentData : undefined;\n\n// Cache for device detection results\nlet cachedDeviceType: DeviceType.DESKTOP | DeviceType.MOBILE | null = null;\nlet cachedMobileType: DeviceType.ANDROID | DeviceType.IOS | null = null;\n\n/**\n * Safe wrapper for window.matchMedia\n */\nfunction safeMatchMedia(query: string): boolean {\n try {\n return window.matchMedia?.(query)?.matches || false;\n } catch {\n return false;\n }\n}\n\n/**\n * Safe wrapper for CSS.supports\n */\nfunction safeCSSSupports(property: string, value: string): boolean {\n try {\n return CSS?.supports?.(property, value) || false;\n } catch {\n return false;\n }\n}\n\n/**\n * Safe wrapper for document.querySelector\n */\nfunction safeQuerySelector(selector: string): boolean {\n try {\n return document?.querySelector?.(selector) !== null;\n } catch {\n return false;\n }\n}\n\n/**\n * Highly accurate device type detection - returns only 'desktop' or 'mobile'\n * Uses multiple detection methods and scoring system for maximum accuracy\n * @returns {DeviceType.DESKTOP | DeviceType.MOBILE} The detected device type\n */\nexport function getDeviceType(): DeviceType.DESKTOP | DeviceType.MOBILE {\n // Return cached result if available\n if (cachedDeviceType !== null) {\n return cachedDeviceType;\n }\n\n // Early return for server-side rendering - assume desktop\n if (!navigatorDefined || !windowDefined) {\n return DeviceType.DESKTOP;\n }\n\n let mobileScore = 0;\n const CONFIDENCE_THRESHOLD = 3; // Need at least 3 points to be considered mobile\n \n // ====== Device Characteristics ======\n \n // Screen dimensions\n const screenWidth = window.innerWidth || window.screen?.width || 0;\n const screenHeight = window.innerHeight || window.screen?.height || 0;\n const hasSmallScreen = screenWidth <= 480 || screenHeight <= 480;\n const hasLargeScreen = screenWidth > 1024 && screenHeight > 768;\n \n // Touch capabilities\n const hasTouch = 'ontouchstart' in window || \n (navigatorDefined && navigator.maxTouchPoints > 0);\n const hasPreciseMouse = safeMatchMedia('(pointer: fine)');\n const canHover = safeMatchMedia('(hover: hover)');\n const hasMouseAndTouch = hasTouch && hasPreciseMouse; // Touchscreen laptop\n \n // Windows touch laptop detection (used for exceptions)\n const isWindowsTouchLaptop = /Windows/i.test(userAgent) && \n hasPreciseMouse && \n hasTouch;\n \n // ====== Mobile Indicators (Add Points) ======\n \n // Touch without mouse = likely mobile (+2 points)\n // Touch with mouse = touchscreen laptop (+1 point)\n if (hasTouch && !hasMouseAndTouch) {\n mobileScore += 2;\n } else if (hasMouseAndTouch) {\n mobileScore += 1;\n }\n \n // Small screen is mobile indicator (+2 points)\n // Exception: Windows touch laptops with precise mouse should not be penalized for small screens\n if (hasSmallScreen && !isWindowsTouchLaptop) {\n mobileScore += 2;\n }\n \n // Mobile user agent is strong indicator (+3 points)\n const hasMobileUserAgent = /android|webos|iphone|ipad|ipod|blackberry|iemobile|opera mini|mobile/i.test(userAgent);\n if (hasMobileUserAgent) {\n mobileScore += 3;\n }\n \n // Mobile APIs only count if combined with other mobile signs (+2 points)\n // Exception: Desktop Safari and Windows touch laptops have mobile APIs but should not be considered mobile\n const hasMobileAPIs = 'orientation' in window || \n 'DeviceMotionEvent' in window ||\n 'DeviceOrientationEvent' in window;\n const isDesktopSafari = /Safari/i.test(userAgent) && \n !/Mobile/i.test(userAgent) && \n /Mac|Intel/i.test(userAgent);\n if (hasMobileAPIs && (hasSmallScreen || hasMobileUserAgent) && !isDesktopSafari && !isWindowsTouchLaptop) {\n mobileScore += 2;\n }\n \n // High DPI with small screen = mobile (+1 point)\n const hasHighDPI = window.devicePixelRatio > 1.5;\n if (hasHighDPI && hasSmallScreen) {\n mobileScore += 1;\n }\n \n // Viewport meta tag with small screen = mobile optimized (+1 point)\n const hasViewportMeta = safeQuerySelector('meta[name=\"viewport\"]');\n if (hasViewportMeta && hasSmallScreen) {\n mobileScore += 1;\n }\n \n // iPad Pro special case: Mac user agent with touch (+2 points)\n const isPadProInDesktopMode = userAgent.includes('macintosh') && hasTouch;\n if (isPadProInDesktopMode) {\n mobileScore += 2;\n }\n \n // ====== Desktop Indicators (Subtract Points) ======\n \n // Large screen with mouse = desktop (-3 points)\n if (hasLargeScreen && hasPreciseMouse) {\n mobileScore -= 3;\n } \n // Large screen without touch = desktop (-2 points)\n else if (hasLargeScreen && !hasTouch) {\n mobileScore -= 2;\n }\n \n // Can hover with precise pointer = has real mouse (-2 points)\n if (hasPreciseMouse && canHover) {\n mobileScore -= 2;\n }\n \n // Windows user agent = strong desktop indicator (-3 points)\n const isWindowsDesktop = /Windows/i.test(userAgent) && !hasMobileUserAgent;\n if (isWindowsDesktop) {\n mobileScore -= 3;\n }\n\n // Cache and return the result\n cachedDeviceType = mobileScore >= CONFIDENCE_THRESHOLD ? DeviceType.MOBILE : DeviceType.DESKTOP;\n return cachedDeviceType;\n}\n\n/**\n * Highly accurate mobile device type detection - returns only 'android' or 'ios'\n * Should only be called when getDeviceType() returns 'mobile'\n * @returns {DeviceType.ANDROID | DeviceType.IOS} The detected mobile device type\n */\nexport function getMobileDeviceType(): DeviceType.ANDROID | DeviceType.IOS {\n // Return cached result if available\n if (cachedMobileType !== null) {\n return cachedMobileType;\n }\n\n // Early return for server-side rendering - default to Android\n if (!navigatorDefined || !windowDefined) {\n return DeviceType.ANDROID;\n }\n\n const ua = navigator.userAgent;\n \n // ====== iOS Detection ======\n \n // Direct iOS device detection\n const hasIOSDeviceName = /iPad|iPhone|iPod/i.test(ua);\n if (hasIOSDeviceName) {\n cachedMobileType = DeviceType.IOS;\n return cachedMobileType;\n }\n \n // iPad Pro detection (reports as Mac but has touch)\n const isMacWithTouch = /Macintosh|MacIntel/i.test(ua) && 'ontouchstart' in window;\n const isMacOSWithTouch = userAgentData?.platform === 'macOS' && 'ontouchstart' in window;\n if (isMacWithTouch || isMacOSWithTouch) {\n cachedMobileType = DeviceType.IOS;\n return cachedMobileType;\n }\n \n // iOS-specific APIs\n const hasIOSPermissionAPI = typeof (window as any).DeviceMotionEvent?.requestPermission === 'function';\n const hasIOSTouchCallout = safeCSSSupports('-webkit-touch-callout', 'none');\n if (hasIOSPermissionAPI || hasIOSTouchCallout) {\n cachedMobileType = DeviceType.IOS;\n return cachedMobileType;\n }\n \n // Safari without Chrome (iOS WebKit) - but not desktop Safari\n const isIOSWebKit = /WebKit/i.test(ua) && \n !/Chrome|CriOS|Android/i.test(ua) && \n !/Macintosh|MacIntel/i.test(ua);\n if (isIOSWebKit) {\n cachedMobileType = DeviceType.IOS;\n return cachedMobileType;\n }\n \n // ====== Android Detection ======\n \n // Direct Android detection\n const hasAndroidKeyword = /Android/i.test(ua);\n if (hasAndroidKeyword) {\n cachedMobileType = DeviceType.ANDROID;\n return cachedMobileType;\n }\n \n // Mobile Chrome (usually Android)\n const isChromeOnMobile = (window as any).chrome && /Mobile/i.test(ua);\n if (isChromeOnMobile) {\n cachedMobileType = DeviceType.ANDROID;\n return cachedMobileType;\n }\n \n // Default fallback - Android is more common globally\n cachedMobileType = DeviceType.ANDROID;\n return cachedMobileType;\n}\n\n/**\n * Convenience method to check if current device is mobile\n * @returns {boolean} True if device is mobile\n */\nexport function isMobileDevice(): boolean {\n return getDeviceType() === DeviceType.MOBILE;\n}\n\n/**\n * Convenience method to check if current device is desktop\n * @returns {boolean} True if device is desktop\n */\nexport function isDesktopDevice(): boolean {\n return getDeviceType() === DeviceType.DESKTOP;\n}\n\n/**\n * Clear cached device detection results (useful for testing)\n */\nexport function clearDeviceCache(): void {\n cachedDeviceType = null;\n cachedMobileType = null;\n}\n\n// Export safe wrappers for testing\nexport { safeMatchMedia, safeCSSSupports, safeQuerySelector };","import { ethers } from 'ethers';\n\nexport const ATTESTATION_NONCE_DOMAIN = 'RECLAIM_TEE_NONCE_V1';\n\nexport function generateAttestationNonce(\n appSecret: string,\n applicationId: string,\n sessionId: string,\n timestamp: string\n): string {\n const noncePayload = [\n ATTESTATION_NONCE_DOMAIN,\n applicationId,\n sessionId,\n timestamp,\n appSecret\n ].join(':');\n\n return ethers.keccak256(ethers.toUtf8Bytes(noncePayload)).replace(/^0x/i, '');\n}\n","import { hashProofClaimParams } from \"../witness\";\nimport { InvalidRequestSpecError, ProviderConfigFetchError } from \"./errors\";\nimport { fetchProviderConfigs } from \"./sessionUtils\";\nimport loggerModule from './logger';\nimport { Proof } from \"./interfaces\";\n\nconst logger = loggerModule.logger;\n\n/**\n * Fetches the provider configuration by the providerId and its version; and constructs the robust hash requirements needed for proof validation.\n * It resolves both explicitly required HTTP requests and allowed injected requests based on the provider version.\n * \n * See also:\n * \n * * `ReclaimProofRequest.getProviderHashRequirements()` - An alternative of this function to get the expected hashes for a proof request. The result can be provided in verifyProof function's `config` parameter for proof validation.\n * * `getProviderHashRequirementsFromSpec()` - An alternative of this function to get the expected hashes from a provider spec. The result can be provided in verifyProof function's `config` parameter for proof validation.\n * \n * @param providerId - The unique identifier of the selected provider.\n * @param exactProviderVersionString - The specific version string of the provider configuration to ensure deterministic validation.\n * @returns A promise that resolves to `ProviderHashRequirementsConfig` representing the expected hashes for proof validation.\n */\nexport async function fetchProviderHashRequirementsBy(providerId: string, exactProviderVersionString: string | null | undefined, allowedTags: string[] | null | undefined, proofs?: Proof[]): Promise<ProviderHashRequirementsConfig[]> {\n const providerResponse = await fetchProviderConfigs(providerId, exactProviderVersionString, allowedTags);\n\n try {\n const providerConfigs = providerResponse.providers;\n if (!providerConfigs || !providerConfigs.length) {\n throw new ProviderConfigFetchError(`No provider configs found for providerId: ${providerId}, exactProviderVersionString: ${exactProviderVersionString}`);\n }\n\n const hashRequirements: ProviderHashRequirementsConfig[] = [];\n\n for (const providerConfig of providerConfigs) {\n const requestSpec = getProviderHashRequirementSpecFromProviderConfig(providerConfig, proofs);\n hashRequirements.push(getProviderHashRequirementsFromSpec(requestSpec));\n }\n\n return hashRequirements;\n } catch (e) {\n const errorMessage = `Failed to fetch provider hash requirements for providerId: ${providerId}, exactProviderVersionString: ${exactProviderVersionString}`;\n logger.info(errorMessage, e);\n throw new ProviderConfigFetchError(`Error fetching provider hash requirements for providerId: ${providerId}, exactProviderVersionString: ${exactProviderVersionString}`);\n }\n}\n\n/**\n * Generates an array of `RequestSpec` objects by replacing template parameters with their corresponding values.\n * \n * If the input template includes `templateParams` (e.g., `['param1', 'param2']`), this function will \n * cartesian-map (or pairwise-map) the provided `templateParameters` record (e.g., `{ param1: ['v1', 'v2'], param2: ['a1', 'a2'] }`) \n * to generate multiple unique `RequestSpec` configurations.\n * \n * The function ensures that:\n * 1. Parameters strictly specified in `template.templateParams` are found.\n * 2. All specified template parameters arrays have the exact same length (pairwise mapping).\n * 3. String replacements are fully applied (all occurrences) to `responseMatches` (value) and `responseRedactions` (jsonPath, xPath, regex).\n * \n * @param requestSpecTemplates - The base template `RequestSpec` containing parameter placeholders.\n * @param templateParameters - A record mapping parameter names to arrays of strings representing the extracted values.\n * @returns An array of fully constructed `RequestSpec` objects with templates replaced.\n * @throws {InvalidRequestSpecError} If required parameters are missing or parameter value arrays have mismatched lengths.\n */\nexport function generateSpecsFromRequestSpecTemplate(requestSpecTemplates: RequestSpec[], templateParameters: Record<string, string[]>): RequestSpec[] {\n if (!requestSpecTemplates) return [];\n\n const generatedRequestTemplate: RequestSpec[] = [];\n\n for (const template of requestSpecTemplates) {\n const templateVariables = template.templateParams ?? [];\n if (!templateVariables.length) {\n generatedRequestTemplate.push(template);\n continue;\n }\n\n const templateParamsPairMatch = Object.entries(templateParameters).filter(([key, value]) => templateVariables.includes(key) && value.length)\n const hasAllTemplateVariableMatch = templateParamsPairMatch.length === templateVariables.length;\n if (!hasAllTemplateVariableMatch) {\n throw new InvalidRequestSpecError(`Not all template variables are present for template`);\n }\n\n // check all template variables have same length\n const templateParamsPairMatchLength = templateParamsPairMatch[0][1].length;\n const allTemplateVariablesHaveSameLength = templateParamsPairMatch.every(([key, value]) => value.length === templateParamsPairMatchLength);\n if (!allTemplateVariablesHaveSameLength) {\n throw new InvalidRequestSpecError(`Not all template variables have same length for template`);\n }\n\n const getRequestSpecVariableTemplate = (key: string) => {\n return `\\${${key}}`;\n }\n\n for (let i = 0; i < templateParamsPairMatchLength; i++) {\n const currentTemplateParams: Record<string, string> = {};\n for (const [key, values] of templateParamsPairMatch) {\n currentTemplateParams[key] = values[i];\n }\n\n const spec: RequestSpec = {\n ...template,\n responseMatches: template.responseMatches ? template.responseMatches.map(m => ({ ...m })) : [],\n responseRedactions: template.responseRedactions ? template.responseRedactions.map(r => ({ ...r })) : [],\n }\n\n for (const match of spec.responseMatches) {\n for (const [key, value] of Object.entries(currentTemplateParams)) {\n match.value = match.value.split(getRequestSpecVariableTemplate(key)).join(value);\n }\n }\n\n for (const redaction of spec.responseRedactions) {\n for (const [key, value] of Object.entries(currentTemplateParams)) {\n redaction.jsonPath = redaction.jsonPath.split(getRequestSpecVariableTemplate(key)).join(value);\n redaction.xPath = redaction.xPath.split(getRequestSpecVariableTemplate(key)).join(value);\n redaction.regex = redaction.regex.split(getRequestSpecVariableTemplate(key)).join(value);\n }\n }\n\n generatedRequestTemplate.push(spec);\n }\n }\n\n return generatedRequestTemplate\n}\n\nexport function takeTemplateParametersFromProofs(proofs?: Proof[]): Record<string, string[]> {\n return takePairsWhereValueIsArray(proofs?.map(it => JSON.parse(it.claimData.context).extractedParameters as Record<string, string>).reduce((acc, it) => ({ ...acc, ...it }), {}));\n}\n\nexport function takePairsWhereValueIsArray(o: Record<string, string> | undefined): Record<string, string[]> {\n if (!o) return {};\n const pairs: Record<string, string[]> = {};\n for (const [key, value] of Object.entries(o)) {\n if (Array.isArray(value) && value.length) {\n pairs[key] = value;\n } else {\n try {\n const parsedValue = JSON.parse(value);\n if (Array.isArray(parsedValue) && parsedValue.length) {\n pairs[key] = parsedValue;\n }\n } catch (_) {\n // ignore parsing errors\n }\n }\n }\n return pairs;\n}\n\n/**\n * Builds and returns raw hash requirement spec that can be used with `getProviderHashRequirementsFromSpec` to computes the expected proof hashes for a provider configuration\n * by combining its explicitly required requests and allowed injected requests.\n * It resolves template parameters from provided proofs to generate the final request specifications.\n * \n * @param providerConfig - The provider configuration containing request data and allowed injected requests.\n * @param proofs - Optional array of proofs used to extract template parameters for resolving placeholders in injected requests.\n * @returns A structured configuration containing that can be used with `getProviderHashRequirementsFromSpec` to compute the hashes.\n */\nexport function getProviderHashRequirementSpecFromProviderConfig(providerConfig: ReclaimProviderConfigWithRequestSpec, proofs?: Proof[]): ProviderHashRequirementSpec {\n return {\n requests: [...(providerConfig?.requestData ?? []), ...generateSpecsFromRequestSpecTemplate(providerConfig?.allowedInjectedRequestData ?? [], takeTemplateParametersFromProofs(proofs))],\n };\n}\n\n/**\n * Transforms a raw provider hash requirement specification into a structured configuration for proof validation.\n * It computes the proof hashes for both required and allowed extra requests to correctly match uploaded proofs.\n * \n * See also:\n * \n * * `fetchProviderHashRequirementsBy()` - An alternative of this function to get the expected hashes for a provider version by providing providerId and exactProviderVersionString. The result can be provided in verifyProof function's `config` parameter for proof validation.\n * * `ReclaimProofRequest.getProviderHashRequirements()` - An alternative of this function to get the expected hashes for a proof request. The result can be provided in verifyProof function's `config` parameter for proof validation.\n *\n * @param spec - The raw provider specifications including required and allowed requests.\n * @returns A structured configuration containing computed required and allowed hashes for validation.\n */\nexport function getProviderHashRequirementsFromSpec(spec: ProviderHashRequirementSpec): ProviderHashRequirementsConfig {\n return {\n hashes: spec?.requests?.map(hashRequestSpec) || [],\n };\n}\n\n/**\n * Computes the claim hash for a specific request specification based on its properties.\n *\n * @param request - The HTTP request specification (e.g., URL, method, sniffs).\n * @returns A string representing the hashed proof claim parameters.\n */\nexport function hashRequestSpec(request: RequestSpec): HashRequirement {\n const hash = hashProofClaimParams({\n ...request,\n // Body is strictly empty unless body sniff is explicitly enabled\n body: request.bodySniff.enabled ? request.bodySniff.template : '',\n });\n\n return {\n value: hash,\n required: request.required,\n multiple: request.multiple,\n }\n}\n\n/**\n * Represents the raw specification of hash requirements provided by a provider's configuration.\n */\nexport interface ProviderHashRequirementSpec {\n /** List of request specs that can match with HTTP requests to create a proof using Reclaim Protocol */\n requests: RequestSpec[] | undefined;\n}\n\n/**\n * The structured hash requirements configuration used during proof verification and content validation.\n */\nexport type ProviderHashRequirementsConfig = {\n /** \n * Array of computed hash requirements that must be satisfied by the proofs.\n */\n hashes: HashRequirement[];\n}\n\n/**\n * Describes a hash requirement for a proof.\n */\nexport type HashRequirement = {\n /**\n * The hash value(s) to match. An array represents multiple valid hashes for optional configurations.\n */\n value: string | string[];\n /**\n * Whether the hash is required to be present in the proof.\n * Defaults to true\n */\n required?: boolean;\n /**\n * Whether the hash can appear multiple times in the proof.\n * Defaults to false\n */\n multiple?: boolean;\n}\n\nexport interface ReclaimProviderConfigWithRequestSpec {\n requestData: InterceptorRequestSpec[];\n allowedInjectedRequestData: InjectedRequestSpec[];\n}\n\n/**\n * Specific marker interface for intercepted request specifications.\n */\nexport interface InterceptorRequestSpec extends RequestSpec { }\n\n/**\n * Specific marker interface for injected request specifications.\n */\nexport interface InjectedRequestSpec extends RequestSpec { }\n\n/**\n * Represents the properties and validation steps for an HTTP request involved in a Reclaim proof.\n */\nexport interface RequestSpec {\n /** The URL or generic path of the HTTP request */\n url: string;\n /** Type or representation of the URL */\n urlType: string;\n /** The HTTP method used for the request */\n method: \"GET\" | \"POST\" | \"PUT\" | \"PATCH\" | \"DELETE\";\n /** Identifies and captures the request body if enabled */\n bodySniff: BodySniff;\n /** Required matching configurations for the HTTP response */\n responseMatches: ResponseMatchSpec[];\n /** Redaction rules applied to the HTTP response before passing to attestors */\n responseRedactions: ResponseRedactionSpec[];\n /**\n * Whether request matching this spec is required and always expected in list of proofs\n * Defaults to true.\n */\n required?: boolean;\n /**\n * Whether request matching this spec is allowed to appear multiple times in list of proofs.\n * Defaults to true.\n */\n multiple?: boolean;\n /**\n * Template parameter variables for the request spec that should be replaced with real values\n * during dynamic request spec construction.\n */\n templateParams?: string[]\n}\n\n/**\n * Defines the configuration for identifying/sniffing the request body.\n */\nexport interface BodySniff {\n /** Indicates whether body sniffing is enabled */\n enabled: boolean;\n /** The template string used to match or capture the body */\n template: string;\n}\n\n/**\n * Specifies a rule to match against a string in response to validate proof content.\n */\nexport interface ResponseMatchSpec {\n /** If true, the match condition is reversed */\n invert: boolean | undefined;\n /** If true, the match condition is optional and won't fail if absent */\n isOptional: boolean | undefined;\n /** The matching mechanism, typically regex or simple string containment */\n type: \"regex\" | \"contains\";\n /** The pattern or value to look for in the response */\n value: string;\n}\n\n/**\n * Specifies redaction rules for obscuring sensitive parts of the response.\n */\nexport interface ResponseRedactionSpec {\n /** Optional hashing method applied to the redacted content (e.g., 'oprf') */\n hash?: \"oprf\" | \"oprf-mpc\" | \"oprf-raw\" | undefined;\n /** JSON path for locating the value to redact */\n jsonPath: string;\n /** RegEx applied to correctly parse and extract/redact value */\n regex: string;\n /** XPath for XML/HTML matching configuration */\n xPath: string;\n}\n","import { HttpProviderClaimParams } from \"./types\";\nimport { hashProofClaimParams } from \"../witness\";\nimport { ProofNotValidatedError, UnknownProofsNotValidatedError } from \"./errors\";\nimport loggerModule from './logger';\nimport { Proof, ProviderVersionInfo } from \"./interfaces\";\nimport { fetchProviderHashRequirementsBy, HashRequirement, ProviderHashRequirementsConfig } from \"./providerUtils\";\nimport type { AttestorTeeAttestationConfig } from \"./verifyAttestorTee\";\n\nconst logger = loggerModule.logger;\n\n\n/**\n * Content validation configuration specifying essential required hashes and optional extra proofs.\n * Used to explicitly validate that a generated proof matches the exact request structure expected.\n */\nexport type ValidationConfigWithHash = {\n /**\n * Array of computed hashes that must be satisfied by the proofs.\n * \n * An element can be a `HashRequirement` object or a string that is equivalent to\n * a `{ value: '<hash>', required: true, multiple: false }` as `HashRequirement`.\n */\n hashes: (string | HashRequirement)[]\n};\n\n/**\n * Content validation configuration specifying the provider id and version used in the verification session that generated the proofs.\n * Used to explicitly validate that a generated proof matches the exact request structure expected.\n * \n * See also:\n * \n * * `ReclaimProofRequest.getProviderVersion()` - With a ReclaimProofRequest object, you can get the provider id & exact version of provider used in verification session.\n */\nexport interface ValidationConfigWithProviderInformation {\n /**\n * The identifier of provider used in verifications that resulted in a proof\n * \n * See also:\n * \n * * `ReclaimProofRequest.getProviderVersion()` - With a ReclaimProofRequest object, you can get the provider id & exact version of provider used in verification session.\n **/\n providerId: string;\n /**\n * The exact version of provider used in verifications that resulted in a proof.\n * \n * This cannot be a version constaint or version expression. It can be undefined or left blank if proof must be validated with latest version of provider.\n * Patches for the next provider version are also fetched and hashes from that spec is also be used to compare the hashes from proof.\n * \n * See also:\n * \n * * `ReclaimProofRequest.getProviderVersion()` - With a ReclaimProofRequest object, you can get the provider id & exact version of provider used in verification session.\n **/\n providerVersion?: string;\n /**\n * List of allowed pre-release tags.\n * For example, if you are using AI, provide `['ai']` to allow AI patch versions of the provider.\n */\n allowedTags?: string[];\n}\n\n/**\n * Legacy configuration to completely bypass content validation during verification.\n * Warning: Using this poses a risk as it avoids strictly matching proof parameters to expected hashes.\n */\nexport interface ValidationConfigWithDisabledValidation { dangerouslyDisableContentValidation: true }\n\n/**\n * Represents the configuration options applied when validating proof contents, allowing\n * strict hash checking or intentionally skipping validation if flagged.\n */\nexport type ValidationConfig = ValidationConfigWithHash | ValidationConfigWithProviderInformation | ValidationConfigWithDisabledValidation;\n\n/**\n * Describes the comprehensive configuration required to initialize the proof verification process.\n * Aligns with `ValidationConfig` options for verifying signatures alongside proof contents.\n */\nexport type TeeAttestationConfig = {\n /**\n * Your application secret (Ethereum private key).\n * Used to recompute the TEE attestation nonce and to derive the application ID\n * for binding the attestation to your application.\n */\n appSecret: string;\n};\n\nexport type VerificationConfig = ValidationConfig & {\n /**\n * TEE attestation verification configuration.\n * When provided, verifies the TEE attestation included in the proof.\n * The result will include `isTeeAttestationVerified` and `isVerified` will be false\n * if TEE attestation data is missing or verification fails.\n */\n teeAttestation?: TeeAttestationConfig;\n /**\n * Attestor TEE attestation verification configuration.\n * When provided, verifies that every witness on every proof has a valid\n * `claimAttestation` from an attestor running inside a TEE (GCP\n * Confidential Space).\n *\n * Independent of `teeAttestation`, which verifies the verifier-app's\n * own TEE attestation. Both can be enabled together.\n *\n * The result will include `isAttestorTeeAttestationVerified` and\n * `isVerified` will be false if any witness is missing TEE attestation\n * data or its verification fails.\n */\n attestorTeeAttestation?: AttestorTeeAttestationConfig;\n};\n\n\nconst HASH_REQUIRED_DEFAULT = true;\nconst HASH_MATCH_MULTIPLE_DEFAULT = true;\n\nexport function assertValidProofsByHash(proofs: Proof[], config: ProviderHashRequirementsConfig) {\n if (!config.hashes) {\n throw new ProofNotValidatedError('No proof hash was provided for validation');\n }\n\n const unvalidatedProofHashByIndex = new Map<number, string[]>();\n\n for (let i = 0; i < proofs.length; i++) {\n const proof = proofs[i];\n const claimParams = getHttpProviderClaimParamsFromProof(proof);\n const computedHashesOfProof = hashProofClaimParams(claimParams);\n const proofHashes = Array.isArray(computedHashesOfProof)\n ? computedHashesOfProof.map(h => h.toLowerCase().trim())\n : [computedHashesOfProof.toLowerCase().trim()];\n unvalidatedProofHashByIndex.set(i, proofHashes);\n }\n\n for (const hashRequirement of config.hashes) {\n let found = false;\n\n // The expectedHashes array incorporates multiple valid permutations when optional rule sets are defined in config.\n const expectedHashes = Array.isArray(hashRequirement.value)\n ? hashRequirement.value.map(h => h.toLowerCase().trim())\n : [hashRequirement.value.toLowerCase().trim()];\n\n const isRequired = hashRequirement.required ?? HASH_REQUIRED_DEFAULT;\n const canMatchMultiple = hashRequirement.multiple ?? HASH_MATCH_MULTIPLE_DEFAULT;\n\n // Iterate through unvalidated proofs to assert that the generated deterministic hash \n // derived from the User's actual matched elements structurally matches ANY of the permissible configurations.\n for (const [i, proofHashes] of unvalidatedProofHashByIndex.entries()) {\n const intersection = expectedHashes.filter(eh => proofHashes.includes(eh));\n\n // If the Proof's claim exactly replicates one of the Valid Config permutations:\n if (intersection.length > 0) {\n // Remove the proof so it can't validate subsequent independent requirements\n unvalidatedProofHashByIndex.delete(i);\n if (!found) {\n found = true;\n } else if (!canMatchMultiple) {\n // Preclude an attack surface where User passes duplicated valid proofs \n // matching permutations of the SAME underlying strict configuration.\n const expectedHashStr = expectedHashes.length === 1 ? expectedHashes[0] : `[${expectedHashes.join(', ')}]`;\n throw new ProofNotValidatedError(`Proof by hash '${expectedHashStr}' is not allowed to appear more than once`);\n }\n }\n }\n\n if (!found && isRequired) {\n const expectedHashStr = expectedHashes.length === 1 ? expectedHashes[0] : `[${expectedHashes.join(', ')}]`;\n throw new ProofNotValidatedError(`Proof by required hash '${expectedHashStr}' was not found`);\n }\n }\n\n if (unvalidatedProofHashByIndex.size > 0) {\n // if allowedExtraProofHashes was provided (not empty) and there are still unvalidated proofs, it means they are not allowed\n const contactSupport = 'Please contact Reclaim Protocol Support team or mail us at support@reclaimprotocol.org.';\n const unvalidatedHashesStrArr = [...unvalidatedProofHashByIndex.values()]\n .map(h => h.length === 1 ? h[0] : `[${h.join(', ')}]`);\n throw new UnknownProofsNotValidatedError(`Extra ${unvalidatedProofHashByIndex.size} proof(s) by hashes ${unvalidatedHashesStrArr.join(', ')} was found but could not be validated and indicates a security risk. ${contactSupport}`);\n }\n}\n\nconst allowedHttpMethods = new Set([\"GET\", \"POST\", \"PUT\", \"PATCH\", \"DELETE\"]);\n\nexport function isHttpProviderClaimParams(claimParams: unknown): claimParams is HttpProviderClaimParams {\n // Fail fast on non-objects\n if (!claimParams || typeof claimParams !== 'object' || Array.isArray(claimParams)) {\n return false;\n }\n\n // Cast to a Record so we can check properties directly without 'in'\n const params = claimParams as Record<string, unknown>;\n\n return (\n typeof params.url === 'string' &&\n typeof params.method === 'string' &&\n allowedHttpMethods.has(params.method) &&\n (params.body == null || typeof params.body === 'string') &&\n Array.isArray(params.responseMatches) &&\n params.responseMatches.length > 0 &&\n Array.isArray(params.responseRedactions)\n );\n}\n\nexport function getHttpProviderClaimParamsFromProof(proof: Proof): HttpProviderClaimParams {\n try {\n const claimParams = JSON.parse(proof.claimData.parameters);\n if (isHttpProviderClaimParams(claimParams)) {\n return claimParams;\n }\n } catch (_) { }\n throw new ProofNotValidatedError('Proof has no HTTP provider params to hash');\n}\n\n/**\n * Asserts that the proof is validated by checking the content of proof with with expectations from provider config or hash based on [options]\n * @param proofs - The proofs to validate\n * @param config - The validation config\n * @throws {ProofNotValidatedError} When the proof is not validated\n */\nexport async function assertValidateProof(proofs: Proof[], config: VerificationConfig) {\n if ('dangerouslyDisableContentValidation' in config && config.dangerouslyDisableContentValidation) {\n logger.warn('Validation skipped because it was disabled during proof verification')\n return\n }\n\n if ('providerId' in config) {\n if (!config.providerId || typeof config.providerId !== 'string') {\n throw new ProofNotValidatedError('Provider id is required for proof validation');\n }\n if (config.providerVersion && typeof config.providerVersion !== 'string') {\n throw new ProofNotValidatedError('Provider version must be a string');\n }\n const hashRequirementsFromProvider = await fetchProviderHashRequirementsBy(config.providerId, config.providerVersion, config.allowedTags, proofs);\n if (!hashRequirementsFromProvider.length) {\n throw new ProofNotValidatedError('Could not find any provider information for the given provider id and version');\n }\n if (hashRequirementsFromProvider.length != 1) {\n let lastError: unknown | null = null;\n for (const hashRequirement of hashRequirementsFromProvider) {\n try {\n return await assertValidateProof(proofs, hashRequirement);\n } catch (e) {\n lastError = e;\n }\n }\n throw new ProofNotValidatedError('Could not validate proof', lastError as any);\n } else {\n return assertValidateProof(proofs, hashRequirementsFromProvider[0]);\n }\n }\n\n const effectiveHashRequirement = ('hashes' in config && Array.isArray(config?.hashes) ? config.hashes : []).map(it => {\n if (typeof it == 'string') {\n return {\n value: it,\n }\n } else {\n return it\n }\n });\n\n return assertValidProofsByHash(proofs, {\n hashes: effectiveHashRequirement,\n })\n}\n","import { Proof, TeeAttestation } from './interfaces';\nimport { ethers } from 'ethers';\nimport { generateAttestationNonce } from './attestationNonce';\nimport { GCP_CONFIDENTIAL_SPACE_ISSUER } from './constants';\nimport { TeeVerificationError } from './errors';\nimport type { TeeAttestationConfig } from './proofValidationUtils';\nimport loggerModule from './logger';\n\nconst logger = loggerModule.logger;\n\nconst EXPECTED_HW_MODEL = 'GCP_AMD_SEV';\nconst EXPECTED_TEE_PROVIDER = 'gcp';\nconst EXPECTED_TEE_TECHNOLOGY = 'amd-sev';\nconst SUPPORTED_PROOF_VERSIONS = ['v2', 'v3'];\nconst TOKEN_CLOCK_SKEW_S = 60;\nconst NONCE_TIMESTAMP_MAX_SKEW_MS = 10 * 60 * 1000;\n\ntype JsonWebKeyLike = JsonWebKey & {\n kid?: string;\n alg?: string;\n use?: string;\n};\n\ntype DecodedJwt = {\n header: Record<string, any>;\n payload: Record<string, any>;\n signingInput: string;\n signature: Uint8Array;\n};\n\ntype NonceContextData = {\n applicationId: string;\n sessionId: string;\n timestamp: string;\n};\n\nexport type TeeVerificationResult = {\n isVerified: boolean;\n error?: string;\n};\n\nconst BROWSER_ENVIRONMENT_ERROR =\n 'TEE attestation verification is only supported in non-browser environments. Run verifyTeeAttestation on your server or API route.';\n\nfunction assert(condition: unknown, message: string): asserts condition {\n if (!condition) {\n throw new Error(message);\n }\n}\n\nfunction isBrowserEnvironment(): boolean {\n if (typeof window !== 'undefined' || typeof document !== 'undefined') {\n return true;\n }\n\n if (typeof navigator !== 'undefined' && typeof process === 'undefined') {\n return true;\n }\n\n const workerGlobalScope = (globalThis as any).WorkerGlobalScope;\n if (\n typeof workerGlobalScope !== 'undefined' &&\n typeof self !== 'undefined' &&\n self instanceof workerGlobalScope\n ) {\n return true;\n }\n\n return false;\n}\n\nfunction assertNonBrowserEnvironment() {\n if (isBrowserEnvironment()) {\n throw new Error(BROWSER_ENVIRONMENT_ERROR);\n }\n}\n\nfunction normalizeHex(value: string | undefined | null): string {\n return (value || '').trim().replace(/^0x/i, '').toLowerCase();\n}\n\nfunction isHex(value: string): boolean {\n return /^[0-9a-f]+$/i.test(value);\n}\n\nfunction decodeBase64Url(input: string): Uint8Array {\n const normalized = input.replace(/-/g, '+').replace(/_/g, '/');\n const padded = normalized + '='.repeat((4 - normalized.length % 4) % 4);\n\n if (typeof Buffer !== 'undefined') {\n return new Uint8Array(Buffer.from(padded, 'base64'));\n }\n if (typeof atob === 'function') {\n const binary = atob(padded);\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i += 1) {\n bytes[i] = binary.charCodeAt(i);\n }\n return bytes;\n }\n\n throw new Error('Base64 decoding is not supported in this environment');\n}\n\nfunction decodeUtf8(bytes: Uint8Array): string {\n return new TextDecoder().decode(bytes);\n}\n\nfunction decodeJwt(token: string): DecodedJwt {\n const parts = token.split('.');\n assert(parts.length === 3, 'attestation token is not a JWT');\n\n return {\n header: JSON.parse(decodeUtf8(decodeBase64Url(parts[0]))),\n payload: JSON.parse(decodeUtf8(decodeBase64Url(parts[1]))),\n signingInput: `${parts[0]}.${parts[1]}`,\n signature: decodeBase64Url(parts[2]),\n };\n}\n\nfunction getFetch(): typeof fetch {\n const fetchFn = globalThis.fetch;\n assert(fetchFn, 'fetch is not available in this environment');\n return fetchFn.bind(globalThis);\n}\n\nfunction getSubtleCrypto(): SubtleCrypto {\n if (globalThis.crypto?.subtle) {\n return globalThis.crypto.subtle;\n }\n\n const nodeCrypto = typeof process !== 'undefined' && process.versions?.node\n ? require('crypto')\n : undefined;\n if (nodeCrypto?.webcrypto?.subtle) {\n return nodeCrypto.webcrypto.subtle as SubtleCrypto;\n }\n\n throw new Error('WebCrypto subtle is not available in this environment');\n}\n\nasync function fetchJson(url: string): Promise<any> {\n const response = await getFetch()(url);\n if (!response.ok) {\n throw new Error(`GET ${url} returned ${response.status} ${response.statusText}`);\n }\n return response.json();\n}\n\nasync function sha256Hex(input: string): Promise<string> {\n const digest = await getSubtleCrypto().digest('SHA-256', new TextEncoder().encode(input));\n return Array.from(new Uint8Array(digest), (value) => value.toString(16).padStart(2, '0')).join('');\n}\n\nconst JWKS_CACHE_TTL_MS = 5 * 60 * 1000;\nlet cachedJwksUri: string | null = null;\nlet cachedJwksKeys: JsonWebKeyLike[] | null = null;\nlet cachedJwksAt = 0;\n\nasync function verifyJwtSignature(token: string, issuer: string): Promise<Record<string, any>> {\n const { header, payload, signingInput, signature } = decodeJwt(token);\n assert(header.alg === 'RS256', `unexpected attestation signing algorithm: ${header.alg}`);\n assert(typeof header.kid === 'string' && header.kid.length > 0, 'attestation token kid is missing');\n\n const isCacheFresh = cachedJwksKeys && (Date.now() - cachedJwksAt) < JWKS_CACHE_TTL_MS;\n\n if (!isCacheFresh) {\n const oidc = await fetchJson(`${issuer}/.well-known/openid-configuration`);\n assert(typeof oidc?.jwks_uri === 'string' && oidc.jwks_uri.length > 0, 'issuer JWKS URI is missing');\n cachedJwksUri = oidc.jwks_uri;\n\n const jwks = await fetchJson(cachedJwksUri!);\n cachedJwksKeys = jwks?.keys || [];\n cachedJwksAt = Date.now();\n }\n\n const jwk = cachedJwksKeys!.find((key: JsonWebKeyLike) => key.kid === header.kid) as JsonWebKeyLike | undefined;\n assert(jwk, `no JWKS key found for kid ${header.kid}`);\n\n const cryptoKey = await getSubtleCrypto().importKey(\n 'jwk',\n jwk,\n { name: 'RSASSA-PKCS1-v1_5', hash: 'SHA-256' },\n false,\n ['verify']\n );\n\n const isValid = await getSubtleCrypto().verify(\n 'RSASSA-PKCS1-v1_5',\n cryptoKey,\n signature as unknown as BufferSource,\n new TextEncoder().encode(signingInput) as unknown as BufferSource\n );\n assert(isValid, 'JWT signature verification failed');\n\n return payload;\n}\n\nfunction isNonceContextData(obj: unknown): obj is NonceContextData {\n if (!obj || typeof obj !== 'object') return false;\n const o = obj as Record<string, unknown>;\n return typeof o.applicationId === 'string' && o.applicationId.length > 0\n && typeof o.sessionId === 'string' && o.sessionId.length > 0\n && typeof o.timestamp === 'string' && o.timestamp.length > 0;\n}\n\nfunction parseProofContext(proof: Proof): { parsedContext: Record<string, unknown>; nonceDataObj: NonceContextData; expectedNonce: string } {\n let parsedContext: unknown;\n try {\n parsedContext = JSON.parse(proof.claimData.context);\n } catch {\n throw new Error('Malformed proof: claimData.context is not valid JSON');\n }\n\n if (!parsedContext || typeof parsedContext !== 'object') {\n throw new Error('Malformed proof: claimData.context is not a JSON object');\n }\n\n const ctx = parsedContext as Record<string, unknown>;\n const expectedNonce = ctx.attestationNonce;\n assert(typeof expectedNonce === 'string' && expectedNonce.length > 0, 'Proof context is missing attestationNonce');\n\n const nonceDataObj = ctx.attestationNonceData;\n assert(isNonceContextData(nonceDataObj), 'Proof context is missing or has invalid attestationNonceData (requires applicationId, sessionId, timestamp)');\n\n return { parsedContext: ctx, nonceDataObj, expectedNonce };\n}\n\nfunction verifyApplicationAndSessionBinding(\n proof: Proof,\n parsedContext: any,\n nonceDataObj: NonceContextData,\n expectedApplicationId?: string\n) {\n const { applicationId, sessionId, timestamp } = nonceDataObj;\n\n if (expectedApplicationId) {\n assert(\n applicationId.toLowerCase() === expectedApplicationId.toLowerCase(),\n `Application ID Mismatch! Expected ${expectedApplicationId}, but proof context contains ${applicationId}`\n );\n }\n\n let parsedParameters: Record<string, unknown> = {};\n if (proof.claimData.parameters) {\n try {\n const parsed = JSON.parse(proof.claimData.parameters);\n parsedParameters = (parsed && typeof parsed === 'object' && !Array.isArray(parsed)) ? parsed : {};\n } catch {\n throw new Error('Malformed proof: claimData.parameters is not valid JSON');\n }\n }\n\n const contextSessionId = parsedContext?.reclaimSessionId;\n const parameterSessionId = parsedParameters?.proxySessionId ?? parsedParameters?.sessionId;\n\n if (contextSessionId && contextSessionId.toString() !== sessionId.toString()) {\n throw new Error(`Session ID Mismatch! Expected ${sessionId}, but proof context contains reclaimSessionId=${contextSessionId}`);\n }\n if (parameterSessionId && parameterSessionId.toString() !== sessionId.toString()) {\n throw new Error(`Session ID Mismatch! Expected ${sessionId}, but proof parameters contain ${parameterSessionId}`);\n }\n if (!contextSessionId && !parameterSessionId) {\n throw new Error('Proof is missing reclaimSessionId and proxySessionId/sessionId for attestation nonce verification');\n }\n\n const claimTimestampMs = proof.claimData.timestampS * 1000;\n const nonceTimestampMs = parseInt(timestamp, 10);\n const diffMs = Math.abs(claimTimestampMs - nonceTimestampMs);\n if (diffMs > NONCE_TIMESTAMP_MAX_SKEW_MS) {\n throw new Error(`Timestamp Skew Too Large! claimData.timestampS and attestationNonce timestamp differ by ${Math.round(diffMs / 1000)}s (limit: 600s)`);\n }\n}\n\nfunction verifyNonceMaterial(\n expectedNonce: string,\n nonceDataObj: NonceContextData,\n expectedAppSecret?: string\n) {\n const cleanExpectedNonce = normalizeHex(expectedNonce);\n const { applicationId, sessionId, timestamp } = nonceDataObj;\n\n assert(cleanExpectedNonce.length > 0, 'Proof context attestationNonce is empty');\n assert(isHex(cleanExpectedNonce), 'Proof context attestationNonce is not valid hex');\n\n if (expectedAppSecret) {\n const recomputedNonce = generateAttestationNonce(expectedAppSecret, applicationId, sessionId, timestamp);\n assert(\n recomputedNonce === cleanExpectedNonce,\n 'Attestation nonce verification failed: app secret, application ID, session ID, or timestamp do not match'\n );\n return;\n }\n\n if (cleanExpectedNonce.length > 74) {\n const legacyNonceData = `${applicationId}:${sessionId}:${timestamp}`;\n const nonceMsg = ethers.getBytes(ethers.keccak256(new TextEncoder().encode(legacyNonceData)));\n const recoveredAddress = ethers.verifyMessage(\n nonceMsg,\n expectedNonce.startsWith('0x') ? expectedNonce : `0x${expectedNonce}`\n );\n\n assert(\n recoveredAddress.toLowerCase() === applicationId.toLowerCase(),\n `Nonce signature verification failed: recovered ${recoveredAddress}, expected ${applicationId}`\n );\n return;\n }\n\n throw new Error('App secret is required to verify hash-based attestation nonces');\n}\n\nfunction assertTokenFresh(claims: Record<string, any>) {\n const now = Math.floor(Date.now() / 1000);\n\n if (typeof claims.nbf === 'number' && now + TOKEN_CLOCK_SKEW_S < claims.nbf) {\n throw new Error(`Attestation token is not valid before ${claims.nbf}`);\n }\n if (typeof claims.exp === 'number' && now - TOKEN_CLOCK_SKEW_S > claims.exp) {\n throw new Error(`Attestation token expired at ${claims.exp}`);\n }\n if (typeof claims.iat === 'number' && claims.iat > now + TOKEN_CLOCK_SKEW_S) {\n throw new Error(`Attestation token issued-at ${claims.iat} is in the future`);\n }\n}\n\nfunction assertAudienceClaim(aud: unknown) {\n if (typeof aud === 'string') {\n assert(aud.length > 0, 'attestation token audience is empty');\n return;\n }\n if (Array.isArray(aud)) {\n assert(aud.length > 0, 'attestation token audience is empty');\n assert(aud.every((entry) => typeof entry === 'string' && entry.length > 0), 'attestation token audience contains invalid entries');\n return;\n }\n throw new Error('attestation token audience is missing');\n}\n\nfunction getProofVersion(teeAttestation: TeeAttestation): string | undefined {\n return (teeAttestation as any).proof_version ?? (teeAttestation as any).proofVersion;\n}\n\nfunction assertProofShape(teeAttestation: TeeAttestation) {\n if (teeAttestation.error) {\n throw new Error(`${teeAttestation.error.code}: ${teeAttestation.error.message}`);\n }\n\n const proofVersion = getProofVersion(teeAttestation);\n assert(typeof proofVersion === 'string' && SUPPORTED_PROOF_VERSIONS.includes(proofVersion), `unexpected proof version: ${proofVersion}`);\n assert(teeAttestation.tee_provider === EXPECTED_TEE_PROVIDER, `unexpected tee provider: ${teeAttestation.tee_provider}`);\n assert(teeAttestation.tee_technology === EXPECTED_TEE_TECHNOLOGY, `unexpected tee technology: ${teeAttestation.tee_technology}`);\n assert(typeof teeAttestation.nonce === 'string' && teeAttestation.nonce.length > 0, 'tee attestation nonce missing');\n assert(typeof teeAttestation.timestamp === 'string' && teeAttestation.timestamp.length > 0, 'tee attestation timestamp missing');\n assert(!Number.isNaN(Date.parse(teeAttestation.timestamp)), 'tee attestation timestamp is invalid');\n assert(typeof teeAttestation.workload?.image_digest === 'string' && teeAttestation.workload.image_digest.length > 0, 'workload image digest missing');\n assert(typeof teeAttestation.verifier?.image_digest === 'string' && teeAttestation.verifier.image_digest.length > 0, 'verifier image digest missing');\n assert(typeof teeAttestation.attestation?.token === 'string' && teeAttestation.attestation.token.length > 0, 'attestation token missing');\n}\n\nasync function computeDigestBinding(teeAttestation: TeeAttestation): Promise<string> {\n const proofVersion = getProofVersion(teeAttestation);\n\n if (proofVersion === 'v3') {\n assert(typeof teeAttestation.workload.container_name === 'string' && teeAttestation.workload.container_name.length > 0, 'workload container name missing');\n assert(typeof teeAttestation.verifier.container_name === 'string' && teeAttestation.verifier.container_name.length > 0, 'verifier container name missing');\n\n return sha256Hex([\n 'v3',\n `workload.container_name=${teeAttestation.workload.container_name}`,\n `workload.image_digest=${teeAttestation.workload.image_digest}`,\n `verifier.container_name=${teeAttestation.verifier.container_name}`,\n `verifier.image_digest=${teeAttestation.verifier.image_digest}`,\n ].join('\\n'));\n }\n\n return sha256Hex(\n `${teeAttestation.workload.image_digest}\\n${teeAttestation.verifier.image_digest}`\n );\n}\n\nasync function verifyGcpClaims(teeAttestation: TeeAttestation, expectedNonce: string) {\n const claims = await verifyJwtSignature(teeAttestation.attestation.token, GCP_CONFIDENTIAL_SPACE_ISSUER);\n\n assert(claims.iss === GCP_CONFIDENTIAL_SPACE_ISSUER, `unexpected issuer: ${claims.iss}`);\n assertAudienceClaim(claims.aud);\n assert(Array.isArray(claims.eat_nonce), 'eat_nonce claim missing');\n\n const digestBinding = await computeDigestBinding(teeAttestation);\n\n assert(claims.eat_nonce.includes(expectedNonce), 'request nonce is not present in attestation token');\n assert(claims.eat_nonce.includes(digestBinding), 'digest-binding nonce is not present in attestation token');\n assert(claims.hwmodel === EXPECTED_HW_MODEL, `unexpected hwmodel: ${claims.hwmodel}`);\n assert(claims.secboot === true, 'secure boot claim is not true');\n assert(claims.submods?.gce, 'gce submod claim missing');\n\n assertTokenFresh(claims);\n}\n\n/**\n * Validates the hardware TEE attestation included in the proof.\n * Derives the application ID from `appSecret` and verifies the attestation\n * was generated for your application.\n * Returns a result object with `isVerified` and an optional `error` message.\n *\n * This check is stateless and does not protect against replay of a previously\n * valid proof. Callers must enforce session matching and dedup `sessionId` on\n * their server. See the README's \"Replay Protection\" section.\n *\n * @param proof - The proof containing TEE attestation data\n * @param appSecret - Your application secret (Ethereum private key). Used to\n * derive the application ID and recompute the attestation nonce.\n */\nexport async function verifyTeeAttestation(\n proof: Proof,\n appSecret: string\n): Promise<TeeVerificationResult> {\n assertNonBrowserEnvironment();\n\n try {\n const appId = new ethers.Wallet(appSecret).address;\n\n let teeAttestation = proof.teeAttestation;\n if (!teeAttestation) {\n throw new Error('Missing teeAttestation in proof');\n }\n\n if (typeof teeAttestation === 'string') {\n teeAttestation = JSON.parse(teeAttestation) as TeeAttestation;\n }\n\n assertProofShape(teeAttestation);\n\n const { parsedContext, nonceDataObj, expectedNonce } = parseProofContext(proof);\n verifyApplicationAndSessionBinding(proof, parsedContext, nonceDataObj, appId);\n verifyNonceMaterial(expectedNonce, nonceDataObj, appSecret);\n\n const cleanExpectedNonce = normalizeHex(expectedNonce);\n const cleanTeeNonce = normalizeHex(teeAttestation.nonce);\n assert(cleanTeeNonce.length > 0, 'TEE attestation nonce is empty');\n assert(isHex(cleanTeeNonce), 'TEE attestation nonce is not valid hex');\n assert(cleanTeeNonce === cleanExpectedNonce, `Nonce Mismatch! Expected ${cleanExpectedNonce}, got ${cleanTeeNonce}`);\n\n await verifyGcpClaims(teeAttestation, cleanExpectedNonce);\n\n return { isVerified: true };\n } catch (error) {\n logger.error('TEE attestation verification failed:', error);\n return {\n isVerified: false,\n error: error instanceof Error ? error.message : String(error),\n };\n }\n}\n\n/**\n * Verifies TEE attestation for all proofs.\n * Throws `TeeVerificationError` if any proof is missing TEE data or fails verification.\n *\n * @param proofs - The proofs to verify\n * @param config - TEE attestation configuration containing the app secret\n * @throws {TeeVerificationError} When TEE data is missing or verification fails\n */\nexport async function runTeeVerification(proofs: Proof[], config: TeeAttestationConfig): Promise<void> {\n const hasTeeData = proofs.every(proof => {\n if (proof.teeAttestation) return true;\n try {\n const context = JSON.parse(proof.claimData.context);\n return !!context?.attestationNonce;\n } catch {\n return false;\n }\n });\n\n if (!hasTeeData) {\n throw new TeeVerificationError('TEE verification requested but one or more proofs are missing TEE attestation data');\n }\n\n const teeResults = await Promise.all(\n proofs.map(proof => verifyTeeAttestation(proof, config.appSecret))\n );\n\n if (!teeResults.every(r => r.isVerified)) {\n throw new TeeVerificationError('TEE attestation verification failed for one or more proofs');\n }\n}\n","import crypto, { X509Certificate } from 'crypto';\nimport { ethers } from 'ethers';\nimport { createSignDataForClaim } from '../witness';\nimport {\n ATTESTOR_NONCE_PATTERN,\n GCP_CONFIDENTIAL_SPACE_ISSUER,\n GCP_CONFIDENTIAL_SPACE_ROOT_CA,\n} from './constants';\nimport { AttestorTeeVerificationError } from './errors';\nimport type { AttestorClaimAttestation, Proof } from './interfaces';\nimport loggerModule from './logger';\n\nconst logger = loggerModule.logger;\n\nconst BROWSER_ENVIRONMENT_ERROR =\n 'Attestor TEE attestation verification is only supported in non-browser environments. Run verifyAttestorTeeAttestation on your server or API route.';\n\nfunction isBrowserEnvironment(): boolean {\n if (typeof window !== 'undefined' || typeof document !== 'undefined') {\n return true;\n }\n if (typeof navigator !== 'undefined' && typeof process === 'undefined') {\n return true;\n }\n const workerGlobalScope = (globalThis as any).WorkerGlobalScope;\n if (\n typeof workerGlobalScope !== 'undefined' &&\n typeof self !== 'undefined' &&\n self instanceof workerGlobalScope\n ) {\n return true;\n }\n return false;\n}\n\nfunction assertNonBrowserEnvironment() {\n if (isBrowserEnvironment()) {\n throw new Error(BROWSER_ENVIRONMENT_ERROR);\n }\n}\n\n/**\n * Result of verifying an attestor TEE attestation.\n */\nexport type AttestorTeeVerificationResult = {\n isVerified: boolean;\n error?: string;\n /** sha256 image digest of the attestor container, on success. */\n imageDigest?: string;\n};\n\nconst TOKEN_CLOCK_SKEW_S = 60;\n\nfunction decodeBase64Url(input: string): Buffer {\n const normalized = input.replace(/-/g, '+').replace(/_/g, '/');\n const padded = normalized + '='.repeat((4 - (normalized.length % 4)) % 4);\n return Buffer.from(padded, 'base64');\n}\n\nfunction normalizeAddress(address: string): string {\n return address.trim().toLowerCase().replace(/^0x/, '');\n}\n\n/**\n * Walks the x5c certificate chain (leaf first) and verifies each link\n * up to the pinned GCP Confidential Space Root CA. Returns the leaf\n * certificate's public key on success.\n */\nfunction verifyX5cChain(x5cChain: string[]): crypto.KeyObject {\n if (!x5cChain || x5cChain.length === 0) {\n throw new Error('Empty x5c certificate chain');\n }\n\n const certs = x5cChain.map(\n (b64) => new X509Certificate(`-----BEGIN CERTIFICATE-----\\n${b64}\\n-----END CERTIFICATE-----`)\n );\n const root = new X509Certificate(GCP_CONFIDENTIAL_SPACE_ROOT_CA);\n\n for (let i = 0; i < certs.length - 1; i++) {\n if (!certs[i].verify(certs[i + 1].publicKey)) {\n throw new Error(`Certificate chain verification failed at level ${i}`);\n }\n }\n\n const top = certs[certs.length - 1];\n if (!top.verify(root.publicKey)) {\n throw new Error('Certificate chain does not root to GCP Confidential Space Root CA');\n }\n\n return certs[0].publicKey;\n}\n\n/**\n * Validates a GCP Confidential Space attestation JWT produced by an\n * attestor running in a Confidential Space VM, and asserts that the\n * attestation binds to the given attestor address.\n *\n * The attestor (running inside the TEE) calls the Confidential Space\n * launcher's attestation endpoint with two nonces:\n * - `attestor_public_key:<eth-address>` - binds to the signing key.\n * - `attestor_cert_hash:<sha256-hex>` - binds to the live TLS cert.\n *\n * This function only verifies the public-key nonce. The TLS cert hash\n * binding is informational and not checked here. Callers that need to\n * pin to a specific attestor image should compare the returned\n * `imageDigest` against a known-good value.\n *\n * The JWT signature is verified by walking the x5c certificate chain\n * to a pinned GCP Confidential Space Root CA. No outbound network\n * calls are made.\n *\n * Node-only (uses node:crypto). Mirrors the environment restriction in\n * the existing `verifyTeeAttestation` helper.\n *\n * @param report - the raw JWT string (header.payload.signature).\n * @param expectedAttestorAddress - hex ETH address (0x-prefixed or\n * unprefixed) that the attestation should be bound to.\n */\nexport async function verifyAttestorTeeAttestation(\n report: string,\n expectedAttestorAddress: string\n): Promise<AttestorTeeVerificationResult> {\n try {\n assertNonBrowserEnvironment();\n\n if (!report || typeof report !== 'string') {\n throw new Error('attestation report is empty or not a string');\n }\n if (!expectedAttestorAddress || typeof expectedAttestorAddress !== 'string') {\n throw new Error('expectedAttestorAddress is required');\n }\n\n const parts = report.split('.');\n if (parts.length !== 3) {\n throw new Error('attestation report is not a JWT (expected 3 parts)');\n }\n const [headerB64, payloadB64, signatureB64] = parts;\n\n const header = JSON.parse(decodeBase64Url(headerB64).toString('utf8'));\n const payload = JSON.parse(decodeBase64Url(payloadB64).toString('utf8'));\n\n if (header.alg !== 'RS256') {\n throw new Error(`unexpected signing algorithm: ${header.alg}`);\n }\n if (!Array.isArray(header.x5c) || header.x5c.length === 0) {\n throw new Error('attestation report is missing x5c certificate chain');\n }\n\n if (payload.iss !== GCP_CONFIDENTIAL_SPACE_ISSUER) {\n throw new Error(`unexpected issuer: ${payload.iss}`);\n }\n\n const now = Math.floor(Date.now() / 1000);\n if (typeof payload.nbf === 'number' && now + TOKEN_CLOCK_SKEW_S < payload.nbf) {\n throw new Error(`attestation not yet valid (nbf=${payload.nbf})`);\n }\n if (typeof payload.exp === 'number' && now - TOKEN_CLOCK_SKEW_S > payload.exp) {\n throw new Error(`attestation expired (exp=${payload.exp})`);\n }\n if (typeof payload.iat === 'number' && payload.iat > now + TOKEN_CLOCK_SKEW_S) {\n throw new Error(`attestation issued in future (iat=${payload.iat})`);\n }\n\n const publicKey = verifyX5cChain(header.x5c);\n\n const verifier = crypto.createVerify('RSA-SHA256');\n verifier.update(`${headerB64}.${payloadB64}`);\n if (!verifier.verify(publicKey, new Uint8Array(decodeBase64Url(signatureB64)))) {\n throw new Error('attestation signature verification failed');\n }\n\n if (!payload.eat_nonce) {\n throw new Error('eat_nonce claim is missing');\n }\n const nonces: string[] = Array.isArray(payload.eat_nonce)\n ? payload.eat_nonce\n : [payload.eat_nonce];\n\n let attestedAddress: string | undefined;\n for (const n of nonces) {\n const m = typeof n === 'string' ? n.match(ATTESTOR_NONCE_PATTERN) : null;\n if (m) {\n attestedAddress = m[1];\n break;\n }\n }\n if (!attestedAddress) {\n throw new Error(\n `attestor_public_key nonce not found in eat_nonce: ${JSON.stringify(payload.eat_nonce)}`\n );\n }\n\n if (normalizeAddress(attestedAddress) !== normalizeAddress(expectedAttestorAddress)) {\n throw new Error(\n `attestor address mismatch: attestation binds to 0x${attestedAddress.toLowerCase()}, ` +\n `expected ${expectedAttestorAddress}`\n );\n }\n\n const imageDigest: string | undefined =\n payload.submods?.container?.image_digest\n ?? payload.google?.compute_engine?.image_digest;\n\n return { isVerified: true, imageDigest };\n } catch (error) {\n return {\n isVerified: false,\n error: error instanceof Error ? error.message : String(error),\n };\n }\n}\n\n/**\n * Configuration for verifying the attestor's TEE attestation on each\n * witness of the proof.\n */\nexport type AttestorTeeAttestationConfig = {\n /**\n * Optional allowlist of expected attestor container image digests\n * (e.g. `\"sha256:4906340f...\"`). When provided, the attestation's\n * `submods.container.image_digest` must be in this list.\n *\n * Leave undefined to skip image pinning and rely solely on the JWT\n * chain rooting to the GCP Confidential Space Root CA + nonce\n * binding to the attestor address.\n */\n expectedImageDigests?: string[];\n};\n\nfunction normalizeAttestorAddress(address: string): string {\n return address.trim().toLowerCase();\n}\n\nfunction normalizeSignature(sig: string): string {\n return sig.trim().toLowerCase();\n}\n\nasync function verifyAttestorTeeForProof(\n proof: Proof,\n config: AttestorTeeAttestationConfig\n): Promise<void> {\n if (!proof.witnesses || proof.witnesses.length === 0) {\n throw new AttestorTeeVerificationError('Proof has no witnesses');\n }\n\n const expectedDigests = config.expectedImageDigests?.map(d => d.trim());\n\n const proofSignatures = new Set((proof.signatures || []).map(normalizeSignature));\n const claimSignData = createSignDataForClaim(proof.claimData);\n\n for (const witness of proof.witnesses) {\n const att: AttestorClaimAttestation | undefined = witness.claimAttestation;\n if (!att) {\n throw new AttestorTeeVerificationError(\n `Witness ${witness.id} is missing claimAttestation`\n );\n }\n\n if (normalizeAttestorAddress(att.attestor_address) !== normalizeAttestorAddress(witness.id)) {\n throw new AttestorTeeVerificationError(\n `claimAttestation.attestor_address ${att.attestor_address} does not match witness id ${witness.id}`\n );\n }\n\n if (!proofSignatures.has(normalizeSignature(att.claim_signature))) {\n throw new AttestorTeeVerificationError(\n `claimAttestation.claim_signature for witness ${witness.id} is not present in proof.signatures`\n );\n }\n\n let recoveredSigner: string;\n try {\n recoveredSigner = ethers.verifyMessage(claimSignData, att.claim_signature);\n } catch (error) {\n throw new AttestorTeeVerificationError(\n `Failed to recover signer from claimAttestation.claim_signature for witness ${witness.id}`,\n error\n );\n }\n if (normalizeAttestorAddress(recoveredSigner) !== normalizeAttestorAddress(witness.id)) {\n throw new AttestorTeeVerificationError(\n `claim_signature recovers to ${recoveredSigner}, expected attestor ${witness.id}`\n );\n }\n\n const result = await verifyAttestorTeeAttestation(att.attestation_report, witness.id);\n if (!result.isVerified) {\n throw new AttestorTeeVerificationError(\n `Attestor TEE attestation verification failed for witness ${witness.id}: ${result.error}`\n );\n }\n\n if (expectedDigests && expectedDigests.length > 0) {\n if (!result.imageDigest) {\n throw new AttestorTeeVerificationError(\n `Attestor TEE attestation for witness ${witness.id} did not expose an image digest to check against expectedImageDigests`\n );\n }\n if (!expectedDigests.includes(result.imageDigest)) {\n throw new AttestorTeeVerificationError(\n `Attestor image digest ${result.imageDigest} for witness ${witness.id} is not in expectedImageDigests`\n );\n }\n }\n }\n}\n\n/**\n * Verifies the attestor's TEE attestation for every witness of every\n * provided proof. Throws `AttestorTeeVerificationError` on the first\n * failure.\n *\n * Each witness must carry a `claimAttestation`. For each one, this:\n * 1. Asserts `attestor_address` matches `witness.id`.\n * 2. Asserts `claim_signature` is present in `proof.signatures`.\n * 3. Recovers the signer of `claim_signature` from the claim data and\n * asserts it equals `witness.id` (binds the signature to the\n * attestor that the TEE attestation will cover).\n * 4. Calls `verifyAttestorTeeAttestation` to validate the JWT against\n * the pinned GCP Confidential Space Root CA and the attestor-key\n * nonce.\n * 5. If `expectedImageDigests` is provided, asserts the attestation's\n * container image digest is in the allowlist.\n *\n * Node-only (uses node:crypto), like `verifyTeeAttestation`.\n *\n * @param proofs - The proofs to verify.\n * @param config - Optional config; see {@link AttestorTeeAttestationConfig}.\n */\nexport async function runAttestorTeeVerification(\n proofs: Proof[],\n config: AttestorTeeAttestationConfig = {}\n): Promise<void> {\n if (!proofs || proofs.length === 0) {\n throw new AttestorTeeVerificationError('No proofs provided for attestor TEE verification');\n }\n\n try {\n for (const proof of proofs) {\n await verifyAttestorTeeForProof(proof, config);\n }\n } catch (error) {\n logger.error('Attestor TEE attestation verification failed:', error);\n if (error instanceof AttestorTeeVerificationError) {\n throw error;\n }\n throw new AttestorTeeVerificationError(\n 'Attestor TEE attestation verification failed',\n error\n );\n }\n}\n","import { ethers } from 'ethers';\nimport canonicalize from 'canonicalize';\nimport { SignatureGeneratingError } from './errors';\nimport { validateFunctionParams } from './validationUtils';\n\n/**\n * Computes the signature required by `initSession` over `{providerId, timestamp}`.\n *\n * Use this on a trusted server (where `appSecret` lives) to produce a signature\n * that can then be passed to `ReclaimProofRequest.initWithSignature(...)` from a\n * client that never sees the secret.\n *\n * @param appSecret - The application secret (private key). Must remain server-side.\n * @param providerId - The provider id the session will be initialized against.\n * @param timestamp - The timestamp (ms epoch as string) that will be sent with init.\n * The same value MUST be passed to `initWithSignature`.\n */\nexport async function generateInitSignature(\n appSecret: string,\n providerId: string,\n timestamp: string\n): Promise<string> {\n validateFunctionParams([\n { input: appSecret, paramName: 'appSecret', isString: true },\n { input: providerId, paramName: 'providerId', isString: true },\n { input: timestamp, paramName: 'timestamp', isString: true }\n ], 'generateInitSignature');\n\n try {\n const wallet = new ethers.Wallet(appSecret);\n const canonicalData = canonicalize({ providerId, timestamp });\n if (!canonicalData) {\n throw new SignatureGeneratingError('Failed to canonicalize data for signing.');\n }\n const messageHash = ethers.keccak256(new TextEncoder().encode(canonicalData));\n return await wallet.signMessage(ethers.getBytes(messageHash));\n } catch (err) {\n throw new SignatureGeneratingError(\n `Error generating init signature for providerId: ${providerId}`,\n err\n );\n }\n}\n"],"mappings":"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","names":["exports","module","import_ethers","import_canonicalize","import_canonicalize","canonicalize","logger","canonicalize","logger","logger","fetchRetry","logger","import_ethers","import_ethers","logger","logger","QRCode","import_ethers","logger","logger","import_ethers","logger","import_ethers","logger","BROWSER_ENVIRONMENT_ERROR","isBrowserEnvironment","assertNonBrowserEnvironment","TOKEN_CLOCK_SKEW_S","decodeBase64Url","crypto","logger","sdkVersion","canonicalize","_a","import_ethers","import_canonicalize","canonicalize"]}
|
|
1
|
+
{"version":3,"sources":["../package.json","../src/index.ts","../src/utils/interfaces.ts","../src/Reclaim.ts","../src/utils/errors.ts","../src/utils/logger.ts","../src/utils/validationUtils.ts","../src/utils/strings.ts","../src/utils/helper.ts","../src/utils/constants.ts","../src/utils/fetch.ts","../src/utils/sessionUtils.ts","../src/utils/proofUtils.ts","../src/witness.ts","../src/utils/modalUtils.ts","../src/utils/device.ts","../src/utils/attestationNonce.ts","../src/utils/providerUtils.ts","../src/utils/proofValidationUtils.ts","../src/utils/verifyTee.ts","../src/utils/verifyAttestorTee.ts","../src/utils/signatureUtils.ts"],"sourcesContent":["{\n \"name\": \"@reclaimprotocol/js-sdk\",\n \"version\": \"5.5.0\",\n \"description\": \"Designed to request proofs from the Reclaim protocol and manage the flow of claims and witness interactions.\",\n \"main\": \"dist/index.js\",\n \"types\": \"dist/index.d.ts\",\n \"keywords\": [\n \"reclaim\",\n \"protocol\",\n \"blockchain\",\n \"proof\",\n \"verification\",\n \"identity\",\n \"claims\",\n \"witness\",\n \"sdk\",\n \"javascript\",\n \"typescript\",\n \"decentralized\",\n \"web3\"\n ],\n \"files\": [\n \"dist\"\n ],\n \"tsup\": {\n \"entry\": [\n \"src/index.ts\"\n ],\n \"splitting\": false,\n \"sourcemap\": true,\n \"clean\": true\n },\n \"scripts\": {\n \"build\": \"sh scripts/build.sh\",\n \"prepare\": \"npm run build\",\n \"release\": \"release-it\",\n \"test\": \"jest\",\n \"test:watch\": \"jest --watch\",\n \"test:coverage\": \"jest --coverage\",\n \"commitlint\": \"commitlint --edit\"\n },\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"https://github.com/reclaimprotocol/reclaim-js-sdk\"\n },\n \"author\": \"ali <ali@creatoros.co>\",\n \"license\": \"See License in <https://github.com/reclaimprotocol/.github/blob/main/LICENSE>\",\n \"bugs\": {\n \"url\": \"https://github.com/reclaimprotocol/reclaim-js-sdk/issues\"\n },\n \"homepage\": \"https://github.com/reclaimprotocol/reclaim-js-sdk/\",\n \"publishConfig\": {\n \"registry\": \"https://registry.npmjs.org/\",\n \"access\": \"public\"\n },\n \"release-it\": {\n \"git\": {\n \"commitMessage\": \"chore: release ${version}\",\n \"tagName\": \"v${version}\"\n },\n \"npm\": {\n \"publish\": true,\n \"tag\": \"latest\"\n },\n \"github\": {\n \"release\": true\n },\n \"plugins\": {\n \"@release-it/conventional-changelog\": {\n \"preset\": \"angular\"\n }\n }\n },\n \"devDependencies\": {\n \"@commitlint/cli\": \"^17.7.1\",\n \"@commitlint/config-conventional\": \"^17.7.0\",\n \"@release-it/conventional-changelog\": \"10.0.6\",\n \"@types/jest\": \"^30.0.0\",\n \"@types/node-forge\": \"^1.3.14\",\n \"@types/qrcode\": \"^1.5.5\",\n \"@types/qs\": \"^6.9.11\",\n \"@types/url-parse\": \"^1.4.11\",\n \"@types/uuid\": \"^9.0.7\",\n \"jest\": \"^30.1.3\",\n \"jest-environment-jsdom\": \"^30.1.2\",\n \"qs\": \"^6.11.2\",\n \"release-it\": \"^19.2.4\",\n \"ts-jest\": \"^29.4.1\",\n \"tsup\": \"^8.0.1\",\n \"typescript\": \"^5.3.3\"\n },\n \"dependencies\": {\n \"canonicalize\": \"^2.0.0\",\n \"ethers\": \"^6.9.1\",\n \"fetch-retry\": \"^6.0.0\",\n \"node-forge\": \"^1.3.3\",\n \"qrcode\": \"^1.5.4\",\n \"url-parse\": \"^1.5.10\",\n \"uuid\": \"^9.0.1\"\n },\n \"overrides\": {\n \"@conventional-changelog/git-client\": \"^2.0.0\"\n }\n}","export * from './Reclaim';\nexport type * from './utils/interfaces';\nexport type * from './utils/types';\nexport * from './utils/proofUtils';\nexport type * from './utils/proofUtils';\nexport * from './utils/proofValidationUtils';\nexport type * from './utils/proofValidationUtils';\nexport * from './utils/providerUtils';\nexport type * from './utils/providerUtils';\nexport * from './utils/sessionUtils';\nexport type * from './utils/sessionUtils';\nexport { generateInitSignature } from './utils/signatureUtils';\nexport { generateAttestationNonce } from './utils/attestationNonce';\nexport * from './witness';\nexport type * from './witness';\nexport { verifyTeeAttestation, runTeeVerification } from './utils/verifyTee';\nexport type { TeeVerificationResult } from './utils/verifyTee';\nexport { verifyAttestorTeeAttestation } from './utils/verifyAttestorTee';\nexport type { AttestorTeeVerificationResult } from './utils/verifyAttestorTee';\nexport { TeeVerificationError } from './utils/errors';\n// Export device detection utilities for debugging (optional)\nexport {\n getDeviceType,\n getMobileDeviceType,\n isMobileDevice,\n isDesktopDevice,\n clearDeviceCache\n} from './utils/device';\n","export const SUPPORTED_TEE_ATTESTATION_VERSIONS = ['v2', 'v3'] as const;\n\nexport type TeeAttestationVersion = typeof SUPPORTED_TEE_ATTESTATION_VERSIONS[number];\n\nexport interface TeeAttestation {\n proof_version: TeeAttestationVersion;\n tee_provider: string;\n tee_technology: string;\n nonce: string;\n timestamp: string;\n workload: {\n container_name: string;\n image_digest: string;\n };\n verifier: {\n container_name: string;\n image_digest: string;\n };\n attestation: {\n token: string;\n };\n error?: {\n code: string;\n message: string;\n };\n}\n\n// Proof-related interfaces\nexport interface Proof {\n identifier: string;\n claimData: ProviderClaimData;\n signatures: string[];\n witnesses: WitnessData[];\n extractedParameterValues: any;\n /**\n * A JSON serializable object that is returned by the provider as additional data attached to proof.\n * This data is not verified or validated.\n */\n publicData?: any;\n taskId?: number;\n teeAttestation?: TeeAttestation;\n}\n\n// Extension Interactions\nexport const RECLAIM_EXTENSION_ACTIONS = {\n CHECK_EXTENSION: 'RECLAIM_EXTENSION_CHECK',\n EXTENSION_RESPONSE: 'RECLAIM_EXTENSION_RESPONSE',\n START_VERIFICATION: 'RECLAIM_START_VERIFICATION',\n STATUS_UPDATE: 'RECLAIM_STATUS_UPDATE',\n};\n\nexport interface ExtensionMessage {\n action: string;\n messageId: string;\n data?: any;\n extensionID?: string;\n}\n\nexport interface WitnessData {\n id: string;\n url: string;\n claimAttestation?: AttestorClaimAttestation;\n}\n\n/**\n * Attestation produced by an attestor running inside a Trusted Execution\n * Environment. Binds the attestor's signing key (and its signature over\n * the claim) to a hardware-backed enclave identity.\n *\n * Verified by `runAttestorTeeVerification`.\n */\nexport interface AttestorClaimAttestation {\n /** ETH address of the attestor whose enclave produced the attestation. Matches `WitnessData.id`. */\n attestor_address: string;\n /** Attestor signature over the claim. Must equal the corresponding entry in `Proof.signatures`. */\n claim_signature: string;\n /** Raw attestation report. For GCP Confidential Space, a JWT (header.payload.signature). */\n attestation_report: string;\n}\n\nexport interface ProviderClaimData {\n provider: string;\n parameters: string;\n owner: string;\n timestampS: number;\n context: string;\n identifier: string;\n epoch: number;\n}\n\n// Context and Beacon interfaces\nexport interface Context {\n contextAddress: string;\n contextMessage: string;\n reclaimSessionId: string;\n extractedParameters?: Record<string, string>;\n providerHash?: string;\n attestationNonce?: string;\n attestationNonceData?: {\n applicationId: string;\n sessionId: string;\n timestamp: string;\n attestationVersion?: TeeAttestationVersion;\n };\n}\n\nexport interface Beacon {\n getState(epoch?: number): Promise<BeaconState>;\n close?(): Promise<void>;\n}\n\nexport type BeaconState = {\n witnesses: WitnessData[];\n epoch: number;\n witnessesRequiredForClaim: number;\n nextEpochTimestampS: number;\n};\n\n/**\n * Information of the exact provider and its version used in the verification session.\n * \n * See also:\n * \n * * `ReclaimProofRequest.getProviderVersion()` - With a ReclaimProofRequest object, you can get the provider id & exact version of provider used in verification session.\n */\nexport interface ProviderVersionInfo {\n /**\n * The identifier of provider used in verifications that resulted in a proof\n * \n * See also:\n * \n * * `ReclaimProofRequest.getProviderVersion()` - With a ReclaimProofRequest object, you can get the provider id & exact version of provider used in verification session.\n */\n providerId: string;\n /**\n * The exact version of provider used in verifications that resulted in a proof.\n * \n * This cannot be a version constaint or version expression.\n * \n * See also:\n * \n * * `ReclaimProofRequest.getProviderVersion()` - With a ReclaimProofRequest object, you can get the provider id & exact version of provider used in verification session.\n */\n providerVersion: string;\n /**\n * List of allowed pre-release tags.\n * For example, if you are using AI, provide `['ai']` to allow AI patch versions of the provider.\n */\n allowedTags: string[];\n}\n","import {\n type Proof,\n type Context,\n RECLAIM_EXTENSION_ACTIONS,\n ExtensionMessage,\n ProviderVersionInfo,\n} from './utils/interfaces'\nimport {\n ProofRequestOptions,\n StartSessionParams,\n ProofPropertiesJSON,\n TemplateData,\n InitSessionResponse,\n ClaimCreationType,\n ModalOptions,\n ReclaimFlowLaunchOptions,\n type FlowHandle,\n HttpFormEntry,\n HttpRedirectionMethod,\n type VerifyProofResult,\n} from './utils/types'\nimport { SessionStatus, DeviceType } from './utils/types'\nimport { ethers } from 'ethers'\nimport canonicalize from 'canonicalize'\nimport {\n createVerifyProofResultSuccess,\n createVerifyProofResultFailure,\n replaceAll,\n scheduleIntervalEndingTask\n} from './utils/helper'\nimport { constants, setBackendBaseUrl } from './utils/constants'\nimport {\n SetContextError,\n GetAppCallbackUrlError,\n GetStatusUrlError,\n InitError,\n InvalidParamError,\n ProofNotVerifiedError,\n ProofSubmissionFailedError,\n ProviderFailedError,\n SessionNotStartedError,\n SetParamsError,\n SetSignatureError,\n SignatureGeneratingError,\n SignatureNotFoundError,\n ErrorDuringVerificationError,\n CallbackUrlRequiredError,\n ProofNotValidatedError,\n} from './utils/errors';\nimport { validateContext, validateFunctionParams, validateParameters, validateSignature, validateURL, validateModalOptions, validateFunctionParamsWithFn, validateRedirectionMethod, validateRedirectionBody } from './utils/validationUtils'\nimport { fetchStatusUrl, initSession, updateSession } from './utils/sessionUtils'\nimport { assertVerifiedProof, createLinkWithTemplateData, getAttestors } from './utils/proofUtils'\nimport { QRCodeModal } from './utils/modalUtils'\nimport loggerModule from './utils/logger';\nimport { getDeviceType, getMobileDeviceType } from './utils/device'\nimport { generateAttestationNonce } from './utils/attestationNonce'\nimport { canonicalStringify } from './utils/strings'\nimport { assertValidateProof, VerificationConfig } from './utils/proofValidationUtils'\nimport { runTeeVerification } from './utils/verifyTee'\nimport { runAttestorTeeVerification } from './utils/verifyAttestorTee'\nimport { fetchProviderHashRequirementsBy, ProviderHashRequirementsConfig } from './utils/providerUtils'\n\nconst logger = loggerModule.logger\n\nconst sdkVersion = require('../package.json').version;\nconst SDK_TEE_ATTESTATION_VERSION = 'v3' as const;\n\n/**\n * Verifies one or more Reclaim proofs by validating signatures, verifying witness information,\n * and performing content validation against the expected configuration.\n *\n * See also:\n *\n * * `ReclaimProofRequest.getProviderHashRequirements()` - To get the expected proof hash requirements for a proof request.\n * * `fetchProviderHashRequirementsBy()` - To get the expected proof hash requirements for a provider version by providing providerId and exactProviderVersionString.\n * * `getProviderHashRequirementsFromSpec()` - To get the expected proof hash requirements from a provider spec.\n * * All 3 functions above are alternatives of each other and result from these functions can be directly used as `config` parameter in this function for proof validation.\n *\n * Replay protection: this function is stateless. It verifies that a proof is cryptographically\n * bound to a specific `sessionId`/`applicationId` (via the `appSecret`-keyed attestation nonce\n * when `teeAttestation` is provided) but does not track which proofs have already been\n * verified. Callers must (a) verify the proof's `sessionId` matches a session they initiated\n * and (b) persist accepted `sessionId`s and reject duplicates. See the README's\n * \"Replay Protection\" section for details.\n *\n * @param proofOrProofs - A single proof object or an array of proof objects to be verified.\n * @param config - Verification configuration that specifies required hashes, allowed extra hashes, or disables content validation. Optionally includes `teeAttestation` to require TEE attestation verification.\n * @returns Verification result with `isVerified`, `isTeeAttestationVerified` (always boolean), extracted `data` from each proof, and optional `error` on failure. The application ID is derived from `appSecret` automatically.\n *\n * @example\n * ```typescript\n * // Fast and simple automatically fetched verification\n * const { isVerified, data } = await verifyProof(proof, request.getProviderVersion());\n *\n * // With TEE attestation verification (fails if TEE data is missing or invalid)\n * const { isVerified, isTeeAttestationVerified, data } = await verifyProof(proof, { ...request.getProviderVersion(), teeAttestation: { appSecret: APP_SECRET } });\n * \n * // Or, by manually providing the details:\n * \n * const { isVerified, data } = await verifyProof(proof, { \n * providerId: \"YOUR_PROVIDER_ID\", \n * // The exact provider version used in the session.\n * providerVersion: \"1.0.0\",\n * // Optionally provide tags. For example, this can be `['ai']` when you want to allow patches from ai.\n * allowedTags: [\"ai\"]\n * });\n * \n * // Validate a single proof against expected hash\n * const { isVerified, data } = await verifyProof(proof, { hashes: ['0xAbC...'] });\n * if (isVerified) {\n * console.log(data[0].context);\n * console.log(data[0].extractedParameters);\n * }\n *\n * // Validate multiple proofs\n * const { isVerified, data } = await verifyProof([proof1, proof2], {\n * hashes: ['0xAbC...', '0xF22..'],\n * });\n * \n * // Validate multiple proofs and handle optional matches or repeated proofs\n * const { isVerified, data } = await verifyProof([proof1, proof2, sameAsProof2], { \n * hashes: [\n * // A string hash is perfectly equivalent to { value: '...', required: true, multiple: true }\n * '0xStrict1...', \n * // An array 'value' means 1 proof can have any 1 matching hash from this list.\n * // 'multiple: true' (the default) means any proof matching this hash is allowed to appear multiple times in the list of proofs.\n * { value: ['0xOpt1..', '0xOpt2..'], multiple: true }, \n * // 'required: false' means there can be 0 proofs matching this hash. Such proofs may be optionally present. (Defaults to true).\n * { value: '0xE33..', required: false }\n * ],\n * });\n * ```\n */\nexport async function verifyProof(\n proofOrProofs: Proof | Proof[],\n config: VerificationConfig,\n): Promise<VerifyProofResult> {\n const proofs = Array.isArray(proofOrProofs) ? proofOrProofs : [proofOrProofs];\n try {\n if (proofs.length === 0) {\n throw new ProofNotValidatedError('No proofs provided');\n }\n\n if (!config) {\n throw new ProofNotValidatedError('Verification configuration is required for `verifyProof(proof, config)`');\n }\n\n const attestors = await getAttestors()\n for (const proof of proofs) {\n await assertVerifiedProof(proof, attestors)\n }\n\n await assertValidateProof(proofs, config);\n\n let isTeeAttestationVerified: boolean | undefined;\n let isAttestorTeeAttestationVerified: boolean | undefined;\n\n if (config.teeAttestation && 'dangerouslyDisableContentValidation' in config && config.dangerouslyDisableContentValidation) {\n logger.warn('teeAttestation is enabled but content validation is disabled — TEE attestation alone does not guarantee proof contents are valid');\n }\n\n if (config.teeAttestation) {\n await runTeeVerification(proofs, config.teeAttestation);\n isTeeAttestationVerified = true;\n }\n\n if (config.attestorTeeAttestation) {\n await runAttestorTeeVerification(proofs, config.attestorTeeAttestation);\n isAttestorTeeAttestationVerified = true;\n }\n\n return createVerifyProofResultSuccess(proofs, isTeeAttestationVerified, isAttestorTeeAttestationVerified);\n } catch (error) {\n logger.error('Error in validating proof:', error);\n const _error = error instanceof Error ? error : new Error(String(error));\n return createVerifyProofResultFailure(_error);\n }\n}\n\n/**\n * Transforms a Reclaim proof into a format suitable for on-chain verification\n *\n * @param proof - The proof object to transform\n * @returns Object containing claimInfo and signedClaim formatted for blockchain contracts\n *\n * @example\n * ```typescript\n * const { claimInfo, signedClaim } = transformForOnchain(proof);\n * // Use claimInfo and signedClaim with smart contract verification\n * ```\n */\nexport function transformForOnchain(proof: Proof): { claimInfo: any, signedClaim: any } {\n const claimInfoBuilder = new Map([\n ['context', proof.claimData.context],\n ['parameters', proof.claimData.parameters],\n ['provider', proof.claimData.provider],\n ]);\n const claimInfo = Object.fromEntries(claimInfoBuilder);\n const claimBuilder = new Map<string, number | string>([\n ['epoch', proof.claimData.epoch],\n ['identifier', proof.claimData.identifier],\n ['owner', proof.claimData.owner],\n ['timestampS', proof.claimData.timestampS],\n ]);\n const signedClaim = {\n claim: Object.fromEntries(claimBuilder),\n signatures: proof.signatures,\n };\n return { claimInfo, signedClaim };\n}\n\n// create a empty template data object to assign to templateData\nconst emptyTemplateData: TemplateData = {\n sessionId: '',\n providerId: '',\n applicationId: '',\n signature: '',\n timestamp: '',\n callbackUrl: '',\n context: '',\n parameters: {},\n redirectUrl: '',\n redirectUrlOptions: { method: 'GET' },\n cancelCallbackUrl: '',\n cancelRedirectUrl: '',\n cancelRedirectUrlOptions: { method: 'GET' },\n acceptAiProviders: false,\n sdkVersion: '',\n providerVersion: '',\n resolvedProviderVersion: '',\n jsonProofResponse: false,\n log: false\n}\nexport class ReclaimProofRequest {\n private applicationId: string;\n private signature?: string;\n private appCallbackUrl?: string;\n private sessionId: string;\n private options?: ProofRequestOptions;\n private context: Context = { contextAddress: '0x0', contextMessage: 'sample context', reclaimSessionId: '' };\n private attestationNonce?: string;\n private attestationNonceData?: Context['attestationNonceData'];\n private claimCreationType?: ClaimCreationType = ClaimCreationType.STANDALONE;\n private providerId: string;\n private resolvedProviderVersion?: string;\n private parameters: { [key: string]: string };\n private redirectUrl?: string;\n private redirectUrlOptions?: TemplateData['redirectUrlOptions'];\n private cancelCallbackUrl?: TemplateData['cancelCallbackUrl'];\n private cancelRedirectUrl?: TemplateData['cancelRedirectUrl'];\n private cancelRedirectUrlOptions?: TemplateData['cancelRedirectUrlOptions'];\n private intervals: Map<string, NodeJS.Timer> = new Map();\n private timeStamp: string;\n private sdkVersion: string;\n private jsonProofResponse: boolean = false;\n private lastFailureTime?: number;\n private templateData: TemplateData;\n private extensionID: string = \"reclaim-extension\";\n private customSharePageUrl?: string;\n private appSharePageUrl: string = constants.DEFAULT_APP_SHARE_PAGE_URL;\n private customAppClipUrl?: string;\n private portalTab?: Window | null;\n private portalIframe?: HTMLIFrameElement;\n private modalOptions?: ModalOptions;\n private modal?: QRCodeModal;\n private readonly FAILURE_TIMEOUT = 30 * 1000; // 30 seconds timeout, can be adjusted\n\n private constructor(applicationId: string, providerId: string, options?: ProofRequestOptions) {\n this.providerId = providerId;\n this.timeStamp = Date.now().toString();\n this.applicationId = applicationId;\n this.sessionId = \"\";\n // keep template data as empty object\n this.templateData = emptyTemplateData;\n this.parameters = {};\n\n if (!options) {\n options = {};\n }\n\n options.useBrowserExtension = options.useBrowserExtension ?? true;\n\n if (options?.log) {\n loggerModule.setLogLevel('info');\n } else {\n loggerModule.setLogLevel('silent');\n }\n\n if (options.useAppClip === undefined) {\n options.useAppClip = false;\n }\n\n // portalUrl is an alias for customSharePageUrl (portalUrl takes precedence)\n // When set, overrides both portal and app share page URLs\n const customUrl = options.portalUrl || options.customSharePageUrl;\n this.customSharePageUrl = customUrl || constants.DEFAULT_PORTAL_URL;\n if (customUrl && customUrl !== constants.DEFAULT_PORTAL_URL) {\n this.appSharePageUrl = customUrl;\n }\n options.customSharePageUrl = this.customSharePageUrl;\n\n if (options?.envUrl) {\n setBackendBaseUrl(options.envUrl);\n } else if (this.customSharePageUrl) {\n try {\n if (new URL(this.customSharePageUrl).hostname === 'eu.portal.reclaimprotocol.org') {\n setBackendBaseUrl('https://eu.api.reclaimprotocol.org');\n }\n } catch { /* invalid URL handled by validateURL in init */ }\n }\n\n if (options.extensionID) {\n this.extensionID = options.extensionID;\n }\n\n if (options?.customAppClipUrl) {\n this.customAppClipUrl = options.customAppClipUrl;\n }\n\n this.options = options;\n // Fetch sdk version from package.json\n this.sdkVersion = 'js-' + sdkVersion;\n logger.info(`Initializing client with applicationId: ${this.applicationId}`);\n }\n\n /**\n * Initializes a new Reclaim proof request instance with automatic signature generation and session creation.\n *\n * @param applicationId - Your Reclaim application ID\n * @param appSecret - Your application secret key for signing requests\n * @param providerId - The ID of the provider to use for proof generation\n * @param options - Optional configuration options for the proof request\n * @returns A fully initialized proof request instance\n * @throws {InitError} When initialization fails due to invalid parameters or session creation errors\n *\n * @example\n * ```typescript\n * const proofRequest = await ReclaimProofRequest.init(\n * 'your-app-id',\n * 'your-app-secret',\n * 'provider-id',\n * { portalUrl: 'https://portal.reclaimprotocol.org', log: true }\n * );\n * ```\n */\n static async init(applicationId: string, appSecret: string, providerId: string, options?: ProofRequestOptions): Promise<ReclaimProofRequest> {\n try {\n validateFunctionParams([\n { paramName: 'applicationId', input: applicationId, isString: true },\n { paramName: 'providerId', input: providerId, isString: true },\n { paramName: 'appSecret', input: appSecret, isString: true }\n ], 'the constructor')\n\n ReclaimProofRequest.validateInitOptions(options, 'the constructor')\n\n const proofRequestOptions = {\n ...options,\n acceptTeeAttestation: options?.acceptTeeAttestation ?? true\n };\n\n const proofRequestInstance = new ReclaimProofRequest(applicationId, providerId, proofRequestOptions)\n\n const signature = await proofRequestInstance.generateSignature(appSecret)\n proofRequestInstance.setSignature(signature)\n\n const data: InitSessionResponse = await initSession(providerId, applicationId, proofRequestInstance.timeStamp, signature, options?.providerVersion);\n proofRequestInstance.sessionId = data.sessionId\n proofRequestInstance.resolvedProviderVersion = data.resolvedProviderVersion\n proofRequestInstance.context.reclaimSessionId = data.sessionId\n\n if (proofRequestOptions.acceptTeeAttestation) {\n const attestationNonce = generateAttestationNonce(\n appSecret,\n applicationId,\n data.sessionId,\n proofRequestInstance.timeStamp\n )\n\n proofRequestInstance.setAttestationContext(attestationNonce, {\n applicationId,\n sessionId: data.sessionId,\n timestamp: proofRequestInstance.timeStamp,\n attestationVersion: SDK_TEE_ATTESTATION_VERSION\n })\n }\n\n return proofRequestInstance\n } catch (error) {\n console.error(error);\n logger.info('Failed to initialize ReclaimProofRequest', error as Error);\n throw new InitError('Failed to initialize ReclaimProofRequest', error as Error)\n }\n }\n\n /**\n * Initializes a new Reclaim proof request using a signature computed externally\n * (e.g. on a trusted backend), so `appSecret` never has to live on the client.\n *\n * The signature must be produced over `canonicalize({ providerId, timestamp })`\n * using the application's `appSecret` — see `generateInitSignature()` for the\n * exact algorithm. The same `timestamp` used at signing time must be passed here.\n *\n * TEE attestation: the attestation nonce depends on `sessionId`, which is only\n * known after the backend init call. To use TEE without exposing `appSecret`,\n * pass an async `getAttestationNonce` callback that derives the nonce on your\n * server using `generateAttestationNonce(appSecret, applicationId, sessionId, timestamp)`.\n * If `acceptTeeAttestation` is left enabled but no callback is provided, init throws.\n *\n * @param applicationId - Your Reclaim application ID\n * @param providerId - The ID of the provider to use for proof generation\n * @param sessionAuth - Pre-computed signature, the timestamp it was signed over,\n * and an optional async callback to compute the attestation nonce.\n * @param options - Optional configuration options for the proof request\n *\n * @example\n * ```typescript\n * // Backend (Node):\n * const timestamp = Date.now().toString();\n * const signature = await generateInitSignature(APP_SECRET, providerId, timestamp);\n * // ...return { signature, timestamp } to the client...\n *\n * // Client:\n * const proofRequest = await ReclaimProofRequest.initWithSignature(\n * applicationId,\n * providerId,\n * { signature, timestamp },\n * { acceptTeeAttestation: false }\n * );\n * ```\n */\n static async initWithSignature(\n applicationId: string,\n providerId: string,\n sessionAuth: {\n signature: string;\n timestamp: string;\n getAttestationNonce?: (sessionId: string) => Promise<string> | string;\n },\n options?: ProofRequestOptions\n ): Promise<ReclaimProofRequest> {\n try {\n validateFunctionParams([\n { paramName: 'applicationId', input: applicationId, isString: true },\n { paramName: 'providerId', input: providerId, isString: true },\n { paramName: 'signature', input: sessionAuth?.signature, isString: true },\n { paramName: 'timestamp', input: sessionAuth?.timestamp, isString: true }\n ], 'initWithSignature')\n\n ReclaimProofRequest.validateInitOptions(options, 'initWithSignature')\n\n const proofRequestOptions = {\n ...options,\n acceptTeeAttestation: options?.acceptTeeAttestation ?? true\n };\n\n if (proofRequestOptions.acceptTeeAttestation && !sessionAuth.getAttestationNonce) {\n throw new InvalidParamError(\n 'initWithSignature requires a `getAttestationNonce` callback when `acceptTeeAttestation` is enabled. ' +\n 'Either pass `acceptTeeAttestation: false`, or provide a callback that computes the nonce server-side ' +\n 'using `generateAttestationNonce(appSecret, applicationId, sessionId, timestamp)`.'\n )\n }\n\n const proofRequestInstance = new ReclaimProofRequest(applicationId, providerId, proofRequestOptions)\n proofRequestInstance.timeStamp = sessionAuth.timestamp\n proofRequestInstance.setSignature(sessionAuth.signature)\n\n const data: InitSessionResponse = await initSession(\n providerId,\n applicationId,\n sessionAuth.timestamp,\n sessionAuth.signature,\n options?.providerVersion\n );\n proofRequestInstance.sessionId = data.sessionId\n proofRequestInstance.resolvedProviderVersion = data.resolvedProviderVersion\n proofRequestInstance.context.reclaimSessionId = data.sessionId\n\n if (proofRequestOptions.acceptTeeAttestation && sessionAuth.getAttestationNonce) {\n const attestationNonce = await sessionAuth.getAttestationNonce(data.sessionId)\n validateFunctionParams(\n [{ input: attestationNonce, paramName: 'attestationNonce', isString: true }],\n 'initWithSignature'\n )\n proofRequestInstance.setAttestationContext(attestationNonce, {\n applicationId,\n sessionId: data.sessionId,\n timestamp: sessionAuth.timestamp,\n attestationVersion: SDK_TEE_ATTESTATION_VERSION\n })\n }\n\n return proofRequestInstance\n } catch (error) {\n console.error(error);\n logger.info('Failed to initialize ReclaimProofRequest with signature', error as Error);\n throw new InitError('Failed to initialize ReclaimProofRequest with signature', error as Error)\n }\n }\n\n /**\n * Creates a ReclaimProofRequest instance from a JSON string representation\n *\n * This method deserializes a previously exported proof request (via toJsonString) and reconstructs\n * the instance with all its properties. Useful for recreating requests on the frontend or across different contexts.\n *\n * @param jsonString - JSON string containing the serialized proof request data\n * @returns {Promise<ReclaimProofRequest>} - Reconstructed proof request instance\n * @throws {InvalidParamError} When JSON string is invalid or contains invalid parameters\n *\n * @example\n * ```typescript\n * const jsonString = proofRequest.toJsonString();\n * const reconstructed = await ReclaimProofRequest.fromJsonString(jsonString);\n * // Can also be used with InApp SDK's startVerificationFromJson method\n * ```\n */\n static async fromJsonString(jsonString: string): Promise<ReclaimProofRequest> {\n try {\n const {\n applicationId,\n providerId,\n sessionId,\n context,\n parameters,\n signature,\n redirectUrl,\n redirectUrlOptions,\n cancelCallbackUrl,\n cancelRedirectUrl,\n cancelRedirectUrlOptions,\n timeStamp,\n timestamp,\n appCallbackUrl,\n claimCreationType,\n options,\n sdkVersion,\n jsonProofResponse,\n resolvedProviderVersion,\n modalOptions\n }: ProofPropertiesJSON = JSON.parse(jsonString)\n\n // Prefer 'timestamp' over 'timeStamp' for backward compatibility (remove in future versions)\n const resolvedTimestamp = timestamp || timeStamp;\n\n validateFunctionParams([\n { input: applicationId, paramName: 'applicationId', isString: true },\n { input: providerId, paramName: 'providerId', isString: true },\n { input: signature, paramName: 'signature', isString: true },\n { input: sessionId, paramName: 'sessionId', isString: true },\n { input: resolvedTimestamp, paramName: 'timestamp', isString: true },\n { input: sdkVersion, paramName: 'sdkVersion', isString: true },\n ], 'fromJsonString');\n\n if (modalOptions) {\n validateModalOptions(modalOptions, 'fromJsonString', 'modalOptions.');\n }\n\n if (redirectUrl) {\n validateURL(redirectUrl, 'fromJsonString');\n }\n\n if (redirectUrlOptions) {\n validateRedirectionMethod(redirectUrlOptions.method, 'fromJsonString');\n validateRedirectionBody(redirectUrlOptions.body, 'fromJsonString');\n }\n\n if (appCallbackUrl) {\n validateURL(appCallbackUrl, 'fromJsonString');\n }\n\n if (cancelRedirectUrl) {\n validateURL(cancelRedirectUrl, 'fromJsonString');\n }\n\n if (cancelRedirectUrlOptions) {\n validateRedirectionMethod(cancelRedirectUrlOptions.method, 'fromJsonString');\n validateRedirectionBody(cancelRedirectUrlOptions.body, 'fromJsonString');\n }\n\n if (cancelCallbackUrl) {\n validateURL(cancelCallbackUrl, 'fromJsonString');\n }\n\n if (context) {\n validateContext(context);\n }\n\n if (parameters) {\n validateParameters(parameters);\n }\n\n if (claimCreationType) {\n validateFunctionParams([\n { input: claimCreationType, paramName: 'claimCreationType' }\n ], 'fromJsonString');\n }\n\n if (jsonProofResponse !== undefined) {\n validateFunctionParams([\n { input: jsonProofResponse, paramName: 'jsonProofResponse' }\n ], 'fromJsonString');\n }\n\n\n if (options?.providerVersion) {\n validateFunctionParams([\n { input: options.providerVersion, paramName: 'options.providerVersion', isString: true }\n ], 'fromJsonString');\n }\n\n if (resolvedProviderVersion) {\n validateFunctionParams([\n { input: resolvedProviderVersion, paramName: 'resolvedProviderVersion', isString: true }\n ], 'fromJsonString');\n }\n\n if (options?.preferredLocale) {\n validateFunctionParams([\n { paramName: 'options.preferredLocale', input: options.preferredLocale, isString: true }\n ], 'fromJsonString');\n validateFunctionParamsWithFn({\n paramName: 'options.preferredLocale', input: options.preferredLocale, isValid: () => {\n try {\n Intl.getCanonicalLocales(options.preferredLocale);\n return true;\n } catch (error) {\n logger.info('Failed to canonicalize locale', error);\n return false;\n }\n }\n }, 'fromJsonString');\n }\n const proofRequestInstance = new ReclaimProofRequest(applicationId, providerId, options);\n proofRequestInstance.sessionId = sessionId;\n proofRequestInstance.context = context;\n proofRequestInstance.setAttestationContext(context?.attestationNonce, context?.attestationNonceData);\n proofRequestInstance.parameters = parameters;\n proofRequestInstance.appCallbackUrl = appCallbackUrl;\n proofRequestInstance.redirectUrl = redirectUrl;\n proofRequestInstance.redirectUrlOptions = redirectUrlOptions;\n proofRequestInstance.timeStamp = resolvedTimestamp!\n proofRequestInstance.signature = signature\n proofRequestInstance.sdkVersion = sdkVersion;\n proofRequestInstance.resolvedProviderVersion = resolvedProviderVersion;\n proofRequestInstance.modalOptions = modalOptions;\n proofRequestInstance.jsonProofResponse = jsonProofResponse ?? false;\n proofRequestInstance.cancelCallbackUrl = cancelCallbackUrl;\n proofRequestInstance.cancelRedirectUrl = cancelRedirectUrl;\n proofRequestInstance.cancelRedirectUrlOptions = cancelRedirectUrlOptions;\n return proofRequestInstance\n } catch (error) {\n logger.info('Failed to parse JSON string in fromJsonString:', error);\n throw new InvalidParamError('Invalid JSON string provided to fromJsonString');\n }\n }\n\n /**\n * Sets a custom callback URL where proofs will be submitted via HTTP `POST`\n *\n * By default, proofs are sent as HTTP POST with `Content-Type` as `application/x-www-form-urlencoded`.\n * Pass function argument `jsonProofResponse` as `true` to send proofs with `Content-Type` as `application/json`.\n *\n * When a custom callback URL is set, proofs are sent to the custom URL *instead* of the Reclaim backend.\n * Consequently, the startSession `onSuccess` callback will be invoked with an empty array (`[]`)\n * instead of the proof data, as the proof is not available to the SDK in this flow.\n *\n * This verification session's id will be present in `X-Reclaim-Session-Id` header of the request.\n * The request URL will contain query param `allowAiWitness` with value `true` when AI Witness should be allowed by handler of the request.\n *\n * Note: InApp SDKs are unaffected by this property as they do not handle proof submission.\n *\n * @param url - The URL where proofs should be submitted via HTTP `POST`\n * @param jsonProofResponse - Optional. Set to true to submit proofs as `application/json`. Defaults to false\n * @throws {InvalidParamError} When URL is invalid\n *\n * @example\n * ```typescript\n * proofRequest.setAppCallbackUrl('https://your-backend.com/callback');\n * // Or with JSON format\n * proofRequest.setAppCallbackUrl('https://your-backend.com/callback', true);\n * ```\n */\n setAppCallbackUrl(url: string, jsonProofResponse?: boolean): void {\n validateURL(url, 'setAppCallbackUrl')\n this.appCallbackUrl = url\n this.jsonProofResponse = jsonProofResponse ?? false\n }\n\n /**\n * Sets a redirect URL where users will be redirected after successfully acquiring and submitting proof\n *\n * @param url - The URL where users should be redirected after successful proof generation\n * @param method - The redirection method that should be used for redirection. Allowed options: `GET`, and `POST`.\n * `POST` form redirection is only supported in Portal flow.\n * @param body - List of name-value pairs to be sent as the body of the form request.\n * `When `method` is set to `POST`, `body` will be sent with 'application/x-www-form-urlencoded' content type.\n * When `method` is set to `GET`, if `body` is set then `body` will be sent as query parameters.\n * Sending `body` on redirection is only supported in Portal flow.\n *\n * @throws {InvalidParamError} When URL is invalid\n *\n * @example\n * ```typescript\n * proofRequest.setRedirectUrl('https://your-app.com/success');\n * ```\n */\n setRedirectUrl(url: string, method: HttpRedirectionMethod = 'GET', body?: HttpFormEntry[] | undefined): void {\n validateURL(url, 'setRedirectUrl');\n validateRedirectionMethod(method, 'setRedirectUrl');\n validateRedirectionBody(body, 'setRedirectUrl');\n\n this.redirectUrl = url;\n this.redirectUrlOptions = { method: method || 'GET', body: body }\n }\n\n /**\n * Sets a custom callback URL where errors that abort the verification process will be submitted via HTTP POST\n *\n * Errors will be HTTP POSTed with `header 'Content-Type': 'application/json'`.\n * When a custom error callback URL is set, Reclaim will no longer receive errors upon submission,\n * and listeners on the startSession method will not be triggered. Your application must\n * coordinate with your backend to receive errors.\n *\n * This verification session's id will be present in `X-Reclaim-Session-Id` header of the request.\n *\n * Following is the data format which is sent as an HTTP POST request to the url with `Content-Type: application/json`:\n\n * ```json\n * {\n * \"type\": \"string\", // Name of the exception\n * \"message\": \"string\",\n * \"sessionId\": \"string\",\n * // context as canonicalized json string\n * \"context\": \"string\",\n * // Other fields with more details about error may be present\n * // [key: any]: any\n * }\n * ```\n *\n * For more details about response format, check out [official documentation of Error Callback URL](https://docs.reclaimprotocol.org/js-sdk/preparing-request#cancel-callback).\n *\n * @param url - The URL where errors should be submitted via HTTP POST\n * @throws {InvalidParamError} When URL is invalid\n *\n * @example\n * ```typescript\n * proofRequest.setCancelCallbackUrl('https://your-backend.com/error-callback');\n * ```\n *\n * @since 4.8.1\n *\n */\n setCancelCallbackUrl(url: string): void {\n validateURL(url, 'setCancelCallbackUrl')\n this.cancelCallbackUrl = url\n }\n\n /**\n * Sets an error redirect URL where users will be redirected after an error which aborts the verification process\n *\n * @param url - The URL where users should be redirected after an error which aborts the verification process\n * @param method - The redirection method that should be used for redirection. Allowed options: `GET`, and `POST`.\n * `POST` form redirection is only supported in Portal flow.\n * @param body - List of name-value pairs to be sent as the body of the form request.\n * When `method` is set to `POST`, `body` will be sent with 'application/x-www-form-urlencoded' content type.\n * When `method` is set to `GET`, if `body` is set then `body` will be sent as query parameters.\n * Sending `body` on redirection is only supported in Portal flow.\n * @throws {InvalidParamError} When URL is invalid\n *\n * @example\n * ```typescript\n * proofRequest.setCancelRedirectUrl('https://your-app.com/error');\n * ```\n *\n * @since 4.10.0\n *\n */\n setCancelRedirectUrl(url: string, method: HttpRedirectionMethod = 'GET', body?: HttpFormEntry[] | undefined): void {\n validateURL(url, 'setCancelRedirectUrl');\n validateRedirectionMethod(method, 'setCancelRedirectUrl');\n validateRedirectionBody(body, 'setCancelRedirectUrl');\n\n this.cancelRedirectUrl = url;\n this.cancelRedirectUrlOptions = { method: method || 'GET', body: body }\n }\n\n /**\n * Sets the claim creation type for the proof request\n *\n * @param claimCreationType - The type of claim creation (e.g., STANDALONE)\n *\n * @example\n * ```typescript\n * proofRequest.setClaimCreationType(ClaimCreationType.STANDALONE);\n * ```\n */\n setClaimCreationType(claimCreationType: ClaimCreationType): void {\n this.claimCreationType = claimCreationType;\n }\n\n /**\n * Sets custom options for the QR code modal display\n *\n * @param options - Modal configuration options including title, description, theme, etc.\n * @throws {SetParamsError} When modal options are invalid\n *\n * @example\n * ```typescript\n * proofRequest.setModalOptions({\n * title: 'Scan QR Code',\n * description: 'Scan with your mobile device',\n * darkTheme: true\n * });\n * ```\n */\n setModalOptions(options: ModalOptions): void {\n try {\n // Validate modal options\n validateModalOptions(options, 'setModalOptions');\n\n this.modalOptions = { ...this.modalOptions, ...options };\n logger.info('Modal options set successfully');\n } catch (error) {\n logger.info('Error setting modal options:', error);\n throw new SetParamsError('Error setting modal options', error as Error);\n }\n }\n\n /**\n * Sets additional context data to be stored with the claim\n *\n * This allows you to associate custom JSON serializable data with the proof claim.\n * The context can be retrieved and validated when verifying the proof.\n *\n * Also see [setContext] which is an alternate way to set context that has an address & message.\n *\n * [setContext] and [setJsonContext] overwrite each other. Each call replaces the existing context.\n *\n * @param context - Any additional data you want to store with the claim. Should be serializable to a JSON string.\n * @throws {SetContextError} When context parameters are invalid\n *\n * @example\n * ```typescript\n * proofRequest.setJsonContext({foo: 'bar'});\n * ```\n */\n setJsonContext(context: Record<string, any>) {\n try {\n validateFunctionParams([\n { input: context, paramName: 'context', isString: false }\n ], 'setJsonContext');\n // ensure context is canonically json serializable\n this.context = JSON.parse(canonicalStringify({ ...context, reclaimSessionId: this.sessionId }));\n this.applyAttestationContext();\n } catch (error) {\n logger.info(\"Error setting context\", error)\n throw new SetContextError(\"Error setting context\", error as Error)\n }\n }\n\n /**\n * Sets additional context data to be stored with the claim\n *\n * This allows you to associate custom data (address and message) with the proof claim.\n * The context can be retrieved and validated when verifying the proof.\n *\n * Also see [setJsonContext] which is an alternate way to set context that allows for custom JSON serializable data.\n *\n * [setContext] and [setJsonContext] overwrite each other. Each call replaces the existing context.\n *\n * @param address - Context address identifier\n * @param message - Additional data to associate with the address\n * @throws {SetContextError} When context parameters are invalid\n *\n * @example\n * ```typescript\n * proofRequest.setContext('0x1234...', 'User verification for premium access');\n * ```\n */\n setContext(address: string, message: string): void {\n try {\n validateFunctionParams([\n { input: address, paramName: 'address', isString: true },\n { input: message, paramName: 'message', isString: true }\n ], 'setContext');\n this.context = { contextAddress: address, contextMessage: message, reclaimSessionId: this.sessionId };\n this.applyAttestationContext();\n } catch (error) {\n logger.info(\"Error setting context\", error)\n throw new SetContextError(\"Error setting context\", error as Error)\n }\n }\n\n /**\n * @deprecated use setContext instead\n *\n * @param address\n * @param message additional data you want associated with the [address]\n */\n addContext(address: string, message: string): void {\n this.setContext(address, message);\n }\n\n /**\n * Sets provider-specific parameters for the proof request\n *\n * These parameters are passed to the provider and may include configuration options,\n * filters, or other provider-specific settings required for proof generation.\n *\n * @param params - Key-value pairs of parameters to set\n * @throws {SetParamsError} When parameters are invalid\n *\n * @example\n * ```typescript\n * proofRequest.setParams({\n * minFollowers: '1000',\n * platform: 'twitter'\n * });\n * ```\n */\n setParams(params: { [key: string]: string }): void {\n try {\n validateParameters(params);\n this.parameters = { ...this.parameters, ...params }\n } catch (error) {\n logger.info('Error Setting Params:', error);\n throw new SetParamsError(\"Error setting params\", error as Error)\n }\n }\n\n /**\n * Returns the currently configured app callback URL\n *\n * If no custom callback URL was set via setAppCallbackUrl(), this returns the default\n * Reclaim service callback URL with the current session ID.\n *\n * @returns The callback URL where proofs will be submitted\n * @throws {GetAppCallbackUrlError} When unable to retrieve the callback URL\n *\n * @example\n * ```typescript\n * const callbackUrl = proofRequest.getAppCallbackUrl();\n * console.log('Proofs will be sent to:', callbackUrl);\n * ```\n */\n getAppCallbackUrl(): string {\n try {\n validateFunctionParams([{ input: this.sessionId, paramName: 'sessionId', isString: true }], 'getAppCallbackUrl');\n return this.appCallbackUrl || `${constants.DEFAULT_RECLAIM_CALLBACK_URL}${this.sessionId}`\n } catch (error) {\n logger.info(\"Error getting app callback url\", error)\n throw new GetAppCallbackUrlError(\"Error getting app callback url\", error as Error)\n }\n }\n\n /**\n * Returns the currently configured cancel callback URL\n *\n * If no custom cancel callback URL was set via setCancelCallbackUrl(), this returns the default\n * Reclaim service cancel callback URL with the current session ID.\n *\n * @returns The cancel callback URL where proofs will be submitted\n * @throws {GetAppCallbackUrlError} When unable to retrieve the cancel callback URL\n *\n * @example\n * ```typescript\n * const callbackUrl = proofRequest.getCancelCallbackUrl();\n * console.log('Errors will be sent to:', callbackUrl);\n * ```\n */\n getCancelCallbackUrl(): string {\n try {\n validateFunctionParams([{ input: this.sessionId, paramName: 'sessionId', isString: true }], 'getCancelCallbackUrl');\n return this.cancelCallbackUrl || `${constants.DEFAULT_RECLAIM_CANCEL_CALLBACK_URL}${this.sessionId}`\n } catch (error) {\n logger.info(\"Error getting cancel callback url\", error)\n throw new GetAppCallbackUrlError(\"Error getting cancel callback url\", error as Error)\n }\n }\n\n /**\n * Returns the status URL for monitoring the current session\n *\n * This URL can be used to check the status of the proof request session.\n *\n * @returns The status monitoring URL for the current session\n * @throws {GetStatusUrlError} When unable to retrieve the status URL\n *\n * @example\n * ```typescript\n * const statusUrl = proofRequest.getStatusUrl();\n * // Use this URL to poll for session status updates\n * ```\n */\n getStatusUrl(): string {\n try {\n validateFunctionParams([{ input: this.sessionId, paramName: 'sessionId', isString: true }], 'getStatusUrl');\n return `${constants.DEFAULT_RECLAIM_STATUS_URL}${this.sessionId}`\n } catch (error) {\n logger.info(\"Error fetching Status Url\", error)\n throw new GetStatusUrlError(\"Error fetching status url\", error as Error)\n }\n }\n\n /**\n * Returns the session ID associated with this proof request\n *\n * The session ID is automatically generated during initialization and uniquely\n * identifies this proof request session.\n *\n * @returns The session ID string\n * @throws {SessionNotStartedError} When session ID is not set\n *\n * @example\n * ```typescript\n * const sessionId = proofRequest.getSessionId();\n * console.log('Session ID:', sessionId);\n * ```\n */\n getSessionId(): string {\n if (!this.sessionId) {\n throw new SessionNotStartedError(\"SessionId is not set\");\n }\n return this.sessionId;\n }\n\n private static validateInitOptions(options: ProofRequestOptions | undefined, caller: string): void {\n if (!options) return;\n if (options.acceptAiProviders) {\n validateFunctionParams([{ paramName: 'acceptAiProviders', input: options.acceptAiProviders }], caller)\n }\n if (options.providerVersion) {\n validateFunctionParams([{ paramName: 'providerVersion', input: options.providerVersion, isString: true }], caller)\n }\n if (options.log) {\n validateFunctionParams([{ paramName: 'log', input: options.log }], caller)\n }\n if (options.useAppClip) {\n validateFunctionParams([{ paramName: 'useAppClip', input: options.useAppClip }], caller)\n }\n if (options.device) {\n validateFunctionParams([{ paramName: 'device', input: options.device, isString: true }], caller)\n }\n if (options.useBrowserExtension) {\n validateFunctionParams([{ paramName: 'useBrowserExtension', input: options.useBrowserExtension }], caller)\n }\n if (options.extensionID) {\n validateFunctionParams([{ paramName: 'extensionID', input: options.extensionID, isString: true }], caller)\n }\n if (options.envUrl) {\n validateFunctionParams([{ paramName: 'envUrl', input: options.envUrl, isString: true }], caller)\n }\n if (options.portalUrl) {\n validateFunctionParams([{ paramName: 'portalUrl', input: options.portalUrl, isString: true }], caller)\n }\n if (options.customSharePageUrl) {\n validateFunctionParams([{ paramName: 'customSharePageUrl', input: options.customSharePageUrl, isString: true }], caller)\n }\n if (options.customAppClipUrl) {\n validateFunctionParams([{ paramName: 'customAppClipUrl', input: options.customAppClipUrl, isString: true }], caller)\n }\n if (options.preferredLocale) {\n validateFunctionParams([{ paramName: 'preferredLocale', input: options.preferredLocale, isString: true }], caller);\n validateFunctionParamsWithFn({\n paramName: 'preferredLocale', input: options.preferredLocale, isValid: () => {\n try {\n Intl.getCanonicalLocales(options.preferredLocale);\n return true;\n } catch (error) {\n logger.info('Failed to canonicalize locale', error);\n return false;\n }\n }\n }, caller);\n }\n }\n\n // Private helper methods\n private setSignature(signature: string): void {\n try {\n validateFunctionParams([{ input: signature, paramName: 'signature', isString: true }], 'setSignature');\n this.signature = signature;\n logger.info(`Signature set successfully for applicationId: ${this.applicationId}`);\n } catch (error) {\n logger.info(\"Error setting signature\", error)\n throw new SetSignatureError(\"Error setting signature\", error as Error)\n }\n }\n\n private async generateSignature(applicationSecret: string): Promise<string> {\n try {\n const wallet = new ethers.Wallet(applicationSecret)\n const canonicalData = canonicalize({ providerId: this.providerId, timestamp: this.timeStamp });\n\n\n if (!canonicalData) {\n throw new SignatureGeneratingError('Failed to canonicalize data for signing.');\n }\n\n const messageHash = ethers.keccak256(new TextEncoder().encode(canonicalData));\n\n return await wallet.signMessage(ethers.getBytes(messageHash));\n } catch (err) {\n logger.info(`Error generating proof request for applicationId: ${this.applicationId}, providerId: ${this.providerId}, timeStamp: ${this.timeStamp}`);\n throw new SignatureGeneratingError(`Error generating signature for applicationId: ${this.applicationId}`)\n }\n }\n\n private clearInterval(): void {\n if (this.sessionId && this.intervals.has(this.sessionId)) {\n clearInterval(this.intervals.get(this.sessionId) as NodeJS.Timeout)\n this.intervals.delete(this.sessionId)\n }\n }\n\n private setAttestationContext(nonce?: string, data?: Context['attestationNonceData']): void {\n if (!nonce || !data) {\n return;\n }\n this.attestationNonce = nonce;\n this.attestationNonceData = data;\n this.applyAttestationContext();\n }\n\n private applyAttestationContext(): void {\n if (!this.attestationNonce || !this.attestationNonceData) {\n return;\n }\n this.context = {\n ...this.context,\n attestationNonce: this.attestationNonce,\n attestationNonceData: this.attestationNonceData\n };\n }\n\n private encodeTemplateData(templateData: TemplateData): string {\n let template = encodeURIComponent(JSON.stringify(templateData));\n template = replaceAll(template, '(', '%28');\n template = replaceAll(template, ')', '%29');\n return template;\n }\n\n private buildSharePageUrl(template: string): string {\n return `${this.appSharePageUrl}/?template=${template}`;\n }\n\n private async openPortalTab(templateData: TemplateData, preOpenedTab?: Window | null): Promise<void> {\n // Use pre-opened tab if provided, otherwise open one now\n const newTab = preOpenedTab ?? window.open('about:blank', '_blank');\n const link = await createLinkWithTemplateData(templateData, this.customSharePageUrl);\n logger.info('Opening portal in new tab: ' + link);\n if (newTab) {\n this.portalTab = newTab;\n newTab.location = link;\n // Verify navigation actually happened; close blank tab if it didn't\n setTimeout(() => {\n try {\n if (newTab.location.href === 'about:blank') {\n newTab.close();\n this.portalTab = undefined;\n window.open(link, '_blank');\n }\n } catch (_) {\n // Cross-origin after navigation means it worked\n }\n }, 500);\n }\n }\n\n private closePortalTab(): void {\n try {\n this.portalTab?.close();\n } catch (_) {\n // Cross-origin — tab may have navigated away\n }\n this.portalTab = undefined;\n }\n\n private async embedPortalIframe(templateData: TemplateData, target: HTMLElement): Promise<void> {\n let link = await createLinkWithTemplateData(templateData, this.customSharePageUrl);\n // Signal to the portal that it's embedded — skip extension detection\n const separator = link.includes('?') ? '&' : '?';\n link = `${link}${separator}embedded=true`;\n logger.info('Embedding portal in iframe: ' + link);\n\n this.closeEmbeddedFlow();\n\n const iframe = document.createElement('iframe');\n iframe.src = link;\n iframe.style.width = '100%';\n iframe.style.height = '100%';\n iframe.style.border = 'none';\n iframe.setAttribute('allow', 'clipboard-write');\n iframe.setAttribute('sandbox', 'allow-scripts allow-same-origin allow-forms');\n\n target.appendChild(iframe);\n this.portalIframe = iframe;\n }\n\n /**\n * Closes the embedded portal iframe and stops the session polling.\n *\n * Call this to programmatically cancel the embedded verification flow\n * that was started with `triggerReclaimFlow({ target: element })`.\n * Also called automatically when verification succeeds or fails.\n *\n * @example\n * ```typescript\n * proofRequest.closeEmbeddedFlow();\n * ```\n */\n closeEmbeddedFlow(): void {\n if (this.portalIframe) {\n this.portalIframe.remove();\n this.portalIframe = undefined;\n }\n this.clearInterval();\n }\n\n /**\n * Cancels an in-progress verification session.\n *\n * Use this when the user abandons the flow (e.g. navigates back) before a\n * proof is produced. It tears down all local session machinery — the status\n * polling interval, the 10-minute interval-ending timeout, and any portal UI\n * (modal / tab / embedded iframe) — and marks the session CANCELLED on the\n * backend.\n *\n * Marking the session CANCELLED is what prevents a stale, abandoned session\n * from later being reported as a failure: the portal's inactivity monitor\n * treats a cancelled session as a clean terminal state and will not emit a\n * connection-failure error to the cancel/error callback. Because that callback\n * URL is typically shared across sessions, suppressing it here stops an\n * abandoned session from contaminating the next one.\n *\n * `onSuccess` / `onError` are intentionally NOT invoked — cancellation is a\n * deliberate, silent teardown, not a verification outcome. Safe to call more\n * than once; a no-op when no session is active.\n *\n * @example\n * ```typescript\n * // e.g. in a React effect cleanup when the user navigates away\n * await proofRequest.cancelSession();\n * ```\n */\n async cancelSession(): Promise<void> {\n // TODO: Once existing clients stop treating an error callback as a hard\n // \"breaker\" in multi-session flows (i.e. they key error handling by\n // sessionId rather than failing the whole verification on any error to\n // the shared callback URL), migrate cancellation to be reported as an\n // *error* (an explicit USER_CANCELLED error status that fires the\n // cancel/error callback) instead of the current silent SESSION_CANCELLED\n // terminal. Doing that today would re-introduce the cross-session\n // contamination this method was built to avoid, so it must be coordinated\n // with clients first.\n if (!this.sessionId) {\n return;\n }\n const sessionId = this.sessionId;\n logger.info(`Cancelling session: ${sessionId}`);\n\n // Stop all local machinery first so nothing can fire after we return:\n // closeEmbeddedFlow() clears the polling interval (and removes the embedded\n // iframe); deleting the interval also neutralizes the 10-minute\n // scheduleIntervalEndingTask, which no-ops once the sessionId is gone from\n // the intervals map.\n this.closeModal();\n this.closePortalTab();\n this.closeEmbeddedFlow();\n\n // Best-effort backend update. Swallow errors: by the time we cancel, the\n // user is already leaving, and a backend that has moved the session to a\n // final state will reject the update (which is fine — nothing to cancel).\n try {\n await updateSession(sessionId, SessionStatus.SESSION_CANCELLED);\n } catch (error) {\n logger.info(`cancelSession: backend update failed for ${sessionId}: ${error}`);\n }\n }\n\n /**\n * Exports the Reclaim proof verification request as a JSON string\n *\n * This serialized format can be sent to the frontend to recreate this request using\n * ReclaimProofRequest.fromJsonString() or any InApp SDK's startVerificationFromJson()\n * method to initiate the verification journey.\n *\n * @returns JSON string representation of the proof request. Note: The JSON includes both `timestamp` and `timeStamp` (deprecated) for backward compatibility.\n *\n * @example\n * ```typescript\n * const jsonString = proofRequest.toJsonString();\n * // Send to frontend or store for later use\n * // Can be reconstructed with: ReclaimProofRequest.fromJsonString(jsonString)\n * ```\n */\n toJsonString(): string {\n return JSON.stringify({\n applicationId: this.applicationId,\n providerId: this.providerId,\n sessionId: this.sessionId,\n context: this.context,\n appCallbackUrl: this.appCallbackUrl,\n claimCreationType: this.claimCreationType,\n parameters: this.parameters,\n signature: this.signature,\n redirectUrl: this.redirectUrl,\n redirectUrlOptions: this.redirectUrlOptions,\n cancelCallbackUrl: this.cancelCallbackUrl,\n cancelRedirectUrl: this.cancelRedirectUrl,\n cancelRedirectUrlOptions: this.cancelRedirectUrlOptions,\n timestamp: this.timeStamp, // New field with correct spelling\n timeStamp: this.timeStamp, // @deprecated: Remove in future versions\n options: this.options,\n sdkVersion: this.sdkVersion,\n jsonProofResponse: this.jsonProofResponse,\n resolvedProviderVersion: this.resolvedProviderVersion ?? '',\n modalOptions: this.modalOptions ? {\n title: this.modalOptions.title,\n description: this.modalOptions.description,\n extensionUrl: this.modalOptions.extensionUrl,\n darkTheme: this.modalOptions.darkTheme,\n modalPopupTimer: this.modalOptions.modalPopupTimer,\n showExtensionInstallButton: this.modalOptions.showExtensionInstallButton\n // onClose is intentionally excluded as functions cannot be serialized\n } : undefined\n })\n }\n\n /**\n * Validates signature and returns template data\n * @returns\n */\n private getTemplateData = (): TemplateData => {\n if (!this.signature) {\n throw new SignatureNotFoundError('Signature is not set.')\n }\n\n // When using a non-default regional portal, a custom callback URL is required\n const defaultHosts = ['share.reclaimprotocol.org', 'portal.reclaimprotocol.org'];\n if (this.customSharePageUrl) {\n try {\n const sharePageHost = new URL(this.customSharePageUrl).hostname;\n if (!defaultHosts.includes(sharePageHost) && !this.appCallbackUrl) {\n throw new CallbackUrlRequiredError(\n 'A custom callback URL is required when using a customSharePage url'\n );\n }\n } catch (e) {\n if (e instanceof CallbackUrlRequiredError) throw e;\n // If URL parsing fails, skip this check — URL validation elsewhere will catch it\n }\n }\n\n validateSignature(this.providerId, this.signature, this.applicationId, this.timeStamp)\n const templateData: TemplateData = {\n sessionId: this.sessionId,\n providerId: this.providerId,\n applicationId: this.applicationId,\n signature: this.signature,\n timestamp: this.timeStamp,\n callbackUrl: this.getAppCallbackUrl(),\n context: canonicalStringify(this.context),\n providerVersion: this.options?.providerVersion ?? '',\n resolvedProviderVersion: this.resolvedProviderVersion ?? '',\n parameters: this.parameters,\n redirectUrl: this.redirectUrl ?? '',\n redirectUrlOptions: this.redirectUrlOptions,\n cancelCallbackUrl: this.getCancelCallbackUrl(),\n cancelRedirectUrl: this.cancelRedirectUrl,\n cancelRedirectUrlOptions: this.cancelRedirectUrlOptions,\n acceptAiProviders: this.options?.acceptAiProviders ?? false,\n sdkVersion: this.sdkVersion,\n jsonProofResponse: this.jsonProofResponse,\n log: this.options?.log ?? false,\n canAutoSubmit: this.options?.canAutoSubmit ?? true,\n metadata: this.options?.metadata,\n preferredLocale: this.options?.preferredLocale,\n acceptTeeAttestation: this.options?.acceptTeeAttestation,\n teeAttestationVersion: this.context.attestationNonceData?.attestationVersion ?? SDK_TEE_ATTESTATION_VERSION,\n }\n\n return templateData;\n }\n\n /**\n * Generates and returns the request URL for proof verification.\n *\n * Defaults to portal mode. Pass `{ verificationMode: 'app' }` for native app flow URLs.\n *\n * - Portal mode (default): returns portal URL on all platforms\n * - App mode: returns share page URL on all platforms\n * - App mode + `useAppClip: true` on iOS: returns App Clip URL instead\n *\n * Falls back to `launchOptions` set at init time if not passed at call time.\n *\n * @param launchOptions - Optional launch configuration to override default behavior\n * @returns Promise<string> - The generated request URL\n * @throws {SignatureNotFoundError} When signature is not set\n *\n * @example\n * ```typescript\n * // Portal URL (default)\n * const url = await proofRequest.getRequestUrl();\n *\n * // Verifier app flow URL\n * const url = await proofRequest.getRequestUrl({ verificationMode: 'app' });\n * ```\n */\n async getRequestUrl(launchOptions?: ReclaimFlowLaunchOptions): Promise<string> {\n const options = { ...this.options?.launchOptions, ...launchOptions };\n const mode = options.verificationMode ?? 'portal';\n\n logger.info('Creating Request Url')\n if (!this.signature) {\n throw new SignatureNotFoundError('Signature is not set.')\n }\n\n try {\n const templateData = this.getTemplateData()\n await updateSession(this.sessionId, SessionStatus.SESSION_STARTED)\n\n if (mode === 'app') {\n const template = this.encodeTemplateData(templateData);\n\n // App Clip only if useAppClip is true and iOS\n if (this.options?.useAppClip && getDeviceType() === DeviceType.MOBILE && getMobileDeviceType() === DeviceType.IOS) {\n const appClipUrl = this.customAppClipUrl ? `${this.customAppClipUrl}&template=${template}` : `https://appclip.apple.com/id?p=org.reclaimprotocol.app.clip&template=${template}`;\n logger.info('App Clip Url created successfully: ' + appClipUrl);\n return appClipUrl;\n }\n\n // Share page for all other cases in app mode\n const sharePageUrl = await createLinkWithTemplateData(templateData, this.appSharePageUrl);\n logger.info('Share page Url created successfully: ' + sharePageUrl);\n return sharePageUrl;\n }\n\n // Portal mode (default)\n const link = await createLinkWithTemplateData(templateData, this.customSharePageUrl)\n logger.info('Request Url created successfully: ' + link);\n return link;\n } catch (error) {\n logger.info('Error creating Request Url:', error)\n throw error\n }\n }\n\n /**\n * Triggers the appropriate Reclaim verification flow based on device type and configuration.\n *\n * Defaults to portal mode (remote browser verification). Pass `{ verificationMode: 'app' }`\n * for verifier app flow via the share page.\n *\n * - **Embedded iframe**: Pass `{ target: element }` to embed the portal inside a DOM element instead of a new tab\n * - Desktop: browser extension takes priority in both modes\n * - Desktop portal mode (no extension): opens portal in new tab\n * - Desktop app mode (no extension): shows QR code modal with share page URL\n * - Mobile portal mode: opens portal in new tab\n * - Mobile app mode: opens share page (or App Clip on iOS if `useAppClip` is `true`)\n *\n * @param launchOptions - Optional launch configuration to override default behavior\n * @returns Promise<FlowHandle> - Handle to control the flow (close, access iframe)\n * @throws {SignatureNotFoundError} When signature is not set\n *\n * @example\n * ```typescript\n * // Portal flow (default) — opens in new tab\n * const handle = await proofRequest.triggerReclaimFlow();\n * handle.tab; // Window reference to the opened tab\n * handle.close(); // close tab and stop polling\n *\n * // Embed portal in an iframe inside a DOM element\n * const handle = await proofRequest.triggerReclaimFlow({ target: document.getElementById('reclaim-container') });\n * handle.iframe; // HTMLIFrameElement reference\n * handle.close(); // remove iframe and stop polling\n *\n * // Verifier app flow\n * await proofRequest.triggerReclaimFlow({ verificationMode: 'app' });\n *\n * // App Clip on iOS (requires useAppClip: true at init)\n * const request = await ReclaimProofRequest.init(APP_ID, SECRET, PROVIDER, { useAppClip: true });\n * await request.triggerReclaimFlow({ verificationMode: 'app' });\n *\n * // Can also set verificationMode at init time via launchOptions\n * const request = await ReclaimProofRequest.init(APP_ID, SECRET, PROVIDER, {\n * launchOptions: { verificationMode: 'app' }\n * });\n * await request.triggerReclaimFlow(); // uses 'app' mode from init\n * ```\n */\n async triggerReclaimFlow(launchOptions?: ReclaimFlowLaunchOptions): Promise<FlowHandle> {\n const options = { ...this.options?.launchOptions, ...launchOptions };\n const mode = options.verificationMode ?? 'portal';\n\n if (!this.signature) {\n throw new SignatureNotFoundError('Signature is not set.')\n }\n\n try {\n const templateData = this.getTemplateData()\n\n this.templateData = templateData;\n\n logger.info(`Triggering Reclaim flow (mode: ${mode})`);\n\n const deviceType = getDeviceType();\n updateSession(this.sessionId, SessionStatus.SESSION_STARTED)\n\n // Iframe embedding — takes priority when target element is provided\n if (launchOptions && 'target' in launchOptions && !launchOptions.target) {\n logger.warn('triggerReclaimFlow: target was provided but is null/undefined — falling back to default flow. Ensure the element exists in the DOM.');\n }\n if (launchOptions?.target && mode === 'portal') {\n await this.embedPortalIframe(templateData, launchOptions.target);\n return {\n close: () => this.closeEmbeddedFlow(),\n iframe: this.portalIframe!,\n };\n }\n\n if (deviceType === DeviceType.DESKTOP) {\n // Check extension first if enabled\n if (this.options?.useBrowserExtension) {\n const extensionAvailable = await this.isBrowserExtensionAvailable();\n if (extensionAvailable) {\n logger.info('Triggering browser extension flow');\n this.triggerBrowserExtensionFlow();\n return {\n close: () => { this.clearInterval(); },\n };\n }\n }\n\n // No extension — open tab/modal synchronously (click activation preserved\n // because extension check is skipped when useBrowserExtension is false,\n // and when it's true but unavailable, we proceed immediately)\n if (mode === 'portal') {\n await this.openPortalTab(templateData);\n } else {\n // App mode: QR code modal with share page URL\n logger.info('Showing QR code modal with share page URL');\n await this.showQRCodeModal();\n }\n } else if (deviceType === DeviceType.MOBILE) {\n if (mode === 'app') {\n // App Clip only if useAppClip is true and iOS\n if (this.options?.useAppClip && getMobileDeviceType() === DeviceType.IOS) {\n logger.info('Redirecting to iOS app clip');\n this.redirectToAppClip();\n } else {\n // Share page for Android and iOS without useAppClip\n logger.info('Redirecting to share page');\n await this.redirectToInstantApp(options);\n }\n } else {\n await this.openPortalTab(templateData);\n }\n }\n\n return {\n close: () => {\n this.closePortalTab();\n this.closeEmbeddedFlow();\n this.modal?.close();\n },\n tab: this.portalTab ?? undefined,\n };\n } catch (error) {\n logger.info('Error triggering Reclaim flow:', error);\n throw error;\n }\n }\n\n\n /**\n * Checks if the Reclaim browser extension is installed and available\n *\n * This method attempts to communicate with the browser extension to verify its availability.\n * It uses a timeout mechanism to quickly determine if the extension responds.\n *\n * @param timeout - Timeout in milliseconds to wait for extension response. Defaults to 200ms\n * @returns Promise<boolean> - True if extension is available, false otherwise\n *\n * @example\n * ```typescript\n * const hasExtension = await proofRequest.isBrowserExtensionAvailable();\n * if (hasExtension) {\n * console.log('Browser extension is installed');\n * }\n * ```\n */\n async isBrowserExtensionAvailable(timeout = 200): Promise<boolean> {\n try {\n return new Promise<boolean>((resolve) => {\n const messageId = `reclaim-check-${Date.now()}`;\n\n const timeoutId = setTimeout(() => {\n window.removeEventListener('message', messageListener);\n resolve(false);\n }, timeout);\n\n const messageListener = (event: MessageEvent) => {\n if (event.data?.action === RECLAIM_EXTENSION_ACTIONS.EXTENSION_RESPONSE &&\n event.data?.messageId === messageId) {\n clearTimeout(timeoutId);\n window.removeEventListener('message', messageListener);\n resolve(!!event.data.installed);\n }\n };\n\n window.addEventListener('message', messageListener);\n const message: ExtensionMessage = {\n action: RECLAIM_EXTENSION_ACTIONS.CHECK_EXTENSION,\n extensionID: this.extensionID,\n messageId: messageId\n }\n window.postMessage(message, '*');\n });\n } catch (error) {\n logger.info('Error checking Reclaim extension installed:', error);\n return false;\n }\n }\n\n private triggerBrowserExtensionFlow(): void {\n const message: ExtensionMessage = {\n action: RECLAIM_EXTENSION_ACTIONS.START_VERIFICATION,\n messageId: this.sessionId,\n data: this.templateData,\n extensionID: this.extensionID\n }\n window.postMessage(message, '*');\n logger.info('Browser extension flow triggered');\n }\n\n private async showQRCodeModal(): Promise<void> {\n try {\n const requestUrl = await createLinkWithTemplateData(this.templateData, this.appSharePageUrl);\n this.modal = new QRCodeModal(this.modalOptions);\n await this.modal.show(requestUrl);\n } catch (error) {\n logger.info('Error showing QR code modal:', error);\n throw error;\n }\n }\n\n private async redirectToInstantApp(options: ReclaimFlowLaunchOptions): Promise<void> {\n try {\n const template = this.encodeTemplateData(this.templateData);\n let instantAppUrl = this.buildSharePageUrl(template);\n logger.info('Redirecting to Android instant app: ' + instantAppUrl);\n\n const isDeferredDeeplinksFlowEnabled = options.canUseDeferredDeepLinksFlow ?? false;\n\n if (isDeferredDeeplinksFlowEnabled) {\n instantAppUrl = instantAppUrl.replace(\"/verifier\", \"/link\");\n\n // Construct Android intent deep link\n const deepLink = `intent://details?id=org.reclaimprotocol.app&url=${encodeURIComponent(\n instantAppUrl\n )}&template=${template}#Intent;scheme=market;action=android.intent.action.VIEW;package=com.android.vending;end;`;\n\n try {\n const requestUrl = instantAppUrl;\n\n let appInstalled = false;\n let timeoutId: string | number | NodeJS.Timeout | undefined;\n\n // Create hidden iframe to test deep link\n const iframe = document.createElement(\"iframe\");\n iframe.style.display = \"none\";\n iframe.style.width = \"1px\";\n iframe.style.height = \"1px\";\n document.body.appendChild(iframe);\n\n // Function to clean up\n const cleanup = () => {\n if (iframe.parentNode) {\n document.body.removeChild(iframe);\n }\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n };\n\n // If page becomes hidden, app opened successfully\n const onVisibilityChange = () => {\n if (document.hidden) {\n appInstalled = true;\n cleanup();\n // Open in main window since app is installed\n window.location.href = deepLink;\n }\n };\n\n // Listen for visibility change\n document.addEventListener(\"visibilitychange\", onVisibilityChange, { once: true });\n\n // Test reclaimverifier deep link in iframe\n iframe.src = deepLink.replace('intent:', 'reclaimverifier:');\n\n // After timeout, assume app not installed\n timeoutId = setTimeout(() => {\n document.removeEventListener(\"visibilitychange\", onVisibilityChange);\n cleanup();\n\n if (!appInstalled) {\n // App not installed - redirect to the store page to install the app\n window.navigator.clipboard.writeText(requestUrl).catch(() => {\n console.error(\"We can't access the clipboard. Please copy this link and open Reclaim Verifier app.\");\n });\n window.location.href = deepLink;\n }\n }, 1500);\n } catch (e) {\n // Final fallback → verifier\n window.location.href = instantAppUrl;\n }\n return;\n }\n\n // Redirect to instant app\n window.location.href = instantAppUrl;\n } catch (error) {\n logger.info('Error redirecting to instant app:', error);\n throw error;\n }\n }\n\n private redirectToAppClip(): void {\n try {\n const template = this.encodeTemplateData(this.templateData);\n const appClipUrl = this.customAppClipUrl ? `${this.customAppClipUrl}&template=${template}` : `https://appclip.apple.com/id?p=org.reclaimprotocol.app.clip&template=${template}`;\n logger.info('Redirecting to iOS app clip: ' + appClipUrl);\n const verifierUrl = `${this.appSharePageUrl}/?template=${template}`;\n\n // Redirect to app clip\n window.location.href = appClipUrl;\n\n setTimeout(() => {\n window.location.href = verifierUrl;\n // 5 second delay to allow app clip to launch\n }, 5 * 1000);\n } catch (error) {\n logger.info('Error redirecting to app clip:', error);\n throw error;\n }\n }\n\n /**\n * Returns the provider id and exact version of the provider that was used in the verification session of this request. \n * \n * This can be provided as a config parameter to the `verifyProof` function to verify the proof.\n * \n * See also:\n * * `verifyProof()` - Verifies a proof against the expected provider configuration.\n * * `getProviderHashRequirements()` - An alternative of this function to get the expected hashes for a provider version by providing providerId and exactProviderVersionString. The result can be provided in verifyProof function's `config` parameter for proof validation.\n * * `getProviderHashRequirementsFromSpec()` - An alternative of this function to get the expected hashes from a provider spec. The result can be provided in verifyProof function's `config` parameter for proof validation.\n */\n public getProviderVersion(): ProviderVersionInfo {\n // This should be exact version and not a version constraint/expression. This cannot be blank.\n const exactProviderVersionString = this.resolvedProviderVersion ?? '';\n return {\n providerId: this.providerId,\n providerVersion: exactProviderVersionString,\n allowedTags: this.options?.acceptAiProviders ? ['ai'] : [],\n }\n }\n\n /**\n * Fetches the provider config that was used for this session and returns the hash requirements\n * \n * See also:\n * * `verifyProof()` - Verifies a proof against the expected provider configuration.\n * * `fetchProviderHashRequirementsBy()` - An alternative of this function to get the expected hashes for a provider version by providing providerId and exactProviderVersionString. The result can be provided in verifyProof function's `config` parameter for proof validation.\n * * `getProviderHashRequirementsFromSpec()` - An alternative of this function to get the expected hashes from a provider spec. The result can be provided in verifyProof function's `config` parameter for proof validation.\n *\n * @returns A promise that resolves to a `ProviderHashRequirementsConfig` or `ProviderHashRequirementsConfig[]`\n */\n getProviderHashRequirements(proofs: Proof[], allowedTags: string[] | null | undefined): Promise<ProviderHashRequirementsConfig[]> {\n return fetchProviderHashRequirementsBy(this.providerId, this.resolvedProviderVersion ?? '', allowedTags, proofs);\n }\n\n /**\n * Starts the proof request session and monitors for proof submission\n *\n * This method begins polling the session status to detect when\n * a proof has been generated and submitted. It handles both default Reclaim callbacks\n * and custom callback URLs.\n *\n * For default callbacks: Verifies proofs automatically and passes them to onSuccess\n * For custom callbacks: Monitors submission status and notifies via onSuccess when complete.\n * In the custom-callback flow (where the SDK submits a proof to a provided callback URL),\n * onSuccess may be invoked with an empty array (onSuccess([])) when no proof is available\n * (this happens when a callback is set using setAppCallbackUrl where proof is sent to callback instead of reclaim backend).\n *\n * Please refer to the OnSuccess type signature ((proof?: Proof | Proof[]) => void)\n * and the startSession function source for more details.\n *\n * > [!TIP]\n * > **Best Practice:** When using `setAppCallbackUrl` and/or `setCancelCallbackUrl`, your backend receives the proof or cancellation details directly. We recommend your backend notifies the frontend (e.g. via WebSockets, SSE, or polling) to stop the verification process and handle the appropriate success/failure action. When a callback is set, `onSuccess` callback provided to `startSession` will have an empty array as its argument.\n *\n * @param onSuccess - Callback function invoked when proof is successfully submitted\n * @param onError - Callback function invoked when an error occurs during the session\n * @param verificationConfig - Optional configuration to customize proof verification\n * @returns Promise<void>\n * @throws {SessionNotStartedError} When session ID is not defined\n * @throws {ProofNotVerifiedError} When proof verification fails (default callback only)\n * @throws {ProofSubmissionFailedError} When proof submission fails (custom callback only)\n * @throws {ProviderFailedError} When proof generation fails with timeout\n *\n * @example\n * ```typescript\n * await proofRequest.startSession({\n * onSuccess: (proof) => {\n * console.log('Proof received:', proof);\n * },\n * onError: (error) => {\n * console.error('Error:', error);\n * }\n * });\n * ```\n */\n async startSession({ onSuccess, onError, verificationConfig }: StartSessionParams): Promise<void> {\n if (!this.sessionId) {\n const message = \"Session can't be started due to undefined value of sessionId\";\n logger.info(message);\n throw new SessionNotStartedError(message);\n }\n\n logger.info('Starting session');\n\n const sessionUpdatePollingInterval = 3 * 1000;\n const interval = setInterval(async () => {\n try {\n const statusUrlResponse = await fetchStatusUrl(this.sessionId);\n\n if (!statusUrlResponse.session) return;\n\n // Reset failure time if status is not PROOF_GENERATION_FAILED\n if (statusUrlResponse.session.statusV2 !== SessionStatus.PROOF_GENERATION_FAILED) {\n this.lastFailureTime = undefined;\n }\n\n // Check for failure timeout\n if (statusUrlResponse.session.statusV2 === SessionStatus.PROOF_GENERATION_FAILED) {\n const currentTime = Date.now();\n if (!this.lastFailureTime) {\n this.lastFailureTime = currentTime;\n } else if (currentTime - this.lastFailureTime >= this.FAILURE_TIMEOUT) {\n const errorMessage = statusUrlResponse.session.error?.message || 'Proof generation failed - timeout reached';\n throw new ProviderFailedError(errorMessage);\n }\n return; // Continue monitoring if under timeout\n }\n\n if (statusUrlResponse.session.statusV2 === SessionStatus.ERROR_SUBMISSION_FAILED || statusUrlResponse.session.statusV2 === SessionStatus.ERROR_SUBMITTED) {\n throw new ErrorDuringVerificationError();\n }\n\n const isDefaultCallbackUrl = this.getAppCallbackUrl() === `${constants.DEFAULT_RECLAIM_CALLBACK_URL}${this.sessionId}`;\n\n if (isDefaultCallbackUrl) {\n if (statusUrlResponse.session.proofs && statusUrlResponse.session.proofs.length > 0) {\n const proofs = statusUrlResponse.session.proofs;\n if (this.claimCreationType === ClaimCreationType.STANDALONE) {\n // Validate against the version the backend actually used for this\n // session, not the version resolved at init. AI patches created\n // mid-session shift the effective version; validating with the\n // init-time version yields UnknownProofsNotValidatedError for\n // proofs that are in fact valid against the AI patch.\n const sessionProviderVersion = statusUrlResponse.session.providerVersionString;\n const effectiveConfig: VerificationConfig = verificationConfig ?? {\n providerId: this.providerId,\n providerVersion: sessionProviderVersion || this.resolvedProviderVersion || '',\n allowedTags: this.options?.acceptAiProviders ? ['ai'] : [],\n };\n const result = await verifyProof(proofs, effectiveConfig);\n if (!result.isVerified) {\n logger.info(`Proofs not verified: count=${proofs?.length}`);\n throw new ProofNotVerifiedError(`Proofs not verified: count=${proofs?.length}`, result.error);\n }\n }\n // check if the proofs array has only one proof then send the proofs in onSuccess\n if (proofs.length === 1) {\n\n onSuccess(proofs[0]);\n } else {\n onSuccess(proofs);\n }\n this.clearInterval();\n this.modal?.close();\n this.closePortalTab();\n this.closeEmbeddedFlow();\n }\n } else {\n if (statusUrlResponse.session.statusV2 === SessionStatus.PROOF_SUBMISSION_FAILED) {\n const errorMessage = statusUrlResponse.session.error?.message || 'Proof submission failed';\n throw new ProofSubmissionFailedError(errorMessage);\n }\n if (statusUrlResponse.session.statusV2 === SessionStatus.PROOF_SUBMITTED ||\n statusUrlResponse.session.statusV2 === SessionStatus.AI_PROOF_SUBMITTED) {\n if (onSuccess) {\n // Proof submitted successfully to the custom callback url\n // We don't have proof, so we just return empty array\n // Before 4.10.1, this was a string message.\n onSuccess([]);\n }\n this.clearInterval();\n this.modal?.close();\n this.closePortalTab();\n this.closeEmbeddedFlow();\n }\n }\n } catch (e) {\n if (onError) {\n onError(e as Error);\n }\n this.clearInterval();\n this.modal?.close();\n this.closePortalTab();\n this.closeEmbeddedFlow();\n }\n }, sessionUpdatePollingInterval);\n\n this.intervals.set(this.sessionId, interval);\n scheduleIntervalEndingTask(this.sessionId, this.intervals, onError);\n }\n\n /**\n * Closes the QR code modal if it is currently open\n *\n * This method can be called to programmatically close the modal, for example,\n * when implementing custom UI behavior or cleanup logic.\n *\n * @example\n * ```typescript\n * // Close modal after some condition\n * proofRequest.closeModal();\n * ```\n */\n closeModal(): void {\n if (this.modal) {\n this.modal.close();\n logger.info('Modal closed by user');\n }\n }\n\n /**\n * Returns whether proofs will be submitted as JSON format\n *\n * @returns boolean - True if proofs are sent as application/json, false for application/x-www-form-urlencoded\n *\n * @example\n * ```typescript\n * const isJson = proofRequest.getJsonProofResponse();\n * console.log('JSON format:', isJson);\n * ```\n */\n getJsonProofResponse(): boolean {\n return this.jsonProofResponse;\n }\n}\n","function createErrorClass(name: string) {\n return class extends Error {\n constructor(message?: string, public innerError?: unknown) {\n // Include inner error message in the main message if available\n const fullMessage = innerError\n ? `${message || ''} caused by ${innerError && typeof innerError === 'object' && 'name' in innerError ? innerError.name : 'Error'}: ${innerError && typeof innerError === 'object' && 'message' in innerError ? innerError.message : String(innerError)}`\n : message;\n\n super(fullMessage);\n this.name = name;\n if (innerError) {\n this.stack += `\\nCaused by: ${innerError && typeof innerError === 'object' && 'stack' in innerError ? innerError.stack : String(innerError)}`;\n }\n }\n };\n}\n\nexport const TimeoutError = createErrorClass('TimeoutError');\nexport const ProofNotVerifiedError = createErrorClass('ProofNotVerifiedError');\nexport const ProofNotValidatedError = createErrorClass('ProofNotValidatedError');\nexport const InvalidRequestSpecError = createErrorClass('InvalidRequestSpecError');\nexport const UnknownProofsNotValidatedError = createErrorClass('UnknownProofsNotValidatedError');\nexport const SessionNotStartedError = createErrorClass('SessionNotStartedError');\nexport const ProviderNotFoundError = createErrorClass('ProviderNotFoundError');\nexport const SignatureGeneratingError = createErrorClass('SignatureGeneratingError');\nexport const SignatureNotFoundError = createErrorClass('SignatureNotFoundError');\nexport const InvalidSignatureError = createErrorClass('InvalidSignatureError');\nexport const UpdateSessionError = createErrorClass('UpdateSessionError');\nexport const InitSessionError = createErrorClass('InitSessionError');\nexport const ProviderFailedError = createErrorClass('ProviderFailedError');\nexport const InvalidParamError = createErrorClass('InvalidParamError');\nexport const ApplicationError = createErrorClass('ApplicationError');\nexport const InitError = createErrorClass('InitError');\nexport const BackendServerError = createErrorClass('BackendServerError');\nexport const GetStatusUrlError = createErrorClass('GetStatusUrlError');\nexport const NoProviderParamsError = createErrorClass('NoProviderParamsError');\nexport const SetParamsError = createErrorClass('SetParamsError');\nexport const SetContextError = createErrorClass('SetContextError');\nexport const SetSignatureError = createErrorClass('SetSignatureError');\nexport const GetAppCallbackUrlError = createErrorClass(\"GetAppCallbackUrlError\");\nexport const StatusUrlError = createErrorClass('StatusUrlError');\nexport const ProviderConfigFetchError = createErrorClass('ProviderConfigFetchError');\nexport const InavlidParametersError = createErrorClass('InavlidParametersError');\nexport const ProofSubmissionFailedError = createErrorClass('ProofSubmissionFailedError');\nexport const ErrorDuringVerificationError = createErrorClass('ErrorDuringVerificationError');\nexport const CallbackUrlRequiredError = createErrorClass('CallbackUrlRequiredError');\nexport const TeeVerificationError = createErrorClass('TeeVerificationError');\nexport const AttestorTeeVerificationError = createErrorClass('AttestorTeeVerificationError');\n","// Define the possible log levels\nexport type LogLevel = 'info' | 'warn' | 'error' | 'silent';\n\n// Define a simple logger class\nclass SimpleLogger {\n private level: LogLevel = 'info';\n\n setLevel(level: LogLevel) {\n this.level = level;\n }\n\n private shouldLog(messageLevel: LogLevel): boolean {\n const levels: LogLevel[] = ['error', 'warn', 'info', 'silent'];\n return levels.indexOf(this.level) >= levels.indexOf(messageLevel);\n }\n\n private log(level: LogLevel, message: string, ...args: any[]) {\n if (this.shouldLog(level) && this.level !== 'silent') {\n const logFunction = this.getLogFunction(level);\n console.log('current level', this.level);\n logFunction(`[${level.toUpperCase()}]`, message, ...args);\n }\n }\n\n private getLogFunction(level: LogLevel): (message?: any, ...optionalParams: any[]) => void {\n switch (level) {\n case 'error':\n return console.error;\n case 'warn':\n return console.warn;\n case 'info':\n return console.info;\n default:\n return () => {}; // No-op for 'silent'\n }\n }\n\n info(message: string, ...args: any[]) {\n this.log('info', message, ...args);\n }\n\n warn(message: string, ...args: any[]) {\n this.log('warn', message, ...args);\n }\n\n error(message: string, ...args: any[]) {\n this.log('error', message, ...args);\n }\n}\n\n// Create the logger instance\nconst logger = new SimpleLogger();\n\n// Function to set the log level\nexport function setLogLevel(level: LogLevel) {\n logger.setLevel(level);\n}\n\n// Export the logger instance and the setLogLevel function\nexport default {\n logger,\n setLogLevel\n};\n","import { ethers } from \"ethers\";\nimport { InavlidParametersError, InvalidParamError, InvalidSignatureError } from \"./errors\";\nimport canonicalize from 'canonicalize'\nimport { Context } from \"./interfaces\";\nimport loggerModule from './logger';\nimport { ProofRequestOptions, ModalOptions, HttpRedirectionMethod, HttpFormEntry } from \"./types\";\nimport { canonicalStringify } from \"./strings\";\nconst logger = loggerModule.logger;\n\n/**\n * Validates function parameters based on specified criteria\n * @param params - An array of objects containing input, paramName, and optional isString flag\n * @param functionName - The name of the function being validated\n * @throws InvalidParamError if any parameter fails validation\n */\nexport function validateFunctionParams(params: { input: any, paramName: string, isString?: boolean }[], functionName: string): void {\n params.forEach(({ input, paramName, isString }) => {\n if (input == null) {\n logger.info(`Validation failed: ${paramName} in ${functionName} is null or undefined`);\n throw new InvalidParamError(`${paramName} passed to ${functionName} must not be null or undefined.`);\n }\n if (isString && typeof input !== 'string') {\n logger.info(`Validation failed: ${paramName} in ${functionName} is not a string`);\n throw new InvalidParamError(`${paramName} passed to ${functionName} must be a string.`);\n }\n if (isString && input.trim() === '') {\n logger.info(`Validation failed: ${paramName} in ${functionName} is an empty string`);\n throw new InvalidParamError(`${paramName} passed to ${functionName} must not be an empty string.`);\n }\n });\n}\n\nexport function validateFunctionParamsWithFn(param: { input: any, paramName: string, isValid: () => boolean }, functionName: string): void {\n if (!param.isValid()) {\n logger.info(`Validation failed: ${param.paramName} in ${functionName} is not valid`);\n throw new InvalidParamError(`${param.paramName} passed to ${functionName} must be valid.`);\n }\n}\n\n\n// validate the parameters\n/** \n * Validates the parameters object\n * @param parameters - The parameters object to validate\n * @throws InavlidParametersError if the parameters object is not valid\n */\nexport function validateParameters(parameters: { [key: string]: string }): void {\n try {\n // check if the parameters is an object of key value pairs of string and string\n if (typeof parameters !== 'object' || parameters === null) {\n logger.info(`Parameters validation failed: Provided parameters is not an object`);\n throw new InavlidParametersError(`The provided parameters is not an object`);\n }\n // check each key and value in the parameters object\n for (const [key, value] of Object.entries(parameters)) {\n if (typeof key !== 'string' || typeof value !== 'string') {\n logger.info(`Parameters validation failed: Provided parameters is not an object of key value pairs of string and string`);\n throw new InavlidParametersError(`The provided parameters is not an object of key value pairs of string and string`);\n }\n }\n } catch (e) {\n logger.info(`Parameters validation failed: ${(e as Error).message}`);\n throw new InavlidParametersError(`Invalid parameters passed to validateParameters.`, e as Error);\n }\n}\n\n\n/**\n* Validates a URL string\n* @param url - The URL to validate\n* @param functionName - The name of the function calling this validation\n* @throws InvalidParamError if the URL is invalid or empty\n*/\nexport function validateURL(url: string, functionName: string): void {\n try {\n new URL(url);\n } catch (e) {\n logger.info(`URL validation failed for ${url} in ${functionName}: ${(e as Error).message}`);\n throw new InvalidParamError(`Invalid URL format ${url} passed to ${functionName}.`, e as Error);\n }\n}\n\n/**\n* Validates a URL string\n* @param url - The URL to validate\n* @param functionName - The name of the function calling this validation\n* @throws InvalidParamError if the URL is invalid or empty\n*/\nexport function validateRedirectionMethod(method: string | null | undefined, functionName: string): void {\n try {\n if (method === null || method === undefined) {\n return;\n }\n if (method !== 'GET' && method !== 'POST') {\n throw new Error(`Invalid redirection method ${method} passed to ${functionName}.`);\n }\n } catch (e) {\n logger.info(`Redirection method validation failed for ${method} in ${functionName}: ${(e as Error).message}`);\n throw new InvalidParamError(`Invalid redirection method ${method} passed to ${functionName}.`, e as Error);\n }\n}\n\n\n/**\n* Validates a URL string\n* @param url - The URL to validate\n* @param functionName - The name of the function calling this validation\n* @throws InvalidParamError if the URL is invalid or empty\n*/\nexport function validateRedirectionBody(records: HttpFormEntry[] | undefined | null, functionName: string): void {\n try {\n if (records === null || records === undefined) {\n return;\n }\n if (Array.isArray(records)) {\n for (const record of records) {\n if ('name' in record && record.name && typeof record.name === 'string') {\n if ('value' in record && typeof record.value === 'string') {\n continue;\n }\n }\n throw new Error('Record in form entries do not have a valid name and/or value');\n }\n } else {\n throw new Error('Redirection body must be an array of objects with name, and value');\n }\n } catch (e) {\n logger.info(`Redirection body validation failed for ${records} in ${functionName}: ${(e as Error).message}`);\n throw new InvalidParamError(`Invalid redirection body ${records} passed to ${functionName}.`, e as Error);\n }\n}\n\n/**\n* Validates a signature against the provided application ID\n* @param providerId - The ID of the provider\n* @param signature - The signature to validate\n* @param applicationId - The expected application ID\n* @param timestamp - The timestamp of the signature\n* @throws InvalidSignatureError if the signature is invalid or doesn't match the application ID\n*/\nexport function validateSignature(providerId: string, signature: string, applicationId: string, timestamp: string): void {\n try {\n logger.info(`Starting signature validation for providerId: ${providerId}, applicationId: ${applicationId}, timestamp: ${timestamp}`);\n\n const message = canonicalize({ providerId, timestamp });\n if (!message) {\n logger.info('Failed to canonicalize message for signature validation');\n throw new Error('Failed to canonicalize message');\n }\n const messageHash = ethers.keccak256(new TextEncoder().encode(message));\n let appId = ethers.verifyMessage(\n ethers.getBytes(messageHash),\n ethers.hexlify(signature)\n ).toLowerCase();\n\n if (ethers.getAddress(appId) !== ethers.getAddress(applicationId)) {\n logger.info(`Signature validation failed: Mismatch between derived appId (${appId}) and provided applicationId (${applicationId})`);\n throw new InvalidSignatureError(`Signature does not match the application id: ${appId}`);\n }\n\n logger.info(`Signature validated successfully for applicationId: ${applicationId}`);\n } catch (err) {\n logger.info(`Signature validation failed: ${(err as Error).message}`);\n if (err instanceof InvalidSignatureError) {\n throw err;\n }\n throw new InvalidSignatureError(`Failed to validate signature: ${(err as Error).message}`);\n }\n}\n\n/**\n * Validates the context object\n * @param context - The context object to validate\n * @throws InvalidParamError if the context object is not valid\n */\nexport function validateContext(context: Context | Record<string, any>): void {\n if (context && !('contextAddress' in context)) {\n try {\n validateFunctionParams([\n { input: context, paramName: 'context', isString: false }\n ], 'validateContext');\n // ensure context is canonically json serializable\n JSON.parse(canonicalStringify(context));\n return;\n } catch (e) {\n logger.info(`Context validation failed: Provided JSON serializable context is not valid`);\n throw new InvalidParamError(`The provided context is not valid`);\n }\n }\n if (!context.contextAddress) {\n logger.info(`Context validation failed: Provided context address in context is not valid`);\n throw new InvalidParamError(`The provided context address in context is not valid`);\n }\n\n if (!context.contextMessage) {\n logger.info(`Context validation failed: Provided context message in context is not valid`);\n throw new InvalidParamError(`The provided context message in context is not valid`);\n }\n\n validateFunctionParams([\n { input: context.contextAddress, paramName: 'contextAddress', isString: true },\n { input: context.contextMessage, paramName: 'contextMessage', isString: true }\n ], 'validateContext');\n}\n\n/**\n * Validates the options object\n * @param options - The options object to validate\n * @throws InvalidParamError if the options object is not valid\n */\nexport function validateOptions(options: ProofRequestOptions): void {\n if (options.acceptAiProviders && typeof options.acceptAiProviders !== 'boolean') {\n logger.info(`Options validation failed: Provided acceptAiProviders in options is not valid`);\n throw new InvalidParamError(`The provided acceptAiProviders in options is not valid`);\n }\n\n if (options.log && typeof options.log !== 'boolean') {\n logger.info(`Options validation failed: Provided log in options is not valid`);\n throw new InvalidParamError(`The provided log in options is not valid`);\n }\n\n if (options.providerVersion && typeof options.providerVersion !== 'string') {\n logger.info(`Options validation failed: Provided providerVersion in options is not valid`);\n throw new InvalidParamError(`The provided providerVersion in options is not valid`);\n }\n}\n\n/**\n * Validates the modalOptions object\n * @param modalOptions - The modalOptions object to validate\n * @param functionName - The name of the function calling this validation\n * @param paramPrefix - Optional prefix for parameter names (e.g., 'modalOptions.')\n * @throws InvalidParamError if the modalOptions object is not valid\n */\nexport function validateModalOptions(modalOptions: ModalOptions, functionName: string, paramPrefix: string = ''): void {\n if (modalOptions.title !== undefined) {\n validateFunctionParams([\n { input: modalOptions.title, paramName: `${paramPrefix}title`, isString: true }\n ], functionName);\n }\n\n if (modalOptions.description !== undefined) {\n validateFunctionParams([\n { input: modalOptions.description, paramName: `${paramPrefix}description`, isString: true }\n ], functionName);\n }\n\n if (modalOptions.extensionUrl !== undefined) {\n validateURL(modalOptions.extensionUrl, functionName);\n validateFunctionParams([\n { input: modalOptions.extensionUrl, paramName: `${paramPrefix}extensionUrl`, isString: true }\n ], functionName);\n }\n\n if (modalOptions.darkTheme !== undefined) {\n if (typeof modalOptions.darkTheme !== 'boolean') {\n throw new InvalidParamError(`${paramPrefix}darkTheme prop must be a boolean`);\n }\n validateFunctionParams([\n { input: modalOptions.darkTheme, paramName: `${paramPrefix}darkTheme` }\n ], functionName);\n }\n\n if (modalOptions.modalPopupTimer !== undefined) {\n if (typeof modalOptions.modalPopupTimer !== 'number' || modalOptions.modalPopupTimer <= 0 || !Number.isInteger(modalOptions.modalPopupTimer)) {\n throw new InvalidParamError(`${paramPrefix}modalPopupTimer prop must be a valid time in minutes`);\n }\n validateFunctionParams([\n { input: modalOptions.modalPopupTimer, paramName: `${paramPrefix}modalPopupTimer` }\n ], functionName);\n }\n\n if (modalOptions.showExtensionInstallButton !== undefined) {\n if (typeof modalOptions.showExtensionInstallButton !== 'boolean') {\n throw new InvalidParamError(`${paramPrefix}showExtensionInstallButton prop must be a boolean`);\n }\n validateFunctionParams([\n { input: modalOptions.showExtensionInstallButton, paramName: `${paramPrefix}showExtensionInstallButton` }\n ], functionName);\n }\n}\n\n\nexport function hashObject(o: any) {\n try {\n const canonicalData = canonicalStringify(o);\n\n const messageHash = ethers.keccak256(new TextEncoder().encode(canonicalData));\n\n return messageHash;\n\n } catch (e) {\n logger.info(`Failed to hash object: ${(e as Error).message}`);\n throw new Error(`Failed to hash object: ${(e as Error).message}`);\n }\n}\n\n","import canonicalize from \"canonicalize\"\n\n/**\n * Canonically stringifies an object, so that the same object will always\n * produce the same string despite the order of keys\n */\nexport function canonicalStringify(params: { [key: string]: any } | undefined) {\n\tif (!params) {\n\t\treturn ''\n\t}\n\n\t// have to cast as ESM isn't correctly typing this\n\treturn (canonicalize as unknown as ((p: unknown) => string))(params) || ''\n}","import { OnError, TrustedData, VerifyProofResultFailure, VerifyProofResultSuccess } from './types'\nimport { TimeoutError } from './errors'\nimport loggerModule from './logger'\nimport { hashObject } from './validationUtils';\nimport { Proof } from './interfaces';\nconst logger = loggerModule.logger\n\n/**\n * Escapes special characters in a string for use in a regular expression\n * @param string - The input string to escape\n * @returns The input string with special regex characters escaped\n */\nexport function escapeRegExp(string: string): string {\n return string.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&'); // $& means the whole matched string\n}\n\n/**\n * Replaces all occurrences of a substring in a string\n * @param str - The original string\n * @param find - The substring to find\n * @param replace - The string to replace the found substrings with\n * @returns A new string with all occurrences of 'find' replaced by 'replace'\n */\nexport function replaceAll(str: string, find: string, replace: string): string {\n if (find === '') return str;\n return str.replace(new RegExp(escapeRegExp(find), 'g'), replace);\n}\n\n/**\n * Schedules a task to end an interval after a specified timeout\n * @param sessionId - The ID of the current session\n * @param intervals - A Map containing the intervals\n * @param onFailureCallback - Callback function to be called on failure\n * @param timeout - Timeout in milliseconds (default: 10 minutes)\n */\nexport function scheduleIntervalEndingTask(\n sessionId: string,\n intervals: Map<string, NodeJS.Timer>,\n onFailureCallback: OnError,\n timeout: number = 1000 * 60 * 10\n): void {\n setTimeout(() => {\n if (intervals.has(sessionId)) {\n const message = 'Interval ended without receiving proofs'\n onFailureCallback(new TimeoutError(message))\n logger.info(message)\n clearInterval(intervals.get(sessionId) as NodeJS.Timeout)\n intervals.delete(sessionId)\n }\n }, timeout)\n}\n\nexport const createVerifyProofResultSuccess = (\n proofs: Proof[],\n isTeeAttestationVerified?: boolean,\n isAttestorTeeAttestationVerified?: boolean,\n): VerifyProofResultSuccess => {\n return {\n isVerified: true,\n isTeeAttestationVerified,\n isAttestorTeeAttestationVerified,\n error: undefined,\n data: proofs.map(createTrustedDataFromProofData),\n publicData: getPublicDataFromProofs(proofs),\n }\n}\n\n\nexport const createVerifyProofResultFailure = (\n error: Error,\n isTeeAttestationVerified?: boolean,\n isAttestorTeeAttestationVerified?: boolean,\n): VerifyProofResultFailure => {\n return {\n isVerified: false,\n isTeeAttestationVerified,\n isAttestorTeeAttestationVerified,\n error,\n data: [],\n publicData: [],\n }\n}\n\nexport function createTrustedDataFromProofData(proof: Proof): TrustedData {\n try {\n const context = JSON.parse(proof.claimData.context)\n const { extractedParameters, ...rest } = context\n return {\n context: rest,\n extractedParameters: extractedParameters ?? {},\n }\n } catch {\n return {\n context: {},\n extractedParameters: {},\n }\n }\n}\n\nexport function getPublicDataFromProofs(proofs: Proof[]): any[] {\n const data: any[] = [];\n const seenData = new Set<string>();\n for (const proof of proofs) {\n const publicData = proof.publicData;\n if (publicData === null || publicData === undefined) {\n continue;\n }\n try {\n const hash = hashObject(publicData);\n if (seenData.has(hash)) {\n continue;\n }\n seenData.add(hash);\n } catch (_) {\n // if hash fails, we still push the data\n }\n data.push(publicData);\n }\n return data;\n}\n","// Base URL for the backend API\nexport let BACKEND_BASE_URL = \"https://api.reclaimprotocol.org\";\n\nexport function setBackendBaseUrl(url: string) {\n BACKEND_BASE_URL = url;\n}\n\n// Constant values used throughout the application\nexport const constants = {\n // Default callback URL for Reclaim protocol\n get DEFAULT_RECLAIM_CALLBACK_URL() {\n return `${BACKEND_BASE_URL}/api/sdk/callback?callbackId=`;\n },\n\n // Default error callback URL for Reclaim protocol\n get DEFAULT_RECLAIM_CANCEL_CALLBACK_URL() {\n return `${BACKEND_BASE_URL}/api/sdk/error-callback?callbackId=`;\n },\n\n // Default status URL for Reclaim sessions\n get DEFAULT_RECLAIM_STATUS_URL() {\n return `${BACKEND_BASE_URL}/api/sdk/session/`;\n },\n\n // Default attestors URL for Reclaim sessions\n get DEFAULT_ATTESTORS_URL() {\n return `${BACKEND_BASE_URL}/api/attestors`\n },\n\n DEFAULT_PROVIDER_CONFIGS_URL(providerId: string, exactProviderVersionString: string | null | undefined, allowedTags: string[] | null | undefined) {\n return `${BACKEND_BASE_URL}/api/providers/${providerId}/configs?versionNumber=${exactProviderVersionString || ''}&allowedTags=${allowedTags?.join(',') || ''}`\n },\n\n // Default portal URL\n DEFAULT_PORTAL_URL: 'https://portal.reclaimprotocol.org',\n\n // Default sharepage URL\n DEFAULT_APP_SHARE_PAGE_URL: 'https://share.reclaimprotocol.org/verifier',\n\n // URL for sharing Reclaim templates\n RECLAIM_SHARE_URL: 'https://share.reclaimprotocol.org/verifier/?template=',\n\n // Chrome extension URL for Reclaim Protocol\n CHROME_EXTENSION_URL: 'https://chromewebstore.google.com/detail/reclaim-extension/oafieibbbcepkmenknelhmgaoahamdeh'\n};\n\n// GCP Confidential Space Root CA — pinned. Rotates infrequently\n// (current cert valid 2024-2034). Used to verify attestor TEE attestation JWTs.\nexport const GCP_CONFIDENTIAL_SPACE_ROOT_CA = `-----BEGIN CERTIFICATE-----\n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\nuyT5CnJulxSC5CT1\n-----END CERTIFICATE-----`;\n\n// Matches an `attestor_public_key:0x<40-hex>` entry in a GCP Confidential\n// Space attestation JWT's `eat_nonce` claim.\nexport const ATTESTOR_NONCE_PATTERN = /^attestor_public_key:0x([0-9a-fA-F]{40})$/;\n\n// Expected `iss` claim on GCP Confidential Space attestation JWTs.\nexport const GCP_CONFIDENTIAL_SPACE_ISSUER = 'https://confidentialcomputing.googleapis.com';\n","import fetchRetry from \"fetch-retry\";\n\nconst MAX_RETRIES = 3;\nconst MAX_RETRY_DELAY_MS = 60 * 1000;\n\nconst isHttpResponseStatusRetryable = (statusCode: number) => {\n return statusCode === 408 || statusCode === 429 || statusCode >= 500;\n};\n\nconst getRetryDelay = (response: Response | null | undefined): number | undefined => {\n const retryAfter = response?.headers.get('Retry-After');\n if (!retryAfter) {\n return undefined;\n }\n\n const trimmed = retryAfter.trim();\n\n if (/^\\d+$/.test(trimmed)) {\n return Math.min(parseInt(trimmed, 10) * 1000, MAX_RETRY_DELAY_MS);\n }\n\n const date = new Date(trimmed);\n if (!isNaN(date.getTime())) {\n return Math.min(Math.max(0, date.getTime() - Date.now()), MAX_RETRY_DELAY_MS);\n }\n\n return undefined;\n};\n\nexport const http = {\n get client() {\n return fetchRetry(globalThis.fetch, {\n retries: MAX_RETRIES,\n retryDelay: function (attempt, _, response) {\n const delay = getRetryDelay(response);\n if (delay !== undefined) {\n return delay;\n }\n // attempt starts at 0. \n // Returns: 1000ms, 2000ms, 4000ms\n return Math.pow(2, attempt) * 1000;\n },\n retryOn: (attempt, error, response) => {\n if (attempt >= MAX_RETRIES) {\n return false;\n }\n\n if (response && Number.isInteger(response.status)) {\n return isHttpResponseStatusRetryable(response.status);\n }\n\n return !!error && error.name !== 'AbortError';\n },\n })\n },\n}\n","import {\n InitSessionError,\n UpdateSessionError,\n StatusUrlError,\n ProviderConfigFetchError\n} from \"./errors\";\nimport { InitSessionResponse, ProviderConfigResponse, ProviderHashRequirementsResponse, SessionStatus, StatusUrlResponse } from \"./types\";\nimport { validateFunctionParams } from \"./validationUtils\";\nimport { BACKEND_BASE_URL, constants } from './constants';\nimport { http } from \"./fetch\";\nimport loggerModule from './logger';\n\nconst logger = loggerModule.logger;\n\n/**\n * Initializes a session with the provided parameters\n * @param providerId - The ID of the provider\n * @param appId - The ID of the application\n * @param timestamp - The timestamp of the request\n * @param signature - The signature for authentication\n * @returns A promise that resolves to an InitSessionResponse\n * @throws InitSessionError if the session initialization fails\n */\nexport async function initSession(\n providerId: string,\n appId: string,\n timestamp: string,\n signature: string,\n versionNumber?: string\n): Promise<InitSessionResponse> {\n logger.info(`Initializing session for providerId: ${providerId}, appId: ${appId}`);\n try {\n const response = await http.client(`${BACKEND_BASE_URL}/api/sdk/init/session/`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ providerId, appId, timestamp, signature, versionNumber })\n });\n\n const res = await response.json();\n\n if (!response.ok) {\n logger.info(`Session initialization failed: ${res.message || 'Unknown error'}`);\n throw new InitSessionError(res.message || `Error initializing session with providerId: ${providerId}`);\n }\n\n return res as InitSessionResponse;\n } catch (err) {\n logger.info(`Failed to initialize session for providerId: ${providerId}, appId: ${appId}`, err);\n throw err;\n }\n}\n\n/**\n * Updates the status of an existing session\n * @param sessionId - The ID of the session to update\n * @param status - The new status of the session\n * @returns A promise that resolves to the update response\n * @throws UpdateSessionError if the session update fails\n */\nexport async function updateSession(sessionId: string, status: SessionStatus) {\n logger.info(`Updating session status for sessionId: ${sessionId}, new status: ${status}`);\n validateFunctionParams(\n [{ input: sessionId, paramName: 'sessionId', isString: true }],\n 'updateSession'\n );\n\n try {\n const response = await http.client(`${BACKEND_BASE_URL}/api/sdk/update/session/`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ sessionId, status })\n });\n\n const res = await response.json();\n\n if (!response.ok) {\n const errorMessage = `Error updating session with sessionId: ${sessionId}. Status Code: ${response.status}`;\n logger.info(errorMessage, res);\n throw new UpdateSessionError(errorMessage);\n }\n\n logger.info(`Session status updated successfully for sessionId: ${sessionId}`);\n return res;\n } catch (err) {\n const errorMessage = `Failed to update session with sessionId: ${sessionId}`;\n logger.info(errorMessage, err);\n throw new UpdateSessionError(`Error updating session with sessionId: ${sessionId}`);\n }\n}\n\n/**\n * Fetches the status URL for a given session ID\n * @param sessionId - The ID of the session to fetch the status URL for\n * @returns A promise that resolves to a StatusUrlResponse\n * @throws StatusUrlError if the status URL fetch fails\n */\nexport async function fetchStatusUrl(sessionId: string): Promise<StatusUrlResponse> {\n validateFunctionParams(\n [{ input: sessionId, paramName: 'sessionId', isString: true }],\n 'fetchStatusUrl'\n );\n\n try {\n const response = await http.client(`${constants.DEFAULT_RECLAIM_STATUS_URL}${sessionId}`, {\n method: 'GET',\n headers: { 'Content-Type': 'application/json' }\n });\n\n const res = await response.json();\n\n if (!response.ok) {\n const errorMessage = `Error fetching status URL for sessionId: ${sessionId}. Status Code: ${response.status}`;\n logger.info(errorMessage, res);\n throw new StatusUrlError(errorMessage);\n }\n\n return res as StatusUrlResponse;\n } catch (err) {\n const errorMessage = `Failed to fetch status URL for sessionId: ${sessionId}`;\n logger.info(errorMessage, err);\n throw new StatusUrlError(`Error fetching status URL for sessionId: ${sessionId}`);\n }\n}\n\nexport async function fetchProviderConfigs(providerId: string, exactProviderVersionString: string | null | undefined, allowedTags: string[] | null | undefined): Promise<ProviderConfigResponse> {\n validateFunctionParams(\n [\n { input: providerId, paramName: 'providerId', isString: true },\n ],\n 'fetchProviderConfigs'\n );\n\n if (exactProviderVersionString != null && exactProviderVersionString != undefined) {\n validateFunctionParams(\n [\n { input: exactProviderVersionString, paramName: 'exactProviderVersionString', isString: true },\n ],\n 'fetchProviderConfigs'\n );\n }\n\n try {\n const response = await http.client(constants.DEFAULT_PROVIDER_CONFIGS_URL(providerId, exactProviderVersionString, allowedTags), {\n method: 'GET',\n headers: { 'Content-Type': 'application/json' }\n });\n\n const res = await response.json();\n\n if (!response.ok) {\n const errorMessage = `Error fetching provider config for providerId: ${providerId}, exactProviderVersionString: ${exactProviderVersionString}. Status Code: ${response.status}`;\n logger.info(errorMessage, res);\n throw new ProviderConfigFetchError(errorMessage);\n }\n\n return res as ProviderConfigResponse;\n } catch (err) {\n const errorMessage = `Failed to fetch provider config for providerId: ${providerId}, exactProviderVersionString: ${exactProviderVersionString}`;\n logger.info(errorMessage, err);\n throw new ProviderConfigFetchError(`Error fetching provider config for providerId: ${providerId}, exactProviderVersionString: ${exactProviderVersionString}`);\n }\n}\n","import { ethers } from \"ethers\";\nimport { SignedClaim, TemplateData } from \"./types\";\nimport { createSignDataForClaim } from \"../witness\";\nimport { BACKEND_BASE_URL, constants } from \"./constants\";\nimport { replaceAll } from \"./helper\";\nimport { validateURL } from \"./validationUtils\";\nimport { BackendServerError, ProofNotVerifiedError } from \"./errors\";\nimport loggerModule from './logger';\nimport { WitnessData, type Proof } from \"./interfaces\";\nimport { http } from \"./fetch\";\n\nconst logger = loggerModule.logger;\n\n/**\n * Retrieves a shortened URL for the given URL\n * @param url - The URL to be shortened\n * @returns A promise that resolves to the shortened URL, or the original URL if shortening fails\n */\nexport async function getShortenedUrl(url: string): Promise<string> {\n logger.info(`Attempting to shorten URL: ${url}`);\n try {\n validateURL(url, 'getShortenedUrl')\n const response = await http.client(`${BACKEND_BASE_URL}/api/sdk/shortener`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ fullUrl: url })\n })\n const res = await response.json()\n if (!response.ok) {\n logger.info(`Failed to shorten URL: status=${response.status}`);\n return url;\n }\n const shortenedVerificationUrl = res.result.shortUrl\n return shortenedVerificationUrl\n } catch (err) {\n logger.info(`Error shortening URL: ${url}, Error: ${err}`);\n return url\n }\n}\n\n/**\n * Creates a link with embedded template data\n * @param templateData - The data to be embedded in the link\n * @param sharePagePath - The path to the share page (optional)\n * @returns A promise that resolves to the created link (shortened if possible)\n */\nexport async function createLinkWithTemplateData(templateData: TemplateData, sharePagePath?: string): Promise<string> {\n let template = encodeURIComponent(JSON.stringify(templateData))\n template = replaceAll(template, '(', '%28')\n template = replaceAll(template, ')', '%29')\n const fullLink = sharePagePath ? `${sharePagePath}/?template=${template}` : `${constants.RECLAIM_SHARE_URL}${template}`\n try {\n const shortenedLink = await getShortenedUrl(fullLink)\n return shortenedLink;\n } catch (err) {\n logger.info(`Error creating link for sessionId: ${templateData.sessionId}, Error: ${err}`);\n return fullLink;\n }\n}\n\n/**\n * Retrieves the list of witnesses for a given claim\n */\nexport async function getAttestors(): Promise<WitnessData[]> {\n const response = await http.client(constants.DEFAULT_ATTESTORS_URL)\n if (!response.ok) {\n response.body?.cancel()\n throw new BackendServerError(\n `Failed to fetch witness addresses: ${response.status}`\n )\n }\n\n const { data } = await response.json() as {\n data: {\n address: string\n }[]\n }\n return data.map(wt => ({ id: wt.address, url: '' }))\n}\n\n/**\n * Recovers the signers' addresses from a signed claim\n * @param claim - The signed claim object\n * @param signatures - The signatures associated with the claim\n * @returns An array of recovered signer addresses\n */\nexport function recoverSignersOfSignedClaim({\n claim,\n signatures\n}: SignedClaim): string[] {\n const dataStr = createSignDataForClaim({ ...claim })\n const signers = signatures.map(signature =>\n ethers.verifyMessage(dataStr, ethers.hexlify(signature)).toLowerCase()\n )\n return signers;\n}\n\n/**\n * Asserts that the proof is verified by checking the signatures and witness information\n * @param proof - The proof to verify\n * @param attestors - The attestors to check against\n * @throws {ProofNotVerifiedError} When the proof is not verified\n */\nexport async function assertVerifiedProof(\n proof: Proof,\n attestors: WitnessData[]\n) {\n const signers = recoverSignersOfSignedClaim({\n claim: proof.claimData,\n signatures: proof.signatures\n .map(signature => ethers.getBytes(signature))\n })\n // ensure at least one signer is an attestor\n if (!attestors\n .some(attestor => signers.includes(attestor.id.toLowerCase()))) {\n throw new ProofNotVerifiedError('Identifier mismatch')\n }\n}\n\n","import { ethers } from 'ethers';\nimport type { ClaimID, ClaimInfo, CompleteClaimData, HashableHttpProviderClaimParams, HttpProviderClaimParams } from './utils/types';\nimport { canonicalStringify } from './utils/strings';\n\nexport function createSignDataForClaim(data: CompleteClaimData): string {\n const identifier: ClaimID = getIdentifierFromClaimInfo(data);\n const lines: string[] = [\n identifier,\n data.owner.toLowerCase(),\n data.timestampS.toString(),\n data.epoch.toString(),\n ];\n\n return lines.join('\\n');\n}\n\nexport function getIdentifierFromClaimInfo(info: ClaimInfo): ClaimID {\n // re-canonicalize context if it's not empty\n let canonicalContext = info.context || '';\n if (canonicalContext.length > 0) {\n try {\n const ctx = JSON.parse(canonicalContext);\n canonicalContext = canonicalStringify(ctx);\n } catch (e) {\n throw new Error('unable to parse non-empty context. Must be JSON');\n }\n }\n\n const str = `${info.provider}\\n${info.parameters}\\n${canonicalContext}`;\n return ethers.keccak256(strToUint8Array(str)).toLowerCase();\n}\n\n/**\n * Computes the cryptographic claim hash(es) for the HTTP provider payload parameters.\n * \n * If the parameters comprise solely of rigid/required rules (or represents an extracted \n * attested payload that enforces all its defined elements), this computes and returns a single deterministic string.\n *\n * **Combinatorial Hashes Intention:**\n * If the payload configuration defines optional elements (`isOptional: true` on ResponseMatchSpec),\n * a single rule configuration inherently encompasses multiple logical subset definitions. \n * Since cryptographic hashes strictly enforce exact data byte-by-byte, \n * this function recursively computes a hash for every mathematically valid permutation of the optional subsets \n * (inclusive and exclusive) so the validator can verify the proof against any of the legitimate subset match signatures.\n * \n * @param params - The HTTP provider claim configuration or extracted attested parameters.\n * @returns A single keccak256 hash string, or an array of hex-string hashes if parameter optionality generates combinations.\n */\nexport function hashProofClaimParams(params: HttpProviderClaimParams): string | string[] {\n const serializedParams = getProviderParamsAsCanonicalizedString(params);\n\n if (Array.isArray(serializedParams)) {\n return serializedParams.map(serialized =>\n ethers.keccak256(strToUint8Array(serialized)).toLowerCase()\n );\n }\n\n return ethers.keccak256(\n strToUint8Array(serializedParams)\n ).toLowerCase()\n}\n\nfunction strToUint8Array(str: string): Uint8Array {\n return new TextEncoder().encode(str);\n}\n\n/**\n * Computes canonicalized string(s) for the provided HTTP parameter payload.\n *\n * **Architectural Concept**:\n * In Reclaim, proof security revolves around generating a deterministic Hash based on the JSON stringified keys\n * of matched specifications (e.g. `responseMatches` and `responseRedactions`).\n * When processing a Provider Configuration containing `isOptional` rules, the protocol doesn't require users to generate a \n * proof that matched *all* of the rules. A client could inherently omit any optional rules from claim before\n * starting claim creation to make a valid proof if the server payload may not contain them.\n * \n * To ensure the eventual Proof's Hash safely validates against the parent template's Requirement Hash, logic here \n * loops $2^N$ times using bitmask computation (where N = number of rule pairs) and yields canonically sorted \n * permutations for every sub-set of optional combinations. \n * Any combination forcefully omitting a mathematically required (`isOptional: false`) rule is stripped out.\n * \n * Note: When a user successfully generates a proof, their attested parameter payload does not contain `isOptional` tags\n * because the client sending request to attestor omits rules where data may not be present in response, \n * producing exactly 1 deterministic configuration subset (what the user actually proved!).\n * \n * @param params - The structured parameters.\n * @returns Serialized string or array of strings.\n */\nexport function getProviderParamsAsCanonicalizedString(params: HttpProviderClaimParams): string[] {\n // redaction cannot be more than response match\n const pairsCount = params?.responseMatches?.length ?? 0;\n const validCanonicalizedStrings: string[] = [];\n\n // Total combinations: 2^pairsCount\n const totalCombinations = 1 << pairsCount;\n\n for (let i = 0; i < totalCombinations; i++) {\n let isValidCombination = true;\n let includedCount = 0;\n\n const currentMatches: HashableHttpProviderClaimParams['responseMatches'] = [];\n const currentRedactions: HashableHttpProviderClaimParams['responseRedactions'] = [];\n\n for (let j = 0; j < pairsCount; j++) {\n const isIncluded = (i & (1 << j)) !== 0;\n const match = params?.responseMatches?.[j];\n const redaction = params?.responseRedactions?.[j];\n\n if (isIncluded) {\n if (match) {\n currentMatches.push({\n value: match.value ?? '',\n // This needs to be explicitly specified and absence should cause error, but we're choosing to ignore it in this case\n type: match.type ?? 'contains',\n invert: match.invert || undefined,\n });\n }\n if (redaction) {\n currentRedactions.push({\n xPath: redaction.xPath ?? '',\n jsonPath: redaction.jsonPath ?? '',\n regex: redaction.regex ?? '',\n hash: redaction.hash || undefined,\n });\n }\n includedCount++;\n } else {\n if (match && !match.isOptional) {\n isValidCombination = false;\n break;\n }\n }\n }\n\n if (isValidCombination && includedCount > 0) {\n const filteredParams: HashableHttpProviderClaimParams = {\n url: params?.url ?? '',\n // METHOD needs to be explicitly specified and absence or unknown method should cause error, but we're choosing to ignore it in this case\n method: params?.method ?? 'GET',\n body: params?.body ?? '',\n responseMatches: currentMatches,\n responseRedactions: currentRedactions,\n };\n\n validCanonicalizedStrings.push(canonicalStringify(filteredParams));\n }\n }\n\n // If there are no rules initially, we still want to stringify the base params\n if (validCanonicalizedStrings.length === 0) {\n const filteredParams: HashableHttpProviderClaimParams = {\n url: params?.url ?? '',\n method: params?.method ?? 'GET',\n body: params?.body ?? '',\n responseMatches: [],\n responseRedactions: [],\n };\n return [canonicalStringify(filteredParams)];\n }\n\n return validCanonicalizedStrings;\n}\n","import QRCode from 'qrcode';\nimport loggerModule from './logger';\nimport { ModalOptions } from './types';\nimport { constants } from './constants';\nconst logger = loggerModule.logger;\n\nexport class QRCodeModal {\n private modalId: string;\n private options: ModalOptions;\n private autoCloseTimer?: NodeJS.Timeout;\n private countdownTimer?: NodeJS.Timeout;\n private countdownSeconds: number = 60;\n\n constructor(options: ModalOptions = {}) {\n this.modalId = 'reclaim-qr-modal';\n this.options = {\n title: 'Verify with Reclaim',\n description: 'Scan the QR code with your mobile device to complete verification',\n extensionUrl: constants.CHROME_EXTENSION_URL,\n darkTheme: false,\n modalPopupTimer: 1, // default to 1 minute\n showExtensionInstallButton: false, // default to false\n ...options\n };\n }\n\n async show(requestUrl: string): Promise<void> {\n try {\n // Remove existing modal if present\n this.close();\n\n // Create modal HTML\n const modalHTML = this.createModalHTML();\n\n // Add modal to DOM\n document.body.insertAdjacentHTML('beforeend', modalHTML);\n\n // Generate QR code\n await this.generateQRCode(requestUrl, 'reclaim-qr-code');\n\n // Add event listeners\n this.addEventListeners();\n\n // Start auto-close timer\n this.startAutoCloseTimer();\n\n } catch (error) {\n logger.info('Error showing QR code modal:', error);\n throw error;\n }\n }\n\n close(): void {\n // Clear timers\n if (this.autoCloseTimer) {\n clearTimeout(this.autoCloseTimer);\n this.autoCloseTimer = undefined;\n }\n if (this.countdownTimer) {\n clearInterval(this.countdownTimer);\n this.countdownTimer = undefined;\n }\n\n const modal = document.getElementById(this.modalId);\n if (modal) {\n modal.remove();\n }\n if (this.options.onClose) {\n this.options.onClose();\n }\n }\n\n private getThemeStyles() {\n const isDark = this.options.darkTheme;\n\n return {\n modalBackground: isDark ? 'rgba(0, 0, 0, 0.8)' : 'rgba(0, 0, 0, 0.5)',\n cardBackground: isDark ? '#1f2937' : 'white',\n titleColor: isDark ? '#f9fafb' : '#1f2937',\n textColor: isDark ? '#d1d5db' : '#6b7280',\n qrBackground: isDark ? '#374151' : '#f9fafb',\n tipBackground: isDark ? '#1e40af' : '#f0f9ff',\n tipBorder: isDark ? '#1e40af' : '#e0f2fe',\n tipTextColor: isDark ? '#dbeafe' : '#0369a1',\n buttonBackground: isDark ? '#374151' : '#f3f4f6',\n buttonColor: isDark ? '#f9fafb' : '#374151',\n buttonHoverBackground: isDark ? '#4b5563' : '#e5e7eb',\n countdownColor: isDark ? '#6b7280' : '#9ca3af',\n progressBackground: isDark ? '#4b5563' : '#e5e7eb',\n progressGradient: isDark\n ? 'linear-gradient(90deg, #3b82f6 0%, #2563eb 50%, #1d4ed8 100%)'\n : 'linear-gradient(90deg, #2563eb 0%, #1d4ed8 50%, #1e40af 100%)',\n linkColor: isDark ? '#60a5fa' : '#2563eb',\n extensionButtonBackground: isDark ? '#1e40af' : '#2563eb',\n extensionButtonHover: isDark ? '#1d4ed8' : '#1d4ed8'\n };\n }\n\n private createModalHTML(): string {\n const styles = this.getThemeStyles();\n\n return `\n <div id=\"${this.modalId}\" style=\"\n position: fixed;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n background-color: ${styles.modalBackground};\n display: flex;\n justify-content: center;\n align-items: center;\n z-index: 10000;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n \">\n <div style=\"\n background: ${styles.cardBackground};\n border-radius: 12px;\n padding: 32px;\n max-width: 400px;\n width: 90%;\n text-align: center;\n box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);\n position: relative;\n \">\n <button id=\"reclaim-close-modal\" style=\"\n position: absolute;\n top: 16px;\n right: 16px;\n background: none;\n border: none;\n cursor: pointer;\n padding: 4px;\n border-radius: 6px;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: background-color 0.2s;\n width: 32px;\n height: 32px;\n \"\n onmouseover=\"this.style.backgroundColor='${styles.buttonHoverBackground}'\"\n onmouseout=\"this.style.backgroundColor='transparent'\"\n title=\"Close modal\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M12 4L4 12M4 4L12 12\" stroke=\"${styles.buttonColor}\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n </button>\n \n <h2 style=\"\n margin: 0 0 16px 0;\n font-size: 24px;\n font-weight: 600;\n color: ${styles.titleColor};\n \">${this.options.title}</h2>\n \n <p style=\"\n margin: 0 0 24px 0;\n color: ${styles.textColor};\n font-size: 14px;\n line-height: 1.5;\n \">${this.options.description}</p>\n \n <div id=\"reclaim-qr-code\" style=\"\n margin: 0 auto 24px auto;\n background: ${styles.qrBackground};\n border-radius: 8px;\n display: inline-block;\n \"></div>\n \n ${this.options.showExtensionInstallButton ? `\n <div style=\"\n margin-bottom: 24px;\n padding: 16px;\n background: ${styles.tipBackground};\n border: 1px solid ${styles.tipBorder};\n border-radius: 8px;\n \">\n <p style=\"\n margin: 0 0 12px 0;\n font-size: 14px;\n color: ${styles.tipTextColor};\n font-weight: 500;\n \">💡 For a better experience</p>\n <p style=\"\n margin: 0 0 12px 0;\n font-size: 13px;\n color: ${styles.tipTextColor};\n line-height: 1.4;\n \">Install our browser extension for seamless verification without QR codes</p>\n <a href=\"${this.options.extensionUrl}\" \n target=\"_blank\" \n style=\"\n display: inline-block;\n background: ${styles.extensionButtonBackground};\n color: white;\n text-decoration: none;\n padding: 8px 16px;\n border-radius: 6px;\n font-size: 12px;\n font-weight: 500;\n transition: background-color 0.2s;\n \"\n onmouseover=\"this.style.backgroundColor='${styles.extensionButtonHover}'\"\n onmouseout=\"this.style.backgroundColor='${styles.extensionButtonBackground}'\">\n Install Extension\n </a>\n </div>` : ''}\n \n <div style=\"margin-top: 16px;\">\n <div id=\"reclaim-countdown\" style=\"\n font-size: 12px;\n color: ${styles.countdownColor};\n font-weight: 400;\n margin-bottom: 8px;\n \">Auto-close in 1:00</div>\n \n <div style=\"\n width: 100%;\n height: 4px;\n background-color: ${styles.progressBackground};\n border-radius: 2px;\n overflow: hidden;\n \">\n <div id=\"reclaim-progress-bar\" style=\"\n width: 100%;\n height: 100%;\n background: ${styles.progressGradient};\n border-radius: 2px;\n transition: width 1s linear;\n \"></div>\n </div>\n </div>\n </div>\n </div>\n `\n }\n\n private async generateQRCode(text: string, containerId: string): Promise<void> {\n try {\n const dataUrl = await QRCode.toDataURL(text, {\n width: 200,\n margin: 1,\n color: {\n dark: '#000000',\n light: '#ffffff'\n }\n });\n\n const container = document.getElementById(containerId);\n const styles = this.getThemeStyles();\n\n if (container) {\n container.innerHTML = `\n <img src=\"${dataUrl}\"\n alt=\"QR Code for Reclaim verification\"\n style=\"width: 200px; height: 200px; border-radius: 4px;\">\n <div style=\"display: none; padding: 20px; color: ${styles.textColor}; font-size: 14px;\">\n <a href=\"${text}\" target=\"_blank\" style=\"color: ${styles.linkColor}; text-decoration: underline;\">\n Click here to open verification link\n </a>\n </div>\n `;\n }\n } catch (error) {\n logger.info('Error generating QR code:', error);\n // Fallback to text link\n const container = document.getElementById(containerId);\n const styles = this.getThemeStyles();\n\n if (container) {\n container.innerHTML = `\n <div style=\"padding: 20px; color: ${styles.textColor}; font-size: 14px;\">\n <a href=\"${text}\" target=\"_blank\" style=\"color: ${styles.linkColor}; text-decoration: underline;\">\n Click here to open verification link\n </a>\n </div>\n `;\n }\n }\n }\n\n private addEventListeners(): void {\n const closeButton = document.getElementById('reclaim-close-modal');\n const modal = document.getElementById(this.modalId);\n\n const closeModal = () => {\n this.close();\n };\n\n if (closeButton) {\n closeButton.addEventListener('click', closeModal);\n }\n\n // Close on backdrop click\n if (modal) {\n modal.addEventListener('click', (e) => {\n if (e.target === modal) {\n closeModal();\n }\n });\n }\n\n // Close on escape key\n const handleEscape = (e: KeyboardEvent) => {\n if (e.key === 'Escape') {\n closeModal();\n document.removeEventListener('keydown', handleEscape);\n }\n };\n document.addEventListener('keydown', handleEscape);\n }\n\n private startAutoCloseTimer(): void {\n this.countdownSeconds = (this.options.modalPopupTimer || 1) * 60; // default to 1 minute\n\n // Update countdown display immediately\n this.updateCountdownDisplay();\n\n // Start countdown timer (updates every second)\n this.countdownTimer = setInterval(() => {\n this.countdownSeconds--;\n this.updateCountdownDisplay();\n\n if (this.countdownSeconds <= 0) {\n this.close();\n }\n }, 1000);\n\n // Set auto-close timer for the number of minutes specified in the options in milliseconds\n const autoCloseMs = (this.options.modalPopupTimer || 1) * 60 * 1000;\n this.autoCloseTimer = setTimeout(() => {\n this.close();\n }, autoCloseMs);\n }\n\n private updateCountdownDisplay(): void {\n const countdownElement = document.getElementById('reclaim-countdown');\n const progressBar = document.getElementById('reclaim-progress-bar');\n\n if (countdownElement) {\n const minutes = Math.floor(this.countdownSeconds / 60);\n const seconds = this.countdownSeconds % 60;\n const timeString = `${minutes}:${seconds.toString().padStart(2, '0')}`;\n countdownElement.textContent = `Auto-close in ${timeString}`;\n }\n\n if (progressBar) {\n // Calculate progress percentage (reverse: starts at 100%, goes to 0%)\n const totalSeconds = (this.options.modalPopupTimer || 1) * 60;\n const progressPercentage = (this.countdownSeconds / totalSeconds) * 100;\n progressBar.style.width = `${progressPercentage}%`;\n }\n }\n}","import { DeviceType } from \"./types\";\n\nconst navigatorDefined = typeof navigator !== 'undefined';\nconst windowDefined = typeof window !== 'undefined';\n\nconst userAgent = navigatorDefined ? navigator.userAgent.toLowerCase() : '';\nconst userAgentData = navigatorDefined ? (navigator as Navigator & {\n userAgentData?: {\n platform: string;\n brands?: { brand: string; version: string }[];\n }\n}).userAgentData : undefined;\n\n// Cache for device detection results\nlet cachedDeviceType: DeviceType.DESKTOP | DeviceType.MOBILE | null = null;\nlet cachedMobileType: DeviceType.ANDROID | DeviceType.IOS | null = null;\n\n/**\n * Safe wrapper for window.matchMedia\n */\nfunction safeMatchMedia(query: string): boolean {\n try {\n return window.matchMedia?.(query)?.matches || false;\n } catch {\n return false;\n }\n}\n\n/**\n * Safe wrapper for CSS.supports\n */\nfunction safeCSSSupports(property: string, value: string): boolean {\n try {\n return CSS?.supports?.(property, value) || false;\n } catch {\n return false;\n }\n}\n\n/**\n * Safe wrapper for document.querySelector\n */\nfunction safeQuerySelector(selector: string): boolean {\n try {\n return document?.querySelector?.(selector) !== null;\n } catch {\n return false;\n }\n}\n\n/**\n * Highly accurate device type detection - returns only 'desktop' or 'mobile'\n * Uses multiple detection methods and scoring system for maximum accuracy\n * @returns {DeviceType.DESKTOP | DeviceType.MOBILE} The detected device type\n */\nexport function getDeviceType(): DeviceType.DESKTOP | DeviceType.MOBILE {\n // Return cached result if available\n if (cachedDeviceType !== null) {\n return cachedDeviceType;\n }\n\n // Early return for server-side rendering - assume desktop\n if (!navigatorDefined || !windowDefined) {\n return DeviceType.DESKTOP;\n }\n\n let mobileScore = 0;\n const CONFIDENCE_THRESHOLD = 3; // Need at least 3 points to be considered mobile\n \n // ====== Device Characteristics ======\n \n // Screen dimensions\n const screenWidth = window.innerWidth || window.screen?.width || 0;\n const screenHeight = window.innerHeight || window.screen?.height || 0;\n const hasSmallScreen = screenWidth <= 480 || screenHeight <= 480;\n const hasLargeScreen = screenWidth > 1024 && screenHeight > 768;\n \n // Touch capabilities\n const hasTouch = 'ontouchstart' in window || \n (navigatorDefined && navigator.maxTouchPoints > 0);\n const hasPreciseMouse = safeMatchMedia('(pointer: fine)');\n const canHover = safeMatchMedia('(hover: hover)');\n const hasMouseAndTouch = hasTouch && hasPreciseMouse; // Touchscreen laptop\n \n // Windows touch laptop detection (used for exceptions)\n const isWindowsTouchLaptop = /Windows/i.test(userAgent) && \n hasPreciseMouse && \n hasTouch;\n \n // ====== Mobile Indicators (Add Points) ======\n \n // Touch without mouse = likely mobile (+2 points)\n // Touch with mouse = touchscreen laptop (+1 point)\n if (hasTouch && !hasMouseAndTouch) {\n mobileScore += 2;\n } else if (hasMouseAndTouch) {\n mobileScore += 1;\n }\n \n // Small screen is mobile indicator (+2 points)\n // Exception: Windows touch laptops with precise mouse should not be penalized for small screens\n if (hasSmallScreen && !isWindowsTouchLaptop) {\n mobileScore += 2;\n }\n \n // Mobile user agent is strong indicator (+3 points)\n const hasMobileUserAgent = /android|webos|iphone|ipad|ipod|blackberry|iemobile|opera mini|mobile/i.test(userAgent);\n if (hasMobileUserAgent) {\n mobileScore += 3;\n }\n \n // Mobile APIs only count if combined with other mobile signs (+2 points)\n // Exception: Desktop Safari and Windows touch laptops have mobile APIs but should not be considered mobile\n const hasMobileAPIs = 'orientation' in window || \n 'DeviceMotionEvent' in window ||\n 'DeviceOrientationEvent' in window;\n const isDesktopSafari = /Safari/i.test(userAgent) && \n !/Mobile/i.test(userAgent) && \n /Mac|Intel/i.test(userAgent);\n if (hasMobileAPIs && (hasSmallScreen || hasMobileUserAgent) && !isDesktopSafari && !isWindowsTouchLaptop) {\n mobileScore += 2;\n }\n \n // High DPI with small screen = mobile (+1 point)\n const hasHighDPI = window.devicePixelRatio > 1.5;\n if (hasHighDPI && hasSmallScreen) {\n mobileScore += 1;\n }\n \n // Viewport meta tag with small screen = mobile optimized (+1 point)\n const hasViewportMeta = safeQuerySelector('meta[name=\"viewport\"]');\n if (hasViewportMeta && hasSmallScreen) {\n mobileScore += 1;\n }\n \n // iPad Pro special case: Mac user agent with touch (+2 points)\n const isPadProInDesktopMode = userAgent.includes('macintosh') && hasTouch;\n if (isPadProInDesktopMode) {\n mobileScore += 2;\n }\n \n // ====== Desktop Indicators (Subtract Points) ======\n \n // Large screen with mouse = desktop (-3 points)\n if (hasLargeScreen && hasPreciseMouse) {\n mobileScore -= 3;\n } \n // Large screen without touch = desktop (-2 points)\n else if (hasLargeScreen && !hasTouch) {\n mobileScore -= 2;\n }\n \n // Can hover with precise pointer = has real mouse (-2 points)\n if (hasPreciseMouse && canHover) {\n mobileScore -= 2;\n }\n \n // Windows user agent = strong desktop indicator (-3 points)\n const isWindowsDesktop = /Windows/i.test(userAgent) && !hasMobileUserAgent;\n if (isWindowsDesktop) {\n mobileScore -= 3;\n }\n\n // Cache and return the result\n cachedDeviceType = mobileScore >= CONFIDENCE_THRESHOLD ? DeviceType.MOBILE : DeviceType.DESKTOP;\n return cachedDeviceType;\n}\n\n/**\n * Highly accurate mobile device type detection - returns only 'android' or 'ios'\n * Should only be called when getDeviceType() returns 'mobile'\n * @returns {DeviceType.ANDROID | DeviceType.IOS} The detected mobile device type\n */\nexport function getMobileDeviceType(): DeviceType.ANDROID | DeviceType.IOS {\n // Return cached result if available\n if (cachedMobileType !== null) {\n return cachedMobileType;\n }\n\n // Early return for server-side rendering - default to Android\n if (!navigatorDefined || !windowDefined) {\n return DeviceType.ANDROID;\n }\n\n const ua = navigator.userAgent;\n \n // ====== iOS Detection ======\n \n // Direct iOS device detection\n const hasIOSDeviceName = /iPad|iPhone|iPod/i.test(ua);\n if (hasIOSDeviceName) {\n cachedMobileType = DeviceType.IOS;\n return cachedMobileType;\n }\n \n // iPad Pro detection (reports as Mac but has touch)\n const isMacWithTouch = /Macintosh|MacIntel/i.test(ua) && 'ontouchstart' in window;\n const isMacOSWithTouch = userAgentData?.platform === 'macOS' && 'ontouchstart' in window;\n if (isMacWithTouch || isMacOSWithTouch) {\n cachedMobileType = DeviceType.IOS;\n return cachedMobileType;\n }\n \n // iOS-specific APIs\n const hasIOSPermissionAPI = typeof (window as any).DeviceMotionEvent?.requestPermission === 'function';\n const hasIOSTouchCallout = safeCSSSupports('-webkit-touch-callout', 'none');\n if (hasIOSPermissionAPI || hasIOSTouchCallout) {\n cachedMobileType = DeviceType.IOS;\n return cachedMobileType;\n }\n \n // Safari without Chrome (iOS WebKit) - but not desktop Safari\n const isIOSWebKit = /WebKit/i.test(ua) && \n !/Chrome|CriOS|Android/i.test(ua) && \n !/Macintosh|MacIntel/i.test(ua);\n if (isIOSWebKit) {\n cachedMobileType = DeviceType.IOS;\n return cachedMobileType;\n }\n \n // ====== Android Detection ======\n \n // Direct Android detection\n const hasAndroidKeyword = /Android/i.test(ua);\n if (hasAndroidKeyword) {\n cachedMobileType = DeviceType.ANDROID;\n return cachedMobileType;\n }\n \n // Mobile Chrome (usually Android)\n const isChromeOnMobile = (window as any).chrome && /Mobile/i.test(ua);\n if (isChromeOnMobile) {\n cachedMobileType = DeviceType.ANDROID;\n return cachedMobileType;\n }\n \n // Default fallback - Android is more common globally\n cachedMobileType = DeviceType.ANDROID;\n return cachedMobileType;\n}\n\n/**\n * Convenience method to check if current device is mobile\n * @returns {boolean} True if device is mobile\n */\nexport function isMobileDevice(): boolean {\n return getDeviceType() === DeviceType.MOBILE;\n}\n\n/**\n * Convenience method to check if current device is desktop\n * @returns {boolean} True if device is desktop\n */\nexport function isDesktopDevice(): boolean {\n return getDeviceType() === DeviceType.DESKTOP;\n}\n\n/**\n * Clear cached device detection results (useful for testing)\n */\nexport function clearDeviceCache(): void {\n cachedDeviceType = null;\n cachedMobileType = null;\n}\n\n// Export safe wrappers for testing\nexport { safeMatchMedia, safeCSSSupports, safeQuerySelector };","import { ethers } from 'ethers';\n\nexport const ATTESTATION_NONCE_DOMAIN = 'RECLAIM_TEE_NONCE_V1';\n\nexport function generateAttestationNonce(\n appSecret: string,\n applicationId: string,\n sessionId: string,\n timestamp: string\n): string {\n const noncePayload = [\n ATTESTATION_NONCE_DOMAIN,\n applicationId,\n sessionId,\n timestamp,\n appSecret\n ].join(':');\n\n return ethers.keccak256(ethers.toUtf8Bytes(noncePayload)).replace(/^0x/i, '');\n}\n","import { hashProofClaimParams } from \"../witness\";\nimport { InvalidRequestSpecError, ProviderConfigFetchError } from \"./errors\";\nimport { fetchProviderConfigs } from \"./sessionUtils\";\nimport loggerModule from './logger';\nimport { Proof } from \"./interfaces\";\n\nconst logger = loggerModule.logger;\n\n/**\n * Fetches the provider configuration by the providerId and its version; and constructs the robust hash requirements needed for proof validation.\n * It resolves both explicitly required HTTP requests and allowed injected requests based on the provider version.\n * \n * See also:\n * \n * * `ReclaimProofRequest.getProviderHashRequirements()` - An alternative of this function to get the expected hashes for a proof request. The result can be provided in verifyProof function's `config` parameter for proof validation.\n * * `getProviderHashRequirementsFromSpec()` - An alternative of this function to get the expected hashes from a provider spec. The result can be provided in verifyProof function's `config` parameter for proof validation.\n * \n * @param providerId - The unique identifier of the selected provider.\n * @param exactProviderVersionString - The specific version string of the provider configuration to ensure deterministic validation.\n * @returns A promise that resolves to `ProviderHashRequirementsConfig` representing the expected hashes for proof validation.\n */\nexport async function fetchProviderHashRequirementsBy(providerId: string, exactProviderVersionString: string | null | undefined, allowedTags: string[] | null | undefined, proofs?: Proof[]): Promise<ProviderHashRequirementsConfig[]> {\n const providerResponse = await fetchProviderConfigs(providerId, exactProviderVersionString, allowedTags);\n\n try {\n const providerConfigs = providerResponse.providers;\n if (!providerConfigs || !providerConfigs.length) {\n throw new ProviderConfigFetchError(`No provider configs found for providerId: ${providerId}, exactProviderVersionString: ${exactProviderVersionString}`);\n }\n\n const hashRequirements: ProviderHashRequirementsConfig[] = [];\n\n for (const providerConfig of providerConfigs) {\n const requestSpec = getProviderHashRequirementSpecFromProviderConfig(providerConfig, proofs);\n hashRequirements.push(getProviderHashRequirementsFromSpec(requestSpec));\n }\n\n return hashRequirements;\n } catch (e) {\n const errorMessage = `Failed to fetch provider hash requirements for providerId: ${providerId}, exactProviderVersionString: ${exactProviderVersionString}`;\n logger.info(errorMessage, e);\n throw new ProviderConfigFetchError(`Error fetching provider hash requirements for providerId: ${providerId}, exactProviderVersionString: ${exactProviderVersionString}`);\n }\n}\n\n/**\n * Generates an array of `RequestSpec` objects by replacing template parameters with their corresponding values.\n * \n * If the input template includes `templateParams` (e.g., `['param1', 'param2']`), this function will \n * cartesian-map (or pairwise-map) the provided `templateParameters` record (e.g., `{ param1: ['v1', 'v2'], param2: ['a1', 'a2'] }`) \n * to generate multiple unique `RequestSpec` configurations.\n * \n * The function ensures that:\n * 1. Parameters strictly specified in `template.templateParams` are found.\n * 2. All specified template parameters arrays have the exact same length (pairwise mapping).\n * 3. String replacements are fully applied (all occurrences) to `responseMatches` (value) and `responseRedactions` (jsonPath, xPath, regex).\n * \n * @param requestSpecTemplates - The base template `RequestSpec` containing parameter placeholders.\n * @param templateParameters - A record mapping parameter names to arrays of strings representing the extracted values.\n * @returns An array of fully constructed `RequestSpec` objects with templates replaced.\n * @throws {InvalidRequestSpecError} If required parameters are missing or parameter value arrays have mismatched lengths.\n */\nexport function generateSpecsFromRequestSpecTemplate(requestSpecTemplates: RequestSpec[], templateParameters: Record<string, string[]>): RequestSpec[] {\n if (!requestSpecTemplates) return [];\n\n const generatedRequestTemplate: RequestSpec[] = [];\n\n for (const template of requestSpecTemplates) {\n const templateVariables = template.templateParams ?? [];\n if (!templateVariables.length) {\n generatedRequestTemplate.push(template);\n continue;\n }\n\n const templateParamsPairMatch = Object.entries(templateParameters).filter(([key, value]) => templateVariables.includes(key) && value.length)\n const hasAllTemplateVariableMatch = templateParamsPairMatch.length === templateVariables.length;\n if (!hasAllTemplateVariableMatch) {\n throw new InvalidRequestSpecError(`Not all template variables are present for template`);\n }\n\n // check all template variables have same length\n const templateParamsPairMatchLength = templateParamsPairMatch[0][1].length;\n const allTemplateVariablesHaveSameLength = templateParamsPairMatch.every(([key, value]) => value.length === templateParamsPairMatchLength);\n if (!allTemplateVariablesHaveSameLength) {\n throw new InvalidRequestSpecError(`Not all template variables have same length for template`);\n }\n\n const getRequestSpecVariableTemplate = (key: string) => {\n return `\\${${key}}`;\n }\n\n for (let i = 0; i < templateParamsPairMatchLength; i++) {\n const currentTemplateParams: Record<string, string> = {};\n for (const [key, values] of templateParamsPairMatch) {\n currentTemplateParams[key] = values[i];\n }\n\n const spec: RequestSpec = {\n ...template,\n responseMatches: template.responseMatches ? template.responseMatches.map(m => ({ ...m })) : [],\n responseRedactions: template.responseRedactions ? template.responseRedactions.map(r => ({ ...r })) : [],\n }\n\n for (const match of spec.responseMatches) {\n for (const [key, value] of Object.entries(currentTemplateParams)) {\n match.value = match.value.split(getRequestSpecVariableTemplate(key)).join(value);\n }\n }\n\n for (const redaction of spec.responseRedactions) {\n for (const [key, value] of Object.entries(currentTemplateParams)) {\n redaction.jsonPath = redaction.jsonPath.split(getRequestSpecVariableTemplate(key)).join(value);\n redaction.xPath = redaction.xPath.split(getRequestSpecVariableTemplate(key)).join(value);\n redaction.regex = redaction.regex.split(getRequestSpecVariableTemplate(key)).join(value);\n }\n }\n\n generatedRequestTemplate.push(spec);\n }\n }\n\n return generatedRequestTemplate\n}\n\nexport function takeTemplateParametersFromProofs(proofs?: Proof[]): Record<string, string[]> {\n return takePairsWhereValueIsArray(proofs?.map(it => JSON.parse(it.claimData.context).extractedParameters as Record<string, string>).reduce((acc, it) => ({ ...acc, ...it }), {}));\n}\n\nexport function takePairsWhereValueIsArray(o: Record<string, string> | undefined): Record<string, string[]> {\n if (!o) return {};\n const pairs: Record<string, string[]> = {};\n for (const [key, value] of Object.entries(o)) {\n if (Array.isArray(value) && value.length) {\n pairs[key] = value;\n } else {\n try {\n const parsedValue = JSON.parse(value);\n if (Array.isArray(parsedValue) && parsedValue.length) {\n pairs[key] = parsedValue;\n }\n } catch (_) {\n // ignore parsing errors\n }\n }\n }\n return pairs;\n}\n\n/**\n * Builds and returns raw hash requirement spec that can be used with `getProviderHashRequirementsFromSpec` to computes the expected proof hashes for a provider configuration\n * by combining its explicitly required requests and allowed injected requests.\n * It resolves template parameters from provided proofs to generate the final request specifications.\n * \n * @param providerConfig - The provider configuration containing request data and allowed injected requests.\n * @param proofs - Optional array of proofs used to extract template parameters for resolving placeholders in injected requests.\n * @returns A structured configuration containing that can be used with `getProviderHashRequirementsFromSpec` to compute the hashes.\n */\nexport function getProviderHashRequirementSpecFromProviderConfig(providerConfig: ReclaimProviderConfigWithRequestSpec, proofs?: Proof[]): ProviderHashRequirementSpec {\n return {\n requests: [...(providerConfig?.requestData ?? []), ...generateSpecsFromRequestSpecTemplate(providerConfig?.allowedInjectedRequestData ?? [], takeTemplateParametersFromProofs(proofs))],\n };\n}\n\n/**\n * Transforms a raw provider hash requirement specification into a structured configuration for proof validation.\n * It computes the proof hashes for both required and allowed extra requests to correctly match uploaded proofs.\n * \n * See also:\n * \n * * `fetchProviderHashRequirementsBy()` - An alternative of this function to get the expected hashes for a provider version by providing providerId and exactProviderVersionString. The result can be provided in verifyProof function's `config` parameter for proof validation.\n * * `ReclaimProofRequest.getProviderHashRequirements()` - An alternative of this function to get the expected hashes for a proof request. The result can be provided in verifyProof function's `config` parameter for proof validation.\n *\n * @param spec - The raw provider specifications including required and allowed requests.\n * @returns A structured configuration containing computed required and allowed hashes for validation.\n */\nexport function getProviderHashRequirementsFromSpec(spec: ProviderHashRequirementSpec): ProviderHashRequirementsConfig {\n return {\n hashes: spec?.requests?.map(hashRequestSpec) || [],\n };\n}\n\n/**\n * Computes the claim hash for a specific request specification based on its properties.\n *\n * @param request - The HTTP request specification (e.g., URL, method, sniffs).\n * @returns A string representing the hashed proof claim parameters.\n */\nexport function hashRequestSpec(request: RequestSpec): HashRequirement {\n const hash = hashProofClaimParams({\n ...request,\n // Body is strictly empty unless body sniff is explicitly enabled\n body: request.bodySniff.enabled ? request.bodySniff.template : '',\n });\n\n return {\n value: hash,\n required: request.required,\n multiple: request.multiple,\n }\n}\n\n/**\n * Represents the raw specification of hash requirements provided by a provider's configuration.\n */\nexport interface ProviderHashRequirementSpec {\n /** List of request specs that can match with HTTP requests to create a proof using Reclaim Protocol */\n requests: RequestSpec[] | undefined;\n}\n\n/**\n * The structured hash requirements configuration used during proof verification and content validation.\n */\nexport type ProviderHashRequirementsConfig = {\n /** \n * Array of computed hash requirements that must be satisfied by the proofs.\n */\n hashes: HashRequirement[];\n}\n\n/**\n * Describes a hash requirement for a proof.\n */\nexport type HashRequirement = {\n /**\n * The hash value(s) to match. An array represents multiple valid hashes for optional configurations.\n */\n value: string | string[];\n /**\n * Whether the hash is required to be present in the proof.\n * Defaults to true\n */\n required?: boolean;\n /**\n * Whether the hash can appear multiple times in the proof.\n * Defaults to false\n */\n multiple?: boolean;\n}\n\nexport interface ReclaimProviderConfigWithRequestSpec {\n requestData: InterceptorRequestSpec[];\n allowedInjectedRequestData: InjectedRequestSpec[];\n}\n\n/**\n * Specific marker interface for intercepted request specifications.\n */\nexport interface InterceptorRequestSpec extends RequestSpec { }\n\n/**\n * Specific marker interface for injected request specifications.\n */\nexport interface InjectedRequestSpec extends RequestSpec { }\n\n/**\n * Represents the properties and validation steps for an HTTP request involved in a Reclaim proof.\n */\nexport interface RequestSpec {\n /** The URL or generic path of the HTTP request */\n url: string;\n /** Type or representation of the URL */\n urlType: string;\n /** The HTTP method used for the request */\n method: \"GET\" | \"POST\" | \"PUT\" | \"PATCH\" | \"DELETE\";\n /** Identifies and captures the request body if enabled */\n bodySniff: BodySniff;\n /** Required matching configurations for the HTTP response */\n responseMatches: ResponseMatchSpec[];\n /** Redaction rules applied to the HTTP response before passing to attestors */\n responseRedactions: ResponseRedactionSpec[];\n /**\n * Whether request matching this spec is required and always expected in list of proofs\n * Defaults to true.\n */\n required?: boolean;\n /**\n * Whether request matching this spec is allowed to appear multiple times in list of proofs.\n * Defaults to true.\n */\n multiple?: boolean;\n /**\n * Template parameter variables for the request spec that should be replaced with real values\n * during dynamic request spec construction.\n */\n templateParams?: string[]\n}\n\n/**\n * Defines the configuration for identifying/sniffing the request body.\n */\nexport interface BodySniff {\n /** Indicates whether body sniffing is enabled */\n enabled: boolean;\n /** The template string used to match or capture the body */\n template: string;\n}\n\n/**\n * Specifies a rule to match against a string in response to validate proof content.\n */\nexport interface ResponseMatchSpec {\n /** If true, the match condition is reversed */\n invert: boolean | undefined;\n /** If true, the match condition is optional and won't fail if absent */\n isOptional: boolean | undefined;\n /** The matching mechanism, typically regex or simple string containment */\n type: \"regex\" | \"contains\";\n /** The pattern or value to look for in the response */\n value: string;\n}\n\n/**\n * Specifies redaction rules for obscuring sensitive parts of the response.\n */\nexport interface ResponseRedactionSpec {\n /** Optional hashing method applied to the redacted content (e.g., 'oprf') */\n hash?: \"oprf\" | \"oprf-mpc\" | \"oprf-raw\" | undefined;\n /** JSON path for locating the value to redact */\n jsonPath: string;\n /** RegEx applied to correctly parse and extract/redact value */\n regex: string;\n /** XPath for XML/HTML matching configuration */\n xPath: string;\n}\n","import { HttpProviderClaimParams } from \"./types\";\nimport { hashProofClaimParams } from \"../witness\";\nimport { ProofNotValidatedError, UnknownProofsNotValidatedError } from \"./errors\";\nimport loggerModule from './logger';\nimport { Proof, ProviderVersionInfo } from \"./interfaces\";\nimport { fetchProviderHashRequirementsBy, HashRequirement, ProviderHashRequirementsConfig } from \"./providerUtils\";\nimport type { AttestorTeeAttestationConfig } from \"./verifyAttestorTee\";\n\nconst logger = loggerModule.logger;\n\n\n/**\n * Content validation configuration specifying essential required hashes and optional extra proofs.\n * Used to explicitly validate that a generated proof matches the exact request structure expected.\n */\nexport type ValidationConfigWithHash = {\n /**\n * Array of computed hashes that must be satisfied by the proofs.\n * \n * An element can be a `HashRequirement` object or a string that is equivalent to\n * a `{ value: '<hash>', required: true, multiple: false }` as `HashRequirement`.\n */\n hashes: (string | HashRequirement)[]\n};\n\n/**\n * Content validation configuration specifying the provider id and version used in the verification session that generated the proofs.\n * Used to explicitly validate that a generated proof matches the exact request structure expected.\n * \n * See also:\n * \n * * `ReclaimProofRequest.getProviderVersion()` - With a ReclaimProofRequest object, you can get the provider id & exact version of provider used in verification session.\n */\nexport interface ValidationConfigWithProviderInformation {\n /**\n * The identifier of provider used in verifications that resulted in a proof\n * \n * See also:\n * \n * * `ReclaimProofRequest.getProviderVersion()` - With a ReclaimProofRequest object, you can get the provider id & exact version of provider used in verification session.\n **/\n providerId: string;\n /**\n * The exact version of provider used in verifications that resulted in a proof.\n * \n * This cannot be a version constaint or version expression. It can be undefined or left blank if proof must be validated with latest version of provider.\n * Patches for the next provider version are also fetched and hashes from that spec is also be used to compare the hashes from proof.\n * \n * See also:\n * \n * * `ReclaimProofRequest.getProviderVersion()` - With a ReclaimProofRequest object, you can get the provider id & exact version of provider used in verification session.\n **/\n providerVersion?: string;\n /**\n * List of allowed pre-release tags.\n * For example, if you are using AI, provide `['ai']` to allow AI patch versions of the provider.\n */\n allowedTags?: string[];\n}\n\n/**\n * Legacy configuration to completely bypass content validation during verification.\n * Warning: Using this poses a risk as it avoids strictly matching proof parameters to expected hashes.\n */\nexport interface ValidationConfigWithDisabledValidation { dangerouslyDisableContentValidation: true }\n\n/**\n * Represents the configuration options applied when validating proof contents, allowing\n * strict hash checking or intentionally skipping validation if flagged.\n */\nexport type ValidationConfig = ValidationConfigWithHash | ValidationConfigWithProviderInformation | ValidationConfigWithDisabledValidation;\n\n/**\n * Describes the comprehensive configuration required to initialize the proof verification process.\n * Aligns with `ValidationConfig` options for verifying signatures alongside proof contents.\n */\nexport type TeeAttestationConfig = {\n /**\n * Your application secret (Ethereum private key).\n * Used to recompute the TEE attestation nonce and to derive the application ID\n * for binding the attestation to your application.\n */\n appSecret: string;\n};\n\nexport type VerificationConfig = ValidationConfig & {\n /**\n * TEE attestation verification configuration.\n * When provided, verifies the TEE attestation included in the proof.\n * The result will include `isTeeAttestationVerified` and `isVerified` will be false\n * if TEE attestation data is missing or verification fails.\n */\n teeAttestation?: TeeAttestationConfig;\n /**\n * Attestor TEE attestation verification configuration.\n * When provided, verifies that every witness on every proof has a valid\n * `claimAttestation` from an attestor running inside a TEE (GCP\n * Confidential Space).\n *\n * Independent of `teeAttestation`, which verifies the verifier-app's\n * own TEE attestation. Both can be enabled together.\n *\n * The result will include `isAttestorTeeAttestationVerified` and\n * `isVerified` will be false if any witness is missing TEE attestation\n * data or its verification fails.\n */\n attestorTeeAttestation?: AttestorTeeAttestationConfig;\n};\n\n\nconst HASH_REQUIRED_DEFAULT = true;\nconst HASH_MATCH_MULTIPLE_DEFAULT = true;\n\nexport function assertValidProofsByHash(proofs: Proof[], config: ProviderHashRequirementsConfig) {\n if (!config.hashes) {\n throw new ProofNotValidatedError('No proof hash was provided for validation');\n }\n\n const unvalidatedProofHashByIndex = new Map<number, string[]>();\n\n for (let i = 0; i < proofs.length; i++) {\n const proof = proofs[i];\n const claimParams = getHttpProviderClaimParamsFromProof(proof);\n const computedHashesOfProof = hashProofClaimParams(claimParams);\n const proofHashes = Array.isArray(computedHashesOfProof)\n ? computedHashesOfProof.map(h => h.toLowerCase().trim())\n : [computedHashesOfProof.toLowerCase().trim()];\n unvalidatedProofHashByIndex.set(i, proofHashes);\n }\n\n for (const hashRequirement of config.hashes) {\n let found = false;\n\n // The expectedHashes array incorporates multiple valid permutations when optional rule sets are defined in config.\n const expectedHashes = Array.isArray(hashRequirement.value)\n ? hashRequirement.value.map(h => h.toLowerCase().trim())\n : [hashRequirement.value.toLowerCase().trim()];\n\n const isRequired = hashRequirement.required ?? HASH_REQUIRED_DEFAULT;\n const canMatchMultiple = hashRequirement.multiple ?? HASH_MATCH_MULTIPLE_DEFAULT;\n\n // Iterate through unvalidated proofs to assert that the generated deterministic hash \n // derived from the User's actual matched elements structurally matches ANY of the permissible configurations.\n for (const [i, proofHashes] of unvalidatedProofHashByIndex.entries()) {\n const intersection = expectedHashes.filter(eh => proofHashes.includes(eh));\n\n // If the Proof's claim exactly replicates one of the Valid Config permutations:\n if (intersection.length > 0) {\n // Remove the proof so it can't validate subsequent independent requirements\n unvalidatedProofHashByIndex.delete(i);\n if (!found) {\n found = true;\n } else if (!canMatchMultiple) {\n // Preclude an attack surface where User passes duplicated valid proofs \n // matching permutations of the SAME underlying strict configuration.\n const expectedHashStr = expectedHashes.length === 1 ? expectedHashes[0] : `[${expectedHashes.join(', ')}]`;\n throw new ProofNotValidatedError(`Proof by hash '${expectedHashStr}' is not allowed to appear more than once`);\n }\n }\n }\n\n if (!found && isRequired) {\n const expectedHashStr = expectedHashes.length === 1 ? expectedHashes[0] : `[${expectedHashes.join(', ')}]`;\n throw new ProofNotValidatedError(`Proof by required hash '${expectedHashStr}' was not found`);\n }\n }\n\n if (unvalidatedProofHashByIndex.size > 0) {\n // if allowedExtraProofHashes was provided (not empty) and there are still unvalidated proofs, it means they are not allowed\n const contactSupport = 'Please contact Reclaim Protocol Support team or mail us at support@reclaimprotocol.org.';\n const unvalidatedHashesStrArr = [...unvalidatedProofHashByIndex.values()]\n .map(h => h.length === 1 ? h[0] : `[${h.join(', ')}]`);\n throw new UnknownProofsNotValidatedError(`Extra ${unvalidatedProofHashByIndex.size} proof(s) by hashes ${unvalidatedHashesStrArr.join(', ')} was found but could not be validated and indicates a security risk. ${contactSupport}`);\n }\n}\n\nconst allowedHttpMethods = new Set([\"GET\", \"POST\", \"PUT\", \"PATCH\", \"DELETE\"]);\n\nexport function isHttpProviderClaimParams(claimParams: unknown): claimParams is HttpProviderClaimParams {\n // Fail fast on non-objects\n if (!claimParams || typeof claimParams !== 'object' || Array.isArray(claimParams)) {\n return false;\n }\n\n // Cast to a Record so we can check properties directly without 'in'\n const params = claimParams as Record<string, unknown>;\n\n return (\n typeof params.url === 'string' &&\n typeof params.method === 'string' &&\n allowedHttpMethods.has(params.method) &&\n (params.body == null || typeof params.body === 'string') &&\n Array.isArray(params.responseMatches) &&\n params.responseMatches.length > 0 &&\n Array.isArray(params.responseRedactions)\n );\n}\n\nexport function getHttpProviderClaimParamsFromProof(proof: Proof): HttpProviderClaimParams {\n try {\n const claimParams = JSON.parse(proof.claimData.parameters);\n if (isHttpProviderClaimParams(claimParams)) {\n return claimParams;\n }\n } catch (_) { }\n throw new ProofNotValidatedError('Proof has no HTTP provider params to hash');\n}\n\n/**\n * Asserts that the proof is validated by checking the content of proof with with expectations from provider config or hash based on [options]\n * @param proofs - The proofs to validate\n * @param config - The validation config\n * @throws {ProofNotValidatedError} When the proof is not validated\n */\nexport async function assertValidateProof(proofs: Proof[], config: VerificationConfig) {\n if ('dangerouslyDisableContentValidation' in config && config.dangerouslyDisableContentValidation) {\n logger.warn('Validation skipped because it was disabled during proof verification')\n return\n }\n\n if ('providerId' in config) {\n if (!config.providerId || typeof config.providerId !== 'string') {\n throw new ProofNotValidatedError('Provider id is required for proof validation');\n }\n if (config.providerVersion && typeof config.providerVersion !== 'string') {\n throw new ProofNotValidatedError('Provider version must be a string');\n }\n const hashRequirementsFromProvider = await fetchProviderHashRequirementsBy(config.providerId, config.providerVersion, config.allowedTags, proofs);\n if (!hashRequirementsFromProvider.length) {\n throw new ProofNotValidatedError('Could not find any provider information for the given provider id and version');\n }\n if (hashRequirementsFromProvider.length != 1) {\n let lastError: unknown | null = null;\n for (const hashRequirement of hashRequirementsFromProvider) {\n try {\n return await assertValidateProof(proofs, hashRequirement);\n } catch (e) {\n lastError = e;\n }\n }\n throw new ProofNotValidatedError('Could not validate proof', lastError as any);\n } else {\n return assertValidateProof(proofs, hashRequirementsFromProvider[0]);\n }\n }\n\n const effectiveHashRequirement = ('hashes' in config && Array.isArray(config?.hashes) ? config.hashes : []).map(it => {\n if (typeof it == 'string') {\n return {\n value: it,\n }\n } else {\n return it\n }\n });\n\n return assertValidProofsByHash(proofs, {\n hashes: effectiveHashRequirement,\n })\n}\n","import { Proof, TeeAttestation } from './interfaces';\nimport { ethers } from 'ethers';\nimport { generateAttestationNonce } from './attestationNonce';\nimport { GCP_CONFIDENTIAL_SPACE_ISSUER } from './constants';\nimport { TeeVerificationError } from './errors';\nimport type { TeeAttestationConfig } from './proofValidationUtils';\nimport loggerModule from './logger';\n\nconst logger = loggerModule.logger;\n\nconst EXPECTED_HW_MODEL = 'GCP_AMD_SEV';\nconst EXPECTED_TEE_PROVIDER = 'gcp';\nconst EXPECTED_TEE_TECHNOLOGY = 'amd-sev';\nconst SUPPORTED_PROOF_VERSIONS = ['v2', 'v3'];\nconst TOKEN_CLOCK_SKEW_S = 60;\nconst NONCE_TIMESTAMP_MAX_SKEW_MS = 10 * 60 * 1000;\n\ntype JsonWebKeyLike = JsonWebKey & {\n kid?: string;\n alg?: string;\n use?: string;\n};\n\ntype DecodedJwt = {\n header: Record<string, any>;\n payload: Record<string, any>;\n signingInput: string;\n signature: Uint8Array;\n};\n\ntype NonceContextData = {\n applicationId: string;\n sessionId: string;\n timestamp: string;\n};\n\nexport type TeeVerificationResult = {\n isVerified: boolean;\n error?: string;\n};\n\nconst BROWSER_ENVIRONMENT_ERROR =\n 'TEE attestation verification is only supported in non-browser environments. Run verifyTeeAttestation on your server or API route.';\n\nfunction assert(condition: unknown, message: string): asserts condition {\n if (!condition) {\n throw new Error(message);\n }\n}\n\nfunction isBrowserEnvironment(): boolean {\n if (typeof window !== 'undefined' || typeof document !== 'undefined') {\n return true;\n }\n\n if (typeof navigator !== 'undefined' && typeof process === 'undefined') {\n return true;\n }\n\n const workerGlobalScope = (globalThis as any).WorkerGlobalScope;\n if (\n typeof workerGlobalScope !== 'undefined' &&\n typeof self !== 'undefined' &&\n self instanceof workerGlobalScope\n ) {\n return true;\n }\n\n return false;\n}\n\nfunction assertNonBrowserEnvironment() {\n if (isBrowserEnvironment()) {\n throw new Error(BROWSER_ENVIRONMENT_ERROR);\n }\n}\n\nfunction normalizeHex(value: string | undefined | null): string {\n return (value || '').trim().replace(/^0x/i, '').toLowerCase();\n}\n\nfunction isHex(value: string): boolean {\n return /^[0-9a-f]+$/i.test(value);\n}\n\nfunction decodeBase64Url(input: string): Uint8Array {\n const normalized = input.replace(/-/g, '+').replace(/_/g, '/');\n const padded = normalized + '='.repeat((4 - normalized.length % 4) % 4);\n\n if (typeof Buffer !== 'undefined') {\n return new Uint8Array(Buffer.from(padded, 'base64'));\n }\n if (typeof atob === 'function') {\n const binary = atob(padded);\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i += 1) {\n bytes[i] = binary.charCodeAt(i);\n }\n return bytes;\n }\n\n throw new Error('Base64 decoding is not supported in this environment');\n}\n\nfunction decodeUtf8(bytes: Uint8Array): string {\n return new TextDecoder().decode(bytes);\n}\n\nfunction decodeJwt(token: string): DecodedJwt {\n const parts = token.split('.');\n assert(parts.length === 3, 'attestation token is not a JWT');\n\n return {\n header: JSON.parse(decodeUtf8(decodeBase64Url(parts[0]))),\n payload: JSON.parse(decodeUtf8(decodeBase64Url(parts[1]))),\n signingInput: `${parts[0]}.${parts[1]}`,\n signature: decodeBase64Url(parts[2]),\n };\n}\n\nfunction getFetch(): typeof fetch {\n const fetchFn = globalThis.fetch;\n assert(fetchFn, 'fetch is not available in this environment');\n return fetchFn.bind(globalThis);\n}\n\nfunction getSubtleCrypto(): SubtleCrypto {\n if (globalThis.crypto?.subtle) {\n return globalThis.crypto.subtle;\n }\n\n const nodeCrypto = typeof process !== 'undefined' && process.versions?.node\n ? require('crypto')\n : undefined;\n if (nodeCrypto?.webcrypto?.subtle) {\n return nodeCrypto.webcrypto.subtle as SubtleCrypto;\n }\n\n throw new Error('WebCrypto subtle is not available in this environment');\n}\n\nasync function fetchJson(url: string): Promise<any> {\n const response = await getFetch()(url);\n if (!response.ok) {\n throw new Error(`GET ${url} returned ${response.status} ${response.statusText}`);\n }\n return response.json();\n}\n\nasync function sha256Hex(input: string): Promise<string> {\n const digest = await getSubtleCrypto().digest('SHA-256', new TextEncoder().encode(input));\n return Array.from(new Uint8Array(digest), (value) => value.toString(16).padStart(2, '0')).join('');\n}\n\nconst JWKS_CACHE_TTL_MS = 5 * 60 * 1000;\nlet cachedJwksUri: string | null = null;\nlet cachedJwksKeys: JsonWebKeyLike[] | null = null;\nlet cachedJwksAt = 0;\n\nasync function verifyJwtSignature(token: string, issuer: string): Promise<Record<string, any>> {\n const { header, payload, signingInput, signature } = decodeJwt(token);\n assert(header.alg === 'RS256', `unexpected attestation signing algorithm: ${header.alg}`);\n assert(typeof header.kid === 'string' && header.kid.length > 0, 'attestation token kid is missing');\n\n const isCacheFresh = cachedJwksKeys && (Date.now() - cachedJwksAt) < JWKS_CACHE_TTL_MS;\n\n if (!isCacheFresh) {\n const oidc = await fetchJson(`${issuer}/.well-known/openid-configuration`);\n assert(typeof oidc?.jwks_uri === 'string' && oidc.jwks_uri.length > 0, 'issuer JWKS URI is missing');\n cachedJwksUri = oidc.jwks_uri;\n\n const jwks = await fetchJson(cachedJwksUri!);\n cachedJwksKeys = jwks?.keys || [];\n cachedJwksAt = Date.now();\n }\n\n const jwk = cachedJwksKeys!.find((key: JsonWebKeyLike) => key.kid === header.kid) as JsonWebKeyLike | undefined;\n assert(jwk, `no JWKS key found for kid ${header.kid}`);\n\n const cryptoKey = await getSubtleCrypto().importKey(\n 'jwk',\n jwk,\n { name: 'RSASSA-PKCS1-v1_5', hash: 'SHA-256' },\n false,\n ['verify']\n );\n\n const isValid = await getSubtleCrypto().verify(\n 'RSASSA-PKCS1-v1_5',\n cryptoKey,\n signature as unknown as BufferSource,\n new TextEncoder().encode(signingInput) as unknown as BufferSource\n );\n assert(isValid, 'JWT signature verification failed');\n\n return payload;\n}\n\nfunction isNonceContextData(obj: unknown): obj is NonceContextData {\n if (!obj || typeof obj !== 'object') return false;\n const o = obj as Record<string, unknown>;\n return typeof o.applicationId === 'string' && o.applicationId.length > 0\n && typeof o.sessionId === 'string' && o.sessionId.length > 0\n && typeof o.timestamp === 'string' && o.timestamp.length > 0;\n}\n\nfunction parseProofContext(proof: Proof): { parsedContext: Record<string, unknown>; nonceDataObj: NonceContextData; expectedNonce: string } {\n let parsedContext: unknown;\n try {\n parsedContext = JSON.parse(proof.claimData.context);\n } catch {\n throw new Error('Malformed proof: claimData.context is not valid JSON');\n }\n\n if (!parsedContext || typeof parsedContext !== 'object') {\n throw new Error('Malformed proof: claimData.context is not a JSON object');\n }\n\n const ctx = parsedContext as Record<string, unknown>;\n const expectedNonce = ctx.attestationNonce;\n assert(typeof expectedNonce === 'string' && expectedNonce.length > 0, 'Proof context is missing attestationNonce');\n\n const nonceDataObj = ctx.attestationNonceData;\n assert(isNonceContextData(nonceDataObj), 'Proof context is missing or has invalid attestationNonceData (requires applicationId, sessionId, timestamp)');\n\n return { parsedContext: ctx, nonceDataObj, expectedNonce };\n}\n\nfunction verifyApplicationAndSessionBinding(\n proof: Proof,\n parsedContext: any,\n nonceDataObj: NonceContextData,\n expectedApplicationId?: string\n) {\n const { applicationId, sessionId, timestamp } = nonceDataObj;\n\n if (expectedApplicationId) {\n assert(\n applicationId.toLowerCase() === expectedApplicationId.toLowerCase(),\n `Application ID Mismatch! Expected ${expectedApplicationId}, but proof context contains ${applicationId}`\n );\n }\n\n let parsedParameters: Record<string, unknown> = {};\n if (proof.claimData.parameters) {\n try {\n const parsed = JSON.parse(proof.claimData.parameters);\n parsedParameters = (parsed && typeof parsed === 'object' && !Array.isArray(parsed)) ? parsed : {};\n } catch {\n throw new Error('Malformed proof: claimData.parameters is not valid JSON');\n }\n }\n\n const contextSessionId = parsedContext?.reclaimSessionId;\n const parameterSessionId = parsedParameters?.proxySessionId ?? parsedParameters?.sessionId;\n\n if (contextSessionId && contextSessionId.toString() !== sessionId.toString()) {\n throw new Error(`Session ID Mismatch! Expected ${sessionId}, but proof context contains reclaimSessionId=${contextSessionId}`);\n }\n if (parameterSessionId && parameterSessionId.toString() !== sessionId.toString()) {\n throw new Error(`Session ID Mismatch! Expected ${sessionId}, but proof parameters contain ${parameterSessionId}`);\n }\n if (!contextSessionId && !parameterSessionId) {\n throw new Error('Proof is missing reclaimSessionId and proxySessionId/sessionId for attestation nonce verification');\n }\n\n const claimTimestampMs = proof.claimData.timestampS * 1000;\n const nonceTimestampMs = parseInt(timestamp, 10);\n const diffMs = Math.abs(claimTimestampMs - nonceTimestampMs);\n if (diffMs > NONCE_TIMESTAMP_MAX_SKEW_MS) {\n throw new Error(`Timestamp Skew Too Large! claimData.timestampS and attestationNonce timestamp differ by ${Math.round(diffMs / 1000)}s (limit: 600s)`);\n }\n}\n\nfunction verifyNonceMaterial(\n expectedNonce: string,\n nonceDataObj: NonceContextData,\n expectedAppSecret?: string\n) {\n const cleanExpectedNonce = normalizeHex(expectedNonce);\n const { applicationId, sessionId, timestamp } = nonceDataObj;\n\n assert(cleanExpectedNonce.length > 0, 'Proof context attestationNonce is empty');\n assert(isHex(cleanExpectedNonce), 'Proof context attestationNonce is not valid hex');\n\n if (expectedAppSecret) {\n const recomputedNonce = generateAttestationNonce(expectedAppSecret, applicationId, sessionId, timestamp);\n assert(\n recomputedNonce === cleanExpectedNonce,\n 'Attestation nonce verification failed: app secret, application ID, session ID, or timestamp do not match'\n );\n return;\n }\n\n if (cleanExpectedNonce.length > 74) {\n const legacyNonceData = `${applicationId}:${sessionId}:${timestamp}`;\n const nonceMsg = ethers.getBytes(ethers.keccak256(new TextEncoder().encode(legacyNonceData)));\n const recoveredAddress = ethers.verifyMessage(\n nonceMsg,\n expectedNonce.startsWith('0x') ? expectedNonce : `0x${expectedNonce}`\n );\n\n assert(\n recoveredAddress.toLowerCase() === applicationId.toLowerCase(),\n `Nonce signature verification failed: recovered ${recoveredAddress}, expected ${applicationId}`\n );\n return;\n }\n\n throw new Error('App secret is required to verify hash-based attestation nonces');\n}\n\nfunction assertTokenFresh(claims: Record<string, any>) {\n const now = Math.floor(Date.now() / 1000);\n\n if (typeof claims.nbf === 'number' && now + TOKEN_CLOCK_SKEW_S < claims.nbf) {\n throw new Error(`Attestation token is not valid before ${claims.nbf}`);\n }\n if (typeof claims.exp === 'number' && now - TOKEN_CLOCK_SKEW_S > claims.exp) {\n throw new Error(`Attestation token expired at ${claims.exp}`);\n }\n if (typeof claims.iat === 'number' && claims.iat > now + TOKEN_CLOCK_SKEW_S) {\n throw new Error(`Attestation token issued-at ${claims.iat} is in the future`);\n }\n}\n\nfunction assertAudienceClaim(aud: unknown) {\n if (typeof aud === 'string') {\n assert(aud.length > 0, 'attestation token audience is empty');\n return;\n }\n if (Array.isArray(aud)) {\n assert(aud.length > 0, 'attestation token audience is empty');\n assert(aud.every((entry) => typeof entry === 'string' && entry.length > 0), 'attestation token audience contains invalid entries');\n return;\n }\n throw new Error('attestation token audience is missing');\n}\n\nfunction getProofVersion(teeAttestation: TeeAttestation): string | undefined {\n return (teeAttestation as any).proof_version ?? (teeAttestation as any).proofVersion;\n}\n\nfunction assertProofShape(teeAttestation: TeeAttestation) {\n if (teeAttestation.error) {\n throw new Error(`${teeAttestation.error.code}: ${teeAttestation.error.message}`);\n }\n\n const proofVersion = getProofVersion(teeAttestation);\n assert(typeof proofVersion === 'string' && SUPPORTED_PROOF_VERSIONS.includes(proofVersion), `unexpected proof version: ${proofVersion}`);\n assert(teeAttestation.tee_provider === EXPECTED_TEE_PROVIDER, `unexpected tee provider: ${teeAttestation.tee_provider}`);\n assert(teeAttestation.tee_technology === EXPECTED_TEE_TECHNOLOGY, `unexpected tee technology: ${teeAttestation.tee_technology}`);\n assert(typeof teeAttestation.nonce === 'string' && teeAttestation.nonce.length > 0, 'tee attestation nonce missing');\n assert(typeof teeAttestation.timestamp === 'string' && teeAttestation.timestamp.length > 0, 'tee attestation timestamp missing');\n assert(!Number.isNaN(Date.parse(teeAttestation.timestamp)), 'tee attestation timestamp is invalid');\n assert(typeof teeAttestation.workload?.image_digest === 'string' && teeAttestation.workload.image_digest.length > 0, 'workload image digest missing');\n assert(typeof teeAttestation.verifier?.image_digest === 'string' && teeAttestation.verifier.image_digest.length > 0, 'verifier image digest missing');\n assert(typeof teeAttestation.attestation?.token === 'string' && teeAttestation.attestation.token.length > 0, 'attestation token missing');\n}\n\nasync function computeDigestBinding(teeAttestation: TeeAttestation): Promise<string> {\n const proofVersion = getProofVersion(teeAttestation);\n\n if (proofVersion === 'v3') {\n assert(typeof teeAttestation.workload.container_name === 'string' && teeAttestation.workload.container_name.length > 0, 'workload container name missing');\n assert(typeof teeAttestation.verifier.container_name === 'string' && teeAttestation.verifier.container_name.length > 0, 'verifier container name missing');\n\n return sha256Hex([\n 'v3',\n `workload.container_name=${teeAttestation.workload.container_name}`,\n `workload.image_digest=${teeAttestation.workload.image_digest}`,\n `verifier.container_name=${teeAttestation.verifier.container_name}`,\n `verifier.image_digest=${teeAttestation.verifier.image_digest}`,\n ].join('\\n'));\n }\n\n return sha256Hex(\n `${teeAttestation.workload.image_digest}\\n${teeAttestation.verifier.image_digest}`\n );\n}\n\nasync function verifyGcpClaims(teeAttestation: TeeAttestation, expectedNonce: string) {\n const claims = await verifyJwtSignature(teeAttestation.attestation.token, GCP_CONFIDENTIAL_SPACE_ISSUER);\n\n assert(claims.iss === GCP_CONFIDENTIAL_SPACE_ISSUER, `unexpected issuer: ${claims.iss}`);\n assertAudienceClaim(claims.aud);\n assert(Array.isArray(claims.eat_nonce), 'eat_nonce claim missing');\n\n const digestBinding = await computeDigestBinding(teeAttestation);\n\n assert(claims.eat_nonce.includes(expectedNonce), 'request nonce is not present in attestation token');\n assert(claims.eat_nonce.includes(digestBinding), 'digest-binding nonce is not present in attestation token');\n assert(claims.hwmodel === EXPECTED_HW_MODEL, `unexpected hwmodel: ${claims.hwmodel}`);\n assert(claims.secboot === true, 'secure boot claim is not true');\n assert(claims.submods?.gce, 'gce submod claim missing');\n\n assertTokenFresh(claims);\n}\n\n/**\n * Validates the hardware TEE attestation included in the proof.\n * Derives the application ID from `appSecret` and verifies the attestation\n * was generated for your application.\n * Returns a result object with `isVerified` and an optional `error` message.\n *\n * This check is stateless and does not protect against replay of a previously\n * valid proof. Callers must enforce session matching and dedup `sessionId` on\n * their server. See the README's \"Replay Protection\" section.\n *\n * @param proof - The proof containing TEE attestation data\n * @param appSecret - Your application secret (Ethereum private key). Used to\n * derive the application ID and recompute the attestation nonce.\n */\nexport async function verifyTeeAttestation(\n proof: Proof,\n appSecret: string\n): Promise<TeeVerificationResult> {\n assertNonBrowserEnvironment();\n\n try {\n const appId = new ethers.Wallet(appSecret).address;\n\n let teeAttestation = proof.teeAttestation;\n if (!teeAttestation) {\n throw new Error('Missing teeAttestation in proof');\n }\n\n if (typeof teeAttestation === 'string') {\n teeAttestation = JSON.parse(teeAttestation) as TeeAttestation;\n }\n\n assertProofShape(teeAttestation);\n\n const { parsedContext, nonceDataObj, expectedNonce } = parseProofContext(proof);\n verifyApplicationAndSessionBinding(proof, parsedContext, nonceDataObj, appId);\n verifyNonceMaterial(expectedNonce, nonceDataObj, appSecret);\n\n const cleanExpectedNonce = normalizeHex(expectedNonce);\n const cleanTeeNonce = normalizeHex(teeAttestation.nonce);\n assert(cleanTeeNonce.length > 0, 'TEE attestation nonce is empty');\n assert(isHex(cleanTeeNonce), 'TEE attestation nonce is not valid hex');\n assert(cleanTeeNonce === cleanExpectedNonce, `Nonce Mismatch! Expected ${cleanExpectedNonce}, got ${cleanTeeNonce}`);\n\n await verifyGcpClaims(teeAttestation, cleanExpectedNonce);\n\n return { isVerified: true };\n } catch (error) {\n logger.error('TEE attestation verification failed:', error);\n return {\n isVerified: false,\n error: error instanceof Error ? error.message : String(error),\n };\n }\n}\n\n/**\n * Verifies TEE attestation for all proofs.\n * Throws `TeeVerificationError` if any proof is missing TEE data or fails verification.\n *\n * @param proofs - The proofs to verify\n * @param config - TEE attestation configuration containing the app secret\n * @throws {TeeVerificationError} When TEE data is missing or verification fails\n */\nexport async function runTeeVerification(proofs: Proof[], config: TeeAttestationConfig): Promise<void> {\n const hasTeeData = proofs.every(proof => {\n if (proof.teeAttestation) return true;\n try {\n const context = JSON.parse(proof.claimData.context);\n return !!context?.attestationNonce;\n } catch {\n return false;\n }\n });\n\n if (!hasTeeData) {\n throw new TeeVerificationError('TEE verification requested but one or more proofs are missing TEE attestation data');\n }\n\n const teeResults = await Promise.all(\n proofs.map(proof => verifyTeeAttestation(proof, config.appSecret))\n );\n\n if (!teeResults.every(r => r.isVerified)) {\n throw new TeeVerificationError('TEE attestation verification failed for one or more proofs');\n }\n}\n","import crypto, { X509Certificate } from 'crypto';\nimport { ethers } from 'ethers';\nimport { createSignDataForClaim } from '../witness';\nimport {\n ATTESTOR_NONCE_PATTERN,\n GCP_CONFIDENTIAL_SPACE_ISSUER,\n GCP_CONFIDENTIAL_SPACE_ROOT_CA,\n} from './constants';\nimport { AttestorTeeVerificationError } from './errors';\nimport type { AttestorClaimAttestation, Proof } from './interfaces';\nimport loggerModule from './logger';\n\nconst logger = loggerModule.logger;\n\nconst BROWSER_ENVIRONMENT_ERROR =\n 'Attestor TEE attestation verification is only supported in non-browser environments. Run verifyAttestorTeeAttestation on your server or API route.';\n\nfunction isBrowserEnvironment(): boolean {\n if (typeof window !== 'undefined' || typeof document !== 'undefined') {\n return true;\n }\n if (typeof navigator !== 'undefined' && typeof process === 'undefined') {\n return true;\n }\n const workerGlobalScope = (globalThis as any).WorkerGlobalScope;\n if (\n typeof workerGlobalScope !== 'undefined' &&\n typeof self !== 'undefined' &&\n self instanceof workerGlobalScope\n ) {\n return true;\n }\n return false;\n}\n\nfunction assertNonBrowserEnvironment() {\n if (isBrowserEnvironment()) {\n throw new Error(BROWSER_ENVIRONMENT_ERROR);\n }\n}\n\n/**\n * Result of verifying an attestor TEE attestation.\n */\nexport type AttestorTeeVerificationResult = {\n isVerified: boolean;\n error?: string;\n /** sha256 image digest of the attestor container, on success. */\n imageDigest?: string;\n};\n\nconst TOKEN_CLOCK_SKEW_S = 60;\n\nfunction decodeBase64Url(input: string): Buffer {\n const normalized = input.replace(/-/g, '+').replace(/_/g, '/');\n const padded = normalized + '='.repeat((4 - (normalized.length % 4)) % 4);\n return Buffer.from(padded, 'base64');\n}\n\nfunction normalizeAddress(address: string): string {\n return address.trim().toLowerCase().replace(/^0x/, '');\n}\n\n/**\n * Walks the x5c certificate chain (leaf first) and verifies each link\n * up to the pinned GCP Confidential Space Root CA. Returns the leaf\n * certificate's public key on success.\n */\nfunction verifyX5cChain(x5cChain: string[]): crypto.KeyObject {\n if (!x5cChain || x5cChain.length === 0) {\n throw new Error('Empty x5c certificate chain');\n }\n\n const certs = x5cChain.map(\n (b64) => new X509Certificate(`-----BEGIN CERTIFICATE-----\\n${b64}\\n-----END CERTIFICATE-----`)\n );\n const root = new X509Certificate(GCP_CONFIDENTIAL_SPACE_ROOT_CA);\n\n for (let i = 0; i < certs.length - 1; i++) {\n if (!certs[i].verify(certs[i + 1].publicKey)) {\n throw new Error(`Certificate chain verification failed at level ${i}`);\n }\n }\n\n const top = certs[certs.length - 1];\n if (!top.verify(root.publicKey)) {\n throw new Error('Certificate chain does not root to GCP Confidential Space Root CA');\n }\n\n return certs[0].publicKey;\n}\n\n/**\n * Validates a GCP Confidential Space attestation JWT produced by an\n * attestor running in a Confidential Space VM, and asserts that the\n * attestation binds to the given attestor address.\n *\n * The attestor (running inside the TEE) calls the Confidential Space\n * launcher's attestation endpoint with two nonces:\n * - `attestor_public_key:<eth-address>` - binds to the signing key.\n * - `attestor_cert_hash:<sha256-hex>` - binds to the live TLS cert.\n *\n * This function only verifies the public-key nonce. The TLS cert hash\n * binding is informational and not checked here. Callers that need to\n * pin to a specific attestor image should compare the returned\n * `imageDigest` against a known-good value.\n *\n * The JWT signature is verified by walking the x5c certificate chain\n * to a pinned GCP Confidential Space Root CA. No outbound network\n * calls are made.\n *\n * Node-only (uses node:crypto). Mirrors the environment restriction in\n * the existing `verifyTeeAttestation` helper.\n *\n * @param report - the raw JWT string (header.payload.signature).\n * @param expectedAttestorAddress - hex ETH address (0x-prefixed or\n * unprefixed) that the attestation should be bound to.\n */\nexport async function verifyAttestorTeeAttestation(\n report: string,\n expectedAttestorAddress: string\n): Promise<AttestorTeeVerificationResult> {\n try {\n assertNonBrowserEnvironment();\n\n if (!report || typeof report !== 'string') {\n throw new Error('attestation report is empty or not a string');\n }\n if (!expectedAttestorAddress || typeof expectedAttestorAddress !== 'string') {\n throw new Error('expectedAttestorAddress is required');\n }\n\n const parts = report.split('.');\n if (parts.length !== 3) {\n throw new Error('attestation report is not a JWT (expected 3 parts)');\n }\n const [headerB64, payloadB64, signatureB64] = parts;\n\n const header = JSON.parse(decodeBase64Url(headerB64).toString('utf8'));\n const payload = JSON.parse(decodeBase64Url(payloadB64).toString('utf8'));\n\n if (header.alg !== 'RS256') {\n throw new Error(`unexpected signing algorithm: ${header.alg}`);\n }\n if (!Array.isArray(header.x5c) || header.x5c.length === 0) {\n throw new Error('attestation report is missing x5c certificate chain');\n }\n\n if (payload.iss !== GCP_CONFIDENTIAL_SPACE_ISSUER) {\n throw new Error(`unexpected issuer: ${payload.iss}`);\n }\n\n const now = Math.floor(Date.now() / 1000);\n if (typeof payload.nbf === 'number' && now + TOKEN_CLOCK_SKEW_S < payload.nbf) {\n throw new Error(`attestation not yet valid (nbf=${payload.nbf})`);\n }\n if (typeof payload.exp === 'number' && now - TOKEN_CLOCK_SKEW_S > payload.exp) {\n throw new Error(`attestation expired (exp=${payload.exp})`);\n }\n if (typeof payload.iat === 'number' && payload.iat > now + TOKEN_CLOCK_SKEW_S) {\n throw new Error(`attestation issued in future (iat=${payload.iat})`);\n }\n\n const publicKey = verifyX5cChain(header.x5c);\n\n const verifier = crypto.createVerify('RSA-SHA256');\n verifier.update(`${headerB64}.${payloadB64}`);\n if (!verifier.verify(publicKey, new Uint8Array(decodeBase64Url(signatureB64)))) {\n throw new Error('attestation signature verification failed');\n }\n\n if (!payload.eat_nonce) {\n throw new Error('eat_nonce claim is missing');\n }\n const nonces: string[] = Array.isArray(payload.eat_nonce)\n ? payload.eat_nonce\n : [payload.eat_nonce];\n\n let attestedAddress: string | undefined;\n for (const n of nonces) {\n const m = typeof n === 'string' ? n.match(ATTESTOR_NONCE_PATTERN) : null;\n if (m) {\n attestedAddress = m[1];\n break;\n }\n }\n if (!attestedAddress) {\n throw new Error(\n `attestor_public_key nonce not found in eat_nonce: ${JSON.stringify(payload.eat_nonce)}`\n );\n }\n\n if (normalizeAddress(attestedAddress) !== normalizeAddress(expectedAttestorAddress)) {\n throw new Error(\n `attestor address mismatch: attestation binds to 0x${attestedAddress.toLowerCase()}, ` +\n `expected ${expectedAttestorAddress}`\n );\n }\n\n const imageDigest: string | undefined =\n payload.submods?.container?.image_digest\n ?? payload.google?.compute_engine?.image_digest;\n\n return { isVerified: true, imageDigest };\n } catch (error) {\n return {\n isVerified: false,\n error: error instanceof Error ? error.message : String(error),\n };\n }\n}\n\n/**\n * Configuration for verifying the attestor's TEE attestation on each\n * witness of the proof.\n */\nexport type AttestorTeeAttestationConfig = {\n /**\n * Optional allowlist of expected attestor container image digests\n * (e.g. `\"sha256:4906340f...\"`). When provided, the attestation's\n * `submods.container.image_digest` must be in this list.\n *\n * Leave undefined to skip image pinning and rely solely on the JWT\n * chain rooting to the GCP Confidential Space Root CA + nonce\n * binding to the attestor address.\n */\n expectedImageDigests?: string[];\n};\n\nfunction normalizeAttestorAddress(address: string): string {\n return address.trim().toLowerCase();\n}\n\nfunction normalizeSignature(sig: string): string {\n return sig.trim().toLowerCase();\n}\n\nasync function verifyAttestorTeeForProof(\n proof: Proof,\n config: AttestorTeeAttestationConfig\n): Promise<void> {\n if (!proof.witnesses || proof.witnesses.length === 0) {\n throw new AttestorTeeVerificationError('Proof has no witnesses');\n }\n\n const expectedDigests = config.expectedImageDigests?.map(d => d.trim());\n\n const proofSignatures = new Set((proof.signatures || []).map(normalizeSignature));\n const claimSignData = createSignDataForClaim(proof.claimData);\n\n for (const witness of proof.witnesses) {\n const att: AttestorClaimAttestation | undefined = witness.claimAttestation;\n if (!att) {\n throw new AttestorTeeVerificationError(\n `Witness ${witness.id} is missing claimAttestation`\n );\n }\n\n if (normalizeAttestorAddress(att.attestor_address) !== normalizeAttestorAddress(witness.id)) {\n throw new AttestorTeeVerificationError(\n `claimAttestation.attestor_address ${att.attestor_address} does not match witness id ${witness.id}`\n );\n }\n\n if (!proofSignatures.has(normalizeSignature(att.claim_signature))) {\n throw new AttestorTeeVerificationError(\n `claimAttestation.claim_signature for witness ${witness.id} is not present in proof.signatures`\n );\n }\n\n let recoveredSigner: string;\n try {\n recoveredSigner = ethers.verifyMessage(claimSignData, att.claim_signature);\n } catch (error) {\n throw new AttestorTeeVerificationError(\n `Failed to recover signer from claimAttestation.claim_signature for witness ${witness.id}`,\n error\n );\n }\n if (normalizeAttestorAddress(recoveredSigner) !== normalizeAttestorAddress(witness.id)) {\n throw new AttestorTeeVerificationError(\n `claim_signature recovers to ${recoveredSigner}, expected attestor ${witness.id}`\n );\n }\n\n const result = await verifyAttestorTeeAttestation(att.attestation_report, witness.id);\n if (!result.isVerified) {\n throw new AttestorTeeVerificationError(\n `Attestor TEE attestation verification failed for witness ${witness.id}: ${result.error}`\n );\n }\n\n if (expectedDigests && expectedDigests.length > 0) {\n if (!result.imageDigest) {\n throw new AttestorTeeVerificationError(\n `Attestor TEE attestation for witness ${witness.id} did not expose an image digest to check against expectedImageDigests`\n );\n }\n if (!expectedDigests.includes(result.imageDigest)) {\n throw new AttestorTeeVerificationError(\n `Attestor image digest ${result.imageDigest} for witness ${witness.id} is not in expectedImageDigests`\n );\n }\n }\n }\n}\n\n/**\n * Verifies the attestor's TEE attestation for every witness of every\n * provided proof. Throws `AttestorTeeVerificationError` on the first\n * failure.\n *\n * Each witness must carry a `claimAttestation`. For each one, this:\n * 1. Asserts `attestor_address` matches `witness.id`.\n * 2. Asserts `claim_signature` is present in `proof.signatures`.\n * 3. Recovers the signer of `claim_signature` from the claim data and\n * asserts it equals `witness.id` (binds the signature to the\n * attestor that the TEE attestation will cover).\n * 4. Calls `verifyAttestorTeeAttestation` to validate the JWT against\n * the pinned GCP Confidential Space Root CA and the attestor-key\n * nonce.\n * 5. If `expectedImageDigests` is provided, asserts the attestation's\n * container image digest is in the allowlist.\n *\n * Node-only (uses node:crypto), like `verifyTeeAttestation`.\n *\n * @param proofs - The proofs to verify.\n * @param config - Optional config; see {@link AttestorTeeAttestationConfig}.\n */\nexport async function runAttestorTeeVerification(\n proofs: Proof[],\n config: AttestorTeeAttestationConfig = {}\n): Promise<void> {\n if (!proofs || proofs.length === 0) {\n throw new AttestorTeeVerificationError('No proofs provided for attestor TEE verification');\n }\n\n try {\n for (const proof of proofs) {\n await verifyAttestorTeeForProof(proof, config);\n }\n } catch (error) {\n logger.error('Attestor TEE attestation verification failed:', error);\n if (error instanceof AttestorTeeVerificationError) {\n throw error;\n }\n throw new AttestorTeeVerificationError(\n 'Attestor TEE attestation verification failed',\n error\n );\n }\n}\n","import { ethers } from 'ethers';\nimport canonicalize from 'canonicalize';\nimport { SignatureGeneratingError } from './errors';\nimport { validateFunctionParams } from './validationUtils';\n\n/**\n * Computes the signature required by `initSession` over `{providerId, timestamp}`.\n *\n * Use this on a trusted server (where `appSecret` lives) to produce a signature\n * that can then be passed to `ReclaimProofRequest.initWithSignature(...)` from a\n * client that never sees the secret.\n *\n * @param appSecret - The application secret (private key). Must remain server-side.\n * @param providerId - The provider id the session will be initialized against.\n * @param timestamp - The timestamp (ms epoch as string) that will be sent with init.\n * The same value MUST be passed to `initWithSignature`.\n */\nexport async function generateInitSignature(\n appSecret: string,\n providerId: string,\n timestamp: string\n): Promise<string> {\n validateFunctionParams([\n { input: appSecret, paramName: 'appSecret', isString: true },\n { input: providerId, paramName: 'providerId', isString: true },\n { input: timestamp, paramName: 'timestamp', isString: true }\n ], 'generateInitSignature');\n\n try {\n const wallet = new ethers.Wallet(appSecret);\n const canonicalData = canonicalize({ providerId, timestamp });\n if (!canonicalData) {\n throw new SignatureGeneratingError('Failed to canonicalize data for signing.');\n }\n const messageHash = ethers.keccak256(new TextEncoder().encode(canonicalData));\n return await wallet.signMessage(ethers.getBytes(messageHash));\n } catch (err) {\n throw new SignatureGeneratingError(\n `Error generating init signature for providerId: ${providerId}`,\n err\n );\n }\n}\n"],"mappings":"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","names":["exports","module","import_ethers","import_canonicalize","import_canonicalize","canonicalize","logger","canonicalize","logger","logger","fetchRetry","logger","import_ethers","import_ethers","logger","logger","QRCode","import_ethers","logger","logger","import_ethers","logger","import_ethers","logger","BROWSER_ENVIRONMENT_ERROR","isBrowserEnvironment","assertNonBrowserEnvironment","TOKEN_CLOCK_SKEW_S","decodeBase64Url","crypto","logger","sdkVersion","canonicalize","_a","import_ethers","import_canonicalize","canonicalize"]}
|