@nokinc-flur/sdk 2.4.0 → 2.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -48,6 +48,7 @@ __export(index_exports, {
48
48
  CONSUMER_OAC_QR_PREFIX: () => CONSUMER_OAC_QR_PREFIX,
49
49
  CONSUMER_OFFLINE_CLAIM_SUBMIT_GRACE_MS: () => CONSUMER_OFFLINE_CLAIM_SUBMIT_GRACE_MS,
50
50
  CONSUMER_PAYMENT_REQUEST_DOMAIN: () => CONSUMER_PAYMENT_REQUEST_DOMAIN,
51
+ CONSUMER_REVOCATION_DOMAIN: () => CONSUMER_REVOCATION_DOMAIN,
51
52
  CONSUMER_SETTLEMENT_DOMAIN: () => CONSUMER_SETTLEMENT_DOMAIN,
52
53
  CONSUMER_SETTLEMENT_RECEIPT_QR_PREFIX: () => CONSUMER_SETTLEMENT_RECEIPT_QR_PREFIX,
53
54
  CUSTODIAL_MODES: () => CUSTODIAL_MODES,
@@ -145,6 +146,7 @@ __export(index_exports, {
145
146
  RECEIPT_CHANNELS: () => RECEIPT_CHANNELS,
146
147
  RECEIPT_KINDS: () => RECEIPT_KINDS,
147
148
  REPLAY_WINDOW_MS: () => REPLAY_WINDOW_MS,
149
+ REVOCATION_LIST_MAX_ENTRIES: () => REVOCATION_LIST_MAX_ENTRIES,
148
150
  ReceiptArtifactSchema: () => ReceiptArtifactSchema,
149
151
  ReceiptPayloadSchema: () => ReceiptPayloadSchema,
150
152
  ReceiptSchema: () => ReceiptSchema,
@@ -153,12 +155,14 @@ __export(index_exports, {
153
155
  RedemptionSchema: () => RedemptionSchema,
154
156
  RegisterDeviceKeyP256InputSchema: () => RegisterDeviceKeyP256InputSchema,
155
157
  ReversalRecordArtifactSchema: () => ReversalRecordArtifactSchema,
158
+ RevocationListSchema: () => RevocationListSchema,
156
159
  RevokeDeviceKeyInputSchema: () => RevokeDeviceKeyInputSchema,
157
160
  SETTLEMENT_SCHEDULES: () => SETTLEMENT_SCHEDULES,
158
161
  SettleResponseSchema: () => SettleResponseSchema,
159
162
  SettlementRecordArtifactSchema: () => SettlementRecordArtifactSchema,
160
163
  SettlementSchema: () => SettlementSchema,
161
164
  SignedConsumerOACSchema: () => SignedConsumerOACSchema,
165
+ SignedRevocationListSchema: () => SignedRevocationListSchema,
162
166
  StatementArtifactSchema: () => StatementArtifactSchema,
163
167
  UpsertMerchantProfileInputSchema: () => UpsertMerchantProfileInputSchema,
164
168
  UpsertPartnerProfileInputSchema: () => UpsertPartnerProfileInputSchema,
@@ -239,6 +243,7 @@ __export(index_exports, {
239
243
  isConsumerPaymentRequestExpired: () => isConsumerPaymentRequestExpired,
240
244
  isHardenedArtifactType: () => isHardenedArtifactType,
241
245
  isKnownArtifactType: () => isKnownArtifactType,
246
+ isOacRevoked: () => isOacRevoked,
242
247
  isPassWithinValidity: () => isPassWithinValidity,
243
248
  moneyMinorToNumber: () => moneyMinorToNumber,
244
249
  normalizeE164: () => normalizeE164,
@@ -246,6 +251,7 @@ __export(index_exports, {
246
251
  parseNQR: () => parseNQR,
247
252
  parseQR: () => parseQR,
248
253
  readTLV: () => readTLV,
254
+ revocationListSigningPayload: () => revocationListSigningPayload,
249
255
  routingHint: () => routingHint,
250
256
  signArtifact: () => signArtifact,
251
257
  signAuthorization: () => signAuthorization,
@@ -272,6 +278,7 @@ __export(index_exports, {
272
278
  verifyReceipt: () => verifyReceipt,
273
279
  verifyRedemption: () => verifyRedemption,
274
280
  verifyRequestHMAC: () => verifyRequestHMAC,
281
+ verifyRevocationList: () => verifyRevocationList,
275
282
  writeTLV: () => writeTLV
276
283
  });
277
284
  module.exports = __toCommonJS(index_exports);
@@ -3233,76 +3240,142 @@ function createAccountsClient(opts) {
3233
3240
  }
3234
3241
 
3235
3242
  // src/me-offline/client.ts
3243
+ var import_zod14 = require("zod");
3244
+
3245
+ // src/me-offline/revocation.ts
3236
3246
  var import_zod13 = require("zod");
3237
- var Sha256Hex = import_zod13.z.string().regex(/^[0-9a-f]{64}$/);
3238
3247
  var Base64Std3 = import_zod13.z.string().regex(/^[A-Za-z0-9+/]+={0,2}$/);
3239
- var ClaimNonce = import_zod13.z.string().min(8).max(128).refine((value) => !value.includes("|"), {
3248
+ var CONSUMER_REVOCATION_DOMAIN = "flur:consumer-offline:v1:revocation";
3249
+ var REVOCATION_LIST_MAX_ENTRIES = 1e5;
3250
+ var RevocationListSchema = import_zod13.z.object({
3251
+ issuerId: import_zod13.z.string().min(1).max(64),
3252
+ /**
3253
+ * Monotonic snapshot counter. A device MUST NOT replace a pinned list with
3254
+ * one carrying a lower sequence — this defeats a downgrade/rollback attack
3255
+ * that replays an older list to resurrect a revoked credential.
3256
+ */
3257
+ sequence: import_zod13.z.number().int().nonnegative(),
3258
+ issuedAtMs: import_zod13.z.number().int().nonnegative(),
3259
+ /**
3260
+ * Freshness bound. After this instant the list is considered stale and the
3261
+ * verifier treats it as untrustworthy (fail-closed), forcing a re-pin.
3262
+ * Optional so the issuer may publish a list without a hard expiry.
3263
+ */
3264
+ notAfterMs: import_zod13.z.number().int().positive().optional(),
3265
+ /** OAC ids that are revoked AND not yet past their own validity window. */
3266
+ revokedOacIds: import_zod13.z.array(import_zod13.z.string().uuid()).max(REVOCATION_LIST_MAX_ENTRIES)
3267
+ });
3268
+ var SignedRevocationListSchema = import_zod13.z.object({
3269
+ list: RevocationListSchema,
3270
+ /** ASN.1 DER ECDSA P-256 issuer signature over the signing payload, base64. */
3271
+ issuerSig: Base64Std3.min(16).max(2048),
3272
+ /** Issuer's P-256 public key as SubjectPublicKeyInfo DER, base64. */
3273
+ issuerPublicKeySpkiB64: Base64Std3.min(64).max(4096)
3274
+ });
3275
+ function revocationListSigningPayload(list) {
3276
+ const payload = {
3277
+ domain: CONSUMER_REVOCATION_DOMAIN,
3278
+ issuerId: list.issuerId,
3279
+ sequence: list.sequence,
3280
+ issuedAtMs: list.issuedAtMs,
3281
+ revokedOacIds: list.revokedOacIds
3282
+ };
3283
+ if (list.notAfterMs !== void 0) payload.notAfterMs = list.notAfterMs;
3284
+ return payload;
3285
+ }
3286
+ function verifyRevocationList(signed, trustedKeys, options = {}) {
3287
+ const parsed = SignedRevocationListSchema.safeParse(signed);
3288
+ if (!parsed.success) return { ok: false, reason: "malformed" };
3289
+ const list = parsed.data.list;
3290
+ const nowMs = options.nowMs ?? Date.now();
3291
+ const pinned = trustedKeys.filter(
3292
+ (k) => k.issuerId === list.issuerId && (k.notBeforeMs === void 0 || nowMs >= k.notBeforeMs) && (k.notAfterMs === void 0 || nowMs <= k.notAfterMs)
3293
+ );
3294
+ if (pinned.length === 0) return { ok: false, reason: "untrusted_issuer" };
3295
+ const signingBytes = canonicalJSONBytes(revocationListSigningPayload(list));
3296
+ const signatureOk = pinned.some(
3297
+ (k) => verifyIssuerP256(signingBytes, parsed.data.issuerSig, k.publicKeySpkiB64)
3298
+ );
3299
+ if (!signatureOk) return { ok: false, reason: "signature_invalid" };
3300
+ if (list.notAfterMs !== void 0 && nowMs > list.notAfterMs) {
3301
+ return { ok: false, reason: "stale" };
3302
+ }
3303
+ return { ok: true, list, revokedOacIds: new Set(list.revokedOacIds) };
3304
+ }
3305
+ function isOacRevoked(oacId, revokedOacIds) {
3306
+ return revokedOacIds.has(oacId);
3307
+ }
3308
+
3309
+ // src/me-offline/client.ts
3310
+ var Sha256Hex = import_zod14.z.string().regex(/^[0-9a-f]{64}$/);
3311
+ var Base64Std4 = import_zod14.z.string().regex(/^[A-Za-z0-9+/]+={0,2}$/);
3312
+ var ClaimNonce = import_zod14.z.string().min(8).max(128).refine((value) => !value.includes("|"), {
3240
3313
  message: "nonce must not contain |"
3241
3314
  });
3242
3315
  var ACCOUNT_FUNDED_OAC_MAX_TTL_MS = 1e3 * 60 * 60 * 24;
3243
- var IssuerTrustKeySchema = import_zod13.z.object({
3244
- issuerId: import_zod13.z.string().min(1).max(128),
3245
- alg: import_zod13.z.literal("p256"),
3246
- publicKeySpkiB64: Base64Std3.min(64).max(4096),
3247
- notBeforeMs: import_zod13.z.number().int().nonnegative().optional(),
3248
- notAfterMs: import_zod13.z.number().int().positive().optional()
3316
+ var IssuerTrustKeySchema = import_zod14.z.object({
3317
+ issuerId: import_zod14.z.string().min(1).max(128),
3318
+ alg: import_zod14.z.literal("p256"),
3319
+ publicKeySpkiB64: Base64Std4.min(64).max(4096),
3320
+ notBeforeMs: import_zod14.z.number().int().nonnegative().optional(),
3321
+ notAfterMs: import_zod14.z.number().int().positive().optional()
3249
3322
  });
3250
- var IssuerTrustBundleSchema = import_zod13.z.object({
3251
- keys: import_zod13.z.array(IssuerTrustKeySchema).min(1)
3323
+ var IssuerTrustBundleSchema = import_zod14.z.object({
3324
+ keys: import_zod14.z.array(IssuerTrustKeySchema).min(1)
3252
3325
  });
3253
3326
  var CONSUMER_OFFLINE_CLAIM_SUBMIT_GRACE_MS = 1e3 * 60 * 60 * 24;
3254
- var AttestationSecurityLevelSchema = import_zod13.z.enum([
3327
+ var AttestationSecurityLevelSchema = import_zod14.z.enum([
3255
3328
  "STRONGBOX",
3256
3329
  "TEE",
3257
3330
  "SECURE_ENCLAVE",
3258
3331
  "SOFTWARE"
3259
3332
  ]);
3260
- var DeviceKeyAlgSchema = import_zod13.z.literal("p256");
3261
- var RegisterDeviceKeyP256InputSchema = import_zod13.z.object({
3262
- deviceId: import_zod13.z.string().min(1).max(128),
3333
+ var DeviceKeyAlgSchema = import_zod14.z.literal("p256");
3334
+ var RegisterDeviceKeyP256InputSchema = import_zod14.z.object({
3335
+ deviceId: import_zod14.z.string().min(1).max(128),
3263
3336
  /** P-256 SubjectPublicKeyInfo DER, base64. */
3264
- publicKeySpkiB64: Base64Std3.min(64).max(4096),
3337
+ publicKeySpkiB64: Base64Std4.min(64).max(4096),
3265
3338
  /** Base64 of the server-issued enrollment challenge string. */
3266
- challengeB64: Base64Std3.min(8).max(1024),
3339
+ challengeB64: Base64Std4.min(8).max(1024),
3267
3340
  /** iOS App Attest payload or Android X.509 Key Attestation chain. */
3268
- attestationChainB64: import_zod13.z.array(Base64Std3.min(16).max(16384)).min(1).max(16),
3341
+ attestationChainB64: import_zod14.z.array(Base64Std4.min(16).max(16384)).min(1).max(16),
3269
3342
  securityLevel: AttestationSecurityLevelSchema
3270
3343
  });
3271
- var P256EnrollmentChallengeInputSchema = import_zod13.z.object({
3272
- deviceId: import_zod13.z.string().min(1).max(128)
3344
+ var P256EnrollmentChallengeInputSchema = import_zod14.z.object({
3345
+ deviceId: import_zod14.z.string().min(1).max(128)
3273
3346
  });
3274
- var P256EnrollmentChallengeResultSchema = import_zod13.z.object({
3275
- challenge: import_zod13.z.string().min(16),
3276
- expiresAtMs: import_zod13.z.number().int().positive()
3347
+ var P256EnrollmentChallengeResultSchema = import_zod14.z.object({
3348
+ challenge: import_zod14.z.string().min(16),
3349
+ expiresAtMs: import_zod14.z.number().int().positive()
3277
3350
  });
3278
- var DeviceKeyRecordSchema = import_zod13.z.object({
3279
- id: import_zod13.z.string().uuid(),
3280
- userId: import_zod13.z.string().uuid(),
3281
- deviceId: import_zod13.z.string(),
3351
+ var DeviceKeyRecordSchema = import_zod14.z.object({
3352
+ id: import_zod14.z.string().uuid(),
3353
+ userId: import_zod14.z.string().uuid(),
3354
+ deviceId: import_zod14.z.string(),
3282
3355
  /** Always 'p256' on the consumer offline rail. Field retained for forward-compat. */
3283
3356
  alg: DeviceKeyAlgSchema.default("p256"),
3284
3357
  /** P-256 SubjectPublicKeyInfo DER, base64. */
3285
- publicKeySpkiB64: Base64Std3.nullable().default(null),
3358
+ publicKeySpkiB64: Base64Std4.nullable().default(null),
3286
3359
  securityLevel: AttestationSecurityLevelSchema.nullable().default(null),
3287
- hardwareBacked: import_zod13.z.boolean().default(false),
3288
- attestedAtMs: import_zod13.z.number().int().nonnegative().nullable().default(null),
3289
- createdAtMs: import_zod13.z.number().int().nonnegative(),
3290
- revokedAtMs: import_zod13.z.number().int().nonnegative().nullable()
3360
+ hardwareBacked: import_zod14.z.boolean().default(false),
3361
+ attestedAtMs: import_zod14.z.number().int().nonnegative().nullable().default(null),
3362
+ createdAtMs: import_zod14.z.number().int().nonnegative(),
3363
+ revokedAtMs: import_zod14.z.number().int().nonnegative().nullable()
3291
3364
  });
3292
- var ConsumerOACSchema = import_zod13.z.object({
3293
- oacId: import_zod13.z.string().uuid(),
3294
- issuerId: import_zod13.z.string().min(1).max(64),
3295
- userId: import_zod13.z.string().uuid(),
3296
- deviceId: import_zod13.z.string().min(1).max(128),
3365
+ var ConsumerOACSchema = import_zod14.z.object({
3366
+ oacId: import_zod14.z.string().uuid(),
3367
+ issuerId: import_zod14.z.string().min(1).max(64),
3368
+ userId: import_zod14.z.string().uuid(),
3369
+ deviceId: import_zod14.z.string().min(1).max(128),
3297
3370
  /**
3298
3371
  * Always 'p256'. Required on the wire (backend always emits it).
3299
3372
  * Kept as a literal so input/output infer identically and the schema
3300
3373
  * can be nested inside other response shapes without Zod input/output
3301
3374
  * divergence under tsup DTS bundling.
3302
3375
  */
3303
- alg: import_zod13.z.literal("p256"),
3376
+ alg: import_zod14.z.literal("p256"),
3304
3377
  /** P-256 SubjectPublicKeyInfo DER, base64. */
3305
- devicePubkeySpkiB64: Base64Std3.min(64).max(4096),
3378
+ devicePubkeySpkiB64: Base64Std4.min(64).max(4096),
3306
3379
  /**
3307
3380
  * Per-transaction / cumulative offline spend ceilings. Zero is valid and
3308
3381
  * denotes an identity-only OAC: the credential proves who the holder is and
@@ -3310,104 +3383,104 @@ var ConsumerOACSchema = import_zod13.z.object({
3310
3383
  * no offline spend authority (every claim against it routes to REVIEW).
3311
3384
  * Issued to zero-balance wallets so they can still be paid offline.
3312
3385
  */
3313
- perTxCapKobo: import_zod13.z.number().int().nonnegative(),
3314
- cumulativeCapKobo: import_zod13.z.number().int().nonnegative(),
3315
- currency: import_zod13.z.string().length(3),
3316
- validFromMs: import_zod13.z.number().int().nonnegative(),
3317
- validUntilMs: import_zod13.z.number().int().nonnegative(),
3318
- counterSeed: import_zod13.z.number().int().nonnegative(),
3319
- issuedAtMs: import_zod13.z.number().int().nonnegative(),
3386
+ perTxCapKobo: import_zod14.z.number().int().nonnegative(),
3387
+ cumulativeCapKobo: import_zod14.z.number().int().nonnegative(),
3388
+ currency: import_zod14.z.string().length(3),
3389
+ validFromMs: import_zod14.z.number().int().nonnegative(),
3390
+ validUntilMs: import_zod14.z.number().int().nonnegative(),
3391
+ counterSeed: import_zod14.z.number().int().nonnegative(),
3392
+ issuedAtMs: import_zod14.z.number().int().nonnegative(),
3320
3393
  /**
3321
3394
  * Issuer-attested identity folded into the OAC so a single signed
3322
3395
  * credential serves both Tier B offline-verifiable identity and offline
3323
3396
  * spend authority. Verified offline against a pinned issuer key; the
3324
3397
  * backend remains authoritative at settlement.
3325
3398
  */
3326
- phoneE164: import_zod13.z.string().regex(/^\+[1-9]\d{7,14}$/),
3327
- displayName: import_zod13.z.string().min(1).max(64)
3399
+ phoneE164: import_zod14.z.string().regex(/^\+[1-9]\d{7,14}$/),
3400
+ displayName: import_zod14.z.string().min(1).max(64)
3328
3401
  });
3329
- var SignedConsumerOACSchema = import_zod13.z.object({
3402
+ var SignedConsumerOACSchema = import_zod14.z.object({
3330
3403
  oac: ConsumerOACSchema,
3331
3404
  /** ASN.1 DER ECDSA P-256 issuer signature, base64. */
3332
- issuerSig: Base64Std3.min(16).max(2048),
3405
+ issuerSig: Base64Std4.min(16).max(2048),
3333
3406
  /** Issuer's P-256 public key as SubjectPublicKeyInfo DER, base64. */
3334
- issuerPublicKeySpkiB64: Base64Std3.min(64).max(4096)
3407
+ issuerPublicKeySpkiB64: Base64Std4.min(64).max(4096)
3335
3408
  });
3336
3409
  var OACRecordSchema = SignedConsumerOACSchema.extend({
3337
- currentOfflineSpentKobo: import_zod13.z.number().int().nonnegative(),
3338
- status: import_zod13.z.enum(["active", "superseded", "expired", "revoked"]),
3339
- supersededAtMs: import_zod13.z.number().int().nonnegative().nullable(),
3340
- revokedAtMs: import_zod13.z.number().int().nonnegative().nullable()
3410
+ currentOfflineSpentKobo: import_zod14.z.number().int().nonnegative(),
3411
+ status: import_zod14.z.enum(["active", "superseded", "expired", "revoked"]),
3412
+ supersededAtMs: import_zod14.z.number().int().nonnegative().nullable(),
3413
+ revokedAtMs: import_zod14.z.number().int().nonnegative().nullable()
3341
3414
  });
3342
- var IssueAccountOacInputSchema = import_zod13.z.object({
3343
- deviceId: import_zod13.z.string().min(1).max(128),
3344
- perTxCapKobo: import_zod13.z.number().int().positive().optional(),
3345
- cumulativeCapKobo: import_zod13.z.number().int().positive().optional(),
3346
- ttlMs: import_zod13.z.number().int().min(6e4).max(ACCOUNT_FUNDED_OAC_MAX_TTL_MS).optional()
3415
+ var IssueAccountOacInputSchema = import_zod14.z.object({
3416
+ deviceId: import_zod14.z.string().min(1).max(128),
3417
+ perTxCapKobo: import_zod14.z.number().int().positive().optional(),
3418
+ cumulativeCapKobo: import_zod14.z.number().int().positive().optional(),
3419
+ ttlMs: import_zod14.z.number().int().min(6e4).max(ACCOUNT_FUNDED_OAC_MAX_TTL_MS).optional()
3347
3420
  });
3348
- var OfflineStatusResultSchema = import_zod13.z.object({
3421
+ var OfflineStatusResultSchema = import_zod14.z.object({
3349
3422
  active: OACRecordSchema.nullable()
3350
3423
  });
3351
- var ConsumerPaymentClaimSchema = import_zod13.z.object({
3424
+ var ConsumerPaymentClaimSchema = import_zod14.z.object({
3352
3425
  /** Always 'p256'. Retained for forward-compat and as an explicit domain marker. */
3353
- alg: import_zod13.z.literal("p256").default("p256"),
3354
- oacId: import_zod13.z.string().uuid(),
3426
+ alg: import_zod14.z.literal("p256").default("p256"),
3427
+ oacId: import_zod14.z.string().uuid(),
3355
3428
  encounterId: Sha256Hex.optional(),
3356
- payerUserId: import_zod13.z.string().uuid(),
3357
- payeeUserId: import_zod13.z.string().uuid(),
3358
- payerDeviceId: import_zod13.z.string().min(1).max(128),
3429
+ payerUserId: import_zod14.z.string().uuid(),
3430
+ payeeUserId: import_zod14.z.string().uuid(),
3431
+ payerDeviceId: import_zod14.z.string().min(1).max(128),
3359
3432
  payerNonce: ClaimNonce,
3360
3433
  payeeNonce: ClaimNonce,
3361
- amountKobo: import_zod13.z.number().int().positive(),
3362
- currency: import_zod13.z.string().length(3).default("NGN"),
3363
- occurredAtMs: import_zod13.z.number().int().nonnegative(),
3364
- completedAtMs: import_zod13.z.number().int().nonnegative().optional(),
3365
- contextId: import_zod13.z.string().max(128).optional(),
3366
- requestId: import_zod13.z.string().uuid().optional(),
3367
- requestMode: import_zod13.z.enum(["fixed", "editable"]).optional(),
3368
- requestTakerUserId: import_zod13.z.string().uuid().optional(),
3369
- requestAmountKobo: import_zod13.z.number().int().positive().optional(),
3370
- requestCurrency: import_zod13.z.string().length(3).optional(),
3371
- requestReference: import_zod13.z.string().max(128).nullable().optional(),
3372
- requestCreatedAtMs: import_zod13.z.number().int().nonnegative().optional(),
3373
- requestExpiresAtMs: import_zod13.z.number().int().positive().optional(),
3374
- requestNonce: import_zod13.z.string().min(8).max(128).optional(),
3375
- requestTakerDeviceId: import_zod13.z.string().min(1).max(128).nullable().optional(),
3376
- requestTakerPubkeySpkiB64: Base64Std3.min(64).max(4096).optional(),
3377
- requestTakerSignatureDerB64: Base64Std3.min(16).max(2048).optional(),
3378
- payerPubkeySpkiB64: Base64Std3.min(64).max(4096),
3379
- payerSignatureDerB64: Base64Std3.min(16).max(2048),
3380
- payeePubkeySpkiB64: Base64Std3.min(64).max(4096).optional(),
3381
- payeeSignatureDerB64: Base64Std3.min(16).max(2048).optional()
3434
+ amountKobo: import_zod14.z.number().int().positive(),
3435
+ currency: import_zod14.z.string().length(3).default("NGN"),
3436
+ occurredAtMs: import_zod14.z.number().int().nonnegative(),
3437
+ completedAtMs: import_zod14.z.number().int().nonnegative().optional(),
3438
+ contextId: import_zod14.z.string().max(128).optional(),
3439
+ requestId: import_zod14.z.string().uuid().optional(),
3440
+ requestMode: import_zod14.z.enum(["fixed", "editable"]).optional(),
3441
+ requestTakerUserId: import_zod14.z.string().uuid().optional(),
3442
+ requestAmountKobo: import_zod14.z.number().int().positive().optional(),
3443
+ requestCurrency: import_zod14.z.string().length(3).optional(),
3444
+ requestReference: import_zod14.z.string().max(128).nullable().optional(),
3445
+ requestCreatedAtMs: import_zod14.z.number().int().nonnegative().optional(),
3446
+ requestExpiresAtMs: import_zod14.z.number().int().positive().optional(),
3447
+ requestNonce: import_zod14.z.string().min(8).max(128).optional(),
3448
+ requestTakerDeviceId: import_zod14.z.string().min(1).max(128).nullable().optional(),
3449
+ requestTakerPubkeySpkiB64: Base64Std4.min(64).max(4096).optional(),
3450
+ requestTakerSignatureDerB64: Base64Std4.min(16).max(2048).optional(),
3451
+ payerPubkeySpkiB64: Base64Std4.min(64).max(4096),
3452
+ payerSignatureDerB64: Base64Std4.min(16).max(2048),
3453
+ payeePubkeySpkiB64: Base64Std4.min(64).max(4096).optional(),
3454
+ payeeSignatureDerB64: Base64Std4.min(16).max(2048).optional()
3382
3455
  });
3383
- var ConsumerSettlementSchema = import_zod13.z.object({
3384
- settlementId: import_zod13.z.string().uuid(),
3456
+ var ConsumerSettlementSchema = import_zod14.z.object({
3457
+ settlementId: import_zod14.z.string().uuid(),
3385
3458
  settlementKey: Sha256Hex,
3386
3459
  encounterId: Sha256Hex,
3387
- oacId: import_zod13.z.string().uuid(),
3388
- payerUserId: import_zod13.z.string().uuid(),
3389
- payeeUserId: import_zod13.z.string().uuid(),
3390
- amountKobo: import_zod13.z.number().int().positive(),
3391
- currency: import_zod13.z.string().length(3),
3392
- status: import_zod13.z.enum(["SETTLED", "REVIEW"]),
3393
- reviewReason: import_zod13.z.string().nullable(),
3394
- ledgerRef: import_zod13.z.string().nullable(),
3460
+ oacId: import_zod14.z.string().uuid(),
3461
+ payerUserId: import_zod14.z.string().uuid(),
3462
+ payeeUserId: import_zod14.z.string().uuid(),
3463
+ amountKobo: import_zod14.z.number().int().positive(),
3464
+ currency: import_zod14.z.string().length(3),
3465
+ status: import_zod14.z.enum(["SETTLED", "REVIEW"]),
3466
+ reviewReason: import_zod14.z.string().nullable(),
3467
+ ledgerRef: import_zod14.z.string().nullable(),
3395
3468
  /** ASN.1 DER ECDSA P-256 issuer signature, base64. */
3396
- issuerSig: Base64Std3.min(16).max(2048),
3469
+ issuerSig: Base64Std4.min(16).max(2048),
3397
3470
  /** Canonical millisecond timestamp signed into the settlement receipt. */
3398
- issuedAtMs: import_zod13.z.number().int().nonnegative(),
3471
+ issuedAtMs: import_zod14.z.number().int().nonnegative(),
3399
3472
  /** Compatibility alias for API consumers that predate issuedAtMs. */
3400
- createdAtMs: import_zod13.z.number().int().nonnegative().optional()
3473
+ createdAtMs: import_zod14.z.number().int().nonnegative().optional()
3401
3474
  });
3402
- var ConsumerSettleResultSchema = import_zod13.z.object({
3475
+ var ConsumerSettleResultSchema = import_zod14.z.object({
3403
3476
  settlement: ConsumerSettlementSchema,
3404
3477
  encounterId: Sha256Hex,
3405
- replayed: import_zod13.z.boolean()
3478
+ replayed: import_zod14.z.boolean()
3406
3479
  });
3407
- var RevokeDeviceKeyInputSchema = import_zod13.z.object({
3408
- deviceId: import_zod13.z.string().min(1).max(128),
3480
+ var RevokeDeviceKeyInputSchema = import_zod14.z.object({
3481
+ deviceId: import_zod14.z.string().min(1).max(128),
3409
3482
  /** Step-up token from /api/v1/auth/send/verify with purpose='offline_revoke'. */
3410
- sendAuthToken: import_zod13.z.string().min(16)
3483
+ sendAuthToken: import_zod14.z.string().min(16)
3411
3484
  });
3412
3485
  function createMeOfflineClient(opts) {
3413
3486
  const fetchImpl = opts.fetchImpl ?? globalThis.fetch;
@@ -3440,7 +3513,7 @@ function createMeOfflineClient(opts) {
3440
3513
  }
3441
3514
  return parser(raw);
3442
3515
  }
3443
- const deviceKeyItems = import_zod13.z.object({ items: import_zod13.z.array(DeviceKeyRecordSchema) });
3516
+ const deviceKeyItems = import_zod14.z.object({ items: import_zod14.z.array(DeviceKeyRecordSchema) });
3444
3517
  return {
3445
3518
  issueP256EnrollmentChallenge: (input) => call(
3446
3519
  "POST",
@@ -3498,6 +3571,12 @@ function createMeOfflineClient(opts) {
3498
3571
  "/v1/issuer/keys",
3499
3572
  void 0,
3500
3573
  (raw) => IssuerTrustBundleSchema.parse(raw)
3574
+ ),
3575
+ getRevocations: () => call(
3576
+ "GET",
3577
+ "/v1/issuer/revocations",
3578
+ void 0,
3579
+ (raw) => SignedRevocationListSchema.parse(raw)
3501
3580
  )
3502
3581
  };
3503
3582
  }
@@ -3644,26 +3723,26 @@ function verifyClaimSignature(input) {
3644
3723
  }
3645
3724
 
3646
3725
  // src/me-offline/request.ts
3647
- var import_zod14 = require("zod");
3648
- var Base64Std4 = import_zod14.z.string().regex(/^[A-Za-z0-9+/]+={0,2}$/);
3726
+ var import_zod15 = require("zod");
3727
+ var Base64Std5 = import_zod15.z.string().regex(/^[A-Za-z0-9+/]+={0,2}$/);
3649
3728
  var CONSUMER_PAYMENT_REQUEST_DOMAIN = "flur:consumer-offline:v1:request";
3650
- var ConsumerPaymentRequestEnvelopeSchema = import_zod14.z.object({
3651
- requestId: import_zod14.z.string().uuid(),
3652
- mode: import_zod14.z.enum(["fixed", "editable"]),
3653
- takerUserId: import_zod14.z.string().uuid(),
3654
- amountKobo: import_zod14.z.number().int().positive(),
3655
- currency: import_zod14.z.string().length(3).default("NGN"),
3656
- reference: import_zod14.z.string().max(128).nullable().default(null),
3657
- createdAtMs: import_zod14.z.number().int().nonnegative(),
3658
- expiresAtMs: import_zod14.z.number().int().positive(),
3659
- nonce: import_zod14.z.string().min(8).max(128),
3660
- takerDeviceId: import_zod14.z.string().min(1).max(128).nullable().default(null),
3661
- takerPubkeySpkiB64: Base64Std4.min(64).max(4096).optional(),
3662
- takerSignatureDerB64: Base64Std4.min(16).max(2048).optional()
3729
+ var ConsumerPaymentRequestEnvelopeSchema = import_zod15.z.object({
3730
+ requestId: import_zod15.z.string().uuid(),
3731
+ mode: import_zod15.z.enum(["fixed", "editable"]),
3732
+ takerUserId: import_zod15.z.string().uuid(),
3733
+ amountKobo: import_zod15.z.number().int().positive(),
3734
+ currency: import_zod15.z.string().length(3).default("NGN"),
3735
+ reference: import_zod15.z.string().max(128).nullable().default(null),
3736
+ createdAtMs: import_zod15.z.number().int().nonnegative(),
3737
+ expiresAtMs: import_zod15.z.number().int().positive(),
3738
+ nonce: import_zod15.z.string().min(8).max(128),
3739
+ takerDeviceId: import_zod15.z.string().min(1).max(128).nullable().default(null),
3740
+ takerPubkeySpkiB64: Base64Std5.min(64).max(4096).optional(),
3741
+ takerSignatureDerB64: Base64Std5.min(16).max(2048).optional()
3663
3742
  }).superRefine((value, ctx) => {
3664
3743
  if (value.expiresAtMs <= value.createdAtMs) {
3665
3744
  ctx.addIssue({
3666
- code: import_zod14.z.ZodIssueCode.custom,
3745
+ code: import_zod15.z.ZodIssueCode.custom,
3667
3746
  path: ["expiresAtMs"],
3668
3747
  message: "expiresAtMs must be greater than createdAtMs"
3669
3748
  });
@@ -3674,21 +3753,21 @@ var ConsumerPaymentRequestEnvelopeSchema = import_zod14.z.object({
3674
3753
  if (value.mode === "fixed" || hasSignature) {
3675
3754
  if (!value.takerDeviceId) {
3676
3755
  ctx.addIssue({
3677
- code: import_zod14.z.ZodIssueCode.custom,
3756
+ code: import_zod15.z.ZodIssueCode.custom,
3678
3757
  path: ["takerDeviceId"],
3679
3758
  message: "signed requests require takerDeviceId"
3680
3759
  });
3681
3760
  }
3682
3761
  if (!value.takerPubkeySpkiB64) {
3683
3762
  ctx.addIssue({
3684
- code: import_zod14.z.ZodIssueCode.custom,
3763
+ code: import_zod15.z.ZodIssueCode.custom,
3685
3764
  path: ["takerPubkeySpkiB64"],
3686
3765
  message: "signed requests require takerPubkeySpkiB64"
3687
3766
  });
3688
3767
  }
3689
3768
  if (!value.takerSignatureDerB64) {
3690
3769
  ctx.addIssue({
3691
- code: import_zod14.z.ZodIssueCode.custom,
3770
+ code: import_zod15.z.ZodIssueCode.custom,
3692
3771
  path: ["takerSignatureDerB64"],
3693
3772
  message: "signed requests require takerSignatureDerB64"
3694
3773
  });
@@ -3859,7 +3938,7 @@ function base64UrlDecodeUtf8(input) {
3859
3938
  }
3860
3939
 
3861
3940
  // src/me-offline/oac.ts
3862
- var import_zod15 = require("zod");
3941
+ var import_zod16 = require("zod");
3863
3942
  var CONSUMER_OAC_DOMAIN = "flur:consumer-offline:v1:oac";
3864
3943
  function consumerOacSigningPayload(oac) {
3865
3944
  return { domain: CONSUMER_OAC_DOMAIN, ...oac };
@@ -3885,6 +3964,9 @@ function verifyOacOffline(signed, trustedKeys, options = {}) {
3885
3964
  }
3886
3965
  if (nowMs < oac.validFromMs) return { ok: false, reason: "not_yet_valid" };
3887
3966
  if (nowMs >= oac.validUntilMs) return { ok: false, reason: "expired" };
3967
+ if (options.revokedOacIds?.has(oac.oacId)) {
3968
+ return { ok: false, reason: "revoked" };
3969
+ }
3888
3970
  return {
3889
3971
  ok: true,
3890
3972
  oac,
@@ -3902,13 +3984,13 @@ var CONSUMER_OAC_QR_PREFIX = "FLUROAC1.";
3902
3984
  function isConsumerOacQR(value) {
3903
3985
  return value.startsWith(CONSUMER_OAC_QR_PREFIX);
3904
3986
  }
3905
- var OacPresentmentRequestSchema = import_zod15.z.object({
3987
+ var OacPresentmentRequestSchema = import_zod16.z.object({
3906
3988
  /** Requested amount in minor units (kobo). */
3907
- amountMinor: import_zod15.z.number().int().positive().max(1e12).optional(),
3989
+ amountMinor: import_zod16.z.number().int().positive().max(1e12).optional(),
3908
3990
  /** Purpose/intent code (mirrors the NIBSS intent vocabulary). */
3909
- intent: import_zod15.z.string().min(1).max(32).optional(),
3991
+ intent: import_zod16.z.string().min(1).max(32).optional(),
3910
3992
  /** Free-text reference / note. */
3911
- reference: import_zod15.z.string().min(1).max(64).optional()
3993
+ reference: import_zod16.z.string().min(1).max(64).optional()
3912
3994
  }).strict();
3913
3995
  function encodeConsumerOacQR(signed, request) {
3914
3996
  const parsed = SignedConsumerOACSchema.parse(signed);
@@ -4242,14 +4324,14 @@ function base64UrlToBytes(input) {
4242
4324
  }
4243
4325
 
4244
4326
  // src/partner-funding/client.ts
4245
- var import_zod16 = require("zod");
4246
- var MinorString = import_zod16.z.string().regex(/^-?\d+$/);
4247
- var PositiveMinor = import_zod16.z.union([
4248
- import_zod16.z.number().int().positive(),
4249
- import_zod16.z.string().regex(/^[1-9]\d{0,18}$/)
4327
+ var import_zod17 = require("zod");
4328
+ var MinorString = import_zod17.z.string().regex(/^-?\d+$/);
4329
+ var PositiveMinor = import_zod17.z.union([
4330
+ import_zod17.z.number().int().positive(),
4331
+ import_zod17.z.string().regex(/^[1-9]\d{0,18}$/)
4250
4332
  ]);
4251
- var Currency = import_zod16.z.string().trim().length(3).transform((v) => v.toUpperCase());
4252
- var Metadata = import_zod16.z.record(import_zod16.z.unknown());
4333
+ var Currency = import_zod17.z.string().trim().length(3).transform((v) => v.toUpperCase());
4334
+ var Metadata = import_zod17.z.record(import_zod17.z.unknown());
4253
4335
  var PARTNER_KINDS = ["bank", "merchant"];
4254
4336
  var CUSTODIAL_MODES = ["agent_of_bank", "flur_virtual_pool"];
4255
4337
  var PARTNER_PROFILE_STATUSES = [
@@ -4276,126 +4358,126 @@ var WITHDRAWAL_STATES = [
4276
4358
  "failed",
4277
4359
  "reversed"
4278
4360
  ];
4279
- var PartnerProfileSchema = import_zod16.z.object({
4280
- partnerAccountId: import_zod16.z.string().uuid(),
4281
- kind: import_zod16.z.enum(PARTNER_KINDS),
4282
- custodialMode: import_zod16.z.enum(CUSTODIAL_MODES),
4283
- displayName: import_zod16.z.string(),
4284
- bankCode: import_zod16.z.string().nullable(),
4285
- poolAccountNumber: import_zod16.z.string().nullable(),
4286
- status: import_zod16.z.enum(PARTNER_PROFILE_STATUSES),
4361
+ var PartnerProfileSchema = import_zod17.z.object({
4362
+ partnerAccountId: import_zod17.z.string().uuid(),
4363
+ kind: import_zod17.z.enum(PARTNER_KINDS),
4364
+ custodialMode: import_zod17.z.enum(CUSTODIAL_MODES),
4365
+ displayName: import_zod17.z.string(),
4366
+ bankCode: import_zod17.z.string().nullable(),
4367
+ poolAccountNumber: import_zod17.z.string().nullable(),
4368
+ status: import_zod17.z.enum(PARTNER_PROFILE_STATUSES),
4287
4369
  metadata: Metadata,
4288
- createdAtMs: import_zod16.z.number().int().nonnegative(),
4289
- updatedAtMs: import_zod16.z.number().int().nonnegative()
4370
+ createdAtMs: import_zod17.z.number().int().nonnegative(),
4371
+ updatedAtMs: import_zod17.z.number().int().nonnegative()
4290
4372
  });
4291
- var UpsertPartnerProfileInputSchema = import_zod16.z.object({
4292
- kind: import_zod16.z.enum(PARTNER_KINDS),
4293
- custodialMode: import_zod16.z.enum(CUSTODIAL_MODES),
4294
- displayName: import_zod16.z.string().trim().min(1).max(200),
4295
- bankCode: import_zod16.z.string().trim().min(1).max(64).optional(),
4296
- poolAccountNumber: import_zod16.z.string().trim().min(1).max(64).optional(),
4373
+ var UpsertPartnerProfileInputSchema = import_zod17.z.object({
4374
+ kind: import_zod17.z.enum(PARTNER_KINDS),
4375
+ custodialMode: import_zod17.z.enum(CUSTODIAL_MODES),
4376
+ displayName: import_zod17.z.string().trim().min(1).max(200),
4377
+ bankCode: import_zod17.z.string().trim().min(1).max(64).optional(),
4378
+ poolAccountNumber: import_zod17.z.string().trim().min(1).max(64).optional(),
4297
4379
  metadata: Metadata.optional()
4298
4380
  });
4299
- var PartnerFundingEventInputSchema = import_zod16.z.object({
4300
- externalRef: import_zod16.z.string().trim().min(8).max(128),
4301
- direction: import_zod16.z.enum(PARTNER_FUNDING_DIRECTIONS).optional(),
4302
- userId: import_zod16.z.string().uuid().optional(),
4303
- accountId: import_zod16.z.string().uuid().optional(),
4381
+ var PartnerFundingEventInputSchema = import_zod17.z.object({
4382
+ externalRef: import_zod17.z.string().trim().min(8).max(128),
4383
+ direction: import_zod17.z.enum(PARTNER_FUNDING_DIRECTIONS).optional(),
4384
+ userId: import_zod17.z.string().uuid().optional(),
4385
+ accountId: import_zod17.z.string().uuid().optional(),
4304
4386
  amountMinor: PositiveMinor,
4305
4387
  currency: Currency,
4306
- fundingSource: import_zod16.z.string().trim().min(1).max(64).optional(),
4388
+ fundingSource: import_zod17.z.string().trim().min(1).max(64).optional(),
4307
4389
  providerMetadata: Metadata.optional()
4308
4390
  });
4309
- var PartnerFundingSchema = import_zod16.z.object({
4310
- fundingId: import_zod16.z.string().uuid(),
4311
- partnerId: import_zod16.z.string().uuid(),
4312
- accountId: import_zod16.z.string().uuid(),
4313
- userId: import_zod16.z.string().uuid().nullable(),
4314
- direction: import_zod16.z.enum(PARTNER_FUNDING_DIRECTIONS),
4315
- currency: import_zod16.z.string(),
4391
+ var PartnerFundingSchema = import_zod17.z.object({
4392
+ fundingId: import_zod17.z.string().uuid(),
4393
+ partnerId: import_zod17.z.string().uuid(),
4394
+ accountId: import_zod17.z.string().uuid(),
4395
+ userId: import_zod17.z.string().uuid().nullable(),
4396
+ direction: import_zod17.z.enum(PARTNER_FUNDING_DIRECTIONS),
4397
+ currency: import_zod17.z.string(),
4316
4398
  amountMinor: MinorString,
4317
- externalRef: import_zod16.z.string(),
4318
- status: import_zod16.z.enum(PARTNER_FUNDING_STATUSES),
4319
- fundingSource: import_zod16.z.string(),
4320
- ledgerRef: import_zod16.z.string(),
4399
+ externalRef: import_zod17.z.string(),
4400
+ status: import_zod17.z.enum(PARTNER_FUNDING_STATUSES),
4401
+ fundingSource: import_zod17.z.string(),
4402
+ ledgerRef: import_zod17.z.string(),
4321
4403
  providerMetadata: Metadata,
4322
- createdAtMs: import_zod16.z.number().int().nonnegative(),
4323
- updatedAtMs: import_zod16.z.number().int().nonnegative()
4404
+ createdAtMs: import_zod17.z.number().int().nonnegative(),
4405
+ updatedAtMs: import_zod17.z.number().int().nonnegative()
4324
4406
  });
4325
- var IngestFundingResultSchema = import_zod16.z.object({
4407
+ var IngestFundingResultSchema = import_zod17.z.object({
4326
4408
  funding: PartnerFundingSchema,
4327
- replayed: import_zod16.z.boolean()
4409
+ replayed: import_zod17.z.boolean()
4328
4410
  });
4329
- var PayoutDestinationSchema = import_zod16.z.object({
4330
- destinationId: import_zod16.z.string().uuid(),
4331
- accountId: import_zod16.z.string().uuid(),
4332
- partnerId: import_zod16.z.string().uuid(),
4333
- bankCode: import_zod16.z.string(),
4334
- accountNumber: import_zod16.z.string(),
4335
- accountName: import_zod16.z.string(),
4336
- status: import_zod16.z.enum(PAYOUT_DESTINATION_STATUSES),
4337
- verifiedAtMs: import_zod16.z.number().int().nonnegative().nullable(),
4411
+ var PayoutDestinationSchema = import_zod17.z.object({
4412
+ destinationId: import_zod17.z.string().uuid(),
4413
+ accountId: import_zod17.z.string().uuid(),
4414
+ partnerId: import_zod17.z.string().uuid(),
4415
+ bankCode: import_zod17.z.string(),
4416
+ accountNumber: import_zod17.z.string(),
4417
+ accountName: import_zod17.z.string(),
4418
+ status: import_zod17.z.enum(PAYOUT_DESTINATION_STATUSES),
4419
+ verifiedAtMs: import_zod17.z.number().int().nonnegative().nullable(),
4338
4420
  metadata: Metadata,
4339
- createdAtMs: import_zod16.z.number().int().nonnegative(),
4340
- updatedAtMs: import_zod16.z.number().int().nonnegative()
4421
+ createdAtMs: import_zod17.z.number().int().nonnegative(),
4422
+ updatedAtMs: import_zod17.z.number().int().nonnegative()
4341
4423
  });
4342
- var CreatePayoutDestinationInputSchema = import_zod16.z.object({
4343
- partnerId: import_zod16.z.string().uuid(),
4344
- bankCode: import_zod16.z.string().trim().min(1).max(32),
4345
- accountNumber: import_zod16.z.string().trim().min(4).max(64),
4346
- accountName: import_zod16.z.string().trim().min(1).max(200),
4424
+ var CreatePayoutDestinationInputSchema = import_zod17.z.object({
4425
+ partnerId: import_zod17.z.string().uuid(),
4426
+ bankCode: import_zod17.z.string().trim().min(1).max(32),
4427
+ accountNumber: import_zod17.z.string().trim().min(4).max(64),
4428
+ accountName: import_zod17.z.string().trim().min(1).max(200),
4347
4429
  metadata: Metadata.optional()
4348
4430
  });
4349
- var ListPayoutDestinationsResultSchema = import_zod16.z.object({
4350
- items: import_zod16.z.array(PayoutDestinationSchema)
4431
+ var ListPayoutDestinationsResultSchema = import_zod17.z.object({
4432
+ items: import_zod17.z.array(PayoutDestinationSchema)
4351
4433
  });
4352
- var WithdrawalSchema = import_zod16.z.object({
4353
- withdrawalId: import_zod16.z.string().uuid(),
4354
- accountId: import_zod16.z.string().uuid(),
4355
- userId: import_zod16.z.string().uuid(),
4356
- partnerId: import_zod16.z.string().uuid(),
4357
- destinationId: import_zod16.z.string().uuid(),
4358
- currency: import_zod16.z.string(),
4434
+ var WithdrawalSchema = import_zod17.z.object({
4435
+ withdrawalId: import_zod17.z.string().uuid(),
4436
+ accountId: import_zod17.z.string().uuid(),
4437
+ userId: import_zod17.z.string().uuid(),
4438
+ partnerId: import_zod17.z.string().uuid(),
4439
+ destinationId: import_zod17.z.string().uuid(),
4440
+ currency: import_zod17.z.string(),
4359
4441
  amountMinor: MinorString,
4360
- state: import_zod16.z.enum(WITHDRAWAL_STATES),
4361
- idempotencyKey: import_zod16.z.string(),
4362
- providerRef: import_zod16.z.string().nullable(),
4363
- lastError: import_zod16.z.string().nullable(),
4364
- ledgerRef: import_zod16.z.string(),
4365
- reverseLedgerRef: import_zod16.z.string().nullable(),
4442
+ state: import_zod17.z.enum(WITHDRAWAL_STATES),
4443
+ idempotencyKey: import_zod17.z.string(),
4444
+ providerRef: import_zod17.z.string().nullable(),
4445
+ lastError: import_zod17.z.string().nullable(),
4446
+ ledgerRef: import_zod17.z.string(),
4447
+ reverseLedgerRef: import_zod17.z.string().nullable(),
4366
4448
  metadata: Metadata,
4367
- createdAtMs: import_zod16.z.number().int().nonnegative(),
4368
- updatedAtMs: import_zod16.z.number().int().nonnegative()
4449
+ createdAtMs: import_zod17.z.number().int().nonnegative(),
4450
+ updatedAtMs: import_zod17.z.number().int().nonnegative()
4369
4451
  });
4370
- var CreateWithdrawalInputSchema = import_zod16.z.object({
4371
- destinationId: import_zod16.z.string().uuid(),
4452
+ var CreateWithdrawalInputSchema = import_zod17.z.object({
4453
+ destinationId: import_zod17.z.string().uuid(),
4372
4454
  amountMinor: PositiveMinor,
4373
4455
  currency: Currency,
4374
- idempotencyKey: import_zod16.z.string().trim().min(8).max(128),
4456
+ idempotencyKey: import_zod17.z.string().trim().min(8).max(128),
4375
4457
  metadata: Metadata.optional()
4376
4458
  });
4377
- var CreateWithdrawalResultSchema = import_zod16.z.object({
4459
+ var CreateWithdrawalResultSchema = import_zod17.z.object({
4378
4460
  withdrawal: WithdrawalSchema,
4379
- replayed: import_zod16.z.boolean()
4461
+ replayed: import_zod17.z.boolean()
4380
4462
  });
4381
- var PayoutEventInputSchema = import_zod16.z.object({
4382
- externalRef: import_zod16.z.string().trim().min(8).max(128),
4383
- withdrawalId: import_zod16.z.string().uuid().optional(),
4384
- state: import_zod16.z.enum(["submitted", "processing", "paid", "failed"]),
4385
- providerRef: import_zod16.z.string().trim().min(1).max(128).optional(),
4386
- failureCode: import_zod16.z.string().trim().max(64).optional(),
4387
- failureMessage: import_zod16.z.string().trim().max(512).optional(),
4463
+ var PayoutEventInputSchema = import_zod17.z.object({
4464
+ externalRef: import_zod17.z.string().trim().min(8).max(128),
4465
+ withdrawalId: import_zod17.z.string().uuid().optional(),
4466
+ state: import_zod17.z.enum(["submitted", "processing", "paid", "failed"]),
4467
+ providerRef: import_zod17.z.string().trim().min(1).max(128).optional(),
4468
+ failureCode: import_zod17.z.string().trim().max(64).optional(),
4469
+ failureMessage: import_zod17.z.string().trim().max(512).optional(),
4388
4470
  providerMetadata: Metadata.optional()
4389
4471
  });
4390
- var RecordPayoutEventResultSchema = import_zod16.z.object({
4472
+ var RecordPayoutEventResultSchema = import_zod17.z.object({
4391
4473
  withdrawal: WithdrawalSchema,
4392
- replayed: import_zod16.z.boolean()
4474
+ replayed: import_zod17.z.boolean()
4393
4475
  });
4394
- var ReconciliationReportSchema = import_zod16.z.object({
4395
- partnerId: import_zod16.z.string().uuid(),
4396
- currency: import_zod16.z.string(),
4397
- fromMs: import_zod16.z.number().int().nonnegative(),
4398
- toMs: import_zod16.z.number().int().nonnegative(),
4476
+ var ReconciliationReportSchema = import_zod17.z.object({
4477
+ partnerId: import_zod17.z.string().uuid(),
4478
+ currency: import_zod17.z.string(),
4479
+ fromMs: import_zod17.z.number().int().nonnegative(),
4480
+ toMs: import_zod17.z.number().int().nonnegative(),
4399
4481
  fundingsCreditMinor: MinorString,
4400
4482
  fundingsDebitMinor: MinorString,
4401
4483
  withdrawalsPaidMinor: MinorString,
@@ -4404,7 +4486,7 @@ var ReconciliationReportSchema = import_zod16.z.object({
4404
4486
  expectedReserveBalanceMinor: MinorString,
4405
4487
  actualReserveBalanceMinor: MinorString,
4406
4488
  imbalanceMinor: MinorString,
4407
- generatedAtMs: import_zod16.z.number().int().nonnegative()
4489
+ generatedAtMs: import_zod17.z.number().int().nonnegative()
4408
4490
  });
4409
4491
  function createPartnerFundingClient(partner) {
4410
4492
  return {
@@ -4556,19 +4638,19 @@ function createPartnerProfileAdminClient(opts) {
4556
4638
  }
4557
4639
 
4558
4640
  // src/artifacts/envelope.ts
4559
- var import_zod17 = require("zod");
4641
+ var import_zod18 = require("zod");
4560
4642
  var FLUR_ARTIFACT_URI_SCHEME = "flur";
4561
4643
  var FLUR_ARTIFACT_VERSION = 1;
4562
4644
  var FLUR_ARTIFACT_URI_PREFIX = `${FLUR_ARTIFACT_URI_SCHEME}://v${FLUR_ARTIFACT_VERSION}/`;
4563
4645
  var ArtifactTypeRe = /^[a-z][a-z0-9_]{1,63}$/;
4564
- var ArtifactHeaderSchema = import_zod17.z.object({
4565
- v: import_zod17.z.literal(FLUR_ARTIFACT_VERSION),
4566
- t: import_zod17.z.string().regex(ArtifactTypeRe, "invalid artifact type"),
4567
- iss: import_zod17.z.string().min(1).max(128),
4568
- kid: import_zod17.z.string().min(1).max(128),
4569
- iat: import_zod17.z.number().int().nonnegative(),
4570
- exp: import_zod17.z.number().int().positive().optional(),
4571
- nonce: import_zod17.z.string().min(8).max(64).regex(/^[A-Za-z0-9_-]+$/, "nonce must be url-safe")
4646
+ var ArtifactHeaderSchema = import_zod18.z.object({
4647
+ v: import_zod18.z.literal(FLUR_ARTIFACT_VERSION),
4648
+ t: import_zod18.z.string().regex(ArtifactTypeRe, "invalid artifact type"),
4649
+ iss: import_zod18.z.string().min(1).max(128),
4650
+ kid: import_zod18.z.string().min(1).max(128),
4651
+ iat: import_zod18.z.number().int().nonnegative(),
4652
+ exp: import_zod18.z.number().int().positive().optional(),
4653
+ nonce: import_zod18.z.string().min(8).max(64).regex(/^[A-Za-z0-9_-]+$/, "nonce must be url-safe")
4572
4654
  });
4573
4655
  var FlurArtifactError = class extends Error {
4574
4656
  constructor(message, code) {
@@ -4707,7 +4789,7 @@ function verifyArtifactSignature(decoded, publicKeySpkiB64, options = {}) {
4707
4789
  }
4708
4790
 
4709
4791
  // src/artifacts/types.ts
4710
- var import_zod18 = require("zod");
4792
+ var import_zod19 = require("zod");
4711
4793
  var ARTIFACT_TYPES = {
4712
4794
  OFFLINE_PAYMENT_AUTHORIZATION: "offline_payment_authorization",
4713
4795
  RECEIPT: "receipt",
@@ -4722,32 +4804,32 @@ var ARTIFACT_TYPES = {
4722
4804
  PASS: "pass",
4723
4805
  IDENTITY: "identity"
4724
4806
  };
4725
- var HexString = (length) => import_zod18.z.string().regex(
4807
+ var HexString = (length) => import_zod19.z.string().regex(
4726
4808
  new RegExp(`^[0-9a-fA-F]{${length * 2}}$`),
4727
4809
  `expected ${length}-byte hex string`
4728
4810
  );
4729
- var OfflinePaymentAuthorizationArtifactSchema = import_zod18.z.object({
4811
+ var OfflinePaymentAuthorizationArtifactSchema = import_zod19.z.object({
4730
4812
  authorization: OfflinePaymentAuthorizationSchema
4731
4813
  });
4732
- var ReceiptArtifactSchema = import_zod18.z.object({
4733
- receiptId: import_zod18.z.string().min(1).max(64),
4734
- paymentReference: import_zod18.z.string().min(1).max(64),
4735
- payerUserId: import_zod18.z.string().min(1).max(64).optional(),
4736
- payeeUserId: import_zod18.z.string().min(1).max(64),
4737
- amountKobo: import_zod18.z.number().int().positive(),
4738
- currency: import_zod18.z.literal("NGN"),
4739
- channel: import_zod18.z.enum(["online", "offline_reconciled", "pay_link", "nqr"]),
4740
- settledAtMs: import_zod18.z.number().int().positive(),
4741
- ledgerTxnId: import_zod18.z.string().min(1).max(64).optional(),
4742
- memo: import_zod18.z.string().max(140).optional(),
4814
+ var ReceiptArtifactSchema = import_zod19.z.object({
4815
+ receiptId: import_zod19.z.string().min(1).max(64),
4816
+ paymentReference: import_zod19.z.string().min(1).max(64),
4817
+ payerUserId: import_zod19.z.string().min(1).max(64).optional(),
4818
+ payeeUserId: import_zod19.z.string().min(1).max(64),
4819
+ amountKobo: import_zod19.z.number().int().positive(),
4820
+ currency: import_zod19.z.literal("NGN"),
4821
+ channel: import_zod19.z.enum(["online", "offline_reconciled", "pay_link", "nqr"]),
4822
+ settledAtMs: import_zod19.z.number().int().positive(),
4823
+ ledgerTxnId: import_zod19.z.string().min(1).max(64).optional(),
4824
+ memo: import_zod19.z.string().max(140).optional(),
4743
4825
  hashChainPrev: HexString(32).optional()
4744
4826
  });
4745
- var ShortId = import_zod18.z.string().min(1).max(64);
4746
- var PositiveInt = import_zod18.z.number().int().positive();
4747
- var NonNegativeInt = import_zod18.z.number().int().nonnegative();
4748
- var Currency2 = import_zod18.z.literal("NGN");
4749
- var Memo = import_zod18.z.string().max(140);
4750
- var NqrPaymentRequestArtifactSchema = import_zod18.z.object({
4827
+ var ShortId = import_zod19.z.string().min(1).max(64);
4828
+ var PositiveInt = import_zod19.z.number().int().positive();
4829
+ var NonNegativeInt = import_zod19.z.number().int().nonnegative();
4830
+ var Currency2 = import_zod19.z.literal("NGN");
4831
+ var Memo = import_zod19.z.string().max(140);
4832
+ var NqrPaymentRequestArtifactSchema = import_zod19.z.object({
4751
4833
  requestId: ShortId,
4752
4834
  payeeUserId: ShortId,
4753
4835
  amountKobo: PositiveInt.optional(),
@@ -4755,7 +4837,7 @@ var NqrPaymentRequestArtifactSchema = import_zod18.z.object({
4755
4837
  memo: Memo.optional(),
4756
4838
  expiresAtMs: PositiveInt.optional()
4757
4839
  });
4758
- var PaymentIntentArtifactSchema = import_zod18.z.object({
4840
+ var PaymentIntentArtifactSchema = import_zod19.z.object({
4759
4841
  intentId: ShortId,
4760
4842
  payerUserId: ShortId,
4761
4843
  payeeUserId: ShortId,
@@ -4764,7 +4846,7 @@ var PaymentIntentArtifactSchema = import_zod18.z.object({
4764
4846
  idempotencyKey: ShortId,
4765
4847
  createdAtMs: PositiveInt
4766
4848
  });
4767
- var OfflineClaimArtifactSchema = import_zod18.z.object({
4849
+ var OfflineClaimArtifactSchema = import_zod19.z.object({
4768
4850
  claimId: ShortId,
4769
4851
  authorizationId: ShortId,
4770
4852
  payeeUserId: ShortId,
@@ -4773,10 +4855,10 @@ var OfflineClaimArtifactSchema = import_zod18.z.object({
4773
4855
  claimedAtMs: PositiveInt,
4774
4856
  paymentReference: ShortId.optional()
4775
4857
  });
4776
- var SettlementRecordArtifactSchema = import_zod18.z.object({
4858
+ var SettlementRecordArtifactSchema = import_zod19.z.object({
4777
4859
  settlementId: ShortId,
4778
4860
  ledgerTxnId: ShortId,
4779
- sourceRefType: import_zod18.z.enum([
4861
+ sourceRefType: import_zod19.z.enum([
4780
4862
  "offline_authorization",
4781
4863
  "offline_claim",
4782
4864
  "transfer",
@@ -4787,12 +4869,12 @@ var SettlementRecordArtifactSchema = import_zod18.z.object({
4787
4869
  currency: Currency2,
4788
4870
  settledAtMs: PositiveInt
4789
4871
  });
4790
- var ReversalRecordArtifactSchema = import_zod18.z.object({
4872
+ var ReversalRecordArtifactSchema = import_zod19.z.object({
4791
4873
  reversalId: ShortId,
4792
4874
  originalTxnId: ShortId,
4793
4875
  amountKobo: PositiveInt,
4794
4876
  currency: Currency2,
4795
- reason: import_zod18.z.enum([
4877
+ reason: import_zod19.z.enum([
4796
4878
  "user_dispute",
4797
4879
  "fraud",
4798
4880
  "duplicate",
@@ -4802,7 +4884,7 @@ var ReversalRecordArtifactSchema = import_zod18.z.object({
4802
4884
  reversedAtMs: PositiveInt,
4803
4885
  memo: Memo.optional()
4804
4886
  });
4805
- var LedgerJournalEntryArtifactSchema = import_zod18.z.object({
4887
+ var LedgerJournalEntryArtifactSchema = import_zod19.z.object({
4806
4888
  entryId: ShortId,
4807
4889
  journalId: ShortId,
4808
4890
  debitAccountId: ShortId,
@@ -4813,13 +4895,13 @@ var LedgerJournalEntryArtifactSchema = import_zod18.z.object({
4813
4895
  refType: ShortId.optional(),
4814
4896
  refId: ShortId.optional()
4815
4897
  });
4816
- var StatementArtifactSchema = import_zod18.z.object({
4898
+ var StatementArtifactSchema = import_zod19.z.object({
4817
4899
  statementId: ShortId,
4818
4900
  userId: ShortId,
4819
4901
  periodStartMs: PositiveInt,
4820
4902
  periodEndMs: PositiveInt,
4821
- openingBalanceKobo: import_zod18.z.number().int(),
4822
- closingBalanceKobo: import_zod18.z.number().int(),
4903
+ openingBalanceKobo: import_zod19.z.number().int(),
4904
+ closingBalanceKobo: import_zod19.z.number().int(),
4823
4905
  transactionCount: NonNegativeInt,
4824
4906
  currency: Currency2,
4825
4907
  hashChainPrev: HexString(32).optional()
@@ -4827,16 +4909,16 @@ var StatementArtifactSchema = import_zod18.z.object({
4827
4909
  message: "periodEndMs must be greater than periodStartMs",
4828
4910
  path: ["periodEndMs"]
4829
4911
  });
4830
- var PassArtifactSchema = import_zod18.z.object({
4912
+ var PassArtifactSchema = import_zod19.z.object({
4831
4913
  passId: ShortId,
4832
4914
  holderId: ShortId,
4833
- category: import_zod18.z.enum(["membership", "ticket", "loyalty", "access", "voucher"]),
4834
- title: import_zod18.z.string().min(1).max(120),
4915
+ category: import_zod19.z.enum(["membership", "ticket", "loyalty", "access", "voucher"]),
4916
+ title: import_zod19.z.string().min(1).max(120),
4835
4917
  validFromMs: PositiveInt,
4836
4918
  validUntilMs: PositiveInt.optional(),
4837
- metadata: import_zod18.z.record(
4838
- import_zod18.z.string().min(1).max(64),
4839
- import_zod18.z.union([import_zod18.z.string().max(280), import_zod18.z.number(), import_zod18.z.boolean()])
4919
+ metadata: import_zod19.z.record(
4920
+ import_zod19.z.string().min(1).max(64),
4921
+ import_zod19.z.union([import_zod19.z.string().max(280), import_zod19.z.number(), import_zod19.z.boolean()])
4840
4922
  ).optional()
4841
4923
  }).refine(
4842
4924
  (v) => v.validUntilMs === void 0 || v.validUntilMs > v.validFromMs,
@@ -4845,10 +4927,10 @@ var PassArtifactSchema = import_zod18.z.object({
4845
4927
  path: ["validUntilMs"]
4846
4928
  }
4847
4929
  );
4848
- var IdentityArtifactSchema = import_zod18.z.object({
4930
+ var IdentityArtifactSchema = import_zod19.z.object({
4849
4931
  attestationId: ShortId,
4850
4932
  subjectId: ShortId,
4851
- claimType: import_zod18.z.enum([
4933
+ claimType: import_zod19.z.enum([
4852
4934
  "phone_verified",
4853
4935
  "email_verified",
4854
4936
  "bvn_verified",
@@ -4987,6 +5069,7 @@ function createOfflinePaymentAuthorizationArtifactUri(input) {
4987
5069
  CONSUMER_OAC_QR_PREFIX,
4988
5070
  CONSUMER_OFFLINE_CLAIM_SUBMIT_GRACE_MS,
4989
5071
  CONSUMER_PAYMENT_REQUEST_DOMAIN,
5072
+ CONSUMER_REVOCATION_DOMAIN,
4990
5073
  CONSUMER_SETTLEMENT_DOMAIN,
4991
5074
  CONSUMER_SETTLEMENT_RECEIPT_QR_PREFIX,
4992
5075
  CUSTODIAL_MODES,
@@ -5084,6 +5167,7 @@ function createOfflinePaymentAuthorizationArtifactUri(input) {
5084
5167
  RECEIPT_CHANNELS,
5085
5168
  RECEIPT_KINDS,
5086
5169
  REPLAY_WINDOW_MS,
5170
+ REVOCATION_LIST_MAX_ENTRIES,
5087
5171
  ReceiptArtifactSchema,
5088
5172
  ReceiptPayloadSchema,
5089
5173
  ReceiptSchema,
@@ -5092,12 +5176,14 @@ function createOfflinePaymentAuthorizationArtifactUri(input) {
5092
5176
  RedemptionSchema,
5093
5177
  RegisterDeviceKeyP256InputSchema,
5094
5178
  ReversalRecordArtifactSchema,
5179
+ RevocationListSchema,
5095
5180
  RevokeDeviceKeyInputSchema,
5096
5181
  SETTLEMENT_SCHEDULES,
5097
5182
  SettleResponseSchema,
5098
5183
  SettlementRecordArtifactSchema,
5099
5184
  SettlementSchema,
5100
5185
  SignedConsumerOACSchema,
5186
+ SignedRevocationListSchema,
5101
5187
  StatementArtifactSchema,
5102
5188
  UpsertMerchantProfileInputSchema,
5103
5189
  UpsertPartnerProfileInputSchema,
@@ -5178,6 +5264,7 @@ function createOfflinePaymentAuthorizationArtifactUri(input) {
5178
5264
  isConsumerPaymentRequestExpired,
5179
5265
  isHardenedArtifactType,
5180
5266
  isKnownArtifactType,
5267
+ isOacRevoked,
5181
5268
  isPassWithinValidity,
5182
5269
  moneyMinorToNumber,
5183
5270
  normalizeE164,
@@ -5185,6 +5272,7 @@ function createOfflinePaymentAuthorizationArtifactUri(input) {
5185
5272
  parseNQR,
5186
5273
  parseQR,
5187
5274
  readTLV,
5275
+ revocationListSigningPayload,
5188
5276
  routingHint,
5189
5277
  signArtifact,
5190
5278
  signAuthorization,
@@ -5211,6 +5299,7 @@ function createOfflinePaymentAuthorizationArtifactUri(input) {
5211
5299
  verifyReceipt,
5212
5300
  verifyRedemption,
5213
5301
  verifyRequestHMAC,
5302
+ verifyRevocationList,
5214
5303
  writeTLV
5215
5304
  });
5216
5305
  //# sourceMappingURL=index.cjs.map