@nokinc-flur/sdk 2.4.0 → 2.5.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 +363 -274
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +355 -181
- package/dist/index.d.ts +355 -181
- package/dist/index.js +356 -274
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -48,6 +48,7 @@ __export(index_exports, {
|
|
|
48
48
|
CONSUMER_OAC_QR_PREFIX: () => CONSUMER_OAC_QR_PREFIX,
|
|
49
49
|
CONSUMER_OFFLINE_CLAIM_SUBMIT_GRACE_MS: () => CONSUMER_OFFLINE_CLAIM_SUBMIT_GRACE_MS,
|
|
50
50
|
CONSUMER_PAYMENT_REQUEST_DOMAIN: () => CONSUMER_PAYMENT_REQUEST_DOMAIN,
|
|
51
|
+
CONSUMER_REVOCATION_DOMAIN: () => CONSUMER_REVOCATION_DOMAIN,
|
|
51
52
|
CONSUMER_SETTLEMENT_DOMAIN: () => CONSUMER_SETTLEMENT_DOMAIN,
|
|
52
53
|
CONSUMER_SETTLEMENT_RECEIPT_QR_PREFIX: () => CONSUMER_SETTLEMENT_RECEIPT_QR_PREFIX,
|
|
53
54
|
CUSTODIAL_MODES: () => CUSTODIAL_MODES,
|
|
@@ -145,6 +146,7 @@ __export(index_exports, {
|
|
|
145
146
|
RECEIPT_CHANNELS: () => RECEIPT_CHANNELS,
|
|
146
147
|
RECEIPT_KINDS: () => RECEIPT_KINDS,
|
|
147
148
|
REPLAY_WINDOW_MS: () => REPLAY_WINDOW_MS,
|
|
149
|
+
REVOCATION_LIST_MAX_ENTRIES: () => REVOCATION_LIST_MAX_ENTRIES,
|
|
148
150
|
ReceiptArtifactSchema: () => ReceiptArtifactSchema,
|
|
149
151
|
ReceiptPayloadSchema: () => ReceiptPayloadSchema,
|
|
150
152
|
ReceiptSchema: () => ReceiptSchema,
|
|
@@ -153,12 +155,14 @@ __export(index_exports, {
|
|
|
153
155
|
RedemptionSchema: () => RedemptionSchema,
|
|
154
156
|
RegisterDeviceKeyP256InputSchema: () => RegisterDeviceKeyP256InputSchema,
|
|
155
157
|
ReversalRecordArtifactSchema: () => ReversalRecordArtifactSchema,
|
|
158
|
+
RevocationListSchema: () => RevocationListSchema,
|
|
156
159
|
RevokeDeviceKeyInputSchema: () => RevokeDeviceKeyInputSchema,
|
|
157
160
|
SETTLEMENT_SCHEDULES: () => SETTLEMENT_SCHEDULES,
|
|
158
161
|
SettleResponseSchema: () => SettleResponseSchema,
|
|
159
162
|
SettlementRecordArtifactSchema: () => SettlementRecordArtifactSchema,
|
|
160
163
|
SettlementSchema: () => SettlementSchema,
|
|
161
164
|
SignedConsumerOACSchema: () => SignedConsumerOACSchema,
|
|
165
|
+
SignedRevocationListSchema: () => SignedRevocationListSchema,
|
|
162
166
|
StatementArtifactSchema: () => StatementArtifactSchema,
|
|
163
167
|
UpsertMerchantProfileInputSchema: () => UpsertMerchantProfileInputSchema,
|
|
164
168
|
UpsertPartnerProfileInputSchema: () => UpsertPartnerProfileInputSchema,
|
|
@@ -239,6 +243,7 @@ __export(index_exports, {
|
|
|
239
243
|
isConsumerPaymentRequestExpired: () => isConsumerPaymentRequestExpired,
|
|
240
244
|
isHardenedArtifactType: () => isHardenedArtifactType,
|
|
241
245
|
isKnownArtifactType: () => isKnownArtifactType,
|
|
246
|
+
isOacRevoked: () => isOacRevoked,
|
|
242
247
|
isPassWithinValidity: () => isPassWithinValidity,
|
|
243
248
|
moneyMinorToNumber: () => moneyMinorToNumber,
|
|
244
249
|
normalizeE164: () => normalizeE164,
|
|
@@ -246,6 +251,7 @@ __export(index_exports, {
|
|
|
246
251
|
parseNQR: () => parseNQR,
|
|
247
252
|
parseQR: () => parseQR,
|
|
248
253
|
readTLV: () => readTLV,
|
|
254
|
+
revocationListSigningPayload: () => revocationListSigningPayload,
|
|
249
255
|
routingHint: () => routingHint,
|
|
250
256
|
signArtifact: () => signArtifact,
|
|
251
257
|
signAuthorization: () => signAuthorization,
|
|
@@ -272,6 +278,7 @@ __export(index_exports, {
|
|
|
272
278
|
verifyReceipt: () => verifyReceipt,
|
|
273
279
|
verifyRedemption: () => verifyRedemption,
|
|
274
280
|
verifyRequestHMAC: () => verifyRequestHMAC,
|
|
281
|
+
verifyRevocationList: () => verifyRevocationList,
|
|
275
282
|
writeTLV: () => writeTLV
|
|
276
283
|
});
|
|
277
284
|
module.exports = __toCommonJS(index_exports);
|
|
@@ -3233,76 +3240,142 @@ function createAccountsClient(opts) {
|
|
|
3233
3240
|
}
|
|
3234
3241
|
|
|
3235
3242
|
// src/me-offline/client.ts
|
|
3243
|
+
var import_zod14 = require("zod");
|
|
3244
|
+
|
|
3245
|
+
// src/me-offline/revocation.ts
|
|
3236
3246
|
var import_zod13 = require("zod");
|
|
3237
|
-
var Sha256Hex = import_zod13.z.string().regex(/^[0-9a-f]{64}$/);
|
|
3238
3247
|
var Base64Std3 = import_zod13.z.string().regex(/^[A-Za-z0-9+/]+={0,2}$/);
|
|
3239
|
-
var
|
|
3248
|
+
var CONSUMER_REVOCATION_DOMAIN = "flur:consumer-offline:v1:revocation";
|
|
3249
|
+
var REVOCATION_LIST_MAX_ENTRIES = 1e5;
|
|
3250
|
+
var RevocationListSchema = import_zod13.z.object({
|
|
3251
|
+
issuerId: import_zod13.z.string().min(1).max(64),
|
|
3252
|
+
/**
|
|
3253
|
+
* Monotonic snapshot counter. A device MUST NOT replace a pinned list with
|
|
3254
|
+
* one carrying a lower sequence — this defeats a downgrade/rollback attack
|
|
3255
|
+
* that replays an older list to resurrect a revoked credential.
|
|
3256
|
+
*/
|
|
3257
|
+
sequence: import_zod13.z.number().int().nonnegative(),
|
|
3258
|
+
issuedAtMs: import_zod13.z.number().int().nonnegative(),
|
|
3259
|
+
/**
|
|
3260
|
+
* Freshness bound. After this instant the list is considered stale and the
|
|
3261
|
+
* verifier treats it as untrustworthy (fail-closed), forcing a re-pin.
|
|
3262
|
+
* Optional so the issuer may publish a list without a hard expiry.
|
|
3263
|
+
*/
|
|
3264
|
+
notAfterMs: import_zod13.z.number().int().positive().optional(),
|
|
3265
|
+
/** OAC ids that are revoked AND not yet past their own validity window. */
|
|
3266
|
+
revokedOacIds: import_zod13.z.array(import_zod13.z.string().uuid()).max(REVOCATION_LIST_MAX_ENTRIES)
|
|
3267
|
+
});
|
|
3268
|
+
var SignedRevocationListSchema = import_zod13.z.object({
|
|
3269
|
+
list: RevocationListSchema,
|
|
3270
|
+
/** ASN.1 DER ECDSA P-256 issuer signature over the signing payload, base64. */
|
|
3271
|
+
issuerSig: Base64Std3.min(16).max(2048),
|
|
3272
|
+
/** Issuer's P-256 public key as SubjectPublicKeyInfo DER, base64. */
|
|
3273
|
+
issuerPublicKeySpkiB64: Base64Std3.min(64).max(4096)
|
|
3274
|
+
});
|
|
3275
|
+
function revocationListSigningPayload(list) {
|
|
3276
|
+
const payload = {
|
|
3277
|
+
domain: CONSUMER_REVOCATION_DOMAIN,
|
|
3278
|
+
issuerId: list.issuerId,
|
|
3279
|
+
sequence: list.sequence,
|
|
3280
|
+
issuedAtMs: list.issuedAtMs,
|
|
3281
|
+
revokedOacIds: list.revokedOacIds
|
|
3282
|
+
};
|
|
3283
|
+
if (list.notAfterMs !== void 0) payload.notAfterMs = list.notAfterMs;
|
|
3284
|
+
return payload;
|
|
3285
|
+
}
|
|
3286
|
+
function verifyRevocationList(signed, trustedKeys, options = {}) {
|
|
3287
|
+
const parsed = SignedRevocationListSchema.safeParse(signed);
|
|
3288
|
+
if (!parsed.success) return { ok: false, reason: "malformed" };
|
|
3289
|
+
const list = parsed.data.list;
|
|
3290
|
+
const nowMs = options.nowMs ?? Date.now();
|
|
3291
|
+
const pinned = trustedKeys.filter(
|
|
3292
|
+
(k) => k.issuerId === list.issuerId && (k.notBeforeMs === void 0 || nowMs >= k.notBeforeMs) && (k.notAfterMs === void 0 || nowMs <= k.notAfterMs)
|
|
3293
|
+
);
|
|
3294
|
+
if (pinned.length === 0) return { ok: false, reason: "untrusted_issuer" };
|
|
3295
|
+
const signingBytes = canonicalJSONBytes(revocationListSigningPayload(list));
|
|
3296
|
+
const signatureOk = pinned.some(
|
|
3297
|
+
(k) => verifyIssuerP256(signingBytes, parsed.data.issuerSig, k.publicKeySpkiB64)
|
|
3298
|
+
);
|
|
3299
|
+
if (!signatureOk) return { ok: false, reason: "signature_invalid" };
|
|
3300
|
+
if (list.notAfterMs !== void 0 && nowMs > list.notAfterMs) {
|
|
3301
|
+
return { ok: false, reason: "stale" };
|
|
3302
|
+
}
|
|
3303
|
+
return { ok: true, list, revokedOacIds: new Set(list.revokedOacIds) };
|
|
3304
|
+
}
|
|
3305
|
+
function isOacRevoked(oacId, revokedOacIds) {
|
|
3306
|
+
return revokedOacIds.has(oacId);
|
|
3307
|
+
}
|
|
3308
|
+
|
|
3309
|
+
// src/me-offline/client.ts
|
|
3310
|
+
var Sha256Hex = import_zod14.z.string().regex(/^[0-9a-f]{64}$/);
|
|
3311
|
+
var Base64Std4 = import_zod14.z.string().regex(/^[A-Za-z0-9+/]+={0,2}$/);
|
|
3312
|
+
var ClaimNonce = import_zod14.z.string().min(8).max(128).refine((value) => !value.includes("|"), {
|
|
3240
3313
|
message: "nonce must not contain |"
|
|
3241
3314
|
});
|
|
3242
3315
|
var ACCOUNT_FUNDED_OAC_MAX_TTL_MS = 1e3 * 60 * 60 * 24;
|
|
3243
|
-
var IssuerTrustKeySchema =
|
|
3244
|
-
issuerId:
|
|
3245
|
-
alg:
|
|
3246
|
-
publicKeySpkiB64:
|
|
3247
|
-
notBeforeMs:
|
|
3248
|
-
notAfterMs:
|
|
3316
|
+
var IssuerTrustKeySchema = import_zod14.z.object({
|
|
3317
|
+
issuerId: import_zod14.z.string().min(1).max(128),
|
|
3318
|
+
alg: import_zod14.z.literal("p256"),
|
|
3319
|
+
publicKeySpkiB64: Base64Std4.min(64).max(4096),
|
|
3320
|
+
notBeforeMs: import_zod14.z.number().int().nonnegative().optional(),
|
|
3321
|
+
notAfterMs: import_zod14.z.number().int().positive().optional()
|
|
3249
3322
|
});
|
|
3250
|
-
var IssuerTrustBundleSchema =
|
|
3251
|
-
keys:
|
|
3323
|
+
var IssuerTrustBundleSchema = import_zod14.z.object({
|
|
3324
|
+
keys: import_zod14.z.array(IssuerTrustKeySchema).min(1)
|
|
3252
3325
|
});
|
|
3253
3326
|
var CONSUMER_OFFLINE_CLAIM_SUBMIT_GRACE_MS = 1e3 * 60 * 60 * 24;
|
|
3254
|
-
var AttestationSecurityLevelSchema =
|
|
3327
|
+
var AttestationSecurityLevelSchema = import_zod14.z.enum([
|
|
3255
3328
|
"STRONGBOX",
|
|
3256
3329
|
"TEE",
|
|
3257
3330
|
"SECURE_ENCLAVE",
|
|
3258
3331
|
"SOFTWARE"
|
|
3259
3332
|
]);
|
|
3260
|
-
var DeviceKeyAlgSchema =
|
|
3261
|
-
var RegisterDeviceKeyP256InputSchema =
|
|
3262
|
-
deviceId:
|
|
3333
|
+
var DeviceKeyAlgSchema = import_zod14.z.literal("p256");
|
|
3334
|
+
var RegisterDeviceKeyP256InputSchema = import_zod14.z.object({
|
|
3335
|
+
deviceId: import_zod14.z.string().min(1).max(128),
|
|
3263
3336
|
/** P-256 SubjectPublicKeyInfo DER, base64. */
|
|
3264
|
-
publicKeySpkiB64:
|
|
3337
|
+
publicKeySpkiB64: Base64Std4.min(64).max(4096),
|
|
3265
3338
|
/** Base64 of the server-issued enrollment challenge string. */
|
|
3266
|
-
challengeB64:
|
|
3339
|
+
challengeB64: Base64Std4.min(8).max(1024),
|
|
3267
3340
|
/** iOS App Attest payload or Android X.509 Key Attestation chain. */
|
|
3268
|
-
attestationChainB64:
|
|
3341
|
+
attestationChainB64: import_zod14.z.array(Base64Std4.min(16).max(16384)).min(1).max(16),
|
|
3269
3342
|
securityLevel: AttestationSecurityLevelSchema
|
|
3270
3343
|
});
|
|
3271
|
-
var P256EnrollmentChallengeInputSchema =
|
|
3272
|
-
deviceId:
|
|
3344
|
+
var P256EnrollmentChallengeInputSchema = import_zod14.z.object({
|
|
3345
|
+
deviceId: import_zod14.z.string().min(1).max(128)
|
|
3273
3346
|
});
|
|
3274
|
-
var P256EnrollmentChallengeResultSchema =
|
|
3275
|
-
challenge:
|
|
3276
|
-
expiresAtMs:
|
|
3347
|
+
var P256EnrollmentChallengeResultSchema = import_zod14.z.object({
|
|
3348
|
+
challenge: import_zod14.z.string().min(16),
|
|
3349
|
+
expiresAtMs: import_zod14.z.number().int().positive()
|
|
3277
3350
|
});
|
|
3278
|
-
var DeviceKeyRecordSchema =
|
|
3279
|
-
id:
|
|
3280
|
-
userId:
|
|
3281
|
-
deviceId:
|
|
3351
|
+
var DeviceKeyRecordSchema = import_zod14.z.object({
|
|
3352
|
+
id: import_zod14.z.string().uuid(),
|
|
3353
|
+
userId: import_zod14.z.string().uuid(),
|
|
3354
|
+
deviceId: import_zod14.z.string(),
|
|
3282
3355
|
/** Always 'p256' on the consumer offline rail. Field retained for forward-compat. */
|
|
3283
3356
|
alg: DeviceKeyAlgSchema.default("p256"),
|
|
3284
3357
|
/** P-256 SubjectPublicKeyInfo DER, base64. */
|
|
3285
|
-
publicKeySpkiB64:
|
|
3358
|
+
publicKeySpkiB64: Base64Std4.nullable().default(null),
|
|
3286
3359
|
securityLevel: AttestationSecurityLevelSchema.nullable().default(null),
|
|
3287
|
-
hardwareBacked:
|
|
3288
|
-
attestedAtMs:
|
|
3289
|
-
createdAtMs:
|
|
3290
|
-
revokedAtMs:
|
|
3360
|
+
hardwareBacked: import_zod14.z.boolean().default(false),
|
|
3361
|
+
attestedAtMs: import_zod14.z.number().int().nonnegative().nullable().default(null),
|
|
3362
|
+
createdAtMs: import_zod14.z.number().int().nonnegative(),
|
|
3363
|
+
revokedAtMs: import_zod14.z.number().int().nonnegative().nullable()
|
|
3291
3364
|
});
|
|
3292
|
-
var ConsumerOACSchema =
|
|
3293
|
-
oacId:
|
|
3294
|
-
issuerId:
|
|
3295
|
-
userId:
|
|
3296
|
-
deviceId:
|
|
3365
|
+
var ConsumerOACSchema = import_zod14.z.object({
|
|
3366
|
+
oacId: import_zod14.z.string().uuid(),
|
|
3367
|
+
issuerId: import_zod14.z.string().min(1).max(64),
|
|
3368
|
+
userId: import_zod14.z.string().uuid(),
|
|
3369
|
+
deviceId: import_zod14.z.string().min(1).max(128),
|
|
3297
3370
|
/**
|
|
3298
3371
|
* Always 'p256'. Required on the wire (backend always emits it).
|
|
3299
3372
|
* Kept as a literal so input/output infer identically and the schema
|
|
3300
3373
|
* can be nested inside other response shapes without Zod input/output
|
|
3301
3374
|
* divergence under tsup DTS bundling.
|
|
3302
3375
|
*/
|
|
3303
|
-
alg:
|
|
3376
|
+
alg: import_zod14.z.literal("p256"),
|
|
3304
3377
|
/** P-256 SubjectPublicKeyInfo DER, base64. */
|
|
3305
|
-
devicePubkeySpkiB64:
|
|
3378
|
+
devicePubkeySpkiB64: Base64Std4.min(64).max(4096),
|
|
3306
3379
|
/**
|
|
3307
3380
|
* Per-transaction / cumulative offline spend ceilings. Zero is valid and
|
|
3308
3381
|
* denotes an identity-only OAC: the credential proves who the holder is and
|
|
@@ -3310,104 +3383,104 @@ var ConsumerOACSchema = import_zod13.z.object({
|
|
|
3310
3383
|
* no offline spend authority (every claim against it routes to REVIEW).
|
|
3311
3384
|
* Issued to zero-balance wallets so they can still be paid offline.
|
|
3312
3385
|
*/
|
|
3313
|
-
perTxCapKobo:
|
|
3314
|
-
cumulativeCapKobo:
|
|
3315
|
-
currency:
|
|
3316
|
-
validFromMs:
|
|
3317
|
-
validUntilMs:
|
|
3318
|
-
counterSeed:
|
|
3319
|
-
issuedAtMs:
|
|
3386
|
+
perTxCapKobo: import_zod14.z.number().int().nonnegative(),
|
|
3387
|
+
cumulativeCapKobo: import_zod14.z.number().int().nonnegative(),
|
|
3388
|
+
currency: import_zod14.z.string().length(3),
|
|
3389
|
+
validFromMs: import_zod14.z.number().int().nonnegative(),
|
|
3390
|
+
validUntilMs: import_zod14.z.number().int().nonnegative(),
|
|
3391
|
+
counterSeed: import_zod14.z.number().int().nonnegative(),
|
|
3392
|
+
issuedAtMs: import_zod14.z.number().int().nonnegative(),
|
|
3320
3393
|
/**
|
|
3321
3394
|
* Issuer-attested identity folded into the OAC so a single signed
|
|
3322
3395
|
* credential serves both Tier B offline-verifiable identity and offline
|
|
3323
3396
|
* spend authority. Verified offline against a pinned issuer key; the
|
|
3324
3397
|
* backend remains authoritative at settlement.
|
|
3325
3398
|
*/
|
|
3326
|
-
phoneE164:
|
|
3327
|
-
displayName:
|
|
3399
|
+
phoneE164: import_zod14.z.string().regex(/^\+[1-9]\d{7,14}$/),
|
|
3400
|
+
displayName: import_zod14.z.string().min(1).max(64)
|
|
3328
3401
|
});
|
|
3329
|
-
var SignedConsumerOACSchema =
|
|
3402
|
+
var SignedConsumerOACSchema = import_zod14.z.object({
|
|
3330
3403
|
oac: ConsumerOACSchema,
|
|
3331
3404
|
/** ASN.1 DER ECDSA P-256 issuer signature, base64. */
|
|
3332
|
-
issuerSig:
|
|
3405
|
+
issuerSig: Base64Std4.min(16).max(2048),
|
|
3333
3406
|
/** Issuer's P-256 public key as SubjectPublicKeyInfo DER, base64. */
|
|
3334
|
-
issuerPublicKeySpkiB64:
|
|
3407
|
+
issuerPublicKeySpkiB64: Base64Std4.min(64).max(4096)
|
|
3335
3408
|
});
|
|
3336
3409
|
var OACRecordSchema = SignedConsumerOACSchema.extend({
|
|
3337
|
-
currentOfflineSpentKobo:
|
|
3338
|
-
status:
|
|
3339
|
-
supersededAtMs:
|
|
3340
|
-
revokedAtMs:
|
|
3410
|
+
currentOfflineSpentKobo: import_zod14.z.number().int().nonnegative(),
|
|
3411
|
+
status: import_zod14.z.enum(["active", "superseded", "expired", "revoked"]),
|
|
3412
|
+
supersededAtMs: import_zod14.z.number().int().nonnegative().nullable(),
|
|
3413
|
+
revokedAtMs: import_zod14.z.number().int().nonnegative().nullable()
|
|
3341
3414
|
});
|
|
3342
|
-
var IssueAccountOacInputSchema =
|
|
3343
|
-
deviceId:
|
|
3344
|
-
perTxCapKobo:
|
|
3345
|
-
cumulativeCapKobo:
|
|
3346
|
-
ttlMs:
|
|
3415
|
+
var IssueAccountOacInputSchema = import_zod14.z.object({
|
|
3416
|
+
deviceId: import_zod14.z.string().min(1).max(128),
|
|
3417
|
+
perTxCapKobo: import_zod14.z.number().int().positive().optional(),
|
|
3418
|
+
cumulativeCapKobo: import_zod14.z.number().int().positive().optional(),
|
|
3419
|
+
ttlMs: import_zod14.z.number().int().min(6e4).max(ACCOUNT_FUNDED_OAC_MAX_TTL_MS).optional()
|
|
3347
3420
|
});
|
|
3348
|
-
var OfflineStatusResultSchema =
|
|
3421
|
+
var OfflineStatusResultSchema = import_zod14.z.object({
|
|
3349
3422
|
active: OACRecordSchema.nullable()
|
|
3350
3423
|
});
|
|
3351
|
-
var ConsumerPaymentClaimSchema =
|
|
3424
|
+
var ConsumerPaymentClaimSchema = import_zod14.z.object({
|
|
3352
3425
|
/** Always 'p256'. Retained for forward-compat and as an explicit domain marker. */
|
|
3353
|
-
alg:
|
|
3354
|
-
oacId:
|
|
3426
|
+
alg: import_zod14.z.literal("p256").default("p256"),
|
|
3427
|
+
oacId: import_zod14.z.string().uuid(),
|
|
3355
3428
|
encounterId: Sha256Hex.optional(),
|
|
3356
|
-
payerUserId:
|
|
3357
|
-
payeeUserId:
|
|
3358
|
-
payerDeviceId:
|
|
3429
|
+
payerUserId: import_zod14.z.string().uuid(),
|
|
3430
|
+
payeeUserId: import_zod14.z.string().uuid(),
|
|
3431
|
+
payerDeviceId: import_zod14.z.string().min(1).max(128),
|
|
3359
3432
|
payerNonce: ClaimNonce,
|
|
3360
3433
|
payeeNonce: ClaimNonce,
|
|
3361
|
-
amountKobo:
|
|
3362
|
-
currency:
|
|
3363
|
-
occurredAtMs:
|
|
3364
|
-
completedAtMs:
|
|
3365
|
-
contextId:
|
|
3366
|
-
requestId:
|
|
3367
|
-
requestMode:
|
|
3368
|
-
requestTakerUserId:
|
|
3369
|
-
requestAmountKobo:
|
|
3370
|
-
requestCurrency:
|
|
3371
|
-
requestReference:
|
|
3372
|
-
requestCreatedAtMs:
|
|
3373
|
-
requestExpiresAtMs:
|
|
3374
|
-
requestNonce:
|
|
3375
|
-
requestTakerDeviceId:
|
|
3376
|
-
requestTakerPubkeySpkiB64:
|
|
3377
|
-
requestTakerSignatureDerB64:
|
|
3378
|
-
payerPubkeySpkiB64:
|
|
3379
|
-
payerSignatureDerB64:
|
|
3380
|
-
payeePubkeySpkiB64:
|
|
3381
|
-
payeeSignatureDerB64:
|
|
3434
|
+
amountKobo: import_zod14.z.number().int().positive(),
|
|
3435
|
+
currency: import_zod14.z.string().length(3).default("NGN"),
|
|
3436
|
+
occurredAtMs: import_zod14.z.number().int().nonnegative(),
|
|
3437
|
+
completedAtMs: import_zod14.z.number().int().nonnegative().optional(),
|
|
3438
|
+
contextId: import_zod14.z.string().max(128).optional(),
|
|
3439
|
+
requestId: import_zod14.z.string().uuid().optional(),
|
|
3440
|
+
requestMode: import_zod14.z.enum(["fixed", "editable"]).optional(),
|
|
3441
|
+
requestTakerUserId: import_zod14.z.string().uuid().optional(),
|
|
3442
|
+
requestAmountKobo: import_zod14.z.number().int().positive().optional(),
|
|
3443
|
+
requestCurrency: import_zod14.z.string().length(3).optional(),
|
|
3444
|
+
requestReference: import_zod14.z.string().max(128).nullable().optional(),
|
|
3445
|
+
requestCreatedAtMs: import_zod14.z.number().int().nonnegative().optional(),
|
|
3446
|
+
requestExpiresAtMs: import_zod14.z.number().int().positive().optional(),
|
|
3447
|
+
requestNonce: import_zod14.z.string().min(8).max(128).optional(),
|
|
3448
|
+
requestTakerDeviceId: import_zod14.z.string().min(1).max(128).nullable().optional(),
|
|
3449
|
+
requestTakerPubkeySpkiB64: Base64Std4.min(64).max(4096).optional(),
|
|
3450
|
+
requestTakerSignatureDerB64: Base64Std4.min(16).max(2048).optional(),
|
|
3451
|
+
payerPubkeySpkiB64: Base64Std4.min(64).max(4096),
|
|
3452
|
+
payerSignatureDerB64: Base64Std4.min(16).max(2048),
|
|
3453
|
+
payeePubkeySpkiB64: Base64Std4.min(64).max(4096).optional(),
|
|
3454
|
+
payeeSignatureDerB64: Base64Std4.min(16).max(2048).optional()
|
|
3382
3455
|
});
|
|
3383
|
-
var ConsumerSettlementSchema =
|
|
3384
|
-
settlementId:
|
|
3456
|
+
var ConsumerSettlementSchema = import_zod14.z.object({
|
|
3457
|
+
settlementId: import_zod14.z.string().uuid(),
|
|
3385
3458
|
settlementKey: Sha256Hex,
|
|
3386
3459
|
encounterId: Sha256Hex,
|
|
3387
|
-
oacId:
|
|
3388
|
-
payerUserId:
|
|
3389
|
-
payeeUserId:
|
|
3390
|
-
amountKobo:
|
|
3391
|
-
currency:
|
|
3392
|
-
status:
|
|
3393
|
-
reviewReason:
|
|
3394
|
-
ledgerRef:
|
|
3460
|
+
oacId: import_zod14.z.string().uuid(),
|
|
3461
|
+
payerUserId: import_zod14.z.string().uuid(),
|
|
3462
|
+
payeeUserId: import_zod14.z.string().uuid(),
|
|
3463
|
+
amountKobo: import_zod14.z.number().int().positive(),
|
|
3464
|
+
currency: import_zod14.z.string().length(3),
|
|
3465
|
+
status: import_zod14.z.enum(["SETTLED", "REVIEW"]),
|
|
3466
|
+
reviewReason: import_zod14.z.string().nullable(),
|
|
3467
|
+
ledgerRef: import_zod14.z.string().nullable(),
|
|
3395
3468
|
/** ASN.1 DER ECDSA P-256 issuer signature, base64. */
|
|
3396
|
-
issuerSig:
|
|
3469
|
+
issuerSig: Base64Std4.min(16).max(2048),
|
|
3397
3470
|
/** Canonical millisecond timestamp signed into the settlement receipt. */
|
|
3398
|
-
issuedAtMs:
|
|
3471
|
+
issuedAtMs: import_zod14.z.number().int().nonnegative(),
|
|
3399
3472
|
/** Compatibility alias for API consumers that predate issuedAtMs. */
|
|
3400
|
-
createdAtMs:
|
|
3473
|
+
createdAtMs: import_zod14.z.number().int().nonnegative().optional()
|
|
3401
3474
|
});
|
|
3402
|
-
var ConsumerSettleResultSchema =
|
|
3475
|
+
var ConsumerSettleResultSchema = import_zod14.z.object({
|
|
3403
3476
|
settlement: ConsumerSettlementSchema,
|
|
3404
3477
|
encounterId: Sha256Hex,
|
|
3405
|
-
replayed:
|
|
3478
|
+
replayed: import_zod14.z.boolean()
|
|
3406
3479
|
});
|
|
3407
|
-
var RevokeDeviceKeyInputSchema =
|
|
3408
|
-
deviceId:
|
|
3480
|
+
var RevokeDeviceKeyInputSchema = import_zod14.z.object({
|
|
3481
|
+
deviceId: import_zod14.z.string().min(1).max(128),
|
|
3409
3482
|
/** Step-up token from /api/v1/auth/send/verify with purpose='offline_revoke'. */
|
|
3410
|
-
sendAuthToken:
|
|
3483
|
+
sendAuthToken: import_zod14.z.string().min(16)
|
|
3411
3484
|
});
|
|
3412
3485
|
function createMeOfflineClient(opts) {
|
|
3413
3486
|
const fetchImpl = opts.fetchImpl ?? globalThis.fetch;
|
|
@@ -3440,7 +3513,7 @@ function createMeOfflineClient(opts) {
|
|
|
3440
3513
|
}
|
|
3441
3514
|
return parser(raw);
|
|
3442
3515
|
}
|
|
3443
|
-
const deviceKeyItems =
|
|
3516
|
+
const deviceKeyItems = import_zod14.z.object({ items: import_zod14.z.array(DeviceKeyRecordSchema) });
|
|
3444
3517
|
return {
|
|
3445
3518
|
issueP256EnrollmentChallenge: (input) => call(
|
|
3446
3519
|
"POST",
|
|
@@ -3498,6 +3571,12 @@ function createMeOfflineClient(opts) {
|
|
|
3498
3571
|
"/v1/issuer/keys",
|
|
3499
3572
|
void 0,
|
|
3500
3573
|
(raw) => IssuerTrustBundleSchema.parse(raw)
|
|
3574
|
+
),
|
|
3575
|
+
getRevocations: () => call(
|
|
3576
|
+
"GET",
|
|
3577
|
+
"/v1/issuer/revocations",
|
|
3578
|
+
void 0,
|
|
3579
|
+
(raw) => SignedRevocationListSchema.parse(raw)
|
|
3501
3580
|
)
|
|
3502
3581
|
};
|
|
3503
3582
|
}
|
|
@@ -3644,26 +3723,26 @@ function verifyClaimSignature(input) {
|
|
|
3644
3723
|
}
|
|
3645
3724
|
|
|
3646
3725
|
// src/me-offline/request.ts
|
|
3647
|
-
var
|
|
3648
|
-
var
|
|
3726
|
+
var import_zod15 = require("zod");
|
|
3727
|
+
var Base64Std5 = import_zod15.z.string().regex(/^[A-Za-z0-9+/]+={0,2}$/);
|
|
3649
3728
|
var CONSUMER_PAYMENT_REQUEST_DOMAIN = "flur:consumer-offline:v1:request";
|
|
3650
|
-
var ConsumerPaymentRequestEnvelopeSchema =
|
|
3651
|
-
requestId:
|
|
3652
|
-
mode:
|
|
3653
|
-
takerUserId:
|
|
3654
|
-
amountKobo:
|
|
3655
|
-
currency:
|
|
3656
|
-
reference:
|
|
3657
|
-
createdAtMs:
|
|
3658
|
-
expiresAtMs:
|
|
3659
|
-
nonce:
|
|
3660
|
-
takerDeviceId:
|
|
3661
|
-
takerPubkeySpkiB64:
|
|
3662
|
-
takerSignatureDerB64:
|
|
3729
|
+
var ConsumerPaymentRequestEnvelopeSchema = import_zod15.z.object({
|
|
3730
|
+
requestId: import_zod15.z.string().uuid(),
|
|
3731
|
+
mode: import_zod15.z.enum(["fixed", "editable"]),
|
|
3732
|
+
takerUserId: import_zod15.z.string().uuid(),
|
|
3733
|
+
amountKobo: import_zod15.z.number().int().positive(),
|
|
3734
|
+
currency: import_zod15.z.string().length(3).default("NGN"),
|
|
3735
|
+
reference: import_zod15.z.string().max(128).nullable().default(null),
|
|
3736
|
+
createdAtMs: import_zod15.z.number().int().nonnegative(),
|
|
3737
|
+
expiresAtMs: import_zod15.z.number().int().positive(),
|
|
3738
|
+
nonce: import_zod15.z.string().min(8).max(128),
|
|
3739
|
+
takerDeviceId: import_zod15.z.string().min(1).max(128).nullable().default(null),
|
|
3740
|
+
takerPubkeySpkiB64: Base64Std5.min(64).max(4096).optional(),
|
|
3741
|
+
takerSignatureDerB64: Base64Std5.min(16).max(2048).optional()
|
|
3663
3742
|
}).superRefine((value, ctx) => {
|
|
3664
3743
|
if (value.expiresAtMs <= value.createdAtMs) {
|
|
3665
3744
|
ctx.addIssue({
|
|
3666
|
-
code:
|
|
3745
|
+
code: import_zod15.z.ZodIssueCode.custom,
|
|
3667
3746
|
path: ["expiresAtMs"],
|
|
3668
3747
|
message: "expiresAtMs must be greater than createdAtMs"
|
|
3669
3748
|
});
|
|
@@ -3674,21 +3753,21 @@ var ConsumerPaymentRequestEnvelopeSchema = import_zod14.z.object({
|
|
|
3674
3753
|
if (value.mode === "fixed" || hasSignature) {
|
|
3675
3754
|
if (!value.takerDeviceId) {
|
|
3676
3755
|
ctx.addIssue({
|
|
3677
|
-
code:
|
|
3756
|
+
code: import_zod15.z.ZodIssueCode.custom,
|
|
3678
3757
|
path: ["takerDeviceId"],
|
|
3679
3758
|
message: "signed requests require takerDeviceId"
|
|
3680
3759
|
});
|
|
3681
3760
|
}
|
|
3682
3761
|
if (!value.takerPubkeySpkiB64) {
|
|
3683
3762
|
ctx.addIssue({
|
|
3684
|
-
code:
|
|
3763
|
+
code: import_zod15.z.ZodIssueCode.custom,
|
|
3685
3764
|
path: ["takerPubkeySpkiB64"],
|
|
3686
3765
|
message: "signed requests require takerPubkeySpkiB64"
|
|
3687
3766
|
});
|
|
3688
3767
|
}
|
|
3689
3768
|
if (!value.takerSignatureDerB64) {
|
|
3690
3769
|
ctx.addIssue({
|
|
3691
|
-
code:
|
|
3770
|
+
code: import_zod15.z.ZodIssueCode.custom,
|
|
3692
3771
|
path: ["takerSignatureDerB64"],
|
|
3693
3772
|
message: "signed requests require takerSignatureDerB64"
|
|
3694
3773
|
});
|
|
@@ -3859,7 +3938,7 @@ function base64UrlDecodeUtf8(input) {
|
|
|
3859
3938
|
}
|
|
3860
3939
|
|
|
3861
3940
|
// src/me-offline/oac.ts
|
|
3862
|
-
var
|
|
3941
|
+
var import_zod16 = require("zod");
|
|
3863
3942
|
var CONSUMER_OAC_DOMAIN = "flur:consumer-offline:v1:oac";
|
|
3864
3943
|
function consumerOacSigningPayload(oac) {
|
|
3865
3944
|
return { domain: CONSUMER_OAC_DOMAIN, ...oac };
|
|
@@ -3885,6 +3964,9 @@ function verifyOacOffline(signed, trustedKeys, options = {}) {
|
|
|
3885
3964
|
}
|
|
3886
3965
|
if (nowMs < oac.validFromMs) return { ok: false, reason: "not_yet_valid" };
|
|
3887
3966
|
if (nowMs >= oac.validUntilMs) return { ok: false, reason: "expired" };
|
|
3967
|
+
if (options.revokedOacIds?.has(oac.oacId)) {
|
|
3968
|
+
return { ok: false, reason: "revoked" };
|
|
3969
|
+
}
|
|
3888
3970
|
return {
|
|
3889
3971
|
ok: true,
|
|
3890
3972
|
oac,
|
|
@@ -3902,13 +3984,13 @@ var CONSUMER_OAC_QR_PREFIX = "FLUROAC1.";
|
|
|
3902
3984
|
function isConsumerOacQR(value) {
|
|
3903
3985
|
return value.startsWith(CONSUMER_OAC_QR_PREFIX);
|
|
3904
3986
|
}
|
|
3905
|
-
var OacPresentmentRequestSchema =
|
|
3987
|
+
var OacPresentmentRequestSchema = import_zod16.z.object({
|
|
3906
3988
|
/** Requested amount in minor units (kobo). */
|
|
3907
|
-
amountMinor:
|
|
3989
|
+
amountMinor: import_zod16.z.number().int().positive().max(1e12).optional(),
|
|
3908
3990
|
/** Purpose/intent code (mirrors the NIBSS intent vocabulary). */
|
|
3909
|
-
intent:
|
|
3991
|
+
intent: import_zod16.z.string().min(1).max(32).optional(),
|
|
3910
3992
|
/** Free-text reference / note. */
|
|
3911
|
-
reference:
|
|
3993
|
+
reference: import_zod16.z.string().min(1).max(64).optional()
|
|
3912
3994
|
}).strict();
|
|
3913
3995
|
function encodeConsumerOacQR(signed, request) {
|
|
3914
3996
|
const parsed = SignedConsumerOACSchema.parse(signed);
|
|
@@ -4242,14 +4324,14 @@ function base64UrlToBytes(input) {
|
|
|
4242
4324
|
}
|
|
4243
4325
|
|
|
4244
4326
|
// src/partner-funding/client.ts
|
|
4245
|
-
var
|
|
4246
|
-
var MinorString =
|
|
4247
|
-
var PositiveMinor =
|
|
4248
|
-
|
|
4249
|
-
|
|
4327
|
+
var import_zod17 = require("zod");
|
|
4328
|
+
var MinorString = import_zod17.z.string().regex(/^-?\d+$/);
|
|
4329
|
+
var PositiveMinor = import_zod17.z.union([
|
|
4330
|
+
import_zod17.z.number().int().positive(),
|
|
4331
|
+
import_zod17.z.string().regex(/^[1-9]\d{0,18}$/)
|
|
4250
4332
|
]);
|
|
4251
|
-
var Currency =
|
|
4252
|
-
var Metadata =
|
|
4333
|
+
var Currency = import_zod17.z.string().trim().length(3).transform((v) => v.toUpperCase());
|
|
4334
|
+
var Metadata = import_zod17.z.record(import_zod17.z.unknown());
|
|
4253
4335
|
var PARTNER_KINDS = ["bank", "merchant"];
|
|
4254
4336
|
var CUSTODIAL_MODES = ["agent_of_bank", "flur_virtual_pool"];
|
|
4255
4337
|
var PARTNER_PROFILE_STATUSES = [
|
|
@@ -4276,126 +4358,126 @@ var WITHDRAWAL_STATES = [
|
|
|
4276
4358
|
"failed",
|
|
4277
4359
|
"reversed"
|
|
4278
4360
|
];
|
|
4279
|
-
var PartnerProfileSchema =
|
|
4280
|
-
partnerAccountId:
|
|
4281
|
-
kind:
|
|
4282
|
-
custodialMode:
|
|
4283
|
-
displayName:
|
|
4284
|
-
bankCode:
|
|
4285
|
-
poolAccountNumber:
|
|
4286
|
-
status:
|
|
4361
|
+
var PartnerProfileSchema = import_zod17.z.object({
|
|
4362
|
+
partnerAccountId: import_zod17.z.string().uuid(),
|
|
4363
|
+
kind: import_zod17.z.enum(PARTNER_KINDS),
|
|
4364
|
+
custodialMode: import_zod17.z.enum(CUSTODIAL_MODES),
|
|
4365
|
+
displayName: import_zod17.z.string(),
|
|
4366
|
+
bankCode: import_zod17.z.string().nullable(),
|
|
4367
|
+
poolAccountNumber: import_zod17.z.string().nullable(),
|
|
4368
|
+
status: import_zod17.z.enum(PARTNER_PROFILE_STATUSES),
|
|
4287
4369
|
metadata: Metadata,
|
|
4288
|
-
createdAtMs:
|
|
4289
|
-
updatedAtMs:
|
|
4370
|
+
createdAtMs: import_zod17.z.number().int().nonnegative(),
|
|
4371
|
+
updatedAtMs: import_zod17.z.number().int().nonnegative()
|
|
4290
4372
|
});
|
|
4291
|
-
var UpsertPartnerProfileInputSchema =
|
|
4292
|
-
kind:
|
|
4293
|
-
custodialMode:
|
|
4294
|
-
displayName:
|
|
4295
|
-
bankCode:
|
|
4296
|
-
poolAccountNumber:
|
|
4373
|
+
var UpsertPartnerProfileInputSchema = import_zod17.z.object({
|
|
4374
|
+
kind: import_zod17.z.enum(PARTNER_KINDS),
|
|
4375
|
+
custodialMode: import_zod17.z.enum(CUSTODIAL_MODES),
|
|
4376
|
+
displayName: import_zod17.z.string().trim().min(1).max(200),
|
|
4377
|
+
bankCode: import_zod17.z.string().trim().min(1).max(64).optional(),
|
|
4378
|
+
poolAccountNumber: import_zod17.z.string().trim().min(1).max(64).optional(),
|
|
4297
4379
|
metadata: Metadata.optional()
|
|
4298
4380
|
});
|
|
4299
|
-
var PartnerFundingEventInputSchema =
|
|
4300
|
-
externalRef:
|
|
4301
|
-
direction:
|
|
4302
|
-
userId:
|
|
4303
|
-
accountId:
|
|
4381
|
+
var PartnerFundingEventInputSchema = import_zod17.z.object({
|
|
4382
|
+
externalRef: import_zod17.z.string().trim().min(8).max(128),
|
|
4383
|
+
direction: import_zod17.z.enum(PARTNER_FUNDING_DIRECTIONS).optional(),
|
|
4384
|
+
userId: import_zod17.z.string().uuid().optional(),
|
|
4385
|
+
accountId: import_zod17.z.string().uuid().optional(),
|
|
4304
4386
|
amountMinor: PositiveMinor,
|
|
4305
4387
|
currency: Currency,
|
|
4306
|
-
fundingSource:
|
|
4388
|
+
fundingSource: import_zod17.z.string().trim().min(1).max(64).optional(),
|
|
4307
4389
|
providerMetadata: Metadata.optional()
|
|
4308
4390
|
});
|
|
4309
|
-
var PartnerFundingSchema =
|
|
4310
|
-
fundingId:
|
|
4311
|
-
partnerId:
|
|
4312
|
-
accountId:
|
|
4313
|
-
userId:
|
|
4314
|
-
direction:
|
|
4315
|
-
currency:
|
|
4391
|
+
var PartnerFundingSchema = import_zod17.z.object({
|
|
4392
|
+
fundingId: import_zod17.z.string().uuid(),
|
|
4393
|
+
partnerId: import_zod17.z.string().uuid(),
|
|
4394
|
+
accountId: import_zod17.z.string().uuid(),
|
|
4395
|
+
userId: import_zod17.z.string().uuid().nullable(),
|
|
4396
|
+
direction: import_zod17.z.enum(PARTNER_FUNDING_DIRECTIONS),
|
|
4397
|
+
currency: import_zod17.z.string(),
|
|
4316
4398
|
amountMinor: MinorString,
|
|
4317
|
-
externalRef:
|
|
4318
|
-
status:
|
|
4319
|
-
fundingSource:
|
|
4320
|
-
ledgerRef:
|
|
4399
|
+
externalRef: import_zod17.z.string(),
|
|
4400
|
+
status: import_zod17.z.enum(PARTNER_FUNDING_STATUSES),
|
|
4401
|
+
fundingSource: import_zod17.z.string(),
|
|
4402
|
+
ledgerRef: import_zod17.z.string(),
|
|
4321
4403
|
providerMetadata: Metadata,
|
|
4322
|
-
createdAtMs:
|
|
4323
|
-
updatedAtMs:
|
|
4404
|
+
createdAtMs: import_zod17.z.number().int().nonnegative(),
|
|
4405
|
+
updatedAtMs: import_zod17.z.number().int().nonnegative()
|
|
4324
4406
|
});
|
|
4325
|
-
var IngestFundingResultSchema =
|
|
4407
|
+
var IngestFundingResultSchema = import_zod17.z.object({
|
|
4326
4408
|
funding: PartnerFundingSchema,
|
|
4327
|
-
replayed:
|
|
4409
|
+
replayed: import_zod17.z.boolean()
|
|
4328
4410
|
});
|
|
4329
|
-
var PayoutDestinationSchema =
|
|
4330
|
-
destinationId:
|
|
4331
|
-
accountId:
|
|
4332
|
-
partnerId:
|
|
4333
|
-
bankCode:
|
|
4334
|
-
accountNumber:
|
|
4335
|
-
accountName:
|
|
4336
|
-
status:
|
|
4337
|
-
verifiedAtMs:
|
|
4411
|
+
var PayoutDestinationSchema = import_zod17.z.object({
|
|
4412
|
+
destinationId: import_zod17.z.string().uuid(),
|
|
4413
|
+
accountId: import_zod17.z.string().uuid(),
|
|
4414
|
+
partnerId: import_zod17.z.string().uuid(),
|
|
4415
|
+
bankCode: import_zod17.z.string(),
|
|
4416
|
+
accountNumber: import_zod17.z.string(),
|
|
4417
|
+
accountName: import_zod17.z.string(),
|
|
4418
|
+
status: import_zod17.z.enum(PAYOUT_DESTINATION_STATUSES),
|
|
4419
|
+
verifiedAtMs: import_zod17.z.number().int().nonnegative().nullable(),
|
|
4338
4420
|
metadata: Metadata,
|
|
4339
|
-
createdAtMs:
|
|
4340
|
-
updatedAtMs:
|
|
4421
|
+
createdAtMs: import_zod17.z.number().int().nonnegative(),
|
|
4422
|
+
updatedAtMs: import_zod17.z.number().int().nonnegative()
|
|
4341
4423
|
});
|
|
4342
|
-
var CreatePayoutDestinationInputSchema =
|
|
4343
|
-
partnerId:
|
|
4344
|
-
bankCode:
|
|
4345
|
-
accountNumber:
|
|
4346
|
-
accountName:
|
|
4424
|
+
var CreatePayoutDestinationInputSchema = import_zod17.z.object({
|
|
4425
|
+
partnerId: import_zod17.z.string().uuid(),
|
|
4426
|
+
bankCode: import_zod17.z.string().trim().min(1).max(32),
|
|
4427
|
+
accountNumber: import_zod17.z.string().trim().min(4).max(64),
|
|
4428
|
+
accountName: import_zod17.z.string().trim().min(1).max(200),
|
|
4347
4429
|
metadata: Metadata.optional()
|
|
4348
4430
|
});
|
|
4349
|
-
var ListPayoutDestinationsResultSchema =
|
|
4350
|
-
items:
|
|
4431
|
+
var ListPayoutDestinationsResultSchema = import_zod17.z.object({
|
|
4432
|
+
items: import_zod17.z.array(PayoutDestinationSchema)
|
|
4351
4433
|
});
|
|
4352
|
-
var WithdrawalSchema =
|
|
4353
|
-
withdrawalId:
|
|
4354
|
-
accountId:
|
|
4355
|
-
userId:
|
|
4356
|
-
partnerId:
|
|
4357
|
-
destinationId:
|
|
4358
|
-
currency:
|
|
4434
|
+
var WithdrawalSchema = import_zod17.z.object({
|
|
4435
|
+
withdrawalId: import_zod17.z.string().uuid(),
|
|
4436
|
+
accountId: import_zod17.z.string().uuid(),
|
|
4437
|
+
userId: import_zod17.z.string().uuid(),
|
|
4438
|
+
partnerId: import_zod17.z.string().uuid(),
|
|
4439
|
+
destinationId: import_zod17.z.string().uuid(),
|
|
4440
|
+
currency: import_zod17.z.string(),
|
|
4359
4441
|
amountMinor: MinorString,
|
|
4360
|
-
state:
|
|
4361
|
-
idempotencyKey:
|
|
4362
|
-
providerRef:
|
|
4363
|
-
lastError:
|
|
4364
|
-
ledgerRef:
|
|
4365
|
-
reverseLedgerRef:
|
|
4442
|
+
state: import_zod17.z.enum(WITHDRAWAL_STATES),
|
|
4443
|
+
idempotencyKey: import_zod17.z.string(),
|
|
4444
|
+
providerRef: import_zod17.z.string().nullable(),
|
|
4445
|
+
lastError: import_zod17.z.string().nullable(),
|
|
4446
|
+
ledgerRef: import_zod17.z.string(),
|
|
4447
|
+
reverseLedgerRef: import_zod17.z.string().nullable(),
|
|
4366
4448
|
metadata: Metadata,
|
|
4367
|
-
createdAtMs:
|
|
4368
|
-
updatedAtMs:
|
|
4449
|
+
createdAtMs: import_zod17.z.number().int().nonnegative(),
|
|
4450
|
+
updatedAtMs: import_zod17.z.number().int().nonnegative()
|
|
4369
4451
|
});
|
|
4370
|
-
var CreateWithdrawalInputSchema =
|
|
4371
|
-
destinationId:
|
|
4452
|
+
var CreateWithdrawalInputSchema = import_zod17.z.object({
|
|
4453
|
+
destinationId: import_zod17.z.string().uuid(),
|
|
4372
4454
|
amountMinor: PositiveMinor,
|
|
4373
4455
|
currency: Currency,
|
|
4374
|
-
idempotencyKey:
|
|
4456
|
+
idempotencyKey: import_zod17.z.string().trim().min(8).max(128),
|
|
4375
4457
|
metadata: Metadata.optional()
|
|
4376
4458
|
});
|
|
4377
|
-
var CreateWithdrawalResultSchema =
|
|
4459
|
+
var CreateWithdrawalResultSchema = import_zod17.z.object({
|
|
4378
4460
|
withdrawal: WithdrawalSchema,
|
|
4379
|
-
replayed:
|
|
4461
|
+
replayed: import_zod17.z.boolean()
|
|
4380
4462
|
});
|
|
4381
|
-
var PayoutEventInputSchema =
|
|
4382
|
-
externalRef:
|
|
4383
|
-
withdrawalId:
|
|
4384
|
-
state:
|
|
4385
|
-
providerRef:
|
|
4386
|
-
failureCode:
|
|
4387
|
-
failureMessage:
|
|
4463
|
+
var PayoutEventInputSchema = import_zod17.z.object({
|
|
4464
|
+
externalRef: import_zod17.z.string().trim().min(8).max(128),
|
|
4465
|
+
withdrawalId: import_zod17.z.string().uuid().optional(),
|
|
4466
|
+
state: import_zod17.z.enum(["submitted", "processing", "paid", "failed"]),
|
|
4467
|
+
providerRef: import_zod17.z.string().trim().min(1).max(128).optional(),
|
|
4468
|
+
failureCode: import_zod17.z.string().trim().max(64).optional(),
|
|
4469
|
+
failureMessage: import_zod17.z.string().trim().max(512).optional(),
|
|
4388
4470
|
providerMetadata: Metadata.optional()
|
|
4389
4471
|
});
|
|
4390
|
-
var RecordPayoutEventResultSchema =
|
|
4472
|
+
var RecordPayoutEventResultSchema = import_zod17.z.object({
|
|
4391
4473
|
withdrawal: WithdrawalSchema,
|
|
4392
|
-
replayed:
|
|
4474
|
+
replayed: import_zod17.z.boolean()
|
|
4393
4475
|
});
|
|
4394
|
-
var ReconciliationReportSchema =
|
|
4395
|
-
partnerId:
|
|
4396
|
-
currency:
|
|
4397
|
-
fromMs:
|
|
4398
|
-
toMs:
|
|
4476
|
+
var ReconciliationReportSchema = import_zod17.z.object({
|
|
4477
|
+
partnerId: import_zod17.z.string().uuid(),
|
|
4478
|
+
currency: import_zod17.z.string(),
|
|
4479
|
+
fromMs: import_zod17.z.number().int().nonnegative(),
|
|
4480
|
+
toMs: import_zod17.z.number().int().nonnegative(),
|
|
4399
4481
|
fundingsCreditMinor: MinorString,
|
|
4400
4482
|
fundingsDebitMinor: MinorString,
|
|
4401
4483
|
withdrawalsPaidMinor: MinorString,
|
|
@@ -4404,7 +4486,7 @@ var ReconciliationReportSchema = import_zod16.z.object({
|
|
|
4404
4486
|
expectedReserveBalanceMinor: MinorString,
|
|
4405
4487
|
actualReserveBalanceMinor: MinorString,
|
|
4406
4488
|
imbalanceMinor: MinorString,
|
|
4407
|
-
generatedAtMs:
|
|
4489
|
+
generatedAtMs: import_zod17.z.number().int().nonnegative()
|
|
4408
4490
|
});
|
|
4409
4491
|
function createPartnerFundingClient(partner) {
|
|
4410
4492
|
return {
|
|
@@ -4556,19 +4638,19 @@ function createPartnerProfileAdminClient(opts) {
|
|
|
4556
4638
|
}
|
|
4557
4639
|
|
|
4558
4640
|
// src/artifacts/envelope.ts
|
|
4559
|
-
var
|
|
4641
|
+
var import_zod18 = require("zod");
|
|
4560
4642
|
var FLUR_ARTIFACT_URI_SCHEME = "flur";
|
|
4561
4643
|
var FLUR_ARTIFACT_VERSION = 1;
|
|
4562
4644
|
var FLUR_ARTIFACT_URI_PREFIX = `${FLUR_ARTIFACT_URI_SCHEME}://v${FLUR_ARTIFACT_VERSION}/`;
|
|
4563
4645
|
var ArtifactTypeRe = /^[a-z][a-z0-9_]{1,63}$/;
|
|
4564
|
-
var ArtifactHeaderSchema =
|
|
4565
|
-
v:
|
|
4566
|
-
t:
|
|
4567
|
-
iss:
|
|
4568
|
-
kid:
|
|
4569
|
-
iat:
|
|
4570
|
-
exp:
|
|
4571
|
-
nonce:
|
|
4646
|
+
var ArtifactHeaderSchema = import_zod18.z.object({
|
|
4647
|
+
v: import_zod18.z.literal(FLUR_ARTIFACT_VERSION),
|
|
4648
|
+
t: import_zod18.z.string().regex(ArtifactTypeRe, "invalid artifact type"),
|
|
4649
|
+
iss: import_zod18.z.string().min(1).max(128),
|
|
4650
|
+
kid: import_zod18.z.string().min(1).max(128),
|
|
4651
|
+
iat: import_zod18.z.number().int().nonnegative(),
|
|
4652
|
+
exp: import_zod18.z.number().int().positive().optional(),
|
|
4653
|
+
nonce: import_zod18.z.string().min(8).max(64).regex(/^[A-Za-z0-9_-]+$/, "nonce must be url-safe")
|
|
4572
4654
|
});
|
|
4573
4655
|
var FlurArtifactError = class extends Error {
|
|
4574
4656
|
constructor(message, code) {
|
|
@@ -4707,7 +4789,7 @@ function verifyArtifactSignature(decoded, publicKeySpkiB64, options = {}) {
|
|
|
4707
4789
|
}
|
|
4708
4790
|
|
|
4709
4791
|
// src/artifacts/types.ts
|
|
4710
|
-
var
|
|
4792
|
+
var import_zod19 = require("zod");
|
|
4711
4793
|
var ARTIFACT_TYPES = {
|
|
4712
4794
|
OFFLINE_PAYMENT_AUTHORIZATION: "offline_payment_authorization",
|
|
4713
4795
|
RECEIPT: "receipt",
|
|
@@ -4722,32 +4804,32 @@ var ARTIFACT_TYPES = {
|
|
|
4722
4804
|
PASS: "pass",
|
|
4723
4805
|
IDENTITY: "identity"
|
|
4724
4806
|
};
|
|
4725
|
-
var HexString = (length) =>
|
|
4807
|
+
var HexString = (length) => import_zod19.z.string().regex(
|
|
4726
4808
|
new RegExp(`^[0-9a-fA-F]{${length * 2}}$`),
|
|
4727
4809
|
`expected ${length}-byte hex string`
|
|
4728
4810
|
);
|
|
4729
|
-
var OfflinePaymentAuthorizationArtifactSchema =
|
|
4811
|
+
var OfflinePaymentAuthorizationArtifactSchema = import_zod19.z.object({
|
|
4730
4812
|
authorization: OfflinePaymentAuthorizationSchema
|
|
4731
4813
|
});
|
|
4732
|
-
var ReceiptArtifactSchema =
|
|
4733
|
-
receiptId:
|
|
4734
|
-
paymentReference:
|
|
4735
|
-
payerUserId:
|
|
4736
|
-
payeeUserId:
|
|
4737
|
-
amountKobo:
|
|
4738
|
-
currency:
|
|
4739
|
-
channel:
|
|
4740
|
-
settledAtMs:
|
|
4741
|
-
ledgerTxnId:
|
|
4742
|
-
memo:
|
|
4814
|
+
var ReceiptArtifactSchema = import_zod19.z.object({
|
|
4815
|
+
receiptId: import_zod19.z.string().min(1).max(64),
|
|
4816
|
+
paymentReference: import_zod19.z.string().min(1).max(64),
|
|
4817
|
+
payerUserId: import_zod19.z.string().min(1).max(64).optional(),
|
|
4818
|
+
payeeUserId: import_zod19.z.string().min(1).max(64),
|
|
4819
|
+
amountKobo: import_zod19.z.number().int().positive(),
|
|
4820
|
+
currency: import_zod19.z.literal("NGN"),
|
|
4821
|
+
channel: import_zod19.z.enum(["online", "offline_reconciled", "pay_link", "nqr"]),
|
|
4822
|
+
settledAtMs: import_zod19.z.number().int().positive(),
|
|
4823
|
+
ledgerTxnId: import_zod19.z.string().min(1).max(64).optional(),
|
|
4824
|
+
memo: import_zod19.z.string().max(140).optional(),
|
|
4743
4825
|
hashChainPrev: HexString(32).optional()
|
|
4744
4826
|
});
|
|
4745
|
-
var ShortId =
|
|
4746
|
-
var PositiveInt =
|
|
4747
|
-
var NonNegativeInt =
|
|
4748
|
-
var Currency2 =
|
|
4749
|
-
var Memo =
|
|
4750
|
-
var NqrPaymentRequestArtifactSchema =
|
|
4827
|
+
var ShortId = import_zod19.z.string().min(1).max(64);
|
|
4828
|
+
var PositiveInt = import_zod19.z.number().int().positive();
|
|
4829
|
+
var NonNegativeInt = import_zod19.z.number().int().nonnegative();
|
|
4830
|
+
var Currency2 = import_zod19.z.literal("NGN");
|
|
4831
|
+
var Memo = import_zod19.z.string().max(140);
|
|
4832
|
+
var NqrPaymentRequestArtifactSchema = import_zod19.z.object({
|
|
4751
4833
|
requestId: ShortId,
|
|
4752
4834
|
payeeUserId: ShortId,
|
|
4753
4835
|
amountKobo: PositiveInt.optional(),
|
|
@@ -4755,7 +4837,7 @@ var NqrPaymentRequestArtifactSchema = import_zod18.z.object({
|
|
|
4755
4837
|
memo: Memo.optional(),
|
|
4756
4838
|
expiresAtMs: PositiveInt.optional()
|
|
4757
4839
|
});
|
|
4758
|
-
var PaymentIntentArtifactSchema =
|
|
4840
|
+
var PaymentIntentArtifactSchema = import_zod19.z.object({
|
|
4759
4841
|
intentId: ShortId,
|
|
4760
4842
|
payerUserId: ShortId,
|
|
4761
4843
|
payeeUserId: ShortId,
|
|
@@ -4764,7 +4846,7 @@ var PaymentIntentArtifactSchema = import_zod18.z.object({
|
|
|
4764
4846
|
idempotencyKey: ShortId,
|
|
4765
4847
|
createdAtMs: PositiveInt
|
|
4766
4848
|
});
|
|
4767
|
-
var OfflineClaimArtifactSchema =
|
|
4849
|
+
var OfflineClaimArtifactSchema = import_zod19.z.object({
|
|
4768
4850
|
claimId: ShortId,
|
|
4769
4851
|
authorizationId: ShortId,
|
|
4770
4852
|
payeeUserId: ShortId,
|
|
@@ -4773,10 +4855,10 @@ var OfflineClaimArtifactSchema = import_zod18.z.object({
|
|
|
4773
4855
|
claimedAtMs: PositiveInt,
|
|
4774
4856
|
paymentReference: ShortId.optional()
|
|
4775
4857
|
});
|
|
4776
|
-
var SettlementRecordArtifactSchema =
|
|
4858
|
+
var SettlementRecordArtifactSchema = import_zod19.z.object({
|
|
4777
4859
|
settlementId: ShortId,
|
|
4778
4860
|
ledgerTxnId: ShortId,
|
|
4779
|
-
sourceRefType:
|
|
4861
|
+
sourceRefType: import_zod19.z.enum([
|
|
4780
4862
|
"offline_authorization",
|
|
4781
4863
|
"offline_claim",
|
|
4782
4864
|
"transfer",
|
|
@@ -4787,12 +4869,12 @@ var SettlementRecordArtifactSchema = import_zod18.z.object({
|
|
|
4787
4869
|
currency: Currency2,
|
|
4788
4870
|
settledAtMs: PositiveInt
|
|
4789
4871
|
});
|
|
4790
|
-
var ReversalRecordArtifactSchema =
|
|
4872
|
+
var ReversalRecordArtifactSchema = import_zod19.z.object({
|
|
4791
4873
|
reversalId: ShortId,
|
|
4792
4874
|
originalTxnId: ShortId,
|
|
4793
4875
|
amountKobo: PositiveInt,
|
|
4794
4876
|
currency: Currency2,
|
|
4795
|
-
reason:
|
|
4877
|
+
reason: import_zod19.z.enum([
|
|
4796
4878
|
"user_dispute",
|
|
4797
4879
|
"fraud",
|
|
4798
4880
|
"duplicate",
|
|
@@ -4802,7 +4884,7 @@ var ReversalRecordArtifactSchema = import_zod18.z.object({
|
|
|
4802
4884
|
reversedAtMs: PositiveInt,
|
|
4803
4885
|
memo: Memo.optional()
|
|
4804
4886
|
});
|
|
4805
|
-
var LedgerJournalEntryArtifactSchema =
|
|
4887
|
+
var LedgerJournalEntryArtifactSchema = import_zod19.z.object({
|
|
4806
4888
|
entryId: ShortId,
|
|
4807
4889
|
journalId: ShortId,
|
|
4808
4890
|
debitAccountId: ShortId,
|
|
@@ -4813,13 +4895,13 @@ var LedgerJournalEntryArtifactSchema = import_zod18.z.object({
|
|
|
4813
4895
|
refType: ShortId.optional(),
|
|
4814
4896
|
refId: ShortId.optional()
|
|
4815
4897
|
});
|
|
4816
|
-
var StatementArtifactSchema =
|
|
4898
|
+
var StatementArtifactSchema = import_zod19.z.object({
|
|
4817
4899
|
statementId: ShortId,
|
|
4818
4900
|
userId: ShortId,
|
|
4819
4901
|
periodStartMs: PositiveInt,
|
|
4820
4902
|
periodEndMs: PositiveInt,
|
|
4821
|
-
openingBalanceKobo:
|
|
4822
|
-
closingBalanceKobo:
|
|
4903
|
+
openingBalanceKobo: import_zod19.z.number().int(),
|
|
4904
|
+
closingBalanceKobo: import_zod19.z.number().int(),
|
|
4823
4905
|
transactionCount: NonNegativeInt,
|
|
4824
4906
|
currency: Currency2,
|
|
4825
4907
|
hashChainPrev: HexString(32).optional()
|
|
@@ -4827,16 +4909,16 @@ var StatementArtifactSchema = import_zod18.z.object({
|
|
|
4827
4909
|
message: "periodEndMs must be greater than periodStartMs",
|
|
4828
4910
|
path: ["periodEndMs"]
|
|
4829
4911
|
});
|
|
4830
|
-
var PassArtifactSchema =
|
|
4912
|
+
var PassArtifactSchema = import_zod19.z.object({
|
|
4831
4913
|
passId: ShortId,
|
|
4832
4914
|
holderId: ShortId,
|
|
4833
|
-
category:
|
|
4834
|
-
title:
|
|
4915
|
+
category: import_zod19.z.enum(["membership", "ticket", "loyalty", "access", "voucher"]),
|
|
4916
|
+
title: import_zod19.z.string().min(1).max(120),
|
|
4835
4917
|
validFromMs: PositiveInt,
|
|
4836
4918
|
validUntilMs: PositiveInt.optional(),
|
|
4837
|
-
metadata:
|
|
4838
|
-
|
|
4839
|
-
|
|
4919
|
+
metadata: import_zod19.z.record(
|
|
4920
|
+
import_zod19.z.string().min(1).max(64),
|
|
4921
|
+
import_zod19.z.union([import_zod19.z.string().max(280), import_zod19.z.number(), import_zod19.z.boolean()])
|
|
4840
4922
|
).optional()
|
|
4841
4923
|
}).refine(
|
|
4842
4924
|
(v) => v.validUntilMs === void 0 || v.validUntilMs > v.validFromMs,
|
|
@@ -4845,10 +4927,10 @@ var PassArtifactSchema = import_zod18.z.object({
|
|
|
4845
4927
|
path: ["validUntilMs"]
|
|
4846
4928
|
}
|
|
4847
4929
|
);
|
|
4848
|
-
var IdentityArtifactSchema =
|
|
4930
|
+
var IdentityArtifactSchema = import_zod19.z.object({
|
|
4849
4931
|
attestationId: ShortId,
|
|
4850
4932
|
subjectId: ShortId,
|
|
4851
|
-
claimType:
|
|
4933
|
+
claimType: import_zod19.z.enum([
|
|
4852
4934
|
"phone_verified",
|
|
4853
4935
|
"email_verified",
|
|
4854
4936
|
"bvn_verified",
|
|
@@ -4987,6 +5069,7 @@ function createOfflinePaymentAuthorizationArtifactUri(input) {
|
|
|
4987
5069
|
CONSUMER_OAC_QR_PREFIX,
|
|
4988
5070
|
CONSUMER_OFFLINE_CLAIM_SUBMIT_GRACE_MS,
|
|
4989
5071
|
CONSUMER_PAYMENT_REQUEST_DOMAIN,
|
|
5072
|
+
CONSUMER_REVOCATION_DOMAIN,
|
|
4990
5073
|
CONSUMER_SETTLEMENT_DOMAIN,
|
|
4991
5074
|
CONSUMER_SETTLEMENT_RECEIPT_QR_PREFIX,
|
|
4992
5075
|
CUSTODIAL_MODES,
|
|
@@ -5084,6 +5167,7 @@ function createOfflinePaymentAuthorizationArtifactUri(input) {
|
|
|
5084
5167
|
RECEIPT_CHANNELS,
|
|
5085
5168
|
RECEIPT_KINDS,
|
|
5086
5169
|
REPLAY_WINDOW_MS,
|
|
5170
|
+
REVOCATION_LIST_MAX_ENTRIES,
|
|
5087
5171
|
ReceiptArtifactSchema,
|
|
5088
5172
|
ReceiptPayloadSchema,
|
|
5089
5173
|
ReceiptSchema,
|
|
@@ -5092,12 +5176,14 @@ function createOfflinePaymentAuthorizationArtifactUri(input) {
|
|
|
5092
5176
|
RedemptionSchema,
|
|
5093
5177
|
RegisterDeviceKeyP256InputSchema,
|
|
5094
5178
|
ReversalRecordArtifactSchema,
|
|
5179
|
+
RevocationListSchema,
|
|
5095
5180
|
RevokeDeviceKeyInputSchema,
|
|
5096
5181
|
SETTLEMENT_SCHEDULES,
|
|
5097
5182
|
SettleResponseSchema,
|
|
5098
5183
|
SettlementRecordArtifactSchema,
|
|
5099
5184
|
SettlementSchema,
|
|
5100
5185
|
SignedConsumerOACSchema,
|
|
5186
|
+
SignedRevocationListSchema,
|
|
5101
5187
|
StatementArtifactSchema,
|
|
5102
5188
|
UpsertMerchantProfileInputSchema,
|
|
5103
5189
|
UpsertPartnerProfileInputSchema,
|
|
@@ -5178,6 +5264,7 @@ function createOfflinePaymentAuthorizationArtifactUri(input) {
|
|
|
5178
5264
|
isConsumerPaymentRequestExpired,
|
|
5179
5265
|
isHardenedArtifactType,
|
|
5180
5266
|
isKnownArtifactType,
|
|
5267
|
+
isOacRevoked,
|
|
5181
5268
|
isPassWithinValidity,
|
|
5182
5269
|
moneyMinorToNumber,
|
|
5183
5270
|
normalizeE164,
|
|
@@ -5185,6 +5272,7 @@ function createOfflinePaymentAuthorizationArtifactUri(input) {
|
|
|
5185
5272
|
parseNQR,
|
|
5186
5273
|
parseQR,
|
|
5187
5274
|
readTLV,
|
|
5275
|
+
revocationListSigningPayload,
|
|
5188
5276
|
routingHint,
|
|
5189
5277
|
signArtifact,
|
|
5190
5278
|
signAuthorization,
|
|
@@ -5211,6 +5299,7 @@ function createOfflinePaymentAuthorizationArtifactUri(input) {
|
|
|
5211
5299
|
verifyReceipt,
|
|
5212
5300
|
verifyRedemption,
|
|
5213
5301
|
verifyRequestHMAC,
|
|
5302
|
+
verifyRevocationList,
|
|
5214
5303
|
writeTLV
|
|
5215
5304
|
});
|
|
5216
5305
|
//# sourceMappingURL=index.cjs.map
|