@p2pdotme/sdk 1.2.12 → 1.2.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/zkkyc.d.cts CHANGED
@@ -13,7 +13,7 @@ declare class SdkError<TCode extends string = string> extends Error {
13
13
  });
14
14
  }
15
15
 
16
- type ZkkycErrorCode = "VALIDATION_ERROR" | "CONTRACT_READ_ERROR" | "ENCODE_ERROR" | "RECLAIM_INIT_FAILED" | "RECLAIM_SESSION_NOT_FOUND" | "RECLAIM_PROOF_GENERATION_FAILED" | "RECLAIM_PROOF_INVALID" | "RECLAIM_POLLING_ABORTED" | "ZK_PASSPORT_INIT_FAILED" | "ZK_PASSPORT_REJECTED" | "ZK_PASSPORT_VERIFICATION_FAILED" | "ZK_PASSPORT_ABORTED" | "SIMPLE_KYC_SESSION_FAILED" | "SIMPLE_KYC_REDEEM_FAILED" | "BVN_ONBOARD_FAILED" | "BVN_SUBMIT_FAILED" | "BVN_OTP_SEND_FAILED" | "BVN_OTP_CONFIRM_FAILED" | "BVN_ATTESTATION_FAILED" | "BVN_SESSION_EXPIRED" | "PEER_DEPENDENCY_MISSING";
16
+ type ZkkycErrorCode = "VALIDATION_ERROR" | "CONTRACT_READ_ERROR" | "ENCODE_ERROR" | "RECLAIM_INIT_FAILED" | "RECLAIM_SESSION_NOT_FOUND" | "RECLAIM_PROOF_GENERATION_FAILED" | "RECLAIM_PROOF_INVALID" | "RECLAIM_POLLING_ABORTED" | "ZK_PASSPORT_INIT_FAILED" | "ZK_PASSPORT_REJECTED" | "ZK_PASSPORT_VERIFICATION_FAILED" | "ZK_PASSPORT_ABORTED" | "SIMPLE_KYC_SESSION_FAILED" | "SIMPLE_KYC_REDEEM_FAILED" | "LIVENESS_SESSION_FAILED" | "LIVENESS_REDEEM_FAILED" | "BVN_ONBOARD_FAILED" | "BVN_SUBMIT_FAILED" | "BVN_OTP_SEND_FAILED" | "BVN_OTP_CONFIRM_FAILED" | "BVN_ATTESTATION_FAILED" | "BVN_SESSION_EXPIRED" | "PEER_DEPENDENCY_MISSING";
17
17
  declare class ZkkycError extends SdkError<ZkkycErrorCode> {
18
18
  constructor(message: string, options: {
19
19
  code: ZkkycErrorCode;
@@ -104,6 +104,13 @@ declare const ZodBvnSubmitParamsSchema: z.ZodObject<{
104
104
  signature: z.ZodString;
105
105
  }, z.core.$strip>;
106
106
  type BvnSubmitParams = z.infer<typeof ZodBvnSubmitParamsSchema>;
107
+ declare const ZodLivenessSubmitParamsSchema: z.ZodObject<{
108
+ nullifier: z.ZodString;
109
+ limit: z.ZodBigInt;
110
+ expiry: z.ZodBigInt;
111
+ signature: z.ZodString;
112
+ }, z.core.$strip>;
113
+ type LivenessSubmitParams = z.infer<typeof ZodLivenessSubmitParamsSchema>;
107
114
 
108
115
  interface Zkkyc {
109
116
  prepareSocialVerify(params: SocialVerifyParams): Result<{
@@ -126,6 +133,10 @@ interface Zkkyc {
126
133
  to: Address;
127
134
  data: `0x${string}`;
128
135
  }, ZkkycError>;
136
+ prepareSubmitLivenessAttestation(params: LivenessSubmitParams): Result<{
137
+ to: Address;
138
+ data: `0x${string}`;
139
+ }, ZkkycError>;
129
140
  }
130
141
  /**
131
142
  * Creates a Zkkyc client that binds a reputation manager address,
@@ -298,6 +309,58 @@ interface SimpleKycAttestation {
298
309
  /** The opaque unique-human handle (no PII), for app-side bookkeeping. */
299
310
  readonly identityHash?: string;
300
311
  }
312
+ /**
313
+ * Params for `createLivenessFlow`. The app opens the hosted liveness wizard,
314
+ * which runs onboard → active liveness challenge → face embed → 1:N dedup and,
315
+ * on approval, redirects back to `redirectUrl` with `?code=<code>&state=<state>`.
316
+ * The app then calls `resumeLivenessFlow` to redeem the code for the EIP-712
317
+ * attestation.
318
+ *
319
+ * Identical to `SimpleKycFlowParams` minus `country`: liveness reads no
320
+ * document, so there is no issuing market to prebind.
321
+ */
322
+ interface LivenessFlowParams {
323
+ /**
324
+ * Base URL exposing the browser-facing `/v1/widget/public-sessions` and
325
+ * `/v1/widget/attestation` endpoints — the liveness proxy in a client-only
326
+ * setup (e.g. https://liveness-proxy.p2p.cool). The proxy holds the
327
+ * X-API-Key and forwards to the liveness service's key-gated endpoints.
328
+ * This is **not** the same host as the passport (`simple-kyc`) proxy.
329
+ */
330
+ readonly baseUrl: string;
331
+ /** The user's EVM wallet — bound into the attestation and credited on-chain. */
332
+ readonly walletAddress: Address;
333
+ /** Tenant slug (one per consuming contract), e.g. "p2p-reputation-liveness". */
334
+ readonly tenant: string;
335
+ /** Return URL — pass `${window.location.origin}<route>` so each app self-routes. */
336
+ readonly redirectUrl: string;
337
+ /** Opaque state round-tripped back to the app (CSRF/nonce + page to restore). */
338
+ readonly state?: string;
339
+ /** Status callback. */
340
+ readonly onStatus?: (status: LivenessStatus) => void;
341
+ }
342
+ type LivenessStatus = {
343
+ type: "session_created";
344
+ widgetUrl: string;
345
+ } | {
346
+ type: "redirecting";
347
+ widgetUrl: string;
348
+ };
349
+ interface LivenessSession {
350
+ /** The hosted wizard URL to navigate to. */
351
+ readonly widgetUrl: string;
352
+ /** Convenience: navigate the browser to the wizard (no-op outside the browser). */
353
+ readonly redirect: () => void;
354
+ }
355
+ /** The on-chain-ready attestation, shaped for `prepareSubmitLivenessAttestation`. */
356
+ interface LivenessAttestation {
357
+ readonly nullifier: `0x${string}`;
358
+ readonly limit: bigint;
359
+ readonly expiry: bigint;
360
+ readonly signature: `0x${string}`;
361
+ /** The opaque unique-human handle (no PII), for app-side bookkeeping. */
362
+ readonly identityHash?: string;
363
+ }
301
364
  /** OTP delivery channels the BVN backend exposes. `alternate_phone` needs a number. */
302
365
  type BvnOtpMethod = "email" | "phone" | "phone_1" | "alternate_phone";
303
366
  /** BVN identity scope requested during onboard. */
@@ -368,6 +431,19 @@ interface BvnFlow {
368
431
  }, ZkkycError>;
369
432
  }
370
433
 
434
+ /**
435
+ * Drives the BVN (Nigerian Bank Verification Number) on-chain attestation flow.
436
+ *
437
+ * The SDK talks only to a backend proxy — the single party that holds the Mono
438
+ * secret + the EIP-712 attestor key. Every response uses the `{ ok, data }`
439
+ * envelope. On approval, `getAttestation` returns a signed attestation shaped
440
+ * for `zkkyc.prepareSubmitBvnAttestation`, which the app submits on-chain from
441
+ * the same wallet.
442
+ *
443
+ * Flow: onboard → submitBvn → sendOtp → confirmOtp → getAttestation.
444
+ */
445
+ declare function createBvnFlow(config: BvnFlowConfig): BvnFlow;
446
+
371
447
  /** Default Reclaim provider IDs for each social platform. */
372
448
  declare const DEFAULT_RECLAIM_PROVIDER_IDS: Record<SocialPlatform, string>;
373
449
  /** ZK Passport app store links. */
@@ -381,21 +457,42 @@ declare const RECLAIM_APP_LINKS: {
381
457
  };
382
458
  /** Default tenant slug for the P2P reputation contract on the simple-kyc service. */
383
459
  declare const SIMPLE_KYC_DEFAULT_TENANT = "p2p-reputation";
460
+ /**
461
+ * Default tenant slug for the P2P reputation contract on the **liveness**
462
+ * service. Distinct registry from simple-kyc's — the two services keep separate
463
+ * databases, so a slug existing on one says nothing about the other.
464
+ */
465
+ declare const LIVENESS_DEFAULT_TENANT = "p2p-reputation-liveness";
384
466
  /** OTP delivery channels the BVN backend (Mono) exposes. */
385
467
  declare const BVN_OTP_METHODS: readonly ["email", "phone", "phone_1", "alternate_phone"];
386
468
 
387
469
  /**
388
- * Drives the BVN (Nigerian Bank Verification Number) on-chain attestation flow.
470
+ * Starts the hosted liveness wizard flow. Creates a browser-initiable widget
471
+ * session (no API key in the browser — `baseUrl` points at the liveness proxy,
472
+ * which injects the key and whose tenant allowlist validates the redirect_uri),
473
+ * then returns the wizard URL to navigate to.
389
474
  *
390
- * The SDK talks only to a backend proxy the single party that holds the Mono
391
- * secret + the EIP-712 attestor key. Every response uses the `{ ok, data }`
392
- * envelope. On approval, `getAttestation` returns a signed attestation shaped
393
- * for `zkkyc.prepareSubmitBvnAttestation`, which the app submits on-chain from
394
- * the same wallet.
475
+ * The wizard runs onboard active liveness challenge face embed 1:N dedup
476
+ * and, on approval, redirects back to `redirectUrl` with `?code=<code>&state=<state>`.
477
+ * Call `resumeLivenessFlow({ baseUrl, code })` on return to fetch the attestation.
395
478
  *
396
- * Flow: onboard submitBvn sendOtp confirmOtp → getAttestation.
479
+ * Deliberately separate from `createSimpleKycFlow`: the liveness verifier is a
480
+ * different service with its own database, its own attestor key and its own
481
+ * EIP-712 domain (`LivenessVerifier`, vs the passport wizard's `KycVerifier`).
482
+ * Pointing one flow at the other's base URL yields a signature the contract
483
+ * rejects. The one API-shape difference is that liveness takes **no `country`** —
484
+ * it reads no document, so there is no issuing market to prebind.
397
485
  */
398
- declare function createBvnFlow(config: BvnFlowConfig): BvnFlow;
486
+ declare function createLivenessFlow(params: LivenessFlowParams): ResultAsync<LivenessSession, ZkkycError>;
487
+ /**
488
+ * Redeems the one-time `code` from the wizard's redirect for the EIP-712
489
+ * attestation. The result feeds straight into `zkkyc.prepareSubmitLivenessAttestation`.
490
+ * The endpoint returns only the (non-PII, self-verifying) attestation.
491
+ */
492
+ declare function resumeLivenessFlow(args: {
493
+ baseUrl: string;
494
+ code: string;
495
+ }): ResultAsync<LivenessAttestation, ZkkycError>;
399
496
 
400
497
  /**
401
498
  * Initializes a Reclaim social verification flow and returns a session. `init()`
@@ -428,4 +525,4 @@ declare function resumeSimpleKycFlow(args: {
428
525
  /** Initializes a ZK Passport verification flow and returns a session. */
429
526
  declare function createZkPassportFlow(params: ZkPassportFlowParams): ResultAsync<ZkPassportSession, ZkkycError>;
430
527
 
431
- export { type AnonAadharProofParams, BVN_OTP_METHODS, type BvnAttestation, type BvnDecision, type BvnFlow, type BvnFlowConfig, type BvnMethod, type BvnOnboardParams, type BvnOtpMethod, type BvnScope, type BvnSendOtpParams, type BvnSession, type BvnSubmitParams, DEFAULT_RECLAIM_PROVIDER_IDS, RECLAIM_APP_LINKS, type ReclaimFlowParams, type ReclaimProofResult, type ReclaimSession, type ReclaimStatus, SIMPLE_KYC_DEFAULT_TENANT, SOCIAL_PLATFORM_NAMES, type SimpleKycAttestation, type SimpleKycFlowParams, type SimpleKycSession, type SimpleKycStatus, type SimpleKycSubmitParams, type SocialPlatform, type SocialVerifyParams, ZK_PASSPORT_APP_LINKS, type ZkPassportFlowParams, type ZkPassportProofResult, type ZkPassportRegisterParams, type ZkPassportSession, type ZkPassportStatus, type Zkkyc, type ZkkycConfig, ZkkycError, type ZkkycErrorCode, createBvnFlow, createReclaimFlow, createSimpleKycFlow, createZkPassportFlow, createZkkyc, resumeSimpleKycFlow };
528
+ export { type AnonAadharProofParams, BVN_OTP_METHODS, type BvnAttestation, type BvnDecision, type BvnFlow, type BvnFlowConfig, type BvnMethod, type BvnOnboardParams, type BvnOtpMethod, type BvnScope, type BvnSendOtpParams, type BvnSession, type BvnSubmitParams, DEFAULT_RECLAIM_PROVIDER_IDS, LIVENESS_DEFAULT_TENANT, type LivenessAttestation, type LivenessFlowParams, type LivenessSession, type LivenessStatus, type LivenessSubmitParams, RECLAIM_APP_LINKS, type ReclaimFlowParams, type ReclaimProofResult, type ReclaimSession, type ReclaimStatus, SIMPLE_KYC_DEFAULT_TENANT, SOCIAL_PLATFORM_NAMES, type SimpleKycAttestation, type SimpleKycFlowParams, type SimpleKycSession, type SimpleKycStatus, type SimpleKycSubmitParams, type SocialPlatform, type SocialVerifyParams, ZK_PASSPORT_APP_LINKS, type ZkPassportFlowParams, type ZkPassportProofResult, type ZkPassportRegisterParams, type ZkPassportSession, type ZkPassportStatus, type Zkkyc, type ZkkycConfig, ZkkycError, type ZkkycErrorCode, createBvnFlow, createLivenessFlow, createReclaimFlow, createSimpleKycFlow, createZkPassportFlow, createZkkyc, resumeLivenessFlow, resumeSimpleKycFlow };
package/dist/zkkyc.d.ts CHANGED
@@ -13,7 +13,7 @@ declare class SdkError<TCode extends string = string> extends Error {
13
13
  });
14
14
  }
