@nokinc-flur/sdk 2.1.0 → 2.3.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.js CHANGED
@@ -2961,7 +2961,17 @@ var Base64Std3 = z13.string().regex(/^[A-Za-z0-9+/]+={0,2}$/);
2961
2961
  var ClaimNonce = z13.string().min(8).max(128).refine((value) => !value.includes("|"), {
2962
2962
  message: "nonce must not contain |"
2963
2963
  });
2964
- var ACCOUNT_FUNDED_OAC_MAX_TTL_MS = 1e3 * 60 * 60 * 24 * 7;
2964
+ var ACCOUNT_FUNDED_OAC_MAX_TTL_MS = 1e3 * 60 * 60 * 24;
2965
+ var IssuerTrustKeySchema = z13.object({
2966
+ issuerId: z13.string().min(1).max(128),
2967
+ alg: z13.literal("p256"),
2968
+ publicKeySpkiB64: Base64Std3.min(64).max(4096),
2969
+ notBeforeMs: z13.number().int().nonnegative().optional(),
2970
+ notAfterMs: z13.number().int().positive().optional()
2971
+ });
2972
+ var IssuerTrustBundleSchema = z13.object({
2973
+ keys: z13.array(IssuerTrustKeySchema).min(1)
2974
+ });
2965
2975
  var CONSUMER_OFFLINE_CLAIM_SUBMIT_GRACE_MS = 1e3 * 60 * 60 * 24;
