@reclaimprotocol/js-sdk 5.0.0 → 5.1.0-dev.1
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/README.md +1 -1
- package/dist/index.d.ts +131 -93
- package/dist/index.js +78 -23
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
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/helper.ts","../src/utils/constants.ts","../src/utils/validationUtils.ts","../src/utils/strings.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/providerUtils.ts","../src/utils/proofValidationUtils.ts","../src/utils/verifyTee.ts","../src/utils/amdCerts.ts"],"sourcesContent":["{\n \"name\": \"@reclaimprotocol/js-sdk\",\n \"version\": \"5.0.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}\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 * from './witness';\nexport type * from './witness';\nexport { verifyTeeAttestation } from './utils/verifyTee';\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 interface TeeAttestation {\n workload_digest: string;\n verifier_digest: string;\n nonce: string;\n snp_report: string;\n vlek_cert: string;\n timestamp: string;\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 publicData?: { [key: string]: string };\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}\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 };\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}","import { type Proof, type Context, RECLAIM_EXTENSION_ACTIONS, ExtensionMessage, ProviderVersionInfo } 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 TrustedData,\n type VerifyProofResult,\n} from './utils/types'\nimport { SessionStatus, DeviceType } from './utils/types'\nimport { ethers } from 'ethers'\nimport canonicalize from 'canonicalize'\nimport {\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 TeeVerificationError\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 { canonicalStringify } from './utils/strings'\nimport { assertValidateProof, VerificationConfig } from './utils/proofValidationUtils'\nimport { verifyTeeAttestation } from './utils/verifyTee'\nimport { fetchProviderHashRequirementsBy, ProviderHashRequirementsConfig } from './utils/providerUtils'\n\nconst logger = loggerModule.logger\n\nconst sdkVersion = require('../package.json').version;\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 * @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 `verifyTEE` to require TEE attestation verification.\n * @returns Verification result with `isVerified`, extracted `data` from each proof, optional `error` on failure, and `isTeeVerified` when `verifyTEE` is enabled.\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, isTeeVerified, data } = await verifyProof(proof, { ...request.getProviderVersion(), verifyTEE: true });\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 const result: VerifyProofResult = {\n isVerified: true,\n data: proofs.map(extractProofData),\n }\n\n if (config.verifyTEE) {\n const hasTeeData = proofs.every(proof => proof.teeAttestation || JSON.parse(proof.claimData.context).attestationNonce);\n\n if (!hasTeeData) {\n const teeError = new TeeVerificationError('TEE verification requested but one or more proofs are missing TEE attestation data');\n logger.error(teeError.message);\n result.isTeeVerified = false;\n result.isVerified = false;\n result.error = teeError;\n return result;\n }\n\n try {\n const teeResults = await Promise.all(proofs.map(proof => verifyTeeAttestation(proof)));\n result.isTeeVerified = teeResults.every(r => r === true);\n if (!result.isTeeVerified) {\n const teeError = new TeeVerificationError('TEE attestation verification failed for one or more proofs');\n logger.error(teeError.message);\n result.isVerified = false;\n result.error = teeError;\n }\n } catch (error) {\n const teeError = new TeeVerificationError('Error verifying TEE attestation', error);\n logger.error(teeError.message);\n result.isTeeVerified = false;\n result.isVerified = false;\n result.error = teeError;\n }\n }\n\n return result;\n } catch (error) {\n logger.error('Error in validating proof:', error);\n return {\n isVerified: false,\n data: [],\n error: error instanceof Error ? error : new Error(String(error)),\n }\n }\n}\n\nfunction extractProofData(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\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 // check if options is provided and validate each property of options\n if (options) {\n if (options.acceptAiProviders) {\n validateFunctionParams([\n { paramName: 'acceptAiProviders', input: options.acceptAiProviders }\n ], 'the constructor')\n }\n if (options.providerVersion) {\n validateFunctionParams([\n { paramName: 'providerVersion', input: options.providerVersion, isString: true }\n ], 'the constructor')\n }\n if (options.log) {\n validateFunctionParams([\n { paramName: 'log', input: options.log }\n ], 'the constructor')\n }\n if (options.useAppClip) {\n validateFunctionParams([\n { paramName: 'useAppClip', input: options.useAppClip }\n ], 'the constructor')\n }\n if (options.device) {\n validateFunctionParams([\n { paramName: 'device', input: options.device, isString: true }\n ], 'the constructor')\n }\n if (options.useBrowserExtension) {\n validateFunctionParams([\n { paramName: 'useBrowserExtension', input: options.useBrowserExtension }\n ], 'the constructor')\n }\n if (options.extensionID) {\n validateFunctionParams([\n { paramName: 'extensionID', input: options.extensionID, isString: true }\n ], 'the constructor')\n }\n if (options.envUrl) {\n validateFunctionParams([\n { paramName: 'envUrl', input: options.envUrl, isString: true }\n ], 'the constructor')\n }\n if (options.portalUrl) {\n validateFunctionParams([\n { paramName: 'portalUrl', input: options.portalUrl, isString: true }\n ], 'the constructor')\n }\n if (options.customSharePageUrl) {\n validateFunctionParams([\n { paramName: 'customSharePageUrl', input: options.customSharePageUrl, isString: true }\n ], 'the constructor')\n }\n if (options.customAppClipUrl) {\n validateFunctionParams([\n { paramName: 'customAppClipUrl', input: options.customAppClipUrl, isString: true }\n ], 'the constructor')\n }\n if (options.preferredLocale) {\n validateFunctionParams([\n { paramName: 'preferredLocale', input: options.preferredLocale, isString: true }\n ], 'the constructor');\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 }, 'the constructor');\n }\n }\n\n const proofRequestInstance = new ReclaimProofRequest(applicationId, providerId, options)\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 (options?.acceptTeeAttestation) {\n const wallet = new ethers.Wallet(appSecret)\n const nonceData = `${applicationId}:${data.sessionId}:${proofRequestInstance.timeStamp}`\n const nonceMsg = ethers.getBytes(ethers.keccak256(new TextEncoder().encode(nonceData)))\n const nonceSignature = await wallet.signMessage(nonceMsg)\n\n proofRequestInstance.setAttestationContext(nonceSignature, {\n applicationId,\n sessionId: data.sessionId,\n timestamp: proofRequestInstance.timeStamp\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 * 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\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 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 }\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. Do not rely completely on `startSession` callbacks on the frontend when using these backend callbacks.\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 * @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 }: 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 const { isVerified: verified } = await verifyProof(proofs, this.getProviderVersion());\n if (!verified) {\n logger.info(`Proofs not verified: count=${proofs?.length}`);\n throw new ProofNotVerifiedError();\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');\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 { OnError } from './types'\nimport { TimeoutError } from './errors'\nimport loggerModule from './logger'\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","// 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","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\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 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 { 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\" | 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\";\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 VerificationConfig = ValidationConfig & {\n /**\n * If true, verifies TEE (Trusted Execution Environment) attestation included in the proof.\n * When enabled, the result will include `isTeeVerified` and `isVerified` will be false\n * if TEE data is missing or TEE verification fails.\n */\n verifyTEE?: boolean;\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 forge from 'node-forge';\nimport { Proof, TeeAttestation } from './interfaces';\nimport { ethers } from 'ethers';\nimport { AMD_CERTS } from './amdCerts';\nimport loggerModule from './logger';\n\nconst crlCache: Record<string, { buffer: Uint8Array, fetchedAt: number }> = {};\nconst logger = loggerModule.logger;\n\ntype BinaryLike = Uint8Array | ArrayBuffer | Buffer;\n\nfunction toUint8Array(input: BinaryLike): Uint8Array {\n if (typeof Buffer !== 'undefined' && typeof Buffer.isBuffer === 'function' && Buffer.isBuffer(input)) {\n return new Uint8Array(input);\n }\n if (input instanceof Uint8Array) {\n return new Uint8Array(input);\n }\n if (typeof ArrayBuffer !== 'undefined' && input instanceof ArrayBuffer) {\n return new Uint8Array(input);\n }\n throw new Error('Unsupported binary data type');\n}\n\nfunction uint8ArrayToBinaryString(bytes: Uint8Array): string {\n let result = '';\n const chunkSize = 0x8000;\n for (let i = 0; i < bytes.length; i += chunkSize) {\n const chunk = bytes.subarray(i, i + chunkSize);\n result += String.fromCharCode(...chunk);\n }\n return result;\n}\n\nfunction binaryStringToUint8Array(binary: string): Uint8Array {\n const result = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) {\n result[i] = binary.charCodeAt(i);\n }\n return result;\n}\n\nfunction base64ToUint8Array(base64: string): Uint8Array {\n if (typeof atob === 'function') {\n const binary = atob(base64);\n return binaryStringToUint8Array(binary);\n }\n if (typeof Buffer !== 'undefined') {\n return new Uint8Array(Buffer.from(base64, 'base64'));\n }\n throw new Error('Base64 decoding is not supported in this environment');\n}\n\nfunction arrayBufferToHex(buffer: ArrayBuffer | Uint8Array): string {\n const view = buffer instanceof Uint8Array ? buffer : new Uint8Array(buffer);\n let hex = '';\n for (let i = 0; i < view.length; i++) {\n hex += view[i].toString(16).padStart(2, '0');\n }\n return hex;\n}\n\nfunction concatUint8Arrays(parts: Uint8Array[]): Uint8Array {\n const totalLength = parts.reduce((sum, arr) => sum + arr.length, 0);\n const result = new Uint8Array(totalLength);\n let offset = 0;\n for (const arr of parts) {\n result.set(arr, offset);\n offset += arr.length;\n }\n return result;\n}\n\nfunction reverseBytes(bytes: Uint8Array): Uint8Array {\n const copy = Uint8Array.from(bytes);\n copy.reverse();\n return copy;\n}\n\nfunction normalizeSerial(s: string) {\n let cleaned = s.toLowerCase().replace(/[^a-f0-9]/g, '');\n while (cleaned.startsWith('0') && cleaned.length > 1) cleaned = cleaned.substring(1);\n return cleaned;\n}\nconst isNode = typeof process !== 'undefined' && process.versions && process.versions.node;\nconst getSubtleCrypto = () => {\n if (typeof window !== 'undefined' && window.crypto?.subtle) return window.crypto.subtle;\n if (isNode) return require('crypto').webcrypto.subtle;\n throw new Error('No WebCrypto subtle implementation found in this environment');\n};\n\ninterface ParsedCert {\n serialNumber: string;\n tbsDer: Uint8Array;\n signature: Uint8Array;\n sigAlgOid: string;\n spkiDer: Uint8Array;\n notBefore?: Date;\n notAfter?: Date;\n}\n\nfunction parseCert(buffer: BinaryLike): ParsedCert {\n const bytes = toUint8Array(buffer);\n const asn1 = forge.asn1.fromDer(uint8ArrayToBinaryString(bytes));\n const certSeq = asn1.value as any[];\n const tbsAsn1 = certSeq[0];\n const sigAlgAsn1 = certSeq[1];\n const sigValueAsn1 = certSeq[2];\n\n const tbsFields = tbsAsn1.value as any[];\n let idx = 0;\n if (tbsFields[idx].tagClass === 128) idx++; // version\n const serialAsn1 = tbsFields[idx++];\n const serialNumber = forge.util.bytesToHex(serialAsn1.value);\n idx++; // sigAlg\n idx++; // issuer\n const validityAsn1 = tbsFields[idx++];\n idx++; // subject\n const spkiAsn1 = tbsFields[idx];\n\n if (!validityAsn1 || !Array.isArray(validityAsn1.value) || validityAsn1.value.length < 2) {\n throw new Error('Certificate validity window is malformed');\n }\n const notBeforeNode = validityAsn1.value[0];\n const notAfterNode = validityAsn1.value[1];\n const notBefore = notBeforeNode ? parseAsn1Time(notBeforeNode) : undefined;\n const notAfter = notAfterNode ? parseAsn1Time(notAfterNode) : undefined;\n\n const sigRaw = typeof sigValueAsn1.value === 'string' ? sigValueAsn1.value : '';\n const signature = binaryStringToUint8Array(sigRaw.substring(1));\n const sigAlgOid = forge.asn1.derToOid((sigAlgAsn1.value as any[])[0].value);\n\n return {\n serialNumber: normalizeSerial(serialNumber),\n tbsDer: binaryStringToUint8Array(forge.asn1.toDer(tbsAsn1).getBytes()),\n signature,\n sigAlgOid,\n spkiDer: binaryStringToUint8Array(forge.asn1.toDer(spkiAsn1).getBytes()),\n notBefore,\n notAfter\n };\n}\n\nasync function verifySignature(publicKeyPem: string, data: Uint8Array, signature: Uint8Array, sigAlgOid: string) {\n const cryptoSubtle = getSubtleCrypto();\n const forgeCert = forge.pki.certificateFromPem(publicKeyPem);\n const spkiBuf = binaryStringToUint8Array(forge.asn1.toDer(forge.pki.publicKeyToAsn1(forgeCert.publicKey)).getBytes());\n\n let importParams: any;\n let verifyParams: any;\n\n if (sigAlgOid === '1.2.840.113549.1.1.10') { // rsassa-pss\n importParams = { name: 'RSA-PSS', hash: 'SHA-384' };\n verifyParams = { name: 'RSA-PSS', saltLength: 48 };\n } else if (sigAlgOid === '1.2.840.113549.1.1.11' || sigAlgOid === '1.2.840.113549.1.1.12' || sigAlgOid === '1.2.840.113549.1.1.5') {\n importParams = { name: 'RSASSA-PKCS1-v1_5', hash: sigAlgOid === '1.2.840.113549.1.1.12' ? 'SHA-384' : 'SHA-256' };\n verifyParams = { name: 'RSASSA-PKCS1-v1_5' };\n } else if (sigAlgOid === '1.2.840.10045.4.3.3') { // ecdsa-with-sha384\n importParams = { name: 'ECDSA', namedCurve: 'P-384' };\n verifyParams = { name: 'ECDSA', hash: 'SHA-384' };\n } else {\n // Fallback or generic\n importParams = { name: 'RSASSA-PKCS1-v1_5', hash: 'SHA-256' };\n verifyParams = { name: 'RSASSA-PKCS1-v1_5' };\n }\n\n const key = await cryptoSubtle.importKey('spki', spkiBuf, importParams, false, ['verify']);\n const isValid = await cryptoSubtle.verify(verifyParams, key, signature, data);\n if (!isValid) throw new Error(`Signature verification failed (OID: ${sigAlgOid}, ImportParams: ${JSON.stringify(importParams)})`);\n}\n\nconst COSIGN_PUBLIC_KEY = `-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEjiL30OjPuxa+GC1I7SAcBv2u2pMt\nh9WbP33IvB3eFww+C1hoW0fwdZPiq4FxBtKNiZuFpmYuFngW/nJteBu9kQ==\n-----END PUBLIC KEY-----\n`;\n\n/**\n * Validates the hardware TEE attestation included in the proof.\n * Throws an error if the attestation is invalid or compromised.\n */\nexport async function verifyTeeAttestation(proof: Proof, expectedApplicationId?: string): Promise<boolean> {\n try {\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 // 1. Verify Nonce Binding\n let expectedNonceSignature: string | undefined;\n let nonceDataObj: any;\n try {\n const context = JSON.parse(proof.claimData.context);\n expectedNonceSignature = context.attestationNonce;\n nonceDataObj = context.attestationNonceData;\n } catch (e) {\n throw new Error(\"Failed to parse proof context to extract attestationNonce\");\n }\n\n if (!expectedNonceSignature || !nonceDataObj) {\n throw new Error(\"Proof context is missing attestationNonce or attestationNonceData\");\n }\n\n if (teeAttestation.nonce !== expectedNonceSignature) {\n throw new Error(`Nonce Mismatch! Expected signature ${expectedNonceSignature}, got ${teeAttestation.nonce}`);\n }\n\n const { applicationId, sessionId, timestamp } = nonceDataObj;\n\n if (expectedApplicationId && applicationId.toLowerCase() !== expectedApplicationId.toLowerCase()) {\n throw new Error(`Application ID Mismatch! Expected ${expectedApplicationId}, but proof context contains ${applicationId}`);\n }\n\n const expectedNonceData = `${applicationId}:${sessionId}:${timestamp}`;\n const nonceMsg = ethers.getBytes(ethers.keccak256(new TextEncoder().encode(expectedNonceData)));\n const recoveredAddress = ethers.verifyMessage(nonceMsg, expectedNonceSignature);\n\n if (recoveredAddress.toLowerCase() !== applicationId.toLowerCase()) {\n throw new Error(`Nonce signature verification failed: recovered ${recoveredAddress}, expected ${applicationId}`);\n }\n\n try {\n const context = JSON.parse(proof.claimData.context);\n const paramSessionId = context.attestationNonceData.sessionId;\n if (!paramSessionId) {\n throw new Error(`Proof parameters are missing proxySessionId or sessionId`);\n }\n if (paramSessionId.toString() !== sessionId.toString()) {\n throw new Error(`Session ID Mismatch! Expected ${sessionId}, but proof parameters contain ${paramSessionId}`);\n }\n\n // Timestamp skew check: claimData.timestampS (seconds) vs attestationNonceData.timestamp (ms)\n const claimTimestampMs = proof.claimData.timestampS * 1000;\n const nonceTimestampMs = parseInt(timestamp, 10);\n const diffMs = Math.abs(claimTimestampMs - nonceTimestampMs);\n const TEN_MINUTES_MS = 10 * 60 * 1000;\n if (diffMs > TEN_MINUTES_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 } catch (e) {\n if (e instanceof Error && (e.message.includes(\"Session ID Mismatch!\") || e.message.includes(\"Timestamp Skew\"))) {\n throw e;\n }\n throw new Error(`Failed to cross-verify session ID: ${(e as Error).message}`);\n }\n\n // 2. Recompute REPORT_DATA Hash\n // Recompute H(workload_digest || verifier_digest || pubkey_hash || nonce)\n // Here PUBKEY_HASH is the hash of the generic cosign pub key used by Popcorn.\n // For universal verification, we assume the Popcorn standard cosign public key hash matches the one used by Popcorn.\n // Note: To be fully strict, the public key hash should either be provided or fetched. \n // We will compute the SHA256 of the concatenated string.\n\n // The verify_proof script uses the hash of a specific file. We'll reconstruct the data that was signed.\n // However, wait! If JS SDK cannot easily hash the hardcoded cosign public key (or doesn't have it), \n // we must verify using the provided public data or skip the workload digest lock for now.\n // The user requested: \"same verification we do in the popcorn verficcation script\".\n // Let's implement the generic parts first: Hardware Signature and TCB.\n\n const reportBuffer = base64ToUint8Array(teeAttestation.snp_report);\n const report = parseAttestationReport(reportBuffer);\n\n if (report.isDebugEnabled) {\n throw new Error(\"POLICY CHECK FAILED: Debug mode is ALLOWED. Environment is compromised.\");\n }\n\n const certBuffer = base64ToUint8Array(teeAttestation.vlek_cert);\n\n await verifyAMDChain(certBuffer);\n verifyTCB(certBuffer, report);\n await verifyHardwareSignature(reportBuffer, certBuffer);\n await verifyReportData(teeAttestation, proof.claimData.context, report);\n\n return true;\n } catch (error) {\n logger.error('TEE attestation verification failed:', error);\n return false;\n }\n}\n\nfunction parseAttestationReport(buffer: Uint8Array) {\n if (buffer.length < 1000) {\n throw new Error(`Report buffer is too small: ${buffer.length} bytes`);\n }\n\n const view = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength);\n const policy = view.getBigUint64(0x08, true);\n const isDebugEnabled = (policy & (BigInt(1) << BigInt(19))) !== BigInt(0);\n\n const reported_tcb = {\n bootloader: buffer[0x38],\n tee: buffer[0x39],\n snp: buffer[0x3E],\n microcode: buffer[0x3F]\n };\n\n const reportData = arrayBufferToHex(buffer.subarray(0x50, 0x90)); // 64 bytes\n return { policy, isDebugEnabled, reported_tcb, reportData };\n}\n\nfunction getExtValue(certAsn1: any, oidString: string) {\n const tbsCert = certAsn1.value[0];\n if (!tbsCert || !tbsCert.value) return null;\n\n const extBlockWrapper = tbsCert.value.find((node: any) => node.tagClass === forge.asn1.Class.CONTEXT_SPECIFIC && node.type === 3);\n if (!extBlockWrapper || !extBlockWrapper.value || !extBlockWrapper.value.length) return null;\n\n const extSequence = extBlockWrapper.value[0];\n for (const ext of extSequence.value) {\n const extIdAsn1 = ext.value[0];\n const extIdStr = forge.asn1.derToOid(extIdAsn1.value);\n if (extIdStr === oidString) {\n const extValueAsn1 = ext.value[ext.value.length - 1];\n const rawOctetStringBytes = extValueAsn1.value;\n try {\n // The extension value is an OCTET STRING containing the DER encoding of an INTEGER\n const innerAsn1 = forge.asn1.fromDer(forge.util.createBuffer(rawOctetStringBytes));\n if (innerAsn1.type === 2) { // INTEGER\n const bytes = innerAsn1.value;\n if (typeof bytes === 'string' && bytes.length > 0) {\n return bytes.charCodeAt(bytes.length - 1);\n } else {\n throw new Error(`Extension ${oidString} INTEGER value is empty or invalid`);\n }\n } else {\n throw new Error(`Extension ${oidString} does not contain an INTEGER, found type ${innerAsn1.type}`);\n }\n } catch (e) {\n // Fail closed on any parse or schema error\n throw new Error(`Failed to strictly parse AMD TCB extension ${oidString}: ${(e as Error).message}`);\n }\n }\n }\n return null;\n}\n\nfunction verifyTCB(vlekCertBuffer: Uint8Array, report: any) {\n const certAsn1 = forge.asn1.fromDer(forge.util.createBuffer(uint8ArrayToBinaryString(vlekCertBuffer)));\n\n const OID_BOOTLOADER = '1.3.6.1.4.1.3704.1.3.1';\n const OID_TEE = '1.3.6.1.4.1.3704.1.3.2';\n const OID_SNP = '1.3.6.1.4.1.3704.1.3.3';\n const OID_MICROCODE = '1.3.6.1.4.1.3704.1.3.8';\n\n const certTcb = {\n bootloader: getExtValue(certAsn1, OID_BOOTLOADER),\n tee: getExtValue(certAsn1, OID_TEE),\n snp: getExtValue(certAsn1, OID_SNP),\n microcode: getExtValue(certAsn1, OID_MICROCODE)\n };\n\n if (certTcb.bootloader !== null && report.reported_tcb.bootloader < certTcb.bootloader) {\n throw new Error(`TCB Downgrade! Bootloader reported ${report.reported_tcb.bootloader}, but certificate requires ${certTcb.bootloader}`);\n }\n if (certTcb.tee !== null && report.reported_tcb.tee < certTcb.tee) {\n throw new Error(`TCB Downgrade! TEE reported ${report.reported_tcb.tee}, but certificate requires ${certTcb.tee}`);\n }\n if (certTcb.snp !== null && report.reported_tcb.snp < certTcb.snp) {\n throw new Error(`TCB Downgrade! SNP reported ${report.reported_tcb.snp}, but certificate requires ${certTcb.snp}`);\n }\n if (certTcb.microcode !== null && report.reported_tcb.microcode < certTcb.microcode) {\n throw new Error(`TCB Downgrade! Microcode reported ${report.reported_tcb.microcode}, but certificate requires ${certTcb.microcode}`);\n }\n}\n\nfunction parseAsn1Time(node: any): Date {\n const s = node.value as string;\n if (node.type === forge.asn1.Type.UTCTIME) {\n // UTCTime: YYMMDDHHmmssZ\n const yr = parseInt(s.substring(0, 2), 10);\n return new Date(Date.UTC(\n yr >= 50 ? 1900 + yr : 2000 + yr,\n parseInt(s.substring(2, 4), 10) - 1,\n parseInt(s.substring(4, 6), 10),\n parseInt(s.substring(6, 8), 10),\n parseInt(s.substring(8, 10), 10),\n parseInt(s.substring(10, 12), 10)\n ));\n } else {\n // GeneralizedTime: YYYYMMDDHHmmssZ\n return new Date(Date.UTC(\n parseInt(s.substring(0, 4), 10),\n parseInt(s.substring(4, 6), 10) - 1,\n parseInt(s.substring(6, 8), 10),\n parseInt(s.substring(8, 10), 10),\n parseInt(s.substring(10, 12), 10),\n parseInt(s.substring(12, 14), 10)\n ));\n }\n}\n\nasync function verifyCRL(crlBuf: Uint8Array, arkPem: string, vlekSerial: string): Promise<void> {\n // Parse CRL: CertificateList SEQUENCE { TBSCertList, signatureAlgorithm, signatureValue }\n const crlAsn1 = forge.asn1.fromDer(forge.util.createBuffer(uint8ArrayToBinaryString(crlBuf)));\n\n if (!Array.isArray(crlAsn1.value) || crlAsn1.value.length < 3) {\n throw new Error('CRL ASN.1 structure is invalid: expected SEQUENCE with TBSCertList, AlgorithmIdentifier, BIT STRING');\n }\n\n const tbsAsn1 = (crlAsn1.value as any[])[0];\n const sigBitsAsn1 = (crlAsn1.value as any[])[2]; // BIT STRING containing the signature\n\n if (!Array.isArray(tbsAsn1.value)) {\n throw new Error('CRL TBSCertList is not a valid SEQUENCE');\n }\n\n const tbsFields = tbsAsn1.value as any[];\n let fi = 0;\n\n // Optional version field (UNIVERSAL INTEGER — present in CRL v2)\n if (fi < tbsFields.length &&\n tbsFields[fi].tagClass === forge.asn1.Class.UNIVERSAL &&\n tbsFields[fi].type === forge.asn1.Type.INTEGER) {\n fi++;\n }\n\n // signature AlgorithmIdentifier (skip, matches outer signatureAlgorithm)\n if (fi < tbsFields.length) fi++;\n\n // issuer Name\n if (fi >= tbsFields.length) throw new Error('CRL TBSCertList missing issuer');\n const issuerAsn1 = tbsFields[fi++];\n\n // thisUpdate (UTCTime or GeneralizedTime)\n if (fi >= tbsFields.length) throw new Error('CRL TBSCertList missing thisUpdate');\n const thisUpdateAsn1 = tbsFields[fi++];\n\n // nextUpdate (optional — UTCTime or GeneralizedTime)\n let nextUpdateAsn1: any = null;\n if (fi < tbsFields.length &&\n tbsFields[fi].tagClass === forge.asn1.Class.UNIVERSAL &&\n (tbsFields[fi].type === forge.asn1.Type.UTCTIME ||\n tbsFields[fi].type === forge.asn1.Type.GENERALIZEDTIME)) {\n nextUpdateAsn1 = tbsFields[fi++];\n }\n\n // revokedCertificates (optional UNIVERSAL SEQUENCE; skip context-specific extensions)\n let revokedSeq: any = null;\n if (fi < tbsFields.length &&\n tbsFields[fi].tagClass === forge.asn1.Class.UNIVERSAL &&\n tbsFields[fi].type === forge.asn1.Type.SEQUENCE) {\n revokedSeq = tbsFields[fi];\n }\n\n // 1. Validity Period\n const now = new Date();\n const thisUpdate = parseAsn1Time(thisUpdateAsn1);\n if (thisUpdate > now) {\n throw new Error(`CRL is not yet valid: thisUpdate is ${thisUpdate.toISOString()}`);\n }\n if (nextUpdateAsn1) {\n const nextUpdate = parseAsn1Time(nextUpdateAsn1);\n if (nextUpdate < now) {\n throw new Error(`CRL has expired: nextUpdate was ${nextUpdate.toISOString()}`);\n }\n }\n\n // 2. Issuer Verification — compare CRL issuer DER bytes to ARK certificate subject DER bytes\n // The AMD VLEK CRL is issued by the ARK (CN=ARK-Milan/Genoa), not the ASK\n const crlIssuerDer = forge.asn1.toDer(issuerAsn1).getBytes();\n const arkForgeCert = forge.pki.certificateFromPem(arkPem);\n const arkCertAsn1 = forge.pki.certificateToAsn1(arkForgeCert);\n // TBSCertificate field order: [0]version, serial, sigAlg, issuer, validity, subject, spki, ...\n const arkSubjectAsn1 = ((arkCertAsn1.value as any[])[0].value as any[])[5];\n const arkSubjectDer = forge.asn1.toDer(arkSubjectAsn1).getBytes();\n if (crlIssuerDer !== arkSubjectDer) {\n throw new Error('CRL issuer does not match AMD ARK certificate subject — chain mismatch');\n }\n\n // 3. Signature Verification (AMD CRL uses RSA-PSS with SHA-384, signed by ARK)\n const tbsDerBuf = binaryStringToUint8Array(forge.asn1.toDer(tbsAsn1).getBytes());\n // BIT STRING first byte = unused bits count, skip it\n const sigRaw = typeof sigBitsAsn1.value === 'string' ? sigBitsAsn1.value : '';\n const sigBuf = binaryStringToUint8Array(sigRaw.substring(1));\n\n const cryptoSubtle = getSubtleCrypto();\n const spkiBuf = binaryStringToUint8Array(\n forge.asn1.toDer(forge.pki.publicKeyToAsn1(arkForgeCert.publicKey)).getBytes()\n );\n const arkCryptoKey = await cryptoSubtle.importKey(\n 'spki', spkiBuf,\n { name: 'RSA-PSS', hash: 'SHA-384' },\n false, ['verify']\n );\n const isValid = await cryptoSubtle.verify(\n { name: 'RSA-PSS', saltLength: 48 }, // SHA-384 salt length is 48\n arkCryptoKey,\n sigBuf,\n tbsDerBuf\n );\n if (!isValid) {\n throw new Error('CRL signature is INVALID — the CRL may be tampered or forged');\n }\n\n // 4. Revocation Check — only inspect the revokedCertificates list, not arbitrary ASN.1 nodes\n const targetSerial = normalizeSerial(vlekSerial);\n if (revokedSeq && Array.isArray(revokedSeq.value)) {\n for (const entry of revokedSeq.value) {\n if (!Array.isArray(entry.value) || entry.value.length < 2) continue;\n const serialAsn1 = entry.value[0];\n if (serialAsn1.type !== forge.asn1.Type.INTEGER || typeof serialAsn1.value !== 'string') continue;\n const serialHex = forge.util.bytesToHex(serialAsn1.value);\n if (normalizeSerial(serialHex) === targetSerial) {\n throw new Error('🚨 VLEK Certificate is REVOKED per AMD CRL! This hardware may be compromised.');\n }\n }\n }\n}\n\nfunction assertCertValidity(label: string, cert: ParsedCert) {\n const now = Date.now();\n if (cert.notBefore && now < cert.notBefore.getTime()) {\n throw new Error(`${label} certificate is not yet valid (notBefore: ${cert.notBefore.toISOString()})`);\n }\n if (cert.notAfter && now > cert.notAfter.getTime()) {\n throw new Error(`${label} certificate expired on ${cert.notAfter.toISOString()}`);\n }\n}\n\nasync function verifyAMDChain(vlekCertBuffer: Uint8Array) {\n const processors = ['Milan', 'Genoa'];\n let chainVerified = false;\n\n const vlek = parseCert(vlekCertBuffer);\n assertCertValidity('VLEK', vlek);\n\n for (const processor of processors) {\n let matchedChain = false;\n try {\n const chainPem = AMD_CERTS[processor];\n if (!chainPem) continue;\n\n const certs = chainPem.split('-----END CERTIFICATE-----')\n .map(c => c.trim())\n .filter(c => c.length > 0)\n .map(c => c + '\\n-----END CERTIFICATE-----\\n');\n\n const askCert = forge.pki.certificateFromPem(certs[0]);\n const arkCert = forge.pki.certificateFromPem(certs[1]);\n\n const askDer = forge.asn1.toDer(forge.pki.certificateToAsn1(askCert)).getBytes();\n const arkDer = forge.asn1.toDer(forge.pki.certificateToAsn1(arkCert)).getBytes();\n const ask = parseCert(binaryStringToUint8Array(askDer));\n const ark = parseCert(binaryStringToUint8Array(arkDer));\n assertCertValidity('ASK', ask);\n assertCertValidity('ARK', ark);\n\n // ARK -> ASK -> VLEK\n try {\n await verifySignature(certs[1], ark.tbsDer, ark.signature, ark.sigAlgOid); // ARK Self-signed\n } catch (e: any) { throw new Error(`AMD ARK self-signature verification failed: ${e.message}`); }\n\n try {\n await verifySignature(certs[1], ask.tbsDer, ask.signature, ask.sigAlgOid); // ASK signed by ARK\n } catch (e: any) { throw new Error(`AMD ASK-by-ARK signature verification failed: ${e.message}`); }\n\n try {\n await verifySignature(certs[0], vlek.tbsDer, vlek.signature, vlek.sigAlgOid); // VLEK signed by ASK\n } catch (e: any) { throw new Error(`VLEK-by-ASK signature verification failed: ${e.message}`); }\n\n matchedChain = true;\n\n // Check CRL\n let crlBuf: Uint8Array | undefined;\n const now = Date.now();\n if (crlCache[processor] && now - crlCache[processor].fetchedAt < 3600000) {\n crlBuf = crlCache[processor].buffer;\n } else {\n const crlUrl = `https://kdsintf.amd.com/vlek/v1/${processor}/crl`;\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), 5000);\n const crlResp = await fetch(crlUrl, { signal: controller.signal });\n clearTimeout(timeoutId);\n\n if (!crlResp.ok) continue;\n crlBuf = new Uint8Array(await crlResp.arrayBuffer());\n crlCache[processor] = { buffer: crlBuf, fetchedAt: now };\n }\n\n if (vlek.serialNumber && crlBuf) {\n await verifyCRL(crlBuf, certs[1], vlek.serialNumber);\n }\n\n chainVerified = true;\n break;\n } catch (e: any) {\n if (matchedChain) {\n throw e; // Hard fail if we matched the chain but CRL fetch/parse failed or cert is revoked\n }\n continue;\n }\n }\n\n if (!chainVerified) {\n throw new Error(\"VLEK Certificate failed verification against all known AMD Root of Trust chains!\");\n }\n}\n\nasync function verifyHardwareSignature(reportBytes: Uint8Array, certBytes: Uint8Array) {\n const vlek = parseCert(certBytes);\n\n const sigOffset = 0x2A0;\n const rLE = reportBytes.subarray(sigOffset, sigOffset + 72);\n const sLE = reportBytes.subarray(sigOffset + 72, sigOffset + 144);\n\n const rBE = reverseBytes(rLE);\n const sBE = reverseBytes(sLE);\n\n const signedData = reportBytes.subarray(0, 0x2A0);\n\n const cryptoSubtle = getSubtleCrypto();\n\n const importedKey = await cryptoSubtle.importKey(\n \"spki\",\n vlek.spkiDer,\n { name: \"ECDSA\", namedCurve: \"P-384\" },\n false,\n [\"verify\"]\n );\n\n // the subtle crypto ECDSA signature needs to be raw (r || s), each 48 bytes long\n // Our rBE and sBE are exactly 72 bytes. P-384 is 48 bytes!\n // The AMD report reserves 72 bytes for R and 72 bytes for S padded with zeros.\n // We MUST verify the dropped high-order bytes are zero to prevent malicious tampering.\n const rPadding = rBE.subarray(0, rBE.length - 48);\n const sPadding = sBE.subarray(0, sBE.length - 48);\n\n if (!rPadding.every(b => b === 0) || !sPadding.every(b => b === 0)) {\n throw new Error(\"Hardware ECDSA signature is malformed: non-zero padding bytes detected in the structural signature coordinates.\");\n }\n\n const r48 = rBE.subarray(rBE.length - 48);\n const s48 = sBE.subarray(sBE.length - 48);\n const rawSignature = concatUint8Arrays([r48, s48]);\n\n const isValid = await cryptoSubtle.verify(\n { name: \"ECDSA\", hash: { name: \"SHA-384\" } },\n importedKey,\n rawSignature,\n signedData\n );\n\n if (!isValid) {\n throw new Error(\"Hardware ECDSA signature is completely invalid!\");\n }\n}\n\nasync function verifyReportData(teeAttestation: TeeAttestation, proofContext: string, report: any) {\n if (!teeAttestation.workload_digest || !teeAttestation.verifier_digest) {\n throw new Error(\"POLICY CHECK FAILED: Missing workload_digest or verifier_digest in TEE attestation.\");\n }\n\n const { attestationNonce: nonce } = JSON.parse(proofContext);\n\n const cryptoSubtle = getSubtleCrypto();\n\n // 1. Extract raw 32-byte SHA256 digest from image refs (part after \"@sha256:\")\n const extractDigestBytes = (imageRef: string): Uint8Array => {\n const marker = '@sha256:';\n const idx = imageRef.lastIndexOf(marker);\n if (idx < 0) throw new Error(`Image ref missing @sha256: digest: ${imageRef}`);\n const hexDigest = imageRef.substring(idx + marker.length);\n if (hexDigest.length !== 64) throw new Error(`SHA256 digest must be 64 hex chars, got ${hexDigest.length} in: ${imageRef}`);\n const bytes = new Uint8Array(32);\n for (let i = 0; i < 32; i++) bytes[i] = parseInt(hexDigest.substring(i * 2, i * 2 + 2), 16);\n return bytes;\n };\n\n // 2. Hash COSIGN public key as canonical DER SPKI bytes (not PEM text)\n const importedCosignKey = await cryptoSubtle.importKey(\n 'spki',\n base64ToUint8Array(\n COSIGN_PUBLIC_KEY\n .replace('-----BEGIN PUBLIC KEY-----', '')\n .replace('-----END PUBLIC KEY-----', '')\n .replace(/\\s+/g, '')\n ),\n { name: 'ECDSA', namedCurve: 'P-256' },\n true,\n ['verify']\n );\n const pubKeySpkiDer = await cryptoSubtle.exportKey('spki', importedCosignKey);\n const pubKeyHashBuffer = await cryptoSubtle.digest('SHA-256', pubKeySpkiDer);\n const pubKeyHashBytes = new Uint8Array(pubKeyHashBuffer);\n\n // 3. Decode nonce from hex to raw bytes (strip 0x prefix)\n const nonceHex = (teeAttestation.nonce || nonce).replace(/^0x/i, '');\n const nonceBytes = new Uint8Array(nonceHex.length / 2);\n for (let i = 0; i < nonceBytes.length; i++) nonceBytes[i] = parseInt(nonceHex.substring(i * 2, i * 2 + 2), 16);\n\n // 4. Extract raw digest bytes from image refs\n const workloadBytes = extractDigestBytes(teeAttestation.workload_digest);\n const verifierBytes = extractDigestBytes(teeAttestation.verifier_digest);\n\n // 5. Build canonical binary payload:\n // \"POPCORN_TEE_REPORT_DATA_V1\" || 0x01 || workload(32) || verifier(32) || pubkeyHash(32) || nonceBytes\n const domainSep = new TextEncoder().encode('POPCORN_TEE_REPORT_DATA_V1');\n const version = new Uint8Array([0x01]);\n const payload = new Uint8Array(\n domainSep.length + version.length +\n workloadBytes.length + verifierBytes.length +\n pubKeyHashBytes.length + nonceBytes.length\n );\n let offset = 0;\n for (const chunk of [domainSep, version, workloadBytes, verifierBytes, pubKeyHashBytes, nonceBytes]) {\n payload.set(chunk, offset);\n offset += chunk.length;\n }\n\n // 6. Compute SHA-256 of the binary payload, duplicate to 64 bytes, compare to report_data\n const hashBuffer = await cryptoSubtle.digest('SHA-256', payload);\n const hashHex = arrayBufferToHex(hashBuffer);\n const expected64ByteHex = hashHex + hashHex;\n\n if (report.reportData !== expected64ByteHex) {\n throw new Error(`REPORT_DATA Mismatch! Hardware report is not bound to these image digests or nonce.\\nExpected: ${expected64ByteHex}\\nGot: ${report.reportData}`);\n }\n}\n","export const AMD_CERTS: Record<string, string> = {\n 'Milan': `-----BEGIN CERTIFICATE-----\n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\n0YPk\n-----END CERTIFICATE-----\n-----BEGIN CERTIFICATE-----\nMIIGYzCCBBKgAwIBAgIDAQAAMEYGCSqGSIb3DQEBCjA5oA8wDQYJYIZIAWUDBAIC\nBQChHDAaBgkqhkiG9w0BAQgwDQYJYIZIAWUDBAICBQCiAwIBMKMDAgEBMHsxFDAS\nBgNVBAsMC0VuZ2luZWVyaW5nMQswCQYDVQQGEwJVUzEUMBIGA1UEBwwLU2FudGEg\nQ2xhcmExCzAJBgNVBAgMAkNBMR8wHQYDVQQKDBZBZHZhbmNlZCBNaWNybyBEZXZp\nY2VzMRIwEAYDVQQDDAlBUkstTWlsYW4wHhcNMjAxMDIyMTcyMzA1WhcNNDUxMDIy\nMTcyMzA1WjB7MRQwEgYDVQQLDAtFbmdpbmVlcmluZzELMAkGA1UEBhMCVVMxFDAS\nBgNVBAcMC1NhbnRhIENsYXJhMQswCQYDVQQIDAJDQTEfMB0GA1UECgwWQWR2YW5j\nZWQgTWljcm8gRGV2aWNlczESMBAGA1UEAwwJQVJLLU1pbGFuMIICIjANBgkqhkiG\n9w0BAQEFAAOCAg8AMIICCgKCAgEA0Ld52RJOdeiJlqK2JdsVmD7FktuotWwX1fNg\nW41XY9Xz1HEhSUmhLz9Cu9DHRlvgJSNxbeYYsnJfvyjx1MfU0V5tkKiU1EesNFta\n1kTA0szNisdYc9isqk7mXT5+KfGRbfc4V/9zRIcE8jlHN61S1ju8X93+6dxDUrG2\nSzxqJ4BhqyYmUDruPXJSX4vUc01P7j98MpqOS95rORdGHeI52Naz5m2B+O+vjsC0\n60d37jY9LFeuOP4Meri8qgfi2S5kKqg/aF6aPtuAZQVR7u3KFYXP59XmJgtcog05\ngmI0T/OitLhuzVvpZcLph0odh/1IPXqx3+MnjD97A7fXpqGd/y8KxX7jksTEzAOg\nbKAeam3lm+3yKIcTYMlsRMXPcjNbIvmsBykD//xSniusuHBkgnlENEWx1UcbQQrs\n+gVDkuVPhsnzIRNgYvM48Y+7LGiJYnrmE8xcrexekBxrva2V9TJQqnN3Q53kt5vi\nQi3+gCfmkwC0F0tirIZbLkXPrPwzZ0M9eNxhIySb2npJfgnqz55I0u33wh4r0ZNQ\neTGfw03MBUtyuzGesGkcw+loqMaq1qR4tjGbPYxCvpCq7+OgpCCoMNit2uLo9M18\nfHz10lOMT8nWAUvRZFzteXCm+7PHdYPlmQwUw3LvenJ/ILXoQPHfbkH0CyPfhl1j\nWhJFZasCAwEAAaN+MHwwDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBSFrBrRQ/fI\nrFXUxR1BSKvVeErUUzAPBgNVHRMBAf8EBTADAQH/MDoGA1UdHwQzMDEwL6AtoCuG\nKWh0dHBzOi8va2RzaW50Zi5hbWQuY29tL3ZjZWsvdjEvTWlsYW4vY3JsMEYGCSqG\nSIb3DQEBCjA5oA8wDQYJYIZIAWUDBAICBQChHDAaBgkqhkiG9w0BAQgwDQYJYIZI\nAWUDBAICBQCiAwIBMKMDAgEBA4ICAQC6m0kDp6zv4Ojfgy+zleehsx6ol0ocgVel\nETobpx+EuCsqVFRPK1jZ1sp/lyd9+0fQ0r66n7kagRk4Ca39g66WGTJMeJdqYriw\nSTjjDCKVPSesWXYPVAyDhmP5n2v+BYipZWhpvqpaiO+EGK5IBP+578QeW/sSokrK\ndHaLAxG2LhZxj9aF73fqC7OAJZ5aPonw4RE299FVarh1Tx2eT3wSgkDgutCTB1Yq\nzT5DuwvAe+co2CIVIzMDamYuSFjPN0BCgojl7V+bTou7dMsqIu/TW/rPCX9/EUcp\nKGKqPQ3P+N9r1hjEFY1plBg93t53OOo49GNI+V1zvXPLI6xIFVsh+mto2RtgEX/e\npmMKTNN6psW88qg7c1hTWtN6MbRuQ0vm+O+/2tKBF2h8THb94OvvHHoFDpbCELlq\nHnIYhxy0YKXGyaW1NjfULxrrmxVW4wcn5E8GddmvNa6yYm8scJagEi13mhGu4Jqh\n3QU3sf8iUSUr09xQDwHtOQUVIqx4maBZPBtSMf+qUDtjXSSq8lfWcd8bLr9mdsUn\nJZJ0+tuPMKmBnSH860llKk+VpVQsgqbzDIvOLvD6W1Umq25boxCYJ+TuBoa4s+HH\nCViAvgT9kf/rBq1d+ivj6skkHxuzcxbk1xv6ZGxrteJxVH7KlX7YRdZ6eARKwLe4\nAFZEAwoKCQ==\n-----END CERTIFICATE-----`,\n 'Genoa': `-----BEGIN CERTIFICATE-----\n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\n2cko\n-----END CERTIFICATE-----\n-----BEGIN CERTIFICATE-----\n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\n/wMz1R1BHg==\n-----END CERTIFICATE-----`\n};\n"],"mappings":"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","names":["exports","module","import_ethers","import_canonicalize","logger","import_canonicalize","canonicalize","logger","canonicalize","fetchRetry","logger","import_ethers","import_ethers","logger","logger","QRCode","logger","logger","import_ethers","logger","forge","logger","sdkVersion","canonicalize","_a"]}
|
|
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/helper.ts","../src/utils/constants.ts","../src/utils/validationUtils.ts","../src/utils/strings.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/providerUtils.ts","../src/utils/proofValidationUtils.ts","../src/utils/verifyTee.ts","../src/utils/amdCerts.ts"],"sourcesContent":["{\n \"name\": \"@reclaimprotocol/js-sdk\",\n \"version\": \"5.1.0-dev.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 * from './witness';\nexport type * from './witness';\nexport { verifyTeeAttestation } from './utils/verifyTee';\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 interface TeeAttestation {\n workload_digest: string;\n verifier_digest: string;\n nonce: string;\n snp_report: string;\n vlek_cert: string;\n timestamp: string;\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}\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 };\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}","import { type Proof, type Context, RECLAIM_EXTENSION_ACTIONS, ExtensionMessage, ProviderVersionInfo } 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 TrustedData,\n type VerifyProofResult,\n type VerifyProofResultSuccess,\n type VerifyProofResultFailure,\n} from './utils/types'\nimport { SessionStatus, DeviceType } from './utils/types'\nimport { ethers } from 'ethers'\nimport canonicalize from 'canonicalize'\nimport {\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 TeeVerificationError\n} from './utils/errors';\nimport { validateContext, validateFunctionParams, validateParameters, validateSignature, validateURL, validateModalOptions, validateFunctionParamsWithFn, validateRedirectionMethod, validateRedirectionBody, hashObject } 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 { canonicalStringify } from './utils/strings'\nimport { assertValidateProof, VerificationConfig } from './utils/proofValidationUtils'\nimport { verifyTeeAttestation } from './utils/verifyTee'\nimport { fetchProviderHashRequirementsBy, ProviderHashRequirementsConfig } from './utils/providerUtils'\n\nconst logger = loggerModule.logger\n\nconst sdkVersion = require('../package.json').version;\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 * @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 `verifyTEE` to require TEE attestation verification.\n * @returns Verification result with `isVerified`, extracted `data` from each proof, optional `error` on failure, and `isTeeVerified` when `verifyTEE` is enabled.\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, isTeeVerified, data } = await verifyProof(proof, { ...request.getProviderVersion(), verifyTEE: true });\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 isTeeVerified: boolean | undefined = undefined;\n\n if (config.verifyTEE) {\n const hasTeeData = proofs.every(proof => proof.teeAttestation || JSON.parse(proof.claimData.context).attestationNonce);\n\n if (!hasTeeData) {\n const teeError = new TeeVerificationError('TEE verification requested but one or more proofs are missing TEE attestation data');\n logger.error(teeError.message);\n\n const errorResult: VerifyProofResultFailure = {\n isVerified: false,\n isTeeVerified: false,\n error: teeError,\n data: [],\n publicData: [],\n }\n\n return errorResult;\n }\n\n try {\n const teeResults = await Promise.all(proofs.map(proof => verifyTeeAttestation(proof)));\n isTeeVerified = teeResults.every(r => r === true);\n if (!isTeeVerified) {\n const teeError = new TeeVerificationError('TEE attestation verification failed for one or more proofs');\n logger.error(teeError.message);\n const errorResult: VerifyProofResultFailure = {\n isVerified: false,\n isTeeVerified: false,\n error: teeError,\n data: [],\n publicData: [],\n }\n\n return errorResult;\n }\n } catch (error) {\n const teeError = new TeeVerificationError('Error verifying TEE attestation', error);\n logger.error(teeError.message);\n\n const errorResult: VerifyProofResultFailure = {\n isVerified: false,\n isTeeVerified: false,\n error: teeError,\n data: [],\n publicData: [],\n }\n\n return errorResult;\n }\n }\n\n const result: VerifyProofResultSuccess = {\n isVerified: true,\n isTeeVerified: isTeeVerified,\n data: proofs.map(createTrustedDataFromProofData),\n publicData: getPublicDataFromProofs(proofs),\n error: undefined,\n }\n\n return result;\n } catch (error) {\n logger.error('Error in validating proof:', error);\n return {\n isVerified: false,\n error: error instanceof Error ? error : new Error(String(error)),\n data: [],\n publicData: [],\n }\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\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 // check if options is provided and validate each property of options\n if (options) {\n if (options.acceptAiProviders) {\n validateFunctionParams([\n { paramName: 'acceptAiProviders', input: options.acceptAiProviders }\n ], 'the constructor')\n }\n if (options.providerVersion) {\n validateFunctionParams([\n { paramName: 'providerVersion', input: options.providerVersion, isString: true }\n ], 'the constructor')\n }\n if (options.log) {\n validateFunctionParams([\n { paramName: 'log', input: options.log }\n ], 'the constructor')\n }\n if (options.useAppClip) {\n validateFunctionParams([\n { paramName: 'useAppClip', input: options.useAppClip }\n ], 'the constructor')\n }\n if (options.device) {\n validateFunctionParams([\n { paramName: 'device', input: options.device, isString: true }\n ], 'the constructor')\n }\n if (options.useBrowserExtension) {\n validateFunctionParams([\n { paramName: 'useBrowserExtension', input: options.useBrowserExtension }\n ], 'the constructor')\n }\n if (options.extensionID) {\n validateFunctionParams([\n { paramName: 'extensionID', input: options.extensionID, isString: true }\n ], 'the constructor')\n }\n if (options.envUrl) {\n validateFunctionParams([\n { paramName: 'envUrl', input: options.envUrl, isString: true }\n ], 'the constructor')\n }\n if (options.portalUrl) {\n validateFunctionParams([\n { paramName: 'portalUrl', input: options.portalUrl, isString: true }\n ], 'the constructor')\n }\n if (options.customSharePageUrl) {\n validateFunctionParams([\n { paramName: 'customSharePageUrl', input: options.customSharePageUrl, isString: true }\n ], 'the constructor')\n }\n if (options.customAppClipUrl) {\n validateFunctionParams([\n { paramName: 'customAppClipUrl', input: options.customAppClipUrl, isString: true }\n ], 'the constructor')\n }\n if (options.preferredLocale) {\n validateFunctionParams([\n { paramName: 'preferredLocale', input: options.preferredLocale, isString: true }\n ], 'the constructor');\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 }, 'the constructor');\n }\n }\n\n const proofRequestInstance = new ReclaimProofRequest(applicationId, providerId, options)\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 (options?.acceptTeeAttestation) {\n const wallet = new ethers.Wallet(appSecret)\n const nonceData = `${applicationId}:${data.sessionId}:${proofRequestInstance.timeStamp}`\n const nonceMsg = ethers.getBytes(ethers.keccak256(new TextEncoder().encode(nonceData)))\n const nonceSignature = await wallet.signMessage(nonceMsg)\n\n proofRequestInstance.setAttestationContext(nonceSignature, {\n applicationId,\n sessionId: data.sessionId,\n timestamp: proofRequestInstance.timeStamp\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 * 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\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 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 }\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 const result = await verifyProof(proofs, verificationConfig ?? this.getProviderVersion());\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');\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 { OnError } from './types'\nimport { TimeoutError } from './errors'\nimport loggerModule from './logger'\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","// 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","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 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 { 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\";\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 VerificationConfig = ValidationConfig & {\n /**\n * If true, verifies TEE (Trusted Execution Environment) attestation included in the proof.\n * When enabled, the result will include `isTeeVerified` and `isVerified` will be false\n * if TEE data is missing or TEE verification fails.\n */\n verifyTEE?: boolean;\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 forge from 'node-forge';\nimport { Proof, TeeAttestation } from './interfaces';\nimport { ethers } from 'ethers';\nimport { AMD_CERTS } from './amdCerts';\nimport loggerModule from './logger';\n\nconst crlCache: Record<string, { buffer: Uint8Array, fetchedAt: number }> = {};\nconst logger = loggerModule.logger;\n\ntype BinaryLike = Uint8Array | ArrayBuffer | Buffer;\n\nfunction toUint8Array(input: BinaryLike): Uint8Array {\n if (typeof Buffer !== 'undefined' && typeof Buffer.isBuffer === 'function' && Buffer.isBuffer(input)) {\n return new Uint8Array(input);\n }\n if (input instanceof Uint8Array) {\n return new Uint8Array(input);\n }\n if (typeof ArrayBuffer !== 'undefined' && input instanceof ArrayBuffer) {\n return new Uint8Array(input);\n }\n throw new Error('Unsupported binary data type');\n}\n\nfunction uint8ArrayToBinaryString(bytes: Uint8Array): string {\n let result = '';\n const chunkSize = 0x8000;\n for (let i = 0; i < bytes.length; i += chunkSize) {\n const chunk = bytes.subarray(i, i + chunkSize);\n result += String.fromCharCode(...chunk);\n }\n return result;\n}\n\nfunction binaryStringToUint8Array(binary: string): Uint8Array {\n const result = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) {\n result[i] = binary.charCodeAt(i);\n }\n return result;\n}\n\nfunction base64ToUint8Array(base64: string): Uint8Array {\n if (typeof atob === 'function') {\n const binary = atob(base64);\n return binaryStringToUint8Array(binary);\n }\n if (typeof Buffer !== 'undefined') {\n return new Uint8Array(Buffer.from(base64, 'base64'));\n }\n throw new Error('Base64 decoding is not supported in this environment');\n}\n\nfunction arrayBufferToHex(buffer: ArrayBuffer | Uint8Array): string {\n const view = buffer instanceof Uint8Array ? buffer : new Uint8Array(buffer);\n let hex = '';\n for (let i = 0; i < view.length; i++) {\n hex += view[i].toString(16).padStart(2, '0');\n }\n return hex;\n}\n\nfunction concatUint8Arrays(parts: Uint8Array[]): Uint8Array {\n const totalLength = parts.reduce((sum, arr) => sum + arr.length, 0);\n const result = new Uint8Array(totalLength);\n let offset = 0;\n for (const arr of parts) {\n result.set(arr, offset);\n offset += arr.length;\n }\n return result;\n}\n\nfunction reverseBytes(bytes: Uint8Array): Uint8Array {\n const copy = Uint8Array.from(bytes);\n copy.reverse();\n return copy;\n}\n\nfunction normalizeSerial(s: string) {\n let cleaned = s.toLowerCase().replace(/[^a-f0-9]/g, '');\n while (cleaned.startsWith('0') && cleaned.length > 1) cleaned = cleaned.substring(1);\n return cleaned;\n}\nconst isNode = typeof process !== 'undefined' && process.versions && process.versions.node;\nconst getSubtleCrypto = () => {\n if (typeof window !== 'undefined' && window.crypto?.subtle) return window.crypto.subtle;\n if (isNode) return require('crypto').webcrypto.subtle;\n throw new Error('No WebCrypto subtle implementation found in this environment');\n};\n\ninterface ParsedCert {\n serialNumber: string;\n tbsDer: Uint8Array;\n signature: Uint8Array;\n sigAlgOid: string;\n spkiDer: Uint8Array;\n notBefore?: Date;\n notAfter?: Date;\n}\n\nfunction parseCert(buffer: BinaryLike): ParsedCert {\n const bytes = toUint8Array(buffer);\n const asn1 = forge.asn1.fromDer(uint8ArrayToBinaryString(bytes));\n const certSeq = asn1.value as any[];\n const tbsAsn1 = certSeq[0];\n const sigAlgAsn1 = certSeq[1];\n const sigValueAsn1 = certSeq[2];\n\n const tbsFields = tbsAsn1.value as any[];\n let idx = 0;\n if (tbsFields[idx].tagClass === 128) idx++; // version\n const serialAsn1 = tbsFields[idx++];\n const serialNumber = forge.util.bytesToHex(serialAsn1.value);\n idx++; // sigAlg\n idx++; // issuer\n const validityAsn1 = tbsFields[idx++];\n idx++; // subject\n const spkiAsn1 = tbsFields[idx];\n\n if (!validityAsn1 || !Array.isArray(validityAsn1.value) || validityAsn1.value.length < 2) {\n throw new Error('Certificate validity window is malformed');\n }\n const notBeforeNode = validityAsn1.value[0];\n const notAfterNode = validityAsn1.value[1];\n const notBefore = notBeforeNode ? parseAsn1Time(notBeforeNode) : undefined;\n const notAfter = notAfterNode ? parseAsn1Time(notAfterNode) : undefined;\n\n const sigRaw = typeof sigValueAsn1.value === 'string' ? sigValueAsn1.value : '';\n const signature = binaryStringToUint8Array(sigRaw.substring(1));\n const sigAlgOid = forge.asn1.derToOid((sigAlgAsn1.value as any[])[0].value);\n\n return {\n serialNumber: normalizeSerial(serialNumber),\n tbsDer: binaryStringToUint8Array(forge.asn1.toDer(tbsAsn1).getBytes()),\n signature,\n sigAlgOid,\n spkiDer: binaryStringToUint8Array(forge.asn1.toDer(spkiAsn1).getBytes()),\n notBefore,\n notAfter\n };\n}\n\nasync function verifySignature(publicKeyPem: string, data: Uint8Array, signature: Uint8Array, sigAlgOid: string) {\n const cryptoSubtle = getSubtleCrypto();\n const forgeCert = forge.pki.certificateFromPem(publicKeyPem);\n const spkiBuf = binaryStringToUint8Array(forge.asn1.toDer(forge.pki.publicKeyToAsn1(forgeCert.publicKey)).getBytes());\n\n let importParams: any;\n let verifyParams: any;\n\n if (sigAlgOid === '1.2.840.113549.1.1.10') { // rsassa-pss\n importParams = { name: 'RSA-PSS', hash: 'SHA-384' };\n verifyParams = { name: 'RSA-PSS', saltLength: 48 };\n } else if (sigAlgOid === '1.2.840.113549.1.1.11' || sigAlgOid === '1.2.840.113549.1.1.12' || sigAlgOid === '1.2.840.113549.1.1.5') {\n importParams = { name: 'RSASSA-PKCS1-v1_5', hash: sigAlgOid === '1.2.840.113549.1.1.12' ? 'SHA-384' : 'SHA-256' };\n verifyParams = { name: 'RSASSA-PKCS1-v1_5' };\n } else if (sigAlgOid === '1.2.840.10045.4.3.3') { // ecdsa-with-sha384\n importParams = { name: 'ECDSA', namedCurve: 'P-384' };\n verifyParams = { name: 'ECDSA', hash: 'SHA-384' };\n } else {\n // Fallback or generic\n importParams = { name: 'RSASSA-PKCS1-v1_5', hash: 'SHA-256' };\n verifyParams = { name: 'RSASSA-PKCS1-v1_5' };\n }\n\n const key = await cryptoSubtle.importKey('spki', spkiBuf, importParams, false, ['verify']);\n const isValid = await cryptoSubtle.verify(verifyParams, key, signature, data);\n if (!isValid) throw new Error(`Signature verification failed (OID: ${sigAlgOid}, ImportParams: ${JSON.stringify(importParams)})`);\n}\n\nconst COSIGN_PUBLIC_KEY = `-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEjiL30OjPuxa+GC1I7SAcBv2u2pMt\nh9WbP33IvB3eFww+C1hoW0fwdZPiq4FxBtKNiZuFpmYuFngW/nJteBu9kQ==\n-----END PUBLIC KEY-----\n`;\n\n/**\n * Validates the hardware TEE attestation included in the proof.\n * Throws an error if the attestation is invalid or compromised.\n */\nexport async function verifyTeeAttestation(proof: Proof, expectedApplicationId?: string): Promise<boolean> {\n try {\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 // 1. Verify Nonce Binding\n let expectedNonceSignature: string | undefined;\n let nonceDataObj: any;\n try {\n const context = JSON.parse(proof.claimData.context);\n expectedNonceSignature = context.attestationNonce;\n nonceDataObj = context.attestationNonceData;\n } catch (e) {\n throw new Error(\"Failed to parse proof context to extract attestationNonce\");\n }\n\n if (!expectedNonceSignature || !nonceDataObj) {\n throw new Error(\"Proof context is missing attestationNonce or attestationNonceData\");\n }\n\n if (teeAttestation.nonce !== expectedNonceSignature) {\n throw new Error(`Nonce Mismatch! Expected signature ${expectedNonceSignature}, got ${teeAttestation.nonce}`);\n }\n\n const { applicationId, sessionId, timestamp } = nonceDataObj;\n\n if (expectedApplicationId && applicationId.toLowerCase() !== expectedApplicationId.toLowerCase()) {\n throw new Error(`Application ID Mismatch! Expected ${expectedApplicationId}, but proof context contains ${applicationId}`);\n }\n\n const expectedNonceData = `${applicationId}:${sessionId}:${timestamp}`;\n const nonceMsg = ethers.getBytes(ethers.keccak256(new TextEncoder().encode(expectedNonceData)));\n const recoveredAddress = ethers.verifyMessage(nonceMsg, expectedNonceSignature);\n\n if (recoveredAddress.toLowerCase() !== applicationId.toLowerCase()) {\n throw new Error(`Nonce signature verification failed: recovered ${recoveredAddress}, expected ${applicationId}`);\n }\n\n try {\n const context = JSON.parse(proof.claimData.context);\n const paramSessionId = context.attestationNonceData.sessionId;\n if (!paramSessionId) {\n throw new Error(`Proof parameters are missing proxySessionId or sessionId`);\n }\n if (paramSessionId.toString() !== sessionId.toString()) {\n throw new Error(`Session ID Mismatch! Expected ${sessionId}, but proof parameters contain ${paramSessionId}`);\n }\n\n // Timestamp skew check: claimData.timestampS (seconds) vs attestationNonceData.timestamp (ms)\n const claimTimestampMs = proof.claimData.timestampS * 1000;\n const nonceTimestampMs = parseInt(timestamp, 10);\n const diffMs = Math.abs(claimTimestampMs - nonceTimestampMs);\n const TEN_MINUTES_MS = 10 * 60 * 1000;\n if (diffMs > TEN_MINUTES_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 } catch (e) {\n if (e instanceof Error && (e.message.includes(\"Session ID Mismatch!\") || e.message.includes(\"Timestamp Skew\"))) {\n throw e;\n }\n throw new Error(`Failed to cross-verify session ID: ${(e as Error).message}`);\n }\n\n // 2. Recompute REPORT_DATA Hash\n // Recompute H(workload_digest || verifier_digest || pubkey_hash || nonce)\n // Here PUBKEY_HASH is the hash of the generic cosign pub key used by Popcorn.\n // For universal verification, we assume the Popcorn standard cosign public key hash matches the one used by Popcorn.\n // Note: To be fully strict, the public key hash should either be provided or fetched. \n // We will compute the SHA256 of the concatenated string.\n\n // The verify_proof script uses the hash of a specific file. We'll reconstruct the data that was signed.\n // However, wait! If JS SDK cannot easily hash the hardcoded cosign public key (or doesn't have it), \n // we must verify using the provided public data or skip the workload digest lock for now.\n // The user requested: \"same verification we do in the popcorn verficcation script\".\n // Let's implement the generic parts first: Hardware Signature and TCB.\n\n const reportBuffer = base64ToUint8Array(teeAttestation.snp_report);\n const report = parseAttestationReport(reportBuffer);\n\n if (report.isDebugEnabled) {\n throw new Error(\"POLICY CHECK FAILED: Debug mode is ALLOWED. Environment is compromised.\");\n }\n\n const certBuffer = base64ToUint8Array(teeAttestation.vlek_cert);\n\n await verifyAMDChain(certBuffer);\n verifyTCB(certBuffer, report);\n await verifyHardwareSignature(reportBuffer, certBuffer);\n await verifyReportData(teeAttestation, proof.claimData.context, report);\n\n return true;\n } catch (error) {\n logger.error('TEE attestation verification failed:', error);\n return false;\n }\n}\n\nfunction parseAttestationReport(buffer: Uint8Array) {\n if (buffer.length < 1000) {\n throw new Error(`Report buffer is too small: ${buffer.length} bytes`);\n }\n\n const view = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength);\n const policy = view.getBigUint64(0x08, true);\n const isDebugEnabled = (policy & (BigInt(1) << BigInt(19))) !== BigInt(0);\n\n const reported_tcb = {\n bootloader: buffer[0x38],\n tee: buffer[0x39],\n snp: buffer[0x3E],\n microcode: buffer[0x3F]\n };\n\n const reportData = arrayBufferToHex(buffer.subarray(0x50, 0x90)); // 64 bytes\n return { policy, isDebugEnabled, reported_tcb, reportData };\n}\n\nfunction getExtValue(certAsn1: any, oidString: string) {\n const tbsCert = certAsn1.value[0];\n if (!tbsCert || !tbsCert.value) return null;\n\n const extBlockWrapper = tbsCert.value.find((node: any) => node.tagClass === forge.asn1.Class.CONTEXT_SPECIFIC && node.type === 3);\n if (!extBlockWrapper || !extBlockWrapper.value || !extBlockWrapper.value.length) return null;\n\n const extSequence = extBlockWrapper.value[0];\n for (const ext of extSequence.value) {\n const extIdAsn1 = ext.value[0];\n const extIdStr = forge.asn1.derToOid(extIdAsn1.value);\n if (extIdStr === oidString) {\n const extValueAsn1 = ext.value[ext.value.length - 1];\n const rawOctetStringBytes = extValueAsn1.value;\n try {\n // The extension value is an OCTET STRING containing the DER encoding of an INTEGER\n const innerAsn1 = forge.asn1.fromDer(forge.util.createBuffer(rawOctetStringBytes));\n if (innerAsn1.type === 2) { // INTEGER\n const bytes = innerAsn1.value;\n if (typeof bytes === 'string' && bytes.length > 0) {\n return bytes.charCodeAt(bytes.length - 1);\n } else {\n throw new Error(`Extension ${oidString} INTEGER value is empty or invalid`);\n }\n } else {\n throw new Error(`Extension ${oidString} does not contain an INTEGER, found type ${innerAsn1.type}`);\n }\n } catch (e) {\n // Fail closed on any parse or schema error\n throw new Error(`Failed to strictly parse AMD TCB extension ${oidString}: ${(e as Error).message}`);\n }\n }\n }\n return null;\n}\n\nfunction verifyTCB(vlekCertBuffer: Uint8Array, report: any) {\n const certAsn1 = forge.asn1.fromDer(forge.util.createBuffer(uint8ArrayToBinaryString(vlekCertBuffer)));\n\n const OID_BOOTLOADER = '1.3.6.1.4.1.3704.1.3.1';\n const OID_TEE = '1.3.6.1.4.1.3704.1.3.2';\n const OID_SNP = '1.3.6.1.4.1.3704.1.3.3';\n const OID_MICROCODE = '1.3.6.1.4.1.3704.1.3.8';\n\n const certTcb = {\n bootloader: getExtValue(certAsn1, OID_BOOTLOADER),\n tee: getExtValue(certAsn1, OID_TEE),\n snp: getExtValue(certAsn1, OID_SNP),\n microcode: getExtValue(certAsn1, OID_MICROCODE)\n };\n\n if (certTcb.bootloader !== null && report.reported_tcb.bootloader < certTcb.bootloader) {\n throw new Error(`TCB Downgrade! Bootloader reported ${report.reported_tcb.bootloader}, but certificate requires ${certTcb.bootloader}`);\n }\n if (certTcb.tee !== null && report.reported_tcb.tee < certTcb.tee) {\n throw new Error(`TCB Downgrade! TEE reported ${report.reported_tcb.tee}, but certificate requires ${certTcb.tee}`);\n }\n if (certTcb.snp !== null && report.reported_tcb.snp < certTcb.snp) {\n throw new Error(`TCB Downgrade! SNP reported ${report.reported_tcb.snp}, but certificate requires ${certTcb.snp}`);\n }\n if (certTcb.microcode !== null && report.reported_tcb.microcode < certTcb.microcode) {\n throw new Error(`TCB Downgrade! Microcode reported ${report.reported_tcb.microcode}, but certificate requires ${certTcb.microcode}`);\n }\n}\n\nfunction parseAsn1Time(node: any): Date {\n const s = node.value as string;\n if (node.type === forge.asn1.Type.UTCTIME) {\n // UTCTime: YYMMDDHHmmssZ\n const yr = parseInt(s.substring(0, 2), 10);\n return new Date(Date.UTC(\n yr >= 50 ? 1900 + yr : 2000 + yr,\n parseInt(s.substring(2, 4), 10) - 1,\n parseInt(s.substring(4, 6), 10),\n parseInt(s.substring(6, 8), 10),\n parseInt(s.substring(8, 10), 10),\n parseInt(s.substring(10, 12), 10)\n ));\n } else {\n // GeneralizedTime: YYYYMMDDHHmmssZ\n return new Date(Date.UTC(\n parseInt(s.substring(0, 4), 10),\n parseInt(s.substring(4, 6), 10) - 1,\n parseInt(s.substring(6, 8), 10),\n parseInt(s.substring(8, 10), 10),\n parseInt(s.substring(10, 12), 10),\n parseInt(s.substring(12, 14), 10)\n ));\n }\n}\n\nasync function verifyCRL(crlBuf: Uint8Array, arkPem: string, vlekSerial: string): Promise<void> {\n // Parse CRL: CertificateList SEQUENCE { TBSCertList, signatureAlgorithm, signatureValue }\n const crlAsn1 = forge.asn1.fromDer(forge.util.createBuffer(uint8ArrayToBinaryString(crlBuf)));\n\n if (!Array.isArray(crlAsn1.value) || crlAsn1.value.length < 3) {\n throw new Error('CRL ASN.1 structure is invalid: expected SEQUENCE with TBSCertList, AlgorithmIdentifier, BIT STRING');\n }\n\n const tbsAsn1 = (crlAsn1.value as any[])[0];\n const sigBitsAsn1 = (crlAsn1.value as any[])[2]; // BIT STRING containing the signature\n\n if (!Array.isArray(tbsAsn1.value)) {\n throw new Error('CRL TBSCertList is not a valid SEQUENCE');\n }\n\n const tbsFields = tbsAsn1.value as any[];\n let fi = 0;\n\n // Optional version field (UNIVERSAL INTEGER — present in CRL v2)\n if (fi < tbsFields.length &&\n tbsFields[fi].tagClass === forge.asn1.Class.UNIVERSAL &&\n tbsFields[fi].type === forge.asn1.Type.INTEGER) {\n fi++;\n }\n\n // signature AlgorithmIdentifier (skip, matches outer signatureAlgorithm)\n if (fi < tbsFields.length) fi++;\n\n // issuer Name\n if (fi >= tbsFields.length) throw new Error('CRL TBSCertList missing issuer');\n const issuerAsn1 = tbsFields[fi++];\n\n // thisUpdate (UTCTime or GeneralizedTime)\n if (fi >= tbsFields.length) throw new Error('CRL TBSCertList missing thisUpdate');\n const thisUpdateAsn1 = tbsFields[fi++];\n\n // nextUpdate (optional — UTCTime or GeneralizedTime)\n let nextUpdateAsn1: any = null;\n if (fi < tbsFields.length &&\n tbsFields[fi].tagClass === forge.asn1.Class.UNIVERSAL &&\n (tbsFields[fi].type === forge.asn1.Type.UTCTIME ||\n tbsFields[fi].type === forge.asn1.Type.GENERALIZEDTIME)) {\n nextUpdateAsn1 = tbsFields[fi++];\n }\n\n // revokedCertificates (optional UNIVERSAL SEQUENCE; skip context-specific extensions)\n let revokedSeq: any = null;\n if (fi < tbsFields.length &&\n tbsFields[fi].tagClass === forge.asn1.Class.UNIVERSAL &&\n tbsFields[fi].type === forge.asn1.Type.SEQUENCE) {\n revokedSeq = tbsFields[fi];\n }\n\n // 1. Validity Period\n const now = new Date();\n const thisUpdate = parseAsn1Time(thisUpdateAsn1);\n if (thisUpdate > now) {\n throw new Error(`CRL is not yet valid: thisUpdate is ${thisUpdate.toISOString()}`);\n }\n if (nextUpdateAsn1) {\n const nextUpdate = parseAsn1Time(nextUpdateAsn1);\n if (nextUpdate < now) {\n throw new Error(`CRL has expired: nextUpdate was ${nextUpdate.toISOString()}`);\n }\n }\n\n // 2. Issuer Verification — compare CRL issuer DER bytes to ARK certificate subject DER bytes\n // The AMD VLEK CRL is issued by the ARK (CN=ARK-Milan/Genoa), not the ASK\n const crlIssuerDer = forge.asn1.toDer(issuerAsn1).getBytes();\n const arkForgeCert = forge.pki.certificateFromPem(arkPem);\n const arkCertAsn1 = forge.pki.certificateToAsn1(arkForgeCert);\n // TBSCertificate field order: [0]version, serial, sigAlg, issuer, validity, subject, spki, ...\n const arkSubjectAsn1 = ((arkCertAsn1.value as any[])[0].value as any[])[5];\n const arkSubjectDer = forge.asn1.toDer(arkSubjectAsn1).getBytes();\n if (crlIssuerDer !== arkSubjectDer) {\n throw new Error('CRL issuer does not match AMD ARK certificate subject — chain mismatch');\n }\n\n // 3. Signature Verification (AMD CRL uses RSA-PSS with SHA-384, signed by ARK)\n const tbsDerBuf = binaryStringToUint8Array(forge.asn1.toDer(tbsAsn1).getBytes());\n // BIT STRING first byte = unused bits count, skip it\n const sigRaw = typeof sigBitsAsn1.value === 'string' ? sigBitsAsn1.value : '';\n const sigBuf = binaryStringToUint8Array(sigRaw.substring(1));\n\n const cryptoSubtle = getSubtleCrypto();\n const spkiBuf = binaryStringToUint8Array(\n forge.asn1.toDer(forge.pki.publicKeyToAsn1(arkForgeCert.publicKey)).getBytes()\n );\n const arkCryptoKey = await cryptoSubtle.importKey(\n 'spki', spkiBuf,\n { name: 'RSA-PSS', hash: 'SHA-384' },\n false, ['verify']\n );\n const isValid = await cryptoSubtle.verify(\n { name: 'RSA-PSS', saltLength: 48 }, // SHA-384 salt length is 48\n arkCryptoKey,\n sigBuf,\n tbsDerBuf\n );\n if (!isValid) {\n throw new Error('CRL signature is INVALID — the CRL may be tampered or forged');\n }\n\n // 4. Revocation Check — only inspect the revokedCertificates list, not arbitrary ASN.1 nodes\n const targetSerial = normalizeSerial(vlekSerial);\n if (revokedSeq && Array.isArray(revokedSeq.value)) {\n for (const entry of revokedSeq.value) {\n if (!Array.isArray(entry.value) || entry.value.length < 2) continue;\n const serialAsn1 = entry.value[0];\n if (serialAsn1.type !== forge.asn1.Type.INTEGER || typeof serialAsn1.value !== 'string') continue;\n const serialHex = forge.util.bytesToHex(serialAsn1.value);\n if (normalizeSerial(serialHex) === targetSerial) {\n throw new Error('🚨 VLEK Certificate is REVOKED per AMD CRL! This hardware may be compromised.');\n }\n }\n }\n}\n\nfunction assertCertValidity(label: string, cert: ParsedCert) {\n const now = Date.now();\n if (cert.notBefore && now < cert.notBefore.getTime()) {\n throw new Error(`${label} certificate is not yet valid (notBefore: ${cert.notBefore.toISOString()})`);\n }\n if (cert.notAfter && now > cert.notAfter.getTime()) {\n throw new Error(`${label} certificate expired on ${cert.notAfter.toISOString()}`);\n }\n}\n\nasync function verifyAMDChain(vlekCertBuffer: Uint8Array) {\n const processors = ['Milan', 'Genoa'];\n let chainVerified = false;\n\n const vlek = parseCert(vlekCertBuffer);\n assertCertValidity('VLEK', vlek);\n\n for (const processor of processors) {\n let matchedChain = false;\n try {\n const chainPem = AMD_CERTS[processor];\n if (!chainPem) continue;\n\n const certs = chainPem.split('-----END CERTIFICATE-----')\n .map(c => c.trim())\n .filter(c => c.length > 0)\n .map(c => c + '\\n-----END CERTIFICATE-----\\n');\n\n const askCert = forge.pki.certificateFromPem(certs[0]);\n const arkCert = forge.pki.certificateFromPem(certs[1]);\n\n const askDer = forge.asn1.toDer(forge.pki.certificateToAsn1(askCert)).getBytes();\n const arkDer = forge.asn1.toDer(forge.pki.certificateToAsn1(arkCert)).getBytes();\n const ask = parseCert(binaryStringToUint8Array(askDer));\n const ark = parseCert(binaryStringToUint8Array(arkDer));\n assertCertValidity('ASK', ask);\n assertCertValidity('ARK', ark);\n\n // ARK -> ASK -> VLEK\n try {\n await verifySignature(certs[1], ark.tbsDer, ark.signature, ark.sigAlgOid); // ARK Self-signed\n } catch (e: any) { throw new Error(`AMD ARK self-signature verification failed: ${e.message}`); }\n\n try {\n await verifySignature(certs[1], ask.tbsDer, ask.signature, ask.sigAlgOid); // ASK signed by ARK\n } catch (e: any) { throw new Error(`AMD ASK-by-ARK signature verification failed: ${e.message}`); }\n\n try {\n await verifySignature(certs[0], vlek.tbsDer, vlek.signature, vlek.sigAlgOid); // VLEK signed by ASK\n } catch (e: any) { throw new Error(`VLEK-by-ASK signature verification failed: ${e.message}`); }\n\n matchedChain = true;\n\n // Check CRL\n let crlBuf: Uint8Array | undefined;\n const now = Date.now();\n if (crlCache[processor] && now - crlCache[processor].fetchedAt < 3600000) {\n crlBuf = crlCache[processor].buffer;\n } else {\n const crlUrl = `https://kdsintf.amd.com/vlek/v1/${processor}/crl`;\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), 5000);\n const crlResp = await fetch(crlUrl, { signal: controller.signal });\n clearTimeout(timeoutId);\n\n if (!crlResp.ok) continue;\n crlBuf = new Uint8Array(await crlResp.arrayBuffer());\n crlCache[processor] = { buffer: crlBuf, fetchedAt: now };\n }\n\n if (vlek.serialNumber && crlBuf) {\n await verifyCRL(crlBuf, certs[1], vlek.serialNumber);\n }\n\n chainVerified = true;\n break;\n } catch (e: any) {\n if (matchedChain) {\n throw e; // Hard fail if we matched the chain but CRL fetch/parse failed or cert is revoked\n }\n continue;\n }\n }\n\n if (!chainVerified) {\n throw new Error(\"VLEK Certificate failed verification against all known AMD Root of Trust chains!\");\n }\n}\n\nasync function verifyHardwareSignature(reportBytes: Uint8Array, certBytes: Uint8Array) {\n const vlek = parseCert(certBytes);\n\n const sigOffset = 0x2A0;\n const rLE = reportBytes.subarray(sigOffset, sigOffset + 72);\n const sLE = reportBytes.subarray(sigOffset + 72, sigOffset + 144);\n\n const rBE = reverseBytes(rLE);\n const sBE = reverseBytes(sLE);\n\n const signedData = reportBytes.subarray(0, 0x2A0);\n\n const cryptoSubtle = getSubtleCrypto();\n\n const importedKey = await cryptoSubtle.importKey(\n \"spki\",\n vlek.spkiDer,\n { name: \"ECDSA\", namedCurve: \"P-384\" },\n false,\n [\"verify\"]\n );\n\n // the subtle crypto ECDSA signature needs to be raw (r || s), each 48 bytes long\n // Our rBE and sBE are exactly 72 bytes. P-384 is 48 bytes!\n // The AMD report reserves 72 bytes for R and 72 bytes for S padded with zeros.\n // We MUST verify the dropped high-order bytes are zero to prevent malicious tampering.\n const rPadding = rBE.subarray(0, rBE.length - 48);\n const sPadding = sBE.subarray(0, sBE.length - 48);\n\n if (!rPadding.every(b => b === 0) || !sPadding.every(b => b === 0)) {\n throw new Error(\"Hardware ECDSA signature is malformed: non-zero padding bytes detected in the structural signature coordinates.\");\n }\n\n const r48 = rBE.subarray(rBE.length - 48);\n const s48 = sBE.subarray(sBE.length - 48);\n const rawSignature = concatUint8Arrays([r48, s48]);\n\n const isValid = await cryptoSubtle.verify(\n { name: \"ECDSA\", hash: { name: \"SHA-384\" } },\n importedKey,\n rawSignature,\n signedData\n );\n\n if (!isValid) {\n throw new Error(\"Hardware ECDSA signature is completely invalid!\");\n }\n}\n\nasync function verifyReportData(teeAttestation: TeeAttestation, proofContext: string, report: any) {\n if (!teeAttestation.workload_digest || !teeAttestation.verifier_digest) {\n throw new Error(\"POLICY CHECK FAILED: Missing workload_digest or verifier_digest in TEE attestation.\");\n }\n\n const { attestationNonce: nonce } = JSON.parse(proofContext);\n\n const cryptoSubtle = getSubtleCrypto();\n\n // 1. Extract raw 32-byte SHA256 digest from image refs (part after \"@sha256:\")\n const extractDigestBytes = (imageRef: string): Uint8Array => {\n const marker = '@sha256:';\n const idx = imageRef.lastIndexOf(marker);\n if (idx < 0) throw new Error(`Image ref missing @sha256: digest: ${imageRef}`);\n const hexDigest = imageRef.substring(idx + marker.length);\n if (hexDigest.length !== 64) throw new Error(`SHA256 digest must be 64 hex chars, got ${hexDigest.length} in: ${imageRef}`);\n const bytes = new Uint8Array(32);\n for (let i = 0; i < 32; i++) bytes[i] = parseInt(hexDigest.substring(i * 2, i * 2 + 2), 16);\n return bytes;\n };\n\n // 2. Hash COSIGN public key as canonical DER SPKI bytes (not PEM text)\n const importedCosignKey = await cryptoSubtle.importKey(\n 'spki',\n base64ToUint8Array(\n COSIGN_PUBLIC_KEY\n .replace('-----BEGIN PUBLIC KEY-----', '')\n .replace('-----END PUBLIC KEY-----', '')\n .replace(/\\s+/g, '')\n ),\n { name: 'ECDSA', namedCurve: 'P-256' },\n true,\n ['verify']\n );\n const pubKeySpkiDer = await cryptoSubtle.exportKey('spki', importedCosignKey);\n const pubKeyHashBuffer = await cryptoSubtle.digest('SHA-256', pubKeySpkiDer);\n const pubKeyHashBytes = new Uint8Array(pubKeyHashBuffer);\n\n // 3. Decode nonce from hex to raw bytes (strip 0x prefix)\n const nonceHex = (teeAttestation.nonce || nonce).replace(/^0x/i, '');\n const nonceBytes = new Uint8Array(nonceHex.length / 2);\n for (let i = 0; i < nonceBytes.length; i++) nonceBytes[i] = parseInt(nonceHex.substring(i * 2, i * 2 + 2), 16);\n\n // 4. Extract raw digest bytes from image refs\n const workloadBytes = extractDigestBytes(teeAttestation.workload_digest);\n const verifierBytes = extractDigestBytes(teeAttestation.verifier_digest);\n\n // 5. Build canonical binary payload:\n // \"POPCORN_TEE_REPORT_DATA_V1\" || 0x01 || workload(32) || verifier(32) || pubkeyHash(32) || nonceBytes\n const domainSep = new TextEncoder().encode('POPCORN_TEE_REPORT_DATA_V1');\n const version = new Uint8Array([0x01]);\n const payload = new Uint8Array(\n domainSep.length + version.length +\n workloadBytes.length + verifierBytes.length +\n pubKeyHashBytes.length + nonceBytes.length\n );\n let offset = 0;\n for (const chunk of [domainSep, version, workloadBytes, verifierBytes, pubKeyHashBytes, nonceBytes]) {\n payload.set(chunk, offset);\n offset += chunk.length;\n }\n\n // 6. Compute SHA-256 of the binary payload, duplicate to 64 bytes, compare to report_data\n const hashBuffer = await cryptoSubtle.digest('SHA-256', payload);\n const hashHex = arrayBufferToHex(hashBuffer);\n const expected64ByteHex = hashHex + hashHex;\n\n if (report.reportData !== expected64ByteHex) {\n throw new Error(`REPORT_DATA Mismatch! Hardware report is not bound to these image digests or nonce.\\nExpected: ${expected64ByteHex}\\nGot: ${report.reportData}`);\n }\n}\n","export const AMD_CERTS: Record<string, string> = {\n 'Milan': `-----BEGIN CERTIFICATE-----\nMIIGjzCCBD6gAwIBAgIDAQEBMEYGCSqGSIb3DQEBCjA5oA8wDQYJYIZIAWUDBAIC\nBQChHDAaBgkqhkiG9w0BAQgwDQYJYIZIAWUDBAICBQCiAwIBMKMDAgEBMHsxFDAS\nBgNVBAsMC0VuZ2luZWVyaW5nMQswCQYDVQQGEwJVUzEUMBIGA1UEBwwLU2FudGEg\nQ2xhcmExCzAJBgNVBAgMAkNBMR8wHQYDVQQKDBZBZHZhbmNlZCBNaWNybyBEZXZp\nY2VzMRIwEAYDVQQDDAlBUkstTWlsYW4wHhcNMjIxMTE2MjI0NTI0WhcNNDcxMTE2\nMjI0NTI0WjCBgDEUMBIGA1UECwwLRW5naW5lZXJpbmcxCzAJBgNVBAYTAlVTMRQw\nEgYDVQQHDAtTYW50YSBDbGFyYTELMAkGA1UECAwCQ0ExHzAdBgNVBAoMFkFkdmFu\nY2VkIE1pY3JvIERldmljZXMxFzAVBgNVBAMMDlNFVi1WTEVLLU1pbGFuMIICIjAN\nBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA1EUWkz5FTPz+uWT2hCEyisam8FRu\nXZAmS3l+rXgSCeS1Q0+1olcnFSJpiwfssfhoutJqePyicu+OhkX131PMeO/VOtH3\nupK4YNJmq36IJp7ZWIm5nK2fJNkYEHW0m/NXcIA9U2iHl5bAQ5cbGp97/FaOJ4Vm\nGoTMV658Yox/plFmZRFfRcsw2hyNhqUl1gzdpnIIgPkygUovFEgaa0IVSgGLHQhZ\nQiebNLLSVWRVReve0t94zlRIRRdrz84cckP9H9DTAUMyQaxSZbPINKbV6TPmtrwA\nV9UP1Qq418xn9I+C0SsWutP/5S1OiL8OTzQ4CvgbHOfd2F3yVv4xDBza4SelF2ig\noDf+BF4XI/IIHJL2N5uKy3+gkSB2Xl6prohgVmqRFvBW9OTCEa32WhXu0t1Z1abE\nKDZ3LpZt9/Crg6zyPpXDLR/tLHHpSaPRj7CTzHieKMTz+Q6RrCCQcHGfaAD/ETNY\n56aHvNJRZgbzXDUJvnLr3dYyOvvn/DtKhCSimJynn7Len4ArDVQVwXRPe3hR/asC\nE2CajT7kGC1AOtUzQuIKZS2D0Qk74g297JhLHpEBlQiyjRJ+LCWZNx9uJcixGyza\nv6fiOWx4U8uWhRzHs8nvDAdcS4LW31tPlA9BeOK/BGimQTu7hM5MDFZL0C9dWK5p\nuCUJex6I2vSqvycCAwEAAaOBozCBoDAdBgNVHQ4EFgQUNuJXE6qi45/CgqkKRPtV\nLObC7pEwHwYDVR0jBBgwFoAUhawa0UP3yKxV1MUdQUir1XhK1FMwEgYDVR0TAQH/\nBAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAQQwOgYDVR0fBDMwMTAvoC2gK4YpaHR0\ncHM6Ly9rZHNpbnRmLmFtZC5jb20vdmxlay92MS9NaWxhbi9jcmwwRgYJKoZIhvcN\nAQEKMDmgDzANBglghkgBZQMEAgIFAKEcMBoGCSqGSIb3DQEBCDANBglghkgBZQME\nAgIFAKIDAgEwowMCAQEDggIBAI7ayEXDNj1rCVnjQFb6L91NNOmEIOmi6XtopAqr\n8fj7wqXap1MY82Y0AIi1K9R7C7G1sCmY8QyEyX0zqHsoNbU2IMcSdZrIp8neT8af\nv8tPt7qoW3hZ+QQRMtgVkVVrjJZelvlB74xr5ifDcDiBd2vu/C9IqoQS4pVBKNSF\npofzjtYKvebBBBXxeM2b901UxNgVjCY26TtHEWN9cA6cDVqDDCCL6uOeR9UOvKDS\nSqlM6nXldSj7bgK7Wh9M9587IwRvNZluXc1CDiKMZybLdSKOlyMJH9ss1GPn0eBV\nEhVjf/gttn7HrcQ9xJZVXyDtL3tkGzemrPK14NOYzmph6xr1iiedAzOVpNdPiEXn\n2lvas0P4TD9UgBh0Y7xyf2yENHiSgJT4T8Iktm/TSzuh4vqkQ72A1HdNTGjoZcfz\nKCsQJ/YuFICeaNxw5cIAGBK/o+6Ek32NPv5XtixNOhEx7GsaVRG05bq5oTt14b4h\nKYhqV1CDrX5hiVRpFFDs/sAGfgTzLdiGXLcvYAUz1tCKIT/eQS9c4/yitn4F3mCP\nd4uQB+fggMtK0qPRthpFtc2SqVCTvHnhxyXqo7GpXMsssgLgKNwaFPe2+Ld5OwPR\n6Pokji9h55m05Dxob8XtD4gW6oFLo9Icg7XqdOr9Iip5RBIPxy7rKk/ReqGs9KH7\n0YPk\n-----END CERTIFICATE-----\n-----BEGIN CERTIFICATE-----\nMIIGYzCCBBKgAwIBAgIDAQAAMEYGCSqGSIb3DQEBCjA5oA8wDQYJYIZIAWUDBAIC\nBQChHDAaBgkqhkiG9w0BAQgwDQYJYIZIAWUDBAICBQCiAwIBMKMDAgEBMHsxFDAS\nBgNVBAsMC0VuZ2luZWVyaW5nMQswCQYDVQQGEwJVUzEUMBIGA1UEBwwLU2FudGEg\nQ2xhcmExCzAJBgNVBAgMAkNBMR8wHQYDVQQKDBZBZHZhbmNlZCBNaWNybyBEZXZp\nY2VzMRIwEAYDVQQDDAlBUkstTWlsYW4wHhcNMjAxMDIyMTcyMzA1WhcNNDUxMDIy\nMTcyMzA1WjB7MRQwEgYDVQQLDAtFbmdpbmVlcmluZzELMAkGA1UEBhMCVVMxFDAS\nBgNVBAcMC1NhbnRhIENsYXJhMQswCQYDVQQIDAJDQTEfMB0GA1UECgwWQWR2YW5j\nZWQgTWljcm8gRGV2aWNlczESMBAGA1UEAwwJQVJLLU1pbGFuMIICIjANBgkqhkiG\n9w0BAQEFAAOCAg8AMIICCgKCAgEA0Ld52RJOdeiJlqK2JdsVmD7FktuotWwX1fNg\nW41XY9Xz1HEhSUmhLz9Cu9DHRlvgJSNxbeYYsnJfvyjx1MfU0V5tkKiU1EesNFta\n1kTA0szNisdYc9isqk7mXT5+KfGRbfc4V/9zRIcE8jlHN61S1ju8X93+6dxDUrG2\nSzxqJ4BhqyYmUDruPXJSX4vUc01P7j98MpqOS95rORdGHeI52Naz5m2B+O+vjsC0\n60d37jY9LFeuOP4Meri8qgfi2S5kKqg/aF6aPtuAZQVR7u3KFYXP59XmJgtcog05\ngmI0T/OitLhuzVvpZcLph0odh/1IPXqx3+MnjD97A7fXpqGd/y8KxX7jksTEzAOg\nbKAeam3lm+3yKIcTYMlsRMXPcjNbIvmsBykD//xSniusuHBkgnlENEWx1UcbQQrs\n+gVDkuVPhsnzIRNgYvM48Y+7LGiJYnrmE8xcrexekBxrva2V9TJQqnN3Q53kt5vi\nQi3+gCfmkwC0F0tirIZbLkXPrPwzZ0M9eNxhIySb2npJfgnqz55I0u33wh4r0ZNQ\neTGfw03MBUtyuzGesGkcw+loqMaq1qR4tjGbPYxCvpCq7+OgpCCoMNit2uLo9M18\nfHz10lOMT8nWAUvRZFzteXCm+7PHdYPlmQwUw3LvenJ/ILXoQPHfbkH0CyPfhl1j\nWhJFZasCAwEAAaN+MHwwDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBSFrBrRQ/fI\nrFXUxR1BSKvVeErUUzAPBgNVHRMBAf8EBTADAQH/MDoGA1UdHwQzMDEwL6AtoCuG\nKWh0dHBzOi8va2RzaW50Zi5hbWQuY29tL3ZjZWsvdjEvTWlsYW4vY3JsMEYGCSqG\nSIb3DQEBCjA5oA8wDQYJYIZIAWUDBAICBQChHDAaBgkqhkiG9w0BAQgwDQYJYIZI\nAWUDBAICBQCiAwIBMKMDAgEBA4ICAQC6m0kDp6zv4Ojfgy+zleehsx6ol0ocgVel\nETobpx+EuCsqVFRPK1jZ1sp/lyd9+0fQ0r66n7kagRk4Ca39g66WGTJMeJdqYriw\nSTjjDCKVPSesWXYPVAyDhmP5n2v+BYipZWhpvqpaiO+EGK5IBP+578QeW/sSokrK\ndHaLAxG2LhZxj9aF73fqC7OAJZ5aPonw4RE299FVarh1Tx2eT3wSgkDgutCTB1Yq\nzT5DuwvAe+co2CIVIzMDamYuSFjPN0BCgojl7V+bTou7dMsqIu/TW/rPCX9/EUcp\nKGKqPQ3P+N9r1hjEFY1plBg93t53OOo49GNI+V1zvXPLI6xIFVsh+mto2RtgEX/e\npmMKTNN6psW88qg7c1hTWtN6MbRuQ0vm+O+/2tKBF2h8THb94OvvHHoFDpbCELlq\nHnIYhxy0YKXGyaW1NjfULxrrmxVW4wcn5E8GddmvNa6yYm8scJagEi13mhGu4Jqh\n3QU3sf8iUSUr09xQDwHtOQUVIqx4maBZPBtSMf+qUDtjXSSq8lfWcd8bLr9mdsUn\nJZJ0+tuPMKmBnSH860llKk+VpVQsgqbzDIvOLvD6W1Umq25boxCYJ+TuBoa4s+HH\nCViAvgT9kf/rBq1d+ivj6skkHxuzcxbk1xv6ZGxrteJxVH7KlX7YRdZ6eARKwLe4\nAFZEAwoKCQ==\n-----END CERTIFICATE-----`,\n 'Genoa': `-----BEGIN CERTIFICATE-----\n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\n2cko\n-----END CERTIFICATE-----\n-----BEGIN CERTIFICATE-----\n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\n/wMz1R1BHg==\n-----END CERTIFICATE-----`\n};\n"],"mappings":"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","names":["exports","module","import_ethers","import_canonicalize","logger","import_canonicalize","canonicalize","logger","canonicalize","logger","fetchRetry","logger","import_ethers","import_ethers","logger","logger","QRCode","logger","logger","import_ethers","logger","forge","logger","sdkVersion","canonicalize","_a"]}
|