@nokinc-flur/sdk 1.0.5 → 1.1.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
@@ -26,11 +26,24 @@ __export(index_exports, {
26
26
  AccountMembershipSchema: () => AccountMembershipSchema,
27
27
  AccountSchema: () => AccountSchema,
28
28
  ApiCredentialPublicSchema: () => ApiCredentialPublicSchema,
29
+ COLLECTION_INTENT_STATUSES: () => COLLECTION_INTENT_STATUSES,
30
+ COLLECTION_PAYMENT_STATUSES: () => COLLECTION_PAYMENT_STATUSES,
31
+ CUSTODIAL_MODES: () => CUSTODIAL_MODES,
32
+ CollectionIntentSchema: () => CollectionIntentSchema,
33
+ CollectionPaymentResultSchema: () => CollectionPaymentResultSchema,
34
+ CollectionPaymentSchema: () => CollectionPaymentSchema,
35
+ CollectionReportSummarySchema: () => CollectionReportSummarySchema,
36
+ CollectionStatementSchema: () => CollectionStatementSchema,
29
37
  ConsumerOACRecordSchema: () => OACRecordSchema,
30
38
  ConsumerOACSchema: () => ConsumerOACSchema,
31
39
  ConsumerPaymentClaimSchema: () => ConsumerPaymentClaimSchema,
32
40
  ConsumerSettleResultSchema: () => ConsumerSettleResultSchema,
33
41
  ConsumerSettlementSchema: () => ConsumerSettlementSchema,
42
+ CreateCollectionIntentInputSchema: () => CreateCollectionIntentInputSchema,
43
+ CreatePayoutDestinationInputSchema: () => CreatePayoutDestinationInputSchema,
44
+ CreatePayoutInputSchema: () => CreatePayoutInputSchema,
45
+ CreateWithdrawalInputSchema: () => CreateWithdrawalInputSchema,
46
+ CreateWithdrawalResultSchema: () => CreateWithdrawalResultSchema,
34
47
  DeviceKeyRecordSchema: () => DeviceKeyRecordSchema,
35
48
  DisableOfflineInputSchema: () => DisableOfflineInputSchema,
36
49
  DisableOfflineResultSchema: () => DisableOfflineResultSchema,
@@ -43,8 +56,14 @@ __export(index_exports, {
43
56
  FlurError: () => FlurError,
44
57
  FlurExpiredError: () => FlurExpiredError,
45
58
  FlurReplayError: () => FlurReplayError,
59
+ IngestFundingResultSchema: () => IngestFundingResultSchema,
46
60
  IssueOACInputSchema: () => IssueOACInputSchema,
61
+ ListPayoutDestinationsResultSchema: () => ListPayoutDestinationsResultSchema,
47
62
  MEMBERSHIP_ROLES: () => MEMBERSHIP_ROLES,
63
+ MERCHANT_PAYOUT_STATUSES: () => MERCHANT_PAYOUT_STATUSES,
64
+ MERCHANT_PROFILE_STATUSES: () => MERCHANT_PROFILE_STATUSES,
65
+ MerchantPayoutSchema: () => MerchantPayoutSchema,
66
+ MerchantProfileSchema: () => MerchantProfileSchema,
48
67
  MintedApiCredentialSchema: () => MintedApiCredentialSchema,
49
68
  NGN_CURRENCY_CODE: () => NGN_CURRENCY_CODE,
50
69
  NG_COUNTRY_CODE: () => NG_COUNTRY_CODE,
@@ -59,25 +78,46 @@ __export(index_exports, {
59
78
  OfflineStateResultSchema: () => OfflineStateResultSchema,
60
79
  OfflineStatusResultSchema: () => OfflineStatusResultSchema,
61
80
  OfflineTokenSchema: () => OfflineTokenSchema,
81
+ PARTNER_FUNDING_DIRECTIONS: () => PARTNER_FUNDING_DIRECTIONS,
82
+ PARTNER_FUNDING_STATUSES: () => PARTNER_FUNDING_STATUSES,
83
+ PARTNER_KINDS: () => PARTNER_KINDS,
84
+ PARTNER_PROFILE_STATUSES: () => PARTNER_PROFILE_STATUSES,
62
85
  PARTNER_SCOPES: () => PARTNER_SCOPES,
63
86
  PASS_KINDS: () => PASS_KINDS,
64
87
  PASS_STATES: () => PASS_STATES,
65
88
  PAYLOAD_FORMAT_INDICATOR_VALUE: () => PAYLOAD_FORMAT_INDICATOR_VALUE,
89
+ PAYOUT_DESTINATION_STATUSES: () => PAYOUT_DESTINATION_STATUSES,
66
90
  POINT_OF_INITIATION: () => POINT_OF_INITIATION,
91
+ PartnerFundingEventInputSchema: () => PartnerFundingEventInputSchema,
92
+ PartnerFundingSchema: () => PartnerFundingSchema,
93
+ PartnerProfileSchema: () => PartnerProfileSchema,
67
94
  PassMetadataSchema: () => PassMetadataSchema,
68
95
  PassSchema: () => PassSchema,
96
+ PayCollectionInputSchema: () => PayCollectionInputSchema,
69
97
  PaymentClaimSchema: () => PaymentClaimSchema,
98
+ PayoutDestinationSchema: () => PayoutDestinationSchema,
99
+ PayoutEventInputSchema: () => PayoutEventInputSchema,
100
+ ProviderEventInputSchema: () => ProviderEventInputSchema,
101
+ ProviderEventRecordSchema: () => ProviderEventRecordSchema,
102
+ PublicCollectionIntentSchema: () => PublicCollectionIntentSchema,
70
103
  RECEIPT_CHANNELS: () => RECEIPT_CHANNELS,
71
104
  RECEIPT_KINDS: () => RECEIPT_KINDS,
72
105
  REPLAY_WINDOW_MS: () => REPLAY_WINDOW_MS,
73
106
  ReceiptPayloadSchema: () => ReceiptPayloadSchema,
74
107
  ReceiptSchema: () => ReceiptSchema,
108
+ ReconciliationReportSchema: () => ReconciliationReportSchema,
109
+ RecordPayoutEventResultSchema: () => RecordPayoutEventResultSchema,
75
110
  RedemptionSchema: () => RedemptionSchema,
76
111
  RegisterDeviceKeyInputSchema: () => RegisterDeviceKeyInputSchema,
77
112
  RevokeDeviceKeyInputSchema: () => RevokeDeviceKeyInputSchema,
113
+ SETTLEMENT_SCHEDULES: () => SETTLEMENT_SCHEDULES,
78
114
  SettleResponseSchema: () => SettleResponseSchema,
79
115
  SettlementSchema: () => SettlementSchema,
80
116
  SignedConsumerOACSchema: () => SignedConsumerOACSchema,
117
+ UpsertMerchantProfileInputSchema: () => UpsertMerchantProfileInputSchema,
118
+ UpsertPartnerProfileInputSchema: () => UpsertPartnerProfileInputSchema,
119
+ WITHDRAWAL_STATES: () => WITHDRAWAL_STATES,
120
+ WithdrawalSchema: () => WithdrawalSchema,
81
121
  bodySha256Hex: () => bodySha256Hex,
82
122
  buildAuthorization: () => buildAuthorization,
83
123
  buildOAC: () => buildOAC,
@@ -94,10 +134,16 @@ __export(index_exports, {
94
134
  crc16ccittHex: () => crc16ccittHex,
95
135
  createAccountsClient: () => createAccountsClient,
96
136
  createApiCredentialsAdminClient: () => createApiCredentialsAdminClient,
137
+ createCollectionsClient: () => createCollectionsClient,
138
+ createConsumerCollectionsClient: () => createConsumerCollectionsClient,
139
+ createConsumerWithdrawalsClient: () => createConsumerWithdrawalsClient,
97
140
  createFlurPartnerClient: () => createFlurPartnerClient,
98
141
  createHmacFetch: () => createHmacFetch,
99
142
  createMeOfflineClient: () => createMeOfflineClient,
100
143
  createOfflineSettlementsClient: () => createOfflineSettlementsClient,
144
+ createPartnerCollectionsClient: () => createPartnerCollectionsClient,
145
+ createPartnerFundingClient: () => createPartnerFundingClient,
146
+ createPartnerProfileAdminClient: () => createPartnerProfileAdminClient,
101
147
  createPassesClient: () => createPassesClient,
102
148
  createReceiptsClient: () => createReceiptsClient,
103
149
  decodeAuthorizationQR: () => decodeAuthorizationQR,
@@ -145,7 +191,7 @@ __export(index_exports, {
145
191
  module.exports = __toCommonJS(index_exports);
146
192
 
147
193
  // src/client.ts
148
- var import_zod3 = require("zod");
194
+ var import_zod4 = require("zod");
149
195
 
150
196
  // src/contracts.ts
151
197
  var import_zod = require("zod");
@@ -298,6 +344,13 @@ var AccountActivityItemSchema = import_zod.z.object({
298
344
  timestamp: IsoDateSchema
299
345
  });
300
346
  var AccountSummaryResponseSchema = import_zod.z.object({
347
+ /** Authenticated user's stable internal id. */
348
+ userId: UuidSchema,
349
+ /**
350
+ * 10-digit Nigeria Uniform Bank Account Number (NUBAN) allocated by the
351
+ * bank partner. `null` when the user has no partner-allocated account yet.
352
+ */
353
+ nuban: import_zod.z.string().regex(/^[0-9]{10}$/).nullable(),
301
354
  balance: import_zod.z.number().int(),
302
355
  currency: CurrencySchema,
303
356
  dailySendLimit: import_zod.z.number().int().nonnegative(),
@@ -533,6 +586,341 @@ function moneyMinorToNumber(amountMinor) {
533
586
  return asNumber;
534
587
  }
535
588
 
589
+ // src/collections/client.ts
590
+ var import_zod3 = require("zod");
591
+ var MERCHANT_PROFILE_STATUSES = [
592
+ "pending",
593
+ "active",
594
+ "suspended",
595
+ "closed"
596
+ ];
597
+ var SETTLEMENT_SCHEDULES = ["manual", "daily", "t1"];
598
+ var COLLECTION_INTENT_STATUSES = [
599
+ "created",
600
+ "pending",
601
+ "paid",
602
+ "expired",
603
+ "cancelled",
604
+ "failed",
605
+ "reversed"
606
+ ];
607
+ var COLLECTION_PAYMENT_STATUSES = [
608
+ "pending",
609
+ "paid",
610
+ "failed",
611
+ "reversed"
612
+ ];
613
+ var MERCHANT_PAYOUT_STATUSES = [
614
+ "requested",
615
+ "processing",
616
+ "paid",
617
+ "failed",
618
+ "cancelled"
619
+ ];
620
+ var MoneyKoboSchema = import_zod3.z.number().int().positive().max(Number.MAX_SAFE_INTEGER);
621
+ var MetadataSchema = import_zod3.z.record(
622
+ import_zod3.z.union([import_zod3.z.string(), import_zod3.z.number(), import_zod3.z.boolean(), import_zod3.z.null()])
623
+ );
624
+ var CurrencySchema2 = import_zod3.z.string().trim().length(3).transform((value) => value.toUpperCase());
625
+ var ReferenceSchema = import_zod3.z.string().trim().min(6).max(128).regex(/^[A-Za-z0-9._:-]+$/);
626
+ var MerchantProfileSchema = import_zod3.z.object({
627
+ accountId: import_zod3.z.string().uuid(),
628
+ legalName: import_zod3.z.string(),
629
+ tradingName: import_zod3.z.string(),
630
+ merchantCategoryCode: import_zod3.z.string().regex(/^\d{4}$/),
631
+ nqrMerchantId: import_zod3.z.string(),
632
+ settlementBankCode: import_zod3.z.string(),
633
+ settlementAccountNumber: import_zod3.z.string(),
634
+ settlementAccountName: import_zod3.z.string(),
635
+ settlementSchedule: import_zod3.z.enum(SETTLEMENT_SCHEDULES),
636
+ status: import_zod3.z.enum(MERCHANT_PROFILE_STATUSES),
637
+ offlineEnabled: import_zod3.z.boolean(),
638
+ perTxLimitKobo: MoneyKoboSchema,
639
+ dailyLimitKobo: MoneyKoboSchema,
640
+ metadata: MetadataSchema,
641
+ createdAtMs: import_zod3.z.number().int().nonnegative(),
642
+ updatedAtMs: import_zod3.z.number().int().nonnegative()
643
+ });
644
+ var UpsertMerchantProfileInputSchema = import_zod3.z.object({
645
+ legalName: import_zod3.z.string().trim().min(1).max(200),
646
+ tradingName: import_zod3.z.string().trim().min(1).max(25),
647
+ merchantCategoryCode: import_zod3.z.string().trim().regex(/^\d{4}$/),
648
+ nqrMerchantId: import_zod3.z.string().trim().min(3).max(64),
649
+ settlementBankCode: import_zod3.z.string().trim().min(2).max(16),
650
+ settlementAccountNumber: import_zod3.z.string().trim().min(5).max(32),
651
+ settlementAccountName: import_zod3.z.string().trim().min(1).max(200),
652
+ settlementSchedule: import_zod3.z.enum(SETTLEMENT_SCHEDULES).optional(),
653
+ status: import_zod3.z.enum(MERCHANT_PROFILE_STATUSES).optional(),
654
+ offlineEnabled: import_zod3.z.boolean().optional(),
655
+ perTxLimitKobo: MoneyKoboSchema.optional(),
656
+ dailyLimitKobo: MoneyKoboSchema.optional(),
657
+ metadata: MetadataSchema.optional()
658
+ });
659
+ var CollectionIntentSchema = import_zod3.z.object({
660
+ intentId: import_zod3.z.string().uuid(),
661
+ accountId: import_zod3.z.string().uuid(),
662
+ terminalId: import_zod3.z.string().uuid().nullable(),
663
+ reference: import_zod3.z.string(),
664
+ amountKobo: import_zod3.z.number().int().positive().nullable(),
665
+ currency: import_zod3.z.string().length(3),
666
+ status: import_zod3.z.enum(COLLECTION_INTENT_STATUSES),
667
+ description: import_zod3.z.string().nullable(),
668
+ nqrPayload: import_zod3.z.string(),
669
+ provider: import_zod3.z.string(),
670
+ providerReference: import_zod3.z.string().nullable(),
671
+ metadata: MetadataSchema,
672
+ expiresAtMs: import_zod3.z.number().int().nonnegative().nullable(),
673
+ paidAtMs: import_zod3.z.number().int().nonnegative().nullable(),
674
+ createdAtMs: import_zod3.z.number().int().nonnegative(),
675
+ updatedAtMs: import_zod3.z.number().int().nonnegative()
676
+ });
677
+ var CreateCollectionIntentInputSchema = import_zod3.z.object({
678
+ reference: ReferenceSchema.optional(),
679
+ amountKobo: MoneyKoboSchema.optional(),
680
+ currency: CurrencySchema2.optional(),
681
+ terminalId: import_zod3.z.string().uuid().optional(),
682
+ terminalLabel: import_zod3.z.string().trim().min(1).max(25).optional(),
683
+ merchantCity: import_zod3.z.string().trim().min(1).max(15).optional(),
684
+ description: import_zod3.z.string().trim().min(1).max(280).optional(),
685
+ expiresAtMs: import_zod3.z.number().int().positive().optional(),
686
+ provider: import_zod3.z.string().trim().min(1).max(40).optional(),
687
+ metadata: MetadataSchema.optional()
688
+ });
689
+ var PublicCollectionIntentSchema = import_zod3.z.object({
690
+ intentId: import_zod3.z.string().uuid(),
691
+ reference: import_zod3.z.string(),
692
+ amountKobo: import_zod3.z.number().int().positive().nullable(),
693
+ currency: import_zod3.z.string().length(3),
694
+ status: import_zod3.z.enum(COLLECTION_INTENT_STATUSES),
695
+ merchantAccountId: import_zod3.z.string().uuid(),
696
+ merchantName: import_zod3.z.string(),
697
+ merchantCategoryCode: import_zod3.z.string(),
698
+ description: import_zod3.z.string().nullable(),
699
+ expiresAtMs: import_zod3.z.number().int().nonnegative().nullable()
700
+ });
701
+ var PayCollectionInputSchema = import_zod3.z.object({
702
+ reference: ReferenceSchema,
703
+ amountKobo: MoneyKoboSchema.optional(),
704
+ currency: CurrencySchema2.optional(),
705
+ idempotencyKey: import_zod3.z.string().trim().min(8).max(160).optional()
706
+ });
707
+ var CollectionPaymentSchema = import_zod3.z.object({
708
+ paymentId: import_zod3.z.string().uuid(),
709
+ intentId: import_zod3.z.string().uuid(),
710
+ accountId: import_zod3.z.string().uuid(),
711
+ payerUserId: import_zod3.z.string().uuid().nullable(),
712
+ merchantOwnerUserId: import_zod3.z.string().uuid(),
713
+ amountKobo: MoneyKoboSchema,
714
+ currency: import_zod3.z.string().length(3),
715
+ status: import_zod3.z.enum(COLLECTION_PAYMENT_STATUSES),
716
+ provider: import_zod3.z.string(),
717
+ providerReference: import_zod3.z.string().nullable(),
718
+ idempotencyKey: import_zod3.z.string().nullable(),
719
+ ledgerRef: import_zod3.z.string(),
720
+ failureCode: import_zod3.z.string().nullable(),
721
+ failureMessage: import_zod3.z.string().nullable(),
722
+ paidAtMs: import_zod3.z.number().int().nonnegative().nullable(),
723
+ createdAtMs: import_zod3.z.number().int().nonnegative(),
724
+ updatedAtMs: import_zod3.z.number().int().nonnegative()
725
+ });
726
+ var CollectionPaymentResultSchema = import_zod3.z.object({
727
+ payment: CollectionPaymentSchema,
728
+ intent: CollectionIntentSchema,
729
+ receipt: import_zod3.z.unknown().optional(),
730
+ replayed: import_zod3.z.boolean()
731
+ });
732
+ var CollectionReportSummarySchema = import_zod3.z.object({
733
+ accountId: import_zod3.z.string().uuid(),
734
+ fromMs: import_zod3.z.number().int().nonnegative(),
735
+ toMs: import_zod3.z.number().int().nonnegative(),
736
+ currency: import_zod3.z.string().length(3),
737
+ paidCount: import_zod3.z.number().int().nonnegative(),
738
+ paidAmountKobo: import_zod3.z.number().int().nonnegative(),
739
+ pendingCount: import_zod3.z.number().int().nonnegative(),
740
+ failedCount: import_zod3.z.number().int().nonnegative(),
741
+ reversedCount: import_zod3.z.number().int().nonnegative(),
742
+ availableBalanceKobo: import_zod3.z.number().int().nonnegative()
743
+ });
744
+ var CollectionStatementSchema = import_zod3.z.object({
745
+ accountId: import_zod3.z.string().uuid(),
746
+ year: import_zod3.z.number().int(),
747
+ month: import_zod3.z.number().int().min(1).max(12),
748
+ currency: import_zod3.z.string().length(3),
749
+ totalPaidKobo: import_zod3.z.number().int().nonnegative(),
750
+ items: import_zod3.z.array(CollectionPaymentSchema)
751
+ });
752
+ var CreatePayoutInputSchema = import_zod3.z.object({
753
+ amountKobo: MoneyKoboSchema,
754
+ currency: CurrencySchema2.optional(),
755
+ idempotencyKey: import_zod3.z.string().trim().min(8).max(160)
756
+ });
757
+ var MerchantPayoutSchema = import_zod3.z.object({
758
+ payoutId: import_zod3.z.string().uuid(),
759
+ accountId: import_zod3.z.string().uuid(),
760
+ amountKobo: MoneyKoboSchema,
761
+ currency: import_zod3.z.string().length(3),
762
+ status: import_zod3.z.enum(MERCHANT_PAYOUT_STATUSES),
763
+ idempotencyKey: import_zod3.z.string().nullable(),
764
+ ledgerRef: import_zod3.z.string(),
765
+ providerReference: import_zod3.z.string().nullable(),
766
+ requestedByUserId: import_zod3.z.string().uuid().nullable(),
767
+ failureCode: import_zod3.z.string().nullable(),
768
+ failureMessage: import_zod3.z.string().nullable(),
769
+ createdAtMs: import_zod3.z.number().int().nonnegative(),
770
+ updatedAtMs: import_zod3.z.number().int().nonnegative()
771
+ });
772
+ var ProviderEventInputSchema = import_zod3.z.object({
773
+ provider: import_zod3.z.string().trim().min(1).max(80),
774
+ eventId: import_zod3.z.string().trim().min(1).max(160),
775
+ eventType: import_zod3.z.string().trim().min(1).max(120),
776
+ payload: import_zod3.z.record(import_zod3.z.unknown()).optional()
777
+ });
778
+ var ProviderEventRecordSchema = import_zod3.z.object({
779
+ id: import_zod3.z.string().uuid(),
780
+ provider: import_zod3.z.string(),
781
+ eventId: import_zod3.z.string(),
782
+ eventType: import_zod3.z.string(),
783
+ signatureVerified: import_zod3.z.boolean(),
784
+ receivedAtMs: import_zod3.z.number().int().nonnegative(),
785
+ processedAtMs: import_zod3.z.number().int().nonnegative().nullable()
786
+ });
787
+ function createCollectionsClient(opts) {
788
+ const fetchImpl = opts.fetchImpl ?? globalThis.fetch;
789
+ if (!fetchImpl) {
790
+ throw new Error(
791
+ "createCollectionsClient: no fetch implementation available"
792
+ );
793
+ }
794
+ const baseUrl = opts.baseUrl.replace(/\/$/, "");
795
+ async function call(method, path, body, parser) {
796
+ const init2 = {
797
+ method,
798
+ headers: { accept: "application/json" }
799
+ };
800
+ if (body !== void 0) {
801
+ init2.body = JSON.stringify(body);
802
+ init2.headers = { ...init2.headers, "content-type": "application/json" };
803
+ }
804
+ const resp = await fetchImpl(`${baseUrl}${path}`, init2);
805
+ const text = await resp.text();
806
+ let raw;
807
+ if (text) {
808
+ try {
809
+ raw = JSON.parse(text);
810
+ } catch {
811
+ raw = text;
812
+ }
813
+ }
814
+ if (!resp.ok) {
815
+ const code = raw && typeof raw === "object" && "code" in raw && typeof raw.code === "string" ? raw.code : `http_${resp.status}`;
816
+ const message = raw && typeof raw === "object" && "message" in raw && typeof raw.message === "string" ? raw.message : `request failed with status ${resp.status}`;
817
+ throw new FlurApiError(resp.status, code, message, raw);
818
+ }
819
+ return parser(raw);
820
+ }
821
+ return {
822
+ upsertMerchantProfile: (accountId, input) => call(
823
+ "PUT",
824
+ `/v1/accounts/${encodeURIComponent(accountId)}/merchant-profile`,
825
+ UpsertMerchantProfileInputSchema.parse(input),
826
+ (raw) => MerchantProfileSchema.parse(raw)
827
+ ),
828
+ getMerchantProfile: (accountId) => call(
829
+ "GET",
830
+ `/v1/accounts/${encodeURIComponent(accountId)}/merchant-profile`,
831
+ void 0,
832
+ (raw) => MerchantProfileSchema.parse(raw)
833
+ ),
834
+ createIntent: (input) => call(
835
+ "POST",
836
+ "/v1/collections/intents",
837
+ CreateCollectionIntentInputSchema.parse(input),
838
+ (raw) => CollectionIntentSchema.parse(raw)
839
+ ),
840
+ getIntent: (intentId) => call(
841
+ "GET",
842
+ `/v1/collections/intents/${encodeURIComponent(intentId)}`,
843
+ void 0,
844
+ (raw) => CollectionIntentSchema.parse(raw)
845
+ ),
846
+ resolveIntent: (reference) => call(
847
+ "GET",
848
+ `/v1/collections/resolve/${encodeURIComponent(reference)}`,
849
+ void 0,
850
+ (raw) => PublicCollectionIntentSchema.parse(raw)
851
+ ),
852
+ pay: (input) => call(
853
+ "POST",
854
+ "/v1/collections/pay",
855
+ PayCollectionInputSchema.parse(input),
856
+ (raw) => CollectionPaymentResultSchema.parse(raw)
857
+ ),
858
+ reportSummary: (input) => {
859
+ const qs = new URLSearchParams({
860
+ fromMs: String(input.fromMs),
861
+ toMs: String(input.toMs)
862
+ });
863
+ if (input.currency) qs.set("currency", input.currency);
864
+ return call(
865
+ "GET",
866
+ `/v1/collections/reports/summary?${qs.toString()}`,
867
+ void 0,
868
+ (raw) => CollectionReportSummarySchema.parse(raw)
869
+ );
870
+ },
871
+ monthlyStatement: (input) => {
872
+ const qs = new URLSearchParams({
873
+ year: String(input.year),
874
+ month: String(input.month)
875
+ });
876
+ if (input.currency) qs.set("currency", input.currency);
877
+ return call(
878
+ "GET",
879
+ `/v1/collections/statements/monthly?${qs.toString()}`,
880
+ void 0,
881
+ (raw) => CollectionStatementSchema.parse(raw)
882
+ );
883
+ },
884
+ createPayout: (input) => call(
885
+ "POST",
886
+ "/v1/collections/payouts",
887
+ CreatePayoutInputSchema.parse(input),
888
+ (raw) => MerchantPayoutSchema.parse(raw)
889
+ ),
890
+ getPayout: (payoutId) => call(
891
+ "GET",
892
+ `/v1/collections/payouts/${encodeURIComponent(payoutId)}`,
893
+ void 0,
894
+ (raw) => MerchantPayoutSchema.parse(raw)
895
+ ),
896
+ recordProviderEvent: (input) => call(
897
+ "POST",
898
+ "/v1/collections/provider-events",
899
+ ProviderEventInputSchema.parse(input),
900
+ (raw) => ProviderEventRecordSchema.parse(raw)
901
+ )
902
+ };
903
+ }
904
+ function createPartnerCollectionsClient(opts) {
905
+ const client = createCollectionsClient(opts);
906
+ return {
907
+ createIntent: client.createIntent,
908
+ getIntent: client.getIntent,
909
+ reportSummary: client.reportSummary,
910
+ monthlyStatement: client.monthlyStatement,
911
+ createPayout: client.createPayout,
912
+ getPayout: client.getPayout,
913
+ recordProviderEvent: client.recordProviderEvent
914
+ };
915
+ }
916
+ function createConsumerCollectionsClient(opts) {
917
+ const client = createCollectionsClient(opts);
918
+ return {
919
+ resolveIntent: client.resolveIntent,
920
+ pay: client.pay
921
+ };
922
+ }
923
+
536
924
  // src/client.ts
537
925
  var FlurClient = class {
538
926
  baseUrl;
@@ -781,6 +1169,36 @@ var FlurClient = class {
781
1169
  }
782
1170
  );
783
1171
  }
1172
+ async resolveCollection(reference, options) {
1173
+ return this.requestJson(
1174
+ `/v1/collections/resolve/${encodeURIComponent(reference)}`,
1175
+ {
1176
+ method: "GET",
1177
+ headers: {
1178
+ authorization: `Bearer ${options.accessToken}`
1179
+ }
1180
+ },
1181
+ void 0,
1182
+ PublicCollectionIntentSchema
1183
+ );
1184
+ }
1185
+ async payCollection(input, options) {
1186
+ const idempotencyKey = input.idempotencyKey ?? options.idempotencyKey ?? getSecureRandomUuid();
1187
+ return this.requestJson(
1188
+ "/v1/collections/pay",
1189
+ {
1190
+ method: "POST",
1191
+ headers: {
1192
+ "content-type": "application/json",
1193
+ authorization: `Bearer ${options.accessToken}`,
1194
+ "x-idempotency-key": idempotencyKey
1195
+ }
1196
+ },
1197
+ PayCollectionInputSchema,
1198
+ CollectionPaymentResultSchema,
1199
+ { ...input, idempotencyKey }
1200
+ );
1201
+ }
784
1202
  async accountSummary(options) {
785
1203
  return this.requestJson(
786
1204
  "/api/v1/account/summary",
@@ -879,7 +1297,7 @@ var FlurClient = class {
879
1297
  try {
880
1298
  body = requestSchema ? JSON.stringify(requestSchema.parse(input)) : init2.body;
881
1299
  } catch (err) {
882
- if (err instanceof import_zod3.z.ZodError) {
1300
+ if (err instanceof import_zod4.z.ZodError) {
883
1301
  throw new FlurError("Invalid request payload", "INVALID_REQUEST", {
884
1302
  details: err.flatten()
885
1303
  });
@@ -907,7 +1325,7 @@ var FlurClient = class {
907
1325
  try {
908
1326
  return responseSchema.parse(payload);
909
1327
  } catch (err) {
910
- if (err instanceof import_zod3.z.ZodError) {
1328
+ if (err instanceof import_zod4.z.ZodError) {
911
1329
  throw new FlurError(
912
1330
  "SDK contract validation failed",
913
1331
  "INVALID_REQUEST",
@@ -1365,24 +1783,24 @@ function verifyCanonical(value, signature, publicKey) {
1365
1783
  }
1366
1784
 
1367
1785
  // src/offline/oac.ts
1368
- var import_zod4 = require("zod");
1786
+ var import_zod5 = require("zod");
1369
1787
  var OAC_DEFAULT_PER_TX_KOBO = 5e5;
1370
1788
  var OAC_DEFAULT_CUMULATIVE_KOBO = 2e6;
1371
1789
  var OAC_DEFAULT_VALIDITY_MS = 24 * 60 * 60 * 1e3;
1372
- var HexString = (length) => import_zod4.z.string().regex(
1790
+ var HexString = (length) => import_zod5.z.string().regex(
1373
1791
  new RegExp(`^[0-9a-fA-F]{${length * 2}}$`),
1374
1792
  `expected ${length}-byte hex string`
1375
1793
  );
1376
- var OACSchema = import_zod4.z.object({
1377
- userId: import_zod4.z.string().min(1),
1378
- deviceId: import_zod4.z.string().min(1),
1794
+ var OACSchema = import_zod5.z.object({
1795
+ userId: import_zod5.z.string().min(1),
1796
+ deviceId: import_zod5.z.string().min(1),
1379
1797
  devicePublicKey: HexString(32),
1380
- perTxCapKobo: import_zod4.z.number().int().nonnegative(),
1381
- cumulativeCapKobo: import_zod4.z.number().int().nonnegative(),
1382
- validFromMs: import_zod4.z.number().int().nonnegative(),
1383
- validUntilMs: import_zod4.z.number().int().positive(),
1384
- counterSeed: import_zod4.z.number().int().nonnegative(),
1385
- nonce: import_zod4.z.string().min(1),
1798
+ perTxCapKobo: import_zod5.z.number().int().nonnegative(),
1799
+ cumulativeCapKobo: import_zod5.z.number().int().nonnegative(),
1800
+ validFromMs: import_zod5.z.number().int().nonnegative(),
1801
+ validUntilMs: import_zod5.z.number().int().positive(),
1802
+ counterSeed: import_zod5.z.number().int().nonnegative(),
1803
+ nonce: import_zod5.z.string().min(1),
1386
1804
  issuerSig: HexString(64)
1387
1805
  }).refine((v) => v.validUntilMs > v.validFromMs, {
1388
1806
  message: "validUntilMs must be greater than validFromMs"
@@ -1489,19 +1907,19 @@ function decodeBase45(s) {
1489
1907
  }
1490
1908
 
1491
1909
  // src/offline/messages.ts
1492
- var import_zod5 = require("zod");
1493
- var HexSig = import_zod5.z.string().regex(/^[0-9a-fA-F]{128}$/, "expected 64-byte hex signature");
1494
- var OfflinePaymentRequestSchema = import_zod5.z.object({
1495
- reference: import_zod5.z.string().min(1),
1496
- amountKobo: import_zod5.z.number().int().positive(),
1910
+ var import_zod6 = require("zod");
1911
+ var HexSig = import_zod6.z.string().regex(/^[0-9a-fA-F]{128}$/, "expected 64-byte hex signature");
1912
+ var OfflinePaymentRequestSchema = import_zod6.z.object({
1913
+ reference: import_zod6.z.string().min(1),
1914
+ amountKobo: import_zod6.z.number().int().positive(),
1497
1915
  merchantOAC: OACSchema,
1498
- expiresAtMs: import_zod5.z.number().int().positive(),
1916
+ expiresAtMs: import_zod6.z.number().int().positive(),
1499
1917
  merchantSig: HexSig
1500
1918
  });
1501
- var OfflinePaymentAuthorizationSchema = import_zod5.z.object({
1919
+ var OfflinePaymentAuthorizationSchema = import_zod6.z.object({
1502
1920
  request: OfflinePaymentRequestSchema,
1503
1921
  payerOAC: OACSchema,
1504
- payerCounter: import_zod5.z.number().int().positive(),
1922
+ payerCounter: import_zod6.z.number().int().positive(),
1505
1923
  payerSig: HexSig
1506
1924
  });
1507
1925
  function buildPaymentRequest(input) {
@@ -1610,56 +2028,56 @@ function decodeAuthorizationQR(s) {
1610
2028
  }
1611
2029
 
1612
2030
  // src/offline/settlements.ts
1613
- var import_zod6 = require("zod");
2031
+ var import_zod7 = require("zod");
1614
2032
  var import_sha256 = require("@noble/hashes/sha256");
1615
2033
  var import_utils = require("@noble/hashes/utils");
1616
- var OfflineTokenSchema = import_zod6.z.object({
1617
- tokenId: import_zod6.z.string().uuid(),
1618
- tokenSerial: import_zod6.z.string(),
1619
- issuerAccountId: import_zod6.z.string().uuid(),
1620
- payerUserId: import_zod6.z.string().uuid(),
1621
- maxAmountKobo: import_zod6.z.number().int().positive(),
1622
- currency: import_zod6.z.string().length(3),
1623
- issuedAtMs: import_zod6.z.number().int().nonnegative(),
1624
- expiresAtMs: import_zod6.z.number().int().nonnegative(),
1625
- issuerSig: import_zod6.z.string()
1626
- });
1627
- var PaymentClaimSchema = import_zod6.z.object({
1628
- encounterId: import_zod6.z.string().regex(/^[0-9a-f]{64}$/i).optional(),
1629
- tokenSerial: import_zod6.z.string(),
1630
- payerUserId: import_zod6.z.string().uuid(),
1631
- payeeUserId: import_zod6.z.string().uuid(),
1632
- payerNonce: import_zod6.z.string(),
1633
- payeeNonce: import_zod6.z.string(),
1634
- amountKobo: import_zod6.z.number().int().positive(),
1635
- currency: import_zod6.z.string().length(3).default("NGN"),
1636
- occurredAtMs: import_zod6.z.number().int().nonnegative(),
1637
- completedAtMs: import_zod6.z.number().int().nonnegative().optional(),
1638
- contextId: import_zod6.z.string().optional(),
1639
- payerPubkey: import_zod6.z.string().regex(/^[0-9a-f]{64}$/i),
1640
- payerSignature: import_zod6.z.string().regex(/^[0-9a-f]+$/i),
1641
- payeePubkey: import_zod6.z.string().regex(/^[0-9a-f]{64}$/i).optional(),
1642
- payeeSignature: import_zod6.z.string().regex(/^[0-9a-f]+$/i).optional()
1643
- });
1644
- var SettlementSchema = import_zod6.z.object({
1645
- settlementId: import_zod6.z.string().uuid(),
1646
- settlementKey: import_zod6.z.string().regex(/^[0-9a-f]{64}$/i),
1647
- encounterId: import_zod6.z.string().regex(/^[0-9a-f]{64}$/i),
1648
- issuerAccountId: import_zod6.z.string().uuid(),
1649
- tokenSerial: import_zod6.z.string(),
1650
- payerUserId: import_zod6.z.string().uuid(),
1651
- payeeUserId: import_zod6.z.string().uuid(),
1652
- amountKobo: import_zod6.z.number().int().nonnegative(),
1653
- currency: import_zod6.z.string().length(3),
1654
- receiptId: import_zod6.z.string().nullable(),
1655
- status: import_zod6.z.enum(["SETTLED", "REVIEW", "REJECTED"]),
1656
- issuerSig: import_zod6.z.string(),
1657
- createdAtMs: import_zod6.z.number().int().nonnegative()
1658
- });
1659
- var SettleResponseSchema = import_zod6.z.object({
2034
+ var OfflineTokenSchema = import_zod7.z.object({
2035
+ tokenId: import_zod7.z.string().uuid(),
2036
+ tokenSerial: import_zod7.z.string(),
2037
+ issuerAccountId: import_zod7.z.string().uuid(),
2038
+ payerUserId: import_zod7.z.string().uuid(),
2039
+ maxAmountKobo: import_zod7.z.number().int().positive(),
2040
+ currency: import_zod7.z.string().length(3),
2041
+ issuedAtMs: import_zod7.z.number().int().nonnegative(),
2042
+ expiresAtMs: import_zod7.z.number().int().nonnegative(),
2043
+ issuerSig: import_zod7.z.string()
2044
+ });
2045
+ var PaymentClaimSchema = import_zod7.z.object({
2046
+ encounterId: import_zod7.z.string().regex(/^[0-9a-f]{64}$/i).optional(),
2047
+ tokenSerial: import_zod7.z.string(),
2048
+ payerUserId: import_zod7.z.string().uuid(),
2049
+ payeeUserId: import_zod7.z.string().uuid(),
2050
+ payerNonce: import_zod7.z.string(),
2051
+ payeeNonce: import_zod7.z.string(),
2052
+ amountKobo: import_zod7.z.number().int().positive(),
2053
+ currency: import_zod7.z.string().length(3).default("NGN"),
2054
+ occurredAtMs: import_zod7.z.number().int().nonnegative(),
2055
+ completedAtMs: import_zod7.z.number().int().nonnegative().optional(),
2056
+ contextId: import_zod7.z.string().optional(),
2057
+ payerPubkey: import_zod7.z.string().regex(/^[0-9a-f]{64}$/i),
2058
+ payerSignature: import_zod7.z.string().regex(/^[0-9a-f]+$/i),
2059
+ payeePubkey: import_zod7.z.string().regex(/^[0-9a-f]{64}$/i).optional(),
2060
+ payeeSignature: import_zod7.z.string().regex(/^[0-9a-f]+$/i).optional()
2061
+ });
2062
+ var SettlementSchema = import_zod7.z.object({
2063
+ settlementId: import_zod7.z.string().uuid(),
2064
+ settlementKey: import_zod7.z.string().regex(/^[0-9a-f]{64}$/i),
2065
+ encounterId: import_zod7.z.string().regex(/^[0-9a-f]{64}$/i),
2066
+ issuerAccountId: import_zod7.z.string().uuid(),
2067
+ tokenSerial: import_zod7.z.string(),
2068
+ payerUserId: import_zod7.z.string().uuid(),
2069
+ payeeUserId: import_zod7.z.string().uuid(),
2070
+ amountKobo: import_zod7.z.number().int().nonnegative(),
2071
+ currency: import_zod7.z.string().length(3),
2072
+ receiptId: import_zod7.z.string().nullable(),
2073
+ status: import_zod7.z.enum(["SETTLED", "REVIEW", "REJECTED"]),
2074
+ issuerSig: import_zod7.z.string(),
2075
+ createdAtMs: import_zod7.z.number().int().nonnegative()
2076
+ });
2077
+ var SettleResponseSchema = import_zod7.z.object({
1660
2078
  settlement: SettlementSchema,
1661
- encounterId: import_zod6.z.string().regex(/^[0-9a-f]{64}$/i),
1662
- replayed: import_zod6.z.boolean()
2079
+ encounterId: import_zod7.z.string().regex(/^[0-9a-f]{64}$/i),
2080
+ replayed: import_zod7.z.boolean()
1663
2081
  });
1664
2082
  var ENCOUNTER_DOMAIN = "offline:v1:encounter";
1665
2083
  async function sha256Hex(input) {
@@ -1832,133 +2250,351 @@ function createHmacFetch(opts) {
1832
2250
  });
1833
2251
  }
1834
2252
 
1835
- // src/passes/pass.ts
1836
- var import_zod7 = require("zod");
1837
- var PASS_KINDS = [
1838
- "ride-ticket",
1839
- "transit-pass",
1840
- "event-ticket",
1841
- "voucher",
1842
- "loyalty",
1843
- "receipt-link"
1844
- ];
1845
- var PASS_STATES = [
1846
- "issued",
1847
- "active",
1848
- "redeemed",
1849
- "expired",
1850
- "revoked"
2253
+ // src/partner/client.ts
2254
+ var import_zod8 = require("zod");
2255
+ var import_sha2563 = require("@noble/hashes/sha256");
2256
+ var import_hmac4 = require("@noble/hashes/hmac");
2257
+ var import_utils2 = require("@noble/hashes/utils");
2258
+ var PARTNER_SCOPES = [
2259
+ "passes:write",
2260
+ "passes:read",
2261
+ "passes:redeem",
2262
+ "receipts:write",
2263
+ "receipts:read",
2264
+ "offline:issue",
2265
+ "offline:settle",
2266
+ "offline:read",
2267
+ "collections:write",
2268
+ "collections:read",
2269
+ "collections:pay",
2270
+ "collections:webhook",
2271
+ "reports:read",
2272
+ "payouts:write",
2273
+ "payouts:read",
2274
+ "partner:funding:write",
2275
+ "partner:payout:write",
2276
+ "partner:reconciliation:read"
1851
2277
  ];
1852
- var HexString2 = (length) => import_zod7.z.string().regex(
1853
- new RegExp(`^[0-9a-fA-F]{${length * 2}}$`),
1854
- `expected ${length}-byte hex string`
1855
- );
1856
- var PassMetadataSchema = import_zod7.z.record(
1857
- import_zod7.z.union([import_zod7.z.string(), import_zod7.z.number(), import_zod7.z.boolean(), import_zod7.z.null()])
1858
- );
1859
- var PassSchema = import_zod7.z.object({
1860
- passId: import_zod7.z.string().min(1),
1861
- /** Optional client/template grouping id (server may omit). */
1862
- templateId: import_zod7.z.string().min(1).optional(),
1863
- /** Optional human-facing holder identity (server may omit). The cryptographic binding
1864
- * is `holderDevicePubkey` below. */
1865
- holderUserId: import_zod7.z.string().min(1).optional(),
1866
- kind: import_zod7.z.enum(PASS_KINDS),
1867
- issuerId: import_zod7.z.string().min(1),
1868
- issuedAtMs: import_zod7.z.number().int().nonnegative(),
1869
- validFromMs: import_zod7.z.number().int().nonnegative(),
1870
- validUntilMs: import_zod7.z.number().int().positive(),
1871
- state: import_zod7.z.enum(PASS_STATES),
1872
- metadata: PassMetadataSchema,
1873
- nonce: import_zod7.z.string().min(1),
1874
- /** Device id this pass is bound to (FK to backend `device_keys`). */
1875
- holderDeviceId: import_zod7.z.string().min(1),
1876
- /** 32-byte hex Ed25519 public key of the bound device. The redemption signature
1877
- * is verified against this key — it is the security-critical binding. */
1878
- holderDevicePubkey: HexString2(32),
1879
- /** Optional fixed amount for monetary passes (vouchers, gift cards) in kobo. */
1880
- amountKobo: import_zod7.z.number().int().nonnegative().optional(),
1881
- /** ISO-4217-ish currency code; required on the wire. SDK builders default to NGN. */
1882
- currency: import_zod7.z.string().min(3).max(8),
1883
- /** Monotonic redemption counter floor. Redemption.counter MUST be > counterSeed. */
1884
- counterSeed: import_zod7.z.number().int().nonnegative(),
1885
- /** Optional cumulative spend cap in kobo across all redemptions of this pass. */
1886
- cumulativeCapKobo: import_zod7.z.number().int().nonnegative().optional(),
1887
- issuerSig: HexString2(64)
1888
- }).refine((v) => v.validUntilMs > v.validFromMs, {
1889
- message: "validUntilMs must be greater than validFromMs"
2278
+ var ApiCredentialPublicSchema = import_zod8.z.object({
2279
+ id: import_zod8.z.string().uuid(),
2280
+ accountId: import_zod8.z.string().uuid(),
2281
+ keyId: import_zod8.z.string(),
2282
+ scopes: import_zod8.z.array(import_zod8.z.enum(PARTNER_SCOPES)),
2283
+ label: import_zod8.z.string().nullable(),
2284
+ createdAtMs: import_zod8.z.number().int().nonnegative(),
2285
+ lastUsedAtMs: import_zod8.z.number().int().nonnegative().nullable(),
2286
+ revokedAtMs: import_zod8.z.number().int().nonnegative().nullable()
1890
2287
  });
1891
- function buildPass(input) {
1892
- if (input.validUntilMs <= input.validFromMs) {
1893
- throw new Error("validUntilMs must be greater than validFromMs");
1894
- }
1895
- const out = {
1896
- passId: input.passId,
1897
- kind: input.kind,
1898
- issuerId: input.issuerId,
1899
- issuedAtMs: input.issuedAtMs,
1900
- validFromMs: input.validFromMs,
1901
- validUntilMs: input.validUntilMs,
1902
- state: input.state,
1903
- metadata: input.metadata,
1904
- nonce: input.nonce,
1905
- holderDeviceId: input.holderDeviceId,
1906
- holderDevicePubkey: input.holderDevicePubkey,
1907
- currency: input.currency ?? "NGN",
1908
- counterSeed: input.counterSeed
1909
- };
1910
- if (typeof input.templateId === "string") out.templateId = input.templateId;
1911
- if (typeof input.holderUserId === "string")
1912
- out.holderUserId = input.holderUserId;
1913
- if (typeof input.amountKobo === "number") out.amountKobo = input.amountKobo;
1914
- if (typeof input.cumulativeCapKobo === "number") {
1915
- out.cumulativeCapKobo = input.cumulativeCapKobo;
1916
- }
1917
- return out;
2288
+ var MintedApiCredentialSchema = ApiCredentialPublicSchema.extend({
2289
+ secret: import_zod8.z.string().min(1)
2290
+ });
2291
+ var enc = new TextEncoder();
2292
+ async function sha256Hex2(input) {
2293
+ const data = typeof input === "string" ? enc.encode(input) : input;
2294
+ return (0, import_utils2.bytesToHex)((0, import_sha2563.sha256)(data));
1918
2295
  }
1919
- function signPass(unsigned, issuerPrivateKey) {
1920
- const issuerSig = bytesToHex(
1921
- sign(canonicalJSONBytes(unsigned), issuerPrivateKey)
1922
- );
1923
- return { ...unsigned, issuerSig };
2296
+ async function hmacSha256Hex(keyHex, message) {
2297
+ return (0, import_utils2.bytesToHex)((0, import_hmac4.hmac)(import_sha2563.sha256, enc.encode(keyHex), enc.encode(message)));
1924
2298
  }
1925
- function verifyPass(pass, issuerPublicKey) {
1926
- try {
1927
- const parsed = PassSchema.parse(pass);
1928
- const { issuerSig, ...unsigned } = parsed;
1929
- return verify(
1930
- canonicalJSONBytes(unsigned),
1931
- hexToBytes(issuerSig),
1932
- issuerPublicKey
1933
- );
1934
- } catch {
1935
- return false;
1936
- }
2299
+ function defaultNonce2() {
2300
+ const c = globalThis.crypto;
2301
+ if (c?.randomUUID) return c.randomUUID();
2302
+ return `${Date.now().toString(16)}-${Math.random().toString(16).slice(2)}`;
1937
2303
  }
1938
- function isPassWithinValidity(pass, nowMs) {
1939
- return nowMs >= pass.validFromMs && nowMs < pass.validUntilMs;
2304
+ function canonical(params) {
2305
+ return [
2306
+ params.method.toUpperCase(),
2307
+ params.path,
2308
+ params.ts,
2309
+ params.nonce,
2310
+ params.bodyHash
2311
+ ].join("\n");
1940
2312
  }
1941
-
1942
- // src/passes/redemption.ts
1943
- var import_zod8 = require("zod");
1944
- var HexSig2 = import_zod8.z.string().regex(/^[0-9a-fA-F]{128}$/, "expected 64-byte hex signature");
1945
- var RedemptionSchema = import_zod8.z.object({
1946
- pass: PassSchema,
1947
- redeemerId: import_zod8.z.string().min(1),
1948
- redeemedAtMs: import_zod8.z.number().int().nonnegative(),
1949
- /** Strictly monotonic counter scoped to a single pass. Must be > pass.counterSeed
1950
- * and > the redeemer's lastSeenCounter for this pass. */
1951
- counter: import_zod8.z.number().int().positive(),
1952
- /** Amount being redeemed in kobo (0 for non-monetary passes like ride tickets). */
1953
- amountKobo: import_zod8.z.number().int().nonnegative(),
1954
- nonce: import_zod8.z.string().min(1),
1955
- holderSig: HexSig2
1956
- });
1957
- var REDEEMABLE_STATES = /* @__PURE__ */ new Set(["issued", "active"]);
1958
- function buildRedemption(input) {
1959
- if (!REDEEMABLE_STATES.has(input.pass.state)) {
1960
- throw new Error(`pass not in redeemable state: ${input.pass.state}`);
1961
- }
2313
+ async function signPartnerRequest(params) {
2314
+ const ts = String(Math.floor((params.nowMs ?? Date.now()) / 1e3));
2315
+ const nonce = params.nonce ?? defaultNonce2();
2316
+ const bodyData = typeof params.body === "string" ? enc.encode(params.body) : params.body ?? new Uint8Array();
2317
+ const bodyHash = await sha256Hex2(bodyData);
2318
+ const message = canonical({
2319
+ method: params.method,
2320
+ path: params.path,
2321
+ ts,
2322
+ nonce,
2323
+ bodyHash
2324
+ });
2325
+ const signingKey = await sha256Hex2(params.secret);
2326
+ const sig = await hmacSha256Hex(signingKey, message);
2327
+ return {
2328
+ authorization: `Flur-Hmac key=${params.keyId}, ts=${ts}, nonce=${nonce}, sig=${sig}`,
2329
+ ts,
2330
+ nonce,
2331
+ bodyHash
2332
+ };
2333
+ }
2334
+ function createFlurPartnerClient(opts) {
2335
+ const fetchImpl = opts.fetchImpl ?? globalThis.fetch;
2336
+ if (!fetchImpl) {
2337
+ throw new Error(
2338
+ "createFlurPartnerClient: no fetch implementation available"
2339
+ );
2340
+ }
2341
+ const baseUrl = opts.baseUrl.replace(/\/$/, "");
2342
+ const scopeHeader = normalizeScopeHeader(opts.scope);
2343
+ async function makeSignedInit(method, path, body) {
2344
+ const sig = await signPartnerRequest({
2345
+ keyId: opts.keyId,
2346
+ secret: opts.secret,
2347
+ method,
2348
+ path,
2349
+ body: body ?? "",
2350
+ nowMs: opts.nowMs?.(),
2351
+ nonce: opts.nonce?.()
2352
+ });
2353
+ const headers = {
2354
+ authorization: sig.authorization,
2355
+ accept: "application/json"
2356
+ };
2357
+ if (scopeHeader) headers["x-flur-scope"] = scopeHeader;
2358
+ if (body !== void 0) headers["content-type"] = "application/json";
2359
+ const init2 = { method, headers };
2360
+ if (body !== void 0) init2.body = body;
2361
+ return init2;
2362
+ }
2363
+ async function request(opts2) {
2364
+ const bodyStr = opts2.body === void 0 ? void 0 : JSON.stringify(opts2.body);
2365
+ const init2 = await makeSignedInit(opts2.method, opts2.path, bodyStr);
2366
+ const resp = await fetchImpl(`${baseUrl}${opts2.path}`, init2);
2367
+ const text = await resp.text();
2368
+ let raw;
2369
+ if (text) {
2370
+ try {
2371
+ raw = JSON.parse(text);
2372
+ } catch {
2373
+ }
2374
+ }
2375
+ if (!resp.ok) {
2376
+ const code = raw && typeof raw === "object" && "code" in raw && typeof raw.code === "string" ? raw.code : `http_${resp.status}`;
2377
+ const message = raw && typeof raw === "object" && "message" in raw && typeof raw.message === "string" ? raw.message : `request failed with status ${resp.status}`;
2378
+ throw new FlurApiError(resp.status, code, message, raw);
2379
+ }
2380
+ return raw;
2381
+ }
2382
+ const fetchLike = async (input, init2) => {
2383
+ const url = typeof input === "string" ? input : input.toString();
2384
+ const u = new URL(url, baseUrl);
2385
+ const path = `${u.pathname}${u.search}`;
2386
+ const method = (init2?.method ?? "GET").toUpperCase();
2387
+ let bodyStr;
2388
+ if (init2?.body) {
2389
+ bodyStr = typeof init2.body === "string" ? init2.body : init2.body.toString();
2390
+ }
2391
+ const signed = await makeSignedInit(method, path, bodyStr);
2392
+ return fetchImpl(`${baseUrl}${path}`, {
2393
+ ...init2,
2394
+ ...signed,
2395
+ headers: {
2396
+ ...init2?.headers,
2397
+ ...signed.headers
2398
+ }
2399
+ });
2400
+ };
2401
+ return { request, fetch: fetchLike };
2402
+ }
2403
+ function normalizeScopeHeader(scope) {
2404
+ if (!scope || scope.length === 0) return void 0;
2405
+ const unique = Array.from(new Set(scope));
2406
+ for (const item of unique) {
2407
+ if (!PARTNER_SCOPES.includes(item)) {
2408
+ throw new Error(`unsupported partner scope: ${item}`);
2409
+ }
2410
+ }
2411
+ return unique.join(" ");
2412
+ }
2413
+ function createApiCredentialsAdminClient(opts) {
2414
+ const fetchImpl = opts.fetchImpl ?? globalThis.fetch;
2415
+ if (!fetchImpl) {
2416
+ throw new Error(
2417
+ "createApiCredentialsAdminClient: no fetch implementation available"
2418
+ );
2419
+ }
2420
+ const baseUrl = opts.baseUrl.replace(/\/$/, "");
2421
+ async function call(method, path, body, parser) {
2422
+ const init2 = {
2423
+ method,
2424
+ headers: {
2425
+ "content-type": "application/json",
2426
+ accept: "application/json"
2427
+ }
2428
+ };
2429
+ if (body !== void 0) init2.body = JSON.stringify(body);
2430
+ const resp = await fetchImpl(`${baseUrl}${path}`, init2);
2431
+ const text = await resp.text();
2432
+ let raw;
2433
+ if (text) {
2434
+ try {
2435
+ raw = JSON.parse(text);
2436
+ } catch {
2437
+ }
2438
+ }
2439
+ if (!resp.ok) {
2440
+ const code = raw && typeof raw === "object" && "code" in raw && typeof raw.code === "string" ? raw.code : `http_${resp.status}`;
2441
+ const message = raw && typeof raw === "object" && "message" in raw && typeof raw.message === "string" ? raw.message : `request failed with status ${resp.status}`;
2442
+ throw new FlurApiError(resp.status, code, message, raw);
2443
+ }
2444
+ return parser(raw);
2445
+ }
2446
+ const listSchema = import_zod8.z.object({
2447
+ items: import_zod8.z.array(ApiCredentialPublicSchema)
2448
+ });
2449
+ return {
2450
+ list: (accountId) => call(
2451
+ "GET",
2452
+ `/v1/accounts/${accountId}/api-credentials`,
2453
+ void 0,
2454
+ (raw) => listSchema.parse(raw)
2455
+ ),
2456
+ mint: (accountId, input) => call(
2457
+ "POST",
2458
+ `/v1/accounts/${accountId}/api-credentials`,
2459
+ input,
2460
+ (raw) => MintedApiCredentialSchema.parse(raw)
2461
+ ),
2462
+ revoke: (accountId, credentialId) => call(
2463
+ "DELETE",
2464
+ `/v1/accounts/${accountId}/api-credentials/${credentialId}`,
2465
+ void 0,
2466
+ (raw) => ApiCredentialPublicSchema.parse(raw)
2467
+ )
2468
+ };
2469
+ }
2470
+
2471
+ // src/passes/pass.ts
2472
+ var import_zod9 = require("zod");
2473
+ var PASS_KINDS = [
2474
+ "ride-ticket",
2475
+ "transit-pass",
2476
+ "event-ticket",
2477
+ "voucher",
2478
+ "loyalty",
2479
+ "receipt-link"
2480
+ ];
2481
+ var PASS_STATES = [
2482
+ "issued",
2483
+ "active",
2484
+ "redeemed",
2485
+ "expired",
2486
+ "revoked"
2487
+ ];
2488
+ var HexString2 = (length) => import_zod9.z.string().regex(
2489
+ new RegExp(`^[0-9a-fA-F]{${length * 2}}$`),
2490
+ `expected ${length}-byte hex string`
2491
+ );
2492
+ var PassMetadataSchema = import_zod9.z.record(
2493
+ import_zod9.z.union([import_zod9.z.string(), import_zod9.z.number(), import_zod9.z.boolean(), import_zod9.z.null()])
2494
+ );
2495
+ var PassSchema = import_zod9.z.object({
2496
+ passId: import_zod9.z.string().min(1),
2497
+ /** Optional client/template grouping id (server may omit). */
2498
+ templateId: import_zod9.z.string().min(1).optional(),
2499
+ /** Optional human-facing holder identity (server may omit). The cryptographic binding
2500
+ * is `holderDevicePubkey` below. */
2501
+ holderUserId: import_zod9.z.string().min(1).optional(),
2502
+ kind: import_zod9.z.enum(PASS_KINDS),
2503
+ issuerId: import_zod9.z.string().min(1),
2504
+ issuedAtMs: import_zod9.z.number().int().nonnegative(),
2505
+ validFromMs: import_zod9.z.number().int().nonnegative(),
2506
+ validUntilMs: import_zod9.z.number().int().positive(),
2507
+ state: import_zod9.z.enum(PASS_STATES),
2508
+ metadata: PassMetadataSchema,
2509
+ nonce: import_zod9.z.string().min(1),
2510
+ /** Device id this pass is bound to (FK to backend `device_keys`). */
2511
+ holderDeviceId: import_zod9.z.string().min(1),
2512
+ /** 32-byte hex Ed25519 public key of the bound device. The redemption signature
2513
+ * is verified against this key — it is the security-critical binding. */
2514
+ holderDevicePubkey: HexString2(32),
2515
+ /** Optional fixed amount for monetary passes (vouchers, gift cards) in kobo. */
2516
+ amountKobo: import_zod9.z.number().int().nonnegative().optional(),
2517
+ /** ISO-4217-ish currency code; required on the wire. SDK builders default to NGN. */
2518
+ currency: import_zod9.z.string().min(3).max(8),
2519
+ /** Monotonic redemption counter floor. Redemption.counter MUST be > counterSeed. */
2520
+ counterSeed: import_zod9.z.number().int().nonnegative(),
2521
+ /** Optional cumulative spend cap in kobo across all redemptions of this pass. */
2522
+ cumulativeCapKobo: import_zod9.z.number().int().nonnegative().optional(),
2523
+ issuerSig: HexString2(64)
2524
+ }).refine((v) => v.validUntilMs > v.validFromMs, {
2525
+ message: "validUntilMs must be greater than validFromMs"
2526
+ });
2527
+ function buildPass(input) {
2528
+ if (input.validUntilMs <= input.validFromMs) {
2529
+ throw new Error("validUntilMs must be greater than validFromMs");
2530
+ }
2531
+ const out = {
2532
+ passId: input.passId,
2533
+ kind: input.kind,
2534
+ issuerId: input.issuerId,
2535
+ issuedAtMs: input.issuedAtMs,
2536
+ validFromMs: input.validFromMs,
2537
+ validUntilMs: input.validUntilMs,
2538
+ state: input.state,
2539
+ metadata: input.metadata,
2540
+ nonce: input.nonce,
2541
+ holderDeviceId: input.holderDeviceId,
2542
+ holderDevicePubkey: input.holderDevicePubkey,
2543
+ currency: input.currency ?? "NGN",
2544
+ counterSeed: input.counterSeed
2545
+ };
2546
+ if (typeof input.templateId === "string") out.templateId = input.templateId;
2547
+ if (typeof input.holderUserId === "string")
2548
+ out.holderUserId = input.holderUserId;
2549
+ if (typeof input.amountKobo === "number") out.amountKobo = input.amountKobo;
2550
+ if (typeof input.cumulativeCapKobo === "number") {
2551
+ out.cumulativeCapKobo = input.cumulativeCapKobo;
2552
+ }
2553
+ return out;
2554
+ }
2555
+ function signPass(unsigned, issuerPrivateKey) {
2556
+ const issuerSig = bytesToHex(
2557
+ sign(canonicalJSONBytes(unsigned), issuerPrivateKey)
2558
+ );
2559
+ return { ...unsigned, issuerSig };
2560
+ }
2561
+ function verifyPass(pass, issuerPublicKey) {
2562
+ try {
2563
+ const parsed = PassSchema.parse(pass);
2564
+ const { issuerSig, ...unsigned } = parsed;
2565
+ return verify(
2566
+ canonicalJSONBytes(unsigned),
2567
+ hexToBytes(issuerSig),
2568
+ issuerPublicKey
2569
+ );
2570
+ } catch {
2571
+ return false;
2572
+ }
2573
+ }
2574
+ function isPassWithinValidity(pass, nowMs) {
2575
+ return nowMs >= pass.validFromMs && nowMs < pass.validUntilMs;
2576
+ }
2577
+
2578
+ // src/passes/redemption.ts
2579
+ var import_zod10 = require("zod");
2580
+ var HexSig2 = import_zod10.z.string().regex(/^[0-9a-fA-F]{128}$/, "expected 64-byte hex signature");
2581
+ var RedemptionSchema = import_zod10.z.object({
2582
+ pass: PassSchema,
2583
+ redeemerId: import_zod10.z.string().min(1),
2584
+ redeemedAtMs: import_zod10.z.number().int().nonnegative(),
2585
+ /** Strictly monotonic counter scoped to a single pass. Must be > pass.counterSeed
2586
+ * and > the redeemer's lastSeenCounter for this pass. */
2587
+ counter: import_zod10.z.number().int().positive(),
2588
+ /** Amount being redeemed in kobo (0 for non-monetary passes like ride tickets). */
2589
+ amountKobo: import_zod10.z.number().int().nonnegative(),
2590
+ nonce: import_zod10.z.string().min(1),
2591
+ holderSig: HexSig2
2592
+ });
2593
+ var REDEEMABLE_STATES = /* @__PURE__ */ new Set(["issued", "active"]);
2594
+ function buildRedemption(input) {
2595
+ if (!REDEEMABLE_STATES.has(input.pass.state)) {
2596
+ throw new Error(`pass not in redeemable state: ${input.pass.state}`);
2597
+ }
1962
2598
  if (input.redeemedAtMs < input.pass.validFromMs) {
1963
2599
  throw new Error("redeemedAtMs is before pass validFromMs");
1964
2600
  }
@@ -2037,43 +2673,43 @@ function verifyRedemption(r, issuerPublicKey) {
2037
2673
  }
2038
2674
 
2039
2675
  // src/receipts/receipt.ts
2040
- var import_zod9 = require("zod");
2676
+ var import_zod11 = require("zod");
2041
2677
  var RECEIPT_CHANNELS = ["cash", "pass"];
2042
2678
  var RECEIPT_KINDS = RECEIPT_CHANNELS;
2043
- var HexString3 = (length) => import_zod9.z.string().regex(
2679
+ var HexString3 = (length) => import_zod11.z.string().regex(
2044
2680
  new RegExp(`^[0-9a-fA-F]{${length * 2}}$`),
2045
2681
  `expected ${length}-byte hex string`
2046
2682
  );
2047
- var ReceiptPayloadSchema = import_zod9.z.record(
2048
- import_zod9.z.union([import_zod9.z.string(), import_zod9.z.number(), import_zod9.z.boolean(), import_zod9.z.null()])
2683
+ var ReceiptPayloadSchema = import_zod11.z.record(
2684
+ import_zod11.z.union([import_zod11.z.string(), import_zod11.z.number(), import_zod11.z.boolean(), import_zod11.z.null()])
2049
2685
  );
2050
- var ReceiptSchema = import_zod9.z.object({
2051
- receiptId: import_zod9.z.string().min(1),
2052
- channel: import_zod9.z.enum(RECEIPT_CHANNELS),
2686
+ var ReceiptSchema = import_zod11.z.object({
2687
+ receiptId: import_zod11.z.string().min(1),
2688
+ channel: import_zod11.z.enum(RECEIPT_CHANNELS),
2053
2689
  /** Cash-channel: send_intents.id. Required when channel === 'cash'. */
2054
- intentId: import_zod9.z.string().min(1).optional(),
2690
+ intentId: import_zod11.z.string().min(1).optional(),
2055
2691
  /** Pass-channel: pass_redemptions.id. Required when channel === 'pass'. */
2056
- passRedemptionId: import_zod9.z.string().min(1).optional(),
2057
- payerUserId: import_zod9.z.string().min(1),
2058
- payeeUserId: import_zod9.z.string().min(1),
2059
- amountKobo: import_zod9.z.number().int().nonnegative(),
2060
- currency: import_zod9.z.string().min(3).max(8),
2061
- issuedAtMs: import_zod9.z.number().int().nonnegative(),
2062
- issuerId: import_zod9.z.string().min(1),
2692
+ passRedemptionId: import_zod11.z.string().min(1).optional(),
2693
+ payerUserId: import_zod11.z.string().min(1),
2694
+ payeeUserId: import_zod11.z.string().min(1),
2695
+ amountKobo: import_zod11.z.number().int().nonnegative(),
2696
+ currency: import_zod11.z.string().min(3).max(8),
2697
+ issuedAtMs: import_zod11.z.number().int().nonnegative(),
2698
+ issuerId: import_zod11.z.string().min(1),
2063
2699
  payload: ReceiptPayloadSchema,
2064
2700
  issuerSig: HexString3(64)
2065
2701
  }).superRefine((v, ctx) => {
2066
2702
  if (v.channel === "cash") {
2067
2703
  if (!v.intentId) {
2068
2704
  ctx.addIssue({
2069
- code: import_zod9.z.ZodIssueCode.custom,
2705
+ code: import_zod11.z.ZodIssueCode.custom,
2070
2706
  message: "cash receipts require intentId",
2071
2707
  path: ["intentId"]
2072
2708
  });
2073
2709
  }
2074
2710
  if (v.passRedemptionId) {
2075
2711
  ctx.addIssue({
2076
- code: import_zod9.z.ZodIssueCode.custom,
2712
+ code: import_zod11.z.ZodIssueCode.custom,
2077
2713
  message: "cash receipts must not carry passRedemptionId",
2078
2714
  path: ["passRedemptionId"]
2079
2715
  });
@@ -2081,14 +2717,14 @@ var ReceiptSchema = import_zod9.z.object({
2081
2717
  } else if (v.channel === "pass") {
2082
2718
  if (!v.passRedemptionId) {
2083
2719
  ctx.addIssue({
2084
- code: import_zod9.z.ZodIssueCode.custom,
2720
+ code: import_zod11.z.ZodIssueCode.custom,
2085
2721
  message: "pass receipts require passRedemptionId",
2086
2722
  path: ["passRedemptionId"]
2087
2723
  });
2088
2724
  }
2089
2725
  if (v.intentId) {
2090
2726
  ctx.addIssue({
2091
- code: import_zod9.z.ZodIssueCode.custom,
2727
+ code: import_zod11.z.ZodIssueCode.custom,
2092
2728
  message: "pass receipts must not carry intentId",
2093
2729
  path: ["intentId"]
2094
2730
  });
@@ -2327,317 +2963,90 @@ function createReceiptsClient(opts) {
2327
2963
  verifyReceipt: (receipt, issuerPublicKey) => verifyReceipt(receipt, issuerPublicKey)
2328
2964
  };
2329
2965
  }
2330
-
2331
- // src/client/flur.ts
2332
- function generateStaticQR(input) {
2333
- return encodeNQR({ ...input, pointOfInitiation: "static" });
2334
- }
2335
- function generateDynamicQR(input) {
2336
- return encodeNQR({ ...input, pointOfInitiation: "dynamic" });
2337
- }
2338
- function parseQR(payload) {
2339
- return parseNQR(payload);
2340
- }
2341
- function init(opts) {
2342
- const signedFetch = createHmacFetch({
2343
- apiKey: opts.apiKey,
2344
- apiSecret: opts.apiSecret,
2345
- fetchImpl: opts.fetchImpl,
2346
- scope: opts.scope
2347
- });
2348
- const baseUrl = opts.baseUrl.replace(/\/$/, "");
2349
- function subscribeToPayments(s) {
2350
- const controller = new AbortController();
2351
- let cancelled = false;
2352
- (async () => {
2353
- try {
2354
- const url = `${baseUrl}/v1/payments/subscribe?reference=${encodeURIComponent(s.reference)}`;
2355
- const resp = await signedFetch(url, {
2356
- method: "GET",
2357
- headers: { accept: "text/event-stream" },
2358
- signal: controller.signal
2359
- });
2360
- if (!resp.body) return;
2361
- const reader = resp.body.getReader();
2362
- const decoder = new TextDecoder();
2363
- let buffer = "";
2364
- while (!cancelled) {
2365
- const { value, done } = await reader.read();
2366
- if (done) return;
2367
- buffer += decoder.decode(value, { stream: true });
2368
- let idx;
2369
- while ((idx = buffer.indexOf("\n\n")) >= 0) {
2370
- const chunk = buffer.slice(0, idx);
2371
- buffer = buffer.slice(idx + 2);
2372
- for (const line of chunk.split("\n")) {
2373
- if (!line.startsWith("data:")) continue;
2374
- const json = line.slice(5).trim();
2375
- if (!json) continue;
2376
- try {
2377
- s.onEvent(JSON.parse(json));
2378
- } catch (err) {
2379
- s.onError?.(err);
2380
- }
2381
- }
2382
- }
2383
- }
2384
- } catch (err) {
2385
- if (!cancelled) s.onError?.(err);
2386
- }
2387
- })();
2388
- return () => {
2389
- cancelled = true;
2390
- controller.abort();
2391
- };
2392
- }
2393
- const cash = {
2394
- generateStaticQR,
2395
- generateDynamicQR,
2396
- parseQR,
2397
- subscribeToPayments
2398
- };
2399
- const passes = createPassesClient({ baseUrl, fetchImpl: signedFetch });
2400
- const receipts = createReceiptsClient({ baseUrl, fetchImpl: signedFetch });
2401
- return {
2402
- // top-level back-compat surface
2403
- generateStaticQR,
2404
- generateDynamicQR,
2405
- parseQR,
2406
- subscribeToPayments,
2407
- // namespaces
2408
- cash,
2409
- passes,
2410
- receipts
2411
- };
2412
- }
2413
-
2414
- // src/accounts/client.ts
2415
- var import_zod10 = require("zod");
2416
- var ACCOUNT_TYPES = ["personal", "business", "partner"];
2417
- var ACCOUNT_STATUSES = ["active", "suspended", "closed"];
2418
- var MEMBERSHIP_ROLES = ["owner", "admin", "driver", "staff"];
2419
- var AccountSchema = import_zod10.z.object({
2420
- accountId: import_zod10.z.string().uuid(),
2421
- type: import_zod10.z.enum(ACCOUNT_TYPES),
2422
- displayName: import_zod10.z.string().min(1),
2423
- status: import_zod10.z.enum(ACCOUNT_STATUSES),
2424
- ownerUserId: import_zod10.z.string().uuid().nullable(),
2425
- createdAtMs: import_zod10.z.number().int().nonnegative()
2426
- });
2427
- var AccountMembershipSchema = import_zod10.z.object({
2428
- accountId: import_zod10.z.string().uuid(),
2429
- userId: import_zod10.z.string().uuid(),
2430
- role: import_zod10.z.enum(MEMBERSHIP_ROLES),
2431
- createdAtMs: import_zod10.z.number().int().nonnegative()
2432
- });
2433
- function createAccountsClient(opts) {
2434
- const fetchImpl = opts.fetchImpl ?? globalThis.fetch;
2435
- if (!fetchImpl) {
2436
- throw new Error("createAccountsClient: no fetch implementation available");
2437
- }
2438
- const baseUrl = opts.baseUrl.replace(/\/$/, "");
2439
- async function call(method, path, body, parser) {
2440
- const init2 = {
2441
- method,
2442
- headers: {
2443
- "content-type": "application/json",
2444
- accept: "application/json"
2445
- }
2446
- };
2447
- if (body !== void 0) init2.body = JSON.stringify(body);
2448
- const resp = await fetchImpl(`${baseUrl}${path}`, init2);
2449
- const text = await resp.text();
2450
- let raw = void 0;
2451
- if (text) {
2452
- try {
2453
- raw = JSON.parse(text);
2454
- } catch {
2455
- }
2456
- }
2457
- if (!resp.ok) {
2458
- const code = raw && typeof raw === "object" && "code" in raw && typeof raw.code === "string" ? raw.code : `http_${resp.status}`;
2459
- const message = raw && typeof raw === "object" && "message" in raw && typeof raw.message === "string" ? raw.message : `request failed with status ${resp.status}`;
2460
- throw new FlurApiError(resp.status, code, message, raw);
2461
- }
2462
- return parser(raw);
2463
- }
2464
- const itemsSchema = import_zod10.z.object({ items: import_zod10.z.array(AccountSchema) });
2465
- const memberItemsSchema = import_zod10.z.object({
2466
- items: import_zod10.z.array(AccountMembershipSchema)
2467
- });
2468
- return {
2469
- listMyAccounts: () => call(
2470
- "GET",
2471
- "/v1/accounts/me",
2472
- void 0,
2473
- (raw) => itemsSchema.parse(raw)
2474
- ),
2475
- getAccount: (accountId) => call(
2476
- "GET",
2477
- `/v1/accounts/${encodeURIComponent(accountId)}`,
2478
- void 0,
2479
- (raw) => AccountSchema.parse(raw)
2480
- ),
2481
- listMembers: (accountId) => call(
2482
- "GET",
2483
- `/v1/accounts/${encodeURIComponent(accountId)}/members`,
2484
- void 0,
2485
- (raw) => memberItemsSchema.parse(raw)
2486
- ),
2487
- createBusinessAccount: (input) => call("POST", "/v1/accounts", input, (raw) => AccountSchema.parse(raw)),
2488
- addMember: (accountId, input) => call(
2489
- "POST",
2490
- `/v1/accounts/${encodeURIComponent(accountId)}/members`,
2491
- input,
2492
- (raw) => AccountMembershipSchema.parse(raw)
2493
- )
2494
- };
2495
- }
2496
-
2497
- // src/partner/client.ts
2498
- var import_zod11 = require("zod");
2499
- var import_sha2563 = require("@noble/hashes/sha256");
2500
- var import_hmac4 = require("@noble/hashes/hmac");
2501
- var import_utils2 = require("@noble/hashes/utils");
2502
- var PARTNER_SCOPES = [
2503
- "passes:write",
2504
- "passes:read",
2505
- "passes:redeem",
2506
- "receipts:write",
2507
- "receipts:read",
2508
- "offline:issue",
2509
- "offline:settle",
2510
- "offline:read"
2511
- ];
2512
- var ApiCredentialPublicSchema = import_zod11.z.object({
2513
- id: import_zod11.z.string().uuid(),
2514
- accountId: import_zod11.z.string().uuid(),
2515
- keyId: import_zod11.z.string(),
2516
- scopes: import_zod11.z.array(import_zod11.z.enum(PARTNER_SCOPES)),
2517
- label: import_zod11.z.string().nullable(),
2518
- createdAtMs: import_zod11.z.number().int().nonnegative(),
2519
- lastUsedAtMs: import_zod11.z.number().int().nonnegative().nullable(),
2520
- revokedAtMs: import_zod11.z.number().int().nonnegative().nullable()
2521
- });
2522
- var MintedApiCredentialSchema = ApiCredentialPublicSchema.extend({
2523
- secret: import_zod11.z.string().min(1)
2524
- });
2525
- var enc = new TextEncoder();
2526
- async function sha256Hex2(input) {
2527
- const data = typeof input === "string" ? enc.encode(input) : input;
2528
- return (0, import_utils2.bytesToHex)((0, import_sha2563.sha256)(data));
2529
- }
2530
- async function hmacSha256Hex(keyHex, message) {
2531
- return (0, import_utils2.bytesToHex)((0, import_hmac4.hmac)(import_sha2563.sha256, enc.encode(keyHex), enc.encode(message)));
2532
- }
2533
- function defaultNonce2() {
2534
- const c = globalThis.crypto;
2535
- if (c?.randomUUID) return c.randomUUID();
2536
- return `${Date.now().toString(16)}-${Math.random().toString(16).slice(2)}`;
2537
- }
2538
- function canonical(params) {
2539
- return [
2540
- params.method.toUpperCase(),
2541
- params.path,
2542
- params.ts,
2543
- params.nonce,
2544
- params.bodyHash
2545
- ].join("\n");
2546
- }
2547
- async function signPartnerRequest(params) {
2548
- const ts = String(Math.floor((params.nowMs ?? Date.now()) / 1e3));
2549
- const nonce = params.nonce ?? defaultNonce2();
2550
- const bodyData = typeof params.body === "string" ? enc.encode(params.body) : params.body ?? new Uint8Array();
2551
- const bodyHash = await sha256Hex2(bodyData);
2552
- const message = canonical({
2553
- method: params.method,
2554
- path: params.path,
2555
- ts,
2556
- nonce,
2557
- bodyHash
2558
- });
2559
- const signingKey = await sha256Hex2(params.secret);
2560
- const sig = await hmacSha256Hex(signingKey, message);
2561
- return {
2562
- authorization: `Flur-Hmac key=${params.keyId}, ts=${ts}, nonce=${nonce}, sig=${sig}`,
2563
- ts,
2564
- nonce,
2565
- bodyHash
2566
- };
2966
+
2967
+ // src/client/flur.ts
2968
+ function generateStaticQR(input) {
2969
+ return encodeNQR({ ...input, pointOfInitiation: "static" });
2567
2970
  }
2568
- function createFlurPartnerClient(opts) {
2569
- const fetchImpl = opts.fetchImpl ?? globalThis.fetch;
2570
- if (!fetchImpl) {
2571
- throw new Error(
2572
- "createFlurPartnerClient: no fetch implementation available"
2573
- );
2574
- }
2971
+ function generateDynamicQR(input) {
2972
+ return encodeNQR({ ...input, pointOfInitiation: "dynamic" });
2973
+ }
2974
+ function parseQR(payload) {
2975
+ return parseNQR(payload);
2976
+ }
2977
+ function init(opts) {
2978
+ const partner = createFlurPartnerClient({
2979
+ baseUrl: opts.baseUrl,
2980
+ keyId: opts.apiKey,
2981
+ secret: opts.apiSecret,
2982
+ fetchImpl: opts.fetchImpl,
2983
+ scope: opts.scope
2984
+ });
2985
+ const signedFetch = partner.fetch;
2575
2986
  const baseUrl = opts.baseUrl.replace(/\/$/, "");
2576
- async function makeSignedInit(method, path, body) {
2577
- const sig = await signPartnerRequest({
2578
- keyId: opts.keyId,
2579
- secret: opts.secret,
2580
- method,
2581
- path,
2582
- body: body ?? "",
2583
- nowMs: opts.nowMs?.(),
2584
- nonce: opts.nonce?.()
2987
+ function subscribeToPayments(s) {
2988
+ let cancelled = false;
2989
+ queueMicrotask(() => {
2990
+ if (cancelled) return;
2991
+ s.onError?.(
2992
+ new Error(
2993
+ "cash.subscribeToPayments is not available on this backend release; use collections reports or provider webhooks for payment status."
2994
+ )
2995
+ );
2585
2996
  });
2586
- const headers = {
2587
- authorization: sig.authorization,
2588
- accept: "application/json"
2997
+ return () => {
2998
+ cancelled = true;
2589
2999
  };
2590
- if (body !== void 0) headers["content-type"] = "application/json";
2591
- const init2 = { method, headers };
2592
- if (body !== void 0) init2.body = body;
2593
- return init2;
2594
- }
2595
- async function request(opts2) {
2596
- const bodyStr = opts2.body === void 0 ? void 0 : JSON.stringify(opts2.body);
2597
- const init2 = await makeSignedInit(opts2.method, opts2.path, bodyStr);
2598
- const resp = await fetchImpl(`${baseUrl}${opts2.path}`, init2);
2599
- const text = await resp.text();
2600
- let raw;
2601
- if (text) {
2602
- try {
2603
- raw = JSON.parse(text);
2604
- } catch {
2605
- }
2606
- }
2607
- if (!resp.ok) {
2608
- const code = raw && typeof raw === "object" && "code" in raw && typeof raw.code === "string" ? raw.code : `http_${resp.status}`;
2609
- const message = raw && typeof raw === "object" && "message" in raw && typeof raw.message === "string" ? raw.message : `request failed with status ${resp.status}`;
2610
- throw new FlurApiError(resp.status, code, message, raw);
2611
- }
2612
- return raw;
2613
3000
  }
2614
- const fetchLike = async (input, init2) => {
2615
- const url = typeof input === "string" ? input : input.toString();
2616
- const u = new URL(url, baseUrl);
2617
- const path = `${u.pathname}${u.search}`;
2618
- const method = (init2?.method ?? "GET").toUpperCase();
2619
- let bodyStr;
2620
- if (init2?.body) {
2621
- bodyStr = typeof init2.body === "string" ? init2.body : init2.body.toString();
2622
- }
2623
- const signed = await makeSignedInit(method, path, bodyStr);
2624
- return fetchImpl(`${baseUrl}${path}`, {
2625
- ...init2,
2626
- ...signed,
2627
- headers: {
2628
- ...init2?.headers,
2629
- ...signed.headers
2630
- }
2631
- });
3001
+ const cash = {
3002
+ generateStaticQR,
3003
+ generateDynamicQR,
3004
+ parseQR,
3005
+ subscribeToPayments
3006
+ };
3007
+ const passes = createPassesClient({ baseUrl, fetchImpl: signedFetch });
3008
+ const receipts = createReceiptsClient({ baseUrl, fetchImpl: signedFetch });
3009
+ const collections = createPartnerCollectionsClient({
3010
+ baseUrl,
3011
+ fetchImpl: signedFetch
3012
+ });
3013
+ return {
3014
+ // top-level back-compat surface
3015
+ generateStaticQR,
3016
+ generateDynamicQR,
3017
+ parseQR,
3018
+ subscribeToPayments,
3019
+ // namespaces
3020
+ cash,
3021
+ collections,
3022
+ passes,
3023
+ receipts
2632
3024
  };
2633
- return { request, fetch: fetchLike };
2634
3025
  }
2635
- function createApiCredentialsAdminClient(opts) {
3026
+
3027
+ // src/accounts/client.ts
3028
+ var import_zod12 = require("zod");
3029
+ var ACCOUNT_TYPES = ["personal", "business", "partner"];
3030
+ var ACCOUNT_STATUSES = ["active", "suspended", "closed"];
3031
+ var MEMBERSHIP_ROLES = ["owner", "admin", "driver", "staff"];
3032
+ var AccountSchema = import_zod12.z.object({
3033
+ accountId: import_zod12.z.string().uuid(),
3034
+ type: import_zod12.z.enum(ACCOUNT_TYPES),
3035
+ displayName: import_zod12.z.string().min(1),
3036
+ status: import_zod12.z.enum(ACCOUNT_STATUSES),
3037
+ ownerUserId: import_zod12.z.string().uuid().nullable(),
3038
+ createdAtMs: import_zod12.z.number().int().nonnegative()
3039
+ });
3040
+ var AccountMembershipSchema = import_zod12.z.object({
3041
+ accountId: import_zod12.z.string().uuid(),
3042
+ userId: import_zod12.z.string().uuid(),
3043
+ role: import_zod12.z.enum(MEMBERSHIP_ROLES),
3044
+ createdAtMs: import_zod12.z.number().int().nonnegative()
3045
+ });
3046
+ function createAccountsClient(opts) {
2636
3047
  const fetchImpl = opts.fetchImpl ?? globalThis.fetch;
2637
3048
  if (!fetchImpl) {
2638
- throw new Error(
2639
- "createApiCredentialsAdminClient: no fetch implementation available"
2640
- );
3049
+ throw new Error("createAccountsClient: no fetch implementation available");
2641
3050
  }
2642
3051
  const baseUrl = opts.baseUrl.replace(/\/$/, "");
2643
3052
  async function call(method, path, body, parser) {
@@ -2651,7 +3060,7 @@ function createApiCredentialsAdminClient(opts) {
2651
3060
  if (body !== void 0) init2.body = JSON.stringify(body);
2652
3061
  const resp = await fetchImpl(`${baseUrl}${path}`, init2);
2653
3062
  const text = await resp.text();
2654
- let raw;
3063
+ let raw = void 0;
2655
3064
  if (text) {
2656
3065
  try {
2657
3066
  raw = JSON.parse(text);
@@ -2665,70 +3074,78 @@ function createApiCredentialsAdminClient(opts) {
2665
3074
  }
2666
3075
  return parser(raw);
2667
3076
  }
2668
- const listSchema = import_zod11.z.object({
2669
- items: import_zod11.z.array(ApiCredentialPublicSchema)
3077
+ const itemsSchema = import_zod12.z.object({ items: import_zod12.z.array(AccountSchema) });
3078
+ const memberItemsSchema = import_zod12.z.object({
3079
+ items: import_zod12.z.array(AccountMembershipSchema)
2670
3080
  });
2671
3081
  return {
2672
- list: (accountId) => call(
3082
+ listMyAccounts: () => call(
2673
3083
  "GET",
2674
- `/v1/accounts/${accountId}/api-credentials`,
3084
+ "/v1/accounts/me",
2675
3085
  void 0,
2676
- (raw) => listSchema.parse(raw)
3086
+ (raw) => itemsSchema.parse(raw)
2677
3087
  ),
2678
- mint: (accountId, input) => call(
2679
- "POST",
2680
- `/v1/accounts/${accountId}/api-credentials`,
2681
- input,
2682
- (raw) => MintedApiCredentialSchema.parse(raw)
3088
+ getAccount: (accountId) => call(
3089
+ "GET",
3090
+ `/v1/accounts/${encodeURIComponent(accountId)}`,
3091
+ void 0,
3092
+ (raw) => AccountSchema.parse(raw)
2683
3093
  ),
2684
- revoke: (accountId, credentialId) => call(
2685
- "DELETE",
2686
- `/v1/accounts/${accountId}/api-credentials/${credentialId}`,
3094
+ listMembers: (accountId) => call(
3095
+ "GET",
3096
+ `/v1/accounts/${encodeURIComponent(accountId)}/members`,
2687
3097
  void 0,
2688
- (raw) => ApiCredentialPublicSchema.parse(raw)
3098
+ (raw) => memberItemsSchema.parse(raw)
3099
+ ),
3100
+ createBusinessAccount: (input) => call("POST", "/v1/accounts", input, (raw) => AccountSchema.parse(raw)),
3101
+ addMember: (accountId, input) => call(
3102
+ "POST",
3103
+ `/v1/accounts/${encodeURIComponent(accountId)}/members`,
3104
+ input,
3105
+ (raw) => AccountMembershipSchema.parse(raw)
2689
3106
  )
2690
3107
  };
2691
3108
  }
2692
3109
 
2693
3110
  // src/me-offline/client.ts
2694
- var import_zod12 = require("zod");
2695
- var Hex64 = import_zod12.z.string().regex(/^[0-9a-f]{64}$/i);
2696
- var HexAny = import_zod12.z.string().regex(/^[0-9a-f]+$/i);
2697
- var Sha256Hex = import_zod12.z.string().regex(/^[0-9a-f]{64}$/i);
2698
- var RegisterDeviceKeyInputSchema = import_zod12.z.object({
2699
- deviceId: import_zod12.z.string().min(1).max(128),
3111
+ var import_zod13 = require("zod");
3112
+ var Hex64 = import_zod13.z.string().regex(/^[0-9a-f]{64}$/i);
3113
+ var HexAny = import_zod13.z.string().regex(/^[0-9a-f]+$/i);
3114
+ var Sha256Hex = import_zod13.z.string().regex(/^[0-9a-f]{64}$/i);
3115
+ var RegisterDeviceKeyInputSchema = import_zod13.z.object({
3116
+ deviceId: import_zod13.z.string().min(1).max(128),
2700
3117
  publicKeyHex: Hex64
2701
3118
  });
2702
- var DeviceKeyRecordSchema = import_zod12.z.object({
2703
- id: import_zod12.z.string().uuid(),
2704
- userId: import_zod12.z.string().uuid(),
2705
- deviceId: import_zod12.z.string(),
3119
+ var DeviceKeyRecordSchema = import_zod13.z.object({
3120
+ id: import_zod13.z.string().uuid(),
3121
+ userId: import_zod13.z.string().uuid(),
3122
+ deviceId: import_zod13.z.string(),
2706
3123
  publicKeyHex: Hex64,
2707
- createdAtMs: import_zod12.z.number().int().nonnegative(),
2708
- revokedAtMs: import_zod12.z.number().int().nonnegative().nullable()
3124
+ createdAtMs: import_zod13.z.number().int().nonnegative(),
3125
+ revokedAtMs: import_zod13.z.number().int().nonnegative().nullable()
2709
3126
  });
2710
- var ConsumerOACSchema = import_zod12.z.object({
2711
- oacId: import_zod12.z.string().uuid(),
2712
- issuerId: import_zod12.z.string().min(1).max(64),
2713
- userId: import_zod12.z.string().uuid(),
2714
- deviceId: import_zod12.z.string().min(1).max(128),
3127
+ var ConsumerOACSchema = import_zod13.z.object({
3128
+ oacId: import_zod13.z.string().uuid(),
3129
+ issuerId: import_zod13.z.string().min(1).max(64),
3130
+ userId: import_zod13.z.string().uuid(),
3131
+ deviceId: import_zod13.z.string().min(1).max(128),
2715
3132
  devicePubkeyHex: Hex64,
2716
- perTxCapKobo: import_zod12.z.number().int().positive(),
2717
- cumulativeCapKobo: import_zod12.z.number().int().positive(),
2718
- currency: import_zod12.z.string().length(3),
2719
- validFromMs: import_zod12.z.number().int().nonnegative(),
2720
- validUntilMs: import_zod12.z.number().int().nonnegative(),
2721
- counterSeed: import_zod12.z.number().int().nonnegative(),
2722
- issuedAtMs: import_zod12.z.number().int().nonnegative()
2723
- });
2724
- var SignedConsumerOACSchema = import_zod12.z.object({
3133
+ perTxCapKobo: import_zod13.z.number().int().positive(),
3134
+ cumulativeCapKobo: import_zod13.z.number().int().positive(),
3135
+ currency: import_zod13.z.string().length(3),
3136
+ validFromMs: import_zod13.z.number().int().nonnegative(),
3137
+ validUntilMs: import_zod13.z.number().int().nonnegative(),
3138
+ counterSeed: import_zod13.z.number().int().nonnegative(),
3139
+ issuedAtMs: import_zod13.z.number().int().nonnegative()
3140
+ });
3141
+ var SignedConsumerOACSchema = import_zod13.z.object({
2725
3142
  oac: ConsumerOACSchema,
2726
3143
  issuerSig: HexAny,
2727
3144
  issuerPublicKeyHex: Hex64
2728
3145
  });
2729
3146
  var OACRecordSchema = SignedConsumerOACSchema.extend({
2730
- currentOfflineSpentKobo: import_zod12.z.number().int().nonnegative(),
2731
- status: import_zod12.z.enum([
3147
+ currentOfflineSpentKobo: import_zod13.z.number().int().nonnegative(),
3148
+ status: import_zod13.z.enum([
2732
3149
  "active",
2733
3150
  "superseded",
2734
3151
  "expired",
@@ -2737,43 +3154,43 @@ var OACRecordSchema = SignedConsumerOACSchema.extend({
2737
3154
  "draining",
2738
3155
  "closed"
2739
3156
  ]),
2740
- supersededAtMs: import_zod12.z.number().int().nonnegative().nullable(),
2741
- revokedAtMs: import_zod12.z.number().int().nonnegative().nullable(),
2742
- holdId: import_zod12.z.string().uuid().nullable().optional()
2743
- });
2744
- var IssueOACInputSchema = import_zod12.z.object({
2745
- deviceId: import_zod12.z.string().min(1).max(128),
2746
- perTxCapKobo: import_zod12.z.number().int().positive().optional(),
2747
- cumulativeCapKobo: import_zod12.z.number().int().positive().optional(),
2748
- ttlMs: import_zod12.z.number().int().min(6e4).max(1e3 * 60 * 60 * 24 * 7).optional(),
2749
- spendableOnlineKobo: import_zod12.z.number().int().nonnegative().optional()
2750
- });
2751
- var EnableOfflineInputSchema = import_zod12.z.object({
2752
- deviceId: import_zod12.z.string().min(1).max(128),
2753
- amountKobo: import_zod12.z.number().int().positive(),
2754
- perTxCapKobo: import_zod12.z.number().int().positive().optional(),
2755
- ttlMs: import_zod12.z.number().int().min(6e4).max(1e3 * 60 * 60 * 24 * 7).optional(),
2756
- installId: import_zod12.z.string().min(1).max(128),
2757
- partnerId: import_zod12.z.string().min(1).max(64).optional()
2758
- });
2759
- var DisableOfflineInputSchema = import_zod12.z.object({
2760
- deviceId: import_zod12.z.string().min(1).max(128),
2761
- installId: import_zod12.z.string().min(1).max(128).optional(),
2762
- claims: import_zod12.z.array(import_zod12.z.unknown()).max(256).optional()
2763
- });
2764
- var OfflineHoldRecordSchema = import_zod12.z.object({
2765
- holdId: import_zod12.z.string().uuid(),
2766
- userId: import_zod12.z.string().uuid(),
2767
- deviceId: import_zod12.z.string(),
2768
- partnerId: import_zod12.z.string(),
2769
- adapterKind: import_zod12.z.string(),
2770
- externalHoldRef: import_zod12.z.string().nullable(),
2771
- amountKobo: import_zod12.z.number().int().nonnegative(),
2772
- capturedKobo: import_zod12.z.number().int().nonnegative(),
2773
- releasedKobo: import_zod12.z.number().int().nonnegative(),
2774
- remainingKobo: import_zod12.z.number().int().nonnegative(),
2775
- currency: import_zod12.z.string().length(3),
2776
- status: import_zod12.z.enum([
3157
+ supersededAtMs: import_zod13.z.number().int().nonnegative().nullable(),
3158
+ revokedAtMs: import_zod13.z.number().int().nonnegative().nullable(),
3159
+ holdId: import_zod13.z.string().uuid().nullable().optional()
3160
+ });
3161
+ var IssueOACInputSchema = import_zod13.z.object({
3162
+ deviceId: import_zod13.z.string().min(1).max(128),
3163
+ perTxCapKobo: import_zod13.z.number().int().positive().optional(),
3164
+ cumulativeCapKobo: import_zod13.z.number().int().positive().optional(),
3165
+ ttlMs: import_zod13.z.number().int().min(6e4).max(1e3 * 60 * 60 * 24 * 7).optional(),
3166
+ spendableOnlineKobo: import_zod13.z.number().int().nonnegative().optional()
3167
+ });
3168
+ var EnableOfflineInputSchema = import_zod13.z.object({
3169
+ deviceId: import_zod13.z.string().min(1).max(128),
3170
+ amountKobo: import_zod13.z.number().int().positive(),
3171
+ perTxCapKobo: import_zod13.z.number().int().positive().optional(),
3172
+ ttlMs: import_zod13.z.number().int().min(6e4).max(1e3 * 60 * 60 * 24 * 7).optional(),
3173
+ installId: import_zod13.z.string().min(1).max(128),
3174
+ partnerId: import_zod13.z.string().min(1).max(64).optional()
3175
+ });
3176
+ var DisableOfflineInputSchema = import_zod13.z.object({
3177
+ deviceId: import_zod13.z.string().min(1).max(128),
3178
+ installId: import_zod13.z.string().min(1).max(128).optional(),
3179
+ claims: import_zod13.z.array(import_zod13.z.unknown()).max(256).optional()
3180
+ });
3181
+ var OfflineHoldRecordSchema = import_zod13.z.object({
3182
+ holdId: import_zod13.z.string().uuid(),
3183
+ userId: import_zod13.z.string().uuid(),
3184
+ deviceId: import_zod13.z.string(),
3185
+ partnerId: import_zod13.z.string(),
3186
+ adapterKind: import_zod13.z.string(),
3187
+ externalHoldRef: import_zod13.z.string().nullable(),
3188
+ amountKobo: import_zod13.z.number().int().nonnegative(),
3189
+ capturedKobo: import_zod13.z.number().int().nonnegative(),
3190
+ releasedKobo: import_zod13.z.number().int().nonnegative(),
3191
+ remainingKobo: import_zod13.z.number().int().nonnegative(),
3192
+ currency: import_zod13.z.string().length(3),
3193
+ status: import_zod13.z.enum([
2777
3194
  "placing",
2778
3195
  "active",
2779
3196
  "disabling",
@@ -2782,71 +3199,71 @@ var OfflineHoldRecordSchema = import_zod12.z.object({
2782
3199
  "revoked",
2783
3200
  "failed"
2784
3201
  ]),
2785
- installId: import_zod12.z.string().nullable(),
2786
- drainDeadlineMs: import_zod12.z.number().int().nonnegative(),
2787
- disableRequestedAtMs: import_zod12.z.number().int().nonnegative().nullable(),
2788
- createdAtMs: import_zod12.z.number().int().nonnegative(),
2789
- closedAtMs: import_zod12.z.number().int().nonnegative().nullable(),
2790
- isTrusted: import_zod12.z.boolean().optional()
2791
- });
2792
- var EnableOfflineResultSchema = import_zod12.z.object({
3202
+ installId: import_zod13.z.string().nullable(),
3203
+ drainDeadlineMs: import_zod13.z.number().int().nonnegative(),
3204
+ disableRequestedAtMs: import_zod13.z.number().int().nonnegative().nullable(),
3205
+ createdAtMs: import_zod13.z.number().int().nonnegative(),
3206
+ closedAtMs: import_zod13.z.number().int().nonnegative().nullable(),
3207
+ isTrusted: import_zod13.z.boolean().optional()
3208
+ });
3209
+ var EnableOfflineResultSchema = import_zod13.z.object({
2793
3210
  hold: OfflineHoldRecordSchema,
2794
3211
  oac: OACRecordSchema
2795
3212
  });
2796
- var DisableOfflineResultSchema = import_zod12.z.object({
3213
+ var DisableOfflineResultSchema = import_zod13.z.object({
2797
3214
  hold: OfflineHoldRecordSchema,
2798
- trusted: import_zod12.z.boolean(),
2799
- settledClaims: import_zod12.z.number().int().nonnegative()
3215
+ trusted: import_zod13.z.boolean(),
3216
+ settledClaims: import_zod13.z.number().int().nonnegative()
2800
3217
  });
2801
- var OfflineStatusResultSchema = import_zod12.z.object({
3218
+ var OfflineStatusResultSchema = import_zod13.z.object({
2802
3219
  hold: OfflineHoldRecordSchema.nullable(),
2803
3220
  active: OACRecordSchema.nullable()
2804
3221
  });
2805
- var OfflineStateResultSchema = import_zod12.z.object({
3222
+ var OfflineStateResultSchema = import_zod13.z.object({
2806
3223
  active: OACRecordSchema.nullable()
2807
3224
  });
2808
- var ConsumerPaymentClaimSchema = import_zod12.z.object({
2809
- oacId: import_zod12.z.string().uuid(),
3225
+ var ConsumerPaymentClaimSchema = import_zod13.z.object({
3226
+ oacId: import_zod13.z.string().uuid(),
2810
3227
  encounterId: Sha256Hex.optional(),
2811
- payerUserId: import_zod12.z.string().uuid(),
2812
- payeeUserId: import_zod12.z.string().uuid(),
2813
- payerDeviceId: import_zod12.z.string().min(1).max(128),
2814
- payerNonce: import_zod12.z.string().min(8).max(128),
2815
- payeeNonce: import_zod12.z.string().min(8).max(128),
2816
- amountKobo: import_zod12.z.number().int().positive(),
2817
- currency: import_zod12.z.string().length(3).default("NGN"),
2818
- occurredAtMs: import_zod12.z.number().int().nonnegative(),
2819
- completedAtMs: import_zod12.z.number().int().nonnegative().optional(),
2820
- contextId: import_zod12.z.string().max(128).optional(),
3228
+ payerUserId: import_zod13.z.string().uuid(),
3229
+ payeeUserId: import_zod13.z.string().uuid(),
3230
+ payerDeviceId: import_zod13.z.string().min(1).max(128),
3231
+ payerNonce: import_zod13.z.string().min(8).max(128),
3232
+ payeeNonce: import_zod13.z.string().min(8).max(128),
3233
+ amountKobo: import_zod13.z.number().int().positive(),
3234
+ currency: import_zod13.z.string().length(3).default("NGN"),
3235
+ occurredAtMs: import_zod13.z.number().int().nonnegative(),
3236
+ completedAtMs: import_zod13.z.number().int().nonnegative().optional(),
3237
+ contextId: import_zod13.z.string().max(128).optional(),
2821
3238
  payerPubkeyHex: Hex64,
2822
3239
  payerSignature: HexAny,
2823
3240
  payeePubkeyHex: Hex64.optional(),
2824
3241
  payeeSignature: HexAny.optional()
2825
3242
  });
2826
- var ConsumerSettlementSchema = import_zod12.z.object({
2827
- settlementId: import_zod12.z.string().uuid(),
3243
+ var ConsumerSettlementSchema = import_zod13.z.object({
3244
+ settlementId: import_zod13.z.string().uuid(),
2828
3245
  settlementKey: Sha256Hex,
2829
3246
  encounterId: Sha256Hex,
2830
- oacId: import_zod12.z.string().uuid(),
2831
- payerUserId: import_zod12.z.string().uuid(),
2832
- payeeUserId: import_zod12.z.string().uuid(),
2833
- amountKobo: import_zod12.z.number().int().positive(),
2834
- currency: import_zod12.z.string().length(3),
2835
- status: import_zod12.z.enum(["SETTLED", "REVIEW"]),
2836
- reviewReason: import_zod12.z.string().nullable(),
2837
- ledgerRef: import_zod12.z.string().nullable(),
3247
+ oacId: import_zod13.z.string().uuid(),
3248
+ payerUserId: import_zod13.z.string().uuid(),
3249
+ payeeUserId: import_zod13.z.string().uuid(),
3250
+ amountKobo: import_zod13.z.number().int().positive(),
3251
+ currency: import_zod13.z.string().length(3),
3252
+ status: import_zod13.z.enum(["SETTLED", "REVIEW"]),
3253
+ reviewReason: import_zod13.z.string().nullable(),
3254
+ ledgerRef: import_zod13.z.string().nullable(),
2838
3255
  issuerSig: HexAny,
2839
- createdAtMs: import_zod12.z.number().int().nonnegative()
3256
+ createdAtMs: import_zod13.z.number().int().nonnegative()
2840
3257
  });
2841
- var ConsumerSettleResultSchema = import_zod12.z.object({
3258
+ var ConsumerSettleResultSchema = import_zod13.z.object({
2842
3259
  settlement: ConsumerSettlementSchema,
2843
3260
  encounterId: Sha256Hex,
2844
- replayed: import_zod12.z.boolean()
3261
+ replayed: import_zod13.z.boolean()
2845
3262
  });
2846
- var RevokeDeviceKeyInputSchema = import_zod12.z.object({
2847
- deviceId: import_zod12.z.string().min(1).max(128),
3263
+ var RevokeDeviceKeyInputSchema = import_zod13.z.object({
3264
+ deviceId: import_zod13.z.string().min(1).max(128),
2848
3265
  /** Step-up token from /api/v1/auth/send/verify with purpose='offline_revoke'. */
2849
- sendAuthToken: import_zod12.z.string().min(16)
3266
+ sendAuthToken: import_zod13.z.string().min(16)
2850
3267
  });
2851
3268
  function createMeOfflineClient(opts) {
2852
3269
  const fetchImpl = opts.fetchImpl ?? globalThis.fetch;
@@ -2879,7 +3296,7 @@ function createMeOfflineClient(opts) {
2879
3296
  }
2880
3297
  return parser(raw);
2881
3298
  }
2882
- const deviceKeyItems = import_zod12.z.object({ items: import_zod12.z.array(DeviceKeyRecordSchema) });
3299
+ const deviceKeyItems = import_zod13.z.object({ items: import_zod13.z.array(DeviceKeyRecordSchema) });
2883
3300
  return {
2884
3301
  registerDeviceKey: (input) => call(
2885
3302
  "POST",
@@ -2943,6 +3360,320 @@ function createMeOfflineClient(opts) {
2943
3360
  )
2944
3361
  };
2945
3362
  }
3363
+
3364
+ // src/partner-funding/client.ts
3365
+ var import_zod14 = require("zod");
3366
+ var MinorString = import_zod14.z.string().regex(/^-?\d+$/);
3367
+ var PositiveMinor = import_zod14.z.union([
3368
+ import_zod14.z.number().int().positive(),
3369
+ import_zod14.z.string().regex(/^[1-9]\d{0,18}$/)
3370
+ ]);
3371
+ var Currency = import_zod14.z.string().trim().length(3).transform((v) => v.toUpperCase());
3372
+ var Metadata = import_zod14.z.record(import_zod14.z.unknown());
3373
+ var PARTNER_KINDS = ["bank", "merchant"];
3374
+ var CUSTODIAL_MODES = ["agent_of_bank", "flur_virtual_pool"];
3375
+ var PARTNER_PROFILE_STATUSES = [
3376
+ "active",
3377
+ "suspended",
3378
+ "closed"
3379
+ ];
3380
+ var PARTNER_FUNDING_DIRECTIONS = ["credit", "debit"];
3381
+ var PARTNER_FUNDING_STATUSES = [
3382
+ "pending",
3383
+ "posted",
3384
+ "failed"
3385
+ ];
3386
+ var PAYOUT_DESTINATION_STATUSES = [
3387
+ "pending",
3388
+ "verified",
3389
+ "disabled"
3390
+ ];
3391
+ var WITHDRAWAL_STATES = [
3392
+ "requested",
3393
+ "submitted",
3394
+ "processing",
3395
+ "paid",
3396
+ "failed",
3397
+ "reversed"
3398
+ ];
3399
+ var PartnerProfileSchema = import_zod14.z.object({
3400
+ partnerAccountId: import_zod14.z.string().uuid(),
3401
+ kind: import_zod14.z.enum(PARTNER_KINDS),
3402
+ custodialMode: import_zod14.z.enum(CUSTODIAL_MODES),
3403
+ displayName: import_zod14.z.string(),
3404
+ bankCode: import_zod14.z.string().nullable(),
3405
+ poolAccountNumber: import_zod14.z.string().nullable(),
3406
+ status: import_zod14.z.enum(PARTNER_PROFILE_STATUSES),
3407
+ metadata: Metadata,
3408
+ createdAtMs: import_zod14.z.number().int().nonnegative(),
3409
+ updatedAtMs: import_zod14.z.number().int().nonnegative()
3410
+ });
3411
+ var UpsertPartnerProfileInputSchema = import_zod14.z.object({
3412
+ kind: import_zod14.z.enum(PARTNER_KINDS),
3413
+ custodialMode: import_zod14.z.enum(CUSTODIAL_MODES),
3414
+ displayName: import_zod14.z.string().trim().min(1).max(200),
3415
+ bankCode: import_zod14.z.string().trim().min(1).max(64).optional(),
3416
+ poolAccountNumber: import_zod14.z.string().trim().min(1).max(64).optional(),
3417
+ metadata: Metadata.optional()
3418
+ });
3419
+ var PartnerFundingEventInputSchema = import_zod14.z.object({
3420
+ externalRef: import_zod14.z.string().trim().min(8).max(128),
3421
+ direction: import_zod14.z.enum(PARTNER_FUNDING_DIRECTIONS).optional(),
3422
+ userId: import_zod14.z.string().uuid().optional(),
3423
+ accountId: import_zod14.z.string().uuid().optional(),
3424
+ amountMinor: PositiveMinor,
3425
+ currency: Currency,
3426
+ fundingSource: import_zod14.z.string().trim().min(1).max(64).optional(),
3427
+ providerMetadata: Metadata.optional()
3428
+ });
3429
+ var PartnerFundingSchema = import_zod14.z.object({
3430
+ fundingId: import_zod14.z.string().uuid(),
3431
+ partnerId: import_zod14.z.string().uuid(),
3432
+ accountId: import_zod14.z.string().uuid(),
3433
+ userId: import_zod14.z.string().uuid().nullable(),
3434
+ direction: import_zod14.z.enum(PARTNER_FUNDING_DIRECTIONS),
3435
+ currency: import_zod14.z.string(),
3436
+ amountMinor: MinorString,
3437
+ externalRef: import_zod14.z.string(),
3438
+ status: import_zod14.z.enum(PARTNER_FUNDING_STATUSES),
3439
+ fundingSource: import_zod14.z.string(),
3440
+ ledgerRef: import_zod14.z.string(),
3441
+ providerMetadata: Metadata,
3442
+ createdAtMs: import_zod14.z.number().int().nonnegative(),
3443
+ updatedAtMs: import_zod14.z.number().int().nonnegative()
3444
+ });
3445
+ var IngestFundingResultSchema = import_zod14.z.object({
3446
+ funding: PartnerFundingSchema,
3447
+ replayed: import_zod14.z.boolean()
3448
+ });
3449
+ var PayoutDestinationSchema = import_zod14.z.object({
3450
+ destinationId: import_zod14.z.string().uuid(),
3451
+ accountId: import_zod14.z.string().uuid(),
3452
+ partnerId: import_zod14.z.string().uuid(),
3453
+ bankCode: import_zod14.z.string(),
3454
+ accountNumber: import_zod14.z.string(),
3455
+ accountName: import_zod14.z.string(),
3456
+ status: import_zod14.z.enum(PAYOUT_DESTINATION_STATUSES),
3457
+ verifiedAtMs: import_zod14.z.number().int().nonnegative().nullable(),
3458
+ metadata: Metadata,
3459
+ createdAtMs: import_zod14.z.number().int().nonnegative(),
3460
+ updatedAtMs: import_zod14.z.number().int().nonnegative()
3461
+ });
3462
+ var CreatePayoutDestinationInputSchema = import_zod14.z.object({
3463
+ partnerId: import_zod14.z.string().uuid(),
3464
+ bankCode: import_zod14.z.string().trim().min(1).max(32),
3465
+ accountNumber: import_zod14.z.string().trim().min(4).max(64),
3466
+ accountName: import_zod14.z.string().trim().min(1).max(200),
3467
+ metadata: Metadata.optional()
3468
+ });
3469
+ var ListPayoutDestinationsResultSchema = import_zod14.z.object({
3470
+ items: import_zod14.z.array(PayoutDestinationSchema)
3471
+ });
3472
+ var WithdrawalSchema = import_zod14.z.object({
3473
+ withdrawalId: import_zod14.z.string().uuid(),
3474
+ accountId: import_zod14.z.string().uuid(),
3475
+ userId: import_zod14.z.string().uuid(),
3476
+ partnerId: import_zod14.z.string().uuid(),
3477
+ destinationId: import_zod14.z.string().uuid(),
3478
+ currency: import_zod14.z.string(),
3479
+ amountMinor: MinorString,
3480
+ state: import_zod14.z.enum(WITHDRAWAL_STATES),
3481
+ idempotencyKey: import_zod14.z.string(),
3482
+ providerRef: import_zod14.z.string().nullable(),
3483
+ lastError: import_zod14.z.string().nullable(),
3484
+ ledgerRef: import_zod14.z.string(),
3485
+ reverseLedgerRef: import_zod14.z.string().nullable(),
3486
+ metadata: Metadata,
3487
+ createdAtMs: import_zod14.z.number().int().nonnegative(),
3488
+ updatedAtMs: import_zod14.z.number().int().nonnegative()
3489
+ });
3490
+ var CreateWithdrawalInputSchema = import_zod14.z.object({
3491
+ destinationId: import_zod14.z.string().uuid(),
3492
+ amountMinor: PositiveMinor,
3493
+ currency: Currency,
3494
+ idempotencyKey: import_zod14.z.string().trim().min(8).max(128),
3495
+ metadata: Metadata.optional()
3496
+ });
3497
+ var CreateWithdrawalResultSchema = import_zod14.z.object({
3498
+ withdrawal: WithdrawalSchema,
3499
+ replayed: import_zod14.z.boolean()
3500
+ });
3501
+ var PayoutEventInputSchema = import_zod14.z.object({
3502
+ externalRef: import_zod14.z.string().trim().min(8).max(128),
3503
+ withdrawalId: import_zod14.z.string().uuid().optional(),
3504
+ state: import_zod14.z.enum(["submitted", "processing", "paid", "failed"]),
3505
+ providerRef: import_zod14.z.string().trim().min(1).max(128).optional(),
3506
+ failureCode: import_zod14.z.string().trim().max(64).optional(),
3507
+ failureMessage: import_zod14.z.string().trim().max(512).optional(),
3508
+ providerMetadata: Metadata.optional()
3509
+ });
3510
+ var RecordPayoutEventResultSchema = import_zod14.z.object({
3511
+ withdrawal: WithdrawalSchema,
3512
+ replayed: import_zod14.z.boolean()
3513
+ });
3514
+ var ReconciliationReportSchema = import_zod14.z.object({
3515
+ partnerId: import_zod14.z.string().uuid(),
3516
+ currency: import_zod14.z.string(),
3517
+ fromMs: import_zod14.z.number().int().nonnegative(),
3518
+ toMs: import_zod14.z.number().int().nonnegative(),
3519
+ fundingsCreditMinor: MinorString,
3520
+ fundingsDebitMinor: MinorString,
3521
+ withdrawalsPaidMinor: MinorString,
3522
+ withdrawalsReversedMinor: MinorString,
3523
+ withdrawalsInFlightMinor: MinorString,
3524
+ expectedReserveBalanceMinor: MinorString,
3525
+ actualReserveBalanceMinor: MinorString,
3526
+ imbalanceMinor: MinorString,
3527
+ generatedAtMs: import_zod14.z.number().int().nonnegative()
3528
+ });
3529
+ function createPartnerFundingClient(partner) {
3530
+ return {
3531
+ ingestFunding: async (input) => {
3532
+ const body = PartnerFundingEventInputSchema.parse(input);
3533
+ const raw = await partner.request({
3534
+ method: "POST",
3535
+ path: "/v1/partners/fundings",
3536
+ body
3537
+ });
3538
+ return IngestFundingResultSchema.parse(raw);
3539
+ },
3540
+ recordPayoutEvent: async (input) => {
3541
+ const body = PayoutEventInputSchema.parse(input);
3542
+ const raw = await partner.request({
3543
+ method: "POST",
3544
+ path: "/v1/partners/payouts/events",
3545
+ body
3546
+ });
3547
+ return RecordPayoutEventResultSchema.parse(raw);
3548
+ },
3549
+ reconciliation: async (input) => {
3550
+ const qs = new URLSearchParams({
3551
+ currency: input.currency
3552
+ });
3553
+ if (typeof input.fromMs === "number")
3554
+ qs.set("fromMs", String(input.fromMs));
3555
+ if (typeof input.toMs === "number") qs.set("toMs", String(input.toMs));
3556
+ const raw = await partner.request({
3557
+ method: "GET",
3558
+ path: `/v1/partners/reconciliation/daily?${qs.toString()}`
3559
+ });
3560
+ return ReconciliationReportSchema.parse(raw);
3561
+ }
3562
+ };
3563
+ }
3564
+ function createConsumerWithdrawalsClient(opts) {
3565
+ const fetchImpl = opts.fetchImpl ?? globalThis.fetch;
3566
+ if (!fetchImpl) {
3567
+ throw new Error(
3568
+ "createConsumerWithdrawalsClient: no fetch implementation available"
3569
+ );
3570
+ }
3571
+ const baseUrl = opts.baseUrl.replace(/\/$/, "");
3572
+ async function call(method, path, body, parser) {
3573
+ const init2 = {
3574
+ method,
3575
+ headers: { accept: "application/json" }
3576
+ };
3577
+ if (body !== void 0) {
3578
+ init2.body = JSON.stringify(body);
3579
+ init2.headers = { ...init2.headers, "content-type": "application/json" };
3580
+ }
3581
+ const resp = await fetchImpl(`${baseUrl}${path}`, init2);
3582
+ const text = await resp.text();
3583
+ let raw;
3584
+ if (text) {
3585
+ try {
3586
+ raw = JSON.parse(text);
3587
+ } catch {
3588
+ raw = text;
3589
+ }
3590
+ }
3591
+ if (!resp.ok) {
3592
+ const code = raw && typeof raw === "object" && "code" in raw && typeof raw.code === "string" ? raw.code : `http_${resp.status}`;
3593
+ const message = raw && typeof raw === "object" && "message" in raw && typeof raw.message === "string" ? raw.message : `request failed with status ${resp.status}`;
3594
+ throw new FlurApiError(resp.status, code, message, raw);
3595
+ }
3596
+ return parser(raw);
3597
+ }
3598
+ return {
3599
+ listDestinations: () => call(
3600
+ "GET",
3601
+ "/v1/me/payout-destinations",
3602
+ void 0,
3603
+ (raw) => ListPayoutDestinationsResultSchema.parse(raw)
3604
+ ),
3605
+ createDestination: (input) => call(
3606
+ "POST",
3607
+ "/v1/me/payout-destinations",
3608
+ CreatePayoutDestinationInputSchema.parse(input),
3609
+ (raw) => PayoutDestinationSchema.parse(raw)
3610
+ ),
3611
+ verifyDestination: (destinationId) => call(
3612
+ "POST",
3613
+ `/v1/me/payout-destinations/${encodeURIComponent(destinationId)}/verify`,
3614
+ {},
3615
+ (raw) => PayoutDestinationSchema.parse(raw)
3616
+ ),
3617
+ disableDestination: (destinationId) => call(
3618
+ "POST",
3619
+ `/v1/me/payout-destinations/${encodeURIComponent(destinationId)}/disable`,
3620
+ {},
3621
+ (raw) => PayoutDestinationSchema.parse(raw)
3622
+ ),
3623
+ createWithdrawal: (input) => call(
3624
+ "POST",
3625
+ "/v1/me/withdrawals",
3626
+ CreateWithdrawalInputSchema.parse(input),
3627
+ (raw) => CreateWithdrawalResultSchema.parse(raw)
3628
+ ),
3629
+ getWithdrawal: (withdrawalId) => call(
3630
+ "GET",
3631
+ `/v1/me/withdrawals/${encodeURIComponent(withdrawalId)}`,
3632
+ void 0,
3633
+ (raw) => WithdrawalSchema.parse(raw)
3634
+ )
3635
+ };
3636
+ }
3637
+ function createPartnerProfileAdminClient(opts) {
3638
+ const fetchImpl = opts.fetchImpl ?? globalThis.fetch;
3639
+ if (!fetchImpl) {
3640
+ throw new Error(
3641
+ "createPartnerProfileAdminClient: no fetch implementation available"
3642
+ );
3643
+ }
3644
+ const baseUrl = opts.baseUrl.replace(/\/$/, "");
3645
+ return {
3646
+ upsertProfile: async (partnerAccountId, input) => {
3647
+ const body = {
3648
+ partnerAccountId,
3649
+ ...UpsertPartnerProfileInputSchema.parse(input)
3650
+ };
3651
+ const resp = await fetchImpl(`${baseUrl}/v1/partners/profile`, {
3652
+ method: "POST",
3653
+ headers: {
3654
+ "content-type": "application/json",
3655
+ accept: "application/json"
3656
+ },
3657
+ body: JSON.stringify(body)
3658
+ });
3659
+ const text = await resp.text();
3660
+ let raw;
3661
+ if (text) {
3662
+ try {
3663
+ raw = JSON.parse(text);
3664
+ } catch {
3665
+ raw = text;
3666
+ }
3667
+ }
3668
+ if (!resp.ok) {
3669
+ const code = raw && typeof raw === "object" && "code" in raw && typeof raw.code === "string" ? raw.code : `http_${resp.status}`;
3670
+ const message = raw && typeof raw === "object" && "message" in raw && typeof raw.message === "string" ? raw.message : `request failed with status ${resp.status}`;
3671
+ throw new FlurApiError(resp.status, code, message, raw);
3672
+ }
3673
+ return PartnerProfileSchema.parse(raw);
3674
+ }
3675
+ };
3676
+ }
2946
3677
  // Annotate the CommonJS export names for ESM import in node:
2947
3678
  0 && (module.exports = {
2948
3679
  ACCOUNT_STATUSES,
@@ -2951,11 +3682,24 @@ function createMeOfflineClient(opts) {
2951
3682
  AccountMembershipSchema,
2952
3683
  AccountSchema,
2953
3684
  ApiCredentialPublicSchema,
3685
+ COLLECTION_INTENT_STATUSES,
3686
+ COLLECTION_PAYMENT_STATUSES,
3687
+ CUSTODIAL_MODES,
3688
+ CollectionIntentSchema,
3689
+ CollectionPaymentResultSchema,
3690
+ CollectionPaymentSchema,
3691
+ CollectionReportSummarySchema,
3692
+ CollectionStatementSchema,
2954
3693
  ConsumerOACRecordSchema,
2955
3694
  ConsumerOACSchema,
2956
3695
  ConsumerPaymentClaimSchema,
2957
3696
  ConsumerSettleResultSchema,
2958
3697
  ConsumerSettlementSchema,
3698
+ CreateCollectionIntentInputSchema,
3699
+ CreatePayoutDestinationInputSchema,
3700
+ CreatePayoutInputSchema,
3701
+ CreateWithdrawalInputSchema,
3702
+ CreateWithdrawalResultSchema,
2959
3703
  DeviceKeyRecordSchema,
2960
3704
  DisableOfflineInputSchema,
2961
3705
  DisableOfflineResultSchema,
@@ -2968,8 +3712,14 @@ function createMeOfflineClient(opts) {
2968
3712
  FlurError,
2969
3713
  FlurExpiredError,
2970
3714
  FlurReplayError,
3715
+ IngestFundingResultSchema,
2971
3716
  IssueOACInputSchema,
3717
+ ListPayoutDestinationsResultSchema,
2972
3718
  MEMBERSHIP_ROLES,
3719
+ MERCHANT_PAYOUT_STATUSES,
3720
+ MERCHANT_PROFILE_STATUSES,
3721
+ MerchantPayoutSchema,
3722
+ MerchantProfileSchema,
2973
3723
  MintedApiCredentialSchema,
2974
3724
  NGN_CURRENCY_CODE,
2975
3725
  NG_COUNTRY_CODE,
@@ -2984,25 +3734,46 @@ function createMeOfflineClient(opts) {
2984
3734
  OfflineStateResultSchema,
2985
3735
  OfflineStatusResultSchema,
2986
3736
  OfflineTokenSchema,
3737
+ PARTNER_FUNDING_DIRECTIONS,
3738
+ PARTNER_FUNDING_STATUSES,
3739
+ PARTNER_KINDS,
3740
+ PARTNER_PROFILE_STATUSES,
2987
3741
  PARTNER_SCOPES,
2988
3742
  PASS_KINDS,
2989
3743
  PASS_STATES,
2990
3744
  PAYLOAD_FORMAT_INDICATOR_VALUE,
3745
+ PAYOUT_DESTINATION_STATUSES,
2991
3746
  POINT_OF_INITIATION,
3747
+ PartnerFundingEventInputSchema,
3748
+ PartnerFundingSchema,
3749
+ PartnerProfileSchema,
2992
3750
  PassMetadataSchema,
2993
3751
  PassSchema,
3752
+ PayCollectionInputSchema,
2994
3753
  PaymentClaimSchema,
3754
+ PayoutDestinationSchema,
3755
+ PayoutEventInputSchema,
3756
+ ProviderEventInputSchema,
3757
+ ProviderEventRecordSchema,
3758
+ PublicCollectionIntentSchema,
2995
3759
  RECEIPT_CHANNELS,
2996
3760
  RECEIPT_KINDS,
2997
3761
  REPLAY_WINDOW_MS,
2998
3762
  ReceiptPayloadSchema,
2999
3763
  ReceiptSchema,
3764
+ ReconciliationReportSchema,
3765
+ RecordPayoutEventResultSchema,
3000
3766
  RedemptionSchema,
3001
3767
  RegisterDeviceKeyInputSchema,
3002
3768
  RevokeDeviceKeyInputSchema,
3769
+ SETTLEMENT_SCHEDULES,
3003
3770
  SettleResponseSchema,
3004
3771
  SettlementSchema,
3005
3772
  SignedConsumerOACSchema,
3773
+ UpsertMerchantProfileInputSchema,
3774
+ UpsertPartnerProfileInputSchema,
3775
+ WITHDRAWAL_STATES,
3776
+ WithdrawalSchema,
3006
3777
  bodySha256Hex,
3007
3778
  buildAuthorization,
3008
3779
  buildOAC,
@@ -3019,10 +3790,16 @@ function createMeOfflineClient(opts) {
3019
3790
  crc16ccittHex,
3020
3791
  createAccountsClient,
3021
3792
  createApiCredentialsAdminClient,
3793
+ createCollectionsClient,
3794
+ createConsumerCollectionsClient,
3795
+ createConsumerWithdrawalsClient,
3022
3796
  createFlurPartnerClient,
3023
3797
  createHmacFetch,
3024
3798
  createMeOfflineClient,
3025
3799
  createOfflineSettlementsClient,
3800
+ createPartnerCollectionsClient,
3801
+ createPartnerFundingClient,
3802
+ createPartnerProfileAdminClient,
3026
3803
  createPassesClient,
3027
3804
  createReceiptsClient,
3028
3805
  decodeAuthorizationQR,