@auths-dev/verifier 0.1.1
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/README.md +99 -0
- package/dist/cjs/index.js +284 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/types.js +3 -0
- package/dist/cjs/types.js.map +1 -0
- package/dist/esm/index.js +238 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/types.js +2 -0
- package/dist/esm/types.js.map +1 -0
- package/dist/types/index.d.ts +158 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/types.d.ts +102 -0
- package/dist/types/types.d.ts.map +1 -0
- package/package.json +52 -0
package/README.md
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# @auths-dev/verifier
|
|
2
|
+
|
|
3
|
+
TypeScript/JavaScript library for verifying Auths attestations using WASM.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @auths-dev/verifier
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Requirements: Node.js 18+
|
|
12
|
+
|
|
13
|
+
## Quick start
|
|
14
|
+
|
|
15
|
+
```typescript
|
|
16
|
+
import { init, verifyAttestation, verifyChain } from '@auths-dev/verifier';
|
|
17
|
+
|
|
18
|
+
// Initialize WASM module (required once)
|
|
19
|
+
await init();
|
|
20
|
+
|
|
21
|
+
// Verify a single attestation
|
|
22
|
+
const result = verifyAttestation(attestationJson, issuerPublicKeyHex);
|
|
23
|
+
if (result.valid) {
|
|
24
|
+
console.log('Attestation is valid!');
|
|
25
|
+
} else {
|
|
26
|
+
console.error('Verification failed:', result.error);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// Verify a chain of attestations
|
|
30
|
+
const report = verifyChain(attestationsArray, rootPublicKeyHex);
|
|
31
|
+
if (report.status.type === 'Valid') {
|
|
32
|
+
console.log('Chain verified!');
|
|
33
|
+
}
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## API reference
|
|
37
|
+
|
|
38
|
+
### Functions
|
|
39
|
+
|
|
40
|
+
| Function | Returns | Description |
|
|
41
|
+
|----------|---------|-------------|
|
|
42
|
+
| `init()` | `Promise<void>` | Initialize WASM module (call once) |
|
|
43
|
+
| `verifyAttestation(json, pkHex)` | `VerificationResult` | Verify single attestation |
|
|
44
|
+
| `verifyChain(attestations, rootPkHex)` | `VerificationReport` | Verify attestation chain |
|
|
45
|
+
| `verifyAttestationOrThrow(json, pkHex)` | `void` | Verify or throw on failure |
|
|
46
|
+
| `isInitialized()` | `boolean` | Check WASM init state |
|
|
47
|
+
| `isVerificationValid(report)` | `boolean` | Helper for report status |
|
|
48
|
+
|
|
49
|
+
### Types
|
|
50
|
+
|
|
51
|
+
```typescript
|
|
52
|
+
interface VerificationResult {
|
|
53
|
+
valid: boolean;
|
|
54
|
+
error?: string;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
interface VerificationReport {
|
|
58
|
+
status: VerificationStatus;
|
|
59
|
+
chain: ChainLink[];
|
|
60
|
+
warnings: string[];
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
type VerificationStatus =
|
|
64
|
+
| { type: "Valid" }
|
|
65
|
+
| { type: "Expired"; at: string }
|
|
66
|
+
| { type: "Revoked"; at?: string }
|
|
67
|
+
| { type: "InvalidSignature"; step: number }
|
|
68
|
+
| { type: "BrokenChain"; missing_link: string };
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## Browser usage
|
|
72
|
+
|
|
73
|
+
```html
|
|
74
|
+
<script type="module">
|
|
75
|
+
import init, { verifyAttestation } from './pkg/auths_verifier.js';
|
|
76
|
+
|
|
77
|
+
await init();
|
|
78
|
+
const result = verifyAttestation(json, pkHex);
|
|
79
|
+
</script>
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Building from source
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
npm install
|
|
86
|
+
npm run build:wasm # Requires Rust and wasm-pack
|
|
87
|
+
npm run build:ts
|
|
88
|
+
npm run build # Build everything
|
|
89
|
+
npm test
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## License
|
|
93
|
+
|
|
94
|
+
MIT -- see [LICENSE](../../LICENSE).
|
|
95
|
+
|
|
96
|
+
## Links
|
|
97
|
+
|
|
98
|
+
- [Documentation](https://github.com/auths-dev/auths/tree/main/packages/auths-verifier-ts)
|
|
99
|
+
- [Repository](https://github.com/auths-dev/auths)
|
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @auths-dev/verifier - Attestation verification for TypeScript/JavaScript
|
|
4
|
+
*
|
|
5
|
+
* This package provides WASM-powered cryptographic verification of Auths attestations.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* import { init, verifyAttestation, verifyChain } from '@auths-dev/verifier';
|
|
10
|
+
*
|
|
11
|
+
* // Initialize the WASM module (required before verification)
|
|
12
|
+
* await init();
|
|
13
|
+
*
|
|
14
|
+
* // Verify a single attestation
|
|
15
|
+
* const result = verifyAttestation(attestationJson, issuerPublicKeyHex);
|
|
16
|
+
* if (!result.valid) {
|
|
17
|
+
* console.error('Verification failed:', result.error);
|
|
18
|
+
* }
|
|
19
|
+
*
|
|
20
|
+
* // Verify a chain of attestations
|
|
21
|
+
* const report = verifyChain(attestationsArray, rootPublicKeyHex);
|
|
22
|
+
* if (report.status.type !== 'Valid') {
|
|
23
|
+
* console.error('Chain verification failed:', report.status);
|
|
24
|
+
* }
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
28
|
+
if (k2 === undefined) k2 = k;
|
|
29
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
30
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
31
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
32
|
+
}
|
|
33
|
+
Object.defineProperty(o, k2, desc);
|
|
34
|
+
}) : (function(o, m, k, k2) {
|
|
35
|
+
if (k2 === undefined) k2 = k;
|
|
36
|
+
o[k2] = m[k];
|
|
37
|
+
}));
|
|
38
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
39
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
40
|
+
}) : function(o, v) {
|
|
41
|
+
o["default"] = v;
|
|
42
|
+
});
|
|
43
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
44
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
45
|
+
};
|
|
46
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
47
|
+
var ownKeys = function(o) {
|
|
48
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
49
|
+
var ar = [];
|
|
50
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
51
|
+
return ar;
|
|
52
|
+
};
|
|
53
|
+
return ownKeys(o);
|
|
54
|
+
};
|
|
55
|
+
return function (mod) {
|
|
56
|
+
if (mod && mod.__esModule) return mod;
|
|
57
|
+
var result = {};
|
|
58
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
59
|
+
__setModuleDefault(result, mod);
|
|
60
|
+
return result;
|
|
61
|
+
};
|
|
62
|
+
})();
|
|
63
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
64
|
+
exports.init = init;
|
|
65
|
+
exports.isInitialized = isInitialized;
|
|
66
|
+
exports.verifyAttestation = verifyAttestation;
|
|
67
|
+
exports.verifyAttestationOrThrow = verifyAttestationOrThrow;
|
|
68
|
+
exports.verifyChain = verifyChain;
|
|
69
|
+
exports.isVerificationValid = isVerificationValid;
|
|
70
|
+
exports.verifyKel = verifyKel;
|
|
71
|
+
exports.verifyDeviceLink = verifyDeviceLink;
|
|
72
|
+
__exportStar(require("./types"), exports);
|
|
73
|
+
// WASM module state
|
|
74
|
+
let wasmModule = null;
|
|
75
|
+
/**
|
|
76
|
+
* Initialize the WASM module. Must be called before any verification functions.
|
|
77
|
+
*
|
|
78
|
+
* @throws Error if WASM initialization fails
|
|
79
|
+
*
|
|
80
|
+
* @example
|
|
81
|
+
* ```typescript
|
|
82
|
+
* await init();
|
|
83
|
+
* // Now verification functions can be used
|
|
84
|
+
* ```
|
|
85
|
+
*/
|
|
86
|
+
async function init() {
|
|
87
|
+
if (wasmModule) {
|
|
88
|
+
return; // Already initialized
|
|
89
|
+
}
|
|
90
|
+
try {
|
|
91
|
+
const wasm = await Promise.resolve().then(() => __importStar(require('../wasm/auths_verifier.js')));
|
|
92
|
+
wasmModule = wasm;
|
|
93
|
+
}
|
|
94
|
+
catch (error) {
|
|
95
|
+
throw new Error(`Failed to initialize WASM module: ${error}`);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Check if the WASM module is initialized
|
|
100
|
+
*/
|
|
101
|
+
function isInitialized() {
|
|
102
|
+
return wasmModule !== null;
|
|
103
|
+
}
|
|
104
|
+
function ensureInitialized() {
|
|
105
|
+
if (!wasmModule) {
|
|
106
|
+
throw new Error('WASM module not initialized. Call init() first and await its completion.');
|
|
107
|
+
}
|
|
108
|
+
return wasmModule;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Verify a single attestation against an issuer's public key.
|
|
112
|
+
*
|
|
113
|
+
* @param attestationJson - The attestation as a JSON string
|
|
114
|
+
* @param issuerPublicKeyHex - The issuer's Ed25519 public key in hex format (64 characters)
|
|
115
|
+
* @returns VerificationResult with valid flag and optional error
|
|
116
|
+
*
|
|
117
|
+
* @example
|
|
118
|
+
* ```typescript
|
|
119
|
+
* const result = verifyAttestation(
|
|
120
|
+
* JSON.stringify(attestation),
|
|
121
|
+
* 'a1b2c3d4...' // 64 hex characters
|
|
122
|
+
* );
|
|
123
|
+
*
|
|
124
|
+
* if (result.valid) {
|
|
125
|
+
* console.log('Attestation is valid!');
|
|
126
|
+
* } else {
|
|
127
|
+
* console.error('Invalid:', result.error);
|
|
128
|
+
* }
|
|
129
|
+
* ```
|
|
130
|
+
*/
|
|
131
|
+
async function verifyAttestation(attestationJson, issuerPublicKeyHex) {
|
|
132
|
+
const wasm = ensureInitialized();
|
|
133
|
+
try {
|
|
134
|
+
const resultJson = await wasm.verifyAttestationWithResult(attestationJson, issuerPublicKeyHex);
|
|
135
|
+
return JSON.parse(resultJson);
|
|
136
|
+
}
|
|
137
|
+
catch (error) {
|
|
138
|
+
return {
|
|
139
|
+
valid: false,
|
|
140
|
+
error: error instanceof Error ? error.message : String(error),
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Verify a single attestation, throwing on failure.
|
|
146
|
+
*
|
|
147
|
+
* @param attestationJson - The attestation as a JSON string
|
|
148
|
+
* @param issuerPublicKeyHex - The issuer's Ed25519 public key in hex format
|
|
149
|
+
* @throws Error if verification fails
|
|
150
|
+
*
|
|
151
|
+
* @example
|
|
152
|
+
* ```typescript
|
|
153
|
+
* try {
|
|
154
|
+
* verifyAttestationOrThrow(attestationJson, issuerPk);
|
|
155
|
+
* console.log('Valid!');
|
|
156
|
+
* } catch (error) {
|
|
157
|
+
* console.error('Invalid:', error.message);
|
|
158
|
+
* }
|
|
159
|
+
* ```
|
|
160
|
+
*/
|
|
161
|
+
async function verifyAttestationOrThrow(attestationJson, issuerPublicKeyHex) {
|
|
162
|
+
const wasm = ensureInitialized();
|
|
163
|
+
try {
|
|
164
|
+
await wasm.verifyAttestationJson(attestationJson, issuerPublicKeyHex);
|
|
165
|
+
}
|
|
166
|
+
catch (error) {
|
|
167
|
+
throw new Error(`Attestation verification failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Verify a chain of attestations from a root identity to a leaf device.
|
|
172
|
+
*
|
|
173
|
+
* @param attestations - Array of attestations (as JSON strings or objects)
|
|
174
|
+
* @param rootPublicKeyHex - The root identity's Ed25519 public key in hex format
|
|
175
|
+
* @returns VerificationReport with status, chain details, and warnings
|
|
176
|
+
*
|
|
177
|
+
* @example
|
|
178
|
+
* ```typescript
|
|
179
|
+
* const report = verifyChain(
|
|
180
|
+
* [rootToIdentityAtt, identityToDeviceAtt],
|
|
181
|
+
* rootPublicKeyHex
|
|
182
|
+
* );
|
|
183
|
+
*
|
|
184
|
+
* if (report.status.type === 'Valid') {
|
|
185
|
+
* console.log('Chain verified!');
|
|
186
|
+
* } else {
|
|
187
|
+
* console.error('Chain invalid:', report.status);
|
|
188
|
+
* }
|
|
189
|
+
*
|
|
190
|
+
* // Check individual links
|
|
191
|
+
* report.chain.forEach((link, i) => {
|
|
192
|
+
* console.log(`Link ${i}: ${link.valid ? 'OK' : link.error}`);
|
|
193
|
+
* });
|
|
194
|
+
* ```
|
|
195
|
+
*/
|
|
196
|
+
async function verifyChain(attestations, rootPublicKeyHex) {
|
|
197
|
+
const wasm = ensureInitialized();
|
|
198
|
+
const attestationsJson = JSON.stringify(attestations.map(att => (typeof att === 'string' ? JSON.parse(att) : att)));
|
|
199
|
+
try {
|
|
200
|
+
const reportJson = await wasm.verifyChainJson(attestationsJson, rootPublicKeyHex);
|
|
201
|
+
return JSON.parse(reportJson);
|
|
202
|
+
}
|
|
203
|
+
catch (error) {
|
|
204
|
+
return {
|
|
205
|
+
status: {
|
|
206
|
+
type: 'BrokenChain',
|
|
207
|
+
missing_link: error instanceof Error ? error.message : String(error),
|
|
208
|
+
},
|
|
209
|
+
chain: [],
|
|
210
|
+
warnings: [],
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Helper to check if a verification report indicates success
|
|
216
|
+
*
|
|
217
|
+
* @param report - The verification report to check
|
|
218
|
+
* @returns true if the status is Valid
|
|
219
|
+
*/
|
|
220
|
+
function isVerificationValid(report) {
|
|
221
|
+
return report.status.type === 'Valid';
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Verify a KERI Key Event Log and return the resulting key state.
|
|
225
|
+
*
|
|
226
|
+
* @param kelJson - JSON array of KEL events (inception, rotation, interaction)
|
|
227
|
+
* @returns KeriKeyState with the current public key and sequence number
|
|
228
|
+
* @throws Error if KEL parsing or verification fails
|
|
229
|
+
*
|
|
230
|
+
* @example
|
|
231
|
+
* ```typescript
|
|
232
|
+
* const keyState = await verifyKel(kelEventsJson);
|
|
233
|
+
* console.log('Current key:', keyState.current_key_encoded);
|
|
234
|
+
* console.log('Sequence:', keyState.sequence);
|
|
235
|
+
* ```
|
|
236
|
+
*/
|
|
237
|
+
async function verifyKel(kelJson) {
|
|
238
|
+
const wasm = ensureInitialized();
|
|
239
|
+
try {
|
|
240
|
+
const resultJson = await wasm.validateKelJson(kelJson);
|
|
241
|
+
return JSON.parse(resultJson);
|
|
242
|
+
}
|
|
243
|
+
catch (error) {
|
|
244
|
+
throw new Error(`KEL verification failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* Verify that a device is cryptographically linked to a KERI identity.
|
|
249
|
+
*
|
|
250
|
+
* Composes KEL verification, attestation signature verification, device DID matching,
|
|
251
|
+
* and seal anchoring. Returns a result object — never throws for verification failures.
|
|
252
|
+
*
|
|
253
|
+
* @param kelJson - JSON array of KEL events for the identity
|
|
254
|
+
* @param attestationJson - JSON attestation linking the identity to the device
|
|
255
|
+
* @param deviceDid - Expected device DID string (e.g. "did:key:z6Mk...")
|
|
256
|
+
* @returns DeviceLinkResult with valid flag, optional key state, and seal info
|
|
257
|
+
*
|
|
258
|
+
* @example
|
|
259
|
+
* ```typescript
|
|
260
|
+
* const result = await verifyDeviceLink(kelJson, attestationJson, 'did:key:z6Mk...');
|
|
261
|
+
* if (result.valid) {
|
|
262
|
+
* console.log('Device verified! Identity key:', result.key_state?.current_key_encoded);
|
|
263
|
+
* if (result.seal_sequence !== undefined) {
|
|
264
|
+
* console.log('Attestation anchored at KEL sequence:', result.seal_sequence);
|
|
265
|
+
* }
|
|
266
|
+
* } else {
|
|
267
|
+
* console.error('Verification failed:', result.error);
|
|
268
|
+
* }
|
|
269
|
+
* ```
|
|
270
|
+
*/
|
|
271
|
+
async function verifyDeviceLink(kelJson, attestationJson, deviceDid) {
|
|
272
|
+
const wasm = ensureInitialized();
|
|
273
|
+
try {
|
|
274
|
+
const resultJson = await wasm.verifyDeviceLink(kelJson, attestationJson, deviceDid);
|
|
275
|
+
return JSON.parse(resultJson);
|
|
276
|
+
}
|
|
277
|
+
catch (error) {
|
|
278
|
+
return {
|
|
279
|
+
valid: false,
|
|
280
|
+
error: error instanceof Error ? error.message : String(error),
|
|
281
|
+
};
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @auths-dev/verifier - Attestation verification for TypeScript/JavaScript
|
|
3
|
+
*
|
|
4
|
+
* This package provides WASM-powered cryptographic verification of Auths attestations.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```typescript
|
|
8
|
+
* import { init, verifyAttestation, verifyChain } from '@auths-dev/verifier';
|
|
9
|
+
*
|
|
10
|
+
* // Initialize the WASM module (required before verification)
|
|
11
|
+
* await init();
|
|
12
|
+
*
|
|
13
|
+
* // Verify a single attestation
|
|
14
|
+
* const result = verifyAttestation(attestationJson, issuerPublicKeyHex);
|
|
15
|
+
* if (!result.valid) {
|
|
16
|
+
* console.error('Verification failed:', result.error);
|
|
17
|
+
* }
|
|
18
|
+
*
|
|
19
|
+
* // Verify a chain of attestations
|
|
20
|
+
* const report = verifyChain(attestationsArray, rootPublicKeyHex);
|
|
21
|
+
* if (report.status.type !== 'Valid') {
|
|
22
|
+
* console.error('Chain verification failed:', report.status);
|
|
23
|
+
* }
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
export * from './types';
|
|
27
|
+
// WASM module state
|
|
28
|
+
let wasmModule = null;
|
|
29
|
+
/**
|
|
30
|
+
* Initialize the WASM module. Must be called before any verification functions.
|
|
31
|
+
*
|
|
32
|
+
* @throws Error if WASM initialization fails
|
|
33
|
+
*
|
|
34
|
+
* @example
|
|
35
|
+
* ```typescript
|
|
36
|
+
* await init();
|
|
37
|
+
* // Now verification functions can be used
|
|
38
|
+
* ```
|
|
39
|
+
*/
|
|
40
|
+
export async function init() {
|
|
41
|
+
if (wasmModule) {
|
|
42
|
+
return; // Already initialized
|
|
43
|
+
}
|
|
44
|
+
try {
|
|
45
|
+
const wasm = await import('../wasm/auths_verifier.js');
|
|
46
|
+
wasmModule = wasm;
|
|
47
|
+
}
|
|
48
|
+
catch (error) {
|
|
49
|
+
throw new Error(`Failed to initialize WASM module: ${error}`);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Check if the WASM module is initialized
|
|
54
|
+
*/
|
|
55
|
+
export function isInitialized() {
|
|
56
|
+
return wasmModule !== null;
|
|
57
|
+
}
|
|
58
|
+
function ensureInitialized() {
|
|
59
|
+
if (!wasmModule) {
|
|
60
|
+
throw new Error('WASM module not initialized. Call init() first and await its completion.');
|
|
61
|
+
}
|
|
62
|
+
return wasmModule;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Verify a single attestation against an issuer's public key.
|
|
66
|
+
*
|
|
67
|
+
* @param attestationJson - The attestation as a JSON string
|
|
68
|
+
* @param issuerPublicKeyHex - The issuer's Ed25519 public key in hex format (64 characters)
|
|
69
|
+
* @returns VerificationResult with valid flag and optional error
|
|
70
|
+
*
|
|
71
|
+
* @example
|
|
72
|
+
* ```typescript
|
|
73
|
+
* const result = verifyAttestation(
|
|
74
|
+
* JSON.stringify(attestation),
|
|
75
|
+
* 'a1b2c3d4...' // 64 hex characters
|
|
76
|
+
* );
|
|
77
|
+
*
|
|
78
|
+
* if (result.valid) {
|
|
79
|
+
* console.log('Attestation is valid!');
|
|
80
|
+
* } else {
|
|
81
|
+
* console.error('Invalid:', result.error);
|
|
82
|
+
* }
|
|
83
|
+
* ```
|
|
84
|
+
*/
|
|
85
|
+
export async function verifyAttestation(attestationJson, issuerPublicKeyHex) {
|
|
86
|
+
const wasm = ensureInitialized();
|
|
87
|
+
try {
|
|
88
|
+
const resultJson = await wasm.verifyAttestationWithResult(attestationJson, issuerPublicKeyHex);
|
|
89
|
+
return JSON.parse(resultJson);
|
|
90
|
+
}
|
|
91
|
+
catch (error) {
|
|
92
|
+
return {
|
|
93
|
+
valid: false,
|
|
94
|
+
error: error instanceof Error ? error.message : String(error),
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Verify a single attestation, throwing on failure.
|
|
100
|
+
*
|
|
101
|
+
* @param attestationJson - The attestation as a JSON string
|
|
102
|
+
* @param issuerPublicKeyHex - The issuer's Ed25519 public key in hex format
|
|
103
|
+
* @throws Error if verification fails
|
|
104
|
+
*
|
|
105
|
+
* @example
|
|
106
|
+
* ```typescript
|
|
107
|
+
* try {
|
|
108
|
+
* verifyAttestationOrThrow(attestationJson, issuerPk);
|
|
109
|
+
* console.log('Valid!');
|
|
110
|
+
* } catch (error) {
|
|
111
|
+
* console.error('Invalid:', error.message);
|
|
112
|
+
* }
|
|
113
|
+
* ```
|
|
114
|
+
*/
|
|
115
|
+
export async function verifyAttestationOrThrow(attestationJson, issuerPublicKeyHex) {
|
|
116
|
+
const wasm = ensureInitialized();
|
|
117
|
+
try {
|
|
118
|
+
await wasm.verifyAttestationJson(attestationJson, issuerPublicKeyHex);
|
|
119
|
+
}
|
|
120
|
+
catch (error) {
|
|
121
|
+
throw new Error(`Attestation verification failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Verify a chain of attestations from a root identity to a leaf device.
|
|
126
|
+
*
|
|
127
|
+
* @param attestations - Array of attestations (as JSON strings or objects)
|
|
128
|
+
* @param rootPublicKeyHex - The root identity's Ed25519 public key in hex format
|
|
129
|
+
* @returns VerificationReport with status, chain details, and warnings
|
|
130
|
+
*
|
|
131
|
+
* @example
|
|
132
|
+
* ```typescript
|
|
133
|
+
* const report = verifyChain(
|
|
134
|
+
* [rootToIdentityAtt, identityToDeviceAtt],
|
|
135
|
+
* rootPublicKeyHex
|
|
136
|
+
* );
|
|
137
|
+
*
|
|
138
|
+
* if (report.status.type === 'Valid') {
|
|
139
|
+
* console.log('Chain verified!');
|
|
140
|
+
* } else {
|
|
141
|
+
* console.error('Chain invalid:', report.status);
|
|
142
|
+
* }
|
|
143
|
+
*
|
|
144
|
+
* // Check individual links
|
|
145
|
+
* report.chain.forEach((link, i) => {
|
|
146
|
+
* console.log(`Link ${i}: ${link.valid ? 'OK' : link.error}`);
|
|
147
|
+
* });
|
|
148
|
+
* ```
|
|
149
|
+
*/
|
|
150
|
+
export async function verifyChain(attestations, rootPublicKeyHex) {
|
|
151
|
+
const wasm = ensureInitialized();
|
|
152
|
+
const attestationsJson = JSON.stringify(attestations.map(att => (typeof att === 'string' ? JSON.parse(att) : att)));
|
|
153
|
+
try {
|
|
154
|
+
const reportJson = await wasm.verifyChainJson(attestationsJson, rootPublicKeyHex);
|
|
155
|
+
return JSON.parse(reportJson);
|
|
156
|
+
}
|
|
157
|
+
catch (error) {
|
|
158
|
+
return {
|
|
159
|
+
status: {
|
|
160
|
+
type: 'BrokenChain',
|
|
161
|
+
missing_link: error instanceof Error ? error.message : String(error),
|
|
162
|
+
},
|
|
163
|
+
chain: [],
|
|
164
|
+
warnings: [],
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Helper to check if a verification report indicates success
|
|
170
|
+
*
|
|
171
|
+
* @param report - The verification report to check
|
|
172
|
+
* @returns true if the status is Valid
|
|
173
|
+
*/
|
|
174
|
+
export function isVerificationValid(report) {
|
|
175
|
+
return report.status.type === 'Valid';
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Verify a KERI Key Event Log and return the resulting key state.
|
|
179
|
+
*
|
|
180
|
+
* @param kelJson - JSON array of KEL events (inception, rotation, interaction)
|
|
181
|
+
* @returns KeriKeyState with the current public key and sequence number
|
|
182
|
+
* @throws Error if KEL parsing or verification fails
|
|
183
|
+
*
|
|
184
|
+
* @example
|
|
185
|
+
* ```typescript
|
|
186
|
+
* const keyState = await verifyKel(kelEventsJson);
|
|
187
|
+
* console.log('Current key:', keyState.current_key_encoded);
|
|
188
|
+
* console.log('Sequence:', keyState.sequence);
|
|
189
|
+
* ```
|
|
190
|
+
*/
|
|
191
|
+
export async function verifyKel(kelJson) {
|
|
192
|
+
const wasm = ensureInitialized();
|
|
193
|
+
try {
|
|
194
|
+
const resultJson = await wasm.validateKelJson(kelJson);
|
|
195
|
+
return JSON.parse(resultJson);
|
|
196
|
+
}
|
|
197
|
+
catch (error) {
|
|
198
|
+
throw new Error(`KEL verification failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Verify that a device is cryptographically linked to a KERI identity.
|
|
203
|
+
*
|
|
204
|
+
* Composes KEL verification, attestation signature verification, device DID matching,
|
|
205
|
+
* and seal anchoring. Returns a result object — never throws for verification failures.
|
|
206
|
+
*
|
|
207
|
+
* @param kelJson - JSON array of KEL events for the identity
|
|
208
|
+
* @param attestationJson - JSON attestation linking the identity to the device
|
|
209
|
+
* @param deviceDid - Expected device DID string (e.g. "did:key:z6Mk...")
|
|
210
|
+
* @returns DeviceLinkResult with valid flag, optional key state, and seal info
|
|
211
|
+
*
|
|
212
|
+
* @example
|
|
213
|
+
* ```typescript
|
|
214
|
+
* const result = await verifyDeviceLink(kelJson, attestationJson, 'did:key:z6Mk...');
|
|
215
|
+
* if (result.valid) {
|
|
216
|
+
* console.log('Device verified! Identity key:', result.key_state?.current_key_encoded);
|
|
217
|
+
* if (result.seal_sequence !== undefined) {
|
|
218
|
+
* console.log('Attestation anchored at KEL sequence:', result.seal_sequence);
|
|
219
|
+
* }
|
|
220
|
+
* } else {
|
|
221
|
+
* console.error('Verification failed:', result.error);
|
|
222
|
+
* }
|
|
223
|
+
* ```
|
|
224
|
+
*/
|
|
225
|
+
export async function verifyDeviceLink(kelJson, attestationJson, deviceDid) {
|
|
226
|
+
const wasm = ensureInitialized();
|
|
227
|
+
try {
|
|
228
|
+
const resultJson = await wasm.verifyDeviceLink(kelJson, attestationJson, deviceDid);
|
|
229
|
+
return JSON.parse(resultJson);
|
|
230
|
+
}
|
|
231
|
+
catch (error) {
|
|
232
|
+
return {
|
|
233
|
+
valid: false,
|
|
234
|
+
error: error instanceof Error ? error.message : String(error),
|
|
235
|
+
};
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,cAAc,SAAS,CAAC;AAExB,oBAAoB;AACpB,IAAI,UAAU,GAAsB,IAAI,CAAC;AAYzC;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,IAAI;IACxB,IAAI,UAAU,EAAE,CAAC;QACf,OAAO,CAAC,sBAAsB;IAChC,CAAC;IAED,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,2BAA2B,CAAC,CAAC;QACvD,UAAU,GAAG,IAAI,CAAC;IACpB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,qCAAqC,KAAK,EAAE,CAAC,CAAC;IAChE,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,aAAa;IAC3B,OAAO,UAAU,KAAK,IAAI,CAAC;AAC7B,CAAC;AAED,SAAS,iBAAiB;IACxB,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,MAAM,IAAI,KAAK,CACb,0EAA0E,CAC3E,CAAC;IACJ,CAAC;IACD,OAAO,UAAU,CAAC;AACpB,CAAC;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,eAAuB,EACvB,kBAA0B;IAE1B,MAAM,IAAI,GAAG,iBAAiB,EAAE,CAAC;IAEjC,IAAI,CAAC;QACH,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,2BAA2B,CAAC,eAAe,EAAE,kBAAkB,CAAC,CAAC;QAC/F,OAAO,IAAI,CAAC,KAAK,CAAC,UAAU,CAAuB,CAAC;IACtD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO;YACL,KAAK,EAAE,KAAK;YACZ,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;SAC9D,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAC5C,eAAuB,EACvB,kBAA0B;IAE1B,MAAM,IAAI,GAAG,iBAAiB,EAAE,CAAC;IAEjC,IAAI,CAAC;QACH,MAAM,IAAI,CAAC,qBAAqB,CAAC,eAAe,EAAE,kBAAkB,CAAC,CAAC;IACxE,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CACb,oCAAoC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAC7F,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,YAAiC,EACjC,gBAAwB;IAExB,MAAM,IAAI,GAAG,iBAAiB,EAAE,CAAC;IAEjC,MAAM,gBAAgB,GAAG,IAAI,CAAC,SAAS,CACrC,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAC3E,CAAC;IAEF,IAAI,CAAC;QACH,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,gBAAgB,EAAE,gBAAgB,CAAC,CAAC;QAClF,OAAO,IAAI,CAAC,KAAK,CAAC,UAAU,CAAuB,CAAC;IACtD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO;YACL,MAAM,EAAE;gBACN,IAAI,EAAE,aAAa;gBACnB,YAAY,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;aACrE;YACD,KAAK,EAAE,EAAE;YACT,QAAQ,EAAE,EAAE;SACb,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,mBAAmB,CAAC,MAA0B;IAC5D,OAAO,MAAM,CAAC,MAAM,CAAC,IAAI,KAAK,OAAO,CAAC;AACxC,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,OAAe;IAC7C,MAAM,IAAI,GAAG,iBAAiB,EAAE,CAAC;IAEjC,IAAI,CAAC;QACH,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;QACvD,OAAO,IAAI,CAAC,KAAK,CAAC,UAAU,CAAiB,CAAC;IAChD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CACb,4BAA4B,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CACrF,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,OAAe,EACf,eAAuB,EACvB,SAAiB;IAEjB,MAAM,IAAI,GAAG,iBAAiB,EAAE,CAAC;IAEjC,IAAI,CAAC;QACH,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,gBAAgB,CAAC,OAAO,EAAE,eAAe,EAAE,SAAS,CAAC,CAAC;QACpF,OAAO,IAAI,CAAC,KAAK,CAAC,UAAU,CAAqB,CAAC;IACpD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO;YACL,KAAK,EAAE,KAAK;YACZ,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;SAC9D,CAAC;IACJ,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @auths-dev/verifier - Attestation verification for TypeScript/JavaScript
|
|
3
|
+
*
|
|
4
|
+
* This package provides WASM-powered cryptographic verification of Auths attestations.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```typescript
|
|
8
|
+
* import { init, verifyAttestation, verifyChain } from '@auths-dev/verifier';
|
|
9
|
+
*
|
|
10
|
+
* // Initialize the WASM module (required before verification)
|
|
11
|
+
* await init();
|
|
12
|
+
*
|
|
13
|
+
* // Verify a single attestation
|
|
14
|
+
* const result = verifyAttestation(attestationJson, issuerPublicKeyHex);
|
|
15
|
+
* if (!result.valid) {
|
|
16
|
+
* console.error('Verification failed:', result.error);
|
|
17
|
+
* }
|
|
18
|
+
*
|
|
19
|
+
* // Verify a chain of attestations
|
|
20
|
+
* const report = verifyChain(attestationsArray, rootPublicKeyHex);
|
|
21
|
+
* if (report.status.type !== 'Valid') {
|
|
22
|
+
* console.error('Chain verification failed:', report.status);
|
|
23
|
+
* }
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
export * from './types';
|
|
27
|
+
import type { VerificationResult, VerificationReport, KeriKeyState, DeviceLinkResult } from './types';
|
|
28
|
+
/**
|
|
29
|
+
* Initialize the WASM module. Must be called before any verification functions.
|
|
30
|
+
*
|
|
31
|
+
* @throws Error if WASM initialization fails
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* ```typescript
|
|
35
|
+
* await init();
|
|
36
|
+
* // Now verification functions can be used
|
|
37
|
+
* ```
|
|
38
|
+
*/
|
|
39
|
+
export declare function init(): Promise<void>;
|
|
40
|
+
/**
|
|
41
|
+
* Check if the WASM module is initialized
|
|
42
|
+
*/
|
|
43
|
+
export declare function isInitialized(): boolean;
|
|
44
|
+
/**
|
|
45
|
+
* Verify a single attestation against an issuer's public key.
|
|
46
|
+
*
|
|
47
|
+
* @param attestationJson - The attestation as a JSON string
|
|
48
|
+
* @param issuerPublicKeyHex - The issuer's Ed25519 public key in hex format (64 characters)
|
|
49
|
+
* @returns VerificationResult with valid flag and optional error
|
|
50
|
+
*
|
|
51
|
+
* @example
|
|
52
|
+
* ```typescript
|
|
53
|
+
* const result = verifyAttestation(
|
|
54
|
+
* JSON.stringify(attestation),
|
|
55
|
+
* 'a1b2c3d4...' // 64 hex characters
|
|
56
|
+
* );
|
|
57
|
+
*
|
|
58
|
+
* if (result.valid) {
|
|
59
|
+
* console.log('Attestation is valid!');
|
|
60
|
+
* } else {
|
|
61
|
+
* console.error('Invalid:', result.error);
|
|
62
|
+
* }
|
|
63
|
+
* ```
|
|
64
|
+
*/
|
|
65
|
+
export declare function verifyAttestation(attestationJson: string, issuerPublicKeyHex: string): Promise<VerificationResult>;
|
|
66
|
+
/**
|
|
67
|
+
* Verify a single attestation, throwing on failure.
|
|
68
|
+
*
|
|
69
|
+
* @param attestationJson - The attestation as a JSON string
|
|
70
|
+
* @param issuerPublicKeyHex - The issuer's Ed25519 public key in hex format
|
|
71
|
+
* @throws Error if verification fails
|
|
72
|
+
*
|
|
73
|
+
* @example
|
|
74
|
+
* ```typescript
|
|
75
|
+
* try {
|
|
76
|
+
* verifyAttestationOrThrow(attestationJson, issuerPk);
|
|
77
|
+
* console.log('Valid!');
|
|
78
|
+
* } catch (error) {
|
|
79
|
+
* console.error('Invalid:', error.message);
|
|
80
|
+
* }
|
|
81
|
+
* ```
|
|
82
|
+
*/
|
|
83
|
+
export declare function verifyAttestationOrThrow(attestationJson: string, issuerPublicKeyHex: string): Promise<void>;
|
|
84
|
+
/**
|
|
85
|
+
* Verify a chain of attestations from a root identity to a leaf device.
|
|
86
|
+
*
|
|
87
|
+
* @param attestations - Array of attestations (as JSON strings or objects)
|
|
88
|
+
* @param rootPublicKeyHex - The root identity's Ed25519 public key in hex format
|
|
89
|
+
* @returns VerificationReport with status, chain details, and warnings
|
|
90
|
+
*
|
|
91
|
+
* @example
|
|
92
|
+
* ```typescript
|
|
93
|
+
* const report = verifyChain(
|
|
94
|
+
* [rootToIdentityAtt, identityToDeviceAtt],
|
|
95
|
+
* rootPublicKeyHex
|
|
96
|
+
* );
|
|
97
|
+
*
|
|
98
|
+
* if (report.status.type === 'Valid') {
|
|
99
|
+
* console.log('Chain verified!');
|
|
100
|
+
* } else {
|
|
101
|
+
* console.error('Chain invalid:', report.status);
|
|
102
|
+
* }
|
|
103
|
+
*
|
|
104
|
+
* // Check individual links
|
|
105
|
+
* report.chain.forEach((link, i) => {
|
|
106
|
+
* console.log(`Link ${i}: ${link.valid ? 'OK' : link.error}`);
|
|
107
|
+
* });
|
|
108
|
+
* ```
|
|
109
|
+
*/
|
|
110
|
+
export declare function verifyChain(attestations: (string | object)[], rootPublicKeyHex: string): Promise<VerificationReport>;
|
|
111
|
+
/**
|
|
112
|
+
* Helper to check if a verification report indicates success
|
|
113
|
+
*
|
|
114
|
+
* @param report - The verification report to check
|
|
115
|
+
* @returns true if the status is Valid
|
|
116
|
+
*/
|
|
117
|
+
export declare function isVerificationValid(report: VerificationReport): boolean;
|
|
118
|
+
/**
|
|
119
|
+
* Verify a KERI Key Event Log and return the resulting key state.
|
|
120
|
+
*
|
|
121
|
+
* @param kelJson - JSON array of KEL events (inception, rotation, interaction)
|
|
122
|
+
* @returns KeriKeyState with the current public key and sequence number
|
|
123
|
+
* @throws Error if KEL parsing or verification fails
|
|
124
|
+
*
|
|
125
|
+
* @example
|
|
126
|
+
* ```typescript
|
|
127
|
+
* const keyState = await verifyKel(kelEventsJson);
|
|
128
|
+
* console.log('Current key:', keyState.current_key_encoded);
|
|
129
|
+
* console.log('Sequence:', keyState.sequence);
|
|
130
|
+
* ```
|
|
131
|
+
*/
|
|
132
|
+
export declare function verifyKel(kelJson: string): Promise<KeriKeyState>;
|
|
133
|
+
/**
|
|
134
|
+
* Verify that a device is cryptographically linked to a KERI identity.
|
|
135
|
+
*
|
|
136
|
+
* Composes KEL verification, attestation signature verification, device DID matching,
|
|
137
|
+
* and seal anchoring. Returns a result object — never throws for verification failures.
|
|
138
|
+
*
|
|
139
|
+
* @param kelJson - JSON array of KEL events for the identity
|
|
140
|
+
* @param attestationJson - JSON attestation linking the identity to the device
|
|
141
|
+
* @param deviceDid - Expected device DID string (e.g. "did:key:z6Mk...")
|
|
142
|
+
* @returns DeviceLinkResult with valid flag, optional key state, and seal info
|
|
143
|
+
*
|
|
144
|
+
* @example
|
|
145
|
+
* ```typescript
|
|
146
|
+
* const result = await verifyDeviceLink(kelJson, attestationJson, 'did:key:z6Mk...');
|
|
147
|
+
* if (result.valid) {
|
|
148
|
+
* console.log('Device verified! Identity key:', result.key_state?.current_key_encoded);
|
|
149
|
+
* if (result.seal_sequence !== undefined) {
|
|
150
|
+
* console.log('Attestation anchored at KEL sequence:', result.seal_sequence);
|
|
151
|
+
* }
|
|
152
|
+
* } else {
|
|
153
|
+
* console.error('Verification failed:', result.error);
|
|
154
|
+
* }
|
|
155
|
+
* ```
|
|
156
|
+
*/
|
|
157
|
+
export declare function verifyDeviceLink(kelJson: string, attestationJson: string, deviceDid: string): Promise<DeviceLinkResult>;
|
|
158
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,cAAc,SAAS,CAAC;AAaxB,OAAO,KAAK,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAEtG;;;;;;;;;;GAUG;AACH,wBAAsB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAW1C;AAED;;GAEG;AACH,wBAAgB,aAAa,IAAI,OAAO,CAEvC;AAWD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAsB,iBAAiB,CACrC,eAAe,EAAE,MAAM,EACvB,kBAAkB,EAAE,MAAM,GACzB,OAAO,CAAC,kBAAkB,CAAC,CAY7B;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,wBAAwB,CAC5C,eAAe,EAAE,MAAM,EACvB,kBAAkB,EAAE,MAAM,GACzB,OAAO,CAAC,IAAI,CAAC,CAUf;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAsB,WAAW,CAC/B,YAAY,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,EACjC,gBAAgB,EAAE,MAAM,GACvB,OAAO,CAAC,kBAAkB,CAAC,CAoB7B;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,kBAAkB,GAAG,OAAO,CAEvE;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAWtE;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAsB,gBAAgB,CACpC,OAAO,EAAE,MAAM,EACf,eAAe,EAAE,MAAM,EACvB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,gBAAgB,CAAC,CAY3B"}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Result of a single attestation verification
|
|
3
|
+
*/
|
|
4
|
+
export interface VerificationResult {
|
|
5
|
+
/** Whether the attestation is valid */
|
|
6
|
+
valid: boolean;
|
|
7
|
+
/** Error message if verification failed */
|
|
8
|
+
error?: string;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Status of a verification operation
|
|
12
|
+
*/
|
|
13
|
+
export type VerificationStatus = {
|
|
14
|
+
type: "Valid";
|
|
15
|
+
} | {
|
|
16
|
+
type: "Expired";
|
|
17
|
+
at: string;
|
|
18
|
+
} | {
|
|
19
|
+
type: "Revoked";
|
|
20
|
+
at?: string | null;
|
|
21
|
+
} | {
|
|
22
|
+
type: "InvalidSignature";
|
|
23
|
+
step: number;
|
|
24
|
+
} | {
|
|
25
|
+
type: "BrokenChain";
|
|
26
|
+
missing_link: string;
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* Represents a single link in the attestation chain
|
|
30
|
+
*/
|
|
31
|
+
export interface ChainLink {
|
|
32
|
+
/** Issuer DID */
|
|
33
|
+
issuer: string;
|
|
34
|
+
/** Subject DID */
|
|
35
|
+
subject: string;
|
|
36
|
+
/** Whether this link verified successfully */
|
|
37
|
+
valid: boolean;
|
|
38
|
+
/** Error message if verification failed */
|
|
39
|
+
error?: string | null;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Complete verification report for chain verification
|
|
43
|
+
*/
|
|
44
|
+
export interface VerificationReport {
|
|
45
|
+
/** Overall status of the verification */
|
|
46
|
+
status: VerificationStatus;
|
|
47
|
+
/** Details of each link in the chain */
|
|
48
|
+
chain: ChainLink[];
|
|
49
|
+
/** Warnings (non-fatal issues) */
|
|
50
|
+
warnings: string[];
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Attestation structure (for reference)
|
|
54
|
+
*/
|
|
55
|
+
export interface Attestation {
|
|
56
|
+
version: number;
|
|
57
|
+
rid: string;
|
|
58
|
+
issuer: string;
|
|
59
|
+
subject: string;
|
|
60
|
+
device_public_key: string;
|
|
61
|
+
identity_signature: string;
|
|
62
|
+
device_signature: string;
|
|
63
|
+
revoked: boolean;
|
|
64
|
+
expires_at?: string | null;
|
|
65
|
+
timestamp?: string | null;
|
|
66
|
+
note?: string | null;
|
|
67
|
+
payload?: unknown;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* KERI key state after replaying a Key Event Log.
|
|
71
|
+
* Returned by verifyKel() on successful KEL verification.
|
|
72
|
+
*/
|
|
73
|
+
export interface KeriKeyState {
|
|
74
|
+
/** The KERI prefix (self-addressing identifier) */
|
|
75
|
+
prefix: string;
|
|
76
|
+
/** Current public key in KERI encoding (e.g. "D..." base64url) */
|
|
77
|
+
current_key_encoded: string;
|
|
78
|
+
/** Next-key commitment hash, null if identity is abandoned */
|
|
79
|
+
next_commitment: string | null;
|
|
80
|
+
/** Current sequence number in the KEL */
|
|
81
|
+
sequence: number;
|
|
82
|
+
/** Whether the identity has been abandoned (no next-key commitment) */
|
|
83
|
+
is_abandoned: boolean;
|
|
84
|
+
/** SAID of the last processed event */
|
|
85
|
+
last_event_said: string;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Result of verifying a device's link to a KERI identity.
|
|
89
|
+
* Verification failures are expressed as valid=false with an error message,
|
|
90
|
+
* never as thrown exceptions.
|
|
91
|
+
*/
|
|
92
|
+
export interface DeviceLinkResult {
|
|
93
|
+
/** Whether the device link verified successfully */
|
|
94
|
+
valid: boolean;
|
|
95
|
+
/** Human-readable error if verification failed */
|
|
96
|
+
error?: string;
|
|
97
|
+
/** KERI key state after KEL replay (present on success) */
|
|
98
|
+
key_state?: KeriKeyState;
|
|
99
|
+
/** Sequence number of the IXN event anchoring the attestation seal (if found) */
|
|
100
|
+
seal_sequence?: number;
|
|
101
|
+
}
|
|
102
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,uCAAuC;IACvC,KAAK,EAAE,OAAO,CAAC;IACf,2CAA2C;IAC3C,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,MAAM,kBAAkB,GAC1B;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,GACjB;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,GAC/B;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,GACvC;IAAE,IAAI,EAAE,kBAAkB,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC1C;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,CAAC;AAElD;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,iBAAiB;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,kBAAkB;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,8CAA8C;IAC9C,KAAK,EAAE,OAAO,CAAC;IACf,2CAA2C;IAC3C,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,yCAAyC;IACzC,MAAM,EAAE,kBAAkB,CAAC;IAC3B,wCAAwC;IACxC,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,kCAAkC;IAClC,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,gBAAgB,EAAE,MAAM,CAAC;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B,mDAAmD;IACnD,MAAM,EAAE,MAAM,CAAC;IACf,kEAAkE;IAClE,mBAAmB,EAAE,MAAM,CAAC;IAC5B,8DAA8D;IAC9D,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,yCAAyC;IACzC,QAAQ,EAAE,MAAM,CAAC;IACjB,uEAAuE;IACvE,YAAY,EAAE,OAAO,CAAC;IACtB,uCAAuC;IACvC,eAAe,EAAE,MAAM,CAAC;CACzB;AAED;;;;GAIG;AACH,MAAM,WAAW,gBAAgB;IAC/B,oDAAoD;IACpD,KAAK,EAAE,OAAO,CAAC;IACf,kDAAkD;IAClD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,2DAA2D;IAC3D,SAAS,CAAC,EAAE,YAAY,CAAC;IACzB,iFAAiF;IACjF,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB"}
|
package/package.json
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@auths-dev/verifier",
|
|
3
|
+
"version": "0.1.1",
|
|
4
|
+
"description": "Auths attestation verification library for TypeScript/JavaScript",
|
|
5
|
+
"main": "dist/cjs/index.js",
|
|
6
|
+
"module": "dist/esm/index.js",
|
|
7
|
+
"types": "dist/types/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"import": "./dist/esm/index.js",
|
|
11
|
+
"require": "./dist/cjs/index.js",
|
|
12
|
+
"types": "./dist/types/index.d.ts"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"dist",
|
|
17
|
+
"wasm"
|
|
18
|
+
],
|
|
19
|
+
"scripts": {
|
|
20
|
+
"build": "npm run build:wasm && npm run build:ts",
|
|
21
|
+
"build:wasm": "cd ../../crates/auths-verifier && wasm-pack build --target bundler --no-default-features --features wasm && cp -r pkg/ ../../packages/auths-verifier-ts/wasm",
|
|
22
|
+
"build:ts": "tsc -p tsconfig.esm.json && tsc -p tsconfig.cjs.json && cp -r wasm dist/wasm",
|
|
23
|
+
"test": "jest",
|
|
24
|
+
"clean": "rm -rf dist wasm",
|
|
25
|
+
"prepublishOnly": "npm run build"
|
|
26
|
+
},
|
|
27
|
+
"keywords": [
|
|
28
|
+
"auths",
|
|
29
|
+
"attestation",
|
|
30
|
+
"verification",
|
|
31
|
+
"cryptography",
|
|
32
|
+
"wasm"
|
|
33
|
+
],
|
|
34
|
+
"author": "auths",
|
|
35
|
+
"license": "MIT",
|
|
36
|
+
"repository": {
|
|
37
|
+
"type": "git",
|
|
38
|
+
"url": "https://github.com/auths-dev/auths.git",
|
|
39
|
+
"directory": "packages/auths-verifier-ts"
|
|
40
|
+
},
|
|
41
|
+
"devDependencies": {
|
|
42
|
+
"@types/jest": "^29.5.11",
|
|
43
|
+
"@types/node": "^20.10.0",
|
|
44
|
+
"jest": "^29.7.0",
|
|
45
|
+
"ts-jest": "^29.1.1",
|
|
46
|
+
"typescript": "^5.3.2"
|
|
47
|
+
},
|
|
48
|
+
"peerDependencies": {},
|
|
49
|
+
"engines": {
|
|
50
|
+
"node": ">=18.0.0"
|
|
51
|
+
}
|
|
52
|
+
}
|