2966
2976
  var AttestationSecurityLevelSchema = z13.enum([
2967
2977
  "STRONGBOX",
@@ -3015,13 +3025,28 @@ var ConsumerOACSchema = z13.object({
3015
3025
  alg: z13.literal("p256"),
3016
3026
  /** P-256 SubjectPublicKeyInfo DER, base64. */
3017
3027
  devicePubkeySpkiB64: Base64Std3.min(64).max(4096),
3018
- perTxCapKobo: z13.number().int().positive(),
3019
- cumulativeCapKobo: z13.number().int().positive(),
3028
+ /**
3029
+ * Per-transaction / cumulative offline spend ceilings. Zero is valid and
3030
+ * denotes an identity-only OAC: the credential proves who the holder is and
3031
+ * binds their device key for offline-verifiable first contact, but carries
3032
+ * no offline spend authority (every claim against it routes to REVIEW).
3033
+ * Issued to zero-balance wallets so they can still be paid offline.
3034
+ */
3035
+ perTxCapKobo: z13.number().int().nonnegative(),
3036
+ cumulativeCapKobo: z13.number().int().nonnegative(),
3020
3037
  currency: z13.string().length(3),
3021
3038
  validFromMs: z13.number().int().nonnegative(),
3022
3039
  validUntilMs: z13.number().int().nonnegative(),
3023
3040
  counterSeed: z13.number().int().nonnegative(),
3024
- issuedAtMs: z13.number().int().nonnegative()
3041
+ issuedAtMs: z13.number().int().nonnegative(),
3042
+ /**
3043
+ * Issuer-attested identity folded into the OAC so a single signed
3044
+ * credential serves both Tier B offline-verifiable identity and offline
3045
+ * spend authority. Verified offline against a pinned issuer key; the
3046
+ * backend remains authoritative at settlement.
3047
+ */
3048
+ phoneE164: z13.string().regex(/^\+[1-9]\d{7,14}$/),
3049
+ displayName: z13.string().min(1).max(64)
3025
3050
  });
3026
3051
  var SignedConsumerOACSchema = z13.object({
3027
3052
  oac: ConsumerOACSchema,
@@ -3189,6 +3214,12 @@ function createMeOfflineClient(opts) {
3189
3214
  `/v1/me/offline/settlements/${encodeURIComponent(idOrKey)}`,
3190
3215
  void 0,
3191
3216
  (raw) => ConsumerSettlementSchema.parse(raw)
3217
+ ),
3218
+ getIssuerKeys: () => call(
3219
+ "GET",
3220
+ "/v1/issuer/keys",
3221
+ void 0,
3222
+ (raw) => IssuerTrustBundleSchema.parse(raw)
3192
3223
  )
3193
3224
  };
3194
3225
  }
@@ -3549,13 +3580,101 @@ function base64UrlDecodeUtf8(input) {
3549
3580
  throw new Error("base64 decoder unavailable");
3550
3581
  }
3551
3582
 
3583
+ // src/me-offline/oac.ts
3584
+ var CONSUMER_OAC_DOMAIN = "flur:consumer-offline:v1:oac";
3585
+ function consumerOacSigningPayload(oac) {
3586
+ return { domain: CONSUMER_OAC_DOMAIN, ...oac };
3587
+ }
3588
+ function verifyOacOffline(signed, trustedKeys, options = {}) {
3589
+ const parsed = SignedConsumerOACSchema.safeParse(signed);
3590
+ if (!parsed.success) return { ok: false, reason: "malformed" };
3591
+ const oacParsed = ConsumerOACSchema.safeParse(parsed.data.oac);
3592
+ if (!oacParsed.success) return { ok: false, reason: "malformed" };
3593
+ const oac = oacParsed.data;
3594
+ const nowMs = options.nowMs ?? Date.now();
3595
+ const pinned = trustedKeys.filter(
3596
+ (k) => k.issuerId === oac.issuerId && (k.notBeforeMs === void 0 || nowMs >= k.notBeforeMs) && (k.notAfterMs === void 0 || nowMs <= k.notAfterMs)
3597
+ );
3598
+ if (pinned.length === 0) return { ok: false, reason: "untrusted_issuer" };
3599
+ const signingBytes = canonicalJSONBytes(consumerOacSigningPayload(oac));
3600
+ const signatureOk = pinned.some(
3601
+ (k) => verifyIssuerP256(signingBytes, parsed.data.issuerSig, k.publicKeySpkiB64)
3602
+ );
3603
+ if (!signatureOk) return { ok: false, reason: "signature_invalid" };
3604
+ if (oac.validUntilMs - oac.validFromMs > ACCOUNT_FUNDED_OAC_MAX_TTL_MS) {
3605
+ return { ok: false, reason: "window_too_long" };
3606
+ }
3607
+ if (nowMs < oac.validFromMs) return { ok: false, reason: "not_yet_valid" };
3608
+ if (nowMs >= oac.validUntilMs) return { ok: false, reason: "expired" };
3609
+ return {
3610
+ ok: true,
3611
+ oac,
3612
+ identity: {
3613
+ oacId: oac.oacId,
3614
+ issuerId: oac.issuerId,
3615
+ userId: oac.userId,
3616
+ phoneE164: oac.phoneE164,
3617
+ displayName: oac.displayName,
3618
+ devicePubkeySpkiB64: oac.devicePubkeySpkiB64
3619
+ }
3620
+ };
3621
+ }
3622
+ var CONSUMER_OAC_QR_PREFIX = "FLUROAC1.";
3623
+ function isConsumerOacQR(value) {
3624
+ return value.startsWith(CONSUMER_OAC_QR_PREFIX);
3625
+ }
3626
+ function encodeConsumerOacQR(signed) {
3627
+ const parsed = SignedConsumerOACSchema.parse(signed);
3628
+ return `${CONSUMER_OAC_QR_PREFIX}${base64UrlEncodeUtf82(JSON.stringify(parsed))}`;
3629
+ }
3630
+ function decodeUnverifiedConsumerOacQR(value) {
3631
+ if (!value.startsWith(CONSUMER_OAC_QR_PREFIX)) {
3632
+ throw new Error("not a Flur consumer OAC QR");
3633
+ }
3634
+ const encoded = value.slice(CONSUMER_OAC_QR_PREFIX.length);
3635
+ let raw;
3636
+ try {
3637
+ raw = JSON.parse(base64UrlDecodeUtf82(encoded));
3638
+ } catch {
3639
+ throw new Error("consumer OAC QR is malformed");
3640
+ }
3641
+ return SignedConsumerOACSchema.parse(raw);
3642
+ }
3643
+ function base64UrlEncodeUtf82(input) {
3644
+ const bytes = new TextEncoder().encode(input);
3645
+ let binary = "";
3646
+ for (const byte of bytes) binary += String.fromCharCode(byte);
3647
+ const base64 = typeof btoa === "function" ? btoa(binary) : typeof Buffer !== "undefined" ? Buffer.from(bytes).toString("base64") : void 0;
3648
+ if (!base64) throw new Error("base64 encoder unavailable");
3649
+ return base64.replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, "");
3650
+ }
3651
+ function base64UrlDecodeUtf82(input) {
3652
+ const base64 = input.replace(/-/g, "+").replace(/_/g, "/");
3653
+ const padded = base64.padEnd(
3654
+ base64.length + (4 - base64.length % 4) % 4,
3655
+ "="
3656
+ );
3657
+ if (typeof atob === "function") {
3658
+ const binary = atob(padded);
3659
+ const bytes = new Uint8Array(binary.length);
3660
+ for (let index = 0; index < binary.length; index++) {
3661
+ bytes[index] = binary.charCodeAt(index);
3662
+ }
3663
+ return new TextDecoder().decode(bytes);
3664
+ }
3665
+ if (typeof Buffer !== "undefined") {
3666
+ return Buffer.from(padded, "base64").toString("utf8");
3667
+ }
3668
+ throw new Error("base64 decoder unavailable");
3669
+ }
3670
+
3552
3671
  // src/me-offline/sms.ts
3553
3672
  import { p256 as p2563 } from "@noble/curves/nist";
3554
3673
  var OFFLINE_CLAIM_SMS_PREFIX = "FLURC1.";
3555
3674
  var CLAIM_TOKEN_RE = /(?:^|\s)(FLURC1\.[A-Za-z0-9_-]+={0,2})(?:\s|$)/;
3556
3675
  function encodeOfflineClaimSmsMessage(claim) {
3557
3676
  const parsed = ConsumerPaymentClaimSchema.parse(claim);
3558
- return `${OFFLINE_CLAIM_SMS_PREFIX}${base64UrlEncodeUtf82(
3677
+ return `${OFFLINE_CLAIM_SMS_PREFIX}${base64UrlEncodeUtf83(
3559
3678
  JSON.stringify(parsed)
3560
3679
  )}`;
3561
3680
  }
@@ -3565,7 +3684,7 @@ function decodeOfflineClaimSmsMessage(message) {
3565
3684
  const encoded = token.slice(OFFLINE_CLAIM_SMS_PREFIX.length);
3566
3685
  let raw;
3567
3686
  try {
3568
- raw = JSON.parse(base64UrlDecodeUtf82(encoded));
3687
+ raw = JSON.parse(base64UrlDecodeUtf83(encoded));
3569
3688
  } catch {
3570
3689
  throw new Error("offline claim QR token is malformed");
3571
3690
  }
@@ -3791,10 +3910,10 @@ function bytesToBase64Url(bytes) {
3791
3910
  }
3792
3911
  return base64.replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, "");
3793
3912
  }
3794
- function base64UrlEncodeUtf82(input) {
3913
+ function base64UrlEncodeUtf83(input) {
3795
3914
  return bytesToBase64Url(utf8(input));
3796
3915
  }
3797
- function base64UrlDecodeUtf82(input) {
3916
+ function base64UrlDecodeUtf83(input) {
3798
3917
  return new TextDecoder().decode(base64UrlToBytes(input));
3799
3918
  }
3800
3919
  function base64UrlToBytes(input) {
@@ -4294,7 +4413,10 @@ var ARTIFACT_TYPES = {
4294
4413
  LEDGER_JOURNAL_ENTRY: "ledger_journal_entry",
4295
4414
  STATEMENT: "statement",
4296
4415
  PASS: "pass",
4297
- IDENTITY: "identity"
4416
+ IDENTITY: "identity",
4417
+ // Tier B: holder-signed identity attestation for offline trust. The
4418
+ // envelope.iat / envelope.exp express the card's canonical lifetime.
4419
+ PAY_CARD: "pay_card"
4298
4420
  };
4299
4421
  var HexString = (length) => z17.string().regex(
4300
4422
  new RegExp(`^[0-9a-fA-F]{${length * 2}}$`),
@@ -4432,6 +4554,12 @@ var IdentityArtifactSchema = z17.object({
4432
4554
  claimValueHash: HexString(32),
4433
4555
  attestedAtMs: PositiveInt
4434
4556
  });
4557
+ var PayCardArtifactSchema = z17.object({
4558
+ userId: ShortId,
4559
+ phoneE164: z17.string().regex(/^\+[1-9]\d{7,14}$/, "phoneE164 must be normalised E.164"),
4560
+ displayName: z17.string().min(1).max(64),
4561
+ devicePubKeySpkiB64: z17.string().min(64).max(256).regex(/^[A-Za-z0-9+/]+=*$/, "devicePubKeySpkiB64 must be standard base64")
4562
+ });
4435
4563
  var ARTIFACT_BODY_SCHEMAS = {
4436
4564
  [ARTIFACT_TYPES.OFFLINE_PAYMENT_AUTHORIZATION]: OfflinePaymentAuthorizationArtifactSchema,
4437
4565
  [ARTIFACT_TYPES.RECEIPT]: ReceiptArtifactSchema,
@@ -4443,7 +4571,8 @@ var ARTIFACT_BODY_SCHEMAS = {
4443
4571
  [ARTIFACT_TYPES.LEDGER_JOURNAL_ENTRY]: LedgerJournalEntryArtifactSchema,
4444
4572
  [ARTIFACT_TYPES.STATEMENT]: StatementArtifactSchema,
4445
4573
  [ARTIFACT_TYPES.PASS]: PassArtifactSchema,
4446
- [ARTIFACT_TYPES.IDENTITY]: IdentityArtifactSchema
4574
+ [ARTIFACT_TYPES.IDENTITY]: IdentityArtifactSchema,
4575
+ [ARTIFACT_TYPES.PAY_CARD]: PayCardArtifactSchema
4447
4576
  };
4448
4577
  var HARDENED_ARTIFACT_TYPES = /* @__PURE__ */ new Set([
4449
4578
  ARTIFACT_TYPES.OFFLINE_PAYMENT_AUTHORIZATION,
@@ -4456,7 +4585,8 @@ var HARDENED_ARTIFACT_TYPES = /* @__PURE__ */ new Set([
4456
4585
  ARTIFACT_TYPES.LEDGER_JOURNAL_ENTRY,
4457
4586
  ARTIFACT_TYPES.STATEMENT,
4458
4587
  ARTIFACT_TYPES.PASS,
4459
- ARTIFACT_TYPES.IDENTITY
4588
+ ARTIFACT_TYPES.IDENTITY,
4589
+ ARTIFACT_TYPES.PAY_CARD
4460
4590
  ]);
4461
4591
  function isKnownArtifactType(t) {
4462
4592
  return Object.values(ARTIFACT_TYPES).includes(t);
@@ -4541,6 +4671,130 @@ function createOfflinePaymentAuthorizationArtifactUri(input) {
4541
4671
  type: ARTIFACT_TYPES.OFFLINE_PAYMENT_AUTHORIZATION
4542
4672
  });
4543
4673
  }
4674
+
4675
+ // src/artifacts/paycard.ts
4676
+ var PAY_CARD_DEFAULT_TTL_MS = 90 * 24 * 60 * 60 * 1e3;
4677
+ var PAY_CARD_REFRESH_THRESHOLD_MS = 30 * 24 * 60 * 60 * 1e3;
4678
+ var PAY_CARD_URI_PREFIX = `${FLUR_ARTIFACT_URI_PREFIX}${ARTIFACT_TYPES.PAY_CARD}/`;
4679
+ function createPayCardArtifactUri(input) {
4680
+ if (input.data.userId !== input.issuer) {
4681
+ throw new FlurArtifactError(
4682
+ "pay_card.data.userId must equal envelope issuer",
4683
+ "INVALID_BODY"
4684
+ );
4685
+ }
4686
+ const iat = input.issuedAtSeconds ?? Math.floor(Date.now() / 1e3);
4687
+ const exp = input.expiresAtSeconds ?? iat + Math.floor(PAY_CARD_DEFAULT_TTL_MS / 1e3);
4688
+ return createArtifactUri({
4689
+ type: ARTIFACT_TYPES.PAY_CARD,
4690
+ issuer: input.issuer,
4691
+ keyId: input.keyId,
4692
+ privateKey: input.privateKey,
4693
+ nonce: input.nonce,
4694
+ issuedAtSeconds: iat,
4695
+ expiresAtSeconds: exp,
4696
+ data: input.data
4697
+ });
4698
+ }
4699
+ function isPayCardArtifactUri(uri) {
4700
+ return typeof uri === "string" && uri.startsWith(PAY_CARD_URI_PREFIX);
4701
+ }
4702
+ function decodePayCardArtifact(uri) {
4703
+ if (!isPayCardArtifactUri(uri)) {
4704
+ throw new FlurArtifactError(
4705
+ `URI does not start with ${PAY_CARD_URI_PREFIX}`,
4706
+ "INVALID_URI"
4707
+ );
4708
+ }
4709
+ const decoded = decodeArtifactUri(uri);
4710
+ if (decoded.type !== ARTIFACT_TYPES.PAY_CARD) {
4711
+ throw new FlurArtifactError(
4712
+ `Expected pay_card, got ${decoded.type}`,
4713
+ "TYPE_MISMATCH"
4714
+ );
4715
+ }
4716
+ const parsed = PayCardArtifactSchema.safeParse(decoded.body.data);
4717
+ if (!parsed.success) {
4718
+ throw new FlurArtifactError(
4719
+ `pay_card body invalid: ${parsed.error.message}`,
4720
+ "INVALID_BODY"
4721
+ );
4722
+ }
4723
+ if (parsed.data.userId !== decoded.body.iss) {
4724
+ throw new FlurArtifactError(
4725
+ "pay_card.data.userId must equal envelope issuer",
4726
+ "INVALID_BODY"
4727
+ );
4728
+ }
4729
+ return {
4730
+ body: {
4731
+ ...decoded.body,
4732
+ data: parsed.data
4733
+ },
4734
+ sig: decoded.sig,
4735
+ decoded
4736
+ };
4737
+ }
4738
+ function verifyPayCardArtifact(uri, publicKeySpkiB64, options = {}) {
4739
+ if (!isPayCardArtifactUri(uri)) {
4740
+ throw new FlurArtifactError(
4741
+ `URI does not start with ${PAY_CARD_URI_PREFIX}`,
4742
+ "INVALID_URI"
4743
+ );
4744
+ }
4745
+ const verified = verifyArtifactUri(
4746
+ uri,
4747
+ publicKeySpkiB64,
4748
+ options
4749
+ );
4750
+ if (verified.decoded.type !== ARTIFACT_TYPES.PAY_CARD) {
4751
+ throw new FlurArtifactError(
4752
+ `Expected pay_card, got ${verified.decoded.type}`,
4753
+ "TYPE_MISMATCH"
4754
+ );
4755
+ }
4756
+ if (verified.body.data.userId !== verified.body.iss) {
4757
+ throw new FlurArtifactError(
4758
+ "pay_card.data.userId must equal envelope issuer",
4759
+ "INVALID_BODY"
4760
+ );
4761
+ }
4762
+ return {
4763
+ body: verified.body,
4764
+ sig: verified.sig,
4765
+ decoded: verified.decoded
4766
+ };
4767
+ }
4768
+ function inspectPayCardFreshness(decoded, nowMs = Date.now()) {
4769
+ const exp = decoded.body.exp;
4770
+ if (exp === void 0) return "no_expiry";
4771
+ const remainingMs = exp * 1e3 - nowMs;
4772
+ if (remainingMs <= 0) return "expired";
4773
+ if (remainingMs <= PAY_CARD_REFRESH_THRESHOLD_MS)
4774
+ return "refresh_recommended";
4775
+ return "fresh";
4776
+ }
4777
+ function buildPayCardSigningInput(input) {
4778
+ if (input.data.userId !== input.issuer) {
4779
+ throw new FlurArtifactError(
4780
+ "pay_card.data.userId must equal envelope issuer",
4781
+ "INVALID_BODY"
4782
+ );
4783
+ }
4784
+ const parsedData = PayCardArtifactSchema.parse(input.data);
4785
+ const iat = input.issuedAtSeconds ?? Math.floor(Date.now() / 1e3);
4786
+ const exp = input.expiresAtSeconds ?? iat + Math.floor(PAY_CARD_DEFAULT_TTL_MS / 1e3);
4787
+ const body = buildArtifactBody({
4788
+ type: ARTIFACT_TYPES.PAY_CARD,
4789
+ issuer: input.issuer,
4790
+ keyId: input.keyId,
4791
+ data: parsedData,
4792
+ nonce: input.nonce,
4793
+ issuedAtSeconds: iat,
4794
+ expiresAtSeconds: exp
4795
+ });
4796
+ return { body, bodyBytes: canonicalJSONBytes(body) };
4797
+ }
4544
4798
  export {
4545
4799
  ACCOUNT_FUNDED_OAC_MAX_TTL_MS,
4546
4800
  ACCOUNT_STATUSES,
@@ -4556,6 +4810,8 @@ export {
4556
4810
  CLAIM_DOMAIN_V2,
4557
4811
  COLLECTION_INTENT_STATUSES,
4558
4812
  COLLECTION_PAYMENT_STATUSES,
4813
+ CONSUMER_OAC_DOMAIN,
4814
+ CONSUMER_OAC_QR_PREFIX,
4559
4815
  CONSUMER_OFFLINE_CLAIM_SUBMIT_GRACE_MS,
4560
4816
  CONSUMER_PAYMENT_REQUEST_DOMAIN,
4561
4817
  CONSUMER_SETTLEMENT_DOMAIN,
@@ -4594,6 +4850,8 @@ export {
4594
4850
  IdentityArtifactSchema,
4595
4851
  IngestFundingResultSchema,
4596
4852
  IssueAccountOacInputSchema,
4853
+ IssuerTrustBundleSchema,
4854
+ IssuerTrustKeySchema,
4597
4855
  LedgerJournalEntryArtifactSchema,
4598
4856
  ListPayoutDestinationsResultSchema,
4599
4857
  MEMBERSHIP_ROLES,
@@ -4634,6 +4892,9 @@ export {
4634
4892
  PASS_STATES,
4635
4893
  PAYLOAD_FORMAT_INDICATOR_VALUE,
4636
4894
  PAYOUT_DESTINATION_STATUSES,
4895
+ PAY_CARD_DEFAULT_TTL_MS,
4896
+ PAY_CARD_REFRESH_THRESHOLD_MS,
4897
+ PAY_CARD_URI_PREFIX,
4637
4898
  POINT_OF_INITIATION,
4638
4899
  PartnerFundingEventInputSchema,
4639
4900
  PartnerFundingSchema,
@@ -4641,6 +4902,7 @@ export {
4641
4902
  PassArtifactSchema,
4642
4903
  PassMetadataSchema,
4643
4904
  PassSchema,
4905
+ PayCardArtifactSchema,
4644
4906
  PayCollectionInputSchema,
4645
4907
  PaymentClaimSchema,
4646
4908
  PaymentIntentArtifactSchema,
@@ -4679,6 +4941,7 @@ export {
4679
4941
  buildConsumerPaymentRequest,
4680
4942
  buildOAC,
4681
4943
  buildPass,
4944
+ buildPayCardSigningInput,
4682
4945
  buildPaymentRequest,
4683
4946
  buildReceipt,
4684
4947
  buildRedemption,
@@ -4692,6 +4955,7 @@ export {
4692
4955
  computeConsumerClaimEncounterId,
4693
4956
  computeEncounterId,
4694
4957
  constantTimeEqual,
4958
+ consumerOacSigningPayload,
4695
4959
  consumerPaymentRequestSigningBytes,
4696
4960
  consumerPaymentRequestSigningPayload,
4697
4961
  consumerSettlementSigningPayload,
@@ -4712,6 +4976,7 @@ export {
4712
4976
  createPartnerFundingClient,
4713
4977
  createPartnerProfileAdminClient,
4714
4978
  createPassesClient,
4979
+ createPayCardArtifactUri,
4715
4980
  createReceiptArtifactUri,
4716
4981
  createReceiptsClient,
4717
4982
  createSoftwareP256Signer,
@@ -4721,12 +4986,15 @@ export {
4721
4986
  decodeConsumerSettlementReceiptQR,
4722
4987
  decodeOfflineClaimSmsMessage,
4723
4988
  decodeOfflineSmsSettleToken,
4989
+ decodePayCardArtifact,
4724
4990
  decodePaymentRequestQR,
4991
+ decodeUnverifiedConsumerOacQR,
4725
4992
  decodeUnverifiedConsumerSettlementReceiptQR,
4726
4993
  derToRawP256Signature,
4727
4994
  encodeArtifactUri,
4728
4995
  encodeAuthorizationQR,
4729
4996
  encodeBase45,
4997
+ encodeConsumerOacQR,
4730
4998
  encodeConsumerSettlementReceiptQR,
4731
4999
  encodeNQR,
4732
5000
  encodeOfflineClaimSmsMessage,
@@ -4738,10 +5006,13 @@ export {
4738
5006
  generateDynamicQR,
4739
5007
  generateStaticQR,
4740
5008
  init,
5009
+ inspectPayCardFreshness,
5010
+ isConsumerOacQR,
4741
5011
  isConsumerPaymentRequestExpired,
4742
5012
  isHardenedArtifactType,
4743
5013
  isKnownArtifactType,
4744
5014
  isPassWithinValidity,
5015
+ isPayCardArtifactUri,
4745
5016
  moneyMinorToNumber,
4746
5017
  normalizeE164,
4747
5018
  parseAmountInput,
@@ -4767,8 +5038,10 @@ export {
4767
5038
  verifyConsumerSettlement,
4768
5039
  verifyConsumerSettlementReceiptQR,
4769
5040
  verifyOAC,
5041
+ verifyOacOffline,
4770
5042
  verifyOfflineSmsSettleToken,
4771
5043
  verifyPass,
5044
+ verifyPayCardArtifact,
4772
5045
  verifyPaymentRequest,
4773
5046
  verifyReceipt,
4774
5047
  verifyRedemption,