@blink-authority-com/claude-code-plugin 1.0.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.
Files changed (135) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +146 -0
  3. package/dist/bsec-client.d.ts +35 -0
  4. package/dist/bsec-client.d.ts.map +1 -0
  5. package/dist/bsec-client.js +122 -0
  6. package/dist/bsec-client.js.map +1 -0
  7. package/dist/docs/cache.d.ts +19 -0
  8. package/dist/docs/cache.d.ts.map +1 -0
  9. package/dist/docs/cache.js +92 -0
  10. package/dist/docs/cache.js.map +1 -0
  11. package/dist/docs/fetcher.d.ts +19 -0
  12. package/dist/docs/fetcher.d.ts.map +1 -0
  13. package/dist/docs/fetcher.js +81 -0
  14. package/dist/docs/fetcher.js.map +1 -0
  15. package/dist/docs/parser.d.ts +33 -0
  16. package/dist/docs/parser.d.ts.map +1 -0
  17. package/dist/docs/parser.js +145 -0
  18. package/dist/docs/parser.js.map +1 -0
  19. package/dist/docs/search.d.ts +38 -0
  20. package/dist/docs/search.d.ts.map +1 -0
  21. package/dist/docs/search.js +180 -0
  22. package/dist/docs/search.js.map +1 -0
  23. package/dist/docs/tools/api.d.ts +12 -0
  24. package/dist/docs/tools/api.d.ts.map +1 -0
  25. package/dist/docs/tools/api.js +58 -0
  26. package/dist/docs/tools/api.js.map +1 -0
  27. package/dist/docs/tools/cli.d.ts +12 -0
  28. package/dist/docs/tools/cli.d.ts.map +1 -0
  29. package/dist/docs/tools/cli.js +56 -0
  30. package/dist/docs/tools/cli.js.map +1 -0
  31. package/dist/docs/tools/concepts.d.ts +18 -0
  32. package/dist/docs/tools/concepts.d.ts.map +1 -0
  33. package/dist/docs/tools/concepts.js +136 -0
  34. package/dist/docs/tools/concepts.js.map +1 -0
  35. package/dist/docs/tools/sdk.d.ts +12 -0
  36. package/dist/docs/tools/sdk.d.ts.map +1 -0
  37. package/dist/docs/tools/sdk.js +72 -0
  38. package/dist/docs/tools/sdk.js.map +1 -0
  39. package/dist/docs/tools/search.d.ts +11 -0
  40. package/dist/docs/tools/search.d.ts.map +1 -0
  41. package/dist/docs/tools/search.js +36 -0
  42. package/dist/docs/tools/search.js.map +1 -0
  43. package/dist/docs/types.d.ts +70 -0
  44. package/dist/docs/types.d.ts.map +1 -0
  45. package/dist/docs/types.js +8 -0
  46. package/dist/docs/types.js.map +1 -0
  47. package/dist/index.d.ts +9 -0
  48. package/dist/index.d.ts.map +1 -0
  49. package/dist/index.js +622 -0
  50. package/dist/index.js.map +1 -0
  51. package/dist/prompts/debug.d.ts +16 -0
  52. package/dist/prompts/debug.d.ts.map +1 -0
  53. package/dist/prompts/debug.js +34 -0
  54. package/dist/prompts/debug.js.map +1 -0
  55. package/dist/prompts/integrate.d.ts +16 -0
  56. package/dist/prompts/integrate.d.ts.map +1 -0
  57. package/dist/prompts/integrate.js +30 -0
  58. package/dist/prompts/integrate.js.map +1 -0
  59. package/dist/prompts/review.d.ts +16 -0
  60. package/dist/prompts/review.d.ts.map +1 -0
  61. package/dist/prompts/review.js +28 -0
  62. package/dist/prompts/review.js.map +1 -0
  63. package/dist/resources/changelog.d.ts +22 -0
  64. package/dist/resources/changelog.d.ts.map +1 -0
  65. package/dist/resources/changelog.js +55 -0
  66. package/dist/resources/changelog.js.map +1 -0
  67. package/dist/resources/errors.d.ts +16 -0
  68. package/dist/resources/errors.d.ts.map +1 -0
  69. package/dist/resources/errors.js +103 -0
  70. package/dist/resources/errors.js.map +1 -0
  71. package/dist/resources/patterns.d.ts +16 -0
  72. package/dist/resources/patterns.d.ts.map +1 -0
  73. package/dist/resources/patterns.js +151 -0
  74. package/dist/resources/patterns.js.map +1 -0
  75. package/dist/templates/approval-workflow.d.ts +6 -0
  76. package/dist/templates/approval-workflow.d.ts.map +1 -0
  77. package/dist/templates/approval-workflow.js +467 -0
  78. package/dist/templates/approval-workflow.js.map +1 -0
  79. package/dist/templates/audit-trail.d.ts +6 -0
  80. package/dist/templates/audit-trail.d.ts.map +1 -0
  81. package/dist/templates/audit-trail.js +396 -0
  82. package/dist/templates/audit-trail.js.map +1 -0
  83. package/dist/templates/cli-tool.d.ts +6 -0
  84. package/dist/templates/cli-tool.d.ts.map +1 -0
  85. package/dist/templates/cli-tool.js +346 -0
  86. package/dist/templates/cli-tool.js.map +1 -0
  87. package/dist/templates/express-api.d.ts +6 -0
  88. package/dist/templates/express-api.d.ts.map +1 -0
  89. package/dist/templates/express-api.js +314 -0
  90. package/dist/templates/express-api.js.map +1 -0
  91. package/dist/templates/notary.d.ts +6 -0
  92. package/dist/templates/notary.d.ts.map +1 -0
  93. package/dist/templates/notary.js +360 -0
  94. package/dist/templates/notary.js.map +1 -0
  95. package/dist/test.d.ts +8 -0
  96. package/dist/test.d.ts.map +1 -0
  97. package/dist/test.js +140 -0
  98. package/dist/test.js.map +1 -0
  99. package/dist/tools/add-signing.d.ts +19 -0
  100. package/dist/tools/add-signing.d.ts.map +1 -0
  101. package/dist/tools/add-signing.js +317 -0
  102. package/dist/tools/add-signing.js.map +1 -0
  103. package/dist/tools/decode.d.ts +13 -0
  104. package/dist/tools/decode.d.ts.map +1 -0
  105. package/dist/tools/decode.js +262 -0
  106. package/dist/tools/decode.js.map +1 -0
  107. package/dist/tools/hierarchy.d.ts +13 -0
  108. package/dist/tools/hierarchy.d.ts.map +1 -0
  109. package/dist/tools/hierarchy.js +319 -0
  110. package/dist/tools/hierarchy.js.map +1 -0
  111. package/dist/tools/lint.d.ts +13 -0
  112. package/dist/tools/lint.d.ts.map +1 -0
  113. package/dist/tools/lint.js +323 -0
  114. package/dist/tools/lint.js.map +1 -0
  115. package/dist/tools/scaffold.d.ts +11 -0
  116. package/dist/tools/scaffold.d.ts.map +1 -0
  117. package/dist/tools/scaffold.js +84 -0
  118. package/dist/tools/scaffold.js.map +1 -0
  119. package/dist/tools/sign-test.d.ts +17 -0
  120. package/dist/tools/sign-test.d.ts.map +1 -0
  121. package/dist/tools/sign-test.js +126 -0
  122. package/dist/tools/sign-test.js.map +1 -0
  123. package/dist/tools/test-vectors.d.ts +13 -0
  124. package/dist/tools/test-vectors.d.ts.map +1 -0
  125. package/dist/tools/test-vectors.js +169 -0
  126. package/dist/tools/test-vectors.js.map +1 -0
  127. package/dist/tools/verify-local.d.ts +17 -0
  128. package/dist/tools/verify-local.d.ts.map +1 -0
  129. package/dist/tools/verify-local.js +233 -0
  130. package/dist/tools/verify-local.js.map +1 -0
  131. package/dist/tools/verify-test.d.ts +17 -0
  132. package/dist/tools/verify-test.d.ts.map +1 -0
  133. package/dist/tools/verify-test.js +107 -0
  134. package/dist/tools/verify-test.js.map +1 -0
  135. package/package.json +54 -0
