@nokinc-flur/sdk 2.1.0 → 2.2.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 +158 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +185 -1
- package/dist/index.d.ts +185 -1
- package/dist/index.js +148 -3
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -4294,7 +4294,10 @@ var ARTIFACT_TYPES = {
|
|
|
4294
4294
|
LEDGER_JOURNAL_ENTRY: "ledger_journal_entry",
|
|
4295
4295
|
STATEMENT: "statement",
|
|
4296
4296
|
PASS: "pass",
|
|
4297
|
-
IDENTITY: "identity"
|
|
4297
|
+
IDENTITY: "identity",
|
|
4298
|
+
// Tier B: holder-signed identity attestation for offline trust. The
|
|
4299
|
+
// envelope.iat / envelope.exp express the card's canonical lifetime.
|
|
4300
|
+
PAY_CARD: "pay_card"
|
|
4298
4301
|
};
|
|
4299
4302
|
var HexString = (length) => z17.string().regex(
|
|
4300
4303
|
new RegExp(`^[0-9a-fA-F]{${length * 2}}$`),
|
|
@@ -4432,6 +4435,12 @@ var IdentityArtifactSchema = z17.object({
|
|
|
4432
4435
|
claimValueHash: HexString(32),
|
|
4433
4436
|
attestedAtMs: PositiveInt
|
|
4434
4437
|
});
|
|
4438
|
+
var PayCardArtifactSchema = z17.object({
|
|
4439
|
+
userId: ShortId,
|
|
4440
|
+
phoneE164: z17.string().regex(/^\+[1-9]\d{7,14}$/, "phoneE164 must be normalised E.164"),
|
|
4441
|
+
displayName: z17.string().min(1).max(64),
|
|
4442
|
+
devicePubKeySpkiB64: z17.string().min(64).max(256).regex(/^[A-Za-z0-9+/]+=*$/, "devicePubKeySpkiB64 must be standard base64")
|
|
4443
|
+
});
|
|
4435
4444
|
var ARTIFACT_BODY_SCHEMAS = {
|
|
4436
4445
|
[ARTIFACT_TYPES.OFFLINE_PAYMENT_AUTHORIZATION]: OfflinePaymentAuthorizationArtifactSchema,
|
|
4437
4446
|
[ARTIFACT_TYPES.RECEIPT]: ReceiptArtifactSchema,
|
|
@@ -4443,7 +4452,8 @@ var ARTIFACT_BODY_SCHEMAS = {
|
|
|
4443
4452
|
[ARTIFACT_TYPES.LEDGER_JOURNAL_ENTRY]: LedgerJournalEntryArtifactSchema,
|
|
4444
4453
|
[ARTIFACT_TYPES.STATEMENT]: StatementArtifactSchema,
|
|
4445
4454
|
[ARTIFACT_TYPES.PASS]: PassArtifactSchema,
|
|
4446
|
-
[ARTIFACT_TYPES.IDENTITY]: IdentityArtifactSchema
|
|
4455
|
+
[ARTIFACT_TYPES.IDENTITY]: IdentityArtifactSchema,
|
|
4456
|
+
[ARTIFACT_TYPES.PAY_CARD]: PayCardArtifactSchema
|
|
4447
4457
|
};
|
|
4448
4458
|
var HARDENED_ARTIFACT_TYPES = /* @__PURE__ */ new Set([
|
|
4449
4459
|
ARTIFACT_TYPES.OFFLINE_PAYMENT_AUTHORIZATION,
|
|
@@ -4456,7 +4466,8 @@ var HARDENED_ARTIFACT_TYPES = /* @__PURE__ */ new Set([
|
|
|
4456
4466
|
ARTIFACT_TYPES.LEDGER_JOURNAL_ENTRY,
|
|
4457
4467
|
ARTIFACT_TYPES.STATEMENT,
|
|
4458
4468
|
ARTIFACT_TYPES.PASS,
|
|
4459
|
-
ARTIFACT_TYPES.IDENTITY
|
|
4469
|
+
ARTIFACT_TYPES.IDENTITY,
|
|
4470
|
+
ARTIFACT_TYPES.PAY_CARD
|
|
4460
4471
|
]);
|
|
4461
4472
|
function isKnownArtifactType(t) {
|
|
4462
4473
|
return Object.values(ARTIFACT_TYPES).includes(t);
|
|
@@ -4541,6 +4552,130 @@ function createOfflinePaymentAuthorizationArtifactUri(input) {
|
|
|
4541
4552
|
type: ARTIFACT_TYPES.OFFLINE_PAYMENT_AUTHORIZATION
|
|
4542
4553
|
});
|
|
4543
4554
|
}
|
|
4555
|
+
|
|
4556
|
+
// src/artifacts/paycard.ts
|
|
4557
|
+
var PAY_CARD_DEFAULT_TTL_MS = 90 * 24 * 60 * 60 * 1e3;
|
|
4558
|
+
var PAY_CARD_REFRESH_THRESHOLD_MS = 30 * 24 * 60 * 60 * 1e3;
|
|
4559
|
+
var PAY_CARD_URI_PREFIX = `${FLUR_ARTIFACT_URI_PREFIX}${ARTIFACT_TYPES.PAY_CARD}/`;
|
|
4560
|
+
function createPayCardArtifactUri(input) {
|
|
4561
|
+
if (input.data.userId !== input.issuer) {
|
|
4562
|
+
throw new FlurArtifactError(
|
|
4563
|
+
"pay_card.data.userId must equal envelope issuer",
|
|
4564
|
+
"INVALID_BODY"
|
|
4565
|
+
);
|
|
4566
|
+
}
|
|
4567
|
+
const iat = input.issuedAtSeconds ?? Math.floor(Date.now() / 1e3);
|
|
4568
|
+
const exp = input.expiresAtSeconds ?? iat + Math.floor(PAY_CARD_DEFAULT_TTL_MS / 1e3);
|
|
4569
|
+
return createArtifactUri({
|
|
4570
|
+
type: ARTIFACT_TYPES.PAY_CARD,
|
|
4571
|
+
issuer: input.issuer,
|
|
4572
|
+
keyId: input.keyId,
|
|
4573
|
+
privateKey: input.privateKey,
|
|
4574
|
+
nonce: input.nonce,
|
|
4575
|
+
issuedAtSeconds: iat,
|
|
4576
|
+
expiresAtSeconds: exp,
|
|
4577
|
+
data: input.data
|
|
4578
|
+
});
|
|
4579
|
+
}
|
|
4580
|
+
function isPayCardArtifactUri(uri) {
|
|
4581
|
+
return typeof uri === "string" && uri.startsWith(PAY_CARD_URI_PREFIX);
|
|
4582
|
+
}
|
|
4583
|
+
function decodePayCardArtifact(uri) {
|
|
4584
|
+
if (!isPayCardArtifactUri(uri)) {
|
|
4585
|
+
throw new FlurArtifactError(
|
|
4586
|
+
`URI does not start with ${PAY_CARD_URI_PREFIX}`,
|
|
4587
|
+
"INVALID_URI"
|
|
4588
|
+
);
|
|
4589
|
+
}
|
|
4590
|
+
const decoded = decodeArtifactUri(uri);
|
|
4591
|
+
if (decoded.type !== ARTIFACT_TYPES.PAY_CARD) {
|
|
4592
|
+
throw new FlurArtifactError(
|
|
4593
|
+
`Expected pay_card, got ${decoded.type}`,
|
|
4594
|
+
"TYPE_MISMATCH"
|
|
4595
|
+
);
|
|
4596
|
+
}
|
|
4597
|
+
const parsed = PayCardArtifactSchema.safeParse(decoded.body.data);
|
|
4598
|
+
if (!parsed.success) {
|
|
4599
|
+
throw new FlurArtifactError(
|
|
4600
|
+
`pay_card body invalid: ${parsed.error.message}`,
|
|
4601
|
+
"INVALID_BODY"
|
|
4602
|
+
);
|
|
4603
|
+
}
|
|
4604
|
+
if (parsed.data.userId !== decoded.body.iss) {
|
|
4605
|
+
throw new FlurArtifactError(
|
|
4606
|
+
"pay_card.data.userId must equal envelope issuer",
|
|
4607
|
+
"INVALID_BODY"
|
|
4608
|
+
);
|
|
4609
|
+
}
|
|
4610
|
+
return {
|
|
4611
|
+
body: {
|
|
4612
|
+
...decoded.body,
|
|
4613
|
+
data: parsed.data
|
|
4614
|
+
},
|
|
4615
|
+
sig: decoded.sig,
|
|
4616
|
+
decoded
|
|
4617
|
+
};
|
|
4618
|
+
}
|
|
4619
|
+
function verifyPayCardArtifact(uri, publicKeySpkiB64, options = {}) {
|
|
4620
|
+
if (!isPayCardArtifactUri(uri)) {
|
|
4621
|
+
throw new FlurArtifactError(
|
|
4622
|
+
`URI does not start with ${PAY_CARD_URI_PREFIX}`,
|
|
4623
|
+
"INVALID_URI"
|
|
4624
|
+
);
|
|
4625
|
+
}
|
|
4626
|
+
const verified = verifyArtifactUri(
|
|
4627
|
+
uri,
|
|
4628
|
+
publicKeySpkiB64,
|
|
4629
|
+
options
|
|
4630
|
+
);
|
|
4631
|
+
if (verified.decoded.type !== ARTIFACT_TYPES.PAY_CARD) {
|
|
4632
|
+
throw new FlurArtifactError(
|
|
4633
|
+
`Expected pay_card, got ${verified.decoded.type}`,
|
|
4634
|
+
"TYPE_MISMATCH"
|
|
4635
|
+
);
|
|
4636
|
+
}
|
|
4637
|
+
if (verified.body.data.userId !== verified.body.iss) {
|
|
4638
|
+
throw new FlurArtifactError(
|
|
4639
|
+
"pay_card.data.userId must equal envelope issuer",
|
|
4640
|
+
"INVALID_BODY"
|
|
4641
|
+
);
|
|
4642
|
+
}
|
|
4643
|
+
return {
|
|
4644
|
+
body: verified.body,
|
|
4645
|
+
sig: verified.sig,
|
|
4646
|
+
decoded: verified.decoded
|
|
4647
|
+
};
|
|
4648
|
+
}
|
|
4649
|
+
function inspectPayCardFreshness(decoded, nowMs = Date.now()) {
|
|
4650
|
+
const exp = decoded.body.exp;
|
|
4651
|
+
if (exp === void 0) return "no_expiry";
|
|
4652
|
+
const remainingMs = exp * 1e3 - nowMs;
|
|
4653
|
+
if (remainingMs <= 0) return "expired";
|
|
4654
|
+
if (remainingMs <= PAY_CARD_REFRESH_THRESHOLD_MS)
|
|
4655
|
+
return "refresh_recommended";
|
|
4656
|
+
return "fresh";
|
|
4657
|
+
}
|
|
4658
|
+
function buildPayCardSigningInput(input) {
|
|
4659
|
+
if (input.data.userId !== input.issuer) {
|
|
4660
|
+
throw new FlurArtifactError(
|
|
4661
|
+
"pay_card.data.userId must equal envelope issuer",
|
|
4662
|
+
"INVALID_BODY"
|
|
4663
|
+
);
|
|
4664
|
+
}
|
|
4665
|
+
const parsedData = PayCardArtifactSchema.parse(input.data);
|
|
4666
|
+
const iat = input.issuedAtSeconds ?? Math.floor(Date.now() / 1e3);
|
|
4667
|
+
const exp = input.expiresAtSeconds ?? iat + Math.floor(PAY_CARD_DEFAULT_TTL_MS / 1e3);
|
|
4668
|
+
const body = buildArtifactBody({
|
|
4669
|
+
type: ARTIFACT_TYPES.PAY_CARD,
|
|
4670
|
+
issuer: input.issuer,
|
|
4671
|
+
keyId: input.keyId,
|
|
4672
|
+
data: parsedData,
|
|
4673
|
+
nonce: input.nonce,
|
|
4674
|
+
issuedAtSeconds: iat,
|
|
4675
|
+
expiresAtSeconds: exp
|
|
4676
|
+
});
|
|
4677
|
+
return { body, bodyBytes: canonicalJSONBytes(body) };
|
|
4678
|
+
}
|
|
4544
4679
|
export {
|
|
4545
4680
|
ACCOUNT_FUNDED_OAC_MAX_TTL_MS,
|
|
4546
4681
|
ACCOUNT_STATUSES,
|
|
@@ -4634,6 +4769,9 @@ export {
|
|
|
4634
4769
|
PASS_STATES,
|
|
4635
4770
|
PAYLOAD_FORMAT_INDICATOR_VALUE,
|
|
4636
4771
|
PAYOUT_DESTINATION_STATUSES,
|
|
4772
|
+
PAY_CARD_DEFAULT_TTL_MS,
|
|
4773
|
+
PAY_CARD_REFRESH_THRESHOLD_MS,
|
|
4774
|
+
PAY_CARD_URI_PREFIX,
|
|
4637
4775
|
POINT_OF_INITIATION,
|
|
4638
4776
|
PartnerFundingEventInputSchema,
|
|
4639
4777
|
PartnerFundingSchema,
|
|
@@ -4641,6 +4779,7 @@ export {
|
|
|
4641
4779
|
PassArtifactSchema,
|
|
4642
4780
|
PassMetadataSchema,
|
|
4643
4781
|
PassSchema,
|
|
4782
|
+
PayCardArtifactSchema,
|
|
4644
4783
|
PayCollectionInputSchema,
|
|
4645
4784
|
PaymentClaimSchema,
|
|
4646
4785
|
PaymentIntentArtifactSchema,
|
|
@@ -4679,6 +4818,7 @@ export {
|
|
|
4679
4818
|
buildConsumerPaymentRequest,
|
|
4680
4819
|
buildOAC,
|
|
4681
4820
|
buildPass,
|
|
4821
|
+
buildPayCardSigningInput,
|
|
4682
4822
|
buildPaymentRequest,
|
|
4683
4823
|
buildReceipt,
|
|
4684
4824
|
buildRedemption,
|
|
@@ -4712,6 +4852,7 @@ export {
|
|
|
4712
4852
|
createPartnerFundingClient,
|
|
4713
4853
|
createPartnerProfileAdminClient,
|
|
4714
4854
|
createPassesClient,
|
|
4855
|
+
createPayCardArtifactUri,
|
|
4715
4856
|
createReceiptArtifactUri,
|
|
4716
4857
|
createReceiptsClient,
|
|
4717
4858
|
createSoftwareP256Signer,
|
|
@@ -4721,6 +4862,7 @@ export {
|
|
|
4721
4862
|
decodeConsumerSettlementReceiptQR,
|
|
4722
4863
|
decodeOfflineClaimSmsMessage,
|
|
4723
4864
|
decodeOfflineSmsSettleToken,
|
|
4865
|
+
decodePayCardArtifact,
|
|
4724
4866
|
decodePaymentRequestQR,
|
|
4725
4867
|
decodeUnverifiedConsumerSettlementReceiptQR,
|
|
4726
4868
|
derToRawP256Signature,
|
|
@@ -4738,10 +4880,12 @@ export {
|
|
|
4738
4880
|
generateDynamicQR,
|
|
4739
4881
|
generateStaticQR,
|
|
4740
4882
|
init,
|
|
4883
|
+
inspectPayCardFreshness,
|
|
4741
4884
|
isConsumerPaymentRequestExpired,
|
|
4742
4885
|
isHardenedArtifactType,
|
|
4743
4886
|
isKnownArtifactType,
|
|
4744
4887
|
isPassWithinValidity,
|
|
4888
|
+
isPayCardArtifactUri,
|
|
4745
4889
|
moneyMinorToNumber,
|
|
4746
4890
|
normalizeE164,
|
|
4747
4891
|
parseAmountInput,
|
|
@@ -4769,6 +4913,7 @@ export {
|
|
|
4769
4913
|
verifyOAC,
|
|
4770
4914
|
verifyOfflineSmsSettleToken,
|
|
4771
4915
|
verifyPass,
|
|
4916
|
+
verifyPayCardArtifact,
|
|
4772
4917
|
verifyPaymentRequest,
|
|
4773
4918
|
verifyReceipt,
|
|
4774
4919
|
verifyRedemption,
|