@nokinc-flur/sdk 1.0.3 → 1.0.5
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 +365 -76
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1343 -10
- package/dist/index.d.ts +1343 -10
- package/dist/index.js +347 -66
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __create = Object.create;
|
|
3
2
|
var __defProp = Object.defineProperty;
|
|
4
3
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
4
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
7
5
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
6
|
var __export = (target, all) => {
|
|
9
7
|
for (var name in all)
|
|
@@ -17,14 +15,6 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
17
15
|
}
|
|
18
16
|
return to;
|
|
19
17
|
};
|
|
20
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
-
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
-
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
-
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
-
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
-
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
-
mod
|
|
27
|
-
));
|
|
28
18
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
19
|
|
|
30
20
|
// src/index.ts
|
|
@@ -36,6 +26,16 @@ __export(index_exports, {
|
|
|
36
26
|
AccountMembershipSchema: () => AccountMembershipSchema,
|
|
37
27
|
AccountSchema: () => AccountSchema,
|
|
38
28
|
ApiCredentialPublicSchema: () => ApiCredentialPublicSchema,
|
|
29
|
+
ConsumerOACRecordSchema: () => OACRecordSchema,
|
|
30
|
+
ConsumerOACSchema: () => ConsumerOACSchema,
|
|
31
|
+
ConsumerPaymentClaimSchema: () => ConsumerPaymentClaimSchema,
|
|
32
|
+
ConsumerSettleResultSchema: () => ConsumerSettleResultSchema,
|
|
33
|
+
ConsumerSettlementSchema: () => ConsumerSettlementSchema,
|
|
34
|
+
DeviceKeyRecordSchema: () => DeviceKeyRecordSchema,
|
|
35
|
+
DisableOfflineInputSchema: () => DisableOfflineInputSchema,
|
|
36
|
+
DisableOfflineResultSchema: () => DisableOfflineResultSchema,
|
|
37
|
+
EnableOfflineInputSchema: () => EnableOfflineInputSchema,
|
|
38
|
+
EnableOfflineResultSchema: () => EnableOfflineResultSchema,
|
|
39
39
|
FIELD: () => FIELD,
|
|
40
40
|
FlurApiError: () => FlurApiError,
|
|
41
41
|
FlurCapExceededError: () => FlurCapExceededError,
|
|
@@ -43,6 +43,7 @@ __export(index_exports, {
|
|
|
43
43
|
FlurError: () => FlurError,
|
|
44
44
|
FlurExpiredError: () => FlurExpiredError,
|
|
45
45
|
FlurReplayError: () => FlurReplayError,
|
|
46
|
+
IssueOACInputSchema: () => IssueOACInputSchema,
|
|
46
47
|
MEMBERSHIP_ROLES: () => MEMBERSHIP_ROLES,
|
|
47
48
|
MintedApiCredentialSchema: () => MintedApiCredentialSchema,
|
|
48
49
|
NGN_CURRENCY_CODE: () => NGN_CURRENCY_CODE,
|
|
@@ -52,8 +53,11 @@ __export(index_exports, {
|
|
|
52
53
|
OAC_DEFAULT_CUMULATIVE_KOBO: () => OAC_DEFAULT_CUMULATIVE_KOBO,
|
|
53
54
|
OAC_DEFAULT_PER_TX_KOBO: () => OAC_DEFAULT_PER_TX_KOBO,
|
|
54
55
|
OAC_DEFAULT_VALIDITY_MS: () => OAC_DEFAULT_VALIDITY_MS,
|
|
56
|
+
OfflineHoldRecordSchema: () => OfflineHoldRecordSchema,
|
|
55
57
|
OfflinePaymentAuthorizationSchema: () => OfflinePaymentAuthorizationSchema,
|
|
56
58
|
OfflinePaymentRequestSchema: () => OfflinePaymentRequestSchema,
|
|
59
|
+
OfflineStateResultSchema: () => OfflineStateResultSchema,
|
|
60
|
+
OfflineStatusResultSchema: () => OfflineStatusResultSchema,
|
|
57
61
|
OfflineTokenSchema: () => OfflineTokenSchema,
|
|
58
62
|
PARTNER_SCOPES: () => PARTNER_SCOPES,
|
|
59
63
|
PASS_KINDS: () => PASS_KINDS,
|
|
@@ -69,8 +73,11 @@ __export(index_exports, {
|
|
|
69
73
|
ReceiptPayloadSchema: () => ReceiptPayloadSchema,
|
|
70
74
|
ReceiptSchema: () => ReceiptSchema,
|
|
71
75
|
RedemptionSchema: () => RedemptionSchema,
|
|
76
|
+
RegisterDeviceKeyInputSchema: () => RegisterDeviceKeyInputSchema,
|
|
77
|
+
RevokeDeviceKeyInputSchema: () => RevokeDeviceKeyInputSchema,
|
|
72
78
|
SettleResponseSchema: () => SettleResponseSchema,
|
|
73
79
|
SettlementSchema: () => SettlementSchema,
|
|
80
|
+
SignedConsumerOACSchema: () => SignedConsumerOACSchema,
|
|
74
81
|
bodySha256Hex: () => bodySha256Hex,
|
|
75
82
|
buildAuthorization: () => buildAuthorization,
|
|
76
83
|
buildOAC: () => buildOAC,
|
|
@@ -89,6 +96,7 @@ __export(index_exports, {
|
|
|
89
96
|
createApiCredentialsAdminClient: () => createApiCredentialsAdminClient,
|
|
90
97
|
createFlurPartnerClient: () => createFlurPartnerClient,
|
|
91
98
|
createHmacFetch: () => createHmacFetch,
|
|
99
|
+
createMeOfflineClient: () => createMeOfflineClient,
|
|
92
100
|
createOfflineSettlementsClient: () => createOfflineSettlementsClient,
|
|
93
101
|
createPassesClient: () => createPassesClient,
|
|
94
102
|
createReceiptsClient: () => createReceiptsClient,
|
|
@@ -179,7 +187,9 @@ var OnboardingCompleteResponseSchema = import_zod.z.object({
|
|
|
179
187
|
sessionToken: import_zod.z.string().min(1),
|
|
180
188
|
userId: UuidSchema,
|
|
181
189
|
restricted: import_zod.z.boolean(),
|
|
182
|
-
risk_reasons: import_zod.z.array(
|
|
190
|
+
risk_reasons: import_zod.z.array(
|
|
191
|
+
import_zod.z.enum(["SIM_SWAP_RECENT", "ROAMING", "CARRIER_CHANGED"])
|
|
192
|
+
),
|
|
183
193
|
stepUpRequired: import_zod.z.boolean().optional(),
|
|
184
194
|
riskStatus: import_zod.z.enum(["ok", "unavailable"]).optional()
|
|
185
195
|
});
|
|
@@ -232,9 +242,11 @@ var RegisterSendDeviceKeyRequestSchema = import_zod.z.object({
|
|
|
232
242
|
deviceId: import_zod.z.string().min(3),
|
|
233
243
|
publicKey: import_zod.z.string().min(32)
|
|
234
244
|
});
|
|
245
|
+
var SEND_AUTH_PURPOSES = ["send_money", "offline_revoke"];
|
|
235
246
|
var SendChallengeRequestSchema = import_zod.z.object({
|
|
236
247
|
userId: UuidSchema,
|
|
237
|
-
deviceId: import_zod.z.string().min(3)
|
|
248
|
+
deviceId: import_zod.z.string().min(3),
|
|
249
|
+
purpose: import_zod.z.enum(SEND_AUTH_PURPOSES).optional()
|
|
238
250
|
});
|
|
239
251
|
var SendChallengeResponseSchema = import_zod.z.object({
|
|
240
252
|
challengeId: UuidSchema,
|
|
@@ -534,10 +546,20 @@ var FlurClient = class {
|
|
|
534
546
|
this.getExtraHeaders = opts.getExtraHeaders;
|
|
535
547
|
}
|
|
536
548
|
async health() {
|
|
537
|
-
return this.requestJson(
|
|
549
|
+
return this.requestJson(
|
|
550
|
+
"/health",
|
|
551
|
+
{ method: "GET" },
|
|
552
|
+
void 0,
|
|
553
|
+
HealthResponseSchema
|
|
554
|
+
);
|
|
538
555
|
}
|
|
539
556
|
async welcome() {
|
|
540
|
-
return this.requestJson(
|
|
557
|
+
return this.requestJson(
|
|
558
|
+
"/welcome",
|
|
559
|
+
{ method: "GET" },
|
|
560
|
+
void 0,
|
|
561
|
+
WelcomeResponseSchema
|
|
562
|
+
);
|
|
541
563
|
}
|
|
542
564
|
async onboardingStart(input) {
|
|
543
565
|
return this.requestJson(
|
|
@@ -682,24 +704,33 @@ var FlurClient = class {
|
|
|
682
704
|
}
|
|
683
705
|
async registerBiometricDeviceKey(input) {
|
|
684
706
|
const publicKey = await input.signer.getOrCreateKeyPair(input.deviceId);
|
|
685
|
-
return this.registerSendDeviceKey(
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
707
|
+
return this.registerSendDeviceKey(
|
|
708
|
+
{
|
|
709
|
+
userId: input.userId,
|
|
710
|
+
deviceId: input.deviceId,
|
|
711
|
+
publicKey
|
|
712
|
+
},
|
|
713
|
+
{ accessToken: input.accessToken }
|
|
714
|
+
);
|
|
690
715
|
}
|
|
691
716
|
async authorizeSendWithBiometric(input) {
|
|
692
|
-
const challenge = await this.createSendChallenge(
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
717
|
+
const challenge = await this.createSendChallenge(
|
|
718
|
+
{
|
|
719
|
+
userId: input.userId,
|
|
720
|
+
deviceId: input.deviceId
|
|
721
|
+
},
|
|
722
|
+
{ accessToken: input.accessToken }
|
|
723
|
+
);
|
|
696
724
|
const signature = await input.signer.sign(challenge.nonce);
|
|
697
|
-
return this.verifySendChallenge(
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
725
|
+
return this.verifySendChallenge(
|
|
726
|
+
{
|
|
727
|
+
userId: input.userId,
|
|
728
|
+
deviceId: input.deviceId,
|
|
729
|
+
challengeId: challenge.challengeId,
|
|
730
|
+
signature
|
|
731
|
+
},
|
|
732
|
+
{ accessToken: input.accessToken }
|
|
733
|
+
);
|
|
703
734
|
}
|
|
704
735
|
async resolveRecipient(input, options) {
|
|
705
736
|
return this.requestJson(
|
|
@@ -864,7 +895,12 @@ var FlurClient = class {
|
|
|
864
895
|
...init2.headers,
|
|
865
896
|
...extraHeaders
|
|
866
897
|
};
|
|
867
|
-
const res = await this.fetchImpl(url, {
|
|
898
|
+
const res = await this.fetchImpl(url, {
|
|
899
|
+
...init2,
|
|
900
|
+
headers: finalHeaders,
|
|
901
|
+
body,
|
|
902
|
+
signal: controller.signal
|
|
903
|
+
});
|
|
868
904
|
if (!res.ok) throw await mapToFlurError(res);
|
|
869
905
|
const payload = await res.json();
|
|
870
906
|
if (!responseSchema) return payload;
|
|
@@ -872,9 +908,13 @@ var FlurClient = class {
|
|
|
872
908
|
return responseSchema.parse(payload);
|
|
873
909
|
} catch (err) {
|
|
874
910
|
if (err instanceof import_zod3.z.ZodError) {
|
|
875
|
-
throw new FlurError(
|
|
876
|
-
|
|
877
|
-
|
|
911
|
+
throw new FlurError(
|
|
912
|
+
"SDK contract validation failed",
|
|
913
|
+
"INVALID_REQUEST",
|
|
914
|
+
{
|
|
915
|
+
details: err.flatten()
|
|
916
|
+
}
|
|
917
|
+
);
|
|
878
918
|
}
|
|
879
919
|
throw err;
|
|
880
920
|
}
|
|
@@ -883,7 +923,9 @@ var FlurClient = class {
|
|
|
883
923
|
throw new FlurError("Request timed out", "TIMEOUT");
|
|
884
924
|
}
|
|
885
925
|
if (err instanceof FlurError) throw err;
|
|
886
|
-
throw new FlurError("Network error", "NETWORK_ERROR", {
|
|
926
|
+
throw new FlurError("Network error", "NETWORK_ERROR", {
|
|
927
|
+
details: String(err)
|
|
928
|
+
});
|
|
887
929
|
} finally {
|
|
888
930
|
clearTimeout(t);
|
|
889
931
|
}
|
|
@@ -893,7 +935,10 @@ function getSecureRandomUuid() {
|
|
|
893
935
|
if (typeof globalThis.crypto?.randomUUID === "function") {
|
|
894
936
|
return globalThis.crypto.randomUUID();
|
|
895
937
|
}
|
|
896
|
-
throw new FlurError(
|
|
938
|
+
throw new FlurError(
|
|
939
|
+
"Secure UUID generator unavailable; provide idempotencyKey",
|
|
940
|
+
"INVALID_REQUEST"
|
|
941
|
+
);
|
|
897
942
|
}
|
|
898
943
|
|
|
899
944
|
// src/nqr/fields.ts
|
|
@@ -1566,6 +1611,8 @@ function decodeAuthorizationQR(s) {
|
|
|
1566
1611
|
|
|
1567
1612
|
// src/offline/settlements.ts
|
|
1568
1613
|
var import_zod6 = require("zod");
|
|
1614
|
+
var import_sha256 = require("@noble/hashes/sha256");
|
|
1615
|
+
var import_utils = require("@noble/hashes/utils");
|
|
1569
1616
|
var OfflineTokenSchema = import_zod6.z.object({
|
|
1570
1617
|
tokenId: import_zod6.z.string().uuid(),
|
|
1571
1618
|
tokenSerial: import_zod6.z.string(),
|
|
@@ -1616,14 +1663,7 @@ var SettleResponseSchema = import_zod6.z.object({
|
|
|
1616
1663
|
});
|
|
1617
1664
|
var ENCOUNTER_DOMAIN = "offline:v1:encounter";
|
|
1618
1665
|
async function sha256Hex(input) {
|
|
1619
|
-
|
|
1620
|
-
const enc2 = new TextEncoder().encode(input);
|
|
1621
|
-
if (subtle) {
|
|
1622
|
-
const buf = await subtle.digest("SHA-256", enc2);
|
|
1623
|
-
return Array.from(new Uint8Array(buf)).map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
1624
|
-
}
|
|
1625
|
-
const mod = await import("crypto");
|
|
1626
|
-
return mod.createHash("sha256").update(input).digest("hex");
|
|
1666
|
+
return (0, import_utils.bytesToHex)((0, import_sha256.sha256)(new TextEncoder().encode(input)));
|
|
1627
1667
|
}
|
|
1628
1668
|
async function computeEncounterId(input) {
|
|
1629
1669
|
return sha256Hex(
|
|
@@ -1671,8 +1711,8 @@ function createOfflineSettlementsClient(partner) {
|
|
|
1671
1711
|
|
|
1672
1712
|
// src/auth/hmac.ts
|
|
1673
1713
|
var import_hmac = require("@noble/hashes/hmac");
|
|
1674
|
-
var
|
|
1675
|
-
function
|
|
1714
|
+
var import_sha2562 = require("@noble/hashes/sha256");
|
|
1715
|
+
function bytesToHex3(b) {
|
|
1676
1716
|
let s = "";
|
|
1677
1717
|
for (let i = 0; i < b.length; i++) s += b[i].toString(16).padStart(2, "0");
|
|
1678
1718
|
return s;
|
|
@@ -1684,7 +1724,7 @@ function constantTimeStringEqual(a, b) {
|
|
|
1684
1724
|
return diff === 0;
|
|
1685
1725
|
}
|
|
1686
1726
|
function bodySha256Hex(body) {
|
|
1687
|
-
return
|
|
1727
|
+
return bytesToHex3((0, import_sha2562.sha256)(new TextEncoder().encode(body)));
|
|
1688
1728
|
}
|
|
1689
1729
|
function canonicalRequestString(input) {
|
|
1690
1730
|
return [
|
|
@@ -1696,8 +1736,8 @@ function canonicalRequestString(input) {
|
|
|
1696
1736
|
].join("\n");
|
|
1697
1737
|
}
|
|
1698
1738
|
function signRequestHMAC(input) {
|
|
1699
|
-
return
|
|
1700
|
-
(0, import_hmac.hmac)(
|
|
1739
|
+
return bytesToHex3(
|
|
1740
|
+
(0, import_hmac.hmac)(import_sha2562.sha256, input.apiSecret, canonicalRequestString(input))
|
|
1701
1741
|
);
|
|
1702
1742
|
}
|
|
1703
1743
|
function verifyRequestHMAC(input) {
|
|
@@ -2456,6 +2496,9 @@ function createAccountsClient(opts) {
|
|
|
2456
2496
|
|
|
2457
2497
|
// src/partner/client.ts
|
|
2458
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");
|
|
2459
2502
|
var PARTNER_SCOPES = [
|
|
2460
2503
|
"passes:write",
|
|
2461
2504
|
"passes:read",
|
|
@@ -2479,39 +2522,13 @@ var ApiCredentialPublicSchema = import_zod11.z.object({
|
|
|
2479
2522
|
var MintedApiCredentialSchema = ApiCredentialPublicSchema.extend({
|
|
2480
2523
|
secret: import_zod11.z.string().min(1)
|
|
2481
2524
|
});
|
|
2482
|
-
async function getSubtle() {
|
|
2483
|
-
const c = globalThis.crypto;
|
|
2484
|
-
if (c?.subtle) return c.subtle;
|
|
2485
|
-
const mod = await import("crypto");
|
|
2486
|
-
return mod.webcrypto.subtle;
|
|
2487
|
-
}
|
|
2488
2525
|
var enc = new TextEncoder();
|
|
2489
|
-
function bytesToHex3(buf) {
|
|
2490
|
-
const u = new Uint8Array(buf);
|
|
2491
|
-
let s = "";
|
|
2492
|
-
for (let i = 0; i < u.length; i++) {
|
|
2493
|
-
s += u[i].toString(16).padStart(2, "0");
|
|
2494
|
-
}
|
|
2495
|
-
return s;
|
|
2496
|
-
}
|
|
2497
2526
|
async function sha256Hex2(input) {
|
|
2498
|
-
const subtle = await getSubtle();
|
|
2499
2527
|
const data = typeof input === "string" ? enc.encode(input) : input;
|
|
2500
|
-
|
|
2501
|
-
const buf = await subtle.digest("SHA-256", buffer);
|
|
2502
|
-
return bytesToHex3(buf);
|
|
2528
|
+
return (0, import_utils2.bytesToHex)((0, import_sha2563.sha256)(data));
|
|
2503
2529
|
}
|
|
2504
2530
|
async function hmacSha256Hex(keyHex, message) {
|
|
2505
|
-
|
|
2506
|
-
const key = await subtle.importKey(
|
|
2507
|
-
"raw",
|
|
2508
|
-
enc.encode(keyHex),
|
|
2509
|
-
{ name: "HMAC", hash: "SHA-256" },
|
|
2510
|
-
false,
|
|
2511
|
-
["sign"]
|
|
2512
|
-
);
|
|
2513
|
-
const sig = await subtle.sign("HMAC", key, enc.encode(message));
|
|
2514
|
-
return bytesToHex3(sig);
|
|
2531
|
+
return (0, import_utils2.bytesToHex)((0, import_hmac4.hmac)(import_sha2563.sha256, enc.encode(keyHex), enc.encode(message)));
|
|
2515
2532
|
}
|
|
2516
2533
|
function defaultNonce2() {
|
|
2517
2534
|
const c = globalThis.crypto;
|
|
@@ -2672,6 +2689,260 @@ function createApiCredentialsAdminClient(opts) {
|
|
|
2672
2689
|
)
|
|
2673
2690
|
};
|
|
2674
2691
|
}
|
|
2692
|
+
|
|
2693
|
+
// 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),
|
|
2700
|
+
publicKeyHex: Hex64
|
|
2701
|
+
});
|
|
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(),
|
|
2706
|
+
publicKeyHex: Hex64,
|
|
2707
|
+
createdAtMs: import_zod12.z.number().int().nonnegative(),
|
|
2708
|
+
revokedAtMs: import_zod12.z.number().int().nonnegative().nullable()
|
|
2709
|
+
});
|
|
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),
|
|
2715
|
+
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({
|
|
2725
|
+
oac: ConsumerOACSchema,
|
|
2726
|
+
issuerSig: HexAny,
|
|
2727
|
+
issuerPublicKeyHex: Hex64
|
|
2728
|
+
});
|
|
2729
|
+
var OACRecordSchema = SignedConsumerOACSchema.extend({
|
|
2730
|
+
currentOfflineSpentKobo: import_zod12.z.number().int().nonnegative(),
|
|
2731
|
+
status: import_zod12.z.enum([
|
|
2732
|
+
"active",
|
|
2733
|
+
"superseded",
|
|
2734
|
+
"expired",
|
|
2735
|
+
"revoked",
|
|
2736
|
+
"disabling",
|
|
2737
|
+
"draining",
|
|
2738
|
+
"closed"
|
|
2739
|
+
]),
|
|
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([
|
|
2777
|
+
"placing",
|
|
2778
|
+
"active",
|
|
2779
|
+
"disabling",
|
|
2780
|
+
"draining",
|
|
2781
|
+
"closed",
|
|
2782
|
+
"revoked",
|
|
2783
|
+
"failed"
|
|
2784
|
+
]),
|
|
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({
|
|
2793
|
+
hold: OfflineHoldRecordSchema,
|
|
2794
|
+
oac: OACRecordSchema
|
|
2795
|
+
});
|
|
2796
|
+
var DisableOfflineResultSchema = import_zod12.z.object({
|
|
2797
|
+
hold: OfflineHoldRecordSchema,
|
|
2798
|
+
trusted: import_zod12.z.boolean(),
|
|
2799
|
+
settledClaims: import_zod12.z.number().int().nonnegative()
|
|
2800
|
+
});
|
|
2801
|
+
var OfflineStatusResultSchema = import_zod12.z.object({
|
|
2802
|
+
hold: OfflineHoldRecordSchema.nullable(),
|
|
2803
|
+
active: OACRecordSchema.nullable()
|
|
2804
|
+
});
|
|
2805
|
+
var OfflineStateResultSchema = import_zod12.z.object({
|
|
2806
|
+
active: OACRecordSchema.nullable()
|
|
2807
|
+
});
|
|
2808
|
+
var ConsumerPaymentClaimSchema = import_zod12.z.object({
|
|
2809
|
+
oacId: import_zod12.z.string().uuid(),
|
|
2810
|
+
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(),
|
|
2821
|
+
payerPubkeyHex: Hex64,
|
|
2822
|
+
payerSignature: HexAny,
|
|
2823
|
+
payeePubkeyHex: Hex64.optional(),
|
|
2824
|
+
payeeSignature: HexAny.optional()
|
|
2825
|
+
});
|
|
2826
|
+
var ConsumerSettlementSchema = import_zod12.z.object({
|
|
2827
|
+
settlementId: import_zod12.z.string().uuid(),
|
|
2828
|
+
settlementKey: Sha256Hex,
|
|
2829
|
+
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(),
|
|
2838
|
+
issuerSig: HexAny,
|
|
2839
|
+
createdAtMs: import_zod12.z.number().int().nonnegative()
|
|
2840
|
+
});
|
|
2841
|
+
var ConsumerSettleResultSchema = import_zod12.z.object({
|
|
2842
|
+
settlement: ConsumerSettlementSchema,
|
|
2843
|
+
encounterId: Sha256Hex,
|
|
2844
|
+
replayed: import_zod12.z.boolean()
|
|
2845
|
+
});
|
|
2846
|
+
var RevokeDeviceKeyInputSchema = import_zod12.z.object({
|
|
2847
|
+
deviceId: import_zod12.z.string().min(1).max(128),
|
|
2848
|
+
/** Step-up token from /api/v1/auth/send/verify with purpose='offline_revoke'. */
|
|
2849
|
+
sendAuthToken: import_zod12.z.string().min(16)
|
|
2850
|
+
});
|
|
2851
|
+
function createMeOfflineClient(opts) {
|
|
2852
|
+
const fetchImpl = opts.fetchImpl ?? globalThis.fetch;
|
|
2853
|
+
if (!fetchImpl) {
|
|
2854
|
+
throw new Error("createMeOfflineClient: no fetch implementation available");
|
|
2855
|
+
}
|
|
2856
|
+
const baseUrl = opts.baseUrl.replace(/\/$/, "");
|
|
2857
|
+
async function call(method, path, body, parser) {
|
|
2858
|
+
const init2 = {
|
|
2859
|
+
method,
|
|
2860
|
+
headers: {
|
|
2861
|
+
"content-type": "application/json",
|
|
2862
|
+
accept: "application/json"
|
|
2863
|
+
}
|
|
2864
|
+
};
|
|
2865
|
+
if (body !== void 0) init2.body = JSON.stringify(body);
|
|
2866
|
+
const resp = await fetchImpl(`${baseUrl}${path}`, init2);
|
|
2867
|
+
const text = await resp.text();
|
|
2868
|
+
let raw = void 0;
|
|
2869
|
+
if (text) {
|
|
2870
|
+
try {
|
|
2871
|
+
raw = JSON.parse(text);
|
|
2872
|
+
} catch {
|
|
2873
|
+
}
|
|
2874
|
+
}
|
|
2875
|
+
if (!resp.ok) {
|
|
2876
|
+
const code = raw && typeof raw === "object" && "code" in raw && typeof raw.code === "string" ? raw.code : `http_${resp.status}`;
|
|
2877
|
+
const message = raw && typeof raw === "object" && "message" in raw && typeof raw.message === "string" ? raw.message : `request failed with status ${resp.status}`;
|
|
2878
|
+
throw new FlurApiError(resp.status, code, message, raw);
|
|
2879
|
+
}
|
|
2880
|
+
return parser(raw);
|
|
2881
|
+
}
|
|
2882
|
+
const deviceKeyItems = import_zod12.z.object({ items: import_zod12.z.array(DeviceKeyRecordSchema) });
|
|
2883
|
+
return {
|
|
2884
|
+
registerDeviceKey: (input) => call(
|
|
2885
|
+
"POST",
|
|
2886
|
+
"/v1/me/offline/keys",
|
|
2887
|
+
RegisterDeviceKeyInputSchema.parse(input),
|
|
2888
|
+
(raw) => DeviceKeyRecordSchema.parse(raw)
|
|
2889
|
+
),
|
|
2890
|
+
listDeviceKeys: () => call(
|
|
2891
|
+
"GET",
|
|
2892
|
+
"/v1/me/offline/keys",
|
|
2893
|
+
void 0,
|
|
2894
|
+
(raw) => deviceKeyItems.parse(raw)
|
|
2895
|
+
),
|
|
2896
|
+
revokeDeviceKey: (input) => call(
|
|
2897
|
+
"POST",
|
|
2898
|
+
"/v1/me/offline/keys/revoke",
|
|
2899
|
+
RevokeDeviceKeyInputSchema.parse(input),
|
|
2900
|
+
() => void 0
|
|
2901
|
+
),
|
|
2902
|
+
enable: (input) => call(
|
|
2903
|
+
"POST",
|
|
2904
|
+
"/v1/me/offline/enable",
|
|
2905
|
+
EnableOfflineInputSchema.parse(input),
|
|
2906
|
+
(raw) => EnableOfflineResultSchema.parse(raw)
|
|
2907
|
+
),
|
|
2908
|
+
refresh: (input) => call(
|
|
2909
|
+
"POST",
|
|
2910
|
+
"/v1/me/offline/refresh",
|
|
2911
|
+
IssueOACInputSchema.parse(input),
|
|
2912
|
+
(raw) => OACRecordSchema.parse(raw)
|
|
2913
|
+
),
|
|
2914
|
+
disable: (input) => call(
|
|
2915
|
+
"POST",
|
|
2916
|
+
"/v1/me/offline/disable",
|
|
2917
|
+
DisableOfflineInputSchema.parse(input),
|
|
2918
|
+
(raw) => DisableOfflineResultSchema.parse(raw)
|
|
2919
|
+
),
|
|
2920
|
+
getStatus: (deviceId) => {
|
|
2921
|
+
const qs = deviceId ? `?deviceId=${encodeURIComponent(deviceId)}` : "";
|
|
2922
|
+
return call(
|
|
2923
|
+
"GET",
|
|
2924
|
+
`/v1/me/offline/status${qs}`,
|
|
2925
|
+
void 0,
|
|
2926
|
+
(raw) => OfflineStatusResultSchema.parse(raw)
|
|
2927
|
+
);
|
|
2928
|
+
},
|
|
2929
|
+
getState: (deviceId) => {
|
|
2930
|
+
const qs = deviceId ? `?deviceId=${encodeURIComponent(deviceId)}` : "";
|
|
2931
|
+
return call(
|
|
2932
|
+
"GET",
|
|
2933
|
+
`/v1/me/offline/state${qs}`,
|
|
2934
|
+
void 0,
|
|
2935
|
+
(raw) => OfflineStateResultSchema.parse(raw)
|
|
2936
|
+
);
|
|
2937
|
+
},
|
|
2938
|
+
submitClaim: (claim) => call(
|
|
2939
|
+
"POST",
|
|
2940
|
+
"/v1/me/offline/claims",
|
|
2941
|
+
ConsumerPaymentClaimSchema.parse(claim),
|
|
2942
|
+
(raw) => ConsumerSettleResultSchema.parse(raw)
|
|
2943
|
+
)
|
|
2944
|
+
};
|
|
2945
|
+
}
|
|
2675
2946
|
// Annotate the CommonJS export names for ESM import in node:
|
|
2676
2947
|
0 && (module.exports = {
|
|
2677
2948
|
ACCOUNT_STATUSES,
|
|
@@ -2680,6 +2951,16 @@ function createApiCredentialsAdminClient(opts) {
|
|
|
2680
2951
|
AccountMembershipSchema,
|
|
2681
2952
|
AccountSchema,
|
|
2682
2953
|
ApiCredentialPublicSchema,
|
|
2954
|
+
ConsumerOACRecordSchema,
|
|
2955
|
+
ConsumerOACSchema,
|
|
2956
|
+
ConsumerPaymentClaimSchema,
|
|
2957
|
+
ConsumerSettleResultSchema,
|
|
2958
|
+
ConsumerSettlementSchema,
|
|
2959
|
+
DeviceKeyRecordSchema,
|
|
2960
|
+
DisableOfflineInputSchema,
|
|
2961
|
+
DisableOfflineResultSchema,
|
|
2962
|
+
EnableOfflineInputSchema,
|
|
2963
|
+
EnableOfflineResultSchema,
|
|
2683
2964
|
FIELD,
|
|
2684
2965
|
FlurApiError,
|
|
2685
2966
|
FlurCapExceededError,
|
|
@@ -2687,6 +2968,7 @@ function createApiCredentialsAdminClient(opts) {
|
|
|
2687
2968
|
FlurError,
|
|
2688
2969
|
FlurExpiredError,
|
|
2689
2970
|
FlurReplayError,
|
|
2971
|
+
IssueOACInputSchema,
|
|
2690
2972
|
MEMBERSHIP_ROLES,
|
|
2691
2973
|
MintedApiCredentialSchema,
|
|
2692
2974
|
NGN_CURRENCY_CODE,
|
|
@@ -2696,8 +2978,11 @@ function createApiCredentialsAdminClient(opts) {
|
|
|
2696
2978
|
OAC_DEFAULT_CUMULATIVE_KOBO,
|
|
2697
2979
|
OAC_DEFAULT_PER_TX_KOBO,
|
|
2698
2980
|
OAC_DEFAULT_VALIDITY_MS,
|
|
2981
|
+
OfflineHoldRecordSchema,
|
|
2699
2982
|
OfflinePaymentAuthorizationSchema,
|
|
2700
2983
|
OfflinePaymentRequestSchema,
|
|
2984
|
+
OfflineStateResultSchema,
|
|
2985
|
+
OfflineStatusResultSchema,
|
|
2701
2986
|
OfflineTokenSchema,
|
|
2702
2987
|
PARTNER_SCOPES,
|
|
2703
2988
|
PASS_KINDS,
|
|
@@ -2713,8 +2998,11 @@ function createApiCredentialsAdminClient(opts) {
|
|
|
2713
2998
|
ReceiptPayloadSchema,
|
|
2714
2999
|
ReceiptSchema,
|
|
2715
3000
|
RedemptionSchema,
|
|
3001
|
+
RegisterDeviceKeyInputSchema,
|
|
3002
|
+
RevokeDeviceKeyInputSchema,
|
|
2716
3003
|
SettleResponseSchema,
|
|
2717
3004
|
SettlementSchema,
|
|
3005
|
+
SignedConsumerOACSchema,
|
|
2718
3006
|
bodySha256Hex,
|
|
2719
3007
|
buildAuthorization,
|
|
2720
3008
|
buildOAC,
|
|
@@ -2733,6 +3021,7 @@ function createApiCredentialsAdminClient(opts) {
|
|
|
2733
3021
|
createApiCredentialsAdminClient,
|
|
2734
3022
|
createFlurPartnerClient,
|
|
2735
3023
|
createHmacFetch,
|
|
3024
|
+
createMeOfflineClient,
|
|
2736
3025
|
createOfflineSettlementsClient,
|
|
2737
3026
|
createPassesClient,
|
|
2738
3027
|
createReceiptsClient,
|