UNPKG

@hyperlane-xyz/sdk

Version:

The official SDK for the Hyperlane Network

66 lines 2.43 kB
import { assert, rootLogger } from '@hyperlane-xyz/utils'; import { z } from 'zod'; const DEFAULT_PREDICATE_API_URL = 'https://api.predicate.io/v2/attestation'; export const PredicateAttestationSchema = z.object({ uuid: z.string(), expiration: z.number(), attester: z.string(), signature: z.string(), }); const PredicateAttestationResponseSchema = z.object({ policy_id: z.string(), policy_name: z.string(), verification_hash: z.string(), is_compliant: z.boolean(), attestation: PredicateAttestationSchema, }); export class PredicateApiClient { logger = rootLogger.child({ module: 'PredicateApiClient' }); baseUrl; apiKey; constructor(apiKey, baseUrl = DEFAULT_PREDICATE_API_URL) { assert(apiKey, 'Predicate API key is required'); this.apiKey = apiKey; this.baseUrl = baseUrl; } async fetchAttestation(request) { this.logger.debug('Fetching attestation', { url: this.baseUrl, request, }); const controller = new AbortController(); const timeoutId = setTimeout(() => controller.abort(), 30_000); let response; try { response = await fetch(this.baseUrl, { method: 'POST', headers: { 'Content-Type': 'application/json', 'x-api-key': this.apiKey, }, body: JSON.stringify(request), signal: controller.signal, }); } finally { clearTimeout(timeoutId); } if (!response.ok) { const errorText = await response.text(); throw new Error(`Predicate API error (${response.status}): ${errorText}`); } const result = PredicateAttestationResponseSchema.parse(await response.json()); if (!result.is_compliant) { throw new Error(`Transaction not compliant: policy=${result.policy_id}, hash=${result.verification_hash}`); } const now = Math.floor(Date.now() / 1000); if (result.attestation.expiration <= now) { throw new Error(`Attestation already expired (expiration=${result.attestation.expiration}, now=${now})`); } this.logger.debug('Attestation received', { uuid: result.attestation.uuid, }); return result; } } //# sourceMappingURL=PredicateApiClient.js.map