@validpay/node-sdk 0.1.0 → 0.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 ValidPay
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,52 +1,214 @@
1
1
  # @validpay/node-sdk
2
2
 
3
- Official Node.js SDK for the [ValidPay](https://validpay.io) document verification API.
3
+ Official Node.js SDK for [ValidPay](https://validpay.io) document verification API with **client-side AES-256-GCM encryption**. Sensitive payloads are encrypted on your server before they ever leave the box; ValidPay stores the ciphertext, and only your verifier (with the key you hand them) can read the contents.
4
4
 
5
- ## Overview
5
+ - **Zero production dependencies** — Node.js built-in `crypto` + native `fetch` only
6
+ - **AES-256-GCM** authenticated encryption (tampering is detected on decrypt)
7
+ - **Hybrid commitment scheme** — SHA-256 commitment hash detects server-side tampering
8
+ - **Split-key verification** (Patent C) — XOR-share the key so neither party alone can decrypt
9
+ - **Selective field disclosure** (Patent E) — encrypt fields independently, gate per role
10
+ - **Blind revocation** (Patent H) — revoke / reinstate / inspect audit history
11
+ - **Time-locked verification** (Patent D) — validFrom / validUntil windows
12
+ - **TypeScript-first**, ESM-only, requires Node `>= 20`
13
+ - The encryption key is **never** sent to the ValidPay API
6
14
 
7
- ValidPay provides cryptographic document verification infrastructure. This SDK enables issuers (banks, fintechs, check printers) to create tamper-proof verification intents and allows verifiers to authenticate documents in real-time.
8
-
9
- ## Installation
15
+ ## Install
10
16
 
11
17
  ```bash
12
18
  npm install @validpay/node-sdk
13
19
  ```
14
20
 
15
- ## Quick Start
21
+ ## Quick start
22
+
23
+ ```ts
24
+ import { ValidPayClient } from "@validpay/node-sdk";
25
+
26
+ const client = new ValidPayClient({ apiKey: process.env.VALIDPAY_API_KEY! });
27
+
28
+ // 1. Issuer side — register an intent with sensitive payload
29
+ const { retrievalId, key } = await client.createIntent({
30
+ documentType: "ssn_card",
31
+ payload: { ssn: "123-45-6789", name: "Jane Doe" },
32
+ });
33
+
34
+ // retrievalId is public (e.g. "vp_abc123def456") — embed in a QR code.
35
+ // key is secret — deliver it ONLY to the intended verifier, out-of-band.
36
+
37
+ // 2. Verifier side — fetch and decrypt (no API key needed)
38
+ const result = await client.verifyIntent<{ ssn: string; name: string }>(retrievalId, key);
39
+
40
+ console.log(result.payload); // { ssn: "123-45-6789", name: "Jane Doe" }
41
+ console.log(result.integrityVerified); // true — commitment hash matched
42
+ console.log(result.issuer); // "Acme Bank"
43
+ console.log(result.issuerVerified); // true
44
+ ```
45
+
46
+ ## How it works
47
+
48
+ 1. `createIntent` generates a fresh 256-bit key, encrypts your payload locally with AES-256-GCM, computes a SHA-256 commitment hash of the plaintext, and POSTs only the ciphertext + hash to `POST /v1/intent`.
49
+ 2. The API returns a public `retrieval_id` and stores the ciphertext + commitment hash.
50
+ 3. You hand the verifier the `retrievalId` and the `key` through your own secure channel.
51
+ 4. The verifier calls `verifyIntent`, which fetches `GET /v1/intent/:id`, decrypts the ciphertext locally, then recomputes the commitment hash and compares — any server-side tampering would change the hash.
52
+
53
+ The key is generated client-side, used client-side, and transmitted client-side. ValidPay can never read the payload.
54
+
55
+ ## API reference
56
+
57
+ ### `new ValidPayClient(options)`
58
+
59
+ | Option | Type | Default | Notes |
60
+ | --------- | ------------------- | --------------------------- | ------------------------------------------- |
61
+ | `apiKey` | `string` (required) | — | Your ValidPay issuer API key. |
62
+ | `baseUrl` | `string` | `"https://api.validpay.io"` | Override for staging or self-hosted setups. |
63
+ | `timeout` | `number` | `30000` | Request timeout (ms). |
64
+ | `fetch` | `typeof fetch` | global `fetch` | Inject a custom fetch (useful for testing). |
65
+
66
+ ### Core
67
+
68
+ #### `client.createIntent({ documentType, payload, validFrom?, validUntil? }) → { retrievalId, key }`
69
+
70
+ Generates a key, encrypts `JSON.stringify(payload)`, posts ciphertext + commitment hash to `/v1/intent`. **The key is never sent to the API.**
71
+
72
+ #### `client.createIntentBatch(items[]) → { retrievalId, key }[]`
73
+
74
+ Same as `createIntent` for up to 100 intents in a single request. Each item gets a unique AES key; results match the input order.
16
75
 
17
- ```typescript
18
- import { ValidPayClient } from '@validpay/node-sdk';
76
+ #### `client.verifyIntent<T>(retrievalId, key) → VerifyIntentResult<T>`
19
77
 
20
- const client = new ValidPayClient({
21
- apiKey: process.env.VALIDPAY_API_KEY,
78
+ Fetches the intent and decrypts the payload locally. Verifies the commitment hash. Throws `ValidPayError`:
79
+
80
+ - `decryption_failed` — wrong key or tampered ciphertext (GCM auth-tag failure)
81
+ - `integrity_failure` — commitment hash mismatch (server-side tampering detected)
82
+ - `intent_revoked` — the intent has been revoked
83
+ - `split_key_required` / `selective_disclosure_required` — use the specialised verify method
84
+
85
+ ```ts
86
+ interface VerifyIntentResult<T> {
87
+ intentId: string;
88
+ payload: T;
89
+ issuer: string;
90
+ issuerVerified: boolean;
91
+ registeredAt: string; // ISO 8601
92
+ status: string;
93
+ integrityVerified: boolean;
94
+ validFrom?: string | null;
95
+ validUntil?: string | null;
96
+ timeLockStatus?: "valid" | "not_yet_valid" | "expired" | null;
97
+ }
98
+ ```
99
+
100
+ ### Split-key (Patent C)
101
+
102
+ ```ts
103
+ const { retrievalId, key: shareA } = await client.createSplitKeyIntent({
104
+ documentType: "ssn_card",
105
+ payload: { ssn: "123-45-6789" },
22
106
  });
107
+ // shareA goes in the QR; shareB stays at the API.
23
108
 
24
- // Create a verification intent
25
- const intent = await client.createIntent({
26
- documentType: 'check',
27
- payload: { payee: 'Jane Doe', amount: 1500.00 },
109
+ const result = await client.verifySplitKeyIntent(retrievalId, shareA);
110
+ // SDK fetches shareB from /v1/intent/:id/fragment, XOR-combines, decrypts.
111
+ ```
112
+
113
+ ### Selective disclosure (Patent E)
114
+
115
+ ```ts
116
+ const { retrievalId, key } = await client.createSelectiveIntent({
117
+ documentType: "check",
118
+ payload: { amount: 1500, payee: "Alice", memo: "rent" },
119
+ disclosurePolicy: {
120
+ bank: ["amount"],
121
+ auditor: ["amount", "payee"],
122
+ },
28
123
  });
29
124
 
30
- // intent.id embed in QR code
31
- // intent.verifyUrl direct verification link
125
+ const bankView = await client.verifySelectiveIntent(retrievalId, key, "bank");
126
+ // { amount: 1500, payee: "[REDACTED]", memo: "[REDACTED]" }
127
+
128
+ const fullView = await client.verifySelectiveIntent(retrievalId, key, "full");
129
+ // { amount: 1500, payee: "Alice", memo: "rent" }
130
+ ```
131
+
132
+ ### Revocation (Patent H)
133
+
134
+ ```ts
135
+ await client.revokeIntent(retrievalId, "stop payment requested");
136
+ await client.reinstateIntent(retrievalId, "false alarm");
137
+ const history = await client.getRevocationHistory(retrievalId);
138
+ ```
139
+
140
+ ### Health
141
+
142
+ ```ts
143
+ const { status, version } = await client.health();
32
144
  ```
33
145
 
34
- ## Features
146
+ ### Low-level crypto helpers
147
+
148
+ ```ts
149
+ import {
150
+ generateKey,
151
+ encrypt,
152
+ decrypt,
153
+ commitmentHash,
154
+ splitKey,
155
+ combineKeyShares,
156
+ encryptFields,
157
+ buildKeyMap,
158
+ decryptFields,
159
+ } from "@validpay/node-sdk";
160
+
161
+ const key = generateKey(); // base64 32-byte key
162
+ const blob = encrypt("hello world", key); // base64(iv[12] || authTag[16] || ciphertext)
163
+ const plain = decrypt(blob, key); // "hello world"
164
+ const hash = commitmentHash(plain); // SHA-256 hex
165
+
166
+ const [a, b] = splitKey(key);
167
+ const reconstructed = combineKeyShares(a, b); // === key
168
+ ```
35
169
 
36
- - Zero production dependencies (Node built-in crypto + native fetch)
37
- - ESM-only, TypeScript-first
38
- - AES-256-GCM encryption with client-side key generation
39
- - XOR key splitting for multi-party verification
40
- - Automatic retry with exponential backoff
170
+ ### `ValidPayError`
171
+
172
+ All SDK errors throw `ValidPayError` with a stable `code`:
173
+
174
+ | Code | Meaning |
175
+ | ------------------------------- | ------------------------------------------------------------- |
176
+ | `invalid_config` | Missing `apiKey` (or other constructor options). |
177
+ | `invalid_argument` | Required method argument is missing or invalid. |
178
+ | `invalid_key` | Key is not valid base64 or not 32 bytes. |
179
+ | `invalid_blob` | Blob is not valid base64 or too short. |
180
+ | `decryption_failed` | Wrong key, or ciphertext tampered (GCM auth-tag failure). |
181
+ | `integrity_failure` | Commitment hash didn't match — server tampering detected. |
182
+ | `intent_revoked` | The intent has been revoked. |
183
+ | `split_key_required` | Intent uses split-key; use `verifySplitKeyIntent` instead. |
184
+ | `selective_disclosure_required` | Intent uses per-field encryption; use `verifySelectiveIntent`. |
185
+ | `invalid_role` | Role not present in the disclosure policy. |
186
+ | `missing_fragment` | API did not return a key fragment for a split-key intent. |
187
+ | `network_error` | `fetch` itself rejected (DNS, TCP, abort, etc.). |
188
+ | `http_error` | API returned non-2xx with no machine-readable error. |
189
+ | `not_found` | API returned 404 (e.g. unknown retrieval ID). |
190
+ | `unauthorized` | API returned 401 (invalid or missing API key). |
191
+ | `invalid_response` | API returned 2xx but response shape was unexpected. |
192
+ | `invalid_payload` | Decrypted bytes were not valid JSON. |
193
+
194
+ ## Blob format
195
+
196
+ `encrypt()` returns a base64 string whose decoded bytes are:
41
197
 
42
- ## Documentation
198
+ ```
199
+ [ iv (12 bytes) | authTag (16 bytes) | ciphertext (variable) ]
200
+ ```
43
201
 
44
- Full API documentation: [https://validpay.io/docs](https://validpay.io/docs)
202
+ This matches the Python SDK exactly, so blobs are interoperable in both directions.
45
203
 
46
- ## Status
204
+ ## Development
47
205
 
48
- **Private Beta** — Contact mike@validpay.io for API access.
206
+ ```bash
207
+ npm install
208
+ npm test
209
+ npm run build
210
+ ```
49
211
 
50
212
  ## License
51
213
 
52
- MIT — Copyright (c) 2026 MiLu Technologies LLC
214
+ MIT — see [LICENSE](./LICENSE).
@@ -0,0 +1,24 @@
1
+ import { type ValidPayClientOptions, type CreateIntentParams, type BatchIntentItem, type SelectiveIntentParams, type CreateIntentResult, type VerifyIntentResult, type RevocationResult, type RevocationEvent } from "./types.js";
2
+ export declare class ValidPayClient {
3
+ private readonly apiKey;
4
+ private readonly baseUrl;
5
+ private readonly timeout;
6
+ private readonly fetchImpl;
7
+ constructor(options: ValidPayClientOptions);
8
+ createIntent(params: CreateIntentParams): Promise<CreateIntentResult>;
9
+ createIntentBatch(items: BatchIntentItem[]): Promise<CreateIntentResult[]>;
10
+ verifyIntent<T = unknown>(retrievalId: string, key: string): Promise<VerifyIntentResult<T>>;
11
+ createSplitKeyIntent(params: CreateIntentParams): Promise<CreateIntentResult>;
12
+ verifySplitKeyIntent<T = unknown>(retrievalId: string, shareA: string): Promise<VerifyIntentResult<T>>;
13
+ createSelectiveIntent(params: SelectiveIntentParams): Promise<CreateIntentResult>;
14
+ verifySelectiveIntent(retrievalId: string, key: string, role?: string): Promise<VerifyIntentResult<Record<string, unknown>>>;
15
+ revokeIntent(retrievalId: string, reason?: string): Promise<RevocationResult>;
16
+ reinstateIntent(retrievalId: string, reason?: string): Promise<RevocationResult>;
17
+ getRevocationHistory(retrievalId: string): Promise<RevocationEvent[]>;
18
+ health(): Promise<{
19
+ status: string;
20
+ version?: string;
21
+ }>;
22
+ private request;
23
+ }
24
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAWA,OAAO,EAEL,KAAK,qBAAqB,EAC1B,KAAK,kBAAkB,EACvB,KAAK,eAAe,EACpB,KAAK,qBAAqB,EAC1B,KAAK,kBAAkB,EACvB,KAAK,kBAAkB,EAEvB,KAAK,gBAAgB,EACrB,KAAK,eAAe,EAMrB,MAAM,YAAY,CAAC;AAYpB,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAe;gBAE7B,OAAO,EAAE,qBAAqB;IAYpC,YAAY,CAAC,MAAM,EAAE,kBAAkB,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAgCrE,iBAAiB,CAAC,KAAK,EAAE,eAAe,EAAE,GAAG,OAAO,CAAC,kBAAkB,EAAE,CAAC;IAoE1E,YAAY,CAAC,CAAC,GAAG,OAAO,EAC5B,WAAW,EAAE,MAAM,EACnB,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC;IAmE3B,oBAAoB,CAAC,MAAM,EAAE,kBAAkB,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAoC7E,oBAAoB,CAAC,CAAC,GAAG,OAAO,EACpC,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC;IAiE3B,qBAAqB,CAAC,MAAM,EAAE,qBAAqB,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAyEjF,qBAAqB,CACzB,WAAW,EAAE,MAAM,EACnB,GAAG,EAAE,MAAM,EACX,IAAI,SAAS,GACZ,OAAO,CAAC,kBAAkB,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IA4GjD,YAAY,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAoB7E,eAAe,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAoBhF,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC;IAoBrE,MAAM,IAAI,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;YAQ/C,OAAO;CAgDtB"}
package/dist/client.js ADDED
@@ -0,0 +1,498 @@
1
+ import { generateKey, encrypt, decrypt, commitmentHash, splitKey as splitKeyFn, combineKeyShares, encryptFields, buildKeyMap, decryptFields, } from "./crypto.js";
2
+ import { ValidPayError, } from "./types.js";
3
+ const DEFAULT_BASE_URL = "https://api.validpay.io";
4
+ const DEFAULT_TIMEOUT_MS = 30_000;
5
+ export class ValidPayClient {
6
+ apiKey;
7
+ baseUrl;
8
+ timeout;
9
+ fetchImpl;
10
+ constructor(options) {
11
+ if (!options.apiKey) {
12
+ throw new ValidPayError("invalid_config", "apiKey is required");
13
+ }
14
+ this.apiKey = options.apiKey;
15
+ this.baseUrl = (options.baseUrl ?? DEFAULT_BASE_URL).replace(/\/+$/, "");
16
+ this.timeout = options.timeout ?? DEFAULT_TIMEOUT_MS;
17
+ this.fetchImpl = options.fetch ?? fetch;
18
+ }
19
+ // === Core ===
20
+ async createIntent(params) {
21
+ if (!params.documentType) {
22
+ throw new ValidPayError("invalid_argument", "documentType is required");
23
+ }
24
+ validateTimeLock(params.validFrom, params.validUntil);
25
+ const key = generateKey();
26
+ const plaintext = JSON.stringify(params.payload);
27
+ const encrypted_payload = encrypt(plaintext, key);
28
+ const commitment_hash = commitmentHash(plaintext);
29
+ const body = {
30
+ document_type: params.documentType,
31
+ encrypted_payload,
32
+ commitment_hash,
33
+ };
34
+ if (params.validFrom !== undefined)
35
+ body["valid_from"] = params.validFrom;
36
+ if (params.validUntil !== undefined)
37
+ body["valid_until"] = params.validUntil;
38
+ const data = await this.request("POST", "/v1/intent", {
39
+ body,
40
+ auth: true,
41
+ });
42
+ if (!data?.retrieval_id) {
43
+ throw new ValidPayError("invalid_response", "API response missing retrieval_id", {
44
+ details: data,
45
+ });
46
+ }
47
+ return { retrievalId: data.retrieval_id, key };
48
+ }
49
+ async createIntentBatch(items) {
50
+ if (!Array.isArray(items) || items.length === 0) {
51
+ throw new ValidPayError("invalid_argument", "items must contain at least 1 item");
52
+ }
53
+ if (items.length > 100) {
54
+ throw new ValidPayError("invalid_argument", `items must contain at most 100 items (got ${items.length})`);
55
+ }
56
+ const keys = [];
57
+ const requestItems = [];
58
+ items.forEach((item, idx) => {
59
+ if (!item.documentType) {
60
+ throw new ValidPayError("invalid_argument", `items[${idx}].documentType is required`);
61
+ }
62
+ if (!("payload" in item)) {
63
+ throw new ValidPayError("invalid_argument", `items[${idx}].payload is required`);
64
+ }
65
+ try {
66
+ validateTimeLock(item.validFrom, item.validUntil);
67
+ }
68
+ catch (e) {
69
+ if (e instanceof ValidPayError) {
70
+ throw new ValidPayError("invalid_argument", `items[${idx}]: ${e.message}`);
71
+ }
72
+ throw e;
73
+ }
74
+ const k = generateKey();
75
+ keys.push(k);
76
+ const plaintext = JSON.stringify(item.payload);
77
+ const req = {
78
+ document_type: item.documentType,
79
+ encrypted_payload: encrypt(plaintext, k),
80
+ commitment_hash: commitmentHash(plaintext),
81
+ };
82
+ if (item.validFrom !== undefined)
83
+ req["valid_from"] = item.validFrom;
84
+ if (item.validUntil !== undefined)
85
+ req["valid_until"] = item.validUntil;
86
+ requestItems.push(req);
87
+ });
88
+ const data = await this.request("POST", "/v1/intent/batch", {
89
+ body: { intents: requestItems },
90
+ auth: true,
91
+ });
92
+ if (!Array.isArray(data?.results) || data.results.length !== keys.length) {
93
+ throw new ValidPayError("invalid_response", "API response missing results array of expected length", { details: data });
94
+ }
95
+ return data.results.map((row, i) => {
96
+ if (!row?.retrieval_id) {
97
+ throw new ValidPayError("invalid_response", `results[${i}] missing retrieval_id`, {
98
+ details: data,
99
+ });
100
+ }
101
+ return { retrievalId: row.retrieval_id, key: keys[i] };
102
+ });
103
+ }
104
+ async verifyIntent(retrievalId, key) {
105
+ if (!retrievalId) {
106
+ throw new ValidPayError("invalid_argument", "retrievalId is required");
107
+ }
108
+ if (!key) {
109
+ throw new ValidPayError("invalid_argument", "key is required");
110
+ }
111
+ const data = await this.request("GET", `/v1/intent/${encodeURIComponent(retrievalId)}`, { auth: false });
112
+ if (!data || typeof data !== "object") {
113
+ throw new ValidPayError("invalid_response", "API response missing intent body", {
114
+ details: data,
115
+ });
116
+ }
117
+ if (data.status === "revoked" || !data.encrypted_payload) {
118
+ const reasonSuffix = data.revocation_reason ? `: ${data.revocation_reason}` : "";
119
+ throw new ValidPayError("intent_revoked", `Intent ${retrievalId} has been revoked${reasonSuffix}`, {
120
+ details: {
121
+ intent_id: data.intent_id,
122
+ status: data.status,
123
+ revoked_at: data.revoked_at,
124
+ revocation_reason: data.revocation_reason,
125
+ },
126
+ });
127
+ }
128
+ if (data.selective_disclosure) {
129
+ throw new ValidPayError("selective_disclosure_required", "This intent uses selective field disclosure. Use verifySelectiveIntent(retrievalId, key, role) instead.");
130
+ }
131
+ if (data.split_key) {
132
+ throw new ValidPayError("split_key_required", `Intent ${retrievalId} uses split-key protection. Use verifySplitKeyIntent(retrievalId, shareA) instead.`);
133
+ }
134
+ const decrypted = decrypt(data.encrypted_payload, key);
135
+ const integrityVerified = checkCommitment(data.commitment_hash, decrypted);
136
+ let payload;
137
+ try {
138
+ payload = JSON.parse(decrypted);
139
+ }
140
+ catch (cause) {
141
+ throw new ValidPayError("invalid_payload", "Decrypted payload is not valid JSON", {
142
+ cause,
143
+ });
144
+ }
145
+ return buildVerifyResult(data, payload, integrityVerified);
146
+ }
147
+ // === Split-key (Patent C) ===
148
+ async createSplitKeyIntent(params) {
149
+ if (!params.documentType) {
150
+ throw new ValidPayError("invalid_argument", "documentType is required");
151
+ }
152
+ validateTimeLock(params.validFrom, params.validUntil);
153
+ const fullKey = generateKey();
154
+ const [shareA, shareB] = splitKeyFn(fullKey);
155
+ const plaintext = JSON.stringify(params.payload);
156
+ const encrypted_payload = encrypt(plaintext, fullKey);
157
+ const commitment_hash = commitmentHash(plaintext);
158
+ const body = {
159
+ document_type: params.documentType,
160
+ encrypted_payload,
161
+ commitment_hash,
162
+ split_key: true,
163
+ key_fragment_b: shareB,
164
+ };
165
+ if (params.validFrom !== undefined)
166
+ body["valid_from"] = params.validFrom;
167
+ if (params.validUntil !== undefined)
168
+ body["valid_until"] = params.validUntil;
169
+ const data = await this.request("POST", "/v1/intent", {
170
+ body,
171
+ auth: true,
172
+ });
173
+ if (!data?.retrieval_id) {
174
+ throw new ValidPayError("invalid_response", "API response missing retrieval_id", {
175
+ details: data,
176
+ });
177
+ }
178
+ return { retrievalId: data.retrieval_id, key: shareA };
179
+ }
180
+ async verifySplitKeyIntent(retrievalId, shareA) {
181
+ if (!retrievalId) {
182
+ throw new ValidPayError("invalid_argument", "retrievalId is required");
183
+ }
184
+ if (!shareA) {
185
+ throw new ValidPayError("invalid_argument", "shareA is required");
186
+ }
187
+ const data = await this.request("GET", `/v1/intent/${encodeURIComponent(retrievalId)}`, { auth: false });
188
+ if (data.status === "revoked" || !data.encrypted_payload) {
189
+ const reasonSuffix = data.revocation_reason ? `: ${data.revocation_reason}` : "";
190
+ throw new ValidPayError("intent_revoked", `Intent ${retrievalId} has been revoked${reasonSuffix}`, {
191
+ details: {
192
+ intent_id: data.intent_id,
193
+ status: data.status,
194
+ revoked_at: data.revoked_at,
195
+ revocation_reason: data.revocation_reason,
196
+ },
197
+ });
198
+ }
199
+ const frag = await this.request("GET", `/v1/intent/${encodeURIComponent(retrievalId)}/fragment`, { auth: false });
200
+ if (frag?.error) {
201
+ throw new ValidPayError(frag.error, `Fragment retrieval failed: ${frag.error}`, {
202
+ details: frag,
203
+ });
204
+ }
205
+ if (!frag?.fragment_b) {
206
+ throw new ValidPayError("missing_fragment", "Server did not return key fragment", {
207
+ details: frag,
208
+ });
209
+ }
210
+ const fullKey = combineKeyShares(shareA, frag.fragment_b);
211
+ const decrypted = decrypt(data.encrypted_payload, fullKey);
212
+ const integrityVerified = checkCommitment(data.commitment_hash, decrypted);
213
+ let payload;
214
+ try {
215
+ payload = JSON.parse(decrypted);
216
+ }
217
+ catch (cause) {
218
+ throw new ValidPayError("invalid_payload", "Decrypted payload is not valid JSON", {
219
+ cause,
220
+ });
221
+ }
222
+ return buildVerifyResult(data, payload, integrityVerified);
223
+ }
224
+ // === Selective disclosure (Patent E) ===
225
+ async createSelectiveIntent(params) {
226
+ if (!params.documentType) {
227
+ throw new ValidPayError("invalid_argument", "documentType is required");
228
+ }
229
+ if (!params.payload || Object.keys(params.payload).length === 0) {
230
+ throw new ValidPayError("invalid_argument", "payload must be a non-empty object");
231
+ }
232
+ if (!params.disclosurePolicy || Object.keys(params.disclosurePolicy).length === 0) {
233
+ throw new ValidPayError("invalid_argument", "disclosurePolicy must be a non-empty object");
234
+ }
235
+ validateTimeLock(params.validFrom, params.validUntil);
236
+ for (const [role, fields] of Object.entries(params.disclosurePolicy)) {
237
+ if (!Array.isArray(fields)) {
238
+ throw new ValidPayError("invalid_argument", `disclosurePolicy['${role}'] must be an array`);
239
+ }
240
+ for (const f of fields) {
241
+ if (!(f in params.payload)) {
242
+ throw new ValidPayError("invalid_argument", `Field '${f}' in role '${role}' not found in payload`);
243
+ }
244
+ }
245
+ }
246
+ const masterKey = generateKey();
247
+ const { encryptedFields, fieldKeys } = encryptFields(params.payload);
248
+ const keyMap = buildKeyMap(fieldKeys, params.disclosurePolicy);
249
+ const encrypted_key_map = encrypt(JSON.stringify(keyMap), masterKey);
250
+ const fullPlaintext = JSON.stringify(params.payload);
251
+ const commitment_hash = commitmentHash(fullPlaintext);
252
+ let qrKey = masterKey;
253
+ let key_fragment_b;
254
+ if (params.splitKey) {
255
+ const [shareA, shareB] = splitKeyFn(masterKey);
256
+ qrKey = shareA;
257
+ key_fragment_b = shareB;
258
+ }
259
+ const body = {
260
+ document_type: params.documentType,
261
+ encrypted_payload: JSON.stringify(encryptedFields),
262
+ commitment_hash,
263
+ selective_disclosure: true,
264
+ disclosure_policy: JSON.stringify(params.disclosurePolicy),
265
+ encrypted_key_map,
266
+ split_key: !!params.splitKey,
267
+ };
268
+ if (key_fragment_b !== undefined)
269
+ body["key_fragment_b"] = key_fragment_b;
270
+ if (params.validFrom !== undefined)
271
+ body["valid_from"] = params.validFrom;
272
+ if (params.validUntil !== undefined)
273
+ body["valid_until"] = params.validUntil;
274
+ const data = await this.request("POST", "/v1/intent", {
275
+ body,
276
+ auth: true,
277
+ });
278
+ if (!data?.retrieval_id) {
279
+ throw new ValidPayError("invalid_response", "API response missing retrieval_id", {
280
+ details: data,
281
+ });
282
+ }
283
+ return { retrievalId: data.retrieval_id, key: qrKey };
284
+ }
285
+ async verifySelectiveIntent(retrievalId, key, role = "full") {
286
+ if (!retrievalId) {
287
+ throw new ValidPayError("invalid_argument", "retrievalId is required");
288
+ }
289
+ if (!key) {
290
+ throw new ValidPayError("invalid_argument", "key is required");
291
+ }
292
+ const data = await this.request("GET", `/v1/intent/${encodeURIComponent(retrievalId)}`, { auth: false });
293
+ if (data.status === "revoked" || !data.encrypted_payload) {
294
+ const reasonSuffix = data.revocation_reason ? `: ${data.revocation_reason}` : "";
295
+ throw new ValidPayError("intent_revoked", `Intent ${retrievalId} has been revoked${reasonSuffix}`, {
296
+ details: {
297
+ intent_id: data.intent_id,
298
+ status: data.status,
299
+ revoked_at: data.revoked_at,
300
+ revocation_reason: data.revocation_reason,
301
+ },
302
+ });
303
+ }
304
+ let masterKey = key;
305
+ if (data.split_key) {
306
+ const frag = await this.request("GET", `/v1/intent/${encodeURIComponent(retrievalId)}/fragment`, { auth: false });
307
+ if (frag?.error) {
308
+ throw new ValidPayError(frag.error, `Fragment retrieval failed: ${frag.error}`, {
309
+ details: frag,
310
+ });
311
+ }
312
+ if (!frag?.fragment_b) {
313
+ throw new ValidPayError("missing_fragment", "Server did not return key fragment", {
314
+ details: frag,
315
+ });
316
+ }
317
+ masterKey = combineKeyShares(key, frag.fragment_b);
318
+ }
319
+ if (!data.encrypted_key_map) {
320
+ throw new ValidPayError("invalid_response", "Selective disclosure intent missing encrypted_key_map");
321
+ }
322
+ const keyMapJson = decrypt(data.encrypted_key_map, masterKey);
323
+ let keyMap;
324
+ try {
325
+ keyMap = JSON.parse(keyMapJson);
326
+ }
327
+ catch (cause) {
328
+ throw new ValidPayError("invalid_payload", "Decrypted key map is not valid JSON", {
329
+ cause,
330
+ });
331
+ }
332
+ if (!(role in keyMap)) {
333
+ const available = Object.keys(keyMap).sort().join(", ");
334
+ throw new ValidPayError("invalid_role", `Role '${role}' is not defined in this document's disclosure policy. Available roles: ${available}`);
335
+ }
336
+ const fieldKeys = keyMap[role];
337
+ let encryptedFields;
338
+ try {
339
+ encryptedFields = JSON.parse(data.encrypted_payload);
340
+ }
341
+ catch (cause) {
342
+ throw new ValidPayError("invalid_payload", "Encrypted payload is not a valid JSON envelope", { cause });
343
+ }
344
+ const payload = decryptFields(encryptedFields, fieldKeys);
345
+ let integrityVerified = false;
346
+ if (data.commitment_hash && role === "full") {
347
+ const allKeys = keyMap["full"] ?? {};
348
+ const fullPayload = decryptFields(encryptedFields, allKeys);
349
+ const actual = commitmentHash(JSON.stringify(fullPayload));
350
+ if (actual !== data.commitment_hash) {
351
+ throw new ValidPayError("integrity_failure", "INTEGRITY VERIFICATION FAILED — the decrypted payload does not match the commitment hash stored at issuance.");
352
+ }
353
+ integrityVerified = true;
354
+ }
355
+ return buildVerifyResult(data, payload, integrityVerified);
356
+ }
357
+ // === Revocation (Patent H) ===
358
+ async revokeIntent(retrievalId, reason) {
359
+ if (!retrievalId) {
360
+ throw new ValidPayError("invalid_argument", "retrievalId is required");
361
+ }
362
+ const data = await this.request("PATCH", `/v1/intent/${encodeURIComponent(retrievalId)}/revoke`, { body: reason ? { reason } : {}, auth: true });
363
+ return {
364
+ intentId: data?.intent_id ?? retrievalId,
365
+ status: data?.status ?? "revoked",
366
+ revokedAt: data?.revoked_at,
367
+ };
368
+ }
369
+ async reinstateIntent(retrievalId, reason) {
370
+ if (!retrievalId) {
371
+ throw new ValidPayError("invalid_argument", "retrievalId is required");
372
+ }
373
+ const data = await this.request("PATCH", `/v1/intent/${encodeURIComponent(retrievalId)}/reinstate`, { body: reason ? { reason } : {}, auth: true });
374
+ return {
375
+ intentId: data?.intent_id ?? retrievalId,
376
+ status: data?.status ?? "active",
377
+ reinstatedAt: data?.reinstated_at,
378
+ };
379
+ }
380
+ async getRevocationHistory(retrievalId) {
381
+ if (!retrievalId) {
382
+ throw new ValidPayError("invalid_argument", "retrievalId is required");
383
+ }
384
+ const data = await this.request("GET", `/v1/intent/${encodeURIComponent(retrievalId)}/revocations`, { auth: true });
385
+ if (!Array.isArray(data?.events))
386
+ return [];
387
+ return data.events.map((e) => ({
388
+ id: e.id,
389
+ action: e.action,
390
+ reason: e.reason,
391
+ performedAt: e.performed_at,
392
+ }));
393
+ }
394
+ // === Health ===
395
+ async health() {
396
+ return this.request("GET", "/health", {
397
+ auth: false,
398
+ });
399
+ }
400
+ // === HTTP ===
401
+ async request(method, path, opts) {
402
+ const url = `${this.baseUrl}${path}`;
403
+ const headers = { Accept: "application/json" };
404
+ if (opts.auth)
405
+ headers["Authorization"] = `Bearer ${this.apiKey}`;
406
+ if (opts.body !== undefined)
407
+ headers["Content-Type"] = "application/json";
408
+ const controller = new AbortController();
409
+ const timer = setTimeout(() => controller.abort(), this.timeout);
410
+ let response;
411
+ try {
412
+ response = await this.fetchImpl(url, {
413
+ method,
414
+ headers,
415
+ body: opts.body !== undefined ? JSON.stringify(opts.body) : undefined,
416
+ signal: controller.signal,
417
+ });
418
+ }
419
+ catch (cause) {
420
+ throw new ValidPayError("network_error", `Request to ${url} failed`, { cause });
421
+ }
422
+ finally {
423
+ clearTimeout(timer);
424
+ }
425
+ const text = await response.text();
426
+ let json = undefined;
427
+ if (text) {
428
+ try {
429
+ json = JSON.parse(text);
430
+ }
431
+ catch {
432
+ // leave undefined
433
+ }
434
+ }
435
+ if (!response.ok) {
436
+ const errBody = (json ?? text);
437
+ const code = typeof errBody === "object" && errBody && typeof errBody.error === "string"
438
+ ? errBody.error
439
+ : "http_error";
440
+ throw new ValidPayError(code, `ValidPay API ${method} ${path} failed: ${response.status}`, { status: response.status, details: errBody });
441
+ }
442
+ return json;
443
+ }
444
+ }
445
+ // === Helpers ===
446
+ function checkCommitment(expected, plaintext) {
447
+ if (!expected)
448
+ return false;
449
+ const actual = commitmentHash(plaintext);
450
+ if (actual !== expected) {
451
+ throw new ValidPayError("integrity_failure", "INTEGRITY VERIFICATION FAILED — the decrypted payload does not match the commitment hash stored at issuance.");
452
+ }
453
+ return true;
454
+ }
455
+ function computeTimeLockStatus(validFrom, validUntil) {
456
+ if (!validFrom && !validUntil)
457
+ return null;
458
+ const now = Date.now();
459
+ if (validFrom) {
460
+ const t = Date.parse(validFrom);
461
+ if (!Number.isNaN(t) && now < t)
462
+ return "not_yet_valid";
463
+ }
464
+ if (validUntil) {
465
+ const t = Date.parse(validUntil);
466
+ if (!Number.isNaN(t) && now > t)
467
+ return "expired";
468
+ }
469
+ return "valid";
470
+ }
471
+ function validateTimeLock(validFrom, validUntil) {
472
+ if (validFrom !== undefined && Number.isNaN(Date.parse(validFrom))) {
473
+ throw new ValidPayError("invalid_argument", `validFrom is not a valid ISO-8601: ${validFrom}`);
474
+ }
475
+ if (validUntil !== undefined && Number.isNaN(Date.parse(validUntil))) {
476
+ throw new ValidPayError("invalid_argument", `validUntil is not a valid ISO-8601: ${validUntil}`);
477
+ }
478
+ if (validFrom !== undefined && validUntil !== undefined) {
479
+ if (Date.parse(validFrom) >= Date.parse(validUntil)) {
480
+ throw new ValidPayError("invalid_argument", "validFrom must be before validUntil");
481
+ }
482
+ }
483
+ }
484
+ function buildVerifyResult(data, payload, integrityVerified) {
485
+ return {
486
+ intentId: data.intent_id,
487
+ payload,
488
+ issuer: data.issuer,
489
+ issuerVerified: data.issuer_verified,
490
+ registeredAt: data.registered_at,
491
+ status: data.status,
492
+ integrityVerified,
493
+ validFrom: data.valid_from ?? null,
494
+ validUntil: data.valid_until ?? null,
495
+ timeLockStatus: computeTimeLockStatus(data.valid_from, data.valid_until),
496
+ };
497
+ }
498
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Wire format (matches the Python SDK so blobs are interoperable):
3
+ * base64(iv[12] || authTag[16] || ciphertext)
4
+ */
5
+ export declare function generateKey(): string;
6
+ export declare function encrypt(plaintext: string, key: string): string;
7
+ export declare function decrypt(blob: string, key: string): string;
8
+ export declare function commitmentHash(plaintext: string): string;
9
+ export declare function splitKey(key: string): [string, string];
10
+ export declare function combineKeyShares(shareA: string, shareB: string): string;
11
+ /** Encrypt each field of payload with its own AES key (Selective Disclosure). */
12
+ export declare function encryptFields(payload: Record<string, unknown>): {
13
+ encryptedFields: Record<string, string>;
14
+ fieldKeys: Record<string, string>;
15
+ };
16
+ /** Build per-role key map; "full" role always added with all keys. */
17
+ export declare function buildKeyMap(fieldKeys: Record<string, string>, disclosurePolicy: Record<string, string[]>): Record<string, Record<string, string>>;
18
+ /** Decrypt only fields with keys; others become "[REDACTED]". */
19
+ export declare function decryptFields(encryptedFields: Record<string, string>, fieldKeys: Record<string, string>): Record<string, unknown>;
20
+ //# sourceMappingURL=crypto.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crypto.d.ts","sourceRoot":"","sources":["../src/crypto.ts"],"names":[],"mappings":"AAQA;;;GAGG;AAEH,wBAAgB,WAAW,IAAI,MAAM,CAEpC;AAkBD,wBAAgB,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAO9D;AAED,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAkCzD;AAED,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAExD;AAED,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAQtD;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAQvE;AAED,iFAAiF;AACjF,wBAAgB,aAAa,CAC3B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC/B;IAAE,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,CAUhF;AAED,sEAAsE;AACtE,wBAAgB,WAAW,CACzB,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EACjC,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,GACzC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAWxC;AAED,iEAAiE;AACjE,wBAAgB,aAAa,CAC3B,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EACvC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAChC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAezB"}
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,4 @@
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
+ //# 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"}
package/dist/index.js CHANGED
@@ -1,33 +1,4 @@
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
+ //# 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"}
@@ -0,0 +1,104 @@
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 RawFragmentResponse {
83
+ fragment_b?: string;
84
+ error?: string;
85
+ }
86
+ export interface RawRevocationHistoryResponse {
87
+ events?: Array<{
88
+ id: string;
89
+ action: "revoked" | "reinstated";
90
+ reason?: string;
91
+ performed_at: string;
92
+ }>;
93
+ }
94
+ export declare class ValidPayError extends Error {
95
+ readonly code: string;
96
+ readonly status?: number;
97
+ readonly details?: unknown;
98
+ constructor(code: string, message: string, options?: {
99
+ status?: number;
100
+ details?: unknown;
101
+ cause?: unknown;
102
+ });
103
+ }
104
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
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":"AAwGA,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"}
package/package.json CHANGED
@@ -1,26 +1,55 @@
1
- {
2
- "name": "@validpay/node-sdk",
3
- "version": "0.1.0",
4
- "description": "ValidPay Node.js SDK — Document verification and authentication API client",
5
- "main": "dist/index.js",
6
- "types": "dist/index.d.ts",
7
- "type": "module",
8
- "exports": {
9
- ".": {
10
- "import": "./dist/index.js",
11
- "types": "./dist/index.d.ts"
12
- }
13
- },
14
- "files": ["dist", "README.md"],
15
- "keywords": ["validpay", "document-verification", "authentication", "check-verification", "anti-fraud", "encryption"],
16
- "author": "MiLu Technologies LLC <mike@validpay.io>",
17
- "license": "MIT",
18
- "homepage": "https://validpay.io",
19
- "repository": {
20
- "type": "git",
21
- "url": "https://github.com/ValidPay-io/validpay-node-sdk"
22
- },
23
- "engines": {
24
- "node": ">=20.0.0"
25
- }
26
- }
1
+ {
2
+ "name": "@validpay/node-sdk",
3
+ "version": "0.2.0",
4
+ "description": "Official ValidPay Node.js SDK — client-side AES-256-GCM encryption + commitment hashing + split-key + selective disclosure + revocation. Zero production dependencies.",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.js"
12
+ }
13
+ },
14
+ "files": [
15
+ "dist",
16
+ "README.md",
17
+ "LICENSE"
18
+ ],
19
+ "scripts": {
20
+ "build": "tsc -p tsconfig.build.json",
21
+ "test": "vitest run",
22
+ "test:watch": "vitest",
23
+ "typecheck": "tsc --noEmit",
24
+ "prepublishOnly": "npm run build"
25
+ },
26
+ "engines": {
27
+ "node": ">=20"
28
+ },
29
+ "keywords": [
30
+ "validpay",
31
+ "encryption",
32
+ "aes-256-gcm",
33
+ "document-verification",
34
+ "check-fraud",
35
+ "authentication",
36
+ "selective-disclosure",
37
+ "split-key",
38
+ "blind-escrow"
39
+ ],
40
+ "homepage": "https://github.com/ValidPay-io/validpay-node-sdk",
41
+ "repository": {
42
+ "type": "git",
43
+ "url": "git+https://github.com/ValidPay-io/validpay-node-sdk.git"
44
+ },
45
+ "bugs": {
46
+ "url": "https://github.com/ValidPay-io/validpay-node-sdk/issues"
47
+ },
48
+ "license": "MIT",
49
+ "author": "ValidPay",
50
+ "devDependencies": {
51
+ "@types/node": "^20.11.0",
52
+ "typescript": "^5.4.0",
53
+ "vitest": "^1.6.0"
54
+ }
55
+ }