@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.js
CHANGED
|
@@ -41,7 +41,9 @@ var OnboardingCompleteResponseSchema = z.object({
|
|
|
41
41
|
sessionToken: z.string().min(1),
|
|
42
42
|
userId: UuidSchema,
|
|
43
43
|
restricted: z.boolean(),
|
|
44
|
-
risk_reasons: z.array(
|
|
44
|
+
risk_reasons: z.array(
|
|
45
|
+
z.enum(["SIM_SWAP_RECENT", "ROAMING", "CARRIER_CHANGED"])
|
|
46
|
+
),
|
|
45
47
|
stepUpRequired: z.boolean().optional(),
|
|
46
48
|
riskStatus: z.enum(["ok", "unavailable"]).optional()
|
|
47
49
|
});
|
|
@@ -94,9 +96,11 @@ var RegisterSendDeviceKeyRequestSchema = z.object({
|
|
|
94
96
|
deviceId: z.string().min(3),
|
|
95
97
|
publicKey: z.string().min(32)
|
|
96
98
|
});
|
|
99
|
+
var SEND_AUTH_PURPOSES = ["send_money", "offline_revoke"];
|
|
97
100
|
var SendChallengeRequestSchema = z.object({
|
|
98
101
|
userId: UuidSchema,
|
|
99
|
-
deviceId: z.string().min(3)
|
|
102
|
+
deviceId: z.string().min(3),
|
|
103
|
+
purpose: z.enum(SEND_AUTH_PURPOSES).optional()
|
|
100
104
|
});
|
|
101
105
|
var SendChallengeResponseSchema = z.object({
|
|
102
106
|
challengeId: UuidSchema,
|
|
@@ -396,10 +400,20 @@ var FlurClient = class {
|
|
|
396
400
|
this.getExtraHeaders = opts.getExtraHeaders;
|
|
397
401
|
}
|
|
398
402
|
async health() {
|
|
399
|
-
return this.requestJson(
|
|
403
|
+
return this.requestJson(
|
|
404
|
+
"/health",
|
|
405
|
+
{ method: "GET" },
|
|
406
|
+
void 0,
|
|
407
|
+
HealthResponseSchema
|
|
408
|
+
);
|
|
400
409
|
}
|
|
401
410
|
async welcome() {
|
|
402
|
-
return this.requestJson(
|
|
411
|
+
return this.requestJson(
|
|
412
|
+
"/welcome",
|
|
413
|
+
{ method: "GET" },
|
|
414
|
+
void 0,
|
|
415
|
+
WelcomeResponseSchema
|
|
416
|
+
);
|
|
403
417
|
}
|
|
404
418
|
async onboardingStart(input) {
|
|
405
419
|
return this.requestJson(
|
|
@@ -544,24 +558,33 @@ var FlurClient = class {
|
|
|
544
558
|
}
|
|
545
559
|
async registerBiometricDeviceKey(input) {
|
|
546
560
|
const publicKey = await input.signer.getOrCreateKeyPair(input.deviceId);
|
|
547
|
-
return this.registerSendDeviceKey(
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
561
|
+
return this.registerSendDeviceKey(
|
|
562
|
+
{
|
|
563
|
+
userId: input.userId,
|
|
564
|
+
deviceId: input.deviceId,
|
|
565
|
+
publicKey
|
|
566
|
+
},
|
|
567
|
+
{ accessToken: input.accessToken }
|
|
568
|
+
);
|
|
552
569
|
}
|
|
553
570
|
async authorizeSendWithBiometric(input) {
|
|
554
|
-
const challenge = await this.createSendChallenge(
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
571
|
+
const challenge = await this.createSendChallenge(
|
|
572
|
+
{
|
|
573
|
+
userId: input.userId,
|
|
574
|
+
deviceId: input.deviceId
|
|
575
|
+
},
|
|
576
|
+
{ accessToken: input.accessToken }
|
|
577
|
+
);
|
|
558
578
|
const signature = await input.signer.sign(challenge.nonce);
|
|
559
|
-
return this.verifySendChallenge(
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
579
|
+
return this.verifySendChallenge(
|
|
580
|
+
{
|
|
581
|
+
userId: input.userId,
|
|
582
|
+
deviceId: input.deviceId,
|
|
583
|
+
challengeId: challenge.challengeId,
|
|
584
|
+
signature
|
|
585
|
+
},
|
|
586
|
+
{ accessToken: input.accessToken }
|
|
587
|
+
);
|
|
565
588
|
}
|
|
566
589
|
async resolveRecipient(input, options) {
|
|
567
590
|
return this.requestJson(
|
|
@@ -726,7 +749,12 @@ var FlurClient = class {
|
|
|
726
749
|
...init2.headers,
|
|
727
750
|
...extraHeaders
|
|
728
751
|
};
|
|
729
|
-
const res = await this.fetchImpl(url, {
|
|
752
|
+
const res = await this.fetchImpl(url, {
|
|
753
|
+
...init2,
|
|
754
|
+
headers: finalHeaders,
|
|
755
|
+
body,
|
|
756
|
+
signal: controller.signal
|
|
757
|
+
});
|
|
730
758
|
if (!res.ok) throw await mapToFlurError(res);
|
|
731
759
|
const payload = await res.json();
|
|
732
760
|
if (!responseSchema) return payload;
|
|
@@ -734,9 +762,13 @@ var FlurClient = class {
|
|
|
734
762
|
return responseSchema.parse(payload);
|
|
735
763
|
} catch (err) {
|
|
736
764
|
if (err instanceof z3.ZodError) {
|
|
737
|
-
throw new FlurError(
|
|
738
|
-
|
|
739
|
-
|
|
765
|
+
throw new FlurError(
|
|
766
|
+
"SDK contract validation failed",
|
|
767
|
+
"INVALID_REQUEST",
|
|
768
|
+
{
|
|
769
|
+
details: err.flatten()
|
|
770
|
+
}
|
|
771
|
+
);
|
|
740
772
|
}
|
|
741
773
|
throw err;
|
|
742
774
|
}
|
|
@@ -745,7 +777,9 @@ var FlurClient = class {
|
|
|
745
777
|
throw new FlurError("Request timed out", "TIMEOUT");
|
|
746
778
|
}
|
|
747
779
|
if (err instanceof FlurError) throw err;
|
|
748
|
-
throw new FlurError("Network error", "NETWORK_ERROR", {
|
|
780
|
+
throw new FlurError("Network error", "NETWORK_ERROR", {
|
|
781
|
+
details: String(err)
|
|
782
|
+
});
|
|
749
783
|
} finally {
|
|
750
784
|
clearTimeout(t);
|
|
751
785
|
}
|
|
@@ -755,7 +789,10 @@ function getSecureRandomUuid() {
|
|
|
755
789
|
if (typeof globalThis.crypto?.randomUUID === "function") {
|
|
756
790
|
return globalThis.crypto.randomUUID();
|
|
757
791
|
}
|
|
758
|
-
throw new FlurError(
|
|
792
|
+
throw new FlurError(
|
|
793
|
+
"Secure UUID generator unavailable; provide idempotencyKey",
|
|
794
|
+
"INVALID_REQUEST"
|
|
795
|
+
);
|
|
759
796
|
}
|
|
760
797
|
|
|
761
798
|
// src/nqr/fields.ts
|
|
@@ -1428,6 +1465,8 @@ function decodeAuthorizationQR(s) {
|
|
|
1428
1465
|
|
|
1429
1466
|
// src/offline/settlements.ts
|
|
1430
1467
|
import { z as z6 } from "zod";
|
|
1468
|
+
import { sha256 } from "@noble/hashes/sha256";
|
|
1469
|
+
import { bytesToHex as bytesToHex2 } from "@noble/hashes/utils";
|
|
1431
1470
|
var OfflineTokenSchema = z6.object({
|
|
1432
1471
|
tokenId: z6.string().uuid(),
|
|
1433
1472
|
tokenSerial: z6.string(),
|
|
@@ -1478,14 +1517,7 @@ var SettleResponseSchema = z6.object({
|
|
|
1478
1517
|
});
|
|
1479
1518
|
var ENCOUNTER_DOMAIN = "offline:v1:encounter";
|
|
1480
1519
|
async function sha256Hex(input) {
|
|
1481
|
-
|
|
1482
|
-
const enc2 = new TextEncoder().encode(input);
|
|
1483
|
-
if (subtle) {
|
|
1484
|
-
const buf = await subtle.digest("SHA-256", enc2);
|
|
1485
|
-
return Array.from(new Uint8Array(buf)).map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
1486
|
-
}
|
|
1487
|
-
const mod = await import("crypto");
|
|
1488
|
-
return mod.createHash("sha256").update(input).digest("hex");
|
|
1520
|
+
return bytesToHex2(sha256(new TextEncoder().encode(input)));
|
|
1489
1521
|
}
|
|
1490
1522
|
async function computeEncounterId(input) {
|
|
1491
1523
|
return sha256Hex(
|
|
@@ -1533,8 +1565,8 @@ function createOfflineSettlementsClient(partner) {
|
|
|
1533
1565
|
|
|
1534
1566
|
// src/auth/hmac.ts
|
|
1535
1567
|
import { hmac } from "@noble/hashes/hmac";
|
|
1536
|
-
import { sha256 } from "@noble/hashes/sha256";
|
|
1537
|
-
function
|
|
1568
|
+
import { sha256 as sha2562 } from "@noble/hashes/sha256";
|
|
1569
|
+
function bytesToHex3(b) {
|
|
1538
1570
|
let s = "";
|
|
1539
1571
|
for (let i = 0; i < b.length; i++) s += b[i].toString(16).padStart(2, "0");
|
|
1540
1572
|
return s;
|
|
@@ -1546,7 +1578,7 @@ function constantTimeStringEqual(a, b) {
|
|
|
1546
1578
|
return diff === 0;
|
|
1547
1579
|
}
|
|
1548
1580
|
function bodySha256Hex(body) {
|
|
1549
|
-
return
|
|
1581
|
+
return bytesToHex3(sha2562(new TextEncoder().encode(body)));
|
|
1550
1582
|
}
|
|
1551
1583
|
function canonicalRequestString(input) {
|
|
1552
1584
|
return [
|
|
@@ -1558,8 +1590,8 @@ function canonicalRequestString(input) {
|
|
|
1558
1590
|
].join("\n");
|
|
1559
1591
|
}
|
|
1560
1592
|
function signRequestHMAC(input) {
|
|
1561
|
-
return
|
|
1562
|
-
hmac(
|
|
1593
|
+
return bytesToHex3(
|
|
1594
|
+
hmac(sha2562, input.apiSecret, canonicalRequestString(input))
|
|
1563
1595
|
);
|
|
1564
1596
|
}
|
|
1565
1597
|
function verifyRequestHMAC(input) {
|
|
@@ -2318,6 +2350,9 @@ function createAccountsClient(opts) {
|
|
|
2318
2350
|
|
|
2319
2351
|
// src/partner/client.ts
|
|
2320
2352
|
import { z as z11 } from "zod";
|
|
2353
|
+
import { sha256 as sha2563 } from "@noble/hashes/sha256";
|
|
2354
|
+
import { hmac as hmac2 } from "@noble/hashes/hmac";
|
|
2355
|
+
import { bytesToHex as bytesToHex4 } from "@noble/hashes/utils";
|
|
2321
2356
|
var PARTNER_SCOPES = [
|
|
2322
2357
|
"passes:write",
|
|
2323
2358
|
"passes:read",
|
|
@@ -2341,39 +2376,13 @@ var ApiCredentialPublicSchema = z11.object({
|
|
|
2341
2376
|
var MintedApiCredentialSchema = ApiCredentialPublicSchema.extend({
|
|
2342
2377
|
secret: z11.string().min(1)
|
|
2343
2378
|
});
|
|
2344
|
-
async function getSubtle() {
|
|
2345
|
-
const c = globalThis.crypto;
|
|
2346
|
-
if (c?.subtle) return c.subtle;
|
|
2347
|
-
const mod = await import("crypto");
|
|
2348
|
-
return mod.webcrypto.subtle;
|
|
2349
|
-
}
|
|
2350
2379
|
var enc = new TextEncoder();
|
|
2351
|
-
function bytesToHex3(buf) {
|
|
2352
|
-
const u = new Uint8Array(buf);
|
|
2353
|
-
let s = "";
|
|
2354
|
-
for (let i = 0; i < u.length; i++) {
|
|
2355
|
-
s += u[i].toString(16).padStart(2, "0");
|
|
2356
|
-
}
|
|
2357
|
-
return s;
|
|
2358
|
-
}
|
|
2359
2380
|
async function sha256Hex2(input) {
|
|
2360
|
-
const subtle = await getSubtle();
|
|
2361
2381
|
const data = typeof input === "string" ? enc.encode(input) : input;
|
|
2362
|
-
|
|
2363
|
-
const buf = await subtle.digest("SHA-256", buffer);
|
|
2364
|
-
return bytesToHex3(buf);
|
|
2382
|
+
return bytesToHex4(sha2563(data));
|
|
2365
2383
|
}
|
|
2366
2384
|
async function hmacSha256Hex(keyHex, message) {
|
|
2367
|
-
|
|
2368
|
-
const key = await subtle.importKey(
|
|
2369
|
-
"raw",
|
|
2370
|
-
enc.encode(keyHex),
|
|
2371
|
-
{ name: "HMAC", hash: "SHA-256" },
|
|
2372
|
-
false,
|
|
2373
|
-
["sign"]
|
|
2374
|
-
);
|
|
2375
|
-
const sig = await subtle.sign("HMAC", key, enc.encode(message));
|
|
2376
|
-
return bytesToHex3(sig);
|
|
2385
|
+
return bytesToHex4(hmac2(sha2563, enc.encode(keyHex), enc.encode(message)));
|
|
2377
2386
|
}
|
|
2378
2387
|
function defaultNonce2() {
|
|
2379
2388
|
const c = globalThis.crypto;
|
|
@@ -2534,6 +2543,260 @@ function createApiCredentialsAdminClient(opts) {
|
|
|
2534
2543
|
)
|
|
2535
2544
|
};
|
|
2536
2545
|
}
|
|
2546
|
+
|
|
2547
|
+
// src/me-offline/client.ts
|
|
2548
|
+
import { z as z12 } from "zod";
|
|
2549
|
+
var Hex64 = z12.string().regex(/^[0-9a-f]{64}$/i);
|
|
2550
|
+
var HexAny = z12.string().regex(/^[0-9a-f]+$/i);
|
|
2551
|
+
var Sha256Hex = z12.string().regex(/^[0-9a-f]{64}$/i);
|
|
2552
|
+
var RegisterDeviceKeyInputSchema = z12.object({
|
|
2553
|
+
deviceId: z12.string().min(1).max(128),
|
|
2554
|
+
publicKeyHex: Hex64
|
|
2555
|
+
});
|
|
2556
|
+
var DeviceKeyRecordSchema = z12.object({
|
|
2557
|
+
id: z12.string().uuid(),
|
|
2558
|
+
userId: z12.string().uuid(),
|
|
2559
|
+
deviceId: z12.string(),
|
|
2560
|
+
publicKeyHex: Hex64,
|
|
2561
|
+
createdAtMs: z12.number().int().nonnegative(),
|
|
2562
|
+
revokedAtMs: z12.number().int().nonnegative().nullable()
|
|
2563
|
+
});
|
|
2564
|
+
var ConsumerOACSchema = z12.object({
|
|
2565
|
+
oacId: z12.string().uuid(),
|
|
2566
|
+
issuerId: z12.string().min(1).max(64),
|
|
2567
|
+
userId: z12.string().uuid(),
|
|
2568
|
+
deviceId: z12.string().min(1).max(128),
|
|
2569
|
+
devicePubkeyHex: Hex64,
|
|
2570
|
+
perTxCapKobo: z12.number().int().positive(),
|
|
2571
|
+
cumulativeCapKobo: z12.number().int().positive(),
|
|
2572
|
+
currency: z12.string().length(3),
|
|
2573
|
+
validFromMs: z12.number().int().nonnegative(),
|
|
2574
|
+
validUntilMs: z12.number().int().nonnegative(),
|
|
2575
|
+
counterSeed: z12.number().int().nonnegative(),
|
|
2576
|
+
issuedAtMs: z12.number().int().nonnegative()
|
|
2577
|
+
});
|
|
2578
|
+
var SignedConsumerOACSchema = z12.object({
|
|
2579
|
+
oac: ConsumerOACSchema,
|
|
2580
|
+
issuerSig: HexAny,
|
|
2581
|
+
issuerPublicKeyHex: Hex64
|
|
2582
|
+
});
|
|
2583
|
+
var OACRecordSchema = SignedConsumerOACSchema.extend({
|
|
2584
|
+
currentOfflineSpentKobo: z12.number().int().nonnegative(),
|
|
2585
|
+
status: z12.enum([
|
|
2586
|
+
"active",
|
|
2587
|
+
"superseded",
|
|
2588
|
+
"expired",
|
|
2589
|
+
"revoked",
|
|
2590
|
+
"disabling",
|
|
2591
|
+
"draining",
|
|
2592
|
+
"closed"
|
|
2593
|
+
]),
|
|
2594
|
+
supersededAtMs: z12.number().int().nonnegative().nullable(),
|
|
2595
|
+
revokedAtMs: z12.number().int().nonnegative().nullable(),
|
|
2596
|
+
holdId: z12.string().uuid().nullable().optional()
|
|
2597
|
+
});
|
|
2598
|
+
var IssueOACInputSchema = z12.object({
|
|
2599
|
+
deviceId: z12.string().min(1).max(128),
|
|
2600
|
+
perTxCapKobo: z12.number().int().positive().optional(),
|
|
2601
|
+
cumulativeCapKobo: z12.number().int().positive().optional(),
|
|
2602
|
+
ttlMs: z12.number().int().min(6e4).max(1e3 * 60 * 60 * 24 * 7).optional(),
|
|
2603
|
+
spendableOnlineKobo: z12.number().int().nonnegative().optional()
|
|
2604
|
+
});
|
|
2605
|
+
var EnableOfflineInputSchema = z12.object({
|
|
2606
|
+
deviceId: z12.string().min(1).max(128),
|
|
2607
|
+
amountKobo: z12.number().int().positive(),
|
|
2608
|
+
perTxCapKobo: z12.number().int().positive().optional(),
|
|
2609
|
+
ttlMs: z12.number().int().min(6e4).max(1e3 * 60 * 60 * 24 * 7).optional(),
|
|
2610
|
+
installId: z12.string().min(1).max(128),
|
|
2611
|
+
partnerId: z12.string().min(1).max(64).optional()
|
|
2612
|
+
});
|
|
2613
|
+
var DisableOfflineInputSchema = z12.object({
|
|
2614
|
+
deviceId: z12.string().min(1).max(128),
|
|
2615
|
+
installId: z12.string().min(1).max(128).optional(),
|
|
2616
|
+
claims: z12.array(z12.unknown()).max(256).optional()
|
|
2617
|
+
});
|
|
2618
|
+
var OfflineHoldRecordSchema = z12.object({
|
|
2619
|
+
holdId: z12.string().uuid(),
|
|
2620
|
+
userId: z12.string().uuid(),
|
|
2621
|
+
deviceId: z12.string(),
|
|
2622
|
+
partnerId: z12.string(),
|
|
2623
|
+
adapterKind: z12.string(),
|
|
2624
|
+
externalHoldRef: z12.string().nullable(),
|
|
2625
|
+
amountKobo: z12.number().int().nonnegative(),
|
|
2626
|
+
capturedKobo: z12.number().int().nonnegative(),
|
|
2627
|
+
releasedKobo: z12.number().int().nonnegative(),
|
|
2628
|
+
remainingKobo: z12.number().int().nonnegative(),
|
|
2629
|
+
currency: z12.string().length(3),
|
|
2630
|
+
status: z12.enum([
|
|
2631
|
+
"placing",
|
|
2632
|
+
"active",
|
|
2633
|
+
"disabling",
|
|
2634
|
+
"draining",
|
|
2635
|
+
"closed",
|
|
2636
|
+
"revoked",
|
|
2637
|
+
"failed"
|
|
2638
|
+
]),
|
|
2639
|
+
installId: z12.string().nullable(),
|
|
2640
|
+
drainDeadlineMs: z12.number().int().nonnegative(),
|
|
2641
|
+
disableRequestedAtMs: z12.number().int().nonnegative().nullable(),
|
|
2642
|
+
createdAtMs: z12.number().int().nonnegative(),
|
|
2643
|
+
closedAtMs: z12.number().int().nonnegative().nullable(),
|
|
2644
|
+
isTrusted: z12.boolean().optional()
|
|
2645
|
+
});
|
|
2646
|
+
var EnableOfflineResultSchema = z12.object({
|
|
2647
|
+
hold: OfflineHoldRecordSchema,
|
|
2648
|
+
oac: OACRecordSchema
|
|
2649
|
+
});
|
|
2650
|
+
var DisableOfflineResultSchema = z12.object({
|
|
2651
|
+
hold: OfflineHoldRecordSchema,
|
|
2652
|
+
trusted: z12.boolean(),
|
|
2653
|
+
settledClaims: z12.number().int().nonnegative()
|
|
2654
|
+
});
|
|
2655
|
+
var OfflineStatusResultSchema = z12.object({
|
|
2656
|
+
hold: OfflineHoldRecordSchema.nullable(),
|
|
2657
|
+
active: OACRecordSchema.nullable()
|
|
2658
|
+
});
|
|
2659
|
+
var OfflineStateResultSchema = z12.object({
|
|
2660
|
+
active: OACRecordSchema.nullable()
|
|
2661
|
+
});
|
|
2662
|
+
var ConsumerPaymentClaimSchema = z12.object({
|
|
2663
|
+
oacId: z12.string().uuid(),
|
|
2664
|
+
encounterId: Sha256Hex.optional(),
|
|
2665
|
+
payerUserId: z12.string().uuid(),
|
|
2666
|
+
payeeUserId: z12.string().uuid(),
|
|
2667
|
+
payerDeviceId: z12.string().min(1).max(128),
|
|
2668
|
+
payerNonce: z12.string().min(8).max(128),
|
|
2669
|
+
payeeNonce: z12.string().min(8).max(128),
|
|
2670
|
+
amountKobo: z12.number().int().positive(),
|
|
2671
|
+
currency: z12.string().length(3).default("NGN"),
|
|
2672
|
+
occurredAtMs: z12.number().int().nonnegative(),
|
|
2673
|
+
completedAtMs: z12.number().int().nonnegative().optional(),
|
|
2674
|
+
contextId: z12.string().max(128).optional(),
|
|
2675
|
+
payerPubkeyHex: Hex64,
|
|
2676
|
+
payerSignature: HexAny,
|
|
2677
|
+
payeePubkeyHex: Hex64.optional(),
|
|
2678
|
+
payeeSignature: HexAny.optional()
|
|
2679
|
+
});
|
|
2680
|
+
var ConsumerSettlementSchema = z12.object({
|
|
2681
|
+
settlementId: z12.string().uuid(),
|
|
2682
|
+
settlementKey: Sha256Hex,
|
|
2683
|
+
encounterId: Sha256Hex,
|
|
2684
|
+
oacId: z12.string().uuid(),
|
|
2685
|
+
payerUserId: z12.string().uuid(),
|
|
2686
|
+
payeeUserId: z12.string().uuid(),
|
|
2687
|
+
amountKobo: z12.number().int().positive(),
|
|
2688
|
+
currency: z12.string().length(3),
|
|
2689
|
+
status: z12.enum(["SETTLED", "REVIEW"]),
|
|
2690
|
+
reviewReason: z12.string().nullable(),
|
|
2691
|
+
ledgerRef: z12.string().nullable(),
|
|
2692
|
+
issuerSig: HexAny,
|
|
2693
|
+
createdAtMs: z12.number().int().nonnegative()
|
|
2694
|
+
});
|
|
2695
|
+
var ConsumerSettleResultSchema = z12.object({
|
|
2696
|
+
settlement: ConsumerSettlementSchema,
|
|
2697
|
+
encounterId: Sha256Hex,
|
|
2698
|
+
replayed: z12.boolean()
|
|
2699
|
+
});
|
|
2700
|
+
var RevokeDeviceKeyInputSchema = z12.object({
|
|
2701
|
+
deviceId: z12.string().min(1).max(128),
|
|
2702
|
+
/** Step-up token from /api/v1/auth/send/verify with purpose='offline_revoke'. */
|
|
2703
|
+
sendAuthToken: z12.string().min(16)
|
|
2704
|
+
});
|
|
2705
|
+
function createMeOfflineClient(opts) {
|
|
2706
|
+
const fetchImpl = opts.fetchImpl ?? globalThis.fetch;
|
|
2707
|
+
if (!fetchImpl) {
|
|
2708
|
+
throw new Error("createMeOfflineClient: no fetch implementation available");
|
|
2709
|
+
}
|
|
2710
|
+
const baseUrl = opts.baseUrl.replace(/\/$/, "");
|
|
2711
|
+
async function call(method, path, body, parser) {
|
|
2712
|
+
const init2 = {
|
|
2713
|
+
method,
|
|
2714
|
+
headers: {
|
|
2715
|
+
"content-type": "application/json",
|
|
2716
|
+
accept: "application/json"
|
|
2717
|
+
}
|
|
2718
|
+
};
|
|
2719
|
+
if (body !== void 0) init2.body = JSON.stringify(body);
|
|
2720
|
+
const resp = await fetchImpl(`${baseUrl}${path}`, init2);
|
|
2721
|
+
const text = await resp.text();
|
|
2722
|
+
let raw = void 0;
|
|
2723
|
+
if (text) {
|
|
2724
|
+
try {
|
|
2725
|
+
raw = JSON.parse(text);
|
|
2726
|
+
} catch {
|
|
2727
|
+
}
|
|
2728
|
+
}
|
|
2729
|
+
if (!resp.ok) {
|
|
2730
|
+
const code = raw && typeof raw === "object" && "code" in raw && typeof raw.code === "string" ? raw.code : `http_${resp.status}`;
|
|
2731
|
+
const message = raw && typeof raw === "object" && "message" in raw && typeof raw.message === "string" ? raw.message : `request failed with status ${resp.status}`;
|
|
2732
|
+
throw new FlurApiError(resp.status, code, message, raw);
|
|
2733
|
+
}
|
|
2734
|
+
return parser(raw);
|
|
2735
|
+
}
|
|
2736
|
+
const deviceKeyItems = z12.object({ items: z12.array(DeviceKeyRecordSchema) });
|
|
2737
|
+
return {
|
|
2738
|
+
registerDeviceKey: (input) => call(
|
|
2739
|
+
"POST",
|
|
2740
|
+
"/v1/me/offline/keys",
|
|
2741
|
+
RegisterDeviceKeyInputSchema.parse(input),
|
|
2742
|
+
(raw) => DeviceKeyRecordSchema.parse(raw)
|
|
2743
|
+
),
|
|
2744
|
+
listDeviceKeys: () => call(
|
|
2745
|
+
"GET",
|
|
2746
|
+
"/v1/me/offline/keys",
|
|
2747
|
+
void 0,
|
|
2748
|
+
(raw) => deviceKeyItems.parse(raw)
|
|
2749
|
+
),
|
|
2750
|
+
revokeDeviceKey: (input) => call(
|
|
2751
|
+
"POST",
|
|
2752
|
+
"/v1/me/offline/keys/revoke",
|
|
2753
|
+
RevokeDeviceKeyInputSchema.parse(input),
|
|
2754
|
+
() => void 0
|
|
2755
|
+
),
|
|
2756
|
+
enable: (input) => call(
|
|
2757
|
+
"POST",
|
|
2758
|
+
"/v1/me/offline/enable",
|
|
2759
|
+
EnableOfflineInputSchema.parse(input),
|
|
2760
|
+
(raw) => EnableOfflineResultSchema.parse(raw)
|
|
2761
|
+
),
|
|
2762
|
+
refresh: (input) => call(
|
|
2763
|
+
"POST",
|
|
2764
|
+
"/v1/me/offline/refresh",
|
|
2765
|
+
IssueOACInputSchema.parse(input),
|
|
2766
|
+
(raw) => OACRecordSchema.parse(raw)
|
|
2767
|
+
),
|
|
2768
|
+
disable: (input) => call(
|
|
2769
|
+
"POST",
|
|
2770
|
+
"/v1/me/offline/disable",
|
|
2771
|
+
DisableOfflineInputSchema.parse(input),
|
|
2772
|
+
(raw) => DisableOfflineResultSchema.parse(raw)
|
|
2773
|
+
),
|
|
2774
|
+
getStatus: (deviceId) => {
|
|
2775
|
+
const qs = deviceId ? `?deviceId=${encodeURIComponent(deviceId)}` : "";
|
|
2776
|
+
return call(
|
|
2777
|
+
"GET",
|
|
2778
|
+
`/v1/me/offline/status${qs}`,
|
|
2779
|
+
void 0,
|
|
2780
|
+
(raw) => OfflineStatusResultSchema.parse(raw)
|
|
2781
|
+
);
|
|
2782
|
+
},
|
|
2783
|
+
getState: (deviceId) => {
|
|
2784
|
+
const qs = deviceId ? `?deviceId=${encodeURIComponent(deviceId)}` : "";
|
|
2785
|
+
return call(
|
|
2786
|
+
"GET",
|
|
2787
|
+
`/v1/me/offline/state${qs}`,
|
|
2788
|
+
void 0,
|
|
2789
|
+
(raw) => OfflineStateResultSchema.parse(raw)
|
|
2790
|
+
);
|
|
2791
|
+
},
|
|
2792
|
+
submitClaim: (claim) => call(
|
|
2793
|
+
"POST",
|
|
2794
|
+
"/v1/me/offline/claims",
|
|
2795
|
+
ConsumerPaymentClaimSchema.parse(claim),
|
|
2796
|
+
(raw) => ConsumerSettleResultSchema.parse(raw)
|
|
2797
|
+
)
|
|
2798
|
+
};
|
|
2799
|
+
}
|
|
2537
2800
|
export {
|
|
2538
2801
|
ACCOUNT_STATUSES,
|
|
2539
2802
|
ACCOUNT_TYPES,
|
|
@@ -2541,6 +2804,16 @@ export {
|
|
|
2541
2804
|
AccountMembershipSchema,
|
|
2542
2805
|
AccountSchema,
|
|
2543
2806
|
ApiCredentialPublicSchema,
|
|
2807
|
+
OACRecordSchema as ConsumerOACRecordSchema,
|
|
2808
|
+
ConsumerOACSchema,
|
|
2809
|
+
ConsumerPaymentClaimSchema,
|
|
2810
|
+
ConsumerSettleResultSchema,
|
|
2811
|
+
ConsumerSettlementSchema,
|
|
2812
|
+
DeviceKeyRecordSchema,
|
|
2813
|
+
DisableOfflineInputSchema,
|
|
2814
|
+
DisableOfflineResultSchema,
|
|
2815
|
+
EnableOfflineInputSchema,
|
|
2816
|
+
EnableOfflineResultSchema,
|
|
2544
2817
|
FIELD,
|
|
2545
2818
|
FlurApiError,
|
|
2546
2819
|
FlurCapExceededError,
|
|
@@ -2548,6 +2821,7 @@ export {
|
|
|
2548
2821
|
FlurError,
|
|
2549
2822
|
FlurExpiredError,
|
|
2550
2823
|
FlurReplayError,
|
|
2824
|
+
IssueOACInputSchema,
|
|
2551
2825
|
MEMBERSHIP_ROLES,
|
|
2552
2826
|
MintedApiCredentialSchema,
|
|
2553
2827
|
NGN_CURRENCY_CODE,
|
|
@@ -2557,8 +2831,11 @@ export {
|
|
|
2557
2831
|
OAC_DEFAULT_CUMULATIVE_KOBO,
|
|
2558
2832
|
OAC_DEFAULT_PER_TX_KOBO,
|
|
2559
2833
|
OAC_DEFAULT_VALIDITY_MS,
|
|
2834
|
+
OfflineHoldRecordSchema,
|
|
2560
2835
|
OfflinePaymentAuthorizationSchema,
|
|
2561
2836
|
OfflinePaymentRequestSchema,
|
|
2837
|
+
OfflineStateResultSchema,
|
|
2838
|
+
OfflineStatusResultSchema,
|
|
2562
2839
|
OfflineTokenSchema,
|
|
2563
2840
|
PARTNER_SCOPES,
|
|
2564
2841
|
PASS_KINDS,
|
|
@@ -2574,8 +2851,11 @@ export {
|
|
|
2574
2851
|
ReceiptPayloadSchema,
|
|
2575
2852
|
ReceiptSchema,
|
|
2576
2853
|
RedemptionSchema,
|
|
2854
|
+
RegisterDeviceKeyInputSchema,
|
|
2855
|
+
RevokeDeviceKeyInputSchema,
|
|
2577
2856
|
SettleResponseSchema,
|
|
2578
2857
|
SettlementSchema,
|
|
2858
|
+
SignedConsumerOACSchema,
|
|
2579
2859
|
bodySha256Hex,
|
|
2580
2860
|
buildAuthorization,
|
|
2581
2861
|
buildOAC,
|
|
@@ -2594,6 +2874,7 @@ export {
|
|
|
2594
2874
|
createApiCredentialsAdminClient,
|
|
2595
2875
|
createFlurPartnerClient,
|
|
2596
2876
|
createHmacFetch,
|
|
2877
|
+
createMeOfflineClient,
|
|
2597
2878
|
createOfflineSettlementsClient,
|
|
2598
2879
|
createPassesClient,
|
|
2599
2880
|
createReceiptsClient,
|