15
15
 
16
- type ZkkycErrorCode = "VALIDATION_ERROR" | "CONTRACT_READ_ERROR" | "ENCODE_ERROR" | "RECLAIM_INIT_FAILED" | "RECLAIM_SESSION_NOT_FOUND" | "RECLAIM_PROOF_GENERATION_FAILED" | "RECLAIM_PROOF_INVALID" | "RECLAIM_POLLING_ABORTED" | "ZK_PASSPORT_INIT_FAILED" | "ZK_PASSPORT_REJECTED" | "ZK_PASSPORT_VERIFICATION_FAILED" | "ZK_PASSPORT_ABORTED" | "SIMPLE_KYC_SESSION_FAILED" | "SIMPLE_KYC_REDEEM_FAILED" | "BVN_ONBOARD_FAILED" | "BVN_SUBMIT_FAILED" | "BVN_OTP_SEND_FAILED" | "BVN_OTP_CONFIRM_FAILED" | "BVN_ATTESTATION_FAILED" | "BVN_SESSION_EXPIRED" | "PEER_DEPENDENCY_MISSING";
16
+ type ZkkycErrorCode = "VALIDATION_ERROR" | "CONTRACT_READ_ERROR" | "ENCODE_ERROR" | "RECLAIM_INIT_FAILED" | "RECLAIM_SESSION_NOT_FOUND" | "RECLAIM_PROOF_GENERATION_FAILED" | "RECLAIM_PROOF_INVALID" | "RECLAIM_POLLING_ABORTED" | "ZK_PASSPORT_INIT_FAILED" | "ZK_PASSPORT_REJECTED" | "ZK_PASSPORT_VERIFICATION_FAILED" | "ZK_PASSPORT_ABORTED" | "SIMPLE_KYC_SESSION_FAILED" | "SIMPLE_KYC_REDEEM_FAILED" | "LIVENESS_SESSION_FAILED" | "LIVENESS_REDEEM_FAILED" | "BVN_ONBOARD_FAILED" | "BVN_SUBMIT_FAILED" | "BVN_OTP_SEND_FAILED" | "BVN_OTP_CONFIRM_FAILED" | "BVN_ATTESTATION_FAILED" | "BVN_SESSION_EXPIRED" | "PEER_DEPENDENCY_MISSING";
17
17
  declare class ZkkycError extends SdkError<ZkkycErrorCode> {
18
18
  constructor(message: string, options: {
19
19
  code: ZkkycErrorCode;
@@ -104,6 +104,13 @@ declare const ZodBvnSubmitParamsSchema: z.ZodObject<{
104
104
  signature: z.ZodString;
105
105
  }, z.core.$strip>;
106
106
  type BvnSubmitParams = z.infer<typeof ZodBvnSubmitParamsSchema>;
107
+ declare const ZodLivenessSubmitParamsSchema: z.ZodObject<{
108
+ nullifier: z.ZodString;
109
+ limit: z.ZodBigInt;
110
+ expiry: z.ZodBigInt;
111
+ signature: z.ZodString;
112
+ }, z.core.$strip>;
113
+ type LivenessSubmitParams = z.infer<typeof ZodLivenessSubmitParamsSchema>;
107
114
 
108
115
  interface Zkkyc {
109
116
  prepareSocialVerify(params: SocialVerifyParams): Result<{
@@ -126,6 +133,10 @@ interface Zkkyc {
126
133
  to: Address;
127
134
  data: `0x${string}`;
128
135
  }, ZkkycError>;
136
+ prepareSubmitLivenessAttestation(params: LivenessSubmitParams): Result<{
137
+ to: Address;
138
+ data: `0x${string}`;
139
+ }, ZkkycError>;
129
140
  }
130
141
  /**
131
142
  * Creates a Zkkyc client that binds a reputation manager address,
@@ -298,6 +309,58 @@ interface SimpleKycAttestation {
298
309
  /** The opaque unique-human handle (no PII), for app-side bookkeeping. */
299
310
  readonly identityHash?: string;
300
311
  }
312
+ /**
313
+ * Params for `createLivenessFlow`. The app opens the hosted liveness wizard,
314
+ * which runs onboard → active liveness challenge → face embed → 1:N dedup and,
315
+ * on approval, redirects back to `redirectUrl` with `?code=<code>&state=<state>`.
316
+ * The app then calls `resumeLivenessFlow` to redeem the code for the EIP-712
317
+ * attestation.
318
+ *
319
+ * Identical to `SimpleKycFlowParams` minus `country`: liveness reads no
320
+ * document, so there is no issuing market to prebind.
321
+ */
322
+ interface LivenessFlowParams {
323
+ /**
324
+ * Base URL exposing the browser-facing `/v1/widget/public-sessions` and
325
+ * `/v1/widget/attestation` endpoints — the liveness proxy in a client-only
326
+ * setup (e.g. https://liveness-proxy.p2p.cool). The proxy holds the
327
+ * X-API-Key and forwards to the liveness service's key-gated endpoints.
328
+ * This is **not** the same host as the passport (`simple-kyc`) proxy.
329
+ */
330
+ readonly baseUrl: string;
331
+ /** The user's EVM wallet — bound into the attestation and credited on-chain. */
332
+ readonly walletAddress: Address;
333
+ /** Tenant slug (one per consuming contract), e.g. "p2p-reputation-liveness". */
334
+ readonly tenant: string;
335
+ /** Return URL — pass `${window.location.origin}<route>` so each app self-routes. */
336
+ readonly redirectUrl: string;
337
+ /** Opaque state round-tripped back to the app (CSRF/nonce + page to restore). */
338
+ readonly state?: string;
339
+ /** Status callback. */
340
+ readonly onStatus?: (status: LivenessStatus) => void;
341
+ }
342
+ type LivenessStatus = {
343
+ type: "session_created";
344
+ widgetUrl: string;
345
+ } | {
346
+ type: "redirecting";
347
+ widgetUrl: string;
348
+ };
349
+ interface LivenessSession {
350
+ /** The hosted wizard URL to navigate to. */
351
+ readonly widgetUrl: string;
352
+ /** Convenience: navigate the browser to the wizard (no-op outside the browser). */
353
+ readonly redirect: () => void;
354
+ }
355
+ /** The on-chain-ready attestation, shaped for `prepareSubmitLivenessAttestation`. */
356
+ interface LivenessAttestation {
357
+ readonly nullifier: `0x${string}`;
358
+ readonly limit: bigint;
359
+ readonly expiry: bigint;
360
+ readonly signature: `0x${string}`;
361
+ /** The opaque unique-human handle (no PII), for app-side bookkeeping. */
362
+ readonly identityHash?: string;
363
+ }
301
364
  /** OTP delivery channels the BVN backend exposes. `alternate_phone` needs a number. */
302
365
  type BvnOtpMethod = "email" | "phone" | "phone_1" | "alternate_phone";
303
366
  /** BVN identity scope requested during onboard. */
@@ -368,6 +431,19 @@ interface BvnFlow {
368
431
  }, ZkkycError>;
369
432
  }
370
433
 
434
+ /**
435
+ * Drives the BVN (Nigerian Bank Verification Number) on-chain attestation flow.
436
+ *
437
+ * The SDK talks only to a backend proxy — the single party that holds the Mono
438
+ * secret + the EIP-712 attestor key. Every response uses the `{ ok, data }`
439
+ * envelope. On approval, `getAttestation` returns a signed attestation shaped
440
+ * for `zkkyc.prepareSubmitBvnAttestation`, which the app submits on-chain from
441
+ * the same wallet.
442
+ *
443
+ * Flow: onboard → submitBvn → sendOtp → confirmOtp → getAttestation.
444
+ */
445
+ declare function createBvnFlow(config: BvnFlowConfig): BvnFlow;
446
+
371
447
  /** Default Reclaim provider IDs for each social platform. */
372
448
  declare const DEFAULT_RECLAIM_PROVIDER_IDS: Record<SocialPlatform, string>;
373
449
  /** ZK Passport app store links. */
@@ -381,21 +457,42 @@ declare const RECLAIM_APP_LINKS: {
381
457
  };
382
458
  /** Default tenant slug for the P2P reputation contract on the simple-kyc service. */
383
459
  declare const SIMPLE_KYC_DEFAULT_TENANT = "p2p-reputation";
460
+ /**
461
+ * Default tenant slug for the P2P reputation contract on the **liveness**
462
+ * service. Distinct registry from simple-kyc's — the two services keep separate
463
+ * databases, so a slug existing on one says nothing about the other.
464
+ */
465
+ declare const LIVENESS_DEFAULT_TENANT = "p2p-reputation-liveness";
384
466
  /** OTP delivery channels the BVN backend (Mono) exposes. */
385
467
  declare const BVN_OTP_METHODS: readonly ["email", "phone", "phone_1", "alternate_phone"];
386
468
 
387
469
  /**
388
- * Drives the BVN (Nigerian Bank Verification Number) on-chain attestation flow.
470
+ * Starts the hosted liveness wizard flow. Creates a browser-initiable widget
471
+ * session (no API key in the browser — `baseUrl` points at the liveness proxy,
472
+ * which injects the key and whose tenant allowlist validates the redirect_uri),
473
+ * then returns the wizard URL to navigate to.
389
474
  *
390
- * The SDK talks only to a backend proxy the single party that holds the Mono
391
- * secret + the EIP-712 attestor key. Every response uses the `{ ok, data }`
392
- * envelope. On approval, `getAttestation` returns a signed attestation shaped
393
- * for `zkkyc.prepareSubmitBvnAttestation`, which the app submits on-chain from
394
- * the same wallet.
475
+ * The wizard runs onboard active liveness challenge face embed 1:N dedup
476
+ * and, on approval, redirects back to `redirectUrl` with `?code=<code>&state=<state>`.
477
+ * Call `resumeLivenessFlow({ baseUrl, code })` on return to fetch the attestation.
395
478
  *
396
- * Flow: onboard submitBvn sendOtp confirmOtp → getAttestation.
479
+ * Deliberately separate from `createSimpleKycFlow`: the liveness verifier is a
480
+ * different service with its own database, its own attestor key and its own
481
+ * EIP-712 domain (`LivenessVerifier`, vs the passport wizard's `KycVerifier`).
482
+ * Pointing one flow at the other's base URL yields a signature the contract
483
+ * rejects. The one API-shape difference is that liveness takes **no `country`** —
484
+ * it reads no document, so there is no issuing market to prebind.
397
485
  */
398
- declare function createBvnFlow(config: BvnFlowConfig): BvnFlow;
486
+ declare function createLivenessFlow(params: LivenessFlowParams): ResultAsync<LivenessSession, ZkkycError>;
487
+ /**
488
+ * Redeems the one-time `code` from the wizard's redirect for the EIP-712
489
+ * attestation. The result feeds straight into `zkkyc.prepareSubmitLivenessAttestation`.
490
+ * The endpoint returns only the (non-PII, self-verifying) attestation.
491
+ */
492
+ declare function resumeLivenessFlow(args: {
493
+ baseUrl: string;
494
+ code: string;
495
+ }): ResultAsync<LivenessAttestation, ZkkycError>;
399
496
 
400
497
  /**
401
498
  * Initializes a Reclaim social verification flow and returns a session. `init()`
@@ -428,4 +525,4 @@ declare function resumeSimpleKycFlow(args: {
428
525
  /** Initializes a ZK Passport verification flow and returns a session. */
429
526
  declare function createZkPassportFlow(params: ZkPassportFlowParams): ResultAsync<ZkPassportSession, ZkkycError>;
430
527
 
431
- export { type AnonAadharProofParams, BVN_OTP_METHODS, type BvnAttestation, type BvnDecision, type BvnFlow, type BvnFlowConfig, type BvnMethod, type BvnOnboardParams, type BvnOtpMethod, type BvnScope, type BvnSendOtpParams, type BvnSession, type BvnSubmitParams, DEFAULT_RECLAIM_PROVIDER_IDS, RECLAIM_APP_LINKS, type ReclaimFlowParams, type ReclaimProofResult, type ReclaimSession, type ReclaimStatus, SIMPLE_KYC_DEFAULT_TENANT, SOCIAL_PLATFORM_NAMES, type SimpleKycAttestation, type SimpleKycFlowParams, type SimpleKycSession, type SimpleKycStatus, type SimpleKycSubmitParams, type SocialPlatform, type SocialVerifyParams, ZK_PASSPORT_APP_LINKS, type ZkPassportFlowParams, type ZkPassportProofResult, type ZkPassportRegisterParams, type ZkPassportSession, type ZkPassportStatus, type Zkkyc, type ZkkycConfig, ZkkycError, type ZkkycErrorCode, createBvnFlow, createReclaimFlow, createSimpleKycFlow, createZkPassportFlow, createZkkyc, resumeSimpleKycFlow };
528
+ export { type AnonAadharProofParams, BVN_OTP_METHODS, type BvnAttestation, type BvnDecision, type BvnFlow, type BvnFlowConfig, type BvnMethod, type BvnOnboardParams, type BvnOtpMethod, type BvnScope, type BvnSendOtpParams, type BvnSession, type BvnSubmitParams, DEFAULT_RECLAIM_PROVIDER_IDS, LIVENESS_DEFAULT_TENANT, type LivenessAttestation, type LivenessFlowParams, type LivenessSession, type LivenessStatus, type LivenessSubmitParams, RECLAIM_APP_LINKS, type ReclaimFlowParams, type ReclaimProofResult, type ReclaimSession, type ReclaimStatus, SIMPLE_KYC_DEFAULT_TENANT, SOCIAL_PLATFORM_NAMES, type SimpleKycAttestation, type SimpleKycFlowParams, type SimpleKycSession, type SimpleKycStatus, type SimpleKycSubmitParams, type SocialPlatform, type SocialVerifyParams, ZK_PASSPORT_APP_LINKS, type ZkPassportFlowParams, type ZkPassportProofResult, type ZkPassportRegisterParams, type ZkPassportSession, type ZkPassportStatus, type Zkkyc, type ZkkycConfig, ZkkycError, type ZkkycErrorCode, createBvnFlow, createLivenessFlow, createReclaimFlow, createSimpleKycFlow, createZkPassportFlow, createZkkyc, resumeLivenessFlow, resumeSimpleKycFlow };
package/dist/zkkyc.mjs CHANGED
@@ -158,6 +158,20 @@ var ZodBvnSubmitParamsSchema = z2.object({
158
158
  message: "signature must be a hex string"
159
159
  })
160
160
  });
