@nokinc-flur/sdk 1.1.5 → 2.0.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
@@ -20,6 +20,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // src/index.ts
21
21
  var index_exports = {};
22
22
  __export(index_exports, {
23
+ ACCOUNT_FUNDED_OAC_MAX_TTL_MS: () => ACCOUNT_FUNDED_OAC_MAX_TTL_MS,
23
24
  ACCOUNT_STATUSES: () => ACCOUNT_STATUSES,
24
25
  ACCOUNT_TYPES: () => ACCOUNT_TYPES,
25
26
  ADDITIONAL_DATA_SUBFIELD: () => ADDITIONAL_DATA_SUBFIELD,
@@ -33,6 +34,7 @@ __export(index_exports, {
33
34
  CLAIM_DOMAIN_V2: () => CLAIM_DOMAIN_V2,
34
35
  COLLECTION_INTENT_STATUSES: () => COLLECTION_INTENT_STATUSES,
35
36
  COLLECTION_PAYMENT_STATUSES: () => COLLECTION_PAYMENT_STATUSES,
37
+ CONSUMER_OFFLINE_CLAIM_SUBMIT_GRACE_MS: () => CONSUMER_OFFLINE_CLAIM_SUBMIT_GRACE_MS,
36
38
  CUSTODIAL_MODES: () => CUSTODIAL_MODES,
37
39
  CollectionIntentSchema: () => CollectionIntentSchema,
38
40
  CollectionPaymentResultSchema: () => CollectionPaymentResultSchema,
@@ -51,10 +53,6 @@ __export(index_exports, {
51
53
  CreateWithdrawalResultSchema: () => CreateWithdrawalResultSchema,
52
54
  DeviceKeyAlgSchema: () => DeviceKeyAlgSchema,
53
55
  DeviceKeyRecordSchema: () => DeviceKeyRecordSchema,
54
- DisableOfflineInputSchema: () => DisableOfflineInputSchema,
55
- DisableOfflineResultSchema: () => DisableOfflineResultSchema,
56
- EnableOfflineInputSchema: () => EnableOfflineInputSchema,
57
- EnableOfflineResultSchema: () => EnableOfflineResultSchema,
58
56
  FIELD: () => FIELD,
59
57
  FLUR_ARTIFACT_URI_PREFIX: () => FLUR_ARTIFACT_URI_PREFIX,
60
58
  FLUR_ARTIFACT_URI_SCHEME: () => FLUR_ARTIFACT_URI_SCHEME,
@@ -70,7 +68,6 @@ __export(index_exports, {
70
68
  IdentityArtifactSchema: () => IdentityArtifactSchema,
71
69
  IngestFundingResultSchema: () => IngestFundingResultSchema,
72
70
  IssueAccountOacInputSchema: () => IssueAccountOacInputSchema,
73
- IssueOACInputSchema: () => IssueOACInputSchema,
74
71
  LedgerJournalEntryArtifactSchema: () => LedgerJournalEntryArtifactSchema,
75
72
  ListPayoutDestinationsResultSchema: () => ListPayoutDestinationsResultSchema,
76
73
  MEMBERSHIP_ROLES: () => MEMBERSHIP_ROLES,
@@ -89,11 +86,9 @@ __export(index_exports, {
89
86
  OAC_DEFAULT_VALIDITY_MS: () => OAC_DEFAULT_VALIDITY_MS,
90
87
  OFFLINE_CLAIM_SMS_PREFIX: () => OFFLINE_CLAIM_SMS_PREFIX,
91
88
  OfflineClaimArtifactSchema: () => OfflineClaimArtifactSchema,
92
- OfflineHoldRecordSchema: () => OfflineHoldRecordSchema,
93
89
  OfflinePaymentAuthorizationArtifactSchema: () => OfflinePaymentAuthorizationArtifactSchema,
94
90
  OfflinePaymentAuthorizationSchema: () => OfflinePaymentAuthorizationSchema,
95
91
  OfflinePaymentRequestSchema: () => OfflinePaymentRequestSchema,
96
- OfflineStateResultSchema: () => OfflineStateResultSchema,
97
92
  OfflineStatusResultSchema: () => OfflineStatusResultSchema,
98
93
  OfflineTokenSchema: () => OfflineTokenSchema,
99
94
  P256EnrollmentChallengeInputSchema: () => P256EnrollmentChallengeInputSchema,
@@ -121,8 +116,6 @@ __export(index_exports, {
121
116
  PayoutEventInputSchema: () => PayoutEventInputSchema,
122
117
  ProviderEventInputSchema: () => ProviderEventInputSchema,
123
118
  ProviderEventRecordSchema: () => ProviderEventRecordSchema,
124
- ProvisionOfflineAllowanceInputSchema: () => ProvisionOfflineAllowanceInputSchema,
125
- ProvisionOfflineAllowanceResultSchema: () => ProvisionOfflineAllowanceResultSchema,
126
119
  PublicCollectionIntentSchema: () => PublicCollectionIntentSchema,
127
120
  RECEIPT_CHANNELS: () => RECEIPT_CHANNELS,
128
121
  RECEIPT_KINDS: () => RECEIPT_KINDS,
@@ -133,7 +126,6 @@ __export(index_exports, {
133
126
  ReconciliationReportSchema: () => ReconciliationReportSchema,
134
127
  RecordPayoutEventResultSchema: () => RecordPayoutEventResultSchema,
135
128
  RedemptionSchema: () => RedemptionSchema,
136
- RegisterDeviceKeyInputSchema: () => RegisterDeviceKeyInputSchema,
137
129
  RegisterDeviceKeyP256InputSchema: () => RegisterDeviceKeyP256InputSchema,
138
130
  ReversalRecordArtifactSchema: () => ReversalRecordArtifactSchema,
139
131
  RevokeDeviceKeyInputSchema: () => RevokeDeviceKeyInputSchema,
@@ -234,13 +226,203 @@ __export(index_exports, {
234
226
  module.exports = __toCommonJS(index_exports);
235
227
 
236
228
  // src/client.ts
237
- var import_zod5 = require("zod");
229
+ var import_zod4 = require("zod");
238
230
 
239
231
  // src/contracts.ts
240
- var import_zod2 = require("zod");
241
-
242
- // src/me-offline/client.ts
243
232
  var import_zod = require("zod");
233
+ var E164Regex = /^\+[1-9]\d{7,14}$/;
234
+ var UuidSchema = import_zod.z.string().uuid();
235
+ var IsoDateSchema = import_zod.z.string().datetime({ offset: true });
236
+ var CurrencySchema = import_zod.z.string().trim().length(3).transform((value) => value.toUpperCase());
237
+ var HealthResponseSchema = import_zod.z.object({
238
+ ok: import_zod.z.boolean()
239
+ });
240
+ var WelcomeResponseSchema = import_zod.z.object({
241
+ message: import_zod.z.string()
242
+ });
243
+ var OnboardingStartRequestSchema = import_zod.z.object({
244
+ phoneE164: import_zod.z.string().regex(E164Regex),
245
+ appInstanceId: import_zod.z.string().min(3),
246
+ platform: import_zod.z.enum(["android", "ios", "web"]),
247
+ turnstileToken: import_zod.z.string().min(20).optional(),
248
+ appAttestation: import_zod.z.object({
249
+ provider: import_zod.z.enum(["android", "ios", "web"]),
250
+ token: import_zod.z.string().min(24)
251
+ }).optional(),
252
+ firstName: import_zod.z.string().trim().min(1).max(80).optional(),
253
+ lastName: import_zod.z.string().trim().min(1).max(80).optional()
254
+ });
255
+ var OnboardingStartResponseSchema = import_zod.z.object({
256
+ requestId: import_zod.z.string().min(1),
257
+ checkUrl: import_zod.z.string().url().optional(),
258
+ expiresInSec: import_zod.z.number().int().positive(),
259
+ fallback: import_zod.z.enum(["SILENT_AUTH", "OTP"])
260
+ });
261
+ var OnboardingCompleteRequestSchema = import_zod.z.object({
262
+ requestId: import_zod.z.string().min(1),
263
+ code: import_zod.z.string().min(1).max(32),
264
+ appInstanceId: import_zod.z.string().min(3),
265
+ fingerprintHash: import_zod.z.string().min(3).optional()
266
+ });
267
+ var OnboardingCompleteResponseSchema = import_zod.z.object({
268
+ sessionToken: import_zod.z.string().min(1),
269
+ userId: UuidSchema,
270
+ restricted: import_zod.z.boolean(),
271
+ risk_reasons: import_zod.z.array(
272
+ import_zod.z.enum(["SIM_SWAP_RECENT", "ROAMING", "CARRIER_CHANGED"])
273
+ ),
274
+ stepUpRequired: import_zod.z.boolean().optional(),
275
+ riskStatus: import_zod.z.enum(["ok", "unavailable"]).optional()
276
+ });
277
+ var RegisterDeviceRequestSchema = import_zod.z.object({
278
+ userId: UuidSchema,
279
+ appInstanceId: import_zod.z.string().min(3),
280
+ platform: import_zod.z.string().min(2),
281
+ model: import_zod.z.string().optional(),
282
+ networkSignals: import_zod.z.object({
283
+ ip: import_zod.z.string().min(3),
284
+ asn: import_zod.z.number().int().optional(),
285
+ country: import_zod.z.string().min(2).optional(),
286
+ carrier: import_zod.z.string().optional()
287
+ })
288
+ });
289
+ var RegisterDeviceResponseSchema = import_zod.z.object({
290
+ deviceId: import_zod.z.string().min(1),
291
+ fingerprintHash: import_zod.z.string().min(1),
292
+ driftScore: import_zod.z.number(),
293
+ trustState: import_zod.z.enum(["TRUSTED_PRIMARY", "TRUSTED_SECONDARY", "UNVERIFIED"]),
294
+ stepUpRequired: import_zod.z.boolean()
295
+ });
296
+ var AuthRefreshRequestSchema = import_zod.z.object({
297
+ userId: UuidSchema,
298
+ refreshToken: import_zod.z.string().min(8),
299
+ appInstanceId: import_zod.z.string().min(3),
300
+ fingerprintHash: import_zod.z.string().min(3)
301
+ });
302
+ var AuthRefreshResponseSchema = import_zod.z.object({
303
+ refreshToken: import_zod.z.string().min(8),
304
+ stepUpRequired: import_zod.z.boolean()
305
+ });
306
+ var AuthLogoutRequestSchema = import_zod.z.object({
307
+ userId: UuidSchema,
308
+ refreshToken: import_zod.z.string().min(8)
309
+ });
310
+ var PinSetRequestSchema = import_zod.z.object({
311
+ userId: UuidSchema,
312
+ pin: import_zod.z.string().regex(/^\d{6}$/)
313
+ });
314
+ var PinVerifyRequestSchema = import_zod.z.object({
315
+ userId: UuidSchema,
316
+ pin: import_zod.z.string().regex(/^\d{6}$/)
317
+ });
318
+ var OkResponseSchema = import_zod.z.object({
319
+ ok: import_zod.z.boolean()
320
+ });
321
+ var RegisterSendDeviceKeyRequestSchema = import_zod.z.object({
322
+ userId: UuidSchema,
323
+ deviceId: import_zod.z.string().min(3),
324
+ publicKey: import_zod.z.string().min(32)
325
+ });
326
+ var SEND_AUTH_PURPOSES = ["send_money", "offline_revoke"];
327
+ var SendChallengeRequestSchema = import_zod.z.object({
328
+ userId: UuidSchema,
329
+ deviceId: import_zod.z.string().min(3),
330
+ purpose: import_zod.z.enum(SEND_AUTH_PURPOSES).optional()
331
+ });
332
+ var SendChallengeResponseSchema = import_zod.z.object({
333
+ challengeId: UuidSchema,
334
+ nonce: import_zod.z.string().min(1),
335
+ expiresAt: IsoDateSchema
336
+ });
337
+ var SendVerifyRequestSchema = import_zod.z.object({
338
+ userId: UuidSchema,
339
+ deviceId: import_zod.z.string().min(3),
340
+ challengeId: UuidSchema,
341
+ signature: import_zod.z.string().min(16)
342
+ });
343
+ var SendVerifyResponseSchema = import_zod.z.object({
344
+ sendAuthToken: import_zod.z.string().min(16)
345
+ });
346
+ var ResolveRecipientRequestSchema = import_zod.z.object({
347
+ identifier: import_zod.z.string().min(3)
348
+ });
349
+ var ResolveRecipientResponseSchema = import_zod.z.object({
350
+ recipientUserId: UuidSchema,
351
+ displayName: import_zod.z.string().min(1),
352
+ normalizedIdentifier: import_zod.z.string().regex(E164Regex),
353
+ isActive: import_zod.z.boolean()
354
+ });
355
+ var CreateTransferRequestSchema = import_zod.z.object({
356
+ recipientIdentifier: import_zod.z.string().min(3),
357
+ amountMinor: import_zod.z.number().int().positive(),
358
+ currency: CurrencySchema,
359
+ sendAuthToken: import_zod.z.string().min(16)
360
+ });
361
+ var TransferStatusSchema = import_zod.z.enum(["SETTLED", "PENDING_REVIEW", "DECLINED"]);
362
+ var TransferResponseSchema = import_zod.z.object({
363
+ transactionId: import_zod.z.string().min(1),
364
+ status: TransferStatusSchema,
365
+ userStatus: TransferStatusSchema,
366
+ recipientName: import_zod.z.string().min(1),
367
+ timestamp: IsoDateSchema
368
+ });
369
+ var DirectionSchema = import_zod.z.enum(["OUTGOING", "INCOMING"]);
370
+ var AccountActivityItemSchema = import_zod.z.object({
371
+ id: import_zod.z.string().min(1),
372
+ type: import_zod.z.string().min(1),
373
+ direction: DirectionSchema,
374
+ name: import_zod.z.string().min(1),
375
+ identifier: import_zod.z.string().min(1),
376
+ amountMinor: import_zod.z.number().int(),
377
+ currency: CurrencySchema,
378
+ status: import_zod.z.string().min(1),
379
+ timestamp: IsoDateSchema
380
+ });
381
+ var AccountSummaryResponseSchema = import_zod.z.object({
382
+ /** Authenticated user's stable internal id. */
383
+ userId: UuidSchema,
384
+ /**
385
+ * 10-digit Nigeria Uniform Bank Account Number (NUBAN) allocated by the
386
+ * bank partner. `null` when the user has no partner-allocated account yet.
387
+ */
388
+ nuban: import_zod.z.string().regex(/^[0-9]{10}$/).nullable(),
389
+ balance: import_zod.z.number().int(),
390
+ currency: CurrencySchema,
391
+ dailySendLimit: import_zod.z.number().int().nonnegative(),
392
+ dailySendRemaining: import_zod.z.number().int().nonnegative(),
393
+ kycTier: import_zod.z.string().min(1),
394
+ kycStatus: import_zod.z.string().min(1),
395
+ recentActivity: import_zod.z.array(AccountActivityItemSchema)
396
+ });
397
+ var TransactionsListResponseSchema = import_zod.z.object({
398
+ items: import_zod.z.array(AccountActivityItemSchema),
399
+ nextCursor: import_zod.z.string().nullable()
400
+ });
401
+ var TransactionDetailResponseSchema = import_zod.z.object({
402
+ transactionId: import_zod.z.string().min(1),
403
+ type: import_zod.z.string().min(1),
404
+ direction: DirectionSchema,
405
+ counterpartyName: import_zod.z.string().min(1),
406
+ counterpartyIdentifier: import_zod.z.string().min(1),
407
+ amountMinor: import_zod.z.number().int(),
408
+ currency: CurrencySchema,
409
+ status: import_zod.z.string().min(1),
410
+ timestamp: IsoDateSchema
411
+ });
412
+ var PushRegisterRequestSchema = import_zod.z.object({
413
+ deviceId: import_zod.z.string().min(3),
414
+ platform: import_zod.z.enum(["ios", "android", "web"]),
415
+ token: import_zod.z.string().min(16)
416
+ });
417
+ var CreatePayLinkResponseSchema = import_zod.z.object({
418
+ token: import_zod.z.string().min(1)
419
+ });
420
+ var ResolvePayLinkResponseSchema = import_zod.z.object({
421
+ recipientUserId: UuidSchema,
422
+ displayName: import_zod.z.string().min(1),
423
+ normalizedIdentifier: import_zod.z.string().regex(E164Regex),
424
+ isActive: import_zod.z.boolean()
425
+ });
244
426
 
245
427
  // src/errors.ts
246
428
  var backendErrorCodeSet = /* @__PURE__ */ new Set([
@@ -344,556 +526,9 @@ async function mapToFlurError(res) {
344
526
  });
345
527
  }
346
528
 
347
- // src/me-offline/client.ts
348
- var Hex64 = import_zod.z.string().regex(/^[0-9a-f]{64}$/i);
349
- var Sha256Hex = import_zod.z.string().regex(/^[0-9a-f]{64}$/i);
350
- var Base64Std = import_zod.z.string().regex(/^[A-Za-z0-9+/]+={0,2}$/);
351
- var RegisterDeviceKeyInputSchema = import_zod.z.object({
352
- deviceId: import_zod.z.string().min(1).max(128),
353
- publicKeyHex: Hex64
354
- });
355
- var AttestationSecurityLevelSchema = import_zod.z.enum([
356
- "STRONGBOX",
357
- "TEE",
358
- "SECURE_ENCLAVE",
359
- "SOFTWARE"
360
- ]);
361
- var DeviceKeyAlgSchema = import_zod.z.literal("p256");
362
- var RegisterDeviceKeyP256InputSchema = import_zod.z.object({
363
- deviceId: import_zod.z.string().min(1).max(128),
364
- /** P-256 SubjectPublicKeyInfo DER, base64. */
365
- publicKeySpkiB64: Base64Std.min(64).max(4096),
366
- /** Base64 of the server-issued enrollment challenge string. */
367
- challengeB64: Base64Std.min(8).max(1024),
368
- /** iOS App Attest payload or Android X.509 Key Attestation chain. */
369
- attestationChainB64: import_zod.z.array(Base64Std.min(16).max(16384)).min(1).max(16),
370
- securityLevel: AttestationSecurityLevelSchema
371
- });
372
- var P256EnrollmentChallengeInputSchema = import_zod.z.object({
373
- deviceId: import_zod.z.string().min(1).max(128)
374
- });
375
- var P256EnrollmentChallengeResultSchema = import_zod.z.object({
376
- challenge: import_zod.z.string().min(16),
377
- expiresAtMs: import_zod.z.number().int().positive()
378
- });
379
- var DeviceKeyRecordSchema = import_zod.z.object({
380
- id: import_zod.z.string().uuid(),
381
- userId: import_zod.z.string().uuid(),
382
- deviceId: import_zod.z.string(),
383
- /** Always 'p256' on the consumer offline rail. Field retained for forward-compat. */
384
- alg: DeviceKeyAlgSchema.default("p256"),
385
- /** Legacy ed25519 hex key. Always null on new records (kept for back-compat reads). */
386
- publicKeyHex: Hex64.nullable().default(null),
387
- /** P-256 SubjectPublicKeyInfo DER, base64. Required for new records. */
388
- publicKeySpkiB64: Base64Std.nullable().default(null),
389
- securityLevel: AttestationSecurityLevelSchema.nullable().default(null),
390
- hardwareBacked: import_zod.z.boolean().default(false),
391
- attestedAtMs: import_zod.z.number().int().nonnegative().nullable().default(null),
392
- createdAtMs: import_zod.z.number().int().nonnegative(),
393
- revokedAtMs: import_zod.z.number().int().nonnegative().nullable()
394
- });
395
- var ConsumerOACSchema = import_zod.z.object({
396
- oacId: import_zod.z.string().uuid(),
397
- issuerId: import_zod.z.string().min(1).max(64),
398
- userId: import_zod.z.string().uuid(),
399
- deviceId: import_zod.z.string().min(1).max(128),
400
- /**
401
- * Always 'p256'. Required on the wire (backend always emits it).
402
- * Kept as a literal so input/output infer identically and the schema
403
- * can be nested inside other response shapes without Zod input/output
404
- * divergence under tsup DTS bundling.
405
- */
406
- alg: import_zod.z.literal("p256"),
407
- /** P-256 SubjectPublicKeyInfo DER, base64. */
408
- devicePubkeySpkiB64: Base64Std.min(64).max(4096),
409
- perTxCapKobo: import_zod.z.number().int().positive(),
410
- cumulativeCapKobo: import_zod.z.number().int().positive(),
411
- currency: import_zod.z.string().length(3),
412
- validFromMs: import_zod.z.number().int().nonnegative(),
413
- validUntilMs: import_zod.z.number().int().nonnegative(),
414
- counterSeed: import_zod.z.number().int().nonnegative(),
415
- issuedAtMs: import_zod.z.number().int().nonnegative()
416
- });
417
- var SignedConsumerOACSchema = import_zod.z.object({
418
- oac: ConsumerOACSchema,
419
- /** ASN.1 DER ECDSA P-256 issuer signature, base64. */
420
- issuerSig: Base64Std.min(16).max(2048),
421
- /** Issuer's P-256 public key as SubjectPublicKeyInfo DER, base64. */
422
- issuerPublicKeySpkiB64: Base64Std.min(64).max(4096)
423
- });
424
- var OACRecordSchema = SignedConsumerOACSchema.extend({
425
- currentOfflineSpentKobo: import_zod.z.number().int().nonnegative(),
426
- status: import_zod.z.enum([
427
- "active",
428
- "superseded",
429
- "expired",
430
- "revoked",
431
- "disabling",
432
- "draining",
433
- "closed"
434
- ]),
435
- supersededAtMs: import_zod.z.number().int().nonnegative().nullable(),
436
- revokedAtMs: import_zod.z.number().int().nonnegative().nullable(),
437
- holdId: import_zod.z.string().uuid().nullable().optional()
438
- });
439
- var IssueOACInputSchema = import_zod.z.object({
440
- deviceId: import_zod.z.string().min(1).max(128),
441
- perTxCapKobo: import_zod.z.number().int().positive().optional(),
442
- cumulativeCapKobo: import_zod.z.number().int().positive().optional(),
443
- ttlMs: import_zod.z.number().int().min(6e4).max(1e3 * 60 * 60 * 24 * 7).optional(),
444
- spendableOnlineKobo: import_zod.z.number().int().nonnegative().optional()
445
- });
446
- var IssueAccountOacInputSchema = import_zod.z.object({
447
- deviceId: import_zod.z.string().min(1).max(128),
448
- perTxCapKobo: import_zod.z.number().int().positive().optional(),
449
- cumulativeCapKobo: import_zod.z.number().int().positive().optional(),
450
- ttlMs: import_zod.z.number().int().min(6e4).max(1e3 * 60 * 60 * 24 * 7).optional()
451
- });
452
- var EnableOfflineInputSchema = import_zod.z.object({
453
- deviceId: import_zod.z.string().min(1).max(128),
454
- amountKobo: import_zod.z.number().int().positive(),
455
- perTxCapKobo: import_zod.z.number().int().positive().optional(),
456
- ttlMs: import_zod.z.number().int().min(6e4).max(1e3 * 60 * 60 * 24 * 7).optional(),
457
- installId: import_zod.z.string().min(1).max(128),
458
- partnerId: import_zod.z.string().min(1).max(64).optional()
459
- });
460
- var ProvisionOfflineAllowanceInputSchema = EnableOfflineInputSchema;
461
- var DisableOfflineInputSchema = import_zod.z.object({
462
- deviceId: import_zod.z.string().min(1).max(128),
463
- installId: import_zod.z.string().min(1).max(128).optional(),
464
- claims: import_zod.z.array(import_zod.z.unknown()).max(256).optional()
465
- });
466
- var OfflineHoldRecordSchema = import_zod.z.object({
467
- holdId: import_zod.z.string().uuid(),
468
- userId: import_zod.z.string().uuid(),
469
- deviceId: import_zod.z.string(),
470
- partnerId: import_zod.z.string(),
471
- adapterKind: import_zod.z.string(),
472
- externalHoldRef: import_zod.z.string().nullable(),
473
- amountKobo: import_zod.z.number().int().nonnegative(),
474
- capturedKobo: import_zod.z.number().int().nonnegative(),
475
- releasedKobo: import_zod.z.number().int().nonnegative(),
476
- remainingKobo: import_zod.z.number().int().nonnegative(),
477
- currency: import_zod.z.string().length(3),
478
- status: import_zod.z.enum([
479
- "placing",
480
- "active",
481
- "disabling",
482
- "draining",
483
- "closed",
484
- "revoked",
485
- "failed"
486
- ]),
487
- installId: import_zod.z.string().nullable(),
488
- drainDeadlineMs: import_zod.z.number().int().nonnegative(),
489
- disableRequestedAtMs: import_zod.z.number().int().nonnegative().nullable(),
490
- createdAtMs: import_zod.z.number().int().nonnegative(),
491
- closedAtMs: import_zod.z.number().int().nonnegative().nullable(),
492
- isTrusted: import_zod.z.boolean().optional()
493
- });
494
- var EnableOfflineResultSchema = import_zod.z.object({
495
- hold: OfflineHoldRecordSchema,
496
- oac: OACRecordSchema
497
- });
498
- var ProvisionOfflineAllowanceResultSchema = EnableOfflineResultSchema;
499
- var DisableOfflineResultSchema = import_zod.z.object({
500
- hold: OfflineHoldRecordSchema,
501
- trusted: import_zod.z.boolean(),
502
- settledClaims: import_zod.z.number().int().nonnegative()
503
- });
504
- var OfflineStatusResultSchema = import_zod.z.object({
505
- hold: OfflineHoldRecordSchema.nullable(),
506
- active: OACRecordSchema.nullable()
507
- });
508
- var OfflineStateResultSchema = import_zod.z.object({
509
- active: OACRecordSchema.nullable()
510
- });
511
- var ConsumerPaymentClaimSchema = import_zod.z.object({
512
- /** Always 'p256'. Retained for forward-compat and as an explicit domain marker. */
513
- alg: import_zod.z.literal("p256").default("p256"),
514
- oacId: import_zod.z.string().uuid(),
515
- encounterId: Sha256Hex.optional(),
516
- payerUserId: import_zod.z.string().uuid(),
517
- payeeUserId: import_zod.z.string().uuid(),
518
- payerDeviceId: import_zod.z.string().min(1).max(128),
519
- payerNonce: import_zod.z.string().min(8).max(128),
520
- payeeNonce: import_zod.z.string().min(8).max(128),
521
- amountKobo: import_zod.z.number().int().positive(),
522
- currency: import_zod.z.string().length(3).default("NGN"),
523
- occurredAtMs: import_zod.z.number().int().nonnegative(),
524
- completedAtMs: import_zod.z.number().int().nonnegative().optional(),
525
- contextId: import_zod.z.string().max(128).optional(),
526
- payerPubkeySpkiB64: Base64Std.min(64).max(4096),
527
- payerSignatureDerB64: Base64Std.min(16).max(2048),
528
- payeePubkeySpkiB64: Base64Std.min(64).max(4096).optional(),
529
- payeeSignatureDerB64: Base64Std.min(16).max(2048).optional()
530
- });
531
- var ConsumerSettlementSchema = import_zod.z.object({
532
- settlementId: import_zod.z.string().uuid(),
533
- settlementKey: Sha256Hex,
534
- encounterId: Sha256Hex,
535
- oacId: import_zod.z.string().uuid(),
536
- payerUserId: import_zod.z.string().uuid(),
537
- payeeUserId: import_zod.z.string().uuid(),
538
- amountKobo: import_zod.z.number().int().positive(),
539
- currency: import_zod.z.string().length(3),
540
- status: import_zod.z.enum(["SETTLED", "REVIEW"]),
541
- reviewReason: import_zod.z.string().nullable(),
542
- ledgerRef: import_zod.z.string().nullable(),
543
- /** ASN.1 DER ECDSA P-256 issuer signature, base64. */
544
- issuerSig: Base64Std.min(16).max(2048),
545
- createdAtMs: import_zod.z.number().int().nonnegative()
546
- });
547
- var ConsumerSettleResultSchema = import_zod.z.object({
548
- settlement: ConsumerSettlementSchema,
549
- encounterId: Sha256Hex,
550
- replayed: import_zod.z.boolean()
551
- });
552
- var RevokeDeviceKeyInputSchema = import_zod.z.object({
553
- deviceId: import_zod.z.string().min(1).max(128),
554
- /** Step-up token from /api/v1/auth/send/verify with purpose='offline_revoke'. */
555
- sendAuthToken: import_zod.z.string().min(16)
556
- });
557
- function createMeOfflineClient(opts) {
558
- const fetchImpl = opts.fetchImpl ?? globalThis.fetch;
559
- if (!fetchImpl) {
560
- throw new Error("createMeOfflineClient: no fetch implementation available");
561
- }
562
- const baseUrl = opts.baseUrl.replace(/\/$/, "");
563
- async function call(method, path, body, parser) {
564
- const init2 = {
565
- method,
566
- headers: {
567
- "content-type": "application/json",
568
- accept: "application/json"
569
- }
570
- };
571
- if (body !== void 0) init2.body = JSON.stringify(body);
572
- const resp = await fetchImpl(`${baseUrl}${path}`, init2);
573
- const text = await resp.text();
574
- let raw = void 0;
575
- if (text) {
576
- try {
577
- raw = JSON.parse(text);
578
- } catch {
579
- }
580
- }
581
- if (!resp.ok) {
582
- const code = raw && typeof raw === "object" && "code" in raw && typeof raw.code === "string" ? raw.code : `http_${resp.status}`;
583
- const message = raw && typeof raw === "object" && "message" in raw && typeof raw.message === "string" ? raw.message : `request failed with status ${resp.status}`;
584
- throw new FlurApiError(resp.status, code, message, raw);
585
- }
586
- return parser(raw);
587
- }
588
- const deviceKeyItems = import_zod.z.object({ items: import_zod.z.array(DeviceKeyRecordSchema) });
589
- return {
590
- registerDeviceKey: (input) => call(
591
- "POST",
592
- "/v1/me/offline/keys",
593
- RegisterDeviceKeyInputSchema.parse(input),
594
- (raw) => DeviceKeyRecordSchema.parse(raw)
595
- ),
596
- issueP256EnrollmentChallenge: (input) => call(
597
- "POST",
598
- "/v1/me/offline/keys/p256/challenge",
599
- P256EnrollmentChallengeInputSchema.parse(input),
600
- (raw) => P256EnrollmentChallengeResultSchema.parse(raw)
601
- ),
602
- registerDeviceKeyP256: (input) => call(
603
- "POST",
604
- "/v1/me/offline/keys/p256",
605
- RegisterDeviceKeyP256InputSchema.parse(input),
606
- (raw) => DeviceKeyRecordSchema.parse(raw)
607
- ),
608
- listDeviceKeys: () => call(
609
- "GET",
610
- "/v1/me/offline/keys",
611
- void 0,
612
- (raw) => deviceKeyItems.parse(raw)
613
- ),
614
- revokeDeviceKey: (input) => call(
615
- "POST",
616
- "/v1/me/offline/keys/revoke",
617
- RevokeDeviceKeyInputSchema.parse(input),
618
- () => void 0
619
- ),
620
- issueAccountOac: (input) => call(
621
- "POST",
622
- "/v1/me/offline/oac",
623
- IssueAccountOacInputSchema.parse(input),
624
- (raw) => OACRecordSchema.parse(raw)
625
- ),
626
- provisionAllowance: (input) => call(
627
- "POST",
628
- "/v1/me/offline/allowance",
629
- ProvisionOfflineAllowanceInputSchema.parse(input),
630
- (raw) => ProvisionOfflineAllowanceResultSchema.parse(raw)
631
- ),
632
- enable: (input) => call(
633
- "POST",
634
- "/v1/me/offline/enable",
635
- EnableOfflineInputSchema.parse(input),
636
- (raw) => EnableOfflineResultSchema.parse(raw)
637
- ),
638
- refresh: (input) => call(
639
- "POST",
640
- "/v1/me/offline/refresh",
641
- IssueOACInputSchema.parse(input),
642
- (raw) => OACRecordSchema.parse(raw)
643
- ),
644
- disable: (input) => call(
645
- "POST",
646
- "/v1/me/offline/disable",
647
- DisableOfflineInputSchema.parse(input),
648
- (raw) => DisableOfflineResultSchema.parse(raw)
649
- ),
650
- getStatus: (deviceId) => {
651
- const qs = deviceId ? `?deviceId=${encodeURIComponent(deviceId)}` : "";
652
- return call(
653
- "GET",
654
- `/v1/me/offline/status${qs}`,
655
- void 0,
656
- (raw) => OfflineStatusResultSchema.parse(raw)
657
- );
658
- },
659
- getState: (deviceId) => {
660
- const qs = deviceId ? `?deviceId=${encodeURIComponent(deviceId)}` : "";
661
- return call(
662
- "GET",
663
- `/v1/me/offline/state${qs}`,
664
- void 0,
665
- (raw) => OfflineStateResultSchema.parse(raw)
666
- );
667
- },
668
- submitClaim: (claim) => call(
669
- "POST",
670
- "/v1/me/offline/claims",
671
- ConsumerPaymentClaimSchema.parse(claim),
672
- (raw) => ConsumerSettleResultSchema.parse(raw)
673
- )
674
- };
675
- }
676
-
677
- // src/contracts.ts
678
- var E164Regex = /^\+[1-9]\d{7,14}$/;
679
- var UuidSchema = import_zod2.z.string().uuid();
680
- var IsoDateSchema = import_zod2.z.string().datetime({ offset: true });
681
- var CurrencySchema = import_zod2.z.string().trim().length(3).transform((value) => value.toUpperCase());
682
- var HealthResponseSchema = import_zod2.z.object({
683
- ok: import_zod2.z.boolean()
684
- });
685
- var WelcomeResponseSchema = import_zod2.z.object({
686
- message: import_zod2.z.string()
687
- });
688
- var OnboardingStartRequestSchema = import_zod2.z.object({
689
- phoneE164: import_zod2.z.string().regex(E164Regex),
690
- appInstanceId: import_zod2.z.string().min(3),
691
- platform: import_zod2.z.enum(["android", "ios", "web"]),
692
- turnstileToken: import_zod2.z.string().min(20).optional(),
693
- appAttestation: import_zod2.z.object({
694
- provider: import_zod2.z.enum(["android", "ios", "web"]),
695
- token: import_zod2.z.string().min(24)
696
- }).optional(),
697
- firstName: import_zod2.z.string().trim().min(1).max(80).optional(),
698
- lastName: import_zod2.z.string().trim().min(1).max(80).optional()
699
- });
700
- var OnboardingStartResponseSchema = import_zod2.z.object({
701
- requestId: import_zod2.z.string().min(1),
702
- checkUrl: import_zod2.z.string().url().optional(),
703
- expiresInSec: import_zod2.z.number().int().positive(),
704
- fallback: import_zod2.z.enum(["SILENT_AUTH", "OTP"])
705
- });
706
- var OnboardingCompleteRequestSchema = import_zod2.z.object({
707
- requestId: import_zod2.z.string().min(1),
708
- code: import_zod2.z.string().min(1).max(32),
709
- appInstanceId: import_zod2.z.string().min(3),
710
- fingerprintHash: import_zod2.z.string().min(3).optional()
711
- });
712
- var OnboardingCompleteResponseSchema = import_zod2.z.object({
713
- sessionToken: import_zod2.z.string().min(1),
714
- userId: UuidSchema,
715
- restricted: import_zod2.z.boolean(),
716
- risk_reasons: import_zod2.z.array(
717
- import_zod2.z.enum(["SIM_SWAP_RECENT", "ROAMING", "CARRIER_CHANGED"])
718
- ),
719
- stepUpRequired: import_zod2.z.boolean().optional(),
720
- riskStatus: import_zod2.z.enum(["ok", "unavailable"]).optional()
721
- });
722
- var RegisterDeviceRequestSchema = import_zod2.z.object({
723
- userId: UuidSchema,
724
- appInstanceId: import_zod2.z.string().min(3),
725
- platform: import_zod2.z.string().min(2),
726
- model: import_zod2.z.string().optional(),
727
- networkSignals: import_zod2.z.object({
728
- ip: import_zod2.z.string().min(3),
729
- asn: import_zod2.z.number().int().optional(),
730
- country: import_zod2.z.string().min(2).optional(),
731
- carrier: import_zod2.z.string().optional()
732
- })
733
- });
734
- var RegisterDeviceResponseSchema = import_zod2.z.object({
735
- deviceId: import_zod2.z.string().min(1),
736
- fingerprintHash: import_zod2.z.string().min(1),
737
- driftScore: import_zod2.z.number(),
738
- trustState: import_zod2.z.enum(["TRUSTED_PRIMARY", "TRUSTED_SECONDARY", "UNVERIFIED"]),
739
- stepUpRequired: import_zod2.z.boolean()
740
- });
741
- var AuthRefreshRequestSchema = import_zod2.z.object({
742
- userId: UuidSchema,
743
- refreshToken: import_zod2.z.string().min(8),
744
- appInstanceId: import_zod2.z.string().min(3),
745
- fingerprintHash: import_zod2.z.string().min(3)
746
- });
747
- var AuthRefreshResponseSchema = import_zod2.z.object({
748
- refreshToken: import_zod2.z.string().min(8),
749
- stepUpRequired: import_zod2.z.boolean()
750
- });
751
- var AuthLogoutRequestSchema = import_zod2.z.object({
752
- userId: UuidSchema,
753
- refreshToken: import_zod2.z.string().min(8)
754
- });
755
- var PinSetRequestSchema = import_zod2.z.object({
756
- userId: UuidSchema,
757
- pin: import_zod2.z.string().regex(/^\d{6}$/)
758
- });
759
- var PinVerifyRequestSchema = import_zod2.z.object({
760
- userId: UuidSchema,
761
- pin: import_zod2.z.string().regex(/^\d{6}$/)
762
- });
763
- var OkResponseSchema = import_zod2.z.object({
764
- ok: import_zod2.z.boolean()
765
- });
766
- var RegisterSendDeviceKeyRequestSchema = import_zod2.z.object({
767
- userId: UuidSchema,
768
- deviceId: import_zod2.z.string().min(3),
769
- publicKey: import_zod2.z.string().min(32)
770
- });
771
- var SEND_AUTH_PURPOSES = ["send_money", "offline_revoke"];
772
- var SendChallengeRequestSchema = import_zod2.z.object({
773
- userId: UuidSchema,
774
- deviceId: import_zod2.z.string().min(3),
775
- purpose: import_zod2.z.enum(SEND_AUTH_PURPOSES).optional()
776
- });
777
- var SendChallengeResponseSchema = import_zod2.z.object({
778
- challengeId: UuidSchema,
779
- nonce: import_zod2.z.string().min(1),
780
- expiresAt: IsoDateSchema
781
- });
782
- var SendVerifyRequestSchema = import_zod2.z.object({
783
- userId: UuidSchema,
784
- deviceId: import_zod2.z.string().min(3),
785
- challengeId: UuidSchema,
786
- signature: import_zod2.z.string().min(16)
787
- });
788
- var SendVerifyResponseSchema = import_zod2.z.object({
789
- sendAuthToken: import_zod2.z.string().min(16)
790
- });
791
- var ResolveRecipientRequestSchema = import_zod2.z.object({
792
- identifier: import_zod2.z.string().min(3)
793
- });
794
- var ResolveRecipientResponseSchema = import_zod2.z.object({
795
- recipientUserId: UuidSchema,
796
- displayName: import_zod2.z.string().min(1),
797
- normalizedIdentifier: import_zod2.z.string().regex(E164Regex),
798
- isActive: import_zod2.z.boolean()
799
- });
800
- var CreateTransferRequestSchema = import_zod2.z.object({
801
- recipientIdentifier: import_zod2.z.string().min(3),
802
- amountMinor: import_zod2.z.number().int().positive(),
803
- currency: CurrencySchema,
804
- sendAuthToken: import_zod2.z.string().min(16)
805
- });
806
- var TransferStatusSchema = import_zod2.z.enum(["SETTLED", "PENDING_REVIEW", "DECLINED"]);
807
- var TransferResponseSchema = import_zod2.z.object({
808
- transactionId: import_zod2.z.string().min(1),
809
- status: TransferStatusSchema,
810
- userStatus: TransferStatusSchema,
811
- recipientName: import_zod2.z.string().min(1),
812
- timestamp: IsoDateSchema,
813
- /**
814
- * Fresh issuer-signed OACs returned by the backend's post-commit
815
- * rotation hook on `SETTLED` transfers.
816
- *
817
- * In the current backend implementation this hook rotates LEGACY
818
- * hold-backed OACs only. Account-funded (no-hold) OACs introduced by
819
- * the unified-pay-rails refactor are NOT rotated here — their
820
- * cumulative spend counter and main-balance check are enforced at
821
- * claim submission time via `createTransfer` under the per-sender
822
- * advisory lock, so a stale no-hold OAC cannot authorise overspending
823
- * (it can only resolve to REVIEW on submission).
824
- *
825
- * Optional: omitted when the sender has no registered hold-backed
826
- * devices, when the refresh failed (best-effort), or on retry replays
827
- * that pre-date the refresh. When present, the entries supersede any
828
- * locally cached OACs for the listed devices; when absent, clients
829
- * should fall back to `/v1/me/offline/refresh`.
830
- *
831
- * Each entry is validated against the canonical `OACRecordSchema`,
832
- * so consumers can trust the runtime shape matches the static type.
833
- */
834
- offlineOacs: OACRecordSchema.array().optional()
835
- });
836
- var DirectionSchema = import_zod2.z.enum(["OUTGOING", "INCOMING"]);
837
- var AccountActivityItemSchema = import_zod2.z.object({
838
- id: import_zod2.z.string().min(1),
839
- type: import_zod2.z.string().min(1),
840
- direction: DirectionSchema,
841
- name: import_zod2.z.string().min(1),
842
- identifier: import_zod2.z.string().min(1),
843
- amountMinor: import_zod2.z.number().int(),
844
- currency: CurrencySchema,
845
- status: import_zod2.z.string().min(1),
846
- timestamp: IsoDateSchema
847
- });
848
- var AccountSummaryResponseSchema = import_zod2.z.object({
849
- /** Authenticated user's stable internal id. */
850
- userId: UuidSchema,
851
- /**
852
- * 10-digit Nigeria Uniform Bank Account Number (NUBAN) allocated by the
853
- * bank partner. `null` when the user has no partner-allocated account yet.
854
- */
855
- nuban: import_zod2.z.string().regex(/^[0-9]{10}$/).nullable(),
856
- balance: import_zod2.z.number().int(),
857
- currency: CurrencySchema,
858
- dailySendLimit: import_zod2.z.number().int().nonnegative(),
859
- dailySendRemaining: import_zod2.z.number().int().nonnegative(),
860
- kycTier: import_zod2.z.string().min(1),
861
- kycStatus: import_zod2.z.string().min(1),
862
- recentActivity: import_zod2.z.array(AccountActivityItemSchema)
863
- });
864
- var TransactionsListResponseSchema = import_zod2.z.object({
865
- items: import_zod2.z.array(AccountActivityItemSchema),
866
- nextCursor: import_zod2.z.string().nullable()
867
- });
868
- var TransactionDetailResponseSchema = import_zod2.z.object({
869
- transactionId: import_zod2.z.string().min(1),
870
- type: import_zod2.z.string().min(1),
871
- direction: DirectionSchema,
872
- counterpartyName: import_zod2.z.string().min(1),
873
- counterpartyIdentifier: import_zod2.z.string().min(1),
874
- amountMinor: import_zod2.z.number().int(),
875
- currency: CurrencySchema,
876
- status: import_zod2.z.string().min(1),
877
- timestamp: IsoDateSchema
878
- });
879
- var PushRegisterRequestSchema = import_zod2.z.object({
880
- deviceId: import_zod2.z.string().min(3),
881
- platform: import_zod2.z.enum(["ios", "android", "web"]),
882
- token: import_zod2.z.string().min(16)
883
- });
884
- var CreatePayLinkResponseSchema = import_zod2.z.object({
885
- token: import_zod2.z.string().min(1)
886
- });
887
- var ResolvePayLinkResponseSchema = import_zod2.z.object({
888
- recipientUserId: UuidSchema,
889
- displayName: import_zod2.z.string().min(1),
890
- normalizedIdentifier: import_zod2.z.string().regex(E164Regex),
891
- isActive: import_zod2.z.boolean()
892
- });
893
-
894
529
  // src/primitives.ts
895
- var import_zod3 = require("zod");
896
- var CurrencyCodeSchema = import_zod3.z.string().trim().length(3).transform((value) => value.toUpperCase());
530
+ var import_zod2 = require("zod");
531
+ var CurrencyCodeSchema = import_zod2.z.string().trim().length(3).transform((value) => value.toUpperCase());
897
532
  var currencyFractionDigits = {
898
533
  NGN: 2,
899
534
  USD: 2,
@@ -987,7 +622,7 @@ function moneyMinorToNumber(amountMinor) {
987
622
  }
988
623
 
989
624
  // src/collections/client.ts
990
- var import_zod4 = require("zod");
625
+ var import_zod3 = require("zod");
991
626
  var MERCHANT_PROFILE_STATUSES = [
992
627
  "pending",
993
628
  "active",
@@ -1017,172 +652,172 @@ var MERCHANT_PAYOUT_STATUSES = [
1017
652
  "failed",
1018
653
  "cancelled"
1019
654
  ];
1020
- var MoneyKoboSchema = import_zod4.z.number().int().positive().max(Number.MAX_SAFE_INTEGER);
1021
- var MetadataSchema = import_zod4.z.record(
1022
- import_zod4.z.union([import_zod4.z.string(), import_zod4.z.number(), import_zod4.z.boolean(), import_zod4.z.null()])
655
+ var MoneyKoboSchema = import_zod3.z.number().int().positive().max(Number.MAX_SAFE_INTEGER);
656
+ var MetadataSchema = import_zod3.z.record(
657
+ import_zod3.z.union([import_zod3.z.string(), import_zod3.z.number(), import_zod3.z.boolean(), import_zod3.z.null()])
1023
658
  );
1024
- var CurrencySchema2 = import_zod4.z.string().trim().length(3).transform((value) => value.toUpperCase());
1025
- var ReferenceSchema = import_zod4.z.string().trim().min(6).max(128).regex(/^[A-Za-z0-9._:-]+$/);
1026
- var MerchantProfileSchema = import_zod4.z.object({
1027
- accountId: import_zod4.z.string().uuid(),
1028
- legalName: import_zod4.z.string(),
1029
- tradingName: import_zod4.z.string(),
1030
- merchantCategoryCode: import_zod4.z.string().regex(/^\d{4}$/),
1031
- nqrMerchantId: import_zod4.z.string(),
1032
- settlementBankCode: import_zod4.z.string(),
1033
- settlementAccountNumber: import_zod4.z.string(),
1034
- settlementAccountName: import_zod4.z.string(),
1035
- settlementSchedule: import_zod4.z.enum(SETTLEMENT_SCHEDULES),
1036
- status: import_zod4.z.enum(MERCHANT_PROFILE_STATUSES),
1037
- offlineEnabled: import_zod4.z.boolean(),
659
+ var CurrencySchema2 = import_zod3.z.string().trim().length(3).transform((value) => value.toUpperCase());
660
+ var ReferenceSchema = import_zod3.z.string().trim().min(6).max(128).regex(/^[A-Za-z0-9._:-]+$/);
661
+ var MerchantProfileSchema = import_zod3.z.object({
662
+ accountId: import_zod3.z.string().uuid(),
663
+ legalName: import_zod3.z.string(),
664
+ tradingName: import_zod3.z.string(),
665
+ merchantCategoryCode: import_zod3.z.string().regex(/^\d{4}$/),
666
+ nqrMerchantId: import_zod3.z.string(),
667
+ settlementBankCode: import_zod3.z.string(),
668
+ settlementAccountNumber: import_zod3.z.string(),
669
+ settlementAccountName: import_zod3.z.string(),
670
+ settlementSchedule: import_zod3.z.enum(SETTLEMENT_SCHEDULES),
671
+ status: import_zod3.z.enum(MERCHANT_PROFILE_STATUSES),
672
+ offlineEnabled: import_zod3.z.boolean(),
1038
673
  perTxLimitKobo: MoneyKoboSchema,
1039
674
  dailyLimitKobo: MoneyKoboSchema,
1040
675
  metadata: MetadataSchema,
1041
- createdAtMs: import_zod4.z.number().int().nonnegative(),
1042
- updatedAtMs: import_zod4.z.number().int().nonnegative()
676
+ createdAtMs: import_zod3.z.number().int().nonnegative(),
677
+ updatedAtMs: import_zod3.z.number().int().nonnegative()
1043
678
  });
1044
- var UpsertMerchantProfileInputSchema = import_zod4.z.object({
1045
- legalName: import_zod4.z.string().trim().min(1).max(200),
1046
- tradingName: import_zod4.z.string().trim().min(1).max(25),
1047
- merchantCategoryCode: import_zod4.z.string().trim().regex(/^\d{4}$/),
1048
- nqrMerchantId: import_zod4.z.string().trim().min(3).max(64),
1049
- settlementBankCode: import_zod4.z.string().trim().min(2).max(16),
1050
- settlementAccountNumber: import_zod4.z.string().trim().min(5).max(32),
1051
- settlementAccountName: import_zod4.z.string().trim().min(1).max(200),
1052
- settlementSchedule: import_zod4.z.enum(SETTLEMENT_SCHEDULES).optional(),
1053
- status: import_zod4.z.enum(MERCHANT_PROFILE_STATUSES).optional(),
1054
- offlineEnabled: import_zod4.z.boolean().optional(),
679
+ var UpsertMerchantProfileInputSchema = import_zod3.z.object({
680
+ legalName: import_zod3.z.string().trim().min(1).max(200),
681
+ tradingName: import_zod3.z.string().trim().min(1).max(25),
682
+ merchantCategoryCode: import_zod3.z.string().trim().regex(/^\d{4}$/),
683
+ nqrMerchantId: import_zod3.z.string().trim().min(3).max(64),
684
+ settlementBankCode: import_zod3.z.string().trim().min(2).max(16),
685
+ settlementAccountNumber: import_zod3.z.string().trim().min(5).max(32),
686
+ settlementAccountName: import_zod3.z.string().trim().min(1).max(200),
687
+ settlementSchedule: import_zod3.z.enum(SETTLEMENT_SCHEDULES).optional(),
688
+ status: import_zod3.z.enum(MERCHANT_PROFILE_STATUSES).optional(),
689
+ offlineEnabled: import_zod3.z.boolean().optional(),
1055
690
  perTxLimitKobo: MoneyKoboSchema.optional(),
1056
691
  dailyLimitKobo: MoneyKoboSchema.optional(),
1057
692
  metadata: MetadataSchema.optional()
1058
693
  });
1059
- var CollectionIntentSchema = import_zod4.z.object({
1060
- intentId: import_zod4.z.string().uuid(),
1061
- accountId: import_zod4.z.string().uuid(),
1062
- terminalId: import_zod4.z.string().uuid().nullable(),
1063
- reference: import_zod4.z.string(),
1064
- amountKobo: import_zod4.z.number().int().positive().nullable(),
1065
- currency: import_zod4.z.string().length(3),
1066
- status: import_zod4.z.enum(COLLECTION_INTENT_STATUSES),
1067
- description: import_zod4.z.string().nullable(),
1068
- nqrPayload: import_zod4.z.string(),
1069
- provider: import_zod4.z.string(),
1070
- providerReference: import_zod4.z.string().nullable(),
694
+ var CollectionIntentSchema = import_zod3.z.object({
695
+ intentId: import_zod3.z.string().uuid(),
696
+ accountId: import_zod3.z.string().uuid(),
697
+ terminalId: import_zod3.z.string().uuid().nullable(),
698
+ reference: import_zod3.z.string(),
699
+ amountKobo: import_zod3.z.number().int().positive().nullable(),
700
+ currency: import_zod3.z.string().length(3),
701
+ status: import_zod3.z.enum(COLLECTION_INTENT_STATUSES),
702
+ description: import_zod3.z.string().nullable(),
703
+ nqrPayload: import_zod3.z.string(),
704
+ provider: import_zod3.z.string(),
705
+ providerReference: import_zod3.z.string().nullable(),
1071
706
  metadata: MetadataSchema,
1072
- expiresAtMs: import_zod4.z.number().int().nonnegative().nullable(),
1073
- paidAtMs: import_zod4.z.number().int().nonnegative().nullable(),
1074
- createdAtMs: import_zod4.z.number().int().nonnegative(),
1075
- updatedAtMs: import_zod4.z.number().int().nonnegative()
707
+ expiresAtMs: import_zod3.z.number().int().nonnegative().nullable(),
708
+ paidAtMs: import_zod3.z.number().int().nonnegative().nullable(),
709
+ createdAtMs: import_zod3.z.number().int().nonnegative(),
710
+ updatedAtMs: import_zod3.z.number().int().nonnegative()
1076
711
  });
1077
- var CreateCollectionIntentInputSchema = import_zod4.z.object({
712
+ var CreateCollectionIntentInputSchema = import_zod3.z.object({
1078
713
  reference: ReferenceSchema.optional(),
1079
714
  amountKobo: MoneyKoboSchema.optional(),
1080
715
  currency: CurrencySchema2.optional(),
1081
- terminalId: import_zod4.z.string().uuid().optional(),
1082
- terminalLabel: import_zod4.z.string().trim().min(1).max(25).optional(),
1083
- merchantCity: import_zod4.z.string().trim().min(1).max(15).optional(),
1084
- description: import_zod4.z.string().trim().min(1).max(280).optional(),
1085
- expiresAtMs: import_zod4.z.number().int().positive().optional(),
1086
- provider: import_zod4.z.string().trim().min(1).max(40).optional(),
716
+ terminalId: import_zod3.z.string().uuid().optional(),
717
+ terminalLabel: import_zod3.z.string().trim().min(1).max(25).optional(),
718
+ merchantCity: import_zod3.z.string().trim().min(1).max(15).optional(),
719
+ description: import_zod3.z.string().trim().min(1).max(280).optional(),
720
+ expiresAtMs: import_zod3.z.number().int().positive().optional(),
721
+ provider: import_zod3.z.string().trim().min(1).max(40).optional(),
1087
722
  metadata: MetadataSchema.optional()
1088
723
  });
1089
- var PublicCollectionIntentSchema = import_zod4.z.object({
1090
- intentId: import_zod4.z.string().uuid(),
1091
- reference: import_zod4.z.string(),
1092
- amountKobo: import_zod4.z.number().int().positive().nullable(),
1093
- currency: import_zod4.z.string().length(3),
1094
- status: import_zod4.z.enum(COLLECTION_INTENT_STATUSES),
1095
- merchantAccountId: import_zod4.z.string().uuid(),
1096
- merchantName: import_zod4.z.string(),
1097
- merchantCategoryCode: import_zod4.z.string(),
1098
- description: import_zod4.z.string().nullable(),
1099
- expiresAtMs: import_zod4.z.number().int().nonnegative().nullable()
724
+ var PublicCollectionIntentSchema = import_zod3.z.object({
725
+ intentId: import_zod3.z.string().uuid(),
726
+ reference: import_zod3.z.string(),
727
+ amountKobo: import_zod3.z.number().int().positive().nullable(),
728
+ currency: import_zod3.z.string().length(3),
729
+ status: import_zod3.z.enum(COLLECTION_INTENT_STATUSES),
730
+ merchantAccountId: import_zod3.z.string().uuid(),
731
+ merchantName: import_zod3.z.string(),
732
+ merchantCategoryCode: import_zod3.z.string(),
733
+ description: import_zod3.z.string().nullable(),
734
+ expiresAtMs: import_zod3.z.number().int().nonnegative().nullable()
1100
735
  });
1101
- var PayCollectionInputSchema = import_zod4.z.object({
736
+ var PayCollectionInputSchema = import_zod3.z.object({
1102
737
  reference: ReferenceSchema,
1103
738
  amountKobo: MoneyKoboSchema.optional(),
1104
739
  currency: CurrencySchema2.optional(),
1105
- idempotencyKey: import_zod4.z.string().trim().min(8).max(160).optional()
740
+ idempotencyKey: import_zod3.z.string().trim().min(8).max(160).optional()
1106
741
  });
1107
- var CollectionPaymentSchema = import_zod4.z.object({
1108
- paymentId: import_zod4.z.string().uuid(),
1109
- intentId: import_zod4.z.string().uuid(),
1110
- accountId: import_zod4.z.string().uuid(),
1111
- payerUserId: import_zod4.z.string().uuid().nullable(),
1112
- merchantOwnerUserId: import_zod4.z.string().uuid(),
742
+ var CollectionPaymentSchema = import_zod3.z.object({
743
+ paymentId: import_zod3.z.string().uuid(),
744
+ intentId: import_zod3.z.string().uuid(),
745
+ accountId: import_zod3.z.string().uuid(),
746
+ payerUserId: import_zod3.z.string().uuid().nullable(),
747
+ merchantOwnerUserId: import_zod3.z.string().uuid(),
1113
748
  amountKobo: MoneyKoboSchema,
1114
- currency: import_zod4.z.string().length(3),
1115
- status: import_zod4.z.enum(COLLECTION_PAYMENT_STATUSES),
1116
- provider: import_zod4.z.string(),
1117
- providerReference: import_zod4.z.string().nullable(),
1118
- idempotencyKey: import_zod4.z.string().nullable(),
1119
- ledgerRef: import_zod4.z.string(),
1120
- failureCode: import_zod4.z.string().nullable(),
1121
- failureMessage: import_zod4.z.string().nullable(),
1122
- paidAtMs: import_zod4.z.number().int().nonnegative().nullable(),
1123
- createdAtMs: import_zod4.z.number().int().nonnegative(),
1124
- updatedAtMs: import_zod4.z.number().int().nonnegative()
749
+ currency: import_zod3.z.string().length(3),
750
+ status: import_zod3.z.enum(COLLECTION_PAYMENT_STATUSES),
751
+ provider: import_zod3.z.string(),
752
+ providerReference: import_zod3.z.string().nullable(),
753
+ idempotencyKey: import_zod3.z.string().nullable(),
754
+ ledgerRef: import_zod3.z.string(),
755
+ failureCode: import_zod3.z.string().nullable(),
756
+ failureMessage: import_zod3.z.string().nullable(),
757
+ paidAtMs: import_zod3.z.number().int().nonnegative().nullable(),
758
+ createdAtMs: import_zod3.z.number().int().nonnegative(),
759
+ updatedAtMs: import_zod3.z.number().int().nonnegative()
1125
760
  });
1126
- var CollectionPaymentResultSchema = import_zod4.z.object({
761
+ var CollectionPaymentResultSchema = import_zod3.z.object({
1127
762
  payment: CollectionPaymentSchema,
1128
763
  intent: CollectionIntentSchema,
1129
- receipt: import_zod4.z.unknown().optional(),
1130
- replayed: import_zod4.z.boolean()
764
+ receipt: import_zod3.z.unknown().optional(),
765
+ replayed: import_zod3.z.boolean()
1131
766
  });
1132
- var CollectionReportSummarySchema = import_zod4.z.object({
1133
- accountId: import_zod4.z.string().uuid(),
1134
- fromMs: import_zod4.z.number().int().nonnegative(),
1135
- toMs: import_zod4.z.number().int().nonnegative(),
1136
- currency: import_zod4.z.string().length(3),
1137
- paidCount: import_zod4.z.number().int().nonnegative(),
1138
- paidAmountKobo: import_zod4.z.number().int().nonnegative(),
1139
- pendingCount: import_zod4.z.number().int().nonnegative(),
1140
- failedCount: import_zod4.z.number().int().nonnegative(),
1141
- reversedCount: import_zod4.z.number().int().nonnegative(),
1142
- availableBalanceKobo: import_zod4.z.number().int().nonnegative()
767
+ var CollectionReportSummarySchema = import_zod3.z.object({
768
+ accountId: import_zod3.z.string().uuid(),
769
+ fromMs: import_zod3.z.number().int().nonnegative(),
770
+ toMs: import_zod3.z.number().int().nonnegative(),
771
+ currency: import_zod3.z.string().length(3),
772
+ paidCount: import_zod3.z.number().int().nonnegative(),
773
+ paidAmountKobo: import_zod3.z.number().int().nonnegative(),
774
+ pendingCount: import_zod3.z.number().int().nonnegative(),
775
+ failedCount: import_zod3.z.number().int().nonnegative(),
776
+ reversedCount: import_zod3.z.number().int().nonnegative(),
777
+ availableBalanceKobo: import_zod3.z.number().int().nonnegative()
1143
778
  });
1144
- var CollectionStatementSchema = import_zod4.z.object({
1145
- accountId: import_zod4.z.string().uuid(),
1146
- year: import_zod4.z.number().int(),
1147
- month: import_zod4.z.number().int().min(1).max(12),
1148
- currency: import_zod4.z.string().length(3),
1149
- totalPaidKobo: import_zod4.z.number().int().nonnegative(),
1150
- items: import_zod4.z.array(CollectionPaymentSchema)
779
+ var CollectionStatementSchema = import_zod3.z.object({
780
+ accountId: import_zod3.z.string().uuid(),
781
+ year: import_zod3.z.number().int(),
782
+ month: import_zod3.z.number().int().min(1).max(12),
783
+ currency: import_zod3.z.string().length(3),
784
+ totalPaidKobo: import_zod3.z.number().int().nonnegative(),
785
+ items: import_zod3.z.array(CollectionPaymentSchema)
1151
786
  });
1152
- var CreatePayoutInputSchema = import_zod4.z.object({
787
+ var CreatePayoutInputSchema = import_zod3.z.object({
1153
788
  amountKobo: MoneyKoboSchema,
1154
789
  currency: CurrencySchema2.optional(),
1155
- idempotencyKey: import_zod4.z.string().trim().min(8).max(160)
790
+ idempotencyKey: import_zod3.z.string().trim().min(8).max(160)
1156
791
  });
1157
- var MerchantPayoutSchema = import_zod4.z.object({
1158
- payoutId: import_zod4.z.string().uuid(),
1159
- accountId: import_zod4.z.string().uuid(),
792
+ var MerchantPayoutSchema = import_zod3.z.object({
793
+ payoutId: import_zod3.z.string().uuid(),
794
+ accountId: import_zod3.z.string().uuid(),
1160
795
  amountKobo: MoneyKoboSchema,
1161
- currency: import_zod4.z.string().length(3),
1162
- status: import_zod4.z.enum(MERCHANT_PAYOUT_STATUSES),
1163
- idempotencyKey: import_zod4.z.string().nullable(),
1164
- ledgerRef: import_zod4.z.string(),
1165
- providerReference: import_zod4.z.string().nullable(),
1166
- requestedByUserId: import_zod4.z.string().uuid().nullable(),
1167
- failureCode: import_zod4.z.string().nullable(),
1168
- failureMessage: import_zod4.z.string().nullable(),
1169
- createdAtMs: import_zod4.z.number().int().nonnegative(),
1170
- updatedAtMs: import_zod4.z.number().int().nonnegative()
796
+ currency: import_zod3.z.string().length(3),
797
+ status: import_zod3.z.enum(MERCHANT_PAYOUT_STATUSES),
798
+ idempotencyKey: import_zod3.z.string().nullable(),
799
+ ledgerRef: import_zod3.z.string(),
800
+ providerReference: import_zod3.z.string().nullable(),
801
+ requestedByUserId: import_zod3.z.string().uuid().nullable(),
802
+ failureCode: import_zod3.z.string().nullable(),
803
+ failureMessage: import_zod3.z.string().nullable(),
804
+ createdAtMs: import_zod3.z.number().int().nonnegative(),
805
+ updatedAtMs: import_zod3.z.number().int().nonnegative()
1171
806
  });
1172
- var ProviderEventInputSchema = import_zod4.z.object({
1173
- provider: import_zod4.z.string().trim().min(1).max(80),
1174
- eventId: import_zod4.z.string().trim().min(1).max(160),
1175
- eventType: import_zod4.z.string().trim().min(1).max(120),
1176
- payload: import_zod4.z.record(import_zod4.z.unknown()).optional()
807
+ var ProviderEventInputSchema = import_zod3.z.object({
808
+ provider: import_zod3.z.string().trim().min(1).max(80),
809
+ eventId: import_zod3.z.string().trim().min(1).max(160),
810
+ eventType: import_zod3.z.string().trim().min(1).max(120),
811
+ payload: import_zod3.z.record(import_zod3.z.unknown()).optional()
1177
812
  });
1178
- var ProviderEventRecordSchema = import_zod4.z.object({
1179
- id: import_zod4.z.string().uuid(),
1180
- provider: import_zod4.z.string(),
1181
- eventId: import_zod4.z.string(),
1182
- eventType: import_zod4.z.string(),
1183
- signatureVerified: import_zod4.z.boolean(),
1184
- receivedAtMs: import_zod4.z.number().int().nonnegative(),
1185
- processedAtMs: import_zod4.z.number().int().nonnegative().nullable()
813
+ var ProviderEventRecordSchema = import_zod3.z.object({
814
+ id: import_zod3.z.string().uuid(),
815
+ provider: import_zod3.z.string(),
816
+ eventId: import_zod3.z.string(),
817
+ eventType: import_zod3.z.string(),
818
+ signatureVerified: import_zod3.z.boolean(),
819
+ receivedAtMs: import_zod3.z.number().int().nonnegative(),
820
+ processedAtMs: import_zod3.z.number().int().nonnegative().nullable()
1186
821
  });
1187
822
  function createCollectionsClient(opts) {
1188
823
  const fetchImpl = opts.fetchImpl ?? globalThis.fetch;
@@ -1697,7 +1332,7 @@ var FlurClient = class {
1697
1332
  try {
1698
1333
  body = requestSchema ? JSON.stringify(requestSchema.parse(input)) : init2.body;
1699
1334
  } catch (err) {
1700
- if (err instanceof import_zod5.z.ZodError) {
1335
+ if (err instanceof import_zod4.z.ZodError) {
1701
1336
  throw new FlurError("Invalid request payload", "INVALID_REQUEST", {
1702
1337
  details: err.flatten()
1703
1338
  });
@@ -1725,7 +1360,7 @@ var FlurClient = class {
1725
1360
  try {
1726
1361
  return responseSchema.parse(payload);
1727
1362
  } catch (err) {
1728
- if (err instanceof import_zod5.z.ZodError) {
1363
+ if (err instanceof import_zod4.z.ZodError) {
1729
1364
  throw new FlurError(
1730
1365
  "SDK contract validation failed",
1731
1366
  "INVALID_REQUEST",
@@ -2156,7 +1791,7 @@ function constantTimeEqual(a, b) {
2156
1791
  }
2157
1792
 
2158
1793
  // src/offline/oac.ts
2159
- var import_zod6 = require("zod");
1794
+ var import_zod5 = require("zod");
2160
1795
 
2161
1796
  // src/crypto/p256-issuer.ts
2162
1797
  var import_nist = require("@noble/curves/nist");
@@ -2238,20 +1873,20 @@ function verifyIssuerP256(bytes, signatureB64, issuerPublicKeySpkiB64) {
2238
1873
  var OAC_DEFAULT_PER_TX_KOBO = 5e5;
2239
1874
  var OAC_DEFAULT_CUMULATIVE_KOBO = 2e6;
2240
1875
  var OAC_DEFAULT_VALIDITY_MS = 24 * 60 * 60 * 1e3;
2241
- var Base64Std2 = import_zod6.z.string().min(16).max(4096).regex(/^[A-Za-z0-9+/]+={0,2}$/, "expected base64 (standard) string");
2242
- var OACSchema = import_zod6.z.object({
2243
- userId: import_zod6.z.string().min(1),
2244
- deviceId: import_zod6.z.string().min(1),
1876
+ var Base64Std = import_zod5.z.string().min(16).max(4096).regex(/^[A-Za-z0-9+/]+={0,2}$/, "expected base64 (standard) string");
1877
+ var OACSchema = import_zod5.z.object({
1878
+ userId: import_zod5.z.string().min(1),
1879
+ deviceId: import_zod5.z.string().min(1),
2245
1880
  /** SubjectPublicKeyInfo DER, base64 (P-256). */
2246
- devicePublicKey: Base64Std2,
2247
- perTxCapKobo: import_zod6.z.number().int().nonnegative(),
2248
- cumulativeCapKobo: import_zod6.z.number().int().nonnegative(),
2249
- validFromMs: import_zod6.z.number().int().nonnegative(),
2250
- validUntilMs: import_zod6.z.number().int().positive(),
2251
- counterSeed: import_zod6.z.number().int().nonnegative(),
2252
- nonce: import_zod6.z.string().min(1),
1881
+ devicePublicKey: Base64Std,
1882
+ perTxCapKobo: import_zod5.z.number().int().nonnegative(),
1883
+ cumulativeCapKobo: import_zod5.z.number().int().nonnegative(),
1884
+ validFromMs: import_zod5.z.number().int().nonnegative(),
1885
+ validUntilMs: import_zod5.z.number().int().positive(),
1886
+ counterSeed: import_zod5.z.number().int().nonnegative(),
1887
+ nonce: import_zod5.z.string().min(1),
2253
1888
  /** ASN.1 DER ECDSA(SHA-256) signature, base64. */
2254
- issuerSig: Base64Std2
1889
+ issuerSig: Base64Std
2255
1890
  }).refine((v) => v.validUntilMs > v.validFromMs, {
2256
1891
  message: "validUntilMs must be greater than validFromMs"
2257
1892
  }).refine((v) => v.perTxCapKobo <= v.cumulativeCapKobo, {
@@ -2345,19 +1980,19 @@ function decodeBase45(s) {
2345
1980
  }
2346
1981
 
2347
1982
  // src/offline/messages.ts
2348
- var import_zod7 = require("zod");
2349
- var Base64Sig = import_zod7.z.string().min(16).max(4096).regex(/^[A-Za-z0-9+/]+={0,2}$/, "expected base64 (standard) signature");
2350
- var OfflinePaymentRequestSchema = import_zod7.z.object({
2351
- reference: import_zod7.z.string().min(1),
2352
- amountKobo: import_zod7.z.number().int().positive(),
1983
+ var import_zod6 = require("zod");
1984
+ var Base64Sig = import_zod6.z.string().min(16).max(4096).regex(/^[A-Za-z0-9+/]+={0,2}$/, "expected base64 (standard) signature");
1985
+ var OfflinePaymentRequestSchema = import_zod6.z.object({
1986
+ reference: import_zod6.z.string().min(1),
1987
+ amountKobo: import_zod6.z.number().int().positive(),
2353
1988
  merchantOAC: OACSchema,
2354
- expiresAtMs: import_zod7.z.number().int().positive(),
1989
+ expiresAtMs: import_zod6.z.number().int().positive(),
2355
1990
  merchantSig: Base64Sig
2356
1991
  });
2357
- var OfflinePaymentAuthorizationSchema = import_zod7.z.object({
1992
+ var OfflinePaymentAuthorizationSchema = import_zod6.z.object({
2358
1993
  request: OfflinePaymentRequestSchema,
2359
1994
  payerOAC: OACSchema,
2360
- payerCounter: import_zod7.z.number().int().positive(),
1995
+ payerCounter: import_zod6.z.number().int().positive(),
2361
1996
  payerSig: Base64Sig
2362
1997
  });
2363
1998
  function buildPaymentRequest(input) {
@@ -2469,60 +2104,60 @@ function decodeAuthorizationQR(s) {
2469
2104
  }
2470
2105
 
2471
2106
  // src/offline/settlements.ts
2472
- var import_zod8 = require("zod");
2107
+ var import_zod7 = require("zod");
2473
2108
  var import_sha256 = require("@noble/hashes/sha256");
2474
2109
  var import_utils = require("@noble/hashes/utils");
2475
- var OfflineTokenSchema = import_zod8.z.object({
2476
- tokenId: import_zod8.z.string().uuid(),
2477
- tokenSerial: import_zod8.z.string(),
2478
- issuerAccountId: import_zod8.z.string().uuid(),
2479
- payerUserId: import_zod8.z.string().uuid(),
2480
- maxAmountKobo: import_zod8.z.number().int().positive(),
2481
- currency: import_zod8.z.string().length(3),
2482
- issuedAtMs: import_zod8.z.number().int().nonnegative(),
2483
- expiresAtMs: import_zod8.z.number().int().nonnegative(),
2484
- issuerSig: import_zod8.z.string()
2110
+ var OfflineTokenSchema = import_zod7.z.object({
2111
+ tokenId: import_zod7.z.string().uuid(),
2112
+ tokenSerial: import_zod7.z.string(),
2113
+ issuerAccountId: import_zod7.z.string().uuid(),
2114
+ payerUserId: import_zod7.z.string().uuid(),
2115
+ maxAmountKobo: import_zod7.z.number().int().positive(),
2116
+ currency: import_zod7.z.string().length(3),
2117
+ issuedAtMs: import_zod7.z.number().int().nonnegative(),
2118
+ expiresAtMs: import_zod7.z.number().int().nonnegative(),
2119
+ issuerSig: import_zod7.z.string()
2485
2120
  });
2486
- var PaymentClaimSchema = import_zod8.z.object({
2487
- encounterId: import_zod8.z.string().regex(/^[0-9a-f]{64}$/i).optional(),
2488
- tokenSerial: import_zod8.z.string(),
2489
- payerUserId: import_zod8.z.string().uuid(),
2490
- payeeUserId: import_zod8.z.string().uuid(),
2491
- payerNonce: import_zod8.z.string(),
2492
- payeeNonce: import_zod8.z.string(),
2493
- amountKobo: import_zod8.z.number().int().positive(),
2494
- currency: import_zod8.z.string().length(3).default("NGN"),
2495
- occurredAtMs: import_zod8.z.number().int().nonnegative(),
2496
- completedAtMs: import_zod8.z.number().int().nonnegative().optional(),
2497
- contextId: import_zod8.z.string().optional(),
2121
+ var PaymentClaimSchema = import_zod7.z.object({
2122
+ encounterId: import_zod7.z.string().regex(/^[0-9a-f]{64}$/i).optional(),
2123
+ tokenSerial: import_zod7.z.string(),
2124
+ payerUserId: import_zod7.z.string().uuid(),
2125
+ payeeUserId: import_zod7.z.string().uuid(),
2126
+ payerNonce: import_zod7.z.string(),
2127
+ payeeNonce: import_zod7.z.string(),
2128
+ amountKobo: import_zod7.z.number().int().positive(),
2129
+ currency: import_zod7.z.string().length(3).default("NGN"),
2130
+ occurredAtMs: import_zod7.z.number().int().nonnegative(),
2131
+ completedAtMs: import_zod7.z.number().int().nonnegative().optional(),
2132
+ contextId: import_zod7.z.string().optional(),
2498
2133
  // Stage 2c: P-256 device keys are now SubjectPublicKeyInfo DER, base64.
2499
2134
  // Signatures are ASN.1 DER ECDSA(SHA-256), base64. Backwards-incompatible
2500
2135
  // wire change; the backend has the matching widening in offline-settlements
2501
2136
  // service + zod schema.
2502
- payerPubkey: import_zod8.z.string().min(16).max(4096).regex(/^[A-Za-z0-9+/]+={0,2}$/),
2503
- payerSignature: import_zod8.z.string().min(16).max(4096).regex(/^[A-Za-z0-9+/]+={0,2}$/),
2504
- payeePubkey: import_zod8.z.string().min(16).max(4096).regex(/^[A-Za-z0-9+/]+={0,2}$/).optional(),
2505
- payeeSignature: import_zod8.z.string().min(16).max(4096).regex(/^[A-Za-z0-9+/]+={0,2}$/).optional()
2137
+ payerPubkey: import_zod7.z.string().min(16).max(4096).regex(/^[A-Za-z0-9+/]+={0,2}$/),
2138
+ payerSignature: import_zod7.z.string().min(16).max(4096).regex(/^[A-Za-z0-9+/]+={0,2}$/),
2139
+ payeePubkey: import_zod7.z.string().min(16).max(4096).regex(/^[A-Za-z0-9+/]+={0,2}$/).optional(),
2140
+ payeeSignature: import_zod7.z.string().min(16).max(4096).regex(/^[A-Za-z0-9+/]+={0,2}$/).optional()
2506
2141
  });
2507
- var SettlementSchema = import_zod8.z.object({
2508
- settlementId: import_zod8.z.string().uuid(),
2509
- settlementKey: import_zod8.z.string().regex(/^[0-9a-f]{64}$/i),
2510
- encounterId: import_zod8.z.string().regex(/^[0-9a-f]{64}$/i),
2511
- issuerAccountId: import_zod8.z.string().uuid(),
2512
- tokenSerial: import_zod8.z.string(),
2513
- payerUserId: import_zod8.z.string().uuid(),
2514
- payeeUserId: import_zod8.z.string().uuid(),
2515
- amountKobo: import_zod8.z.number().int().nonnegative(),
2516
- currency: import_zod8.z.string().length(3),
2517
- receiptId: import_zod8.z.string().nullable(),
2518
- status: import_zod8.z.enum(["SETTLED", "REVIEW", "REJECTED"]),
2519
- issuerSig: import_zod8.z.string(),
2520
- createdAtMs: import_zod8.z.number().int().nonnegative()
2142
+ var SettlementSchema = import_zod7.z.object({
2143
+ settlementId: import_zod7.z.string().uuid(),
2144
+ settlementKey: import_zod7.z.string().regex(/^[0-9a-f]{64}$/i),
2145
+ encounterId: import_zod7.z.string().regex(/^[0-9a-f]{64}$/i),
2146
+ issuerAccountId: import_zod7.z.string().uuid(),
2147
+ tokenSerial: import_zod7.z.string(),
2148
+ payerUserId: import_zod7.z.string().uuid(),
2149
+ payeeUserId: import_zod7.z.string().uuid(),
2150
+ amountKobo: import_zod7.z.number().int().nonnegative(),
2151
+ currency: import_zod7.z.string().length(3),
2152
+ receiptId: import_zod7.z.string().nullable(),
2153
+ status: import_zod7.z.enum(["SETTLED", "REVIEW", "REJECTED"]),
2154
+ issuerSig: import_zod7.z.string(),
2155
+ createdAtMs: import_zod7.z.number().int().nonnegative()
2521
2156
  });
2522
- var SettleResponseSchema = import_zod8.z.object({
2157
+ var SettleResponseSchema = import_zod7.z.object({
2523
2158
  settlement: SettlementSchema,
2524
- encounterId: import_zod8.z.string().regex(/^[0-9a-f]{64}$/i),
2525
- replayed: import_zod8.z.boolean()
2159
+ encounterId: import_zod7.z.string().regex(/^[0-9a-f]{64}$/i),
2160
+ replayed: import_zod7.z.boolean()
2526
2161
  });
2527
2162
  var ENCOUNTER_DOMAIN = "offline:v1:encounter";
2528
2163
  async function sha256Hex(input) {
@@ -2696,7 +2331,7 @@ function createHmacFetch(opts) {
2696
2331
  }
2697
2332
 
2698
2333
  // src/partner/client.ts
2699
- var import_zod9 = require("zod");
2334
+ var import_zod8 = require("zod");
2700
2335
  var import_sha2563 = require("@noble/hashes/sha256");
2701
2336
  var import_hmac4 = require("@noble/hashes/hmac");
2702
2337
  var import_utils2 = require("@noble/hashes/utils");
@@ -2720,18 +2355,18 @@ var PARTNER_SCOPES = [
2720
2355
  "partner:payout:write",
2721
2356
  "partner:reconciliation:read"
2722
2357
  ];
2723
- var ApiCredentialPublicSchema = import_zod9.z.object({
2724
- id: import_zod9.z.string().uuid(),
2725
- accountId: import_zod9.z.string().uuid(),
2726
- keyId: import_zod9.z.string(),
2727
- scopes: import_zod9.z.array(import_zod9.z.enum(PARTNER_SCOPES)),
2728
- label: import_zod9.z.string().nullable(),
2729
- createdAtMs: import_zod9.z.number().int().nonnegative(),
2730
- lastUsedAtMs: import_zod9.z.number().int().nonnegative().nullable(),
2731
- revokedAtMs: import_zod9.z.number().int().nonnegative().nullable()
2358
+ var ApiCredentialPublicSchema = import_zod8.z.object({
2359
+ id: import_zod8.z.string().uuid(),
2360
+ accountId: import_zod8.z.string().uuid(),
2361
+ keyId: import_zod8.z.string(),
2362
+ scopes: import_zod8.z.array(import_zod8.z.enum(PARTNER_SCOPES)),
2363
+ label: import_zod8.z.string().nullable(),
2364
+ createdAtMs: import_zod8.z.number().int().nonnegative(),
2365
+ lastUsedAtMs: import_zod8.z.number().int().nonnegative().nullable(),
2366
+ revokedAtMs: import_zod8.z.number().int().nonnegative().nullable()
2732
2367
  });
2733
2368
  var MintedApiCredentialSchema = ApiCredentialPublicSchema.extend({
2734
- secret: import_zod9.z.string().min(1)
2369
+ secret: import_zod8.z.string().min(1)
2735
2370
  });
2736
2371
  var enc = new TextEncoder();
2737
2372
  async function sha256Hex2(input) {
@@ -2888,8 +2523,8 @@ function createApiCredentialsAdminClient(opts) {
2888
2523
  }
2889
2524
  return parser(raw);
2890
2525
  }
2891
- const listSchema = import_zod9.z.object({
2892
- items: import_zod9.z.array(ApiCredentialPublicSchema)
2526
+ const listSchema = import_zod8.z.object({
2527
+ items: import_zod8.z.array(ApiCredentialPublicSchema)
2893
2528
  });
2894
2529
  return {
2895
2530
  list: (accountId) => call(
@@ -2914,7 +2549,7 @@ function createApiCredentialsAdminClient(opts) {
2914
2549
  }
2915
2550
 
2916
2551
  // src/passes/pass.ts
2917
- var import_zod10 = require("zod");
2552
+ var import_zod9 = require("zod");
2918
2553
  var PASS_KINDS = [
2919
2554
  "ride-ticket",
2920
2555
  "transit-pass",
@@ -2930,39 +2565,39 @@ var PASS_STATES = [
2930
2565
  "expired",
2931
2566
  "revoked"
2932
2567
  ];
2933
- var PassMetadataSchema = import_zod10.z.record(
2934
- import_zod10.z.union([import_zod10.z.string(), import_zod10.z.number(), import_zod10.z.boolean(), import_zod10.z.null()])
2568
+ var PassMetadataSchema = import_zod9.z.record(
2569
+ import_zod9.z.union([import_zod9.z.string(), import_zod9.z.number(), import_zod9.z.boolean(), import_zod9.z.null()])
2935
2570
  );
2936
- var PassSchema = import_zod10.z.object({
2937
- passId: import_zod10.z.string().min(1),
2571
+ var PassSchema = import_zod9.z.object({
2572
+ passId: import_zod9.z.string().min(1),
2938
2573
  /** Optional client/template grouping id (server may omit). */
2939
- templateId: import_zod10.z.string().min(1).optional(),
2574
+ templateId: import_zod9.z.string().min(1).optional(),
2940
2575
  /** Optional human-facing holder identity (server may omit). The cryptographic binding
2941
2576
  * is `holderDevicePubkey` below. */
2942
- holderUserId: import_zod10.z.string().min(1).optional(),
2943
- kind: import_zod10.z.enum(PASS_KINDS),
2944
- issuerId: import_zod10.z.string().min(1),
2945
- issuedAtMs: import_zod10.z.number().int().nonnegative(),
2946
- validFromMs: import_zod10.z.number().int().nonnegative(),
2947
- validUntilMs: import_zod10.z.number().int().positive(),
2948
- state: import_zod10.z.enum(PASS_STATES),
2577
+ holderUserId: import_zod9.z.string().min(1).optional(),
2578
+ kind: import_zod9.z.enum(PASS_KINDS),
2579
+ issuerId: import_zod9.z.string().min(1),
2580
+ issuedAtMs: import_zod9.z.number().int().nonnegative(),
2581
+ validFromMs: import_zod9.z.number().int().nonnegative(),
2582
+ validUntilMs: import_zod9.z.number().int().positive(),
2583
+ state: import_zod9.z.enum(PASS_STATES),
2949
2584
  metadata: PassMetadataSchema,
2950
- nonce: import_zod10.z.string().min(1),
2585
+ nonce: import_zod9.z.string().min(1),
2951
2586
  /** Device id this pass is bound to (FK to backend `device_keys`). */
2952
- holderDeviceId: import_zod10.z.string().min(1),
2587
+ holderDeviceId: import_zod9.z.string().min(1),
2953
2588
  /** SubjectPublicKeyInfo DER (P-256) of the bound device, base64. The redemption
2954
2589
  * signature is verified against this key — it is the security-critical binding. */
2955
- holderDevicePubkey: import_zod10.z.string().min(64).max(4096).regex(/^[A-Za-z0-9+/]+={0,2}$/),
2590
+ holderDevicePubkey: import_zod9.z.string().min(64).max(4096).regex(/^[A-Za-z0-9+/]+={0,2}$/),
2956
2591
  /** Optional fixed amount for monetary passes (vouchers, gift cards) in kobo. */
2957
- amountKobo: import_zod10.z.number().int().nonnegative().optional(),
2592
+ amountKobo: import_zod9.z.number().int().nonnegative().optional(),
2958
2593
  /** ISO-4217-ish currency code; required on the wire. SDK builders default to NGN. */
2959
- currency: import_zod10.z.string().min(3).max(8),
2594
+ currency: import_zod9.z.string().min(3).max(8),
2960
2595
  /** Monotonic redemption counter floor. Redemption.counter MUST be > counterSeed. */
2961
- counterSeed: import_zod10.z.number().int().nonnegative(),
2596
+ counterSeed: import_zod9.z.number().int().nonnegative(),
2962
2597
  /** Optional cumulative spend cap in kobo across all redemptions of this pass. */
2963
- cumulativeCapKobo: import_zod10.z.number().int().nonnegative().optional(),
2598
+ cumulativeCapKobo: import_zod9.z.number().int().nonnegative().optional(),
2964
2599
  /** ASN.1 DER ECDSA P-256 signature, base64. */
2965
- issuerSig: import_zod10.z.string().min(64).max(2048).regex(/^[A-Za-z0-9+/]+={0,2}$/)
2600
+ issuerSig: import_zod9.z.string().min(64).max(2048).regex(/^[A-Za-z0-9+/]+={0,2}$/)
2966
2601
  }).refine((v) => v.validUntilMs > v.validFromMs, {
2967
2602
  message: "validUntilMs must be greater than validFromMs"
2968
2603
  });
@@ -3019,20 +2654,20 @@ function isPassWithinValidity(pass, nowMs) {
3019
2654
  }
3020
2655
 
3021
2656
  // src/passes/redemption.ts
3022
- var import_zod11 = require("zod");
3023
- var Base64Std3 = import_zod11.z.string().min(16).max(2048).regex(/^[A-Za-z0-9+/]+={0,2}$/, "expected base64 (std)");
3024
- var RedemptionSchema = import_zod11.z.object({
2657
+ var import_zod10 = require("zod");
2658
+ var Base64Std2 = import_zod10.z.string().min(16).max(2048).regex(/^[A-Za-z0-9+/]+={0,2}$/, "expected base64 (std)");
2659
+ var RedemptionSchema = import_zod10.z.object({
3025
2660
  pass: PassSchema,
3026
- redeemerId: import_zod11.z.string().min(1),
3027
- redeemedAtMs: import_zod11.z.number().int().nonnegative(),
2661
+ redeemerId: import_zod10.z.string().min(1),
2662
+ redeemedAtMs: import_zod10.z.number().int().nonnegative(),
3028
2663
  /** Strictly monotonic counter scoped to a single pass. Must be > pass.counterSeed
3029
2664
  * and > the redeemer's lastSeenCounter for this pass. */
3030
- counter: import_zod11.z.number().int().positive(),
2665
+ counter: import_zod10.z.number().int().positive(),
3031
2666
  /** Amount being redeemed in kobo (0 for non-monetary passes like ride tickets). */
3032
- amountKobo: import_zod11.z.number().int().nonnegative(),
3033
- nonce: import_zod11.z.string().min(1),
2667
+ amountKobo: import_zod10.z.number().int().nonnegative(),
2668
+ nonce: import_zod10.z.string().min(1),
3034
2669
  /** ASN.1 DER ECDSA P-256 signature over canonicalJSONBytes(unsigned), base64. */
3035
- holderSig: Base64Std3
2670
+ holderSig: Base64Std2
3036
2671
  });
3037
2672
  var REDEEMABLE_STATES = /* @__PURE__ */ new Set(["issued", "active"]);
3038
2673
  function buildRedemption(input) {
@@ -3114,40 +2749,40 @@ function verifyRedemption(r, issuerPublicKeySpkiB64) {
3114
2749
  }
3115
2750
 
3116
2751
  // src/receipts/receipt.ts
3117
- var import_zod12 = require("zod");
2752
+ var import_zod11 = require("zod");
3118
2753
  var RECEIPT_CHANNELS = ["cash", "pass"];
3119
2754
  var RECEIPT_KINDS = RECEIPT_CHANNELS;
3120
- var ReceiptPayloadSchema = import_zod12.z.record(
3121
- import_zod12.z.union([import_zod12.z.string(), import_zod12.z.number(), import_zod12.z.boolean(), import_zod12.z.null()])
2755
+ var ReceiptPayloadSchema = import_zod11.z.record(
2756
+ import_zod11.z.union([import_zod11.z.string(), import_zod11.z.number(), import_zod11.z.boolean(), import_zod11.z.null()])
3122
2757
  );
3123
- var ReceiptSchema = import_zod12.z.object({
3124
- receiptId: import_zod12.z.string().min(1),
3125
- channel: import_zod12.z.enum(RECEIPT_CHANNELS),
2758
+ var ReceiptSchema = import_zod11.z.object({
2759
+ receiptId: import_zod11.z.string().min(1),
2760
+ channel: import_zod11.z.enum(RECEIPT_CHANNELS),
3126
2761
  /** Cash-channel: send_intents.id. Required when channel === 'cash'. */
3127
- intentId: import_zod12.z.string().min(1).optional(),
2762
+ intentId: import_zod11.z.string().min(1).optional(),
3128
2763
  /** Pass-channel: pass_redemptions.id. Required when channel === 'pass'. */
3129
- passRedemptionId: import_zod12.z.string().min(1).optional(),
3130
- payerUserId: import_zod12.z.string().min(1),
3131
- payeeUserId: import_zod12.z.string().min(1),
3132
- amountKobo: import_zod12.z.number().int().nonnegative(),
3133
- currency: import_zod12.z.string().min(3).max(8),
3134
- issuedAtMs: import_zod12.z.number().int().nonnegative(),
3135
- issuerId: import_zod12.z.string().min(1),
2764
+ passRedemptionId: import_zod11.z.string().min(1).optional(),
2765
+ payerUserId: import_zod11.z.string().min(1),
2766
+ payeeUserId: import_zod11.z.string().min(1),
2767
+ amountKobo: import_zod11.z.number().int().nonnegative(),
2768
+ currency: import_zod11.z.string().min(3).max(8),
2769
+ issuedAtMs: import_zod11.z.number().int().nonnegative(),
2770
+ issuerId: import_zod11.z.string().min(1),
3136
2771
  payload: ReceiptPayloadSchema,
3137
2772
  /** ASN.1 DER ECDSA P-256 signature, base64. */
3138
- issuerSig: import_zod12.z.string().min(64).max(2048).regex(/^[A-Za-z0-9+/]+={0,2}$/)
2773
+ issuerSig: import_zod11.z.string().min(64).max(2048).regex(/^[A-Za-z0-9+/]+={0,2}$/)
3139
2774
  }).superRefine((v, ctx) => {
3140
2775
  if (v.channel === "cash") {
3141
2776
  if (!v.intentId) {
3142
2777
  ctx.addIssue({
3143
- code: import_zod12.z.ZodIssueCode.custom,
2778
+ code: import_zod11.z.ZodIssueCode.custom,
3144
2779
  message: "cash receipts require intentId",
3145
2780
  path: ["intentId"]
3146
2781
  });
3147
2782
  }
3148
2783
  if (v.passRedemptionId) {
3149
2784
  ctx.addIssue({
3150
- code: import_zod12.z.ZodIssueCode.custom,
2785
+ code: import_zod11.z.ZodIssueCode.custom,
3151
2786
  message: "cash receipts must not carry passRedemptionId",
3152
2787
  path: ["passRedemptionId"]
3153
2788
  });
@@ -3155,14 +2790,14 @@ var ReceiptSchema = import_zod12.z.object({
3155
2790
  } else if (v.channel === "pass") {
3156
2791
  if (!v.passRedemptionId) {
3157
2792
  ctx.addIssue({
3158
- code: import_zod12.z.ZodIssueCode.custom,
2793
+ code: import_zod11.z.ZodIssueCode.custom,
3159
2794
  message: "pass receipts require passRedemptionId",
3160
2795
  path: ["passRedemptionId"]
3161
2796
  });
3162
2797
  }
3163
2798
  if (v.intentId) {
3164
2799
  ctx.addIssue({
3165
- code: import_zod12.z.ZodIssueCode.custom,
2800
+ code: import_zod11.z.ZodIssueCode.custom,
3166
2801
  message: "pass receipts must not carry intentId",
3167
2802
  path: ["intentId"]
3168
2803
  });
@@ -3464,23 +3099,23 @@ function init(opts) {
3464
3099
  }
3465
3100
 
3466
3101
  // src/accounts/client.ts
3467
- var import_zod13 = require("zod");
3102
+ var import_zod12 = require("zod");
3468
3103
  var ACCOUNT_TYPES = ["personal", "business", "partner"];
3469
3104
  var ACCOUNT_STATUSES = ["active", "suspended", "closed"];
3470
3105
  var MEMBERSHIP_ROLES = ["owner", "admin", "driver", "staff"];
3471
- var AccountSchema = import_zod13.z.object({
3472
- accountId: import_zod13.z.string().uuid(),
3473
- type: import_zod13.z.enum(ACCOUNT_TYPES),
3474
- displayName: import_zod13.z.string().min(1),
3475
- status: import_zod13.z.enum(ACCOUNT_STATUSES),
3476
- ownerUserId: import_zod13.z.string().uuid().nullable(),
3477
- createdAtMs: import_zod13.z.number().int().nonnegative()
3106
+ var AccountSchema = import_zod12.z.object({
3107
+ accountId: import_zod12.z.string().uuid(),
3108
+ type: import_zod12.z.enum(ACCOUNT_TYPES),
3109
+ displayName: import_zod12.z.string().min(1),
3110
+ status: import_zod12.z.enum(ACCOUNT_STATUSES),
3111
+ ownerUserId: import_zod12.z.string().uuid().nullable(),
3112
+ createdAtMs: import_zod12.z.number().int().nonnegative()
3478
3113
  });
3479
- var AccountMembershipSchema = import_zod13.z.object({
3480
- accountId: import_zod13.z.string().uuid(),
3481
- userId: import_zod13.z.string().uuid(),
3482
- role: import_zod13.z.enum(MEMBERSHIP_ROLES),
3483
- createdAtMs: import_zod13.z.number().int().nonnegative()
3114
+ var AccountMembershipSchema = import_zod12.z.object({
3115
+ accountId: import_zod12.z.string().uuid(),
3116
+ userId: import_zod12.z.string().uuid(),
3117
+ role: import_zod12.z.enum(MEMBERSHIP_ROLES),
3118
+ createdAtMs: import_zod12.z.number().int().nonnegative()
3484
3119
  });
3485
3120
  function createAccountsClient(opts) {
3486
3121
  const fetchImpl = opts.fetchImpl ?? globalThis.fetch;
@@ -3513,9 +3148,9 @@ function createAccountsClient(opts) {
3513
3148
  }
3514
3149
  return parser(raw);
3515
3150
  }
3516
- const itemsSchema = import_zod13.z.object({ items: import_zod13.z.array(AccountSchema) });
3517
- const memberItemsSchema = import_zod13.z.object({
3518
- items: import_zod13.z.array(AccountMembershipSchema)
3151
+ const itemsSchema = import_zod12.z.object({ items: import_zod12.z.array(AccountSchema) });
3152
+ const memberItemsSchema = import_zod12.z.object({
3153
+ items: import_zod12.z.array(AccountMembershipSchema)
3519
3154
  });
3520
3155
  return {
3521
3156
  listMyAccounts: () => call(
@@ -3546,6 +3181,221 @@ function createAccountsClient(opts) {
3546
3181
  };
3547
3182
  }
3548
3183
 
3184
+ // src/me-offline/client.ts
3185
+ var import_zod13 = require("zod");
3186
+ var Sha256Hex = import_zod13.z.string().regex(/^[0-9a-f]{64}$/);
3187
+ var Base64Std3 = import_zod13.z.string().regex(/^[A-Za-z0-9+/]+={0,2}$/);
3188
+ var ACCOUNT_FUNDED_OAC_MAX_TTL_MS = 1e3 * 60 * 60 * 24 * 7;
3189
+ var CONSUMER_OFFLINE_CLAIM_SUBMIT_GRACE_MS = 1e3 * 60 * 60 * 24;
3190
+ var AttestationSecurityLevelSchema = import_zod13.z.enum([
3191
+ "STRONGBOX",
3192
+ "TEE",
3193
+ "SECURE_ENCLAVE",
3194
+ "SOFTWARE"
3195
+ ]);
3196
+ var DeviceKeyAlgSchema = import_zod13.z.literal("p256");
3197
+ var RegisterDeviceKeyP256InputSchema = import_zod13.z.object({
3198
+ deviceId: import_zod13.z.string().min(1).max(128),
3199
+ /** P-256 SubjectPublicKeyInfo DER, base64. */
3200
+ publicKeySpkiB64: Base64Std3.min(64).max(4096),
3201
+ /** Base64 of the server-issued enrollment challenge string. */
3202
+ challengeB64: Base64Std3.min(8).max(1024),
3203
+ /** iOS App Attest payload or Android X.509 Key Attestation chain. */
3204
+ attestationChainB64: import_zod13.z.array(Base64Std3.min(16).max(16384)).min(1).max(16),
3205
+ securityLevel: AttestationSecurityLevelSchema
3206
+ });
3207
+ var P256EnrollmentChallengeInputSchema = import_zod13.z.object({
3208
+ deviceId: import_zod13.z.string().min(1).max(128)
3209
+ });
3210
+ var P256EnrollmentChallengeResultSchema = import_zod13.z.object({
3211
+ challenge: import_zod13.z.string().min(16),
3212
+ expiresAtMs: import_zod13.z.number().int().positive()
3213
+ });
3214
+ var DeviceKeyRecordSchema = import_zod13.z.object({
3215
+ id: import_zod13.z.string().uuid(),
3216
+ userId: import_zod13.z.string().uuid(),
3217
+ deviceId: import_zod13.z.string(),
3218
+ /** Always 'p256' on the consumer offline rail. Field retained for forward-compat. */
3219
+ alg: DeviceKeyAlgSchema.default("p256"),
3220
+ /** P-256 SubjectPublicKeyInfo DER, base64. */
3221
+ publicKeySpkiB64: Base64Std3.nullable().default(null),
3222
+ securityLevel: AttestationSecurityLevelSchema.nullable().default(null),
3223
+ hardwareBacked: import_zod13.z.boolean().default(false),
3224
+ attestedAtMs: import_zod13.z.number().int().nonnegative().nullable().default(null),
3225
+ createdAtMs: import_zod13.z.number().int().nonnegative(),
3226
+ revokedAtMs: import_zod13.z.number().int().nonnegative().nullable()
3227
+ });
3228
+ var ConsumerOACSchema = import_zod13.z.object({
3229
+ oacId: import_zod13.z.string().uuid(),
3230
+ issuerId: import_zod13.z.string().min(1).max(64),
3231
+ userId: import_zod13.z.string().uuid(),
3232
+ deviceId: import_zod13.z.string().min(1).max(128),
3233
+ /**
3234
+ * Always 'p256'. Required on the wire (backend always emits it).
3235
+ * Kept as a literal so input/output infer identically and the schema
3236
+ * can be nested inside other response shapes without Zod input/output
3237
+ * divergence under tsup DTS bundling.
3238
+ */
3239
+ alg: import_zod13.z.literal("p256"),
3240
+ /** P-256 SubjectPublicKeyInfo DER, base64. */
3241
+ devicePubkeySpkiB64: Base64Std3.min(64).max(4096),
3242
+ perTxCapKobo: import_zod13.z.number().int().positive(),
3243
+ cumulativeCapKobo: import_zod13.z.number().int().positive(),
3244
+ currency: import_zod13.z.string().length(3),
3245
+ validFromMs: import_zod13.z.number().int().nonnegative(),
3246
+ validUntilMs: import_zod13.z.number().int().nonnegative(),
3247
+ counterSeed: import_zod13.z.number().int().nonnegative(),
3248
+ issuedAtMs: import_zod13.z.number().int().nonnegative()
3249
+ });
3250
+ var SignedConsumerOACSchema = import_zod13.z.object({
3251
+ oac: ConsumerOACSchema,
3252
+ /** ASN.1 DER ECDSA P-256 issuer signature, base64. */
3253
+ issuerSig: Base64Std3.min(16).max(2048),
3254
+ /** Issuer's P-256 public key as SubjectPublicKeyInfo DER, base64. */
3255
+ issuerPublicKeySpkiB64: Base64Std3.min(64).max(4096)
3256
+ });
3257
+ var OACRecordSchema = SignedConsumerOACSchema.extend({
3258
+ currentOfflineSpentKobo: import_zod13.z.number().int().nonnegative(),
3259
+ status: import_zod13.z.enum(["active", "superseded", "expired", "revoked"]),
3260
+ supersededAtMs: import_zod13.z.number().int().nonnegative().nullable(),
3261
+ revokedAtMs: import_zod13.z.number().int().nonnegative().nullable()
3262
+ });
3263
+ var IssueAccountOacInputSchema = import_zod13.z.object({
3264
+ deviceId: import_zod13.z.string().min(1).max(128),
3265
+ perTxCapKobo: import_zod13.z.number().int().positive().optional(),
3266
+ cumulativeCapKobo: import_zod13.z.number().int().positive().optional(),
3267
+ ttlMs: import_zod13.z.number().int().min(6e4).max(ACCOUNT_FUNDED_OAC_MAX_TTL_MS).optional()
3268
+ });
3269
+ var OfflineStatusResultSchema = import_zod13.z.object({
3270
+ active: OACRecordSchema.nullable()
3271
+ });
3272
+ var ConsumerPaymentClaimSchema = import_zod13.z.object({
3273
+ /** Always 'p256'. Retained for forward-compat and as an explicit domain marker. */
3274
+ alg: import_zod13.z.literal("p256").default("p256"),
3275
+ oacId: import_zod13.z.string().uuid(),
3276
+ encounterId: Sha256Hex.optional(),
3277
+ payerUserId: import_zod13.z.string().uuid(),
3278
+ payeeUserId: import_zod13.z.string().uuid(),
3279
+ payerDeviceId: import_zod13.z.string().min(1).max(128),
3280
+ payerNonce: import_zod13.z.string().min(8).max(128),
3281
+ payeeNonce: import_zod13.z.string().min(8).max(128),
3282
+ amountKobo: import_zod13.z.number().int().positive(),
3283
+ currency: import_zod13.z.string().length(3).default("NGN"),
3284
+ occurredAtMs: import_zod13.z.number().int().nonnegative(),
3285
+ completedAtMs: import_zod13.z.number().int().nonnegative().optional(),
3286
+ contextId: import_zod13.z.string().max(128).optional(),
3287
+ payerPubkeySpkiB64: Base64Std3.min(64).max(4096),
3288
+ payerSignatureDerB64: Base64Std3.min(16).max(2048),
3289
+ payeePubkeySpkiB64: Base64Std3.min(64).max(4096).optional(),
3290
+ payeeSignatureDerB64: Base64Std3.min(16).max(2048).optional()
3291
+ });
3292
+ var ConsumerSettlementSchema = import_zod13.z.object({
3293
+ settlementId: import_zod13.z.string().uuid(),
3294
+ settlementKey: Sha256Hex,
3295
+ encounterId: Sha256Hex,
3296
+ oacId: import_zod13.z.string().uuid(),
3297
+ payerUserId: import_zod13.z.string().uuid(),
3298
+ payeeUserId: import_zod13.z.string().uuid(),
3299
+ amountKobo: import_zod13.z.number().int().positive(),
3300
+ currency: import_zod13.z.string().length(3),
3301
+ status: import_zod13.z.enum(["SETTLED", "REVIEW"]),
3302
+ reviewReason: import_zod13.z.string().nullable(),
3303
+ ledgerRef: import_zod13.z.string().nullable(),
3304
+ /** ASN.1 DER ECDSA P-256 issuer signature, base64. */
3305
+ issuerSig: Base64Std3.min(16).max(2048),
3306
+ createdAtMs: import_zod13.z.number().int().nonnegative()
3307
+ });
3308
+ var ConsumerSettleResultSchema = import_zod13.z.object({
3309
+ settlement: ConsumerSettlementSchema,
3310
+ encounterId: Sha256Hex,
3311
+ replayed: import_zod13.z.boolean()
3312
+ });
3313
+ var RevokeDeviceKeyInputSchema = import_zod13.z.object({
3314
+ deviceId: import_zod13.z.string().min(1).max(128),
3315
+ /** Step-up token from /api/v1/auth/send/verify with purpose='offline_revoke'. */
3316
+ sendAuthToken: import_zod13.z.string().min(16)
3317
+ });
3318
+ function createMeOfflineClient(opts) {
3319
+ const fetchImpl = opts.fetchImpl ?? globalThis.fetch;
3320
+ if (!fetchImpl) {
3321
+ throw new Error("createMeOfflineClient: no fetch implementation available");
3322
+ }
3323
+ const baseUrl = opts.baseUrl.replace(/\/$/, "");
3324
+ async function call(method, path, body, parser) {
3325
+ const init2 = {
3326
+ method,
3327
+ headers: {
3328
+ "content-type": "application/json",
3329
+ accept: "application/json"
3330
+ }
3331
+ };
3332
+ if (body !== void 0) init2.body = JSON.stringify(body);
3333
+ const resp = await fetchImpl(`${baseUrl}${path}`, init2);
3334
+ const text = await resp.text();
3335
+ let raw = void 0;
3336
+ if (text) {
3337
+ try {
3338
+ raw = JSON.parse(text);
3339
+ } catch {
3340
+ }
3341
+ }
3342
+ if (!resp.ok) {
3343
+ const code = raw && typeof raw === "object" && "code" in raw && typeof raw.code === "string" ? raw.code : `http_${resp.status}`;
3344
+ const message = raw && typeof raw === "object" && "message" in raw && typeof raw.message === "string" ? raw.message : `request failed with status ${resp.status}`;
3345
+ throw new FlurApiError(resp.status, code, message, raw);
3346
+ }
3347
+ return parser(raw);
3348
+ }
3349
+ const deviceKeyItems = import_zod13.z.object({ items: import_zod13.z.array(DeviceKeyRecordSchema) });
3350
+ return {
3351
+ issueP256EnrollmentChallenge: (input) => call(
3352
+ "POST",
3353
+ "/v1/me/offline/keys/p256/challenge",
3354
+ P256EnrollmentChallengeInputSchema.parse(input),
3355
+ (raw) => P256EnrollmentChallengeResultSchema.parse(raw)
3356
+ ),
3357
+ registerDeviceKeyP256: (input) => call(
3358
+ "POST",
3359
+ "/v1/me/offline/keys/p256",
3360
+ RegisterDeviceKeyP256InputSchema.parse(input),
3361
+ (raw) => DeviceKeyRecordSchema.parse(raw)
3362
+ ),
3363
+ listDeviceKeys: () => call(
3364
+ "GET",
3365
+ "/v1/me/offline/keys",
3366
+ void 0,
3367
+ (raw) => deviceKeyItems.parse(raw)
3368
+ ),
3369
+ revokeDeviceKey: (input) => call(
3370
+ "POST",
3371
+ "/v1/me/offline/keys/revoke",
3372
+ RevokeDeviceKeyInputSchema.parse(input),
3373
+ () => void 0
3374
+ ),
3375
+ issueAccountOac: (input) => call(
3376
+ "POST",
3377
+ "/v1/me/offline/oac",
3378
+ IssueAccountOacInputSchema.parse(input),
3379
+ (raw) => OACRecordSchema.parse(raw)
3380
+ ),
3381
+ getStatus: (deviceId) => {
3382
+ const qs = deviceId ? `?deviceId=${encodeURIComponent(deviceId)}` : "";
3383
+ return call(
3384
+ "GET",
3385
+ `/v1/me/offline/status${qs}`,
3386
+ void 0,
3387
+ (raw) => OfflineStatusResultSchema.parse(raw)
3388
+ );
3389
+ },
3390
+ submitClaim: (claim) => call(
3391
+ "POST",
3392
+ "/v1/me/offline/claims",
3393
+ ConsumerPaymentClaimSchema.parse(claim),
3394
+ (raw) => ConsumerSettleResultSchema.parse(raw)
3395
+ )
3396
+ };
3397
+ }
3398
+
3549
3399
  // src/me-offline/signer.ts
3550
3400
  var import_nist2 = require("@noble/curves/nist");
3551
3401
  var CLAIM_DOMAIN_V2 = "flur:consumer-offline:v2:claim";
@@ -4453,6 +4303,7 @@ function createOfflinePaymentAuthorizationArtifactUri(input) {
4453
4303
  }
4454
4304
  // Annotate the CommonJS export names for ESM import in node:
4455
4305
  0 && (module.exports = {
4306
+ ACCOUNT_FUNDED_OAC_MAX_TTL_MS,
4456
4307
  ACCOUNT_STATUSES,
4457
4308
  ACCOUNT_TYPES,
4458
4309
  ADDITIONAL_DATA_SUBFIELD,
@@ -4466,6 +4317,7 @@ function createOfflinePaymentAuthorizationArtifactUri(input) {
4466
4317
  CLAIM_DOMAIN_V2,
4467
4318
  COLLECTION_INTENT_STATUSES,
4468
4319
  COLLECTION_PAYMENT_STATUSES,
4320
+ CONSUMER_OFFLINE_CLAIM_SUBMIT_GRACE_MS,
4469
4321
  CUSTODIAL_MODES,
4470
4322
  CollectionIntentSchema,
4471
4323
  CollectionPaymentResultSchema,
@@ -4484,10 +4336,6 @@ function createOfflinePaymentAuthorizationArtifactUri(input) {
4484
4336
  CreateWithdrawalResultSchema,
4485
4337
  DeviceKeyAlgSchema,
4486
4338
  DeviceKeyRecordSchema,
4487
- DisableOfflineInputSchema,
4488
- DisableOfflineResultSchema,
4489
- EnableOfflineInputSchema,
4490
- EnableOfflineResultSchema,
4491
4339
  FIELD,
4492
4340
  FLUR_ARTIFACT_URI_PREFIX,
4493
4341
  FLUR_ARTIFACT_URI_SCHEME,
@@ -4503,7 +4351,6 @@ function createOfflinePaymentAuthorizationArtifactUri(input) {
4503
4351
  IdentityArtifactSchema,
4504
4352
  IngestFundingResultSchema,
4505
4353
  IssueAccountOacInputSchema,
4506
- IssueOACInputSchema,
4507
4354
  LedgerJournalEntryArtifactSchema,
4508
4355
  ListPayoutDestinationsResultSchema,
4509
4356
  MEMBERSHIP_ROLES,
@@ -4522,11 +4369,9 @@ function createOfflinePaymentAuthorizationArtifactUri(input) {
4522
4369
  OAC_DEFAULT_VALIDITY_MS,
4523
4370
  OFFLINE_CLAIM_SMS_PREFIX,
4524
4371
  OfflineClaimArtifactSchema,
4525
- OfflineHoldRecordSchema,
4526
4372
  OfflinePaymentAuthorizationArtifactSchema,
4527
4373
  OfflinePaymentAuthorizationSchema,
4528
4374
  OfflinePaymentRequestSchema,
4529
- OfflineStateResultSchema,
4530
4375
  OfflineStatusResultSchema,
4531
4376
  OfflineTokenSchema,
4532
4377
  P256EnrollmentChallengeInputSchema,
@@ -4554,8 +4399,6 @@ function createOfflinePaymentAuthorizationArtifactUri(input) {
4554
4399
  PayoutEventInputSchema,
4555
4400
  ProviderEventInputSchema,
4556
4401
  ProviderEventRecordSchema,
4557
- ProvisionOfflineAllowanceInputSchema,
4558
- ProvisionOfflineAllowanceResultSchema,
4559
4402
  PublicCollectionIntentSchema,
4560
4403
  RECEIPT_CHANNELS,
4561
4404
  RECEIPT_KINDS,
@@ -4566,7 +4409,6 @@ function createOfflinePaymentAuthorizationArtifactUri(input) {
4566
4409
  ReconciliationReportSchema,
4567
4410
  RecordPayoutEventResultSchema,
4568
4411
  RedemptionSchema,
4569
- RegisterDeviceKeyInputSchema,
4570
4412
  RegisterDeviceKeyP256InputSchema,
4571
4413
  ReversalRecordArtifactSchema,
4572
4414
  RevokeDeviceKeyInputSchema,