@@ -0,0 +1,346 @@
1
+ /**
2
+ * CLI tool scaffold template.
3
+ * Generates a Commander.js CLI with sign/verify/inspect commands.
4
+ */
5
+ export function generateCliTool(name, features) {
6
+ const hasMultiAlgo = features.includes('multi-algorithm') || features.includes('post-quantum');
7
+ const files = {};
8
+ // --- package.json ---
9
+ files['package.json'] = JSON.stringify({
10
+ name,
11
+ version: '0.1.0',
12
+ description: `${name} — CLI tool with BLINK Authority signing`,
13
+ type: 'module',
14
+ bin: { [name]: 'dist/cli.js' },
15
+ scripts: {
16
+ build: 'tsc',
17
+ start: 'node dist/cli.js',
18
+ dev: 'tsx src/cli.ts',
19
+ },
20
+ dependencies: {
21
+ '@blink-technology/sdk': '^0.14.0',
22
+ commander: '^12.1.0',
23
+ dotenv: '^16.4.0',
24
+ },
25
+ devDependencies: {
26
+ '@types/node': '^22.15.2',
27
+ typescript: '^5.8.3',
28
+ tsx: '^4.19.0',
29
+ },
30
+ }, null, 2);
31
+ // --- tsconfig.json ---
32
+ files['tsconfig.json'] = JSON.stringify({
33
+ compilerOptions: {
34
+ target: 'ES2022',
35
+ module: 'Node16',
36
+ moduleResolution: 'Node16',
37
+ outDir: 'dist',
38
+ rootDir: 'src',
39
+ strict: true,
40
+ esModuleInterop: true,
41
+ skipLibCheck: true,
42
+ forceConsistentCasingInFileNames: true,
43
+ declaration: true,
44
+ sourceMap: true,
45
+ },
46
+ include: ['src/**/*'],
47
+ exclude: ['node_modules', 'dist'],
48
+ }, null, 2);
49
+ // --- src/blink.ts ---
50
+ files['src/blink.ts'] = `/**
51
+ * BLINK Secure Engine connection management for CLI usage.
52
+ *
53
+ * BLINK Authority — https://blink-authority.com
54
+ */
55
+
56
+ import { BlinkSigner, BlinkVerifier, AlgoSuiteId } from '@blink-technology/sdk';
57
+
58
+ ${hasMultiAlgo ? `const ALGO_MAP: Record<string, AlgoSuiteId> = {
59
+ standard: AlgoSuiteId.Ed25519,
60
+ 'post-quantum': AlgoSuiteId.MlDsa44,
61
+ };
62
+
63
+ ` : ''}/**
64
+ * Create a signer connected to BSEC.
65
+ */
66
+ export async function createSigner(
67
+ bsecUrl: string,
68
+ slotName: string,${hasMultiAlgo ? `\n algorithm?: string,` : ''}
69
+ ): Promise<BlinkSigner> {
70
+ ${hasMultiAlgo
71
+ ? ` const algoSuiteId = ALGO_MAP[algorithm ?? 'standard'] ?? AlgoSuiteId.Ed25519;
72
+ return BlinkSigner.connect(bsecUrl, slotName, algoSuiteId);`
73
+ : ` return BlinkSigner.connect(bsecUrl, slotName, AlgoSuiteId.Ed25519);`}
74
+ }
75
+
76
+ /**
77
+ * Create a verifier from a hex-encoded public key.
78
+ */
79
+ export function createVerifier(publicKeyHex: string): BlinkVerifier {
80
+ const keyBytes = Buffer.from(publicKeyHex, 'hex');
81
+ return new BlinkVerifier(new Uint8Array(keyBytes), {
82
+ freshnessWindowMs: 10 * 365.25 * 24 * 60 * 60 * 1000, // 10 years
83
+ clockSkewToleranceMs: 60_000,
84
+ });
85
+ }
86
+ `;
87
+ // --- src/cli.ts ---
88
+ files['src/cli.ts'] = `#!/usr/bin/env node
89
+
90
+ /**
91
+ * ${name} — CLI tool with BLINK Authority signing.
92
+ *
93
+ * Commands:
94
+ * sign — Sign a file or stdin
95
+ * verify — Verify a BLINK envelope
96
+ * inspect — Decode and display envelope contents
97
+ */
98
+
99
+ import 'dotenv/config';
100
+ import { Command } from 'commander';
101
+ import { signCommand } from './commands/sign.js';
102
+ import { verifyCommand } from './commands/verify.js';
103
+ import { inspectCommand } from './commands/inspect.js';
104
+
105
+ const program = new Command();
106
+
107
+ program
108
+ .name('${name}')
109
+ .description('CLI tool with BLINK Authority signing')
110
+ .version('0.1.0');
111
+
112
+ // --- sign ---
113
+ program
114
+ .command('sign')
115
+ .description('Sign a file or stdin with BLINK')
116
+ .requiredOption('-f, --file <path>', 'File to sign (use - for stdin)')
117
+ .option('--bsec-url <url>', 'BSEC endpoint', process.env['BSEC_URL'] ?? 'http://localhost:9100')
118
+ .option('--slot <name>', 'BSEC slot name', process.env['SLOT_NAME'] ?? 'default')
119
+ .option('-o, --output <path>', 'Output path for signed envelope (default: <file>.blink)')
120
+ .action(async (opts) => {
121
+ try {
122
+ await signCommand({
123
+ file: opts.file,
124
+ bsecUrl: opts.bsecUrl,
125
+ slot: opts.slot,
126
+ output: opts.output,
127
+ });
128
+ } catch (err) {
129
+ console.error('Error:', err instanceof Error ? err.message : err);
130
+ process.exit(1);
131
+ }
132
+ });
133
+
134
+ // --- verify ---
135
+ program
136
+ .command('verify')
137
+ .description('Verify a BLINK-signed envelope')
138
+ .requiredOption('-f, --file <path>', 'Original file')
139
+ .requiredOption('-e, --envelope <path>', 'Envelope file (.blink)')
140
+ .requiredOption('-k, --public-key <hex>', 'VRF public key (hex)')
141
+ .action(async (opts) => {
142
+ try {
143
+ await verifyCommand({
144
+ file: opts.file,
145
+ envelope: opts.envelope,
146
+ publicKey: opts.publicKey,
147
+ });
148
+ } catch (err) {
149
+ console.error('Error:', err instanceof Error ? err.message : err);
150
+ process.exit(1);
151
+ }
152
+ });
153
+
154
+ // --- inspect ---
155
+ program
156
+ .command('inspect')
157
+ .description('Decode and display a BLINK envelope')
158
+ .requiredOption('-e, --envelope <path>', 'Envelope file (.blink)')
159
+ .action(async (opts) => {
160
+ try {
161
+ await inspectCommand({ envelope: opts.envelope });
162
+ } catch (err) {
163
+ console.error('Error:', err instanceof Error ? err.message : err);
164
+ process.exit(1);
165
+ }
166
+ });
167
+
168
+ program.parse();
169
+ `;
170
+ // --- src/commands/sign.ts ---
171
+ files['src/commands/sign.ts'] = `/**
172
+ * Sign command — reads a file, signs it with BLINK, outputs the envelope.
173
+ */
174
+
175
+ import { readFile, writeFile } from 'node:fs/promises';
176
+ import { createSigner } from '../blink.js';
177
+
178
+ interface SignOptions {
179
+ file: string;
180
+ bsecUrl: string;
181
+ slot: string;
182
+ output?: string;
183
+ }
184
+
185
+ export async function signCommand(opts: SignOptions): Promise<void> {
186
+ // Read the input file (or stdin)
187
+ let data: Buffer;
188
+ if (opts.file === '-') {
189
+ const chunks: Buffer[] = [];
190
+ for await (const chunk of process.stdin) {
191
+ chunks.push(chunk as Buffer);
192
+ }
193
+ data = Buffer.concat(chunks);
194
+ } else {
195
+ data = await readFile(opts.file);
196
+ }
197
+
198
+ console.error(\`[sign] Read \${data.length} bytes from \${opts.file}\`);
199
+
200
+ // Connect to BSEC and sign
201
+ const signer = await createSigner(opts.bsecUrl, opts.slot);
202
+ const vrfPublicKey = await signer.vrfPublicKey();
203
+
204
+ console.error(\`[sign] Signer public key: \${Buffer.from(vrfPublicKey).toString('hex').slice(0, 16)}...\`);
205
+
206
+ const envelopeBytes = await signer.sign(new Uint8Array(data));
207
+ const envelopeBase64 = Buffer.from(envelopeBytes).toString('base64');
208
+
209
+ // Write envelope
210
+ const outputPath = opts.output ?? (opts.file === '-' ? 'stdin.blink' : \`\${opts.file}.blink\`);
211
+
212
+ const result = {
213
+ envelope: envelopeBase64,
214
+ signerPublicKey: Buffer.from(vrfPublicKey).toString('hex'),
215
+ sourceFile: opts.file === '-' ? '(stdin)' : opts.file,
216
+ sourceSize: data.length,
217
+ signedAt: new Date().toISOString(),
218
+ };
219
+
220
+ await writeFile(outputPath, JSON.stringify(result, null, 2));
221
+ console.log(\`Signed envelope written to \${outputPath}\`);
222
+ console.log(\`Public key: \${result.signerPublicKey}\`);
223
+
224
+ // Clean up
225
+ await signer.close();
226
+ }
227
+ `;
228
+ // --- src/commands/verify.ts ---
229
+ files['src/commands/verify.ts'] = `/**
230
+ * Verify command — verify a BLINK-signed envelope against the original file.
231
+ */
232
+
233
+ import { readFile } from 'node:fs/promises';
234
+ import { createVerifier } from '../blink.js';
235
+
236
+ interface VerifyOptions {
237
+ file: string;
238
+ envelope: string;
239
+ publicKey: string;
240
+ }
241
+
242
+ export async function verifyCommand(opts: VerifyOptions): Promise<void> {
243
+ // Read original file and envelope
244
+ const fileData = await readFile(opts.file);
245
+ const envelopeJson = JSON.parse(await readFile(opts.envelope, 'utf-8'));
246
+ const envelopeBytes = new Uint8Array(Buffer.from(envelopeJson.envelope, 'base64'));
247
+
248
+ console.error(\`[verify] File: \${opts.file} (\${fileData.length} bytes)\`);
249
+ console.error(\`[verify] Envelope: \${opts.envelope}\`);
250
+
251
+ // Verify the envelope
252
+ const verifier = createVerifier(opts.publicKey);
253
+ const result = verifier.verify(envelopeBytes);
254
+
255
+ if (result.valid) {
256
+ console.log('VALID: Signature verification passed');
257
+ console.log(\` Algorithm: \${result.algorithm ?? 'unknown'}\`);
258
+ console.log(\` Signed at: \${result.timestamp ?? 'unknown'}\`);
259
+ process.exit(0);
260
+ } else {
261
+ console.error('INVALID: Signature verification failed');
262
+ console.error(\` Reason: \${result.reason ?? 'unknown'}\`);
263
+ process.exit(1);
264
+ }
265
+ }
266
+ `;
267
+ // --- src/commands/inspect.ts ---
268
+ files['src/commands/inspect.ts'] = `/**
269
+ * Inspect command — decode and display the contents of a BLINK envelope.
270
+ */
271
+
272
+ import { readFile } from 'node:fs/promises';
273
+
274
+ interface InspectOptions {
275
+ envelope: string;
276
+ }
277
+
278
+ export async function inspectCommand(opts: InspectOptions): Promise<void> {
279
+ const envelopeJson = JSON.parse(await readFile(opts.envelope, 'utf-8'));
280
+
281
+ console.log('BLINK Envelope Details');
282
+ console.log('='.repeat(50));
283
+ console.log(\`Source file: \${envelopeJson.sourceFile ?? '(unknown)'}\`);
284
+ console.log(\`Source size: \${envelopeJson.sourceSize ?? '(unknown)'} bytes\`);
285
+ console.log(\`Signed at: \${envelopeJson.signedAt ?? '(unknown)'}\`);
286
+ console.log(\`Signer public key: \${envelopeJson.signerPublicKey ?? '(unknown)'}\`);
287
+
288
+ // Decode the base64 envelope to show raw size
289
+ if (envelopeJson.envelope) {
290
+ const envelopeBytes = Buffer.from(envelopeJson.envelope, 'base64');
291
+ console.log(\`Envelope size: \${envelopeBytes.length} bytes\`);
292
+
293
+ // Try to parse the envelope structure (BLINK envelope binary format)
294
+ // Version byte + algorithm byte + fields
295
+ if (envelopeBytes.length >= 2) {
296
+ console.log(\`Envelope version: \${envelopeBytes[0]}\`);
297
+ const algoId = envelopeBytes[1];
298
+ const algoName = algoId === 1 ? 'Ed25519' : algoId === 2 ? 'ML-DSA-44' : \`unknown (\${algoId})\`;
299
+ console.log(\`Algorithm: \${algoName}\`);
300
+ }
301
+ }
302
+ }
303
+ `;
304
+ // --- README.md ---
305
+ files['README.md'] = `# ${name}
306
+
307
+ CLI tool with **BLINK Authority** signing. Sign files, verify envelopes, and inspect
308
+ signature metadata from the command line.
309
+
310
+ ## Quick Start
311
+
312
+ \`\`\`bash
313
+ npm install
314
+ npm run build
315
+ npm link # optional: install globally
316
+
317
+ # Sign a file
318
+ ${name} sign -f document.pdf --bsec-url http://localhost:9100
319
+
320
+ # Verify a signature
321
+ ${name} verify -f document.pdf -e document.pdf.blink -k <public-key-hex>
322
+
323
+ # Inspect an envelope
324
+ ${name} inspect -e document.pdf.blink
325
+ \`\`\`
326
+
327
+ ## Environment Variables
328
+
329
+ Set these in \`.env\` or as environment variables:
330
+
331
+ - \`BSEC_URL\` — BLINK Secure Engine endpoint (default: http://localhost:9100)
332
+ - \`SLOT_NAME\` — BSEC signing slot (default: "default")
333
+
334
+ ## Project Structure
335
+
336
+ - \`src/blink.ts\` — BSEC connection helpers
337
+ - \`src/cli.ts\` — Commander.js entry point
338
+ - \`src/commands/sign.ts\` — Sign a file
339
+ - \`src/commands/verify.ts\` — Verify an envelope
340
+ - \`src/commands/inspect.ts\` — Inspect envelope contents
341
+
342
+ Built with [BLINK Authority](https://blink-authority.com).
343
+ `;
344
+ return files;
345
+ }
346
+ //# sourceMappingURL=cli-tool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli-tool.js","sourceRoot":"","sources":["../../src/templates/cli-tool.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,UAAU,eAAe,CAC7B,IAAY,EACZ,QAAkB;IAElB,MAAM,YAAY,GAAG,QAAQ,CAAC,QAAQ,CAAC,iBAAiB,CAAC,IAAI,QAAQ,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC;IAE/F,MAAM,KAAK,GAA2B,EAAE,CAAC;IAEzC,uBAAuB;IACvB,KAAK,CAAC,cAAc,CAAC,GAAG,IAAI,CAAC,SAAS,CACpC;QACE,IAAI;QACJ,OAAO,EAAE,OAAO;QAChB,WAAW,EAAE,GAAG,IAAI,0CAA0C;QAC9D,IAAI,EAAE,QAAQ;QACd,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,aAAa,EAAE;QAC9B,OAAO,EAAE;YACP,KAAK,EAAE,KAAK;YACZ,KAAK,EAAE,kBAAkB;YACzB,GAAG,EAAE,gBAAgB;SACtB;QACD,YAAY,EAAE;YACZ,uBAAuB,EAAE,SAAS;YAClC,SAAS,EAAE,SAAS;YACpB,MAAM,EAAE,SAAS;SAClB;QACD,eAAe,EAAE;YACf,aAAa,EAAE,UAAU;YACzB,UAAU,EAAE,QAAQ;YACpB,GAAG,EAAE,SAAS;SACf;KACF,EACD,IAAI,EACJ,CAAC,CACF,CAAC;IAEF,wBAAwB;IACxB,KAAK,CAAC,eAAe,CAAC,GAAG,IAAI,CAAC,SAAS,CACrC;QACE,eAAe,EAAE;YACf,MAAM,EAAE,QAAQ;YAChB,MAAM,EAAE,QAAQ;YAChB,gBAAgB,EAAE,QAAQ;YAC1B,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,KAAK;YACd,MAAM,EAAE,IAAI;YACZ,eAAe,EAAE,IAAI;YACrB,YAAY,EAAE,IAAI;YAClB,gCAAgC,EAAE,IAAI;YACtC,WAAW,EAAE,IAAI;YACjB,SAAS,EAAE,IAAI;SAChB;QACD,OAAO,EAAE,CAAC,UAAU,CAAC;QACrB,OAAO,EAAE,CAAC,cAAc,EAAE,MAAM,CAAC;KAClC,EACD,IAAI,EACJ,CAAC,CACF,CAAC;IAEF,uBAAuB;IACvB,KAAK,CAAC,cAAc,CAAC,GAAG;;;;;;;;EAQxB,YAAY,CAAC,CAAC,CAAC;;;;;CAKhB,CAAC,CAAC,CAAC,EAAE;;;;;qBAKe,YAAY,CAAC,CAAC,CAAC,yBAAyB,CAAC,CAAC,CAAC,EAAE;;EAEhE,YAAY;QACV,CAAC,CAAC;8DACwD;QAC1D,CAAC,CAAC,uEAAuE;;;;;;;;;;;;;CAa5E,CAAC;IAEA,qBAAqB;IACrB,KAAK,CAAC,YAAY,CAAC,GAAG;;;KAGnB,IAAI;;;;;;;;;;;;;;;;;WAiBE,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6Dd,CAAC;IAEA,+BAA+B;IAC/B,KAAK,CAAC,sBAAsB,CAAC,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAwDjC,CAAC;IAEA,iCAAiC;IACjC,KAAK,CAAC,wBAAwB,CAAC,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAqCnC,CAAC;IAEA,kCAAkC;IAClC,KAAK,CAAC,yBAAyB,CAAC,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmCpC,CAAC;IAEA,oBAAoB;IACpB,KAAK,CAAC,WAAW,CAAC,GAAG,KAAK,IAAI;;;;;;;;;;;;;EAa9B,IAAI;;;EAGJ,IAAI;;;EAGJ,IAAI;;;;;;;;;;;;;;;;;;;CAmBL,CAAC;IAEA,OAAO,KAAK,CAAC;AACf,CAAC"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Express API scaffold template.
3
+ * Generates a complete Express app with BLINK signing middleware.
4
+ */
5
+ export declare function generateExpressApi(name: string, features: string[]): Record<string, string>;
6
+ //# sourceMappingURL=express-api.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"express-api.d.ts","sourceRoot":"","sources":["../../src/templates/express-api.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAAE,GACjB,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAsUxB"}
@@ -0,0 +1,314 @@
1
+ /**
2
+ * Express API scaffold template.
3
+ * Generates a complete Express app with BLINK signing middleware.
4
+ */
5
+ export function generateExpressApi(name, features) {
6
+ const hasHealthCheck = features.includes('health-check');
7
+ const hasGracefulShutdown = features.includes('graceful-shutdown');
8
+ const hasMultiAlgo = features.includes('multi-algorithm') || features.includes('post-quantum');
9
+ const files = {};
10
+ // --- package.json ---
11
+ files['package.json'] = JSON.stringify({
12
+ name,
13
+ version: '0.1.0',
14
+ description: `${name} — Express API with BLINK Authority signing`,
15
+ type: 'module',
16
+ scripts: {
17
+ build: 'tsc',
18
+ start: 'node dist/server.js',
19
+ dev: 'tsx src/server.ts',
20
+ },
21
+ dependencies: {
22
+ '@blink-technology/sdk': '^0.14.0',
23
+ express: '^4.21.0',
24
+ dotenv: '^16.4.0',
25
+ },
26
+ devDependencies: {
27
+ '@types/express': '^4.17.21',
28
+ '@types/node': '^22.15.2',
29
+ typescript: '^5.8.3',
30
+ tsx: '^4.19.0',
31
+ },
32
+ }, null, 2);
33
+ // --- tsconfig.json ---
34
+ files['tsconfig.json'] = JSON.stringify({
35
+ compilerOptions: {
36
+ target: 'ES2022',
37
+ module: 'Node16',
38
+ moduleResolution: 'Node16',
39
+ outDir: 'dist',
40
+ rootDir: 'src',
41
+ strict: true,
42
+ esModuleInterop: true,
43
+ skipLibCheck: true,
44
+ forceConsistentCasingInFileNames: true,
45
+ declaration: true,
46
+ sourceMap: true,
47
+ },
48
+ include: ['src/**/*'],
49
+ exclude: ['node_modules', 'dist'],
50
+ }, null, 2);
51
+ // --- .env.example ---
52
+ files['.env.example'] = `# BLINK Secure Engine connection
53
+ BSEC_URL=http://localhost:9100
54
+ BSEC_TOKEN=your-bsec-token-here
55
+ SLOT_NAME=default
56
+
57
+ # Server
58
+ PORT=3000
59
+ `;
60
+ // --- src/blink.ts ---
61
+ files['src/blink.ts'] = `/**
62
+ * BLINK Secure Engine connection management.
63
+ * Handles signer lifecycle: connect, sign, graceful shutdown.
64
+ *
65
+ * BLINK Authority — https://blink-authority.com
66
+ */
67
+
68
+ import { BlinkSigner, BlinkVerifier, AlgoSuiteId } from '@blink-technology/sdk';
69
+
70
+ let signer: BlinkSigner;
71
+ let vrfPublicKey: Uint8Array;
72
+
73
+ ${hasMultiAlgo ? `const ALGO_MAP: Record<string, AlgoSuiteId> = {
74
+ ed25519: AlgoSuiteId.Ed25519,
75
+ 'ml-dsa-44': AlgoSuiteId.MlDsa44,
76
+ };
77
+ ` : ''}
78
+ /**
79
+ * Connect to the BLINK Secure Engine.
80
+ * Must be called before any signing operations.
81
+ */
82
+ export async function initBlink(
83
+ bsecUrl: string,
84
+ slotName: string,
85
+ token?: string,${hasMultiAlgo ? `\n algorithm?: string,` : ''}
86
+ ): Promise<void> {
87
+ ${hasMultiAlgo
88
+ ? ` const algoSuiteId = ALGO_MAP[algorithm ?? 'ed25519'] ?? AlgoSuiteId.Ed25519;
89
+ signer = await BlinkSigner.connect(bsecUrl, slotName, algoSuiteId);`
90
+ : ` signer = await BlinkSigner.connect(bsecUrl, slotName, AlgoSuiteId.Ed25519);`}
91
+ vrfPublicKey = await signer.vrfPublicKey();
92
+
93
+ console.log(
94
+ \`[blink] Connected to BSEC at \${bsecUrl} \` +
95
+ \`(slot=\${slotName}, pk=\${Buffer.from(vrfPublicKey).toString('hex').slice(0, 16)}...)\`,
96
+ );
97
+ }
98
+
99
+ /** Get the active signer instance. */
100
+ export function getSigner(): BlinkSigner {
101
+ return signer;
102
+ }
103
+
104
+ /** Get the VRF public key (cached at connect time). */
105
+ export function getVrfPublicKey(): Uint8Array {
106
+ return vrfPublicKey;
107
+ }
108
+
109
+ /** Get the VRF public key as hex string. */
110
+ export function getVrfPublicKeyHex(): string {
111
+ return Buffer.from(vrfPublicKey).toString('hex');
112
+ }
113
+
114
+ /** Create a verifier using the cached VRF public key. */
115
+ export function createVerifier(): BlinkVerifier {
116
+ return new BlinkVerifier(vrfPublicKey, {
117
+ freshnessWindowMs: 365 * 24 * 60 * 60 * 1000, // 1 year
118
+ clockSkewToleranceMs: 60_000,
119
+ });
120
+ }
121
+
122
+ /** Gracefully close the BSEC connection. */
123
+ export async function shutdownBlink(): Promise<void> {
124
+ if (signer) {
125
+ await signer.close();
126
+ console.log('[blink] Disconnected from BLINK Secure Engine');
127
+ }
128
+ }
129
+ `;
130
+ // --- src/middleware/signing.ts ---
131
+ files['src/middleware/signing.ts'] = `/**
132
+ * BLINK signing middleware.
133
+ * Intercepts JSON responses and adds a BLINK signature envelope.
134
+ *
135
+ * The signature is attached as HTTP headers:
136
+ * X-BLINK-Signature: base64-encoded envelope
137
+ * X-BLINK-PublicKey: hex-encoded VRF public key
138
+ * X-BLINK-Signed: "true"
139
+ */
140
+
141
+ import { Request, Response, NextFunction } from 'express';
142
+ import { getSigner, getVrfPublicKeyHex } from '../blink.js';
143
+
144
+ export function blinkSigningMiddleware() {
145
+ return (req: Request, res: Response, next: NextFunction) => {
146
+ const originalJson = res.json.bind(res);
147
+
148
+ // Override res.json to sign the response before sending
149
+ res.json = ((body: unknown) => {
150
+ signAndSend(res, originalJson, body).catch((err) => {
151
+ console.error('[blink] Signing failed, sending unsigned:', err);
152
+ res.setHeader('X-BLINK-Signed', 'false');
153
+ originalJson(body);
154
+ });
155
+ return res;
156
+ }) as typeof res.json;
157
+
158
+ next();
159
+ };
160
+ }
161
+
162
+ async function signAndSend(
163
+ res: Response,
164
+ originalJson: (body: unknown) => Response,
165
+ body: unknown,
166
+ ): Promise<void> {
167
+ // Canonical JSON for deterministic signatures
168
+ const bodyStr = JSON.stringify(body);
169
+ const payload = new TextEncoder().encode(bodyStr);
170
+
171
+ // Sign the payload via BLINK Secure Engine
172
+ const envelopeBytes = await getSigner().sign(payload);
173
+ const envelopeBase64 = Buffer.from(envelopeBytes).toString('base64');
174
+
175
+ // Attach signature metadata as HTTP headers
176
+ res.setHeader('X-BLINK-Signature', envelopeBase64);
177
+ res.setHeader('X-BLINK-PublicKey', getVrfPublicKeyHex());
178
+ res.setHeader('X-BLINK-Signed', 'true');
179
+
180
+ originalJson(body);
181
+ }
182
+ `;
183
+ // --- src/routes/health.ts ---
184
+ files['src/routes/health.ts'] = `/**
185
+ * Health check endpoint.
186
+ * Reports server status and BLINK connection info.
187
+ */
188
+
189
+ import { Router } from 'express';
190
+ import { getVrfPublicKeyHex } from '../blink.js';
191
+
192
+ const router = Router();
193
+
194
+ router.get('/health', (_req, res) => {
195
+ res.json({
196
+ status: 'ok',
197
+ service: '${name}',
198
+ signerPublicKey: getVrfPublicKeyHex(),
199
+ timestamp: new Date().toISOString(),
200
+ });
201
+ });
202
+
203
+ export default router;
204
+ `;
205
+ // --- src/server.ts ---
206
+ files['src/server.ts'] = `/**
207
+ * ${name} — Express API with BLINK Authority signing.
208
+ *
209
+ * Every JSON response is signed with a single-use BLINK credential.
210
+ * The signing middleware attaches the signature as HTTP headers.
211
+ */
212
+
213
+ import 'dotenv/config';
214
+ import express from 'express';
215
+ import { initBlink, shutdownBlink } from './blink.js';
216
+ import { blinkSigningMiddleware } from './middleware/signing.js';
217
+ import healthRouter from './routes/health.js';
218
+
219
+ async function main(): Promise<void> {
220
+ const bsecUrl = process.env['BSEC_URL'] ?? 'http://localhost:9100';
221
+ const bsecToken = process.env['BSEC_TOKEN'];
222
+ const slotName = process.env['SLOT_NAME'] ?? 'default';
223
+ const port = parseInt(process.env['PORT'] ?? '3000', 10);
224
+
225
+ // Connect to BLINK Secure Engine
226
+ await initBlink(bsecUrl, slotName, bsecToken);
227
+
228
+ const app = express();
229
+ app.use(express.json());
230
+
231
+ // Sign all JSON responses with BLINK
232
+ app.use(blinkSigningMiddleware());
233
+
234
+ // Routes
235
+ app.use(healthRouter);
236
+
237
+ // Example API route — add your own routes here
238
+ app.get('/api/example', (_req, res) => {
239
+ res.json({ message: 'This response is BLINK-signed', timestamp: new Date().toISOString() });
240
+ });
241
+
242
+ const server = app.listen(port, () => {
243
+ console.log(\`[server] ${name} listening on port \${port}\`);
244
+ });
245
+
246
+ // Graceful shutdown — close BSEC connection on exit
247
+ const shutdown = async (signal: string) => {
248
+ console.log(\`[server] Received \${signal}, shutting down...\`);
249
+ server.close();
250
+ await shutdownBlink();
251
+ process.exit(0);
252
+ };
253
+
254
+ process.on('SIGINT', () => shutdown('SIGINT'));
255
+ process.on('SIGTERM', () => shutdown('SIGTERM'));
256
+ }
257
+
258
+ main().catch((err) => {
259
+ console.error('[server] Fatal error:', err);
260
+ process.exit(1);
261
+ });
262
+ `;
263
+ // --- README.md ---
264
+ files['README.md'] = `# ${name}
265
+
266
+ Express API with **BLINK Authority** signing. Every JSON response is cryptographically
267
+ signed using the BLINK Signing Protocol via the BLINK Secure Engine (BSEC).
268
+
269
+ ## Quick Start
270
+
271
+ \`\`\`bash
272
+ npm install
273
+ cp .env.example .env
274
+ # Edit .env with your BSEC connection details
275
+ npm run dev
276
+ \`\`\`
277
+
278
+ ## How It Works
279
+
280
+ 1. The server connects to a BLINK Secure Engine at startup
281
+ 2. The signing middleware intercepts every \`res.json()\` call
282
+ 3. Each response is signed with a single-use credential (Temporal Key Assurance)
283
+ 4. The signature envelope is attached as HTTP headers:
284
+ - \`X-BLINK-Signature\`: base64-encoded BLINK envelope
285
+ - \`X-BLINK-PublicKey\`: hex-encoded VRF public key
286
+ - \`X-BLINK-Signed\`: "true" if signed successfully
287
+
288
+ ## Verifying Responses
289
+
290
+ Clients can verify any response using the BLINK SDK:
291
+
292
+ \`\`\`typescript
293
+ import { BlinkVerifier } from '@blink-technology/sdk';
294
+
295
+ const publicKey = new Uint8Array(Buffer.from(headers['x-blink-publickey'], 'hex'));
296
+ const envelope = new Uint8Array(Buffer.from(headers['x-blink-signature'], 'base64'));
297
+
298
+ const verifier = new BlinkVerifier(publicKey, { freshnessWindowMs: 60_000 });
299
+ const result = verifier.verify(envelope);
300
+ console.log('Valid:', result.valid);
301
+ \`\`\`
302
+
303
+ ## Project Structure
304
+
305
+ - \`src/blink.ts\` — BSEC connection management
306
+ - \`src/server.ts\` — Express app entry point
307
+ - \`src/middleware/signing.ts\` — BLINK signing middleware
308
+ - \`src/routes/health.ts\` — Health check endpoint
309
+
310
+ Built with [BLINK Authority](https://blink-authority.com).
311
+ `;
312
+ return files;
313
+ }
314
+ //# sourceMappingURL=express-api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"express-api.js","sourceRoot":"","sources":["../../src/templates/express-api.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,UAAU,kBAAkB,CAChC,IAAY,EACZ,QAAkB;IAElB,MAAM,cAAc,GAAG,QAAQ,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC;IACzD,MAAM,mBAAmB,GAAG,QAAQ,CAAC,QAAQ,CAAC,mBAAmB,CAAC,CAAC;IACnE,MAAM,YAAY,GAAG,QAAQ,CAAC,QAAQ,CAAC,iBAAiB,CAAC,IAAI,QAAQ,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC;IAE/F,MAAM,KAAK,GAA2B,EAAE,CAAC;IAEzC,uBAAuB;IACvB,KAAK,CAAC,cAAc,CAAC,GAAG,IAAI,CAAC,SAAS,CACpC;QACE,IAAI;QACJ,OAAO,EAAE,OAAO;QAChB,WAAW,EAAE,GAAG,IAAI,6CAA6C;QACjE,IAAI,EAAE,QAAQ;QACd,OAAO,EAAE;YACP,KAAK,EAAE,KAAK;YACZ,KAAK,EAAE,qBAAqB;YAC5B,GAAG,EAAE,mBAAmB;SACzB;QACD,YAAY,EAAE;YACZ,uBAAuB,EAAE,SAAS;YAClC,OAAO,EAAE,SAAS;YAClB,MAAM,EAAE,SAAS;SAClB;QACD,eAAe,EAAE;YACf,gBAAgB,EAAE,UAAU;YAC5B,aAAa,EAAE,UAAU;YACzB,UAAU,EAAE,QAAQ;YACpB,GAAG,EAAE,SAAS;SACf;KACF,EACD,IAAI,EACJ,CAAC,CACF,CAAC;IAEF,wBAAwB;IACxB,KAAK,CAAC,eAAe,CAAC,GAAG,IAAI,CAAC,SAAS,CACrC;QACE,eAAe,EAAE;YACf,MAAM,EAAE,QAAQ;YAChB,MAAM,EAAE,QAAQ;YAChB,gBAAgB,EAAE,QAAQ;YAC1B,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,KAAK;YACd,MAAM,EAAE,IAAI;YACZ,eAAe,EAAE,IAAI;YACrB,YAAY,EAAE,IAAI;YAClB,gCAAgC,EAAE,IAAI;YACtC,WAAW,EAAE,IAAI;YACjB,SAAS,EAAE,IAAI;SAChB;QACD,OAAO,EAAE,CAAC,UAAU,CAAC;QACrB,OAAO,EAAE,CAAC,cAAc,EAAE,MAAM,CAAC;KAClC,EACD,IAAI,EACJ,CAAC,CACF,CAAC;IAEF,uBAAuB;IACvB,KAAK,CAAC,cAAc,CAAC,GAAG;;;;;;;CAOzB,CAAC;IAEA,uBAAuB;IACvB,KAAK,CAAC,cAAc,CAAC,GAAG;;;;;;;;;;;;EAYxB,YAAY,CAAC,CAAC,CAAC;;;;CAIhB,CAAC,CAAC,CAAC,EAAE;;;;;;;;mBAQa,YAAY,CAAC,CAAC,CAAC,yBAAyB,CAAC,CAAC,CAAC,EAAE;;EAE9D,YAAY;QACV,CAAC,CAAC;sEACgE;QAClE,CAAC,CAAC,+EAA+E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAuCpF,CAAC;IAEA,oCAAoC;IACpC,KAAK,CAAC,2BAA2B,CAAC,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmDtC,CAAC;IAEA,+BAA+B;IAC/B,KAAK,CAAC,sBAAsB,CAAC,GAAG;;;;;;;;;;;;;gBAalB,IAAI;;;;;;;CAOnB,CAAC;IAEA,wBAAwB;IACxB,KAAK,CAAC,eAAe,CAAC,GAAG;KACtB,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6BAoCoB,IAAI;;;;;;;;;;;;;;;;;;;CAmBhC,CAAC;IAEA,oBAAoB;IACpB,KAAK,CAAC,WAAW,CAAC,GAAG,KAAK,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+C/B,CAAC;IAEA,OAAO,KAAK,CAAC;AACf,CAAC"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Document notary scaffold template.
3
+ * Generates a notarization service: upload, hash, sign, verify.
4
+ */
5
+ export declare function generateNotary(name: string, features: string[]): Record<string, string>;
6
+ //# sourceMappingURL=notary.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"notary.d.ts","sourceRoot":"","sources":["../../src/templates/notary.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAAE,GACjB,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAoXxB"}