@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.cjs
CHANGED
|
@@ -122,6 +122,9 @@ __export(index_exports, {
|
|
|
122
122
|
PASS_STATES: () => PASS_STATES,
|
|
123
123
|
PAYLOAD_FORMAT_INDICATOR_VALUE: () => PAYLOAD_FORMAT_INDICATOR_VALUE,
|
|
124
124
|
PAYOUT_DESTINATION_STATUSES: () => PAYOUT_DESTINATION_STATUSES,
|
|
125
|
+
PAY_CARD_DEFAULT_TTL_MS: () => PAY_CARD_DEFAULT_TTL_MS,
|
|
126
|
+
PAY_CARD_REFRESH_THRESHOLD_MS: () => PAY_CARD_REFRESH_THRESHOLD_MS,
|
|
127
|
+
PAY_CARD_URI_PREFIX: () => PAY_CARD_URI_PREFIX,
|
|
125
128
|
POINT_OF_INITIATION: () => POINT_OF_INITIATION,
|
|
126
129
|
PartnerFundingEventInputSchema: () => PartnerFundingEventInputSchema,
|
|
127
130
|
PartnerFundingSchema: () => PartnerFundingSchema,
|
|
@@ -129,6 +132,7 @@ __export(index_exports, {
|
|
|
129
132
|
PassArtifactSchema: () => PassArtifactSchema,
|
|
130
133
|
PassMetadataSchema: () => PassMetadataSchema,
|
|
131
134
|
PassSchema: () => PassSchema,
|
|
135
|
+
PayCardArtifactSchema: () => PayCardArtifactSchema,
|
|
132
136
|
PayCollectionInputSchema: () => PayCollectionInputSchema,
|
|
133
137
|
PaymentClaimSchema: () => PaymentClaimSchema,
|
|
134
138
|
PaymentIntentArtifactSchema: () => PaymentIntentArtifactSchema,
|
|
@@ -167,6 +171,7 @@ __export(index_exports, {
|
|
|
167
171
|
buildConsumerPaymentRequest: () => buildConsumerPaymentRequest,
|
|
168
172
|
buildOAC: () => buildOAC,
|
|
169
173
|
buildPass: () => buildPass,
|
|
174
|
+
buildPayCardSigningInput: () => buildPayCardSigningInput,
|
|
170
175
|
buildPaymentRequest: () => buildPaymentRequest,
|
|
171
176
|
buildReceipt: () => buildReceipt,
|
|
172
177
|
buildRedemption: () => buildRedemption,
|
|
@@ -200,6 +205,7 @@ __export(index_exports, {
|
|
|
200
205
|
createPartnerFundingClient: () => createPartnerFundingClient,
|
|
201
206
|
createPartnerProfileAdminClient: () => createPartnerProfileAdminClient,
|
|
202
207
|
createPassesClient: () => createPassesClient,
|
|
208
|
+
createPayCardArtifactUri: () => createPayCardArtifactUri,
|
|
203
209
|
createReceiptArtifactUri: () => createReceiptArtifactUri,
|
|
204
210
|
createReceiptsClient: () => createReceiptsClient,
|
|
205
211
|
createSoftwareP256Signer: () => createSoftwareP256Signer,
|
|
@@ -209,6 +215,7 @@ __export(index_exports, {
|
|
|
209
215
|
decodeConsumerSettlementReceiptQR: () => decodeConsumerSettlementReceiptQR,
|
|
210
216
|
decodeOfflineClaimSmsMessage: () => decodeOfflineClaimSmsMessage,
|
|
211
217
|
decodeOfflineSmsSettleToken: () => decodeOfflineSmsSettleToken,
|
|
218
|
+
decodePayCardArtifact: () => decodePayCardArtifact,
|
|
212
219
|
decodePaymentRequestQR: () => decodePaymentRequestQR,
|
|
213
220
|
decodeUnverifiedConsumerSettlementReceiptQR: () => decodeUnverifiedConsumerSettlementReceiptQR,
|
|
214
221
|
derToRawP256Signature: () => derToRawP256Signature,
|
|
@@ -226,10 +233,12 @@ __export(index_exports, {
|
|
|
226
233
|
generateDynamicQR: () => generateDynamicQR,
|
|
227
234
|
generateStaticQR: () => generateStaticQR,
|
|
228
235
|
init: () => init,
|
|
236
|
+
inspectPayCardFreshness: () => inspectPayCardFreshness,
|
|
229
237
|
isConsumerPaymentRequestExpired: () => isConsumerPaymentRequestExpired,
|
|
230
238
|
isHardenedArtifactType: () => isHardenedArtifactType,
|
|
231
239
|
isKnownArtifactType: () => isKnownArtifactType,
|
|
232
240
|
isPassWithinValidity: () => isPassWithinValidity,
|
|
241
|
+
isPayCardArtifactUri: () => isPayCardArtifactUri,
|
|
233
242
|
moneyMinorToNumber: () => moneyMinorToNumber,
|
|
234
243
|
normalizeE164: () => normalizeE164,
|
|
235
244
|
parseAmountInput: () => parseAmountInput,
|
|
@@ -257,6 +266,7 @@ __export(index_exports, {
|
|
|
257
266
|
verifyOAC: () => verifyOAC,
|
|
258
267
|
verifyOfflineSmsSettleToken: () => verifyOfflineSmsSettleToken,
|
|
259
268
|
verifyPass: () => verifyPass,
|
|
269
|
+
verifyPayCardArtifact: () => verifyPayCardArtifact,
|
|
260
270
|
verifyPaymentRequest: () => verifyPaymentRequest,
|
|
261
271
|
verifyReceipt: () => verifyReceipt,
|
|
262
272
|
verifyRedemption: () => verifyRedemption,
|
|
@@ -4561,7 +4571,10 @@ var ARTIFACT_TYPES = {
|
|
|
4561
4571
|
LEDGER_JOURNAL_ENTRY: "ledger_journal_entry",
|
|
4562
4572
|
STATEMENT: "statement",
|
|
4563
4573
|
PASS: "pass",
|
|
4564
|
-
IDENTITY: "identity"
|
|
4574
|
+
IDENTITY: "identity",
|
|
4575
|
+
// Tier B: holder-signed identity attestation for offline trust. The
|
|
4576
|
+
// envelope.iat / envelope.exp express the card's canonical lifetime.
|
|
4577
|
+
PAY_CARD: "pay_card"
|
|
4565
4578
|
};
|
|
4566
4579
|
var HexString = (length) => import_zod17.z.string().regex(
|
|
4567
4580
|
new RegExp(`^[0-9a-fA-F]{${length * 2}}$`),
|
|
@@ -4699,6 +4712,12 @@ var IdentityArtifactSchema = import_zod17.z.object({
|
|
|
4699
4712
|
claimValueHash: HexString(32),
|
|
4700
4713
|
attestedAtMs: PositiveInt
|
|
4701
4714
|
});
|
|
4715
|
+
var PayCardArtifactSchema = import_zod17.z.object({
|
|
4716
|
+
userId: ShortId,
|
|
4717
|
+
phoneE164: import_zod17.z.string().regex(/^\+[1-9]\d{7,14}$/, "phoneE164 must be normalised E.164"),
|
|
4718
|
+
displayName: import_zod17.z.string().min(1).max(64),
|
|
4719
|
+
devicePubKeySpkiB64: import_zod17.z.string().min(64).max(256).regex(/^[A-Za-z0-9+/]+=*$/, "devicePubKeySpkiB64 must be standard base64")
|
|
4720
|
+
});
|
|
4702
4721
|
var ARTIFACT_BODY_SCHEMAS = {
|
|
4703
4722
|
[ARTIFACT_TYPES.OFFLINE_PAYMENT_AUTHORIZATION]: OfflinePaymentAuthorizationArtifactSchema,
|
|
4704
4723
|
[ARTIFACT_TYPES.RECEIPT]: ReceiptArtifactSchema,
|
|
@@ -4710,7 +4729,8 @@ var ARTIFACT_BODY_SCHEMAS = {
|
|
|
4710
4729
|
[ARTIFACT_TYPES.LEDGER_JOURNAL_ENTRY]: LedgerJournalEntryArtifactSchema,
|
|
4711
4730
|
[ARTIFACT_TYPES.STATEMENT]: StatementArtifactSchema,
|
|
4712
4731
|
[ARTIFACT_TYPES.PASS]: PassArtifactSchema,
|
|
4713
|
-
[ARTIFACT_TYPES.IDENTITY]: IdentityArtifactSchema
|
|
4732
|
+
[ARTIFACT_TYPES.IDENTITY]: IdentityArtifactSchema,
|
|
4733
|
+
[ARTIFACT_TYPES.PAY_CARD]: PayCardArtifactSchema
|
|
4714
4734
|
};
|
|
4715
4735
|
var HARDENED_ARTIFACT_TYPES = /* @__PURE__ */ new Set([
|
|
4716
4736
|
ARTIFACT_TYPES.OFFLINE_PAYMENT_AUTHORIZATION,
|
|
@@ -4723,7 +4743,8 @@ var HARDENED_ARTIFACT_TYPES = /* @__PURE__ */ new Set([
|
|
|
4723
4743
|
ARTIFACT_TYPES.LEDGER_JOURNAL_ENTRY,
|
|
4724
4744
|
ARTIFACT_TYPES.STATEMENT,
|
|
4725
4745
|
ARTIFACT_TYPES.PASS,
|
|
4726
|
-
ARTIFACT_TYPES.IDENTITY
|
|
4746
|
+
ARTIFACT_TYPES.IDENTITY,
|
|
4747
|
+
ARTIFACT_TYPES.PAY_CARD
|
|
4727
4748
|
]);
|
|
4728
4749
|
function isKnownArtifactType(t) {
|
|
4729
4750
|
return Object.values(ARTIFACT_TYPES).includes(t);
|
|
@@ -4808,6 +4829,130 @@ function createOfflinePaymentAuthorizationArtifactUri(input) {
|
|
|
4808
4829
|
type: ARTIFACT_TYPES.OFFLINE_PAYMENT_AUTHORIZATION
|
|
4809
4830
|
});
|
|
4810
4831
|
}
|
|
4832
|
+
|
|
4833
|
+
// src/artifacts/paycard.ts
|
|
4834
|
+
var PAY_CARD_DEFAULT_TTL_MS = 90 * 24 * 60 * 60 * 1e3;
|
|
4835
|
+
var PAY_CARD_REFRESH_THRESHOLD_MS = 30 * 24 * 60 * 60 * 1e3;
|
|
4836
|
+
var PAY_CARD_URI_PREFIX = `${FLUR_ARTIFACT_URI_PREFIX}${ARTIFACT_TYPES.PAY_CARD}/`;
|
|
4837
|
+
function createPayCardArtifactUri(input) {
|
|
4838
|
+
if (input.data.userId !== input.issuer) {
|
|
4839
|
+
throw new FlurArtifactError(
|
|
4840
|
+
"pay_card.data.userId must equal envelope issuer",
|
|
4841
|
+
"INVALID_BODY"
|
|
4842
|
+
);
|
|
4843
|
+
}
|
|
4844
|
+
const iat = input.issuedAtSeconds ?? Math.floor(Date.now() / 1e3);
|
|
4845
|
+
const exp = input.expiresAtSeconds ?? iat + Math.floor(PAY_CARD_DEFAULT_TTL_MS / 1e3);
|
|
4846
|
+
return createArtifactUri({
|
|
4847
|
+
type: ARTIFACT_TYPES.PAY_CARD,
|
|
4848
|
+
issuer: input.issuer,
|
|
4849
|
+
keyId: input.keyId,
|
|
4850
|
+
privateKey: input.privateKey,
|
|
4851
|
+
nonce: input.nonce,
|
|
4852
|
+
issuedAtSeconds: iat,
|
|
4853
|
+
expiresAtSeconds: exp,
|
|
4854
|
+
data: input.data
|
|
4855
|
+
});
|
|
4856
|
+
}
|
|
4857
|
+
function isPayCardArtifactUri(uri) {
|
|
4858
|
+
return typeof uri === "string" && uri.startsWith(PAY_CARD_URI_PREFIX);
|
|
4859
|
+
}
|
|
4860
|
+
function decodePayCardArtifact(uri) {
|
|
4861
|
+
if (!isPayCardArtifactUri(uri)) {
|
|
4862
|
+
throw new FlurArtifactError(
|
|
4863
|
+
`URI does not start with ${PAY_CARD_URI_PREFIX}`,
|
|
4864
|
+
"INVALID_URI"
|
|
4865
|
+
);
|
|
4866
|
+
}
|
|
4867
|
+
const decoded = decodeArtifactUri(uri);
|
|
4868
|
+
if (decoded.type !== ARTIFACT_TYPES.PAY_CARD) {
|
|
4869
|
+
throw new FlurArtifactError(
|
|
4870
|
+
`Expected pay_card, got ${decoded.type}`,
|
|
4871
|
+
"TYPE_MISMATCH"
|
|
4872
|
+
);
|
|
4873
|
+
}
|
|
4874
|
+
const parsed = PayCardArtifactSchema.safeParse(decoded.body.data);
|
|
4875
|
+
if (!parsed.success) {
|
|
4876
|
+
throw new FlurArtifactError(
|
|
4877
|
+
`pay_card body invalid: ${parsed.error.message}`,
|
|
4878
|
+
"INVALID_BODY"
|
|
4879
|
+
);
|
|
4880
|
+
}
|
|
4881
|
+
if (parsed.data.userId !== decoded.body.iss) {
|
|
4882
|
+
throw new FlurArtifactError(
|
|
4883
|
+
"pay_card.data.userId must equal envelope issuer",
|
|
4884
|
+
"INVALID_BODY"
|
|
4885
|
+
);
|
|
4886
|
+
}
|
|
4887
|
+
return {
|
|
4888
|
+
body: {
|
|
4889
|
+
...decoded.body,
|
|
4890
|
+
data: parsed.data
|
|
4891
|
+
},
|
|
4892
|
+
sig: decoded.sig,
|
|
4893
|
+
decoded
|
|
4894
|
+
};
|
|
4895
|
+
}
|
|
4896
|
+
function verifyPayCardArtifact(uri, publicKeySpkiB64, options = {}) {
|
|
4897
|
+
if (!isPayCardArtifactUri(uri)) {
|
|
4898
|
+
throw new FlurArtifactError(
|
|
4899
|
+
`URI does not start with ${PAY_CARD_URI_PREFIX}`,
|
|
4900
|
+
"INVALID_URI"
|
|
4901
|
+
);
|
|
4902
|
+
}
|
|
4903
|
+
const verified = verifyArtifactUri(
|
|
4904
|
+
uri,
|
|
4905
|
+
publicKeySpkiB64,
|
|
4906
|
+
options
|
|
4907
|
+
);
|
|
4908
|
+
if (verified.decoded.type !== ARTIFACT_TYPES.PAY_CARD) {
|
|
4909
|
+
throw new FlurArtifactError(
|
|
4910
|
+
`Expected pay_card, got ${verified.decoded.type}`,
|
|
4911
|
+
"TYPE_MISMATCH"
|
|
4912
|
+
);
|
|
4913
|
+
}
|
|
4914
|
+
if (verified.body.data.userId !== verified.body.iss) {
|
|
4915
|
+
throw new FlurArtifactError(
|
|
4916
|
+
"pay_card.data.userId must equal envelope issuer",
|
|
4917
|
+
"INVALID_BODY"
|
|
4918
|
+
);
|
|
4919
|
+
}
|
|
4920
|
+
return {
|
|
4921
|
+
body: verified.body,
|
|
4922
|
+
sig: verified.sig,
|
|
4923
|
+
decoded: verified.decoded
|
|
4924
|
+
};
|
|
4925
|
+
}
|
|
4926
|
+
function inspectPayCardFreshness(decoded, nowMs = Date.now()) {
|
|
4927
|
+
const exp = decoded.body.exp;
|
|
4928
|
+
if (exp === void 0) return "no_expiry";
|
|
4929
|
+
const remainingMs = exp * 1e3 - nowMs;
|
|
4930
|
+
if (remainingMs <= 0) return "expired";
|
|
4931
|
+
if (remainingMs <= PAY_CARD_REFRESH_THRESHOLD_MS)
|
|
4932
|
+
return "refresh_recommended";
|
|
4933
|
+
return "fresh";
|
|
4934
|
+
}
|
|
4935
|
+
function buildPayCardSigningInput(input) {
|
|
4936
|
+
if (input.data.userId !== input.issuer) {
|
|
4937
|
+
throw new FlurArtifactError(
|
|
4938
|
+
"pay_card.data.userId must equal envelope issuer",
|
|
4939
|
+
"INVALID_BODY"
|
|
4940
|
+
);
|
|
4941
|
+
}
|
|
4942
|
+
const parsedData = PayCardArtifactSchema.parse(input.data);
|
|
4943
|
+
const iat = input.issuedAtSeconds ?? Math.floor(Date.now() / 1e3);
|
|
4944
|
+
const exp = input.expiresAtSeconds ?? iat + Math.floor(PAY_CARD_DEFAULT_TTL_MS / 1e3);
|
|
4945
|
+
const body = buildArtifactBody({
|
|
4946
|
+
type: ARTIFACT_TYPES.PAY_CARD,
|
|
4947
|
+
issuer: input.issuer,
|
|
4948
|
+
keyId: input.keyId,
|
|
4949
|
+
data: parsedData,
|
|
4950
|
+
nonce: input.nonce,
|
|
4951
|
+
issuedAtSeconds: iat,
|
|
4952
|
+
expiresAtSeconds: exp
|
|
4953
|
+
});
|
|
4954
|
+
return { body, bodyBytes: canonicalJSONBytes(body) };
|
|
4955
|
+
}
|
|
4811
4956
|
// Annotate the CommonJS export names for ESM import in node:
|
|
4812
4957
|
0 && (module.exports = {
|
|
4813
4958
|
ACCOUNT_FUNDED_OAC_MAX_TTL_MS,
|
|
@@ -4902,6 +5047,9 @@ function createOfflinePaymentAuthorizationArtifactUri(input) {
|
|
|
4902
5047
|
PASS_STATES,
|
|
4903
5048
|
PAYLOAD_FORMAT_INDICATOR_VALUE,
|
|
4904
5049
|
PAYOUT_DESTINATION_STATUSES,
|
|
5050
|
+
PAY_CARD_DEFAULT_TTL_MS,
|
|
5051
|
+
PAY_CARD_REFRESH_THRESHOLD_MS,
|
|
5052
|
+
PAY_CARD_URI_PREFIX,
|
|
4905
5053
|
POINT_OF_INITIATION,
|
|
4906
5054
|
PartnerFundingEventInputSchema,
|
|
4907
5055
|
PartnerFundingSchema,
|
|
@@ -4909,6 +5057,7 @@ function createOfflinePaymentAuthorizationArtifactUri(input) {
|
|
|
4909
5057
|
PassArtifactSchema,
|
|
4910
5058
|
PassMetadataSchema,
|
|
4911
5059
|
PassSchema,
|
|
5060
|
+
PayCardArtifactSchema,
|
|
4912
5061
|
PayCollectionInputSchema,
|
|
4913
5062
|
PaymentClaimSchema,
|
|
4914
5063
|
PaymentIntentArtifactSchema,
|
|
@@ -4947,6 +5096,7 @@ function createOfflinePaymentAuthorizationArtifactUri(input) {
|
|
|
4947
5096
|
buildConsumerPaymentRequest,
|
|
4948
5097
|
buildOAC,
|
|
4949
5098
|
buildPass,
|
|
5099
|
+
buildPayCardSigningInput,
|
|
4950
5100
|
buildPaymentRequest,
|
|
4951
5101
|
buildReceipt,
|
|
4952
5102
|
buildRedemption,
|
|
@@ -4980,6 +5130,7 @@ function createOfflinePaymentAuthorizationArtifactUri(input) {
|
|
|
4980
5130
|
createPartnerFundingClient,
|
|
4981
5131
|
createPartnerProfileAdminClient,
|
|
4982
5132
|
createPassesClient,
|
|
5133
|
+
createPayCardArtifactUri,
|
|
4983
5134
|
createReceiptArtifactUri,
|
|
4984
5135
|
createReceiptsClient,
|
|
4985
5136
|
createSoftwareP256Signer,
|
|
@@ -4989,6 +5140,7 @@ function createOfflinePaymentAuthorizationArtifactUri(input) {
|
|
|
4989
5140
|
decodeConsumerSettlementReceiptQR,
|
|
4990
5141
|
decodeOfflineClaimSmsMessage,
|
|
4991
5142
|
decodeOfflineSmsSettleToken,
|
|
5143
|
+
decodePayCardArtifact,
|
|
4992
5144
|
decodePaymentRequestQR,
|
|
4993
5145
|
decodeUnverifiedConsumerSettlementReceiptQR,
|
|
4994
5146
|
derToRawP256Signature,
|
|
@@ -5006,10 +5158,12 @@ function createOfflinePaymentAuthorizationArtifactUri(input) {
|
|
|
5006
5158
|
generateDynamicQR,
|
|
5007
5159
|
generateStaticQR,
|
|
5008
5160
|
init,
|
|
5161
|
+
inspectPayCardFreshness,
|
|
5009
5162
|
isConsumerPaymentRequestExpired,
|
|
5010
5163
|
isHardenedArtifactType,
|
|
5011
5164
|
isKnownArtifactType,
|
|
5012
5165
|
isPassWithinValidity,
|
|
5166
|
+
isPayCardArtifactUri,
|
|
5013
5167
|
moneyMinorToNumber,
|
|
5014
5168
|
normalizeE164,
|
|
5015
5169
|
parseAmountInput,
|
|
@@ -5037,6 +5191,7 @@ function createOfflinePaymentAuthorizationArtifactUri(input) {
|
|
|
5037
5191
|
verifyOAC,
|
|
5038
5192
|
verifyOfflineSmsSettleToken,
|
|
5039
5193
|
verifyPass,
|
|
5194
|
+
verifyPayCardArtifact,
|
|
5040
5195
|
verifyPaymentRequest,
|
|
5041
5196
|
verifyReceipt,
|
|
5042
5197
|
verifyRedemption,
|