161
+ var ZodLivenessSubmitParamsSchema = z2.object({
162
+ /** Per-(tenant, identity) Sybil nullifier (bytes32 hex). */
163
+ nullifier: z2.string().refine((v) => /^0x[a-fA-F0-9]{64}$/.test(v), {
164
+ message: "nullifier must be a bytes32 hex string"
165
+ }),
166
+ /** Remaining limit in micro-USDC (part of the signed struct). */
167
+ limit: z2.bigint(),
168
+ /** Attestation expiry (unix seconds). */
169
+ expiry: z2.bigint(),
170
+ /** 65-byte secp256k1 signature (hex). */
171
+ signature: z2.string().refine((v) => /^0x[a-fA-F0-9]+$/.test(v), {
172
+ message: "signature must be a hex string"
173
+ })
174
+ });
161
175
 
162
176
  // src/contracts/abis/index.ts
163
177
  import { erc20Abi } from "viem";
@@ -994,6 +1008,39 @@ var reputationManagerAbi = [
994
1008
  outputs: [{ internalType: "bool", name: "", type: "bool" }],
995
1009
  stateMutability: "view",
996
1010
  type: "function"
1011
+ },
1012
+ // ── Liveness (face-only, no document) attestation ───────────────────────
1013
+ { inputs: [], name: "LivenessSignerNotSet", type: "error" },
1014
+ { inputs: [], name: "LivenessAttestationExpired", type: "error" },
1015
+ { inputs: [], name: "LivenessNullifierZero", type: "error" },
1016
+ { inputs: [], name: "LivenessNullifierAlreadySpent", type: "error" },
1017
+ { inputs: [], name: "LivenessAlreadyVerified", type: "error" },
1018
+ { inputs: [], name: "LivenessInvalidSignature", type: "error" },
1019
+ {
1020
+ inputs: [
1021
+ { internalType: "bytes32", name: "nullifier", type: "bytes32" },
1022
+ { internalType: "uint256", name: "limit", type: "uint256" },
1023
+ { internalType: "uint256", name: "expiry", type: "uint256" },
1024
+ { internalType: "bytes", name: "signature", type: "bytes" }
1025
+ ],
1026
+ name: "submitLivenessAttestation",
1027
+ outputs: [],
1028
+ stateMutability: "nonpayable",
1029
+ type: "function"
1030
+ },
1031
+ {
1032
+ inputs: [],
1033
+ name: "livenessRp",
1034
+ outputs: [{ internalType: "uint256", name: "", type: "uint256" }],
1035
+ stateMutability: "view",
1036
+ type: "function"
1037
+ },
1038
+ {
1039
+ inputs: [{ internalType: "address", name: "", type: "address" }],
1040
+ name: "livenessVerified",
1041
+ outputs: [{ internalType: "bool", name: "", type: "bool" }],
1042
+ stateMutability: "view",
1043
+ type: "function"
997
1044
  }
998
1045
  ];
999
1046
 
@@ -1137,6 +1184,33 @@ function prepareSubmitBvnAttestation(reputationManagerAddress, params) {
1137
1184
  )()
1138
1185
  );
1139
1186
  }
1187
+ function prepareSubmitLivenessAttestation(reputationManagerAddress, params) {
1188
+ return validate(
1189
+ ZodLivenessSubmitParamsSchema,
1190
+ params,
1191
+ (message, cause, data) => new ZkkycError(message, { code: "VALIDATION_ERROR", cause, context: { params: data } })
1192
+ ).andThen(
1193
+ (validated) => Result.fromThrowable(
1194
+ () => ({
1195
+ to: reputationManagerAddress,
1196
+ data: encodeFunctionData({
1197
+ abi: ABIS.EXTERNAL.REPUTATION_MANAGER,
1198
+ functionName: "submitLivenessAttestation",
1199
+ args: [
1200
+ validated.nullifier,
1201
+ validated.limit,
1202
+ validated.expiry,
1203
+ validated.signature
1204
+ ]
1205
+ })
1206
+ }),
1207
+ (error) => new ZkkycError("Failed to encode submitLivenessAttestation", {
1208
+ code: "ENCODE_ERROR",
1209
+ cause: error
1210
+ })
1211
+ )()
1212
+ );
1213
+ }
1140
1214
  function prepareZkPassportRegister(reputationManagerAddress, params) {
1141
1215
  return validate(
1142
1216
  ZodZkPassportRegisterParamsSchema,
@@ -1186,29 +1260,11 @@ function createZkkyc(config) {
1186
1260
  prepareSubmitAnonAadharProof: (params) => prepareSubmitAnonAadharProof(reputationManagerAddress, params),
1187
1261
  prepareZkPassportRegister: (params) => prepareZkPassportRegister(reputationManagerAddress, params),
1188
1262
  prepareSubmitKycAttestation: (params) => prepareSubmitKycAttestation(reputationManagerAddress, params),
1189
- prepareSubmitBvnAttestation: (params) => prepareSubmitBvnAttestation(reputationManagerAddress, params)
1263
+ prepareSubmitBvnAttestation: (params) => prepareSubmitBvnAttestation(reputationManagerAddress, params),
1264
+ prepareSubmitLivenessAttestation: (params) => prepareSubmitLivenessAttestation(reputationManagerAddress, params)
1190
1265
  };
1191
1266
  }
1192
1267
 
1193
- // src/zkkyc/orchestrators/constants.ts
1194
- var DEFAULT_RECLAIM_PROVIDER_IDS = {
1195
- linkedin: "6a86edbe-a0fe-420b-8db2-3155220cc949",
1196
- github: "033f0c06-2eb3-48c8-894c-5599c3356d1c",
1197
- x: "aad95818-f726-4a34-be97-8d1f47631b03",
1198
- instagram: "7e5b59a9-56c5-490c-a169-82a443f9b507",
1199
- facebook: "2701510b-c835-4820-84f0-d9e74569656b",
1200
- binance: "7e40c007-f432-4d47-ac00-3e0762f8a7a0"
1201
- };
1202
- var ZK_PASSPORT_APP_LINKS = {
1203
- IOS: "https://apps.apple.com/us/app/zkpassport/id6477371975",
1204
- ANDROID: "https://play.google.com/store/apps/details?id=app.zkpassport.zkpassport"
1205
- };
1206
- var RECLAIM_APP_LINKS = {
1207
- ANDROID: "https://play.google.com/store/apps/details?id=org.reclaimprotocol.app"
1208
- };
1209
- var SIMPLE_KYC_DEFAULT_TENANT = "p2p-reputation";
1210
- var BVN_OTP_METHODS = ["email", "phone", "phone_1", "alternate_phone"];
1211
-
1212
1268
  // src/zkkyc/orchestrators/bvn.ts
1213
1269
  import { ResultAsync } from "neverthrow";
1214
1270
  function createBvnFlow(config) {
@@ -1348,8 +1404,107 @@ function createBvnFlow(config) {
1348
1404
  };
1349
1405
  }
1350
1406
 
1351
- // src/zkkyc/orchestrators/reclaim.ts
1407
+ // src/zkkyc/orchestrators/constants.ts
1408
+ var DEFAULT_RECLAIM_PROVIDER_IDS = {
1409
+ linkedin: "6a86edbe-a0fe-420b-8db2-3155220cc949",
1410
+ github: "033f0c06-2eb3-48c8-894c-5599c3356d1c",
1411
+ x: "aad95818-f726-4a34-be97-8d1f47631b03",
1412
+ instagram: "7e5b59a9-56c5-490c-a169-82a443f9b507",
1413
+ facebook: "2701510b-c835-4820-84f0-d9e74569656b",
1414
+ binance: "7e40c007-f432-4d47-ac00-3e0762f8a7a0"
1415
+ };
1416
+ var ZK_PASSPORT_APP_LINKS = {
1417
+ IOS: "https://apps.apple.com/us/app/zkpassport/id6477371975",
1418
+ ANDROID: "https://play.google.com/store/apps/details?id=app.zkpassport.zkpassport"
1419
+ };
1420
+ var RECLAIM_APP_LINKS = {
1421
+ ANDROID: "https://play.google.com/store/apps/details?id=org.reclaimprotocol.app"
1422
+ };
1423
+ var SIMPLE_KYC_DEFAULT_TENANT = "p2p-reputation";
1424
+ var LIVENESS_DEFAULT_TENANT = "p2p-reputation-liveness";
1425
+ var BVN_OTP_METHODS = ["email", "phone", "phone_1", "alternate_phone"];
1426
+
1427
+ // src/zkkyc/orchestrators/liveness.ts
1352
1428
  import { ResultAsync as ResultAsync2 } from "neverthrow";
1429
+ function createLivenessFlow(params) {
1430
+ const { baseUrl, walletAddress, tenant, redirectUrl, state, onStatus } = params;
1431
+ return ResultAsync2.fromPromise(
1432
+ (async () => {
1433
+ const res = await fetch(`${baseUrl}/v1/widget/public-sessions`, {
1434
+ method: "POST",
1435
+ headers: { "Content-Type": "application/json" },
1436
+ body: JSON.stringify({
1437
+ wallet_pubkey: walletAddress,
1438
+ redirect_uri: redirectUrl,
1439
+ tenant,
1440
+ state
1441
+ })
1442
+ });
1443
+ if (!res.ok) {
1444
+ const body = await res.text();
1445
+ throw new ZkkycError(`liveness session creation failed: ${res.status} ${body}`, {
1446
+ code: "LIVENESS_SESSION_FAILED",
1447
+ context: { status: res.status }
1448
+ });
1449
+ }
1450
+ const data = await res.json();
1451
+ const widgetUrl = data.widget_url;
1452
+ onStatus?.({ type: "session_created", widgetUrl });
1453
+ return {
1454
+ widgetUrl,
1455
+ redirect: () => {
1456
+ if (typeof window !== "undefined") {
1457
+ onStatus?.({ type: "redirecting", widgetUrl });
1458
+ window.location.href = widgetUrl;
1459
+ }
1460
+ }
1461
+ };
1462
+ })(),
1463
+ (error) => {
1464
+ if (error instanceof ZkkycError) return error;
1465
+ return new ZkkycError("liveness flow failed to start", {
1466
+ code: "LIVENESS_SESSION_FAILED",
1467
+ cause: error
1468
+ });
1469
+ }
1470
+ );
1471
+ }
1472
+ function resumeLivenessFlow(args) {
1473
+ return ResultAsync2.fromPromise(
1474
+ (async () => {
1475
+ const res = await fetch(`${args.baseUrl}/v1/widget/attestation`, {
1476
+ method: "POST",
1477
+ headers: { "Content-Type": "application/json" },
1478
+ body: JSON.stringify({ code: args.code })
1479
+ });
1480
+ if (!res.ok) {
1481
+ const body = await res.text();
1482
+ throw new ZkkycError(`liveness attestation redemption failed: ${res.status} ${body}`, {
1483
+ code: "LIVENESS_REDEEM_FAILED",
1484
+ context: { status: res.status }
1485
+ });
1486
+ }
1487
+ const d = await res.json();
1488
+ return {
1489
+ nullifier: d.nullifier,
1490
+ limit: BigInt(d.limit),
1491
+ expiry: BigInt(d.expiry),
1492
+ signature: d.signature,
1493
+ identityHash: d.identity_hash
1494
+ };
1495
+ })(),
1496
+ (error) => {
1497
+ if (error instanceof ZkkycError) return error;
1498
+ return new ZkkycError("liveness attestation redemption failed", {
1499
+ code: "LIVENESS_REDEEM_FAILED",
1500
+ cause: error
1501
+ });
1502
+ }
1503
+ );
1504
+ }
1505
+
1506
+ // src/zkkyc/orchestrators/reclaim.ts
1507
+ import { ResultAsync as ResultAsync3 } from "neverthrow";
1353
1508
 
1354
1509
  // src/zkkyc/orchestrators/types.ts
1355
1510
  var SOCIAL_PLATFORM_NAMES = {
@@ -1364,7 +1519,7 @@ var SOCIAL_PLATFORM_NAMES = {
1364
1519
  // src/zkkyc/orchestrators/reclaim.ts
1365
1520
  var RECLAIM_SESSION_API = "https://api.reclaimprotocol.org/api/sdk/session";
1366
1521
  function createReclaimFlow(params) {
1367
- return ResultAsync2.fromPromise(
1522
+ return ResultAsync3.fromPromise(
1368
1523
  (async () => {
1369
1524
  const mod = await import("@reclaimprotocol/js-sdk").catch(() => {
1370
1525
  throw new ZkkycError(
@@ -1468,7 +1623,7 @@ function createReclaimFlow(params) {
1468
1623
  const session = {
1469
1624
  sessionId,
1470
1625
  requestUrl,
1471
- start: () => ResultAsync2.fromPromise(pollForProof(), (error) => {
1626
+ start: () => ResultAsync3.fromPromise(pollForProof(), (error) => {
1472
1627
  if (error instanceof ZkkycError) return error;
1473
1628
  return new ZkkycError("Reclaim verification flow failed", {
1474
1629
  code: "RECLAIM_INIT_FAILED",
@@ -1492,10 +1647,10 @@ function createReclaimFlow(params) {
1492
1647
  }
1493
1648
 
1494
1649
  // src/zkkyc/orchestrators/simple-kyc.ts
1495
- import { ResultAsync as ResultAsync3 } from "neverthrow";
1650
+ import { ResultAsync as ResultAsync4 } from "neverthrow";
1496
1651
  function createSimpleKycFlow(params) {
1497
1652
  const { baseUrl, walletAddress, tenant, redirectUrl, country, state, onStatus } = params;
1498
- return ResultAsync3.fromPromise(
1653
+ return ResultAsync4.fromPromise(
1499
1654
  (async () => {
1500
1655
  const res = await fetch(`${baseUrl}/v1/widget/public-sessions`, {
1501
1656
  method: "POST",
@@ -1538,7 +1693,7 @@ function createSimpleKycFlow(params) {
1538
1693
  );
1539
1694
  }
1540
1695
  function resumeSimpleKycFlow(args) {
1541
- return ResultAsync3.fromPromise(
1696
+ return ResultAsync4.fromPromise(
1542
1697
  (async () => {
1543
1698
  const res = await fetch(`${args.baseUrl}/v1/widget/attestation`, {
1544
1699
  method: "POST",
@@ -1572,9 +1727,9 @@ function resumeSimpleKycFlow(args) {
1572
1727
  }
1573
1728
 
1574
1729
  // src/zkkyc/orchestrators/zk-passport.ts
1575
- import { ResultAsync as ResultAsync4 } from "neverthrow";
1730
+ import { ResultAsync as ResultAsync5 } from "neverthrow";
1576
1731
  function createZkPassportFlow(params) {
1577
- return ResultAsync4.fromPromise(
1732
+ return ResultAsync5.fromPromise(
1578
1733
  (async () => {
1579
1734
  const mod = await import("@zkpassport/sdk").catch(() => {
1580
1735
  throw new ZkkycError(
@@ -1670,7 +1825,7 @@ function createZkPassportFlow(params) {
1670
1825
  });
1671
1826
  const session = {
1672
1827
  url,
1673
- result: ResultAsync4.fromPromise(resultPromise, (error) => {
1828
+ result: ResultAsync5.fromPromise(resultPromise, (error) => {
1674
1829
  if (error instanceof ZkkycError) return error;
1675
1830
  return new ZkkycError("ZK Passport flow failed", {
1676
1831
  code: "ZK_PASSPORT_VERIFICATION_FAILED",
@@ -1695,16 +1850,19 @@ function createZkPassportFlow(params) {
1695
1850
  export {
1696
1851
  BVN_OTP_METHODS,
1697
1852
  DEFAULT_RECLAIM_PROVIDER_IDS,
1853
+ LIVENESS_DEFAULT_TENANT,
1698
1854
  RECLAIM_APP_LINKS,
1699
1855
  SIMPLE_KYC_DEFAULT_TENANT,
1700
1856
  SOCIAL_PLATFORM_NAMES,
1701
1857
  ZK_PASSPORT_APP_LINKS,
1702
1858
  ZkkycError,
1703
1859
  createBvnFlow,
1860
+ createLivenessFlow,
1704
1861
  createReclaimFlow,
1705
1862
  createSimpleKycFlow,
1706
1863
  createZkPassportFlow,
1707
1864
  createZkkyc,
1865
+ resumeLivenessFlow,
1708
1866
  resumeSimpleKycFlow
1709
1867
  };
1710
1868
  //# sourceMappingURL=zkkyc.mjs.map