@nokinc-flur/sdk 2.2.0 → 2.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +325 -310
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +329 -191
- package/dist/index.d.ts +329 -191
- package/dist/index.js +314 -300
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -44,6 +44,8 @@ __export(index_exports, {
|
|
|
44
44
|
CLAIM_DOMAIN_V2: () => CLAIM_DOMAIN_V2,
|
|
45
45
|
COLLECTION_INTENT_STATUSES: () => COLLECTION_INTENT_STATUSES,
|
|
46
46
|
COLLECTION_PAYMENT_STATUSES: () => COLLECTION_PAYMENT_STATUSES,
|
|
47
|
+
CONSUMER_OAC_DOMAIN: () => CONSUMER_OAC_DOMAIN,
|
|
48
|
+
CONSUMER_OAC_QR_PREFIX: () => CONSUMER_OAC_QR_PREFIX,
|
|
47
49
|
CONSUMER_OFFLINE_CLAIM_SUBMIT_GRACE_MS: () => CONSUMER_OFFLINE_CLAIM_SUBMIT_GRACE_MS,
|
|
48
50
|
CONSUMER_PAYMENT_REQUEST_DOMAIN: () => CONSUMER_PAYMENT_REQUEST_DOMAIN,
|
|
49
51
|
CONSUMER_SETTLEMENT_DOMAIN: () => CONSUMER_SETTLEMENT_DOMAIN,
|
|
@@ -82,6 +84,8 @@ __export(index_exports, {
|
|
|
82
84
|
IdentityArtifactSchema: () => IdentityArtifactSchema,
|
|
83
85
|
IngestFundingResultSchema: () => IngestFundingResultSchema,
|
|
84
86
|
IssueAccountOacInputSchema: () => IssueAccountOacInputSchema,
|
|
87
|
+
IssuerTrustBundleSchema: () => IssuerTrustBundleSchema,
|
|
88
|
+
IssuerTrustKeySchema: () => IssuerTrustKeySchema,
|
|
85
89
|
LedgerJournalEntryArtifactSchema: () => LedgerJournalEntryArtifactSchema,
|
|
86
90
|
ListPayoutDestinationsResultSchema: () => ListPayoutDestinationsResultSchema,
|
|
87
91
|
MEMBERSHIP_ROLES: () => MEMBERSHIP_ROLES,
|
|
@@ -105,6 +109,7 @@ __export(index_exports, {
|
|
|
105
109
|
OFFLINE_SMS_SETTLE_SIGNATURE_BYTES: () => OFFLINE_SMS_SETTLE_SIGNATURE_BYTES,
|
|
106
110
|
OFFLINE_SMS_SETTLE_TOKEN_BYTES: () => OFFLINE_SMS_SETTLE_TOKEN_BYTES,
|
|
107
111
|
OFFLINE_SMS_SETTLE_VERSION: () => OFFLINE_SMS_SETTLE_VERSION,
|
|
112
|
+
OacPresentmentRequestSchema: () => OacPresentmentRequestSchema,
|
|
108
113
|
OfflineClaimArtifactSchema: () => OfflineClaimArtifactSchema,
|
|
109
114
|
OfflinePaymentAuthorizationArtifactSchema: () => OfflinePaymentAuthorizationArtifactSchema,
|
|
110
115
|
OfflinePaymentAuthorizationSchema: () => OfflinePaymentAuthorizationSchema,
|
|
@@ -122,9 +127,6 @@ __export(index_exports, {
|
|
|
122
127
|
PASS_STATES: () => PASS_STATES,
|
|
123
128
|
PAYLOAD_FORMAT_INDICATOR_VALUE: () => PAYLOAD_FORMAT_INDICATOR_VALUE,
|
|
124
129
|
PAYOUT_DESTINATION_STATUSES: () => PAYOUT_DESTINATION_STATUSES,
|
|
125
|
-
PAY_CARD_DEFAULT_TTL_MS: () => PAY_CARD_DEFAULT_TTL_MS,
|
|
126
|
-
PAY_CARD_REFRESH_THRESHOLD_MS: () => PAY_CARD_REFRESH_THRESHOLD_MS,
|
|
127
|
-
PAY_CARD_URI_PREFIX: () => PAY_CARD_URI_PREFIX,
|
|
128
130
|
POINT_OF_INITIATION: () => POINT_OF_INITIATION,
|
|
129
131
|
PartnerFundingEventInputSchema: () => PartnerFundingEventInputSchema,
|
|
130
132
|
PartnerFundingSchema: () => PartnerFundingSchema,
|
|
@@ -132,7 +134,6 @@ __export(index_exports, {
|
|
|
132
134
|
PassArtifactSchema: () => PassArtifactSchema,
|
|
133
135
|
PassMetadataSchema: () => PassMetadataSchema,
|
|
134
136
|
PassSchema: () => PassSchema,
|
|
135
|
-
PayCardArtifactSchema: () => PayCardArtifactSchema,
|
|
136
137
|
PayCollectionInputSchema: () => PayCollectionInputSchema,
|
|
137
138
|
PaymentClaimSchema: () => PaymentClaimSchema,
|
|
138
139
|
PaymentIntentArtifactSchema: () => PaymentIntentArtifactSchema,
|
|
@@ -171,7 +172,6 @@ __export(index_exports, {
|
|
|
171
172
|
buildConsumerPaymentRequest: () => buildConsumerPaymentRequest,
|
|
172
173
|
buildOAC: () => buildOAC,
|
|
173
174
|
buildPass: () => buildPass,
|
|
174
|
-
buildPayCardSigningInput: () => buildPayCardSigningInput,
|
|
175
175
|
buildPaymentRequest: () => buildPaymentRequest,
|
|
176
176
|
buildReceipt: () => buildReceipt,
|
|
177
177
|
buildRedemption: () => buildRedemption,
|
|
@@ -185,6 +185,7 @@ __export(index_exports, {
|
|
|
185
185
|
computeConsumerClaimEncounterId: () => computeConsumerClaimEncounterId,
|
|
186
186
|
computeEncounterId: () => computeEncounterId,
|
|
187
187
|
constantTimeEqual: () => constantTimeEqual,
|
|
188
|
+
consumerOacSigningPayload: () => consumerOacSigningPayload,
|
|
188
189
|
consumerPaymentRequestSigningBytes: () => consumerPaymentRequestSigningBytes,
|
|
189
190
|
consumerPaymentRequestSigningPayload: () => consumerPaymentRequestSigningPayload,
|
|
190
191
|
consumerSettlementSigningPayload: () => consumerSettlementSigningPayload,
|
|
@@ -205,23 +206,24 @@ __export(index_exports, {
|
|
|
205
206
|
createPartnerFundingClient: () => createPartnerFundingClient,
|
|
206
207
|
createPartnerProfileAdminClient: () => createPartnerProfileAdminClient,
|
|
207
208
|
createPassesClient: () => createPassesClient,
|
|
208
|
-
createPayCardArtifactUri: () => createPayCardArtifactUri,
|
|
209
209
|
createReceiptArtifactUri: () => createReceiptArtifactUri,
|
|
210
210
|
createReceiptsClient: () => createReceiptsClient,
|
|
211
211
|
createSoftwareP256Signer: () => createSoftwareP256Signer,
|
|
212
212
|
decodeArtifactUri: () => decodeArtifactUri,
|
|
213
213
|
decodeAuthorizationQR: () => decodeAuthorizationQR,
|
|
214
214
|
decodeBase45: () => decodeBase45,
|
|
215
|
+
decodeConsumerOacRequest: () => decodeConsumerOacRequest,
|
|
215
216
|
decodeConsumerSettlementReceiptQR: () => decodeConsumerSettlementReceiptQR,
|
|
216
217
|
decodeOfflineClaimSmsMessage: () => decodeOfflineClaimSmsMessage,
|
|
217
218
|
decodeOfflineSmsSettleToken: () => decodeOfflineSmsSettleToken,
|
|
218
|
-
decodePayCardArtifact: () => decodePayCardArtifact,
|
|
219
219
|
decodePaymentRequestQR: () => decodePaymentRequestQR,
|
|
220
|
+
decodeUnverifiedConsumerOacQR: () => decodeUnverifiedConsumerOacQR,
|
|
220
221
|
decodeUnverifiedConsumerSettlementReceiptQR: () => decodeUnverifiedConsumerSettlementReceiptQR,
|
|
221
222
|
derToRawP256Signature: () => derToRawP256Signature,
|
|
222
223
|
encodeArtifactUri: () => encodeArtifactUri,
|
|
223
224
|
encodeAuthorizationQR: () => encodeAuthorizationQR,
|
|
224
225
|
encodeBase45: () => encodeBase45,
|
|
226
|
+
encodeConsumerOacQR: () => encodeConsumerOacQR,
|
|
225
227
|
encodeConsumerSettlementReceiptQR: () => encodeConsumerSettlementReceiptQR,
|
|
226
228
|
encodeNQR: () => encodeNQR,
|
|
227
229
|
encodeOfflineClaimSmsMessage: () => encodeOfflineClaimSmsMessage,
|
|
@@ -233,12 +235,11 @@ __export(index_exports, {
|
|
|
233
235
|
generateDynamicQR: () => generateDynamicQR,
|
|
234
236
|
generateStaticQR: () => generateStaticQR,
|
|
235
237
|
init: () => init,
|
|
236
|
-
|
|
238
|
+
isConsumerOacQR: () => isConsumerOacQR,
|
|
237
239
|
isConsumerPaymentRequestExpired: () => isConsumerPaymentRequestExpired,
|
|
238
240
|
isHardenedArtifactType: () => isHardenedArtifactType,
|
|
239
241
|
isKnownArtifactType: () => isKnownArtifactType,
|
|
240
242
|
isPassWithinValidity: () => isPassWithinValidity,
|
|
241
|
-
isPayCardArtifactUri: () => isPayCardArtifactUri,
|
|
242
243
|
moneyMinorToNumber: () => moneyMinorToNumber,
|
|
243
244
|
normalizeE164: () => normalizeE164,
|
|
244
245
|
parseAmountInput: () => parseAmountInput,
|
|
@@ -264,9 +265,9 @@ __export(index_exports, {
|
|
|
264
265
|
verifyConsumerSettlement: () => verifyConsumerSettlement,
|
|
265
266
|
verifyConsumerSettlementReceiptQR: () => verifyConsumerSettlementReceiptQR,
|
|
266
267
|
verifyOAC: () => verifyOAC,
|
|
268
|
+
verifyOacOffline: () => verifyOacOffline,
|
|
267
269
|
verifyOfflineSmsSettleToken: () => verifyOfflineSmsSettleToken,
|
|
268
270
|
verifyPass: () => verifyPass,
|
|
269
|
-
verifyPayCardArtifact: () => verifyPayCardArtifact,
|
|
270
271
|
verifyPaymentRequest: () => verifyPaymentRequest,
|
|
271
272
|
verifyReceipt: () => verifyReceipt,
|
|
272
273
|
verifyRedemption: () => verifyRedemption,
|
|
@@ -3238,7 +3239,17 @@ var Base64Std3 = import_zod13.z.string().regex(/^[A-Za-z0-9+/]+={0,2}$/);
|
|
|
3238
3239
|
var ClaimNonce = import_zod13.z.string().min(8).max(128).refine((value) => !value.includes("|"), {
|
|
3239
3240
|
message: "nonce must not contain |"
|
|
3240
3241
|
});
|
|
3241
|
-
var ACCOUNT_FUNDED_OAC_MAX_TTL_MS = 1e3 * 60 * 60 * 24
|
|
3242
|
+
var ACCOUNT_FUNDED_OAC_MAX_TTL_MS = 1e3 * 60 * 60 * 24;
|
|
3243
|
+
var IssuerTrustKeySchema = import_zod13.z.object({
|
|
3244
|
+
issuerId: import_zod13.z.string().min(1).max(128),
|
|
3245
|
+
alg: import_zod13.z.literal("p256"),
|
|
3246
|
+
publicKeySpkiB64: Base64Std3.min(64).max(4096),
|
|
3247
|
+
notBeforeMs: import_zod13.z.number().int().nonnegative().optional(),
|
|
3248
|
+
notAfterMs: import_zod13.z.number().int().positive().optional()
|
|
3249
|
+
});
|
|
3250
|
+
var IssuerTrustBundleSchema = import_zod13.z.object({
|
|
3251
|
+
keys: import_zod13.z.array(IssuerTrustKeySchema).min(1)
|
|
3252
|
+
});
|
|
3242
3253
|
var CONSUMER_OFFLINE_CLAIM_SUBMIT_GRACE_MS = 1e3 * 60 * 60 * 24;
|
|
3243
3254
|
var AttestationSecurityLevelSchema = import_zod13.z.enum([
|
|
3244
3255
|
"STRONGBOX",
|
|
@@ -3292,13 +3303,28 @@ var ConsumerOACSchema = import_zod13.z.object({
|
|
|
3292
3303
|
alg: import_zod13.z.literal("p256"),
|
|
3293
3304
|
/** P-256 SubjectPublicKeyInfo DER, base64. */
|
|
3294
3305
|
devicePubkeySpkiB64: Base64Std3.min(64).max(4096),
|
|
3295
|
-
|
|
3296
|
-
|
|
3306
|
+
/**
|
|
3307
|
+
* Per-transaction / cumulative offline spend ceilings. Zero is valid and
|
|
3308
|
+
* denotes an identity-only OAC: the credential proves who the holder is and
|
|
3309
|
+
* binds their device key for offline-verifiable first contact, but carries
|
|
3310
|
+
* no offline spend authority (every claim against it routes to REVIEW).
|
|
3311
|
+
* Issued to zero-balance wallets so they can still be paid offline.
|
|
3312
|
+
*/
|
|
3313
|
+
perTxCapKobo: import_zod13.z.number().int().nonnegative(),
|
|
3314
|
+
cumulativeCapKobo: import_zod13.z.number().int().nonnegative(),
|
|
3297
3315
|
currency: import_zod13.z.string().length(3),
|
|
3298
3316
|
validFromMs: import_zod13.z.number().int().nonnegative(),
|
|
3299
3317
|
validUntilMs: import_zod13.z.number().int().nonnegative(),
|
|
3300
3318
|
counterSeed: import_zod13.z.number().int().nonnegative(),
|
|
3301
|
-
issuedAtMs: import_zod13.z.number().int().nonnegative()
|
|
3319
|
+
issuedAtMs: import_zod13.z.number().int().nonnegative(),
|
|
3320
|
+
/**
|
|
3321
|
+
* Issuer-attested identity folded into the OAC so a single signed
|
|
3322
|
+
* credential serves both Tier B offline-verifiable identity and offline
|
|
3323
|
+
* spend authority. Verified offline against a pinned issuer key; the
|
|
3324
|
+
* backend remains authoritative at settlement.
|
|
3325
|
+
*/
|
|
3326
|
+
phoneE164: import_zod13.z.string().regex(/^\+[1-9]\d{7,14}$/),
|
|
3327
|
+
displayName: import_zod13.z.string().min(1).max(64)
|
|
3302
3328
|
});
|
|
3303
3329
|
var SignedConsumerOACSchema = import_zod13.z.object({
|
|
3304
3330
|
oac: ConsumerOACSchema,
|
|
@@ -3466,6 +3492,12 @@ function createMeOfflineClient(opts) {
|
|
|
3466
3492
|
`/v1/me/offline/settlements/${encodeURIComponent(idOrKey)}`,
|
|
3467
3493
|
void 0,
|
|
3468
3494
|
(raw) => ConsumerSettlementSchema.parse(raw)
|
|
3495
|
+
),
|
|
3496
|
+
getIssuerKeys: () => call(
|
|
3497
|
+
"GET",
|
|
3498
|
+
"/v1/issuer/keys",
|
|
3499
|
+
void 0,
|
|
3500
|
+
(raw) => IssuerTrustBundleSchema.parse(raw)
|
|
3469
3501
|
)
|
|
3470
3502
|
};
|
|
3471
3503
|
}
|
|
@@ -3826,13 +3858,130 @@ function base64UrlDecodeUtf8(input) {
|
|
|
3826
3858
|
throw new Error("base64 decoder unavailable");
|
|
3827
3859
|
}
|
|
3828
3860
|
|
|
3861
|
+
// src/me-offline/oac.ts
|
|
3862
|
+
var import_zod15 = require("zod");
|
|
3863
|
+
var CONSUMER_OAC_DOMAIN = "flur:consumer-offline:v1:oac";
|
|
3864
|
+
function consumerOacSigningPayload(oac) {
|
|
3865
|
+
return { domain: CONSUMER_OAC_DOMAIN, ...oac };
|
|
3866
|
+
}
|
|
3867
|
+
function verifyOacOffline(signed, trustedKeys, options = {}) {
|
|
3868
|
+
const parsed = SignedConsumerOACSchema.safeParse(signed);
|
|
3869
|
+
if (!parsed.success) return { ok: false, reason: "malformed" };
|
|
3870
|
+
const oacParsed = ConsumerOACSchema.safeParse(parsed.data.oac);
|
|
3871
|
+
if (!oacParsed.success) return { ok: false, reason: "malformed" };
|
|
3872
|
+
const oac = oacParsed.data;
|
|
3873
|
+
const nowMs = options.nowMs ?? Date.now();
|
|
3874
|
+
const pinned = trustedKeys.filter(
|
|
3875
|
+
(k) => k.issuerId === oac.issuerId && (k.notBeforeMs === void 0 || nowMs >= k.notBeforeMs) && (k.notAfterMs === void 0 || nowMs <= k.notAfterMs)
|
|
3876
|
+
);
|
|
3877
|
+
if (pinned.length === 0) return { ok: false, reason: "untrusted_issuer" };
|
|
3878
|
+
const signingBytes = canonicalJSONBytes(consumerOacSigningPayload(oac));
|
|
3879
|
+
const signatureOk = pinned.some(
|
|
3880
|
+
(k) => verifyIssuerP256(signingBytes, parsed.data.issuerSig, k.publicKeySpkiB64)
|
|
3881
|
+
);
|
|
3882
|
+
if (!signatureOk) return { ok: false, reason: "signature_invalid" };
|
|
3883
|
+
if (oac.validUntilMs - oac.validFromMs > ACCOUNT_FUNDED_OAC_MAX_TTL_MS) {
|
|
3884
|
+
return { ok: false, reason: "window_too_long" };
|
|
3885
|
+
}
|
|
3886
|
+
if (nowMs < oac.validFromMs) return { ok: false, reason: "not_yet_valid" };
|
|
3887
|
+
if (nowMs >= oac.validUntilMs) return { ok: false, reason: "expired" };
|
|
3888
|
+
return {
|
|
3889
|
+
ok: true,
|
|
3890
|
+
oac,
|
|
3891
|
+
identity: {
|
|
3892
|
+
oacId: oac.oacId,
|
|
3893
|
+
issuerId: oac.issuerId,
|
|
3894
|
+
userId: oac.userId,
|
|
3895
|
+
phoneE164: oac.phoneE164,
|
|
3896
|
+
displayName: oac.displayName,
|
|
3897
|
+
devicePubkeySpkiB64: oac.devicePubkeySpkiB64
|
|
3898
|
+
}
|
|
3899
|
+
};
|
|
3900
|
+
}
|
|
3901
|
+
var CONSUMER_OAC_QR_PREFIX = "FLUROAC1.";
|
|
3902
|
+
function isConsumerOacQR(value) {
|
|
3903
|
+
return value.startsWith(CONSUMER_OAC_QR_PREFIX);
|
|
3904
|
+
}
|
|
3905
|
+
var OacPresentmentRequestSchema = import_zod15.z.object({
|
|
3906
|
+
/** Requested amount in minor units (kobo). */
|
|
3907
|
+
amountMinor: import_zod15.z.number().int().positive().max(1e12).optional(),
|
|
3908
|
+
/** Purpose/intent code (mirrors the NIBSS intent vocabulary). */
|
|
3909
|
+
intent: import_zod15.z.string().min(1).max(32).optional(),
|
|
3910
|
+
/** Free-text reference / note. */
|
|
3911
|
+
reference: import_zod15.z.string().min(1).max(64).optional()
|
|
3912
|
+
}).strict();
|
|
3913
|
+
function encodeConsumerOacQR(signed, request) {
|
|
3914
|
+
const parsed = SignedConsumerOACSchema.parse(signed);
|
|
3915
|
+
const base = `${CONSUMER_OAC_QR_PREFIX}${base64UrlEncodeUtf82(JSON.stringify(parsed))}`;
|
|
3916
|
+
if (request === void 0) return base;
|
|
3917
|
+
const parsedRequest = OacPresentmentRequestSchema.parse(request);
|
|
3918
|
+
if (Object.keys(parsedRequest).length === 0) return base;
|
|
3919
|
+
return `${base}.${base64UrlEncodeUtf82(JSON.stringify(parsedRequest))}`;
|
|
3920
|
+
}
|
|
3921
|
+
function decodeUnverifiedConsumerOacQR(value) {
|
|
3922
|
+
if (!value.startsWith(CONSUMER_OAC_QR_PREFIX)) {
|
|
3923
|
+
throw new Error("not a Flur consumer OAC QR");
|
|
3924
|
+
}
|
|
3925
|
+
const remainder = value.slice(CONSUMER_OAC_QR_PREFIX.length);
|
|
3926
|
+
const encoded = remainder.split(".", 1)[0];
|
|
3927
|
+
let raw;
|
|
3928
|
+
try {
|
|
3929
|
+
raw = JSON.parse(base64UrlDecodeUtf82(encoded));
|
|
3930
|
+
} catch {
|
|
3931
|
+
throw new Error("consumer OAC QR is malformed");
|
|
3932
|
+
}
|
|
3933
|
+
return SignedConsumerOACSchema.parse(raw);
|
|
3934
|
+
}
|
|
3935
|
+
function decodeConsumerOacRequest(value) {
|
|
3936
|
+
if (!value.startsWith(CONSUMER_OAC_QR_PREFIX)) return null;
|
|
3937
|
+
const remainder = value.slice(CONSUMER_OAC_QR_PREFIX.length);
|
|
3938
|
+
const dot = remainder.indexOf(".");
|
|
3939
|
+
if (dot < 0) return null;
|
|
3940
|
+
const suffix = remainder.slice(dot + 1);
|
|
3941
|
+
if (suffix.length === 0) return null;
|
|
3942
|
+
try {
|
|
3943
|
+
const raw = JSON.parse(base64UrlDecodeUtf82(suffix));
|
|
3944
|
+
const parsed = OacPresentmentRequestSchema.safeParse(raw);
|
|
3945
|
+
return parsed.success ? parsed.data : null;
|
|
3946
|
+
} catch {
|
|
3947
|
+
return null;
|
|
3948
|
+
}
|
|
3949
|
+
}
|
|
3950
|
+
function base64UrlEncodeUtf82(input) {
|
|
3951
|
+
const bytes = new TextEncoder().encode(input);
|
|
3952
|
+
let binary = "";
|
|
3953
|
+
for (const byte of bytes) binary += String.fromCharCode(byte);
|
|
3954
|
+
const base64 = typeof btoa === "function" ? btoa(binary) : typeof Buffer !== "undefined" ? Buffer.from(bytes).toString("base64") : void 0;
|
|
3955
|
+
if (!base64) throw new Error("base64 encoder unavailable");
|
|
3956
|
+
return base64.replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, "");
|
|
3957
|
+
}
|
|
3958
|
+
function base64UrlDecodeUtf82(input) {
|
|
3959
|
+
const base64 = input.replace(/-/g, "+").replace(/_/g, "/");
|
|
3960
|
+
const padded = base64.padEnd(
|
|
3961
|
+
base64.length + (4 - base64.length % 4) % 4,
|
|
3962
|
+
"="
|
|
3963
|
+
);
|
|
3964
|
+
if (typeof atob === "function") {
|
|
3965
|
+
const binary = atob(padded);
|
|
3966
|
+
const bytes = new Uint8Array(binary.length);
|
|
3967
|
+
for (let index = 0; index < binary.length; index++) {
|
|
3968
|
+
bytes[index] = binary.charCodeAt(index);
|
|
3969
|
+
}
|
|
3970
|
+
return new TextDecoder().decode(bytes);
|
|
3971
|
+
}
|
|
3972
|
+
if (typeof Buffer !== "undefined") {
|
|
3973
|
+
return Buffer.from(padded, "base64").toString("utf8");
|
|
3974
|
+
}
|
|
3975
|
+
throw new Error("base64 decoder unavailable");
|
|
3976
|
+
}
|
|
3977
|
+
|
|
3829
3978
|
// src/me-offline/sms.ts
|
|
3830
3979
|
var import_nist3 = require("@noble/curves/nist");
|
|
3831
3980
|
var OFFLINE_CLAIM_SMS_PREFIX = "FLURC1.";
|
|
3832
3981
|
var CLAIM_TOKEN_RE = /(?:^|\s)(FLURC1\.[A-Za-z0-9_-]+={0,2})(?:\s|$)/;
|
|
3833
3982
|
function encodeOfflineClaimSmsMessage(claim) {
|
|
3834
3983
|
const parsed = ConsumerPaymentClaimSchema.parse(claim);
|
|
3835
|
-
return `${OFFLINE_CLAIM_SMS_PREFIX}${
|
|
3984
|
+
return `${OFFLINE_CLAIM_SMS_PREFIX}${base64UrlEncodeUtf83(
|
|
3836
3985
|
JSON.stringify(parsed)
|
|
3837
3986
|
)}`;
|
|
3838
3987
|
}
|
|
@@ -3842,7 +3991,7 @@ function decodeOfflineClaimSmsMessage(message) {
|
|
|
3842
3991
|
const encoded = token.slice(OFFLINE_CLAIM_SMS_PREFIX.length);
|
|
3843
3992
|
let raw;
|
|
3844
3993
|
try {
|
|
3845
|
-
raw = JSON.parse(
|
|
3994
|
+
raw = JSON.parse(base64UrlDecodeUtf83(encoded));
|
|
3846
3995
|
} catch {
|
|
3847
3996
|
throw new Error("offline claim QR token is malformed");
|
|
3848
3997
|
}
|
|
@@ -4068,10 +4217,10 @@ function bytesToBase64Url(bytes) {
|
|
|
4068
4217
|
}
|
|
4069
4218
|
return base64.replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, "");
|
|
4070
4219
|
}
|
|
4071
|
-
function
|
|
4220
|
+
function base64UrlEncodeUtf83(input) {
|
|
4072
4221
|
return bytesToBase64Url(utf8(input));
|
|
4073
4222
|
}
|
|
4074
|
-
function
|
|
4223
|
+
function base64UrlDecodeUtf83(input) {
|
|
4075
4224
|
return new TextDecoder().decode(base64UrlToBytes(input));
|
|
4076
4225
|
}
|
|
4077
4226
|
function base64UrlToBytes(input) {
|
|
@@ -4093,14 +4242,14 @@ function base64UrlToBytes(input) {
|
|
|
4093
4242
|
}
|
|
4094
4243
|
|
|
4095
4244
|
// src/partner-funding/client.ts
|
|
4096
|
-
var
|
|
4097
|
-
var MinorString =
|
|
4098
|
-
var PositiveMinor =
|
|
4099
|
-
|
|
4100
|
-
|
|
4245
|
+
var import_zod16 = require("zod");
|
|
4246
|
+
var MinorString = import_zod16.z.string().regex(/^-?\d+$/);
|
|
4247
|
+
var PositiveMinor = import_zod16.z.union([
|
|
4248
|
+
import_zod16.z.number().int().positive(),
|
|
4249
|
+
import_zod16.z.string().regex(/^[1-9]\d{0,18}$/)
|
|
4101
4250
|
]);
|
|
4102
|
-
var Currency =
|
|
4103
|
-
var Metadata =
|
|
4251
|
+
var Currency = import_zod16.z.string().trim().length(3).transform((v) => v.toUpperCase());
|
|
4252
|
+
var Metadata = import_zod16.z.record(import_zod16.z.unknown());
|
|
4104
4253
|
var PARTNER_KINDS = ["bank", "merchant"];
|
|
4105
4254
|
var CUSTODIAL_MODES = ["agent_of_bank", "flur_virtual_pool"];
|
|
4106
4255
|
var PARTNER_PROFILE_STATUSES = [
|
|
@@ -4127,126 +4276,126 @@ var WITHDRAWAL_STATES = [
|
|
|
4127
4276
|
"failed",
|
|
4128
4277
|
"reversed"
|
|
4129
4278
|
];
|
|
4130
|
-
var PartnerProfileSchema =
|
|
4131
|
-
partnerAccountId:
|
|
4132
|
-
kind:
|
|
4133
|
-
custodialMode:
|
|
4134
|
-
displayName:
|
|
4135
|
-
bankCode:
|
|
4136
|
-
poolAccountNumber:
|
|
4137
|
-
status:
|
|
4279
|
+
var PartnerProfileSchema = import_zod16.z.object({
|
|
4280
|
+
partnerAccountId: import_zod16.z.string().uuid(),
|
|
4281
|
+
kind: import_zod16.z.enum(PARTNER_KINDS),
|
|
4282
|
+
custodialMode: import_zod16.z.enum(CUSTODIAL_MODES),
|
|
4283
|
+
displayName: import_zod16.z.string(),
|
|
4284
|
+
bankCode: import_zod16.z.string().nullable(),
|
|
4285
|
+
poolAccountNumber: import_zod16.z.string().nullable(),
|
|
4286
|
+
status: import_zod16.z.enum(PARTNER_PROFILE_STATUSES),
|
|
4138
4287
|
metadata: Metadata,
|
|
4139
|
-
createdAtMs:
|
|
4140
|
-
updatedAtMs:
|
|
4288
|
+
createdAtMs: import_zod16.z.number().int().nonnegative(),
|
|
4289
|
+
updatedAtMs: import_zod16.z.number().int().nonnegative()
|
|
4141
4290
|
});
|
|
4142
|
-
var UpsertPartnerProfileInputSchema =
|
|
4143
|
-
kind:
|
|
4144
|
-
custodialMode:
|
|
4145
|
-
displayName:
|
|
4146
|
-
bankCode:
|
|
4147
|
-
poolAccountNumber:
|
|
4291
|
+
var UpsertPartnerProfileInputSchema = import_zod16.z.object({
|
|
4292
|
+
kind: import_zod16.z.enum(PARTNER_KINDS),
|
|
4293
|
+
custodialMode: import_zod16.z.enum(CUSTODIAL_MODES),
|
|
4294
|
+
displayName: import_zod16.z.string().trim().min(1).max(200),
|
|
4295
|
+
bankCode: import_zod16.z.string().trim().min(1).max(64).optional(),
|
|
4296
|
+
poolAccountNumber: import_zod16.z.string().trim().min(1).max(64).optional(),
|
|
4148
4297
|
metadata: Metadata.optional()
|
|
4149
4298
|
});
|
|
4150
|
-
var PartnerFundingEventInputSchema =
|
|
4151
|
-
externalRef:
|
|
4152
|
-
direction:
|
|
4153
|
-
userId:
|
|
4154
|
-
accountId:
|
|
4299
|
+
var PartnerFundingEventInputSchema = import_zod16.z.object({
|
|
4300
|
+
externalRef: import_zod16.z.string().trim().min(8).max(128),
|
|
4301
|
+
direction: import_zod16.z.enum(PARTNER_FUNDING_DIRECTIONS).optional(),
|
|
4302
|
+
userId: import_zod16.z.string().uuid().optional(),
|
|
4303
|
+
accountId: import_zod16.z.string().uuid().optional(),
|
|
4155
4304
|
amountMinor: PositiveMinor,
|
|
4156
4305
|
currency: Currency,
|
|
4157
|
-
fundingSource:
|
|
4306
|
+
fundingSource: import_zod16.z.string().trim().min(1).max(64).optional(),
|
|
4158
4307
|
providerMetadata: Metadata.optional()
|
|
4159
4308
|
});
|
|
4160
|
-
var PartnerFundingSchema =
|
|
4161
|
-
fundingId:
|
|
4162
|
-
partnerId:
|
|
4163
|
-
accountId:
|
|
4164
|
-
userId:
|
|
4165
|
-
direction:
|
|
4166
|
-
currency:
|
|
4309
|
+
var PartnerFundingSchema = import_zod16.z.object({
|
|
4310
|
+
fundingId: import_zod16.z.string().uuid(),
|
|
4311
|
+
partnerId: import_zod16.z.string().uuid(),
|
|
4312
|
+
accountId: import_zod16.z.string().uuid(),
|
|
4313
|
+
userId: import_zod16.z.string().uuid().nullable(),
|
|
4314
|
+
direction: import_zod16.z.enum(PARTNER_FUNDING_DIRECTIONS),
|
|
4315
|
+
currency: import_zod16.z.string(),
|
|
4167
4316
|
amountMinor: MinorString,
|
|
4168
|
-
externalRef:
|
|
4169
|
-
status:
|
|
4170
|
-
fundingSource:
|
|
4171
|
-
ledgerRef:
|
|
4317
|
+
externalRef: import_zod16.z.string(),
|
|
4318
|
+
status: import_zod16.z.enum(PARTNER_FUNDING_STATUSES),
|
|
4319
|
+
fundingSource: import_zod16.z.string(),
|
|
4320
|
+
ledgerRef: import_zod16.z.string(),
|
|
4172
4321
|
providerMetadata: Metadata,
|
|
4173
|
-
createdAtMs:
|
|
4174
|
-
updatedAtMs:
|
|
4322
|
+
createdAtMs: import_zod16.z.number().int().nonnegative(),
|
|
4323
|
+
updatedAtMs: import_zod16.z.number().int().nonnegative()
|
|
4175
4324
|
});
|
|
4176
|
-
var IngestFundingResultSchema =
|
|
4325
|
+
var IngestFundingResultSchema = import_zod16.z.object({
|
|
4177
4326
|
funding: PartnerFundingSchema,
|
|
4178
|
-
replayed:
|
|
4327
|
+
replayed: import_zod16.z.boolean()
|
|
4179
4328
|
});
|
|
4180
|
-
var PayoutDestinationSchema =
|
|
4181
|
-
destinationId:
|
|
4182
|
-
accountId:
|
|
4183
|
-
partnerId:
|
|
4184
|
-
bankCode:
|
|
4185
|
-
accountNumber:
|
|
4186
|
-
accountName:
|
|
4187
|
-
status:
|
|
4188
|
-
verifiedAtMs:
|
|
4329
|
+
var PayoutDestinationSchema = import_zod16.z.object({
|
|
4330
|
+
destinationId: import_zod16.z.string().uuid(),
|
|
4331
|
+
accountId: import_zod16.z.string().uuid(),
|
|
4332
|
+
partnerId: import_zod16.z.string().uuid(),
|
|
4333
|
+
bankCode: import_zod16.z.string(),
|
|
4334
|
+
accountNumber: import_zod16.z.string(),
|
|
4335
|
+
accountName: import_zod16.z.string(),
|
|
4336
|
+
status: import_zod16.z.enum(PAYOUT_DESTINATION_STATUSES),
|
|
4337
|
+
verifiedAtMs: import_zod16.z.number().int().nonnegative().nullable(),
|
|
4189
4338
|
metadata: Metadata,
|
|
4190
|
-
createdAtMs:
|
|
4191
|
-
updatedAtMs:
|
|
4339
|
+
createdAtMs: import_zod16.z.number().int().nonnegative(),
|
|
4340
|
+
updatedAtMs: import_zod16.z.number().int().nonnegative()
|
|
4192
4341
|
});
|
|
4193
|
-
var CreatePayoutDestinationInputSchema =
|
|
4194
|
-
partnerId:
|
|
4195
|
-
bankCode:
|
|
4196
|
-
accountNumber:
|
|
4197
|
-
accountName:
|
|
4342
|
+
var CreatePayoutDestinationInputSchema = import_zod16.z.object({
|
|
4343
|
+
partnerId: import_zod16.z.string().uuid(),
|
|
4344
|
+
bankCode: import_zod16.z.string().trim().min(1).max(32),
|
|
4345
|
+
accountNumber: import_zod16.z.string().trim().min(4).max(64),
|
|
4346
|
+
accountName: import_zod16.z.string().trim().min(1).max(200),
|
|
4198
4347
|
metadata: Metadata.optional()
|
|
4199
4348
|
});
|
|
4200
|
-
var ListPayoutDestinationsResultSchema =
|
|
4201
|
-
items:
|
|
4349
|
+
var ListPayoutDestinationsResultSchema = import_zod16.z.object({
|
|
4350
|
+
items: import_zod16.z.array(PayoutDestinationSchema)
|
|
4202
4351
|
});
|
|
4203
|
-
var WithdrawalSchema =
|
|
4204
|
-
withdrawalId:
|
|
4205
|
-
accountId:
|
|
4206
|
-
userId:
|
|
4207
|
-
partnerId:
|
|
4208
|
-
destinationId:
|
|
4209
|
-
currency:
|
|
4352
|
+
var WithdrawalSchema = import_zod16.z.object({
|
|
4353
|
+
withdrawalId: import_zod16.z.string().uuid(),
|
|
4354
|
+
accountId: import_zod16.z.string().uuid(),
|
|
4355
|
+
userId: import_zod16.z.string().uuid(),
|
|
4356
|
+
partnerId: import_zod16.z.string().uuid(),
|
|
4357
|
+
destinationId: import_zod16.z.string().uuid(),
|
|
4358
|
+
currency: import_zod16.z.string(),
|
|
4210
4359
|
amountMinor: MinorString,
|
|
4211
|
-
state:
|
|
4212
|
-
idempotencyKey:
|
|
4213
|
-
providerRef:
|
|
4214
|
-
lastError:
|
|
4215
|
-
ledgerRef:
|
|
4216
|
-
reverseLedgerRef:
|
|
4360
|
+
state: import_zod16.z.enum(WITHDRAWAL_STATES),
|
|
4361
|
+
idempotencyKey: import_zod16.z.string(),
|
|
4362
|
+
providerRef: import_zod16.z.string().nullable(),
|
|
4363
|
+
lastError: import_zod16.z.string().nullable(),
|
|
4364
|
+
ledgerRef: import_zod16.z.string(),
|
|
4365
|
+
reverseLedgerRef: import_zod16.z.string().nullable(),
|
|
4217
4366
|
metadata: Metadata,
|
|
4218
|
-
createdAtMs:
|
|
4219
|
-
updatedAtMs:
|
|
4367
|
+
createdAtMs: import_zod16.z.number().int().nonnegative(),
|
|
4368
|
+
updatedAtMs: import_zod16.z.number().int().nonnegative()
|
|
4220
4369
|
});
|
|
4221
|
-
var CreateWithdrawalInputSchema =
|
|
4222
|
-
destinationId:
|
|
4370
|
+
var CreateWithdrawalInputSchema = import_zod16.z.object({
|
|
4371
|
+
destinationId: import_zod16.z.string().uuid(),
|
|
4223
4372
|
amountMinor: PositiveMinor,
|
|
4224
4373
|
currency: Currency,
|
|
4225
|
-
idempotencyKey:
|
|
4374
|
+
idempotencyKey: import_zod16.z.string().trim().min(8).max(128),
|
|
4226
4375
|
metadata: Metadata.optional()
|
|
4227
4376
|
});
|
|
4228
|
-
var CreateWithdrawalResultSchema =
|
|
4377
|
+
var CreateWithdrawalResultSchema = import_zod16.z.object({
|
|
4229
4378
|
withdrawal: WithdrawalSchema,
|
|
4230
|
-
replayed:
|
|
4379
|
+
replayed: import_zod16.z.boolean()
|
|
4231
4380
|
});
|
|
4232
|
-
var PayoutEventInputSchema =
|
|
4233
|
-
externalRef:
|
|
4234
|
-
withdrawalId:
|
|
4235
|
-
state:
|
|
4236
|
-
providerRef:
|
|
4237
|
-
failureCode:
|
|
4238
|
-
failureMessage:
|
|
4381
|
+
var PayoutEventInputSchema = import_zod16.z.object({
|
|
4382
|
+
externalRef: import_zod16.z.string().trim().min(8).max(128),
|
|
4383
|
+
withdrawalId: import_zod16.z.string().uuid().optional(),
|
|
4384
|
+
state: import_zod16.z.enum(["submitted", "processing", "paid", "failed"]),
|
|
4385
|
+
providerRef: import_zod16.z.string().trim().min(1).max(128).optional(),
|
|
4386
|
+
failureCode: import_zod16.z.string().trim().max(64).optional(),
|
|
4387
|
+
failureMessage: import_zod16.z.string().trim().max(512).optional(),
|
|
4239
4388
|
providerMetadata: Metadata.optional()
|
|
4240
4389
|
});
|
|
4241
|
-
var RecordPayoutEventResultSchema =
|
|
4390
|
+
var RecordPayoutEventResultSchema = import_zod16.z.object({
|
|
4242
4391
|
withdrawal: WithdrawalSchema,
|
|
4243
|
-
replayed:
|
|
4392
|
+
replayed: import_zod16.z.boolean()
|
|
4244
4393
|
});
|
|
4245
|
-
var ReconciliationReportSchema =
|
|
4246
|
-
partnerId:
|
|
4247
|
-
currency:
|
|
4248
|
-
fromMs:
|
|
4249
|
-
toMs:
|
|
4394
|
+
var ReconciliationReportSchema = import_zod16.z.object({
|
|
4395
|
+
partnerId: import_zod16.z.string().uuid(),
|
|
4396
|
+
currency: import_zod16.z.string(),
|
|
4397
|
+
fromMs: import_zod16.z.number().int().nonnegative(),
|
|
4398
|
+
toMs: import_zod16.z.number().int().nonnegative(),
|
|
4250
4399
|
fundingsCreditMinor: MinorString,
|
|
4251
4400
|
fundingsDebitMinor: MinorString,
|
|
4252
4401
|
withdrawalsPaidMinor: MinorString,
|
|
@@ -4255,7 +4404,7 @@ var ReconciliationReportSchema = import_zod15.z.object({
|
|
|
4255
4404
|
expectedReserveBalanceMinor: MinorString,
|
|
4256
4405
|
actualReserveBalanceMinor: MinorString,
|
|
4257
4406
|
imbalanceMinor: MinorString,
|
|
4258
|
-
generatedAtMs:
|
|
4407
|
+
generatedAtMs: import_zod16.z.number().int().nonnegative()
|
|
4259
4408
|
});
|
|
4260
4409
|
function createPartnerFundingClient(partner) {
|
|
4261
4410
|
return {
|
|
@@ -4407,19 +4556,19 @@ function createPartnerProfileAdminClient(opts) {
|
|
|
4407
4556
|
}
|
|
4408
4557
|
|
|
4409
4558
|
// src/artifacts/envelope.ts
|
|
4410
|
-
var
|
|
4559
|
+
var import_zod17 = require("zod");
|
|
4411
4560
|
var FLUR_ARTIFACT_URI_SCHEME = "flur";
|
|
4412
4561
|
var FLUR_ARTIFACT_VERSION = 1;
|
|
4413
4562
|
var FLUR_ARTIFACT_URI_PREFIX = `${FLUR_ARTIFACT_URI_SCHEME}://v${FLUR_ARTIFACT_VERSION}/`;
|
|
4414
4563
|
var ArtifactTypeRe = /^[a-z][a-z0-9_]{1,63}$/;
|
|
4415
|
-
var ArtifactHeaderSchema =
|
|
4416
|
-
v:
|
|
4417
|
-
t:
|
|
4418
|
-
iss:
|
|
4419
|
-
kid:
|
|
4420
|
-
iat:
|
|
4421
|
-
exp:
|
|
4422
|
-
nonce:
|
|
4564
|
+
var ArtifactHeaderSchema = import_zod17.z.object({
|
|
4565
|
+
v: import_zod17.z.literal(FLUR_ARTIFACT_VERSION),
|
|
4566
|
+
t: import_zod17.z.string().regex(ArtifactTypeRe, "invalid artifact type"),
|
|
4567
|
+
iss: import_zod17.z.string().min(1).max(128),
|
|
4568
|
+
kid: import_zod17.z.string().min(1).max(128),
|
|
4569
|
+
iat: import_zod17.z.number().int().nonnegative(),
|
|
4570
|
+
exp: import_zod17.z.number().int().positive().optional(),
|
|
4571
|
+
nonce: import_zod17.z.string().min(8).max(64).regex(/^[A-Za-z0-9_-]+$/, "nonce must be url-safe")
|
|
4423
4572
|
});
|
|
4424
4573
|
var FlurArtifactError = class extends Error {
|
|
4425
4574
|
constructor(message, code) {
|
|
@@ -4558,7 +4707,7 @@ function verifyArtifactSignature(decoded, publicKeySpkiB64, options = {}) {
|
|
|
4558
4707
|
}
|
|
4559
4708
|
|
|
4560
4709
|
// src/artifacts/types.ts
|
|
4561
|
-
var
|
|
4710
|
+
var import_zod18 = require("zod");
|
|
4562
4711
|
var ARTIFACT_TYPES = {
|
|
4563
4712
|
OFFLINE_PAYMENT_AUTHORIZATION: "offline_payment_authorization",
|
|
4564
4713
|
RECEIPT: "receipt",
|
|
@@ -4571,37 +4720,34 @@ var ARTIFACT_TYPES = {
|
|
|
4571
4720
|
LEDGER_JOURNAL_ENTRY: "ledger_journal_entry",
|
|
4572
4721
|
STATEMENT: "statement",
|
|
4573
4722
|
PASS: "pass",
|
|
4574
|
-
IDENTITY: "identity"
|
|
4575
|
-
// Tier B: holder-signed identity attestation for offline trust. The
|
|
4576
|
-
// envelope.iat / envelope.exp express the card's canonical lifetime.
|
|
4577
|
-
PAY_CARD: "pay_card"
|
|
4723
|
+
IDENTITY: "identity"
|
|
4578
4724
|
};
|
|
4579
|
-
var HexString = (length) =>
|
|
4725
|
+
var HexString = (length) => import_zod18.z.string().regex(
|
|
4580
4726
|
new RegExp(`^[0-9a-fA-F]{${length * 2}}$`),
|
|
4581
4727
|
`expected ${length}-byte hex string`
|
|
4582
4728
|
);
|
|
4583
|
-
var OfflinePaymentAuthorizationArtifactSchema =
|
|
4729
|
+
var OfflinePaymentAuthorizationArtifactSchema = import_zod18.z.object({
|
|
4584
4730
|
authorization: OfflinePaymentAuthorizationSchema
|
|
4585
4731
|
});
|
|
4586
|
-
var ReceiptArtifactSchema =
|
|
4587
|
-
receiptId:
|
|
4588
|
-
paymentReference:
|
|
4589
|
-
payerUserId:
|
|
4590
|
-
payeeUserId:
|
|
4591
|
-
amountKobo:
|
|
4592
|
-
currency:
|
|
4593
|
-
channel:
|
|
4594
|
-
settledAtMs:
|
|
4595
|
-
ledgerTxnId:
|
|
4596
|
-
memo:
|
|
4732
|
+
var ReceiptArtifactSchema = import_zod18.z.object({
|
|
4733
|
+
receiptId: import_zod18.z.string().min(1).max(64),
|
|
4734
|
+
paymentReference: import_zod18.z.string().min(1).max(64),
|
|
4735
|
+
payerUserId: import_zod18.z.string().min(1).max(64).optional(),
|
|
4736
|
+
payeeUserId: import_zod18.z.string().min(1).max(64),
|
|
4737
|
+
amountKobo: import_zod18.z.number().int().positive(),
|
|
4738
|
+
currency: import_zod18.z.literal("NGN"),
|
|
4739
|
+
channel: import_zod18.z.enum(["online", "offline_reconciled", "pay_link", "nqr"]),
|
|
4740
|
+
settledAtMs: import_zod18.z.number().int().positive(),
|
|
4741
|
+
ledgerTxnId: import_zod18.z.string().min(1).max(64).optional(),
|
|
4742
|
+
memo: import_zod18.z.string().max(140).optional(),
|
|
4597
4743
|
hashChainPrev: HexString(32).optional()
|
|
4598
4744
|
});
|
|
4599
|
-
var ShortId =
|
|
4600
|
-
var PositiveInt =
|
|
4601
|
-
var NonNegativeInt =
|
|
4602
|
-
var Currency2 =
|
|
4603
|
-
var Memo =
|
|
4604
|
-
var NqrPaymentRequestArtifactSchema =
|
|
4745
|
+
var ShortId = import_zod18.z.string().min(1).max(64);
|
|
4746
|
+
var PositiveInt = import_zod18.z.number().int().positive();
|
|
4747
|
+
var NonNegativeInt = import_zod18.z.number().int().nonnegative();
|
|
4748
|
+
var Currency2 = import_zod18.z.literal("NGN");
|
|
4749
|
+
var Memo = import_zod18.z.string().max(140);
|
|
4750
|
+
var NqrPaymentRequestArtifactSchema = import_zod18.z.object({
|
|
4605
4751
|
requestId: ShortId,
|
|
4606
4752
|
payeeUserId: ShortId,
|
|
4607
4753
|
amountKobo: PositiveInt.optional(),
|
|
@@ -4609,7 +4755,7 @@ var NqrPaymentRequestArtifactSchema = import_zod17.z.object({
|
|
|
4609
4755
|
memo: Memo.optional(),
|
|
4610
4756
|
expiresAtMs: PositiveInt.optional()
|
|
4611
4757
|
});
|
|
4612
|
-
var PaymentIntentArtifactSchema =
|
|
4758
|
+
var PaymentIntentArtifactSchema = import_zod18.z.object({
|
|
4613
4759
|
intentId: ShortId,
|
|
4614
4760
|
payerUserId: ShortId,
|
|
4615
4761
|
payeeUserId: ShortId,
|
|
@@ -4618,7 +4764,7 @@ var PaymentIntentArtifactSchema = import_zod17.z.object({
|
|
|
4618
4764
|
idempotencyKey: ShortId,
|
|
4619
4765
|
createdAtMs: PositiveInt
|
|
4620
4766
|
});
|
|
4621
|
-
var OfflineClaimArtifactSchema =
|
|
4767
|
+
var OfflineClaimArtifactSchema = import_zod18.z.object({
|
|
4622
4768
|
claimId: ShortId,
|
|
4623
4769
|
authorizationId: ShortId,
|
|
4624
4770
|
payeeUserId: ShortId,
|
|
@@ -4627,10 +4773,10 @@ var OfflineClaimArtifactSchema = import_zod17.z.object({
|
|
|
4627
4773
|
claimedAtMs: PositiveInt,
|
|
4628
4774
|
paymentReference: ShortId.optional()
|
|
4629
4775
|
});
|
|
4630
|
-
var SettlementRecordArtifactSchema =
|
|
4776
|
+
var SettlementRecordArtifactSchema = import_zod18.z.object({
|
|
4631
4777
|
settlementId: ShortId,
|
|
4632
4778
|
ledgerTxnId: ShortId,
|
|
4633
|
-
sourceRefType:
|
|
4779
|
+
sourceRefType: import_zod18.z.enum([
|
|
4634
4780
|
"offline_authorization",
|
|
4635
4781
|
"offline_claim",
|
|
4636
4782
|
"transfer",
|
|
@@ -4641,12 +4787,12 @@ var SettlementRecordArtifactSchema = import_zod17.z.object({
|
|
|
4641
4787
|
currency: Currency2,
|
|
4642
4788
|
settledAtMs: PositiveInt
|
|
4643
4789
|
});
|
|
4644
|
-
var ReversalRecordArtifactSchema =
|
|
4790
|
+
var ReversalRecordArtifactSchema = import_zod18.z.object({
|
|
4645
4791
|
reversalId: ShortId,
|
|
4646
4792
|
originalTxnId: ShortId,
|
|
4647
4793
|
amountKobo: PositiveInt,
|
|
4648
4794
|
currency: Currency2,
|
|
4649
|
-
reason:
|
|
4795
|
+
reason: import_zod18.z.enum([
|
|
4650
4796
|
"user_dispute",
|
|
4651
4797
|
"fraud",
|
|
4652
4798
|
"duplicate",
|
|
@@ -4656,7 +4802,7 @@ var ReversalRecordArtifactSchema = import_zod17.z.object({
|
|
|
4656
4802
|
reversedAtMs: PositiveInt,
|
|
4657
4803
|
memo: Memo.optional()
|
|
4658
4804
|
});
|
|
4659
|
-
var LedgerJournalEntryArtifactSchema =
|
|
4805
|
+
var LedgerJournalEntryArtifactSchema = import_zod18.z.object({
|
|
4660
4806
|
entryId: ShortId,
|
|
4661
4807
|
journalId: ShortId,
|
|
4662
4808
|
debitAccountId: ShortId,
|
|
@@ -4667,13 +4813,13 @@ var LedgerJournalEntryArtifactSchema = import_zod17.z.object({
|
|
|
4667
4813
|
refType: ShortId.optional(),
|
|
4668
4814
|
refId: ShortId.optional()
|
|
4669
4815
|
});
|
|
4670
|
-
var StatementArtifactSchema =
|
|
4816
|
+
var StatementArtifactSchema = import_zod18.z.object({
|
|
4671
4817
|
statementId: ShortId,
|
|
4672
4818
|
userId: ShortId,
|
|
4673
4819
|
periodStartMs: PositiveInt,
|
|
4674
4820
|
periodEndMs: PositiveInt,
|
|
4675
|
-
openingBalanceKobo:
|
|
4676
|
-
closingBalanceKobo:
|
|
4821
|
+
openingBalanceKobo: import_zod18.z.number().int(),
|
|
4822
|
+
closingBalanceKobo: import_zod18.z.number().int(),
|
|
4677
4823
|
transactionCount: NonNegativeInt,
|
|
4678
4824
|
currency: Currency2,
|
|
4679
4825
|
hashChainPrev: HexString(32).optional()
|
|
@@ -4681,16 +4827,16 @@ var StatementArtifactSchema = import_zod17.z.object({
|
|
|
4681
4827
|
message: "periodEndMs must be greater than periodStartMs",
|
|
4682
4828
|
path: ["periodEndMs"]
|
|
4683
4829
|
});
|
|
4684
|
-
var PassArtifactSchema =
|
|
4830
|
+
var PassArtifactSchema = import_zod18.z.object({
|
|
4685
4831
|
passId: ShortId,
|
|
4686
4832
|
holderId: ShortId,
|
|
4687
|
-
category:
|
|
4688
|
-
title:
|
|
4833
|
+
category: import_zod18.z.enum(["membership", "ticket", "loyalty", "access", "voucher"]),
|
|
4834
|
+
title: import_zod18.z.string().min(1).max(120),
|
|
4689
4835
|
validFromMs: PositiveInt,
|
|
4690
4836
|
validUntilMs: PositiveInt.optional(),
|
|
4691
|
-
metadata:
|
|
4692
|
-
|
|
4693
|
-
|
|
4837
|
+
metadata: import_zod18.z.record(
|
|
4838
|
+
import_zod18.z.string().min(1).max(64),
|
|
4839
|
+
import_zod18.z.union([import_zod18.z.string().max(280), import_zod18.z.number(), import_zod18.z.boolean()])
|
|
4694
4840
|
).optional()
|
|
4695
4841
|
}).refine(
|
|
4696
4842
|
(v) => v.validUntilMs === void 0 || v.validUntilMs > v.validFromMs,
|
|
@@ -4699,10 +4845,10 @@ var PassArtifactSchema = import_zod17.z.object({
|
|
|
4699
4845
|
path: ["validUntilMs"]
|
|
4700
4846
|
}
|
|
4701
4847
|
);
|
|
4702
|
-
var IdentityArtifactSchema =
|
|
4848
|
+
var IdentityArtifactSchema = import_zod18.z.object({
|
|
4703
4849
|
attestationId: ShortId,
|
|
4704
4850
|
subjectId: ShortId,
|
|
4705
|
-
claimType:
|
|
4851
|
+
claimType: import_zod18.z.enum([
|
|
4706
4852
|
"phone_verified",
|
|
4707
4853
|
"email_verified",
|
|
4708
4854
|
"bvn_verified",
|
|
@@ -4712,12 +4858,6 @@ var IdentityArtifactSchema = import_zod17.z.object({
|
|
|
4712
4858
|
claimValueHash: HexString(32),
|
|
4713
4859
|
attestedAtMs: PositiveInt
|
|
4714
4860
|
});
|
|
4715
|
-
var PayCardArtifactSchema = import_zod17.z.object({
|
|
4716
|
-
userId: ShortId,
|
|
4717
|
-
phoneE164: import_zod17.z.string().regex(/^\+[1-9]\d{7,14}$/, "phoneE164 must be normalised E.164"),
|
|
4718
|
-
displayName: import_zod17.z.string().min(1).max(64),
|
|
4719
|
-
devicePubKeySpkiB64: import_zod17.z.string().min(64).max(256).regex(/^[A-Za-z0-9+/]+=*$/, "devicePubKeySpkiB64 must be standard base64")
|
|
4720
|
-
});
|
|
4721
4861
|
var ARTIFACT_BODY_SCHEMAS = {
|
|
4722
4862
|
[ARTIFACT_TYPES.OFFLINE_PAYMENT_AUTHORIZATION]: OfflinePaymentAuthorizationArtifactSchema,
|
|
4723
4863
|
[ARTIFACT_TYPES.RECEIPT]: ReceiptArtifactSchema,
|
|
@@ -4729,8 +4869,7 @@ var ARTIFACT_BODY_SCHEMAS = {
|
|
|
4729
4869
|
[ARTIFACT_TYPES.LEDGER_JOURNAL_ENTRY]: LedgerJournalEntryArtifactSchema,
|
|
4730
4870
|
[ARTIFACT_TYPES.STATEMENT]: StatementArtifactSchema,
|
|
4731
4871
|
[ARTIFACT_TYPES.PASS]: PassArtifactSchema,
|
|
4732
|
-
[ARTIFACT_TYPES.IDENTITY]: IdentityArtifactSchema
|
|
4733
|
-
[ARTIFACT_TYPES.PAY_CARD]: PayCardArtifactSchema
|
|
4872
|
+
[ARTIFACT_TYPES.IDENTITY]: IdentityArtifactSchema
|
|
4734
4873
|
};
|
|
4735
4874
|
var HARDENED_ARTIFACT_TYPES = /* @__PURE__ */ new Set([
|
|
4736
4875
|
ARTIFACT_TYPES.OFFLINE_PAYMENT_AUTHORIZATION,
|
|
@@ -4743,8 +4882,7 @@ var HARDENED_ARTIFACT_TYPES = /* @__PURE__ */ new Set([
|
|
|
4743
4882
|
ARTIFACT_TYPES.LEDGER_JOURNAL_ENTRY,
|
|
4744
4883
|
ARTIFACT_TYPES.STATEMENT,
|
|
4745
4884
|
ARTIFACT_TYPES.PASS,
|
|
4746
|
-
ARTIFACT_TYPES.IDENTITY
|
|
4747
|
-
ARTIFACT_TYPES.PAY_CARD
|
|
4885
|
+
ARTIFACT_TYPES.IDENTITY
|
|
4748
4886
|
]);
|
|
4749
4887
|
function isKnownArtifactType(t) {
|
|
4750
4888
|
return Object.values(ARTIFACT_TYPES).includes(t);
|
|
@@ -4829,130 +4967,6 @@ function createOfflinePaymentAuthorizationArtifactUri(input) {
|
|
|
4829
4967
|
type: ARTIFACT_TYPES.OFFLINE_PAYMENT_AUTHORIZATION
|
|
4830
4968
|
});
|
|
4831
4969
|
}
|
|
4832
|
-
|
|
4833
|
-
// src/artifacts/paycard.ts
|
|
4834
|
-
var PAY_CARD_DEFAULT_TTL_MS = 90 * 24 * 60 * 60 * 1e3;
|
|
4835
|
-
var PAY_CARD_REFRESH_THRESHOLD_MS = 30 * 24 * 60 * 60 * 1e3;
|
|
4836
|
-
var PAY_CARD_URI_PREFIX = `${FLUR_ARTIFACT_URI_PREFIX}${ARTIFACT_TYPES.PAY_CARD}/`;
|
|
4837
|
-
function createPayCardArtifactUri(input) {
|
|
4838
|
-
if (input.data.userId !== input.issuer) {
|
|
4839
|
-
throw new FlurArtifactError(
|
|
4840
|
-
"pay_card.data.userId must equal envelope issuer",
|
|
4841
|
-
"INVALID_BODY"
|
|
4842
|
-
);
|
|
4843
|
-
}
|
|
4844
|
-
const iat = input.issuedAtSeconds ?? Math.floor(Date.now() / 1e3);
|
|
4845
|
-
const exp = input.expiresAtSeconds ?? iat + Math.floor(PAY_CARD_DEFAULT_TTL_MS / 1e3);
|
|
4846
|
-
return createArtifactUri({
|
|
4847
|
-
type: ARTIFACT_TYPES.PAY_CARD,
|
|
4848
|
-
issuer: input.issuer,
|
|
4849
|
-
keyId: input.keyId,
|
|
4850
|
-
privateKey: input.privateKey,
|
|
4851
|
-
nonce: input.nonce,
|
|
4852
|
-
issuedAtSeconds: iat,
|
|
4853
|
-
expiresAtSeconds: exp,
|
|
4854
|
-
data: input.data
|
|
4855
|
-
});
|
|
4856
|
-
}
|
|
4857
|
-
function isPayCardArtifactUri(uri) {
|
|
4858
|
-
return typeof uri === "string" && uri.startsWith(PAY_CARD_URI_PREFIX);
|
|
4859
|
-
}
|
|
4860
|
-
function decodePayCardArtifact(uri) {
|
|
4861
|
-
if (!isPayCardArtifactUri(uri)) {
|
|
4862
|
-
throw new FlurArtifactError(
|
|
4863
|
-
`URI does not start with ${PAY_CARD_URI_PREFIX}`,
|
|
4864
|
-
"INVALID_URI"
|
|
4865
|
-
);
|
|
4866
|
-
}
|
|
4867
|
-
const decoded = decodeArtifactUri(uri);
|
|
4868
|
-
if (decoded.type !== ARTIFACT_TYPES.PAY_CARD) {
|
|
4869
|
-
throw new FlurArtifactError(
|
|
4870
|
-
`Expected pay_card, got ${decoded.type}`,
|
|
4871
|
-
"TYPE_MISMATCH"
|
|
4872
|
-
);
|
|
4873
|
-
}
|
|
4874
|
-
const parsed = PayCardArtifactSchema.safeParse(decoded.body.data);
|
|
4875
|
-
if (!parsed.success) {
|
|
4876
|
-
throw new FlurArtifactError(
|
|
4877
|
-
`pay_card body invalid: ${parsed.error.message}`,
|
|
4878
|
-
"INVALID_BODY"
|
|
4879
|
-
);
|
|
4880
|
-
}
|
|
4881
|
-
if (parsed.data.userId !== decoded.body.iss) {
|
|
4882
|
-
throw new FlurArtifactError(
|
|
4883
|
-
"pay_card.data.userId must equal envelope issuer",
|
|
4884
|
-
"INVALID_BODY"
|
|
4885
|
-
);
|
|
4886
|
-
}
|
|
4887
|
-
return {
|
|
4888
|
-
body: {
|
|
4889
|
-
...decoded.body,
|
|
4890
|
-
data: parsed.data
|
|
4891
|
-
},
|
|
4892
|
-
sig: decoded.sig,
|
|
4893
|
-
decoded
|
|
4894
|
-
};
|
|
4895
|
-
}
|
|
4896
|
-
function verifyPayCardArtifact(uri, publicKeySpkiB64, options = {}) {
|
|
4897
|
-
if (!isPayCardArtifactUri(uri)) {
|
|
4898
|
-
throw new FlurArtifactError(
|
|
4899
|
-
`URI does not start with ${PAY_CARD_URI_PREFIX}`,
|
|
4900
|
-
"INVALID_URI"
|
|
4901
|
-
);
|
|
4902
|
-
}
|
|
4903
|
-
const verified = verifyArtifactUri(
|
|
4904
|
-
uri,
|
|
4905
|
-
publicKeySpkiB64,
|
|
4906
|
-
options
|
|
4907
|
-
);
|
|
4908
|
-
if (verified.decoded.type !== ARTIFACT_TYPES.PAY_CARD) {
|
|
4909
|
-
throw new FlurArtifactError(
|
|
4910
|
-
`Expected pay_card, got ${verified.decoded.type}`,
|
|
4911
|
-
"TYPE_MISMATCH"
|
|
4912
|
-
);
|
|
4913
|
-
}
|
|
4914
|
-
if (verified.body.data.userId !== verified.body.iss) {
|
|
4915
|
-
throw new FlurArtifactError(
|
|
4916
|
-
"pay_card.data.userId must equal envelope issuer",
|
|
4917
|
-
"INVALID_BODY"
|
|
4918
|
-
);
|
|
4919
|
-
}
|
|
4920
|
-
return {
|
|
4921
|
-
body: verified.body,
|
|
4922
|
-
sig: verified.sig,
|
|
4923
|
-
decoded: verified.decoded
|
|
4924
|
-
};
|
|
4925
|
-
}
|
|
4926
|
-
function inspectPayCardFreshness(decoded, nowMs = Date.now()) {
|
|
4927
|
-
const exp = decoded.body.exp;
|
|
4928
|
-
if (exp === void 0) return "no_expiry";
|
|
4929
|
-
const remainingMs = exp * 1e3 - nowMs;
|
|
4930
|
-
if (remainingMs <= 0) return "expired";
|
|
4931
|
-
if (remainingMs <= PAY_CARD_REFRESH_THRESHOLD_MS)
|
|
4932
|
-
return "refresh_recommended";
|
|
4933
|
-
return "fresh";
|
|
4934
|
-
}
|
|
4935
|
-
function buildPayCardSigningInput(input) {
|
|
4936
|
-
if (input.data.userId !== input.issuer) {
|
|
4937
|
-
throw new FlurArtifactError(
|
|
4938
|
-
"pay_card.data.userId must equal envelope issuer",
|
|
4939
|
-
"INVALID_BODY"
|
|
4940
|
-
);
|
|
4941
|
-
}
|
|
4942
|
-
const parsedData = PayCardArtifactSchema.parse(input.data);
|
|
4943
|
-
const iat = input.issuedAtSeconds ?? Math.floor(Date.now() / 1e3);
|
|
4944
|
-
const exp = input.expiresAtSeconds ?? iat + Math.floor(PAY_CARD_DEFAULT_TTL_MS / 1e3);
|
|
4945
|
-
const body = buildArtifactBody({
|
|
4946
|
-
type: ARTIFACT_TYPES.PAY_CARD,
|
|
4947
|
-
issuer: input.issuer,
|
|
4948
|
-
keyId: input.keyId,
|
|
4949
|
-
data: parsedData,
|
|
4950
|
-
nonce: input.nonce,
|
|
4951
|
-
issuedAtSeconds: iat,
|
|
4952
|
-
expiresAtSeconds: exp
|
|
4953
|
-
});
|
|
4954
|
-
return { body, bodyBytes: canonicalJSONBytes(body) };
|
|
4955
|
-
}
|
|
4956
4970
|
// Annotate the CommonJS export names for ESM import in node:
|
|
4957
4971
|
0 && (module.exports = {
|
|
4958
4972
|
ACCOUNT_FUNDED_OAC_MAX_TTL_MS,
|
|
@@ -4969,6 +4983,8 @@ function buildPayCardSigningInput(input) {
|
|
|
4969
4983
|
CLAIM_DOMAIN_V2,
|
|
4970
4984
|
COLLECTION_INTENT_STATUSES,
|
|
4971
4985
|
COLLECTION_PAYMENT_STATUSES,
|
|
4986
|
+
CONSUMER_OAC_DOMAIN,
|
|
4987
|
+
CONSUMER_OAC_QR_PREFIX,
|
|
4972
4988
|
CONSUMER_OFFLINE_CLAIM_SUBMIT_GRACE_MS,
|
|
4973
4989
|
CONSUMER_PAYMENT_REQUEST_DOMAIN,
|
|
4974
4990
|
CONSUMER_SETTLEMENT_DOMAIN,
|
|
@@ -5007,6 +5023,8 @@ function buildPayCardSigningInput(input) {
|
|
|
5007
5023
|
IdentityArtifactSchema,
|
|
5008
5024
|
IngestFundingResultSchema,
|
|
5009
5025
|
IssueAccountOacInputSchema,
|
|
5026
|
+
IssuerTrustBundleSchema,
|
|
5027
|
+
IssuerTrustKeySchema,
|
|
5010
5028
|
LedgerJournalEntryArtifactSchema,
|
|
5011
5029
|
ListPayoutDestinationsResultSchema,
|
|
5012
5030
|
MEMBERSHIP_ROLES,
|
|
@@ -5030,6 +5048,7 @@ function buildPayCardSigningInput(input) {
|
|
|
5030
5048
|
OFFLINE_SMS_SETTLE_SIGNATURE_BYTES,
|
|
5031
5049
|
OFFLINE_SMS_SETTLE_TOKEN_BYTES,
|
|
5032
5050
|
OFFLINE_SMS_SETTLE_VERSION,
|
|
5051
|
+
OacPresentmentRequestSchema,
|
|
5033
5052
|
OfflineClaimArtifactSchema,
|
|
5034
5053
|
OfflinePaymentAuthorizationArtifactSchema,
|
|
5035
5054
|
OfflinePaymentAuthorizationSchema,
|
|
@@ -5047,9 +5066,6 @@ function buildPayCardSigningInput(input) {
|
|
|
5047
5066
|
PASS_STATES,
|
|
5048
5067
|
PAYLOAD_FORMAT_INDICATOR_VALUE,
|
|
5049
5068
|
PAYOUT_DESTINATION_STATUSES,
|
|
5050
|
-
PAY_CARD_DEFAULT_TTL_MS,
|
|
5051
|
-
PAY_CARD_REFRESH_THRESHOLD_MS,
|
|
5052
|
-
PAY_CARD_URI_PREFIX,
|
|
5053
5069
|
POINT_OF_INITIATION,
|
|
5054
5070
|
PartnerFundingEventInputSchema,
|
|
5055
5071
|
PartnerFundingSchema,
|
|
@@ -5057,7 +5073,6 @@ function buildPayCardSigningInput(input) {
|
|
|
5057
5073
|
PassArtifactSchema,
|
|
5058
5074
|
PassMetadataSchema,
|
|
5059
5075
|
PassSchema,
|
|
5060
|
-
PayCardArtifactSchema,
|
|
5061
5076
|
PayCollectionInputSchema,
|
|
5062
5077
|
PaymentClaimSchema,
|
|
5063
5078
|
PaymentIntentArtifactSchema,
|
|
@@ -5096,7 +5111,6 @@ function buildPayCardSigningInput(input) {
|
|
|
5096
5111
|
buildConsumerPaymentRequest,
|
|
5097
5112
|
buildOAC,
|
|
5098
5113
|
buildPass,
|
|
5099
|
-
buildPayCardSigningInput,
|
|
5100
5114
|
buildPaymentRequest,
|
|
5101
5115
|
buildReceipt,
|
|
5102
5116
|
buildRedemption,
|
|
@@ -5110,6 +5124,7 @@ function buildPayCardSigningInput(input) {
|
|
|
5110
5124
|
computeConsumerClaimEncounterId,
|
|
5111
5125
|
computeEncounterId,
|
|
5112
5126
|
constantTimeEqual,
|
|
5127
|
+
consumerOacSigningPayload,
|
|
5113
5128
|
consumerPaymentRequestSigningBytes,
|
|
5114
5129
|
consumerPaymentRequestSigningPayload,
|
|
5115
5130
|
consumerSettlementSigningPayload,
|
|
@@ -5130,23 +5145,24 @@ function buildPayCardSigningInput(input) {
|
|
|
5130
5145
|
createPartnerFundingClient,
|
|
5131
5146
|
createPartnerProfileAdminClient,
|
|
5132
5147
|
createPassesClient,
|
|
5133
|
-
createPayCardArtifactUri,
|
|
5134
5148
|
createReceiptArtifactUri,
|
|
5135
5149
|
createReceiptsClient,
|
|
5136
5150
|
createSoftwareP256Signer,
|
|
5137
5151
|
decodeArtifactUri,
|
|
5138
5152
|
decodeAuthorizationQR,
|
|
5139
5153
|
decodeBase45,
|
|
5154
|
+
decodeConsumerOacRequest,
|
|
5140
5155
|
decodeConsumerSettlementReceiptQR,
|
|
5141
5156
|
decodeOfflineClaimSmsMessage,
|
|
5142
5157
|
decodeOfflineSmsSettleToken,
|
|
5143
|
-
decodePayCardArtifact,
|
|
5144
5158
|
decodePaymentRequestQR,
|
|
5159
|
+
decodeUnverifiedConsumerOacQR,
|
|
5145
5160
|
decodeUnverifiedConsumerSettlementReceiptQR,
|
|
5146
5161
|
derToRawP256Signature,
|
|
5147
5162
|
encodeArtifactUri,
|
|
5148
5163
|
encodeAuthorizationQR,
|
|
5149
5164
|
encodeBase45,
|
|
5165
|
+
encodeConsumerOacQR,
|
|
5150
5166
|
encodeConsumerSettlementReceiptQR,
|
|
5151
5167
|
encodeNQR,
|
|
5152
5168
|
encodeOfflineClaimSmsMessage,
|
|
@@ -5158,12 +5174,11 @@ function buildPayCardSigningInput(input) {
|
|
|
5158
5174
|
generateDynamicQR,
|
|
5159
5175
|
generateStaticQR,
|
|
5160
5176
|
init,
|
|
5161
|
-
|
|
5177
|
+
isConsumerOacQR,
|
|
5162
5178
|
isConsumerPaymentRequestExpired,
|
|
5163
5179
|
isHardenedArtifactType,
|
|
5164
5180
|
isKnownArtifactType,
|
|
5165
5181
|
isPassWithinValidity,
|
|
5166
|
-
isPayCardArtifactUri,
|
|
5167
5182
|
moneyMinorToNumber,
|
|
5168
5183
|
normalizeE164,
|
|
5169
5184
|
parseAmountInput,
|
|
@@ -5189,9 +5204,9 @@ function buildPayCardSigningInput(input) {
|
|
|
5189
5204
|
verifyConsumerSettlement,
|
|
5190
5205
|
verifyConsumerSettlementReceiptQR,
|
|
5191
5206
|
verifyOAC,
|
|
5207
|
+
verifyOacOffline,
|
|
5192
5208
|
verifyOfflineSmsSettleToken,
|
|
5193
5209
|
verifyPass,
|
|
5194
|
-
verifyPayCardArtifact,
|
|
5195
5210
|
verifyPaymentRequest,
|
|
5196
5211
|
verifyReceipt,
|
|
5197
5212
|
verifyRedemption,
|