@nokinc-flur/sdk 1.1.0 → 1.1.1
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 +467 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1520 -1
- package/dist/index.d.ts +1520 -1
- package/dist/index.js +435 -0
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -3482,13 +3482,419 @@ function createPartnerProfileAdminClient(opts) {
|
|
|
3482
3482
|
}
|
|
3483
3483
|
};
|
|
3484
3484
|
}
|
|
3485
|
+
|
|
3486
|
+
// src/artifacts/envelope.ts
|
|
3487
|
+
import { z as z15 } from "zod";
|
|
3488
|
+
var FLUR_ARTIFACT_URI_SCHEME = "flur";
|
|
3489
|
+
var FLUR_ARTIFACT_VERSION = 1;
|
|
3490
|
+
var FLUR_ARTIFACT_URI_PREFIX = `${FLUR_ARTIFACT_URI_SCHEME}://v${FLUR_ARTIFACT_VERSION}/`;
|
|
3491
|
+
var ArtifactTypeRe = /^[a-z][a-z0-9_]{1,63}$/;
|
|
3492
|
+
var ArtifactHeaderSchema = z15.object({
|
|
3493
|
+
v: z15.literal(FLUR_ARTIFACT_VERSION),
|
|
3494
|
+
t: z15.string().regex(ArtifactTypeRe, "invalid artifact type"),
|
|
3495
|
+
iss: z15.string().min(1).max(128),
|
|
3496
|
+
kid: z15.string().min(1).max(128),
|
|
3497
|
+
iat: z15.number().int().nonnegative(),
|
|
3498
|
+
exp: z15.number().int().positive().optional(),
|
|
3499
|
+
nonce: z15.string().min(8).max(64).regex(/^[A-Za-z0-9_-]+$/, "nonce must be url-safe")
|
|
3500
|
+
});
|
|
3501
|
+
var FlurArtifactError = class extends Error {
|
|
3502
|
+
constructor(message, code) {
|
|
3503
|
+
super(message);
|
|
3504
|
+
this.code = code;
|
|
3505
|
+
this.name = "FlurArtifactError";
|
|
3506
|
+
}
|
|
3507
|
+
code;
|
|
3508
|
+
};
|
|
3509
|
+
function base64UrlEncode(bytes) {
|
|
3510
|
+
let bin = "";
|
|
3511
|
+
for (let i = 0; i < bytes.length; i++) bin += String.fromCharCode(bytes[i]);
|
|
3512
|
+
const b64 = typeof btoa === "function" ? btoa(bin) : Buffer.from(bytes).toString("base64");
|
|
3513
|
+
return b64.replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
3514
|
+
}
|
|
3515
|
+
function base64UrlDecode(s) {
|
|
3516
|
+
const pad = s.length % 4 === 0 ? "" : "=".repeat(4 - s.length % 4);
|
|
3517
|
+
const b64 = s.replace(/-/g, "+").replace(/_/g, "/") + pad;
|
|
3518
|
+
if (typeof atob === "function") {
|
|
3519
|
+
const bin = atob(b64);
|
|
3520
|
+
const out = new Uint8Array(bin.length);
|
|
3521
|
+
for (let i = 0; i < bin.length; i++) out[i] = bin.charCodeAt(i);
|
|
3522
|
+
return out;
|
|
3523
|
+
}
|
|
3524
|
+
return new Uint8Array(Buffer.from(b64, "base64"));
|
|
3525
|
+
}
|
|
3526
|
+
function buildArtifactBody(input) {
|
|
3527
|
+
if (!ArtifactTypeRe.test(input.type)) {
|
|
3528
|
+
throw new FlurArtifactError(
|
|
3529
|
+
`Invalid artifact type: ${input.type}`,
|
|
3530
|
+
"INVALID_TYPE"
|
|
3531
|
+
);
|
|
3532
|
+
}
|
|
3533
|
+
const iat = input.issuedAtSeconds ?? Math.floor(Date.now() / 1e3);
|
|
3534
|
+
const header = {
|
|
3535
|
+
v: FLUR_ARTIFACT_VERSION,
|
|
3536
|
+
t: input.type,
|
|
3537
|
+
iss: input.issuer,
|
|
3538
|
+
kid: input.keyId,
|
|
3539
|
+
iat,
|
|
3540
|
+
...input.expiresAtSeconds !== void 0 ? { exp: input.expiresAtSeconds } : {},
|
|
3541
|
+
nonce: input.nonce
|
|
3542
|
+
};
|
|
3543
|
+
ArtifactHeaderSchema.parse(header);
|
|
3544
|
+
return { ...header, data: input.data };
|
|
3545
|
+
}
|
|
3546
|
+
function signArtifact(body, privateKey) {
|
|
3547
|
+
const sig = bytesToHex(sign(canonicalJSONBytes(body), privateKey));
|
|
3548
|
+
return { body, sig };
|
|
3549
|
+
}
|
|
3550
|
+
function encodeArtifactUri(signed) {
|
|
3551
|
+
const bodyBytes = canonicalJSONBytes(signed.body);
|
|
3552
|
+
const bodyB64 = base64UrlEncode(bodyBytes);
|
|
3553
|
+
const sigB64 = base64UrlEncode(hexToBytes(signed.sig));
|
|
3554
|
+
return `${FLUR_ARTIFACT_URI_PREFIX}${signed.body.t}/${bodyB64}.${sigB64}`;
|
|
3555
|
+
}
|
|
3556
|
+
function decodeArtifactUri(uri) {
|
|
3557
|
+
if (!uri.startsWith(FLUR_ARTIFACT_URI_PREFIX)) {
|
|
3558
|
+
throw new FlurArtifactError(
|
|
3559
|
+
`URI does not start with ${FLUR_ARTIFACT_URI_PREFIX}`,
|
|
3560
|
+
"INVALID_URI"
|
|
3561
|
+
);
|
|
3562
|
+
}
|
|
3563
|
+
const rest = uri.slice(FLUR_ARTIFACT_URI_PREFIX.length);
|
|
3564
|
+
const slash = rest.indexOf("/");
|
|
3565
|
+
if (slash <= 0) {
|
|
3566
|
+
throw new FlurArtifactError("Missing artifact type segment", "INVALID_URI");
|
|
3567
|
+
}
|
|
3568
|
+
const type = rest.slice(0, slash);
|
|
3569
|
+
const payload = rest.slice(slash + 1);
|
|
3570
|
+
const dot = payload.indexOf(".");
|
|
3571
|
+
if (dot <= 0 || dot === payload.length - 1) {
|
|
3572
|
+
throw new FlurArtifactError(
|
|
3573
|
+
"Missing body/signature separator",
|
|
3574
|
+
"INVALID_URI"
|
|
3575
|
+
);
|
|
3576
|
+
}
|
|
3577
|
+
if (!ArtifactTypeRe.test(type)) {
|
|
3578
|
+
throw new FlurArtifactError(
|
|
3579
|
+
`Invalid artifact type: ${type}`,
|
|
3580
|
+
"INVALID_TYPE"
|
|
3581
|
+
);
|
|
3582
|
+
}
|
|
3583
|
+
const bodyBytes = base64UrlDecode(payload.slice(0, dot));
|
|
3584
|
+
const sigBytes = base64UrlDecode(payload.slice(dot + 1));
|
|
3585
|
+
if (sigBytes.length !== 64) {
|
|
3586
|
+
throw new FlurArtifactError(
|
|
3587
|
+
`Signature must be 64 bytes, got ${sigBytes.length}`,
|
|
3588
|
+
"INVALID_SIGNATURE"
|
|
3589
|
+
);
|
|
3590
|
+
}
|
|
3591
|
+
let bodyJson;
|
|
3592
|
+
try {
|
|
3593
|
+
bodyJson = JSON.parse(new TextDecoder().decode(bodyBytes));
|
|
3594
|
+
} catch {
|
|
3595
|
+
throw new FlurArtifactError("Body is not valid JSON", "INVALID_BODY");
|
|
3596
|
+
}
|
|
3597
|
+
const headerOnly = ArtifactHeaderSchema.safeParse(bodyJson);
|
|
3598
|
+
if (!headerOnly.success) {
|
|
3599
|
+
throw new FlurArtifactError(
|
|
3600
|
+
`Body header invalid: ${headerOnly.error.message}`,
|
|
3601
|
+
"INVALID_BODY"
|
|
3602
|
+
);
|
|
3603
|
+
}
|
|
3604
|
+
if (headerOnly.data.t !== type) {
|
|
3605
|
+
throw new FlurArtifactError(
|
|
3606
|
+
`URI type ${type} does not match body type ${headerOnly.data.t}`,
|
|
3607
|
+
"TYPE_MISMATCH"
|
|
3608
|
+
);
|
|
3609
|
+
}
|
|
3610
|
+
return {
|
|
3611
|
+
type,
|
|
3612
|
+
bodyBytes,
|
|
3613
|
+
body: bodyJson,
|
|
3614
|
+
sig: bytesToHex(sigBytes)
|
|
3615
|
+
};
|
|
3616
|
+
}
|
|
3617
|
+
function verifyArtifactSignature(decoded, publicKey, options = {}) {
|
|
3618
|
+
if (options.enforceExpiry !== false && decoded.body.exp !== void 0) {
|
|
3619
|
+
const now = options.nowSeconds ?? Math.floor(Date.now() / 1e3);
|
|
3620
|
+
if (decoded.body.exp < now) {
|
|
3621
|
+
throw new FlurArtifactError("Artifact has expired", "EXPIRED");
|
|
3622
|
+
}
|
|
3623
|
+
}
|
|
3624
|
+
return verify(decoded.bodyBytes, hexToBytes(decoded.sig), publicKey);
|
|
3625
|
+
}
|
|
3626
|
+
|
|
3627
|
+
// src/artifacts/types.ts
|
|
3628
|
+
import { z as z16 } from "zod";
|
|
3629
|
+
var ARTIFACT_TYPES = {
|
|
3630
|
+
OFFLINE_PAYMENT_AUTHORIZATION: "offline_payment_authorization",
|
|
3631
|
+
RECEIPT: "receipt",
|
|
3632
|
+
// --- stubs, schemas to be hardened in follow-ups ---
|
|
3633
|
+
NQR_PAYMENT_REQUEST: "nqr_payment_request",
|
|
3634
|
+
PAYMENT_INTENT: "payment_intent",
|
|
3635
|
+
OFFLINE_CLAIM: "offline_claim",
|
|
3636
|
+
SETTLEMENT_RECORD: "settlement_record",
|
|
3637
|
+
REVERSAL_RECORD: "reversal_record",
|
|
3638
|
+
LEDGER_JOURNAL_ENTRY: "ledger_journal_entry",
|
|
3639
|
+
STATEMENT: "statement",
|
|
3640
|
+
PASS: "pass",
|
|
3641
|
+
IDENTITY: "identity"
|
|
3642
|
+
};
|
|
3643
|
+
var HexString4 = (length) => z16.string().regex(
|
|
3644
|
+
new RegExp(`^[0-9a-fA-F]{${length * 2}}$`),
|
|
3645
|
+
`expected ${length}-byte hex string`
|
|
3646
|
+
);
|
|
3647
|
+
var OfflinePaymentAuthorizationArtifactSchema = z16.object({
|
|
3648
|
+
authorization: OfflinePaymentAuthorizationSchema
|
|
3649
|
+
});
|
|
3650
|
+
var ReceiptArtifactSchema = z16.object({
|
|
3651
|
+
receiptId: z16.string().min(1).max(64),
|
|
3652
|
+
paymentReference: z16.string().min(1).max(64),
|
|
3653
|
+
payerUserId: z16.string().min(1).max(64).optional(),
|
|
3654
|
+
payeeUserId: z16.string().min(1).max(64),
|
|
3655
|
+
amountKobo: z16.number().int().positive(),
|
|
3656
|
+
currency: z16.literal("NGN"),
|
|
3657
|
+
channel: z16.enum(["online", "offline_reconciled", "pay_link", "nqr"]),
|
|
3658
|
+
settledAtMs: z16.number().int().positive(),
|
|
3659
|
+
ledgerTxnId: z16.string().min(1).max(64).optional(),
|
|
3660
|
+
memo: z16.string().max(140).optional(),
|
|
3661
|
+
hashChainPrev: HexString4(32).optional()
|
|
3662
|
+
});
|
|
3663
|
+
var ShortId = z16.string().min(1).max(64);
|
|
3664
|
+
var PositiveInt = z16.number().int().positive();
|
|
3665
|
+
var NonNegativeInt = z16.number().int().nonnegative();
|
|
3666
|
+
var Currency2 = z16.literal("NGN");
|
|
3667
|
+
var Memo = z16.string().max(140);
|
|
3668
|
+
var NqrPaymentRequestArtifactSchema = z16.object({
|
|
3669
|
+
requestId: ShortId,
|
|
3670
|
+
payeeUserId: ShortId,
|
|
3671
|
+
amountKobo: PositiveInt.optional(),
|
|
3672
|
+
currency: Currency2,
|
|
3673
|
+
memo: Memo.optional(),
|
|
3674
|
+
expiresAtMs: PositiveInt.optional()
|
|
3675
|
+
});
|
|
3676
|
+
var PaymentIntentArtifactSchema = z16.object({
|
|
3677
|
+
intentId: ShortId,
|
|
3678
|
+
payerUserId: ShortId,
|
|
3679
|
+
payeeUserId: ShortId,
|
|
3680
|
+
amountKobo: PositiveInt,
|
|
3681
|
+
currency: Currency2,
|
|
3682
|
+
idempotencyKey: ShortId,
|
|
3683
|
+
createdAtMs: PositiveInt
|
|
3684
|
+
});
|
|
3685
|
+
var OfflineClaimArtifactSchema = z16.object({
|
|
3686
|
+
claimId: ShortId,
|
|
3687
|
+
authorizationId: ShortId,
|
|
3688
|
+
payeeUserId: ShortId,
|
|
3689
|
+
claimedAmountKobo: PositiveInt,
|
|
3690
|
+
currency: Currency2,
|
|
3691
|
+
claimedAtMs: PositiveInt,
|
|
3692
|
+
paymentReference: ShortId.optional()
|
|
3693
|
+
});
|
|
3694
|
+
var SettlementRecordArtifactSchema = z16.object({
|
|
3695
|
+
settlementId: ShortId,
|
|
3696
|
+
ledgerTxnId: ShortId,
|
|
3697
|
+
sourceRefType: z16.enum([
|
|
3698
|
+
"offline_authorization",
|
|
3699
|
+
"offline_claim",
|
|
3700
|
+
"transfer",
|
|
3701
|
+
"pay_link"
|
|
3702
|
+
]),
|
|
3703
|
+
sourceRefId: ShortId,
|
|
3704
|
+
amountKobo: PositiveInt,
|
|
3705
|
+
currency: Currency2,
|
|
3706
|
+
settledAtMs: PositiveInt
|
|
3707
|
+
});
|
|
3708
|
+
var ReversalRecordArtifactSchema = z16.object({
|
|
3709
|
+
reversalId: ShortId,
|
|
3710
|
+
originalTxnId: ShortId,
|
|
3711
|
+
amountKobo: PositiveInt,
|
|
3712
|
+
currency: Currency2,
|
|
3713
|
+
reason: z16.enum([
|
|
3714
|
+
"user_dispute",
|
|
3715
|
+
"fraud",
|
|
3716
|
+
"duplicate",
|
|
3717
|
+
"admin_correction",
|
|
3718
|
+
"other"
|
|
3719
|
+
]),
|
|
3720
|
+
reversedAtMs: PositiveInt,
|
|
3721
|
+
memo: Memo.optional()
|
|
3722
|
+
});
|
|
3723
|
+
var LedgerJournalEntryArtifactSchema = z16.object({
|
|
3724
|
+
entryId: ShortId,
|
|
3725
|
+
journalId: ShortId,
|
|
3726
|
+
debitAccountId: ShortId,
|
|
3727
|
+
creditAccountId: ShortId,
|
|
3728
|
+
amountKobo: PositiveInt,
|
|
3729
|
+
currency: Currency2,
|
|
3730
|
+
postedAtMs: PositiveInt,
|
|
3731
|
+
refType: ShortId.optional(),
|
|
3732
|
+
refId: ShortId.optional()
|
|
3733
|
+
});
|
|
3734
|
+
var StatementArtifactSchema = z16.object({
|
|
3735
|
+
statementId: ShortId,
|
|
3736
|
+
userId: ShortId,
|
|
3737
|
+
periodStartMs: PositiveInt,
|
|
3738
|
+
periodEndMs: PositiveInt,
|
|
3739
|
+
openingBalanceKobo: z16.number().int(),
|
|
3740
|
+
closingBalanceKobo: z16.number().int(),
|
|
3741
|
+
transactionCount: NonNegativeInt,
|
|
3742
|
+
currency: Currency2,
|
|
3743
|
+
hashChainPrev: HexString4(32).optional()
|
|
3744
|
+
}).refine((v) => v.periodEndMs > v.periodStartMs, {
|
|
3745
|
+
message: "periodEndMs must be greater than periodStartMs",
|
|
3746
|
+
path: ["periodEndMs"]
|
|
3747
|
+
});
|
|
3748
|
+
var PassArtifactSchema = z16.object({
|
|
3749
|
+
passId: ShortId,
|
|
3750
|
+
holderId: ShortId,
|
|
3751
|
+
category: z16.enum(["membership", "ticket", "loyalty", "access", "voucher"]),
|
|
3752
|
+
title: z16.string().min(1).max(120),
|
|
3753
|
+
validFromMs: PositiveInt,
|
|
3754
|
+
validUntilMs: PositiveInt.optional(),
|
|
3755
|
+
metadata: z16.record(
|
|
3756
|
+
z16.string().min(1).max(64),
|
|
3757
|
+
z16.union([z16.string().max(280), z16.number(), z16.boolean()])
|
|
3758
|
+
).optional()
|
|
3759
|
+
}).refine(
|
|
3760
|
+
(v) => v.validUntilMs === void 0 || v.validUntilMs > v.validFromMs,
|
|
3761
|
+
{
|
|
3762
|
+
message: "validUntilMs must be greater than validFromMs",
|
|
3763
|
+
path: ["validUntilMs"]
|
|
3764
|
+
}
|
|
3765
|
+
);
|
|
3766
|
+
var IdentityArtifactSchema = z16.object({
|
|
3767
|
+
attestationId: ShortId,
|
|
3768
|
+
subjectId: ShortId,
|
|
3769
|
+
claimType: z16.enum([
|
|
3770
|
+
"phone_verified",
|
|
3771
|
+
"email_verified",
|
|
3772
|
+
"bvn_verified",
|
|
3773
|
+
"kyc_tier",
|
|
3774
|
+
"age_band"
|
|
3775
|
+
]),
|
|
3776
|
+
claimValueHash: HexString4(32),
|
|
3777
|
+
attestedAtMs: PositiveInt
|
|
3778
|
+
});
|
|
3779
|
+
var ARTIFACT_BODY_SCHEMAS = {
|
|
3780
|
+
[ARTIFACT_TYPES.OFFLINE_PAYMENT_AUTHORIZATION]: OfflinePaymentAuthorizationArtifactSchema,
|
|
3781
|
+
[ARTIFACT_TYPES.RECEIPT]: ReceiptArtifactSchema,
|
|
3782
|
+
[ARTIFACT_TYPES.NQR_PAYMENT_REQUEST]: NqrPaymentRequestArtifactSchema,
|
|
3783
|
+
[ARTIFACT_TYPES.PAYMENT_INTENT]: PaymentIntentArtifactSchema,
|
|
3784
|
+
[ARTIFACT_TYPES.OFFLINE_CLAIM]: OfflineClaimArtifactSchema,
|
|
3785
|
+
[ARTIFACT_TYPES.SETTLEMENT_RECORD]: SettlementRecordArtifactSchema,
|
|
3786
|
+
[ARTIFACT_TYPES.REVERSAL_RECORD]: ReversalRecordArtifactSchema,
|
|
3787
|
+
[ARTIFACT_TYPES.LEDGER_JOURNAL_ENTRY]: LedgerJournalEntryArtifactSchema,
|
|
3788
|
+
[ARTIFACT_TYPES.STATEMENT]: StatementArtifactSchema,
|
|
3789
|
+
[ARTIFACT_TYPES.PASS]: PassArtifactSchema,
|
|
3790
|
+
[ARTIFACT_TYPES.IDENTITY]: IdentityArtifactSchema
|
|
3791
|
+
};
|
|
3792
|
+
var HARDENED_ARTIFACT_TYPES = /* @__PURE__ */ new Set([
|
|
3793
|
+
ARTIFACT_TYPES.OFFLINE_PAYMENT_AUTHORIZATION,
|
|
3794
|
+
ARTIFACT_TYPES.RECEIPT,
|
|
3795
|
+
ARTIFACT_TYPES.NQR_PAYMENT_REQUEST,
|
|
3796
|
+
ARTIFACT_TYPES.PAYMENT_INTENT,
|
|
3797
|
+
ARTIFACT_TYPES.OFFLINE_CLAIM,
|
|
3798
|
+
ARTIFACT_TYPES.SETTLEMENT_RECORD,
|
|
3799
|
+
ARTIFACT_TYPES.REVERSAL_RECORD,
|
|
3800
|
+
ARTIFACT_TYPES.LEDGER_JOURNAL_ENTRY,
|
|
3801
|
+
ARTIFACT_TYPES.STATEMENT,
|
|
3802
|
+
ARTIFACT_TYPES.PASS,
|
|
3803
|
+
ARTIFACT_TYPES.IDENTITY
|
|
3804
|
+
]);
|
|
3805
|
+
function isKnownArtifactType(t) {
|
|
3806
|
+
return Object.values(ARTIFACT_TYPES).includes(t);
|
|
3807
|
+
}
|
|
3808
|
+
function isHardenedArtifactType(t) {
|
|
3809
|
+
return HARDENED_ARTIFACT_TYPES.has(t);
|
|
3810
|
+
}
|
|
3811
|
+
|
|
3812
|
+
// src/artifacts/codec.ts
|
|
3813
|
+
function createArtifactUri(input) {
|
|
3814
|
+
if (!isKnownArtifactType(input.type)) {
|
|
3815
|
+
throw new FlurArtifactError(
|
|
3816
|
+
`Unknown artifact type: ${input.type}`,
|
|
3817
|
+
"INVALID_TYPE"
|
|
3818
|
+
);
|
|
3819
|
+
}
|
|
3820
|
+
if (!isHardenedArtifactType(input.type)) {
|
|
3821
|
+
throw new FlurArtifactError(
|
|
3822
|
+
`Artifact type ${input.type} is not yet hardened for emission`,
|
|
3823
|
+
"INVALID_TYPE"
|
|
3824
|
+
);
|
|
3825
|
+
}
|
|
3826
|
+
const schema = ARTIFACT_BODY_SCHEMAS[input.type];
|
|
3827
|
+
const parsedData = schema.parse(input.data);
|
|
3828
|
+
const body = buildArtifactBody({
|
|
3829
|
+
type: input.type,
|
|
3830
|
+
issuer: input.issuer,
|
|
3831
|
+
keyId: input.keyId,
|
|
3832
|
+
data: parsedData,
|
|
3833
|
+
nonce: input.nonce,
|
|
3834
|
+
issuedAtSeconds: input.issuedAtSeconds,
|
|
3835
|
+
expiresAtSeconds: input.expiresAtSeconds
|
|
3836
|
+
});
|
|
3837
|
+
const signed = signArtifact(body, input.privateKey);
|
|
3838
|
+
return { uri: encodeArtifactUri(signed), signed };
|
|
3839
|
+
}
|
|
3840
|
+
function verifyArtifactUri(uri, publicKey, options = {}) {
|
|
3841
|
+
const decoded = decodeArtifactUri(uri);
|
|
3842
|
+
if (!isKnownArtifactType(decoded.type)) {
|
|
3843
|
+
throw new FlurArtifactError(
|
|
3844
|
+
`Unknown artifact type: ${decoded.type}`,
|
|
3845
|
+
"INVALID_TYPE"
|
|
3846
|
+
);
|
|
3847
|
+
}
|
|
3848
|
+
if (!isHardenedArtifactType(decoded.type)) {
|
|
3849
|
+
throw new FlurArtifactError(
|
|
3850
|
+
`Artifact type ${decoded.type} is not yet hardened for verification`,
|
|
3851
|
+
"INVALID_TYPE"
|
|
3852
|
+
);
|
|
3853
|
+
}
|
|
3854
|
+
const schema = ARTIFACT_BODY_SCHEMAS[decoded.type];
|
|
3855
|
+
const dataParsed = schema.safeParse(decoded.body.data);
|
|
3856
|
+
if (!dataParsed.success) {
|
|
3857
|
+
throw new FlurArtifactError(
|
|
3858
|
+
`Artifact body invalid: ${dataParsed.error.message}`,
|
|
3859
|
+
"INVALID_BODY"
|
|
3860
|
+
);
|
|
3861
|
+
}
|
|
3862
|
+
const ok = verifyArtifactSignature(decoded, publicKey, options);
|
|
3863
|
+
if (!ok) {
|
|
3864
|
+
throw new FlurArtifactError(
|
|
3865
|
+
"Artifact signature verification failed",
|
|
3866
|
+
"INVALID_SIGNATURE"
|
|
3867
|
+
);
|
|
3868
|
+
}
|
|
3869
|
+
return {
|
|
3870
|
+
type: decoded.type,
|
|
3871
|
+
body: decoded.body,
|
|
3872
|
+
sig: decoded.sig,
|
|
3873
|
+
decoded
|
|
3874
|
+
};
|
|
3875
|
+
}
|
|
3876
|
+
function createReceiptArtifactUri(input) {
|
|
3877
|
+
return createArtifactUri({
|
|
3878
|
+
...input,
|
|
3879
|
+
type: ARTIFACT_TYPES.RECEIPT
|
|
3880
|
+
});
|
|
3881
|
+
}
|
|
3882
|
+
function createOfflinePaymentAuthorizationArtifactUri(input) {
|
|
3883
|
+
return createArtifactUri({
|
|
3884
|
+
...input,
|
|
3885
|
+
type: ARTIFACT_TYPES.OFFLINE_PAYMENT_AUTHORIZATION
|
|
3886
|
+
});
|
|
3887
|
+
}
|
|
3485
3888
|
export {
|
|
3486
3889
|
ACCOUNT_STATUSES,
|
|
3487
3890
|
ACCOUNT_TYPES,
|
|
3488
3891
|
ADDITIONAL_DATA_SUBFIELD,
|
|
3892
|
+
ARTIFACT_BODY_SCHEMAS,
|
|
3893
|
+
ARTIFACT_TYPES,
|
|
3489
3894
|
AccountMembershipSchema,
|
|
3490
3895
|
AccountSchema,
|
|
3491
3896
|
ApiCredentialPublicSchema,
|
|
3897
|
+
ArtifactHeaderSchema,
|
|
3492
3898
|
COLLECTION_INTENT_STATUSES,
|
|
3493
3899
|
COLLECTION_PAYMENT_STATUSES,
|
|
3494
3900
|
CUSTODIAL_MODES,
|
|
@@ -3513,14 +3919,21 @@ export {
|
|
|
3513
3919
|
EnableOfflineInputSchema,
|
|
3514
3920
|
EnableOfflineResultSchema,
|
|
3515
3921
|
FIELD,
|
|
3922
|
+
FLUR_ARTIFACT_URI_PREFIX,
|
|
3923
|
+
FLUR_ARTIFACT_URI_SCHEME,
|
|
3924
|
+
FLUR_ARTIFACT_VERSION,
|
|
3516
3925
|
FlurApiError,
|
|
3926
|
+
FlurArtifactError,
|
|
3517
3927
|
FlurCapExceededError,
|
|
3518
3928
|
FlurClient,
|
|
3519
3929
|
FlurError,
|
|
3520
3930
|
FlurExpiredError,
|
|
3521
3931
|
FlurReplayError,
|
|
3932
|
+
HARDENED_ARTIFACT_TYPES,
|
|
3933
|
+
IdentityArtifactSchema,
|
|
3522
3934
|
IngestFundingResultSchema,
|
|
3523
3935
|
IssueOACInputSchema,
|
|
3936
|
+
LedgerJournalEntryArtifactSchema,
|
|
3524
3937
|
ListPayoutDestinationsResultSchema,
|
|
3525
3938
|
MEMBERSHIP_ROLES,
|
|
3526
3939
|
MERCHANT_PAYOUT_STATUSES,
|
|
@@ -3531,11 +3944,14 @@ export {
|
|
|
3531
3944
|
NGN_CURRENCY_CODE,
|
|
3532
3945
|
NG_COUNTRY_CODE,
|
|
3533
3946
|
NQRParseError,
|
|
3947
|
+
NqrPaymentRequestArtifactSchema,
|
|
3534
3948
|
OACSchema,
|
|
3535
3949
|
OAC_DEFAULT_CUMULATIVE_KOBO,
|
|
3536
3950
|
OAC_DEFAULT_PER_TX_KOBO,
|
|
3537
3951
|
OAC_DEFAULT_VALIDITY_MS,
|
|
3952
|
+
OfflineClaimArtifactSchema,
|
|
3538
3953
|
OfflineHoldRecordSchema,
|
|
3954
|
+
OfflinePaymentAuthorizationArtifactSchema,
|
|
3539
3955
|
OfflinePaymentAuthorizationSchema,
|
|
3540
3956
|
OfflinePaymentRequestSchema,
|
|
3541
3957
|
OfflineStateResultSchema,
|
|
@@ -3554,10 +3970,12 @@ export {
|
|
|
3554
3970
|
PartnerFundingEventInputSchema,
|
|
3555
3971
|
PartnerFundingSchema,
|
|
3556
3972
|
PartnerProfileSchema,
|
|
3973
|
+
PassArtifactSchema,
|
|
3557
3974
|
PassMetadataSchema,
|
|
3558
3975
|
PassSchema,
|
|
3559
3976
|
PayCollectionInputSchema,
|
|
3560
3977
|
PaymentClaimSchema,
|
|
3978
|
+
PaymentIntentArtifactSchema,
|
|
3561
3979
|
PayoutDestinationSchema,
|
|
3562
3980
|
PayoutEventInputSchema,
|
|
3563
3981
|
ProviderEventInputSchema,
|
|
@@ -3566,22 +3984,29 @@ export {
|
|
|
3566
3984
|
RECEIPT_CHANNELS,
|
|
3567
3985
|
RECEIPT_KINDS,
|
|
3568
3986
|
REPLAY_WINDOW_MS,
|
|
3987
|
+
ReceiptArtifactSchema,
|
|
3569
3988
|
ReceiptPayloadSchema,
|
|
3570
3989
|
ReceiptSchema,
|
|
3571
3990
|
ReconciliationReportSchema,
|
|
3572
3991
|
RecordPayoutEventResultSchema,
|
|
3573
3992
|
RedemptionSchema,
|
|
3574
3993
|
RegisterDeviceKeyInputSchema,
|
|
3994
|
+
ReversalRecordArtifactSchema,
|
|
3575
3995
|
RevokeDeviceKeyInputSchema,
|
|
3576
3996
|
SETTLEMENT_SCHEDULES,
|
|
3577
3997
|
SettleResponseSchema,
|
|
3998
|
+
SettlementRecordArtifactSchema,
|
|
3578
3999
|
SettlementSchema,
|
|
3579
4000
|
SignedConsumerOACSchema,
|
|
4001
|
+
StatementArtifactSchema,
|
|
3580
4002
|
UpsertMerchantProfileInputSchema,
|
|
3581
4003
|
UpsertPartnerProfileInputSchema,
|
|
3582
4004
|
WITHDRAWAL_STATES,
|
|
3583
4005
|
WithdrawalSchema,
|
|
4006
|
+
base64UrlDecode,
|
|
4007
|
+
base64UrlEncode,
|
|
3584
4008
|
bodySha256Hex,
|
|
4009
|
+
buildArtifactBody,
|
|
3585
4010
|
buildAuthorization,
|
|
3586
4011
|
buildOAC,
|
|
3587
4012
|
buildPass,
|
|
@@ -3597,21 +4022,26 @@ export {
|
|
|
3597
4022
|
crc16ccittHex,
|
|
3598
4023
|
createAccountsClient,
|
|
3599
4024
|
createApiCredentialsAdminClient,
|
|
4025
|
+
createArtifactUri,
|
|
3600
4026
|
createCollectionsClient,
|
|
3601
4027
|
createConsumerCollectionsClient,
|
|
3602
4028
|
createConsumerWithdrawalsClient,
|
|
3603
4029
|
createFlurPartnerClient,
|
|
3604
4030
|
createHmacFetch,
|
|
3605
4031
|
createMeOfflineClient,
|
|
4032
|
+
createOfflinePaymentAuthorizationArtifactUri,
|
|
3606
4033
|
createOfflineSettlementsClient,
|
|
3607
4034
|
createPartnerCollectionsClient,
|
|
3608
4035
|
createPartnerFundingClient,
|
|
3609
4036
|
createPartnerProfileAdminClient,
|
|
3610
4037
|
createPassesClient,
|
|
4038
|
+
createReceiptArtifactUri,
|
|
3611
4039
|
createReceiptsClient,
|
|
4040
|
+
decodeArtifactUri,
|
|
3612
4041
|
decodeAuthorizationQR,
|
|
3613
4042
|
decodeBase45,
|
|
3614
4043
|
decodePaymentRequestQR,
|
|
4044
|
+
encodeArtifactUri,
|
|
3615
4045
|
encodeAuthorizationQR,
|
|
3616
4046
|
encodeBase45,
|
|
3617
4047
|
encodeNQR,
|
|
@@ -3621,6 +4051,8 @@ export {
|
|
|
3621
4051
|
generateKeyPair,
|
|
3622
4052
|
generateStaticQR,
|
|
3623
4053
|
init,
|
|
4054
|
+
isHardenedArtifactType,
|
|
4055
|
+
isKnownArtifactType,
|
|
3624
4056
|
isPassWithinValidity,
|
|
3625
4057
|
moneyMinorToNumber,
|
|
3626
4058
|
normalizeE164,
|
|
@@ -3631,6 +4063,7 @@ export {
|
|
|
3631
4063
|
readTLV,
|
|
3632
4064
|
routingHint,
|
|
3633
4065
|
sign,
|
|
4066
|
+
signArtifact,
|
|
3634
4067
|
signAuthorization,
|
|
3635
4068
|
signCanonical,
|
|
3636
4069
|
signOAC,
|
|
@@ -3641,6 +4074,8 @@ export {
|
|
|
3641
4074
|
signRedemption,
|
|
3642
4075
|
signRequestHMAC,
|
|
3643
4076
|
verify,
|
|
4077
|
+
verifyArtifactSignature,
|
|
4078
|
+
verifyArtifactUri,
|
|
3644
4079
|
verifyAuthorization,
|
|
3645
4080
|
verifyCanonical,
|
|
3646
4081
|
verifyOAC,
|