@nokinc-flur/sdk 2.3.0 → 2.4.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.js CHANGED
@@ -3581,6 +3581,7 @@ function base64UrlDecodeUtf8(input) {
3581
3581
  }
3582
3582
 
3583
3583
  // src/me-offline/oac.ts
3584
+ import { z as z15 } from "zod";
3584
3585
  var CONSUMER_OAC_DOMAIN = "flur:consumer-offline:v1:oac";
3585
3586
  function consumerOacSigningPayload(oac) {
3586
3587
  return { domain: CONSUMER_OAC_DOMAIN, ...oac };
@@ -3623,15 +3624,28 @@ var CONSUMER_OAC_QR_PREFIX = "FLUROAC1.";
3623
3624
  function isConsumerOacQR(value) {
3624
3625
  return value.startsWith(CONSUMER_OAC_QR_PREFIX);
3625
3626
  }
3626
- function encodeConsumerOacQR(signed) {
3627
+ var OacPresentmentRequestSchema = z15.object({
3628
+ /** Requested amount in minor units (kobo). */
3629
+ amountMinor: z15.number().int().positive().max(1e12).optional(),
3630
+ /** Purpose/intent code (mirrors the NIBSS intent vocabulary). */
3631
+ intent: z15.string().min(1).max(32).optional(),
3632
+ /** Free-text reference / note. */
3633
+ reference: z15.string().min(1).max(64).optional()
3634
+ }).strict();
3635
+ function encodeConsumerOacQR(signed, request) {
3627
3636
  const parsed = SignedConsumerOACSchema.parse(signed);
3628
- return `${CONSUMER_OAC_QR_PREFIX}${base64UrlEncodeUtf82(JSON.stringify(parsed))}`;
3637
+ const base = `${CONSUMER_OAC_QR_PREFIX}${base64UrlEncodeUtf82(JSON.stringify(parsed))}`;
3638
+ if (request === void 0) return base;
3639
+ const parsedRequest = OacPresentmentRequestSchema.parse(request);
3640
+ if (Object.keys(parsedRequest).length === 0) return base;
3641
+ return `${base}.${base64UrlEncodeUtf82(JSON.stringify(parsedRequest))}`;
3629
3642
  }
3630
3643
  function decodeUnverifiedConsumerOacQR(value) {
3631
3644
  if (!value.startsWith(CONSUMER_OAC_QR_PREFIX)) {
3632
3645
  throw new Error("not a Flur consumer OAC QR");
3633
3646
  }
3634
- const encoded = value.slice(CONSUMER_OAC_QR_PREFIX.length);
3647
+ const remainder = value.slice(CONSUMER_OAC_QR_PREFIX.length);
3648
+ const encoded = remainder.split(".", 1)[0];
3635
3649
  let raw;
3636
3650
  try {
3637
3651
  raw = JSON.parse(base64UrlDecodeUtf82(encoded));
@@ -3640,6 +3654,21 @@ function decodeUnverifiedConsumerOacQR(value) {
3640
3654
  }
3641
3655
  return SignedConsumerOACSchema.parse(raw);
3642
3656
  }
3657
+ function decodeConsumerOacRequest(value) {
3658
+ if (!value.startsWith(CONSUMER_OAC_QR_PREFIX)) return null;
3659
+ const remainder = value.slice(CONSUMER_OAC_QR_PREFIX.length);
3660
+ const dot = remainder.indexOf(".");
3661
+ if (dot < 0) return null;
3662
+ const suffix = remainder.slice(dot + 1);
3663
+ if (suffix.length === 0) return null;
3664
+ try {
3665
+ const raw = JSON.parse(base64UrlDecodeUtf82(suffix));
3666
+ const parsed = OacPresentmentRequestSchema.safeParse(raw);
3667
+ return parsed.success ? parsed.data : null;
3668
+ } catch {
3669
+ return null;
3670
+ }
3671
+ }
3643
3672
  function base64UrlEncodeUtf82(input) {
3644
3673
  const bytes = new TextEncoder().encode(input);
3645
3674
  let binary = "";
@@ -3935,14 +3964,14 @@ function base64UrlToBytes(input) {
3935
3964
  }
3936
3965
 
3937
3966
  // src/partner-funding/client.ts
3938
- import { z as z15 } from "zod";
3939
- var MinorString = z15.string().regex(/^-?\d+$/);
3940
- var PositiveMinor = z15.union([
3941
- z15.number().int().positive(),
3942
- z15.string().regex(/^[1-9]\d{0,18}$/)
3967
+ import { z as z16 } from "zod";
3968
+ var MinorString = z16.string().regex(/^-?\d+$/);
3969
+ var PositiveMinor = z16.union([
3970
+ z16.number().int().positive(),
3971
+ z16.string().regex(/^[1-9]\d{0,18}$/)
3943
3972
  ]);
3944
- var Currency = z15.string().trim().length(3).transform((v) => v.toUpperCase());
3945
- var Metadata = z15.record(z15.unknown());
3973
+ var Currency = z16.string().trim().length(3).transform((v) => v.toUpperCase());
3974
+ var Metadata = z16.record(z16.unknown());
3946
3975
  var PARTNER_KINDS = ["bank", "merchant"];
3947
3976
  var CUSTODIAL_MODES = ["agent_of_bank", "flur_virtual_pool"];
3948
3977
  var PARTNER_PROFILE_STATUSES = [
@@ -3969,126 +3998,126 @@ var WITHDRAWAL_STATES = [
3969
3998
  "failed",
3970
3999
  "reversed"
3971
4000
  ];
3972
- var PartnerProfileSchema = z15.object({
3973
- partnerAccountId: z15.string().uuid(),
3974
- kind: z15.enum(PARTNER_KINDS),
3975
- custodialMode: z15.enum(CUSTODIAL_MODES),
3976
- displayName: z15.string(),
3977
- bankCode: z15.string().nullable(),
3978
- poolAccountNumber: z15.string().nullable(),
3979
- status: z15.enum(PARTNER_PROFILE_STATUSES),
4001
+ var PartnerProfileSchema = z16.object({
4002
+ partnerAccountId: z16.string().uuid(),
4003
+ kind: z16.enum(PARTNER_KINDS),
4004
+ custodialMode: z16.enum(CUSTODIAL_MODES),
4005
+ displayName: z16.string(),
4006
+ bankCode: z16.string().nullable(),
4007
+ poolAccountNumber: z16.string().nullable(),
4008
+ status: z16.enum(PARTNER_PROFILE_STATUSES),
3980
4009
  metadata: Metadata,
3981
- createdAtMs: z15.number().int().nonnegative(),
3982
- updatedAtMs: z15.number().int().nonnegative()
4010
+ createdAtMs: z16.number().int().nonnegative(),
4011
+ updatedAtMs: z16.number().int().nonnegative()
3983
4012
  });
3984
- var UpsertPartnerProfileInputSchema = z15.object({
3985
- kind: z15.enum(PARTNER_KINDS),
3986
- custodialMode: z15.enum(CUSTODIAL_MODES),
3987
- displayName: z15.string().trim().min(1).max(200),
3988
- bankCode: z15.string().trim().min(1).max(64).optional(),
3989
- poolAccountNumber: z15.string().trim().min(1).max(64).optional(),
4013
+ var UpsertPartnerProfileInputSchema = z16.object({
4014
+ kind: z16.enum(PARTNER_KINDS),
4015
+ custodialMode: z16.enum(CUSTODIAL_MODES),
4016
+ displayName: z16.string().trim().min(1).max(200),
4017
+ bankCode: z16.string().trim().min(1).max(64).optional(),
4018
+ poolAccountNumber: z16.string().trim().min(1).max(64).optional(),
3990
4019
  metadata: Metadata.optional()
3991
4020
  });
3992
- var PartnerFundingEventInputSchema = z15.object({
3993
- externalRef: z15.string().trim().min(8).max(128),
3994
- direction: z15.enum(PARTNER_FUNDING_DIRECTIONS).optional(),
3995
- userId: z15.string().uuid().optional(),
3996
- accountId: z15.string().uuid().optional(),
4021
+ var PartnerFundingEventInputSchema = z16.object({
4022
+ externalRef: z16.string().trim().min(8).max(128),
4023
+ direction: z16.enum(PARTNER_FUNDING_DIRECTIONS).optional(),
4024
+ userId: z16.string().uuid().optional(),
4025
+ accountId: z16.string().uuid().optional(),
3997
4026
  amountMinor: PositiveMinor,
3998
4027
  currency: Currency,
3999
- fundingSource: z15.string().trim().min(1).max(64).optional(),
4028
+ fundingSource: z16.string().trim().min(1).max(64).optional(),
4000
4029
  providerMetadata: Metadata.optional()
4001
4030
  });
4002
- var PartnerFundingSchema = z15.object({
4003
- fundingId: z15.string().uuid(),
4004
- partnerId: z15.string().uuid(),
4005
- accountId: z15.string().uuid(),
4006
- userId: z15.string().uuid().nullable(),
4007
- direction: z15.enum(PARTNER_FUNDING_DIRECTIONS),
4008
- currency: z15.string(),
4031
+ var PartnerFundingSchema = z16.object({
4032
+ fundingId: z16.string().uuid(),
4033
+ partnerId: z16.string().uuid(),
4034
+ accountId: z16.string().uuid(),
4035
+ userId: z16.string().uuid().nullable(),
4036
+ direction: z16.enum(PARTNER_FUNDING_DIRECTIONS),
4037
+ currency: z16.string(),
4009
4038
  amountMinor: MinorString,
4010
- externalRef: z15.string(),
4011
- status: z15.enum(PARTNER_FUNDING_STATUSES),
4012
- fundingSource: z15.string(),
4013
- ledgerRef: z15.string(),
4039
+ externalRef: z16.string(),
4040
+ status: z16.enum(PARTNER_FUNDING_STATUSES),
4041
+ fundingSource: z16.string(),
4042
+ ledgerRef: z16.string(),
4014
4043
  providerMetadata: Metadata,
4015
- createdAtMs: z15.number().int().nonnegative(),
4016
- updatedAtMs: z15.number().int().nonnegative()
4044
+ createdAtMs: z16.number().int().nonnegative(),
4045
+ updatedAtMs: z16.number().int().nonnegative()
4017
4046
  });
4018
- var IngestFundingResultSchema = z15.object({
4047
+ var IngestFundingResultSchema = z16.object({
4019
4048
  funding: PartnerFundingSchema,
4020
- replayed: z15.boolean()
4049
+ replayed: z16.boolean()
4021
4050
  });
4022
- var PayoutDestinationSchema = z15.object({
4023
- destinationId: z15.string().uuid(),
4024
- accountId: z15.string().uuid(),
4025
- partnerId: z15.string().uuid(),
4026
- bankCode: z15.string(),
4027
- accountNumber: z15.string(),
4028
- accountName: z15.string(),
4029
- status: z15.enum(PAYOUT_DESTINATION_STATUSES),
4030
- verifiedAtMs: z15.number().int().nonnegative().nullable(),
4051
+ var PayoutDestinationSchema = z16.object({
4052
+ destinationId: z16.string().uuid(),
4053
+ accountId: z16.string().uuid(),
4054
+ partnerId: z16.string().uuid(),
4055
+ bankCode: z16.string(),
4056
+ accountNumber: z16.string(),
4057
+ accountName: z16.string(),
4058
+ status: z16.enum(PAYOUT_DESTINATION_STATUSES),
4059
+ verifiedAtMs: z16.number().int().nonnegative().nullable(),
4031
4060
  metadata: Metadata,
4032
- createdAtMs: z15.number().int().nonnegative(),
4033
- updatedAtMs: z15.number().int().nonnegative()
4061
+ createdAtMs: z16.number().int().nonnegative(),
4062
+ updatedAtMs: z16.number().int().nonnegative()
4034
4063
  });
4035
- var CreatePayoutDestinationInputSchema = z15.object({
4036
- partnerId: z15.string().uuid(),
4037
- bankCode: z15.string().trim().min(1).max(32),
4038
- accountNumber: z15.string().trim().min(4).max(64),
4039
- accountName: z15.string().trim().min(1).max(200),
4064
+ var CreatePayoutDestinationInputSchema = z16.object({
4065
+ partnerId: z16.string().uuid(),
4066
+ bankCode: z16.string().trim().min(1).max(32),
4067
+ accountNumber: z16.string().trim().min(4).max(64),
4068
+ accountName: z16.string().trim().min(1).max(200),
4040
4069
  metadata: Metadata.optional()
4041
4070
  });
4042
- var ListPayoutDestinationsResultSchema = z15.object({
4043
- items: z15.array(PayoutDestinationSchema)
4071
+ var ListPayoutDestinationsResultSchema = z16.object({
4072
+ items: z16.array(PayoutDestinationSchema)
4044
4073
  });
4045
- var WithdrawalSchema = z15.object({
4046
- withdrawalId: z15.string().uuid(),
4047
- accountId: z15.string().uuid(),
4048
- userId: z15.string().uuid(),
4049
- partnerId: z15.string().uuid(),
4050
- destinationId: z15.string().uuid(),
4051
- currency: z15.string(),
4074
+ var WithdrawalSchema = z16.object({
4075
+ withdrawalId: z16.string().uuid(),
4076
+ accountId: z16.string().uuid(),
4077
+ userId: z16.string().uuid(),
4078
+ partnerId: z16.string().uuid(),
4079
+ destinationId: z16.string().uuid(),
4080
+ currency: z16.string(),
4052
4081
  amountMinor: MinorString,
4053
- state: z15.enum(WITHDRAWAL_STATES),
4054
- idempotencyKey: z15.string(),
4055
- providerRef: z15.string().nullable(),
4056
- lastError: z15.string().nullable(),
4057
- ledgerRef: z15.string(),
4058
- reverseLedgerRef: z15.string().nullable(),
4082
+ state: z16.enum(WITHDRAWAL_STATES),
4083
+ idempotencyKey: z16.string(),
4084
+ providerRef: z16.string().nullable(),
4085
+ lastError: z16.string().nullable(),
4086
+ ledgerRef: z16.string(),
4087
+ reverseLedgerRef: z16.string().nullable(),
4059
4088
  metadata: Metadata,
4060
- createdAtMs: z15.number().int().nonnegative(),
4061
- updatedAtMs: z15.number().int().nonnegative()
4089
+ createdAtMs: z16.number().int().nonnegative(),
4090
+ updatedAtMs: z16.number().int().nonnegative()
4062
4091
  });
4063
- var CreateWithdrawalInputSchema = z15.object({
4064
- destinationId: z15.string().uuid(),
4092
+ var CreateWithdrawalInputSchema = z16.object({
4093
+ destinationId: z16.string().uuid(),
4065
4094
  amountMinor: PositiveMinor,
4066
4095
  currency: Currency,
4067
- idempotencyKey: z15.string().trim().min(8).max(128),
4096
+ idempotencyKey: z16.string().trim().min(8).max(128),
4068
4097
  metadata: Metadata.optional()
4069
4098
  });
4070
- var CreateWithdrawalResultSchema = z15.object({
4099
+ var CreateWithdrawalResultSchema = z16.object({
4071
4100
  withdrawal: WithdrawalSchema,
4072
- replayed: z15.boolean()
4101
+ replayed: z16.boolean()
4073
4102
  });
4074
- var PayoutEventInputSchema = z15.object({
4075
- externalRef: z15.string().trim().min(8).max(128),
4076
- withdrawalId: z15.string().uuid().optional(),
4077
- state: z15.enum(["submitted", "processing", "paid", "failed"]),
4078
- providerRef: z15.string().trim().min(1).max(128).optional(),
4079
- failureCode: z15.string().trim().max(64).optional(),
4080
- failureMessage: z15.string().trim().max(512).optional(),
4103
+ var PayoutEventInputSchema = z16.object({
4104
+ externalRef: z16.string().trim().min(8).max(128),
4105
+ withdrawalId: z16.string().uuid().optional(),
4106
+ state: z16.enum(["submitted", "processing", "paid", "failed"]),
4107
+ providerRef: z16.string().trim().min(1).max(128).optional(),
4108
+ failureCode: z16.string().trim().max(64).optional(),
4109
+ failureMessage: z16.string().trim().max(512).optional(),
4081
4110
  providerMetadata: Metadata.optional()
4082
4111
  });
4083
- var RecordPayoutEventResultSchema = z15.object({
4112
+ var RecordPayoutEventResultSchema = z16.object({
4084
4113
  withdrawal: WithdrawalSchema,
4085
- replayed: z15.boolean()
4114
+ replayed: z16.boolean()
4086
4115
  });
4087
- var ReconciliationReportSchema = z15.object({
4088
- partnerId: z15.string().uuid(),
4089
- currency: z15.string(),
4090
- fromMs: z15.number().int().nonnegative(),
4091
- toMs: z15.number().int().nonnegative(),
4116
+ var ReconciliationReportSchema = z16.object({
4117
+ partnerId: z16.string().uuid(),
4118
+ currency: z16.string(),
4119
+ fromMs: z16.number().int().nonnegative(),
4120
+ toMs: z16.number().int().nonnegative(),
4092
4121
  fundingsCreditMinor: MinorString,
4093
4122
  fundingsDebitMinor: MinorString,
4094
4123
  withdrawalsPaidMinor: MinorString,
@@ -4097,7 +4126,7 @@ var ReconciliationReportSchema = z15.object({
4097
4126
  expectedReserveBalanceMinor: MinorString,
4098
4127
  actualReserveBalanceMinor: MinorString,
4099
4128
  imbalanceMinor: MinorString,
4100
- generatedAtMs: z15.number().int().nonnegative()
4129
+ generatedAtMs: z16.number().int().nonnegative()
4101
4130
  });
4102
4131
  function createPartnerFundingClient(partner) {
4103
4132
  return {
@@ -4249,19 +4278,19 @@ function createPartnerProfileAdminClient(opts) {
4249
4278
  }
4250
4279
 
4251
4280
  // src/artifacts/envelope.ts
4252
- import { z as z16 } from "zod";
4281
+ import { z as z17 } from "zod";
4253
4282
  var FLUR_ARTIFACT_URI_SCHEME = "flur";
4254
4283
  var FLUR_ARTIFACT_VERSION = 1;
4255
4284
  var FLUR_ARTIFACT_URI_PREFIX = `${FLUR_ARTIFACT_URI_SCHEME}://v${FLUR_ARTIFACT_VERSION}/`;
4256
4285
  var ArtifactTypeRe = /^[a-z][a-z0-9_]{1,63}$/;
4257
- var ArtifactHeaderSchema = z16.object({
4258
- v: z16.literal(FLUR_ARTIFACT_VERSION),
4259
- t: z16.string().regex(ArtifactTypeRe, "invalid artifact type"),
4260
- iss: z16.string().min(1).max(128),
4261
- kid: z16.string().min(1).max(128),
4262
- iat: z16.number().int().nonnegative(),
4263
- exp: z16.number().int().positive().optional(),
4264
- nonce: z16.string().min(8).max(64).regex(/^[A-Za-z0-9_-]+$/, "nonce must be url-safe")
4286
+ var ArtifactHeaderSchema = z17.object({
4287
+ v: z17.literal(FLUR_ARTIFACT_VERSION),
4288
+ t: z17.string().regex(ArtifactTypeRe, "invalid artifact type"),
4289
+ iss: z17.string().min(1).max(128),
4290
+ kid: z17.string().min(1).max(128),
4291
+ iat: z17.number().int().nonnegative(),
4292
+ exp: z17.number().int().positive().optional(),
4293
+ nonce: z17.string().min(8).max(64).regex(/^[A-Za-z0-9_-]+$/, "nonce must be url-safe")
4265
4294
  });
4266
4295
  var FlurArtifactError = class extends Error {
4267
4296
  constructor(message, code) {
@@ -4400,7 +4429,7 @@ function verifyArtifactSignature(decoded, publicKeySpkiB64, options = {}) {
4400
4429
  }
4401
4430
 
4402
4431
  // src/artifacts/types.ts
4403
- import { z as z17 } from "zod";
4432
+ import { z as z18 } from "zod";
4404
4433
  var ARTIFACT_TYPES = {
4405
4434
  OFFLINE_PAYMENT_AUTHORIZATION: "offline_payment_authorization",
4406
4435
  RECEIPT: "receipt",
@@ -4413,37 +4442,34 @@ var ARTIFACT_TYPES = {
4413
4442
  LEDGER_JOURNAL_ENTRY: "ledger_journal_entry",
4414
4443
  STATEMENT: "statement",
4415
4444
  PASS: "pass",
4416
- IDENTITY: "identity",
4417
- // Tier B: holder-signed identity attestation for offline trust. The
4418
- // envelope.iat / envelope.exp express the card's canonical lifetime.
4419
- PAY_CARD: "pay_card"
4445
+ IDENTITY: "identity"
4420
4446
  };
4421
- var HexString = (length) => z17.string().regex(
4447
+ var HexString = (length) => z18.string().regex(
4422
4448
  new RegExp(`^[0-9a-fA-F]{${length * 2}}$`),
4423
4449
  `expected ${length}-byte hex string`
4424
4450
  );
4425
- var OfflinePaymentAuthorizationArtifactSchema = z17.object({
4451
+ var OfflinePaymentAuthorizationArtifactSchema = z18.object({
4426
4452
  authorization: OfflinePaymentAuthorizationSchema
4427
4453
  });
4428
- var ReceiptArtifactSchema = z17.object({
4429
- receiptId: z17.string().min(1).max(64),
4430
- paymentReference: z17.string().min(1).max(64),
4431
- payerUserId: z17.string().min(1).max(64).optional(),
4432
- payeeUserId: z17.string().min(1).max(64),
4433
- amountKobo: z17.number().int().positive(),
4434
- currency: z17.literal("NGN"),
4435
- channel: z17.enum(["online", "offline_reconciled", "pay_link", "nqr"]),
4436
- settledAtMs: z17.number().int().positive(),
4437
- ledgerTxnId: z17.string().min(1).max(64).optional(),
4438
- memo: z17.string().max(140).optional(),
4454
+ var ReceiptArtifactSchema = z18.object({
4455
+ receiptId: z18.string().min(1).max(64),
4456
+ paymentReference: z18.string().min(1).max(64),
4457
+ payerUserId: z18.string().min(1).max(64).optional(),
4458
+ payeeUserId: z18.string().min(1).max(64),
4459
+ amountKobo: z18.number().int().positive(),
4460
+ currency: z18.literal("NGN"),
4461
+ channel: z18.enum(["online", "offline_reconciled", "pay_link", "nqr"]),
4462
+ settledAtMs: z18.number().int().positive(),
4463
+ ledgerTxnId: z18.string().min(1).max(64).optional(),
4464
+ memo: z18.string().max(140).optional(),
4439
4465
  hashChainPrev: HexString(32).optional()
4440
4466
  });
4441
- var ShortId = z17.string().min(1).max(64);
4442
- var PositiveInt = z17.number().int().positive();
4443
- var NonNegativeInt = z17.number().int().nonnegative();
4444
- var Currency2 = z17.literal("NGN");
4445
- var Memo = z17.string().max(140);
4446
- var NqrPaymentRequestArtifactSchema = z17.object({
4467
+ var ShortId = z18.string().min(1).max(64);
4468
+ var PositiveInt = z18.number().int().positive();
4469
+ var NonNegativeInt = z18.number().int().nonnegative();
4470
+ var Currency2 = z18.literal("NGN");
4471
+ var Memo = z18.string().max(140);
4472
+ var NqrPaymentRequestArtifactSchema = z18.object({
4447
4473
  requestId: ShortId,
4448
4474
  payeeUserId: ShortId,
4449
4475
  amountKobo: PositiveInt.optional(),
@@ -4451,7 +4477,7 @@ var NqrPaymentRequestArtifactSchema = z17.object({
4451
4477
  memo: Memo.optional(),
4452
4478
  expiresAtMs: PositiveInt.optional()
4453
4479
  });
4454
- var PaymentIntentArtifactSchema = z17.object({
4480
+ var PaymentIntentArtifactSchema = z18.object({
4455
4481
  intentId: ShortId,
4456
4482
  payerUserId: ShortId,
4457
4483
  payeeUserId: ShortId,
@@ -4460,7 +4486,7 @@ var PaymentIntentArtifactSchema = z17.object({
4460
4486
  idempotencyKey: ShortId,
4461
4487
  createdAtMs: PositiveInt
4462
4488
  });
4463
- var OfflineClaimArtifactSchema = z17.object({
4489
+ var OfflineClaimArtifactSchema = z18.object({
4464
4490
  claimId: ShortId,
4465
4491
  authorizationId: ShortId,
4466
4492
  payeeUserId: ShortId,
@@ -4469,10 +4495,10 @@ var OfflineClaimArtifactSchema = z17.object({
4469
4495
  claimedAtMs: PositiveInt,
4470
4496
  paymentReference: ShortId.optional()
4471
4497
  });
4472
- var SettlementRecordArtifactSchema = z17.object({
4498
+ var SettlementRecordArtifactSchema = z18.object({
4473
4499
  settlementId: ShortId,
4474
4500
  ledgerTxnId: ShortId,
4475
- sourceRefType: z17.enum([
4501
+ sourceRefType: z18.enum([
4476
4502
  "offline_authorization",
4477
4503
  "offline_claim",
4478
4504
  "transfer",
@@ -4483,12 +4509,12 @@ var SettlementRecordArtifactSchema = z17.object({
4483
4509
  currency: Currency2,
4484
4510
  settledAtMs: PositiveInt
4485
4511
  });
4486
- var ReversalRecordArtifactSchema = z17.object({
4512
+ var ReversalRecordArtifactSchema = z18.object({
4487
4513
  reversalId: ShortId,
4488
4514
  originalTxnId: ShortId,
4489
4515
  amountKobo: PositiveInt,
4490
4516
  currency: Currency2,
4491
- reason: z17.enum([
4517
+ reason: z18.enum([
4492
4518
  "user_dispute",
4493
4519
  "fraud",
4494
4520
  "duplicate",
@@ -4498,7 +4524,7 @@ var ReversalRecordArtifactSchema = z17.object({
4498
4524
  reversedAtMs: PositiveInt,
4499
4525
  memo: Memo.optional()
4500
4526
  });
4501
- var LedgerJournalEntryArtifactSchema = z17.object({
4527
+ var LedgerJournalEntryArtifactSchema = z18.object({
4502
4528
  entryId: ShortId,
4503
4529
  journalId: ShortId,
4504
4530
  debitAccountId: ShortId,
@@ -4509,13 +4535,13 @@ var LedgerJournalEntryArtifactSchema = z17.object({
4509
4535
  refType: ShortId.optional(),
4510
4536
  refId: ShortId.optional()
4511
4537
  });
4512
- var StatementArtifactSchema = z17.object({
4538
+ var StatementArtifactSchema = z18.object({
4513
4539
  statementId: ShortId,
4514
4540
  userId: ShortId,
4515
4541
  periodStartMs: PositiveInt,
4516
4542
  periodEndMs: PositiveInt,
4517
- openingBalanceKobo: z17.number().int(),
4518
- closingBalanceKobo: z17.number().int(),
4543
+ openingBalanceKobo: z18.number().int(),
4544
+ closingBalanceKobo: z18.number().int(),
4519
4545
  transactionCount: NonNegativeInt,
4520
4546
  currency: Currency2,
4521
4547
  hashChainPrev: HexString(32).optional()
@@ -4523,16 +4549,16 @@ var StatementArtifactSchema = z17.object({
4523
4549
  message: "periodEndMs must be greater than periodStartMs",
4524
4550
  path: ["periodEndMs"]
4525
4551
  });
4526
- var PassArtifactSchema = z17.object({
4552
+ var PassArtifactSchema = z18.object({
4527
4553
  passId: ShortId,
4528
4554
  holderId: ShortId,
4529
- category: z17.enum(["membership", "ticket", "loyalty", "access", "voucher"]),
4530
- title: z17.string().min(1).max(120),
4555
+ category: z18.enum(["membership", "ticket", "loyalty", "access", "voucher"]),
4556
+ title: z18.string().min(1).max(120),
4531
4557
  validFromMs: PositiveInt,
4532
4558
  validUntilMs: PositiveInt.optional(),
4533
- metadata: z17.record(
4534
- z17.string().min(1).max(64),
4535
- z17.union([z17.string().max(280), z17.number(), z17.boolean()])
4559
+ metadata: z18.record(
4560
+ z18.string().min(1).max(64),
4561
+ z18.union([z18.string().max(280), z18.number(), z18.boolean()])
4536
4562
  ).optional()
4537
4563
  }).refine(
4538
4564
  (v) => v.validUntilMs === void 0 || v.validUntilMs > v.validFromMs,
@@ -4541,10 +4567,10 @@ var PassArtifactSchema = z17.object({
4541
4567
  path: ["validUntilMs"]
4542
4568
  }
4543
4569
  );
4544
- var IdentityArtifactSchema = z17.object({
4570
+ var IdentityArtifactSchema = z18.object({
4545
4571
  attestationId: ShortId,
4546
4572
  subjectId: ShortId,
4547
- claimType: z17.enum([
4573
+ claimType: z18.enum([
4548
4574
  "phone_verified",
4549
4575
  "email_verified",
4550
4576
  "bvn_verified",
@@ -4554,12 +4580,6 @@ var IdentityArtifactSchema = z17.object({
4554
4580
  claimValueHash: HexString(32),
4555
4581
  attestedAtMs: PositiveInt
4556
4582
  });
4557
- var PayCardArtifactSchema = z17.object({
4558
- userId: ShortId,
4559
- phoneE164: z17.string().regex(/^\+[1-9]\d{7,14}$/, "phoneE164 must be normalised E.164"),
4560
- displayName: z17.string().min(1).max(64),
4561
- devicePubKeySpkiB64: z17.string().min(64).max(256).regex(/^[A-Za-z0-9+/]+=*$/, "devicePubKeySpkiB64 must be standard base64")
4562
- });
4563
4583
  var ARTIFACT_BODY_SCHEMAS = {
4564
4584
  [ARTIFACT_TYPES.OFFLINE_PAYMENT_AUTHORIZATION]: OfflinePaymentAuthorizationArtifactSchema,
4565
4585
  [ARTIFACT_TYPES.RECEIPT]: ReceiptArtifactSchema,
@@ -4571,8 +4591,7 @@ var ARTIFACT_BODY_SCHEMAS = {
4571
4591
  [ARTIFACT_TYPES.LEDGER_JOURNAL_ENTRY]: LedgerJournalEntryArtifactSchema,
4572
4592
  [ARTIFACT_TYPES.STATEMENT]: StatementArtifactSchema,
4573
4593
  [ARTIFACT_TYPES.PASS]: PassArtifactSchema,
4574
- [ARTIFACT_TYPES.IDENTITY]: IdentityArtifactSchema,
4575
- [ARTIFACT_TYPES.PAY_CARD]: PayCardArtifactSchema
4594
+ [ARTIFACT_TYPES.IDENTITY]: IdentityArtifactSchema
4576
4595
  };
4577
4596
  var HARDENED_ARTIFACT_TYPES = /* @__PURE__ */ new Set([
4578
4597
  ARTIFACT_TYPES.OFFLINE_PAYMENT_AUTHORIZATION,
@@ -4585,8 +4604,7 @@ var HARDENED_ARTIFACT_TYPES = /* @__PURE__ */ new Set([
4585
4604
  ARTIFACT_TYPES.LEDGER_JOURNAL_ENTRY,
4586
4605
  ARTIFACT_TYPES.STATEMENT,
4587
4606
  ARTIFACT_TYPES.PASS,
4588
- ARTIFACT_TYPES.IDENTITY,
4589
- ARTIFACT_TYPES.PAY_CARD
4607
+ ARTIFACT_TYPES.IDENTITY
4590
4608
  ]);
4591
4609
  function isKnownArtifactType(t) {
4592
4610
  return Object.values(ARTIFACT_TYPES).includes(t);
@@ -4671,130 +4689,6 @@ function createOfflinePaymentAuthorizationArtifactUri(input) {
4671
4689
  type: ARTIFACT_TYPES.OFFLINE_PAYMENT_AUTHORIZATION
4672
4690
  });
4673
4691
  }
4674
-
4675
- // src/artifacts/paycard.ts
4676
- var PAY_CARD_DEFAULT_TTL_MS = 90 * 24 * 60 * 60 * 1e3;
4677
- var PAY_CARD_REFRESH_THRESHOLD_MS = 30 * 24 * 60 * 60 * 1e3;
4678
- var PAY_CARD_URI_PREFIX = `${FLUR_ARTIFACT_URI_PREFIX}${ARTIFACT_TYPES.PAY_CARD}/`;
4679
- function createPayCardArtifactUri(input) {
4680
- if (input.data.userId !== input.issuer) {
4681
- throw new FlurArtifactError(
4682
- "pay_card.data.userId must equal envelope issuer",
4683
- "INVALID_BODY"
4684
- );
4685
- }
4686
- const iat = input.issuedAtSeconds ?? Math.floor(Date.now() / 1e3);
4687
- const exp = input.expiresAtSeconds ?? iat + Math.floor(PAY_CARD_DEFAULT_TTL_MS / 1e3);
4688
- return createArtifactUri({
4689
- type: ARTIFACT_TYPES.PAY_CARD,
4690
- issuer: input.issuer,
4691
- keyId: input.keyId,
4692
- privateKey: input.privateKey,
4693
- nonce: input.nonce,
4694
- issuedAtSeconds: iat,
4695
- expiresAtSeconds: exp,
4696
- data: input.data
4697
- });
4698
- }
4699
- function isPayCardArtifactUri(uri) {
4700
- return typeof uri === "string" && uri.startsWith(PAY_CARD_URI_PREFIX);
4701
- }
4702
- function decodePayCardArtifact(uri) {
4703
- if (!isPayCardArtifactUri(uri)) {
4704
- throw new FlurArtifactError(
4705
- `URI does not start with ${PAY_CARD_URI_PREFIX}`,
4706
- "INVALID_URI"
4707
- );
4708
- }
4709
- const decoded = decodeArtifactUri(uri);
4710
- if (decoded.type !== ARTIFACT_TYPES.PAY_CARD) {
4711
- throw new FlurArtifactError(
4712
- `Expected pay_card, got ${decoded.type}`,
4713
- "TYPE_MISMATCH"
4714
- );
4715
- }
4716
- const parsed = PayCardArtifactSchema.safeParse(decoded.body.data);
4717
- if (!parsed.success) {
4718
- throw new FlurArtifactError(
4719
- `pay_card body invalid: ${parsed.error.message}`,
4720
- "INVALID_BODY"
4721
- );
4722
- }
4723
- if (parsed.data.userId !== decoded.body.iss) {
4724
- throw new FlurArtifactError(
4725
- "pay_card.data.userId must equal envelope issuer",
4726
- "INVALID_BODY"
4727
- );
4728
- }
4729
- return {
4730
- body: {
4731
- ...decoded.body,
4732
- data: parsed.data
4733
- },
4734
- sig: decoded.sig,
4735
- decoded
4736
- };
4737
- }
4738
- function verifyPayCardArtifact(uri, publicKeySpkiB64, options = {}) {
4739
- if (!isPayCardArtifactUri(uri)) {
4740
- throw new FlurArtifactError(
4741
- `URI does not start with ${PAY_CARD_URI_PREFIX}`,
4742
- "INVALID_URI"
4743
- );
4744
- }
4745
- const verified = verifyArtifactUri(
4746
- uri,
4747
- publicKeySpkiB64,
4748
- options
4749
- );
4750
- if (verified.decoded.type !== ARTIFACT_TYPES.PAY_CARD) {
4751
- throw new FlurArtifactError(
4752
- `Expected pay_card, got ${verified.decoded.type}`,
4753
- "TYPE_MISMATCH"
4754
- );
4755
- }
4756
- if (verified.body.data.userId !== verified.body.iss) {
4757
- throw new FlurArtifactError(
4758
- "pay_card.data.userId must equal envelope issuer",
4759
- "INVALID_BODY"
4760
- );
4761
- }
4762
- return {
4763
- body: verified.body,
4764
- sig: verified.sig,
4765
- decoded: verified.decoded
4766
- };
4767
- }
4768
- function inspectPayCardFreshness(decoded, nowMs = Date.now()) {
4769
- const exp = decoded.body.exp;
4770
- if (exp === void 0) return "no_expiry";
4771
- const remainingMs = exp * 1e3 - nowMs;
4772
- if (remainingMs <= 0) return "expired";
4773
- if (remainingMs <= PAY_CARD_REFRESH_THRESHOLD_MS)
4774
- return "refresh_recommended";
4775
- return "fresh";
4776
- }
4777
- function buildPayCardSigningInput(input) {
4778
- if (input.data.userId !== input.issuer) {
4779
- throw new FlurArtifactError(
4780
- "pay_card.data.userId must equal envelope issuer",
4781
- "INVALID_BODY"
4782
- );
4783
- }
4784
- const parsedData = PayCardArtifactSchema.parse(input.data);
4785
- const iat = input.issuedAtSeconds ?? Math.floor(Date.now() / 1e3);
4786
- const exp = input.expiresAtSeconds ?? iat + Math.floor(PAY_CARD_DEFAULT_TTL_MS / 1e3);
4787
- const body = buildArtifactBody({
4788
- type: ARTIFACT_TYPES.PAY_CARD,
4789
- issuer: input.issuer,
4790
- keyId: input.keyId,
4791
- data: parsedData,
4792
- nonce: input.nonce,
4793
- issuedAtSeconds: iat,
4794
- expiresAtSeconds: exp
4795
- });
4796
- return { body, bodyBytes: canonicalJSONBytes(body) };
4797
- }
4798
4692
  export {
4799
4693
  ACCOUNT_FUNDED_OAC_MAX_TTL_MS,
4800
4694
  ACCOUNT_STATUSES,
@@ -4875,6 +4769,7 @@ export {
4875
4769
  OFFLINE_SMS_SETTLE_SIGNATURE_BYTES,
4876
4770
  OFFLINE_SMS_SETTLE_TOKEN_BYTES,
4877
4771
  OFFLINE_SMS_SETTLE_VERSION,
4772
+ OacPresentmentRequestSchema,
4878
4773
  OfflineClaimArtifactSchema,
4879
4774
  OfflinePaymentAuthorizationArtifactSchema,
4880
4775
  OfflinePaymentAuthorizationSchema,
@@ -4892,9 +4787,6 @@ export {
4892
4787
  PASS_STATES,
4893
4788
  PAYLOAD_FORMAT_INDICATOR_VALUE,
4894
4789
  PAYOUT_DESTINATION_STATUSES,
4895
- PAY_CARD_DEFAULT_TTL_MS,
4896
- PAY_CARD_REFRESH_THRESHOLD_MS,
4897
- PAY_CARD_URI_PREFIX,
4898
4790
  POINT_OF_INITIATION,
4899
4791
  PartnerFundingEventInputSchema,
4900
4792
  PartnerFundingSchema,
@@ -4902,7 +4794,6 @@ export {
4902
4794
  PassArtifactSchema,
4903
4795
  PassMetadataSchema,
4904
4796
  PassSchema,
4905
- PayCardArtifactSchema,
4906
4797
  PayCollectionInputSchema,
4907
4798
  PaymentClaimSchema,
4908
4799
  PaymentIntentArtifactSchema,
@@ -4941,7 +4832,6 @@ export {
4941
4832
  buildConsumerPaymentRequest,
4942
4833
  buildOAC,
4943
4834
  buildPass,
4944
- buildPayCardSigningInput,
4945
4835
  buildPaymentRequest,
4946
4836
  buildReceipt,
4947
4837
  buildRedemption,
@@ -4976,17 +4866,16 @@ export {
4976
4866
  createPartnerFundingClient,
4977
4867
  createPartnerProfileAdminClient,
4978
4868
  createPassesClient,
4979
- createPayCardArtifactUri,
4980
4869
  createReceiptArtifactUri,
4981
4870
  createReceiptsClient,
4982
4871
  createSoftwareP256Signer,
4983
4872
  decodeArtifactUri,
4984
4873
  decodeAuthorizationQR,
4985
4874
  decodeBase45,
4875
+ decodeConsumerOacRequest,
4986
4876
  decodeConsumerSettlementReceiptQR,
4987
4877
  decodeOfflineClaimSmsMessage,
4988
4878
  decodeOfflineSmsSettleToken,
4989
- decodePayCardArtifact,
4990
4879
  decodePaymentRequestQR,
4991
4880
  decodeUnverifiedConsumerOacQR,
4992
4881
  decodeUnverifiedConsumerSettlementReceiptQR,
@@ -5006,13 +4895,11 @@ export {
5006
4895
  generateDynamicQR,
5007
4896
  generateStaticQR,
5008
4897
  init,
5009
- inspectPayCardFreshness,
5010
4898
  isConsumerOacQR,
5011
4899
  isConsumerPaymentRequestExpired,
5012
4900
  isHardenedArtifactType,
5013
4901
  isKnownArtifactType,
5014
4902
  isPassWithinValidity,
5015
- isPayCardArtifactUri,
5016
4903
  moneyMinorToNumber,
5017
4904
  normalizeE164,
5018
4905
  parseAmountInput,
@@ -5041,7 +4928,6 @@ export {
5041
4928
  verifyOacOffline,
5042
4929
  verifyOfflineSmsSettleToken,
5043
4930
  verifyPass,
5044
- verifyPayCardArtifact,
5045
4931
  verifyPaymentRequest,
5046
4932
  verifyReceipt,
5047
4933
  verifyRedemption,