{"_id":"@cognitiveproof/didsmith-key-request-jwt","_rev":"3-46ad86f0f0076e30508231453d5a881f","name":"@cognitiveproof/didsmith-key-request-jwt","dist-tags":{"latest":"0.2.0"},"versions":{"0.1.0":{"name":"@cognitiveproof/didsmith-key-request-jwt","version":"0.1.0","keywords":["did","did-web","jwt","ed25519","verifiable-credential","didsmith"],"license":"MIT","_id":"@cognitiveproof/didsmith-key-request-jwt@0.1.0","maintainers":[{"name":"mrappard","email":"mrappard@gmail.com"}],"homepage":"https://github.com/Cognitive-Proof/didsmith#readme","bugs":{"url":"https://github.com/Cognitive-Proof/didsmith/issues"},"dist":{"shasum":"073953770f89963aeb961622f7d394761e453f84","tarball":"https://registry.npmjs.org/@cognitiveproof/didsmith-key-request-jwt/-/didsmith-key-request-jwt-0.1.0.tgz","fileCount":9,"integrity":"sha512-jWJkhVKE9GFw467lmTX65R1PlgQ/XtLeJ8UnSDR2u2oW2qtDkyFSBhlhafdiMkcs2DIMBX7nYx2YaqGdT53Mlw==","signatures":[{"sig":"MEYCIQCj4vLdjQQD/IJfBEkIIGTo0XQdU7sGRyfRPQcg5Hl1PQIhAKsjBt9BpABqvCBI300LbRy/wTHq9QKsCBkz6Xgjv7Dj","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":38027},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"}},"gitHead":"1b47ca50a0f35c90590294fc1efb6fdcc3d3b29e","scripts":{"dev":"tsup --watch","build":"tsup","typecheck":"tsc --noEmit","prepublishOnly":"npm run typecheck && npm run build"},"_npmUser":{"name":"mrappard","email":"mrappard@gmail.com"},"repository":{"url":"git+https://github.com/Cognitive-Proof/didsmith.git","type":"git","directory":"key-request-jwt"},"_npmVersion":"11.12.1","description":"Builds and signs the compact JWT-VC \"key request\" DIDsmith's key-linking flow expects, from any Ed25519 signer — a raw seed, an HSM, or @cognitiveproof/webauthn-prf-identity's signBytes. Zero dependencies, works in the browser and Node.","directories":{},"sideEffects":false,"_nodeVersion":"25.9.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.3.0","typescript":"^5.6.0","@types/node":"^22.7.0"},"_npmOperationalInternal":{"tmp":"tmp/didsmith-key-request-jwt_0.1.0_1787925596521_0.31751795934077887","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@cognitiveproof/didsmith-key-request-jwt","version":"0.1.1","keywords":["did","did-web","jwt","ed25519","verifiable-credential","didsmith"],"license":"MIT","_id":"@cognitiveproof/didsmith-key-request-jwt@0.1.1","maintainers":[{"name":"mrappard","email":"mrappard@gmail.com"}],"homepage":"https://github.com/Cognitive-Proof/didsmith#readme","bugs":{"url":"https://github.com/Cognitive-Proof/didsmith/issues"},"dist":{"shasum":"7d5345117dc6a78e168931075735d36078674370","tarball":"https://registry.npmjs.org/@cognitiveproof/didsmith-key-request-jwt/-/didsmith-key-request-jwt-0.1.1.tgz","fileCount":9,"integrity":"sha512-CtvCD8M4RsCDYmCU+IqjEo5CGJPdDzg8SJENVe+NnlCd6rEIMJDAa7KHyB+2xwFSA39O934l8nKZMR7phIzzLA==","signatures":[{"sig":"MEUCIFgUKOE0+GOR2uOGggzv240LZ4nON0IwKXp1tr2T5JLKAiEA9YJ7za7kqWce6VZbZWY9bPR6FrnoGH1hs1cFISyaNfg=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":44057},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"}},"gitHead":"e0a7eb8746b3bb336c47e730b4b242ad769dccb6","scripts":{"dev":"tsup --watch","build":"tsup","typecheck":"tsc --noEmit","prepublishOnly":"npm run typecheck && npm run build"},"_npmUser":{"name":"mrappard","email":"mrappard@gmail.com"},"repository":{"url":"git+https://github.com/Cognitive-Proof/didsmith.git","type":"git","directory":"key-request-jwt"},"_npmVersion":"11.12.1","description":"Builds and signs the compact JWT-VC \"key request\" DIDsmith's key-linking flow expects, from any Ed25519 signer — a raw seed, an HSM, or @cognitiveproof/webauthn-prf-identity's signBytes. Zero dependencies, works in the browser and Node.","directories":{},"sideEffects":false,"_nodeVersion":"25.9.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.3.0","typescript":"^5.6.0","@types/node":"^22.7.0"},"_npmOperationalInternal":{"tmp":"tmp/didsmith-key-request-jwt_0.1.1_1787940545926_0.8901200005934478","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@cognitiveproof/didsmith-key-request-jwt","version":"0.2.0","description":"Builds and signs the compact JWT-VC \"key request\" DIDsmith's key-linking flow expects, from any Ed25519 signer — a raw seed, an HSM, or @cognitiveproof/webauthn-prf-identity's signBytes. Zero dependencies, works in the browser and Node.","type":"module","main":"./dist/index.cjs","module":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"}},"sideEffects":false,"publishConfig":{"access":"public"},"repository":{"type":"git","url":"git+https://github.com/Cognitive-Proof/didsmith.git","directory":"key-request-jwt"},"scripts":{"build":"tsup","dev":"tsup --watch","typecheck":"tsc --noEmit","prepublishOnly":"npm run typecheck && npm run build"},"devDependencies":{"@types/node":"^22.7.0","tsup":"^8.3.0","typescript":"^5.6.0"},"keywords":["did","did-web","jwt","ed25519","verifiable-credential","didsmith"],"engines":{"node":">=18"},"license":"MIT","gitHead":"febf3cdee382c9ae69d21dbb355a6cba5885966c","_id":"@cognitiveproof/didsmith-key-request-jwt@0.2.0","bugs":{"url":"https://github.com/Cognitive-Proof/didsmith/issues"},"homepage":"https://github.com/Cognitive-Proof/didsmith#readme","_nodeVersion":"25.9.0","_npmVersion":"11.12.1","dist":{"integrity":"sha512-YZd/jhHmlUB35ajCqYa5pHDVIQpN++uYgPQb2W7cIPLeP8vuiyUeTdyVgiSqI0tYvUCtXrF9abBAmtmrwbcSqw==","shasum":"53a9c6307d7299f41a1437c476f6afe9fa5b9a2c","tarball":"https://registry.npmjs.org/@cognitiveproof/didsmith-key-request-jwt/-/didsmith-key-request-jwt-0.2.0.tgz","fileCount":9,"unpackedSize":55113,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQDz60FAODUqwYpTG8cMMm5w5n0I6eH6aIL2fKgndDqvFAIhAOy7NYb84dr2OnLO4AiNOPxk2XYoSP1T4ApINiXuVXkQ"}]},"_npmUser":{"name":"mrappard","email":"mrappard@gmail.com"},"directories":{},"maintainers":[{"name":"mrappard","email":"mrappard@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/didsmith-key-request-jwt_0.2.0_1787942720387_0.987012872551944"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-28T13:59:56.300Z","modified":"2026-08-28T18:45:20.707Z","0.1.0":"2026-08-28T13:59:56.670Z","0.1.1":"2026-08-28T18:09:06.085Z","0.2.0":"2026-08-28T18:45:20.518Z"},"bugs":{"url":"https://github.com/Cognitive-Proof/didsmith/issues"},"license":"MIT","homepage":"https://github.com/Cognitive-Proof/didsmith#readme","keywords":["did","did-web","jwt","ed25519","verifiable-credential","didsmith"],"repository":{"type":"git","url":"git+https://github.com/Cognitive-Proof/didsmith.git","directory":"key-request-jwt"},"description":"Builds and signs the compact JWT-VC \"key request\" DIDsmith's key-linking flow expects, from any Ed25519 signer — a raw seed, an HSM, or @cognitiveproof/webauthn-prf-identity's signBytes. Zero dependencies, works in the browser and Node.","maintainers":[{"name":"mrappard","email":"mrappard@gmail.com"}],"readme":"# @cognitiveproof/didsmith-key-request-jwt\n\nBuilds and signs the compact JWT-VC \"key request\" that\n[DIDsmith](https://didsmith.com)'s key-linking flow expects\n(`POST /api/keys/request/verify`) — the portable, signed artifact a user\ndownloads on one site and later uploads to their DIDsmith dashboard to add\nthat key to their `did:web`.\n\nZero runtime dependencies. Works in the browser and in Node. It does **not**\ndepend on [`@cognitiveproof/webauthn-prf-identity`](https://www.npmjs.com/package/@cognitiveproof/webauthn-prf-identity) —\nit just needs a public key and a function that can sign bytes with the\nmatching private key. That signer can be that package's `signBytes`\n(browser, WebAuthn-PRF-derived), a raw in-memory Ed25519 seed, an HSM,\nor anything else that produces a standard 64-byte Ed25519 signature.\n\n## Install\n\n```sh\nnpm install @cognitiveproof/didsmith-key-request-jwt\n```\n\n## Usage\n\n```ts\nimport { signKeyRequestJwt, coSignKeyRequest } from \"@cognitiveproof/didsmith-key-request-jwt\";\n\nconst keyRequestJwt = await signKeyRequestJwt({\n    publicKey, // raw 32-byte Ed25519 public key\n    sign: (bytes) => mySigner.sign(bytes), // returns a raw 64-byte signature\n    subjectDid: \"did:web:api.didsmith.com:<account's DID id>\",\n    origin: \"https://wherever-this-key-was-made.example\",\n});\n\n// download/hand off `keyRequestJwt` — it's a standard compact JWS\n// (header.payload.signature). Uploaded via the DIDsmith dashboard's\n// \"Import a key request\", where the account owner picks an existing key\n// to co-sign it:\nconst authorizationSignature = await coSignKeyRequest(existingKeySign, keyRequestJwt);\n```\n\n### With a raw Ed25519 seed (e.g. `@noble/curves`)\n\n```ts\nimport { ed25519 } from \"@noble/curves/ed25519.js\";\nimport { signKeyRequestJwt } from \"@cognitiveproof/didsmith-key-request-jwt\";\n\nconst seed = ed25519.utils.randomSecretKey();\nconst publicKey = ed25519.getPublicKey(seed);\n\nconst keyRequestJwt = await signKeyRequestJwt({\n    publicKey,\n    sign: (bytes) => ed25519.sign(bytes, seed),\n    subjectDid: \"did:web:api.didsmith.com:abc123\",\n    origin: \"https://my-service.example\",\n});\n```\n\n### With `@cognitiveproof/webauthn-prf-identity` (browser)\n\nThe two packages compose — `webauthn-prf-identity` derives the key and\nsigns; this package only shapes the JWT around whatever signature comes\nback:\n\n```ts\nimport { registerWebAuthnPrfCredential, signBytes } from \"@cognitiveproof/webauthn-prf-identity\";\nimport { signKeyRequestJwt, base64UrlDecode } from \"@cognitiveproof/didsmith-key-request-jwt\";\n\nconst config = { rpName: \"My App\", hkdfInfo: \"my-app-v1\" };\nconst registration = await registerWebAuthnPrfCredential(config, profileId, displayName);\nconst credential = { credentialId: registration.credentialId, prfSalt: registration.prfSalt };\n\nconst keyRequestJwt = await signKeyRequestJwt({\n    publicKey: base64UrlDecode(registration.publicKey), // see note below\n    sign: (bytes) => signBytes(config, credential, bytes),\n    subjectDid,\n    origin: window.location.origin,\n});\n```\n\n`registerWebAuthnPrfCredential`'s `publicKey` is base64url-encoded; decode\nit to raw bytes first with this package's own `base64UrlDecode` (this\npackage works with raw `Uint8Array` public keys throughout, not the\nencoded string).\n\n### Requesting a key you don't hold\n\nDIDsmith doesn't need to possess a key to add it — the account holder can\nbuild the request naming a key that lives entirely elsewhere, hand the\n*unsigned* half to wherever that key actually is, and complete linking\nonce it comes back signed:\n\n```ts\nimport { buildKeyRequestChallenge, parseDidJwk, jwkToPublicKey } from \"@cognitiveproof/didsmith-key-request-jwt\";\n\n// The user pastes a did:jwk they already have — e.g. from another app's\n// own WebAuthn-PRF identity, which is exactly what this and\n// @cognitiveproof/webauthn-prf-identity both produce.\nconst jwk = parseDidJwk(pastedDidJwk);\nconst challenge = buildKeyRequestChallenge({\n    publicKey: jwkToPublicKey(jwk),\n    subjectDid: \"did:web:api.didsmith.com:abc123\",\n    origin: \"wherever this key actually lives\",\n});\n\n// Show `challenge` for copying elsewhere. Whatever holds the matching\n// private key signs it directly — as UTF-8 bytes, with any Ed25519\n// signer, exactly the same operation `coSignKeyRequest` performs on a\n// full JWT. Once a signature comes back:\nconst keyRequestJwt = `${challenge}.${signatureBase64Url}`;\n// `keyRequestJwt` now verifies identically to one signKeyRequestJwt\n// would have produced directly — same two-segment JWS signing input,\n// same shape, same checks on DIDsmith's backend.\n```\n\nNote this asks for a signature over exactly `challenge` (the two-segment\n`header.payload` string) — not a longer string with a placeholder third\nsegment tacked on. That's the actual JWS signing input (RFC 7515/8037),\nand it's what makes the finished request indistinguishable from one\n`signKeyRequestJwt` produced directly, with no separate verification path\nneeded on DIDsmith's end.\n\n## API\n\n- `signKeyRequestJwt(options): Promise<string>` — `options.publicKey`\n  (`Uint8Array`, raw 32 bytes), `options.sign` (`SignFn`),\n  `options.subjectDid`, `options.origin`, optional `options.expiresInSeconds`\n  (default 900) and `options.jti` (default: random). Returns the compact\n  JWS string.\n- `base64UrlDecode(value): Uint8Array` — inverse of the internal base64url\n  encoding this package uses everywhere; handy for decoding a\n  base64url-encoded public key (e.g. `@cognitiveproof/webauthn-prf-identity`'s\n  `registration.publicKey`) back to the raw bytes these functions expect.\n- `buildKeyRequestChallenge(options): string` — same options as\n  `signKeyRequestJwt` minus `sign`; returns just the unsigned two-segment\n  `header.payload` JWS signing input, for requesting a key you don't hold\n  (see above). `signKeyRequestJwt` is built on top of this internally.\n- `coSignKeyRequest(sign, keyRequestJwt): Promise<string>` — signs the raw\n  bytes of an existing key-request JWT with a *different* key (one already\n  authorized on the target DID) and returns a base64url-encoded signature.\n- `computeDidJwk(publicKey): string` — the `did:jwk` identifier a given\n  Ed25519 public key resolves to (what ends up in the JWT's `iss`).\n- `parseDidJwk(didJwk): Ed25519Jwk` — inverse of `computeDidJwk`; decodes\n  a pasted `did:jwk:...` identifier back to the JWK it encodes.\n- `publicKeyToJwk(publicKey): Ed25519Jwk` — `{ kty: \"OKP\", crv: \"Ed25519\", x }`\n  for a raw public key.\n- `jwkToPublicKey(jwk): Uint8Array` — inverse of `publicKeyToJwk`.\n- `SignFn = (bytes: Uint8Array) => Uint8Array | Promise<Uint8Array>` — must\n  return a raw 64-byte Ed25519 signature (RFC 8032, R‖S). The returned JWT\n  is a fully spec-compliant compact JWS: that raw signature, base64url\n  encoded, is exactly what RFC 8037 EdDSA JWS signatures look like.\n\n## Development\n\n```sh\nnpm install\nnpm run build       # tsup -> dist/{index.js,index.cjs,index.d.ts}\nnpm run typecheck\n```\n","readmeFilename":"README.md"}