@validpay/node-sdk 0.1.0 → 0.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/crypto.js ADDED
@@ -0,0 +1,126 @@
1
+ import { randomBytes, createCipheriv, createDecipheriv, createHash } from "node:crypto";
2
+ import { ValidPayError } from "./types.js";
3
+ const ALGORITHM = "aes-256-gcm";
4
+ const KEY_BYTES = 32;
5
+ const IV_BYTES = 12;
6
+ const TAG_BYTES = 16;
7
+ /**
8
+ * Wire format (matches the Python SDK so blobs are interoperable):
9
+ * base64(iv[12] || authTag[16] || ciphertext)
10
+ */
11
+ export function generateKey() {
12
+ return randomBytes(KEY_BYTES).toString("base64");
13
+ }
14
+ function decodeKey(key) {
15
+ let buf;
16
+ try {
17
+ buf = Buffer.from(key, "base64");
18
+ }
19
+ catch (cause) {
20
+ throw new ValidPayError("invalid_key", "Key is not valid base64", { cause });
21
+ }
22
+ if (buf.length !== KEY_BYTES) {
23
+ throw new ValidPayError("invalid_key", `Key must decode to ${KEY_BYTES} bytes (got ${buf.length})`);
24
+ }
25
+ return buf;
26
+ }
27
+ export function encrypt(plaintext, key) {
28
+ const keyBuf = decodeKey(key);
29
+ const iv = randomBytes(IV_BYTES);
30
+ const cipher = createCipheriv(ALGORITHM, keyBuf, iv);
31
+ const ciphertext = Buffer.concat([cipher.update(plaintext, "utf8"), cipher.final()]);
32
+ const authTag = cipher.getAuthTag();
33
+ return Buffer.concat([iv, authTag, ciphertext]).toString("base64");
34
+ }
35
+ export function decrypt(blob, key) {
36
+ const keyBuf = decodeKey(key);
37
+ let buf;
38
+ try {
39
+ buf = Buffer.from(blob, "base64");
40
+ }
41
+ catch (cause) {
42
+ throw new ValidPayError("invalid_blob", "Blob is not valid base64", { cause });
43
+ }
44
+ if (buf.length < IV_BYTES + TAG_BYTES + 1) {
45
+ throw new ValidPayError("invalid_blob", `Blob too short: expected at least ${IV_BYTES + TAG_BYTES + 1} bytes`);
46
+ }
47
+ const iv = buf.subarray(0, IV_BYTES);
48
+ const authTag = buf.subarray(IV_BYTES, IV_BYTES + TAG_BYTES);
49
+ const ciphertext = buf.subarray(IV_BYTES + TAG_BYTES);
50
+ const decipher = createDecipheriv(ALGORITHM, keyBuf, iv);
51
+ decipher.setAuthTag(authTag);
52
+ try {
53
+ const plaintext = Buffer.concat([decipher.update(ciphertext), decipher.final()]);
54
+ return plaintext.toString("utf8");
55
+ }
56
+ catch (cause) {
57
+ throw new ValidPayError("decryption_failed", "Decryption failed — wrong key or tampered blob", { cause });
58
+ }
59
+ }
60
+ export function commitmentHash(plaintext) {
61
+ return createHash("sha256").update(plaintext, "utf8").digest("hex");
62
+ }
63
+ export function splitKey(key) {
64
+ const keyBuf = decodeKey(key);
65
+ const shareA = randomBytes(KEY_BYTES);
66
+ const shareB = Buffer.alloc(KEY_BYTES);
67
+ for (let i = 0; i < KEY_BYTES; i++) {
68
+ shareB[i] = keyBuf[i] ^ shareA[i];
69
+ }
70
+ return [shareA.toString("base64"), shareB.toString("base64")];
71
+ }
72
+ export function combineKeyShares(shareA, shareB) {
73
+ const a = decodeKey(shareA);
74
+ const b = decodeKey(shareB);
75
+ const combined = Buffer.alloc(KEY_BYTES);
76
+ for (let i = 0; i < KEY_BYTES; i++) {
77
+ combined[i] = a[i] ^ b[i];
78
+ }
79
+ return combined.toString("base64");
80
+ }
81
+ /** Encrypt each field of payload with its own AES key (Selective Disclosure). */
82
+ export function encryptFields(payload) {
83
+ const encryptedFields = {};
84
+ const fieldKeys = {};
85
+ for (const [name, value] of Object.entries(payload)) {
86
+ const k = generateKey();
87
+ const plaintext = typeof value === "string" ? value : JSON.stringify(value);
88
+ encryptedFields[name] = encrypt(plaintext, k);
89
+ fieldKeys[name] = k;
90
+ }
91
+ return { encryptedFields, fieldKeys };
92
+ }
93
+ /** Build per-role key map; "full" role always added with all keys. */
94
+ export function buildKeyMap(fieldKeys, disclosurePolicy) {
95
+ const map = {};
96
+ for (const [role, fields] of Object.entries(disclosurePolicy)) {
97
+ const roleKeys = {};
98
+ for (const f of fields) {
99
+ if (fieldKeys[f] !== undefined)
100
+ roleKeys[f] = fieldKeys[f];
101
+ }
102
+ map[role] = roleKeys;
103
+ }
104
+ map["full"] = { ...fieldKeys };
105
+ return map;
106
+ }
107
+ /** Decrypt only fields with keys; others become "[REDACTED]". */
108
+ export function decryptFields(encryptedFields, fieldKeys) {
109
+ const out = {};
110
+ for (const [name, blob] of Object.entries(encryptedFields)) {
111
+ if (fieldKeys[name] !== undefined) {
112
+ const plaintext = decrypt(blob, fieldKeys[name]);
113
+ try {
114
+ out[name] = JSON.parse(plaintext);
115
+ }
116
+ catch {
117
+ out[name] = plaintext;
118
+ }
119
+ }
120
+ else {
121
+ out[name] = "[REDACTED]";
122
+ }
123
+ }
124
+ return out;
125
+ }
126
+ //# sourceMappingURL=crypto.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crypto.js","sourceRoot":"","sources":["../src/crypto.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,24 +1,5 @@
1
- export interface ValidPayClientOptions {
2
- apiKey: string;
3
- baseUrl?: string;
4
- }
5
-
6
- export interface CreateIntentParams {
7
- documentType: 'check' | 'invoice' | 'receipt' | 'document';
8
- payload: Record<string, unknown>;
9
- }
10
-
11
- export interface Intent {
12
- id: string;
13
- verifyUrl: string;
14
- createdAt: string;
15
- expiresAt: string;
16
- }
17
-
18
- export declare class ValidPayClient {
19
- constructor(options: ValidPayClientOptions);
20
- createIntent(params: CreateIntentParams): Promise<Intent>;
21
- getIntent(id: string): Promise<Intent>;
22
- }
23
-
24
- export default ValidPayClient;
1
+ export { ValidPayClient } from "./client.js";
2
+ export { generateKey, encrypt, decrypt, commitmentHash, splitKey, combineKeyShares, encryptFields, buildKeyMap, decryptFields, } from "./crypto.js";
3
+ export { ValidPayError, type ValidPayClientOptions, type CreateIntentParams, type BatchIntentItem, type SelectiveIntentParams, type CreateIntentResult, type VerifyIntentResult, type TimeLockStatus, type RevocationResult, type RevocationEvent, type RawIntentResponse, type RawCreateIntentResponse, } from "./types.js";
4
+ export { verifyWebhookSignature, DEFAULT_WEBHOOK_TOLERANCE_SECONDS, type VerifyWebhookOptions, type WebhookVerifyResult, type WebhookVerifyFailureReason, } from "./webhookSignature.js";
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EACL,WAAW,EACX,OAAO,EACP,OAAO,EACP,cAAc,EACd,QAAQ,EACR,gBAAgB,EAChB,aAAa,EACb,WAAW,EACX,aAAa,GACd,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,aAAa,EACb,KAAK,qBAAqB,EAC1B,KAAK,kBAAkB,EACvB,KAAK,eAAe,EACpB,KAAK,qBAAqB,EAC1B,KAAK,kBAAkB,EACvB,KAAK,kBAAkB,EACvB,KAAK,cAAc,EACnB,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACpB,KAAK,iBAAiB,EACtB,KAAK,uBAAuB,GAC7B,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,sBAAsB,EACtB,iCAAiC,EACjC,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,EACxB,KAAK,0BAA0B,GAChC,MAAM,uBAAuB,CAAC"}
package/dist/index.js CHANGED
@@ -1,33 +1,5 @@
1
- /**
2
- * @validpay/node-sdk
3
- * Official Node.js SDK for the ValidPay document verification API.
4
- *
5
- * Status: Private Beta — Contact mike@validpay.io for API access.
6
- * Docs: https://validpay.io/docs
7
- */
8
-
9
- export class ValidPayClient {
10
- constructor(options = {}) {
11
- if (!options.apiKey) {
12
- throw new Error(
13
- 'ValidPay: API key required. Get yours at https://validpay.io'
14
- );
15
- }
16
- this.apiKey = options.apiKey;
17
- this.baseUrl = options.baseUrl || 'https://api.validpay.io';
18
- }
19
-
20
- async createIntent(params) {
21
- throw new Error(
22
- 'ValidPay SDK is in private beta. Contact mike@validpay.io for access.'
23
- );
24
- }
25
-
26
- async getIntent(id) {
27
- throw new Error(
28
- 'ValidPay SDK is in private beta. Contact mike@validpay.io for access.'
29
- );
30
- }
31
- }
32
-
33
- export default ValidPayClient;
1
+ export { ValidPayClient } from "./client.js";
2
+ export { generateKey, encrypt, decrypt, commitmentHash, splitKey, combineKeyShares, encryptFields, buildKeyMap, decryptFields, } from "./crypto.js";
3
+ export { ValidPayError, } from "./types.js";
4
+ export { verifyWebhookSignature, DEFAULT_WEBHOOK_TOLERANCE_SECONDS, } from "./webhookSignature.js";
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EACL,WAAW,EACX,OAAO,EACP,OAAO,EACP,cAAc,EACd,QAAQ,EACR,gBAAgB,EAChB,aAAa,EACb,WAAW,EACX,aAAa,GACd,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,aAAa,GAYd,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,sBAAsB,EACtB,iCAAiC,GAIlC,MAAM,uBAAuB,CAAC"}
@@ -0,0 +1,159 @@
1
+ export interface ValidPayClientOptions {
2
+ apiKey: string;
3
+ baseUrl?: string;
4
+ timeout?: number;
5
+ fetch?: typeof fetch;
6
+ }
7
+ export interface CreateIntentParams {
8
+ documentType: string;
9
+ payload: unknown;
10
+ validFrom?: string;
11
+ validUntil?: string;
12
+ }
13
+ export interface BatchIntentItem {
14
+ documentType: string;
15
+ payload: unknown;
16
+ validFrom?: string;
17
+ validUntil?: string;
18
+ }
19
+ export interface SelectiveIntentParams {
20
+ documentType: string;
21
+ payload: Record<string, unknown>;
22
+ disclosurePolicy: Record<string, string[]>;
23
+ splitKey?: boolean;
24
+ validFrom?: string;
25
+ validUntil?: string;
26
+ }
27
+ export interface CreateIntentResult {
28
+ retrievalId: string;
29
+ key: string;
30
+ }
31
+ export type TimeLockStatus = "valid" | "not_yet_valid" | "expired";
32
+ export interface VerifyIntentResult<T = unknown> {
33
+ intentId: string;
34
+ payload: T;
35
+ issuer: string;
36
+ issuerVerified: boolean;
37
+ registeredAt: string;
38
+ status: string;
39
+ integrityVerified: boolean;
40
+ validFrom?: string | null;
41
+ validUntil?: string | null;
42
+ timeLockStatus?: TimeLockStatus | null;
43
+ }
44
+ export interface RevocationResult {
45
+ intentId: string;
46
+ status: string;
47
+ revokedAt?: string;
48
+ reinstatedAt?: string;
49
+ }
50
+ export interface RevocationEvent {
51
+ id: string;
52
+ action: "revoked" | "reinstated";
53
+ reason?: string;
54
+ performedAt: string;
55
+ }
56
+ export interface RawIntentResponse {
57
+ intent_id: string;
58
+ encrypted_payload: string | null;
59
+ issuer: string;
60
+ issuer_verified: boolean;
61
+ registered_at: string;
62
+ status: string;
63
+ commitment_hash?: string;
64
+ valid_from?: string | null;
65
+ valid_until?: string | null;
66
+ selective_disclosure?: boolean;
67
+ encrypted_key_map?: string;
68
+ split_key?: boolean;
69
+ revocation_reason?: string;
70
+ revoked_at?: string;
71
+ }
72
+ export interface RawCreateIntentResponse {
73
+ retrieval_id: string;
74
+ status: string;
75
+ }
76
+ export interface RawBatchCreateResponse {
77
+ results: Array<{
78
+ retrieval_id: string;
79
+ status?: string;
80
+ }>;
81
+ }
82
+ export interface ListIntentsParams {
83
+ /** Max results, default 50, max 200. */
84
+ limit?: number;
85
+ offset?: number;
86
+ /** ISO datetime — only intents created at or after this time. */
87
+ since?: string;
88
+ /** ISO datetime — only intents created at or before this time. */
89
+ until?: string;
90
+ status?: "active" | "revoked";
91
+ documentType?: string;
92
+ /** Ordering by createdAt. Default "desc". */
93
+ order?: "asc" | "desc";
94
+ }
95
+ export interface IntentMetadata {
96
+ retrievalId: string;
97
+ documentType: string;
98
+ status: string;
99
+ createdAt: string;
100
+ revokedAt: string | null;
101
+ revocationReason: string | null;
102
+ validFrom: string | null;
103
+ validUntil: string | null;
104
+ commitmentHash: string | null;
105
+ splitKey: boolean;
106
+ selectiveDisclosure: boolean;
107
+ verificationCount: number;
108
+ lastVerifiedAt: string | null;
109
+ }
110
+ export interface ListIntentsResult {
111
+ intents: IntentMetadata[];
112
+ total: number;
113
+ limit: number;
114
+ offset: number;
115
+ }
116
+ export interface RawIntentMetadata {
117
+ retrieval_id: string;
118
+ document_type: string;
119
+ status: string;
120
+ created_at: string;
121
+ revoked_at: string | null;
122
+ revocation_reason: string | null;
123
+ valid_from: string | null;
124
+ valid_until: string | null;
125
+ commitment_hash: string | null;
126
+ split_key: boolean;
127
+ selective_disclosure: boolean;
128
+ verification_count: number;
129
+ last_verified_at: string | null;
130
+ }
131
+ export interface RawListIntentsResponse {
132
+ intents: RawIntentMetadata[];
133
+ total: number;
134
+ limit: number;
135
+ offset: number;
136
+ }
137
+ export interface RawFragmentResponse {
138
+ fragment_b?: string;
139
+ error?: string;
140
+ }
141
+ export interface RawRevocationHistoryResponse {
142
+ events?: Array<{
143
+ id: string;
144
+ action: "revoked" | "reinstated";
145
+ reason?: string;
146
+ performed_at: string;
147
+ }>;
148
+ }
149
+ export declare class ValidPayError extends Error {
150
+ readonly code: string;
151
+ readonly status?: number;
152
+ readonly details?: unknown;
153
+ constructor(code: string, message: string, options?: {
154
+ status?: number;
155
+ details?: unknown;
156
+ cause?: unknown;
157
+ });
158
+ }
159
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;CACtB;AAED,MAAM,WAAW,kBAAkB;IACjC,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,eAAe;IAC9B,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,qBAAqB;IACpC,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IAC3C,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,kBAAkB;IACjC,WAAW,EAAE,MAAM,CAAC;IACpB,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,MAAM,cAAc,GAAG,OAAO,GAAG,eAAe,GAAG,SAAS,CAAC;AAEnE,MAAM,WAAW,kBAAkB,CAAC,CAAC,GAAG,OAAO;IAC7C,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,CAAC,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,OAAO,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,iBAAiB,EAAE,OAAO,CAAC;IAC3B,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,cAAc,CAAC,EAAE,cAAc,GAAG,IAAI,CAAC;CACxC;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,SAAS,GAAG,YAAY,CAAC;IACjC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,eAAe,EAAE,OAAO,CAAC;IACzB,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,uBAAuB;IACtC,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,KAAK,CAAC;QAAE,YAAY,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC3D;AAED,MAAM,WAAW,iBAAiB;IAChC,wCAAwC;IACxC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,iEAAiE;IACjE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,kEAAkE;IAClE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,QAAQ,GAAG,SAAS,CAAC;IAC9B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,6CAA6C;IAC7C,KAAK,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,cAAc;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,QAAQ,EAAE,OAAO,CAAC;IAClB,mBAAmB,EAAE,OAAO,CAAC;IAC7B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/B;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,cAAc,EAAE,CAAC;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,iBAAiB;IAChC,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,SAAS,EAAE,OAAO,CAAC;IACnB,oBAAoB,EAAE,OAAO,CAAC;IAC9B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;CACjC;AAED,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,iBAAiB,EAAE,CAAC;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,mBAAmB;IAClC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,4BAA4B;IAC3C,MAAM,CAAC,EAAE,KAAK,CAAC;QACb,EAAE,EAAE,MAAM,CAAC;QACX,MAAM,EAAE,SAAS,GAAG,YAAY,CAAC;QACjC,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,YAAY,EAAE,MAAM,CAAC;KACtB,CAAC,CAAC;CACJ;AAED,qBAAa,aAAc,SAAQ,KAAK;IACtC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;gBAGzB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,OAAO,GAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,OAAO,CAAA;KAAO;CAQxE"}
package/dist/types.js ADDED
@@ -0,0 +1,13 @@
1
+ export class ValidPayError extends Error {
2
+ code;
3
+ status;
4
+ details;
5
+ constructor(code, message, options = {}) {
6
+ super(message, options.cause !== undefined ? { cause: options.cause } : undefined);
7
+ this.name = "ValidPayError";
8
+ this.code = code;
9
+ this.status = options.status;
10
+ this.details = options.details;
11
+ }
12
+ }
13
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAoKA,MAAM,OAAO,aAAc,SAAQ,KAAK;IAC7B,IAAI,CAAS;IACb,MAAM,CAAU;IAChB,OAAO,CAAW;IAE3B,YACE,IAAY,EACZ,OAAe,EACf,UAAmE,EAAE;QAErE,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;QACnF,IAAI,CAAC,IAAI,GAAG,eAAe,CAAC;QAC5B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;QAC7B,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IACjC,CAAC;CACF"}
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Webhook signature verification (Prompt 079).
3
+ *
4
+ * Mirrors `ValidPay-API/src/services/webhookSignature.ts` so SDK
5
+ * customers can verify inbound webhooks with one import instead of
6
+ * rolling their own constant-time compare.
7
+ *
8
+ * Wire format
9
+ * -----------
10
+ * X-ValidPay-Signature: t=<unix-seconds>,v1=<hex-hmac>
11
+ *
12
+ * The HMAC is computed over the EXACT bytes of `${t}.${rawBody}` using
13
+ * the per-webhook secret. The timestamp inside the signed payload
14
+ * bounds the replay window — even if an attacker captures a delivered
15
+ * request, they can't replay it more than `toleranceSeconds` later.
16
+ *
17
+ * IMPORTANT
18
+ * ---------
19
+ * `rawBody` MUST be the unparsed body string the framework gave you.
20
+ * `JSON.parse(body).toString()` is NOT equivalent — it loses key order
21
+ * and whitespace and the HMAC won't match.
22
+ *
23
+ * Express example
24
+ * ---------------
25
+ * app.post(
26
+ * "/webhooks/validpay",
27
+ * express.raw({ type: "application/json" }), // <- RAW, not json()
28
+ * (req, res) => {
29
+ * const result = verifyWebhookSignature(
30
+ * req.headers["x-validpay-signature"],
31
+ * req.body.toString("utf8"),
32
+ * process.env.VALIDPAY_WEBHOOK_SECRET!,
33
+ * );
34
+ * if (!result.valid) return res.status(401).send(result.reason);
35
+ * const event = JSON.parse(req.body.toString("utf8"));
36
+ * // ... handle event ...
37
+ * res.status(200).send("OK");
38
+ * },
39
+ * );
40
+ */
41
+ /** Default replay-protection window. 5 minutes matches the API side. */
42
+ export declare const DEFAULT_WEBHOOK_TOLERANCE_SECONDS = 300;
43
+ export interface VerifyWebhookOptions {
44
+ /**
45
+ * Reject signatures older than this many seconds. Default 300.
46
+ * Pass `Infinity` to disable — only safe for tests.
47
+ */
48
+ toleranceSeconds?: number;
49
+ /** Inject a clock for tests. */
50
+ nowSeconds?: number;
51
+ }
52
+ export type WebhookVerifyFailureReason = "missing_header" | "malformed_header" | "unsupported_version" | "bad_signature" | "timestamp_outside_tolerance";
53
+ export type WebhookVerifyResult = {
54
+ valid: true;
55
+ timestamp: number;
56
+ } | {
57
+ valid: false;
58
+ reason: WebhookVerifyFailureReason;
59
+ };
60
+ /**
61
+ * Verify a received webhook payload against an X-ValidPay-Signature
62
+ * header. Constant-time signature compare to prevent timing oracles.
63
+ *
64
+ * @param headerValue The X-ValidPay-Signature header value (or null/undefined
65
+ * if absent — returns `missing_header`).
66
+ * @param rawBody The exact unparsed request body string.
67
+ * @param secret The per-webhook secret returned by POST /v1/webhooks.
68
+ */
69
+ export declare function verifyWebhookSignature(headerValue: string | null | undefined, rawBody: string, secret: string, opts?: VerifyWebhookOptions): WebhookVerifyResult;
70
+ //# sourceMappingURL=webhookSignature.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"webhookSignature.d.ts","sourceRoot":"","sources":["../src/webhookSignature.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AAIH,wEAAwE;AACxE,eAAO,MAAM,iCAAiC,MAAM,CAAC;AAErD,MAAM,WAAW,oBAAoB;IACnC;;;OAGG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,gCAAgC;IAChC,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,MAAM,0BAA0B,GAClC,gBAAgB,GAChB,kBAAkB,GAClB,qBAAqB,GACrB,eAAe,GACf,6BAA6B,CAAC;AAElC,MAAM,MAAM,mBAAmB,GAC3B;IAAE,KAAK,EAAE,IAAI,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,GAClC;IAAE,KAAK,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,0BAA0B,CAAA;CAAE,CAAC;AAEzD;;;;;;;;GAQG;AACH,wBAAgB,sBAAsB,CACpC,WAAW,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EACtC,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,EACd,IAAI,GAAE,oBAAyB,GAC9B,mBAAmB,CA4BrB"}
@@ -0,0 +1,107 @@
1
+ /**
2
+ * Webhook signature verification (Prompt 079).
3
+ *
4
+ * Mirrors `ValidPay-API/src/services/webhookSignature.ts` so SDK
5
+ * customers can verify inbound webhooks with one import instead of
6
+ * rolling their own constant-time compare.
7
+ *
8
+ * Wire format
9
+ * -----------
10
+ * X-ValidPay-Signature: t=<unix-seconds>,v1=<hex-hmac>
11
+ *
12
+ * The HMAC is computed over the EXACT bytes of `${t}.${rawBody}` using
13
+ * the per-webhook secret. The timestamp inside the signed payload
14
+ * bounds the replay window — even if an attacker captures a delivered
15
+ * request, they can't replay it more than `toleranceSeconds` later.
16
+ *
17
+ * IMPORTANT
18
+ * ---------
19
+ * `rawBody` MUST be the unparsed body string the framework gave you.
20
+ * `JSON.parse(body).toString()` is NOT equivalent — it loses key order
21
+ * and whitespace and the HMAC won't match.
22
+ *
23
+ * Express example
24
+ * ---------------
25
+ * app.post(
26
+ * "/webhooks/validpay",
27
+ * express.raw({ type: "application/json" }), // <- RAW, not json()
28
+ * (req, res) => {
29
+ * const result = verifyWebhookSignature(
30
+ * req.headers["x-validpay-signature"],
31
+ * req.body.toString("utf8"),
32
+ * process.env.VALIDPAY_WEBHOOK_SECRET!,
33
+ * );
34
+ * if (!result.valid) return res.status(401).send(result.reason);
35
+ * const event = JSON.parse(req.body.toString("utf8"));
36
+ * // ... handle event ...
37
+ * res.status(200).send("OK");
38
+ * },
39
+ * );
40
+ */
41
+ import crypto from "node:crypto";
42
+ /** Default replay-protection window. 5 minutes matches the API side. */
43
+ export const DEFAULT_WEBHOOK_TOLERANCE_SECONDS = 300;
44
+ /**
45
+ * Verify a received webhook payload against an X-ValidPay-Signature
46
+ * header. Constant-time signature compare to prevent timing oracles.
47
+ *
48
+ * @param headerValue The X-ValidPay-Signature header value (or null/undefined
49
+ * if absent — returns `missing_header`).
50
+ * @param rawBody The exact unparsed request body string.
51
+ * @param secret The per-webhook secret returned by POST /v1/webhooks.
52
+ */
53
+ export function verifyWebhookSignature(headerValue, rawBody, secret, opts = {}) {
54
+ if (!headerValue)
55
+ return { valid: false, reason: "missing_header" };
56
+ const parsed = parseSignatureHeader(headerValue);
57
+ if (!parsed)
58
+ return { valid: false, reason: "malformed_header" };
59
+ if (!parsed.v1)
60
+ return { valid: false, reason: "unsupported_version" };
61
+ const tolerance = opts.toleranceSeconds ?? DEFAULT_WEBHOOK_TOLERANCE_SECONDS;
62
+ const now = opts.nowSeconds ?? Math.floor(Date.now() / 1000);
63
+ if (Math.abs(now - parsed.t) > tolerance) {
64
+ return { valid: false, reason: "timestamp_outside_tolerance" };
65
+ }
66
+ const expected = crypto
67
+ .createHmac("sha256", secret)
68
+ .update(`${parsed.t}.${rawBody}`, "utf8")
69
+ .digest("hex");
70
+ const expectedBuf = Buffer.from(expected, "hex");
71
+ const actualBuf = Buffer.from(parsed.v1, "hex");
72
+ if (expectedBuf.length !== actualBuf.length) {
73
+ return { valid: false, reason: "bad_signature" };
74
+ }
75
+ if (!crypto.timingSafeEqual(expectedBuf, actualBuf)) {
76
+ return { valid: false, reason: "bad_signature" };
77
+ }
78
+ return { valid: true, timestamp: parsed.t };
79
+ }
80
+ function parseSignatureHeader(header) {
81
+ const parts = header.split(",").map((p) => p.trim());
82
+ let t = null;
83
+ let v1 = null;
84
+ for (const part of parts) {
85
+ const eq = part.indexOf("=");
86
+ if (eq <= 0)
87
+ return null;
88
+ const key = part.slice(0, eq);
89
+ const value = part.slice(eq + 1);
90
+ if (key === "t") {
91
+ const parsed = Number.parseInt(value, 10);
92
+ if (!Number.isFinite(parsed) || parsed <= 0)
93
+ return null;
94
+ t = parsed;
95
+ }
96
+ else if (key === "v1") {
97
+ if (!/^[0-9a-fA-F]+$/.test(value) || value.length !== 64)
98
+ return null;
99
+ v1 = value.toLowerCase();
100
+ }
101
+ // Unknown keys skipped — forward-compat with future versions.
102
+ }
103
+ if (t === null)
104
+ return null;
105
+ return { t, v1 };
106
+ }
107
+ //# sourceMappingURL=webhookSignature.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"webhookSignature.js","sourceRoot":"","sources":["../src/webhookSignature.ts"],"names":[],"mappings":"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"}