@solidus-network/sdk 0.1.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chain/bbs.d.ts +128 -0
- package/dist/chain/bbs.d.ts.map +1 -0
- package/dist/chain/bbs.js +142 -0
- package/dist/chain/bbs.js.map +1 -0
- package/dist/chain/credentials.js +6 -6
- package/dist/chain/credentials.js.map +1 -1
- package/dist/chain/did.d.ts +52 -0
- package/dist/chain/did.d.ts.map +1 -1
- package/dist/chain/did.js +91 -2
- package/dist/chain/did.js.map +1 -1
- package/dist/chain/index.d.ts.map +1 -1
- package/dist/chain/index.js +2 -0
- package/dist/chain/index.js.map +1 -1
- package/dist/index.d.ts +39 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -1
- package/dist/sdjwt/index.d.ts +8 -0
- package/dist/sdjwt/index.d.ts.map +1 -0
- package/dist/sdjwt/index.js +8 -0
- package/dist/sdjwt/index.js.map +1 -0
- package/dist/sdjwt/issue.d.ts +12 -0
- package/dist/sdjwt/issue.d.ts.map +1 -0
- package/dist/sdjwt/issue.js +119 -0
- package/dist/sdjwt/issue.js.map +1 -0
- package/dist/sdjwt/present.d.ts +15 -0
- package/dist/sdjwt/present.d.ts.map +1 -0
- package/dist/sdjwt/present.js +80 -0
- package/dist/sdjwt/present.js.map +1 -0
- package/dist/sdjwt/signer.d.ts +59 -0
- package/dist/sdjwt/signer.d.ts.map +1 -0
- package/dist/sdjwt/signer.js +119 -0
- package/dist/sdjwt/signer.js.map +1 -0
- package/dist/sdjwt/status-list.d.ts +61 -0
- package/dist/sdjwt/status-list.d.ts.map +1 -0
- package/dist/sdjwt/status-list.js +63 -0
- package/dist/sdjwt/status-list.js.map +1 -0
- package/dist/sdjwt/types.d.ts +181 -0
- package/dist/sdjwt/types.d.ts.map +1 -0
- package/dist/sdjwt/types.js +12 -0
- package/dist/sdjwt/types.js.map +1 -0
- package/dist/sdjwt/verify.d.ts +23 -0
- package/dist/sdjwt/verify.d.ts.map +1 -0
- package/dist/sdjwt/verify.js +201 -0
- package/dist/sdjwt/verify.js.map +1 -0
- package/dist/stub/credentials.js +3 -3
- package/dist/stub/credentials.js.map +1 -1
- package/package.json +7 -5
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
import type { DID, DIDDocument, VerifiableCredential, IssueCredentialParams, VerificationResult, AuthResult } from '@solidus-network/types';
|
|
2
|
+
import type { BbsDisclosedMessage, BbsCredentialProofResult } from './chain/bbs.js';
|
|
2
3
|
export type { DID, DIDDocument, VerifiableCredential, IssueCredentialParams, VerificationResult, AuthResult, };
|
|
3
4
|
export { runMigrations, closeConnection } from './stub/db.js';
|
|
4
5
|
export { generateKeypair, decodePublicKey } from './stub/crypto.js';
|
|
5
6
|
export type { ChainConfig } from './chain/index.js';
|
|
7
|
+
export { createChainClient } from './chain/index.js';
|
|
8
|
+
export type { BbsDisclosedMessage, BbsCredentialProofResult, BbsCredentialRecord, } from './chain/bbs.js';
|
|
9
|
+
export { utf8ToHex, toHex } from './chain/bbs.js';
|
|
10
|
+
export { issueSdJwtVc, verifySdJwtVc, presentSdJwtVc, createStatusListJwt, ed25519PublicKeyToJwk, ed25519PublicKeyFromJwk, } from './sdjwt/index.js';
|
|
11
|
+
export type { IssueSdJwtVcParams, IssuedSdJwtVc, VerifySdJwtVcParams, PresentSdJwtVcParams, PresentationResult, CreateStatusListJwtParams, Ed25519Jwk, VerificationResult as SdJwtVerificationResult, } from './sdjwt/index.js';
|
|
6
12
|
export interface SolidusSDK {
|
|
7
13
|
did: {
|
|
8
14
|
create(publicKey: string): Promise<DID>;
|
|
@@ -19,6 +25,39 @@ export interface SolidusSDK {
|
|
|
19
25
|
createChallenge(domain: string): Promise<string>;
|
|
20
26
|
verifyPresentation(vp: string, challenge: string, domain: string): Promise<AuthResult>;
|
|
21
27
|
};
|
|
28
|
+
/**
|
|
29
|
+
* BBS+ selective-disclosure operations. Available only in chain mode
|
|
30
|
+
* (testnet/mainnet) — `undefined` in stub mode.
|
|
31
|
+
*/
|
|
32
|
+
bbs?: {
|
|
33
|
+
issueCredential(params: {
|
|
34
|
+
issuerPrivateKey: string;
|
|
35
|
+
subjectDid: string;
|
|
36
|
+
credentialType: string;
|
|
37
|
+
payloadHash: Uint8Array;
|
|
38
|
+
bbsPubkey: Uint8Array;
|
|
39
|
+
bbsMessageCount: number;
|
|
40
|
+
}): Promise<{
|
|
41
|
+
txHash: string;
|
|
42
|
+
credentialId: string;
|
|
43
|
+
receipt: unknown;
|
|
44
|
+
}>;
|
|
45
|
+
verifyProof(params: {
|
|
46
|
+
proofHex: string;
|
|
47
|
+
pubkeyHex: string;
|
|
48
|
+
headerHex?: string;
|
|
49
|
+
phHex?: string;
|
|
50
|
+
disclosedMessages: BbsDisclosedMessage[];
|
|
51
|
+
totalMessageCount: number;
|
|
52
|
+
}): Promise<boolean>;
|
|
53
|
+
verifyCredentialProof(params: {
|
|
54
|
+
credentialId: string;
|
|
55
|
+
proofHex: string;
|
|
56
|
+
headerHex?: string;
|
|
57
|
+
phHex?: string;
|
|
58
|
+
disclosedMessages: BbsDisclosedMessage[];
|
|
59
|
+
}): Promise<BbsCredentialProofResult>;
|
|
60
|
+
};
|
|
22
61
|
}
|
|
23
62
|
export interface SolidusConfig {
|
|
24
63
|
mode: 'stub' | 'testnet' | 'mainnet';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,GAAG,EAAE,WAAW,EAAE,oBAAoB,EACtC,qBAAqB,EAAE,kBAAkB,EAAE,UAAU,EACtD,MAAM,gBAAgB,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -5,6 +5,13 @@ import { getSql } from './stub/db.js';
|
|
|
5
5
|
import { createChainClient } from './chain/index.js';
|
|
6
6
|
export { runMigrations, closeConnection } from './stub/db.js';
|
|
7
7
|
export { generateKeypair, decodePublicKey } from './stub/crypto.js';
|
|
8
|
+
export { createChainClient } from './chain/index.js';
|
|
9
|
+
export { utf8ToHex, toHex } from './chain/bbs.js';
|
|
10
|
+
// SD-JWT VC (selective-disclosure JWT, VC profile) — required for
|
|
11
|
+
// EUDI Wallet interop.
|
|
12
|
+
// Phase 1: issue + verify on flat subjects.
|
|
13
|
+
// Phase 2: holder presentation API + Key-Binding JWT.
|
|
14
|
+
export { issueSdJwtVc, verifySdJwtVc, presentSdJwtVc, createStatusListJwt, ed25519PublicKeyToJwk, ed25519PublicKeyFromJwk, } from './sdjwt/index.js';
|
|
8
15
|
function createStubSdk() {
|
|
9
16
|
return {
|
|
10
17
|
did: {
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAKxC,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,eAAe,CAAA;AACpE,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AAChH,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA;AACrC,OAAO,EAAE,iBAAiB,EAAoB,MAAM,kBAAkB,CAAA;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAKxC,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,eAAe,CAAA;AACpE,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AAChH,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA;AACrC,OAAO,EAAE,iBAAiB,EAAoB,MAAM,kBAAkB,CAAA;AAWtE,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,cAAc,CAAA;AAC7D,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAA;AAEnE,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAA;AAMpD,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAA;AAEjD,kEAAkE;AAClE,uBAAuB;AACvB,8CAA8C;AAC9C,wDAAwD;AACxD,OAAO,EACL,YAAY,EACZ,aAAa,EACb,cAAc,EACd,mBAAmB,EACnB,qBAAqB,EACrB,uBAAuB,GACxB,MAAM,kBAAkB,CAAA;AAmEzB,SAAS,aAAa;IACpB,OAAO;QACL,GAAG,EAAE;YACH,MAAM,EAAE,SAAS;YACjB,OAAO,EAAE,UAAU;YACnB,UAAU,EAAE,aAAa;SAC1B;QACD,WAAW,EAAE;YACX,KAAK,EAAE,gBAAgB;YACvB,MAAM,EAAE,iBAAiB;YACzB,MAAM,EAAE,iBAAiB;YACzB,KAAK,EAAE,gBAAgB;SACxB;QACD,IAAI,EAAE;YACJ,KAAK,CAAC,eAAe,CAAC,MAAc;gBAClC,MAAM,GAAG,GAAG,MAAM,EAAE,CAAA;gBACpB,MAAM,SAAS,GAAG,UAAU,EAAE,CAAA;gBAC9B,MAAM,GAAG,CAAA,2DAA2D,SAAS,KAAK,MAAM,GAAG,CAAA;gBAC3F,OAAO,SAAS,CAAA;YAClB,CAAC;YACD,KAAK,CAAC,kBAAkB,CACtB,GAAW,EACX,UAAkB,EAClB,OAAe;gBAEf,qDAAqD;gBACrD,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,CAAA;YACpC,CAAC;SACF;KACF,CAAA;AACH,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,MAAqB;IAC7C,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,IAAI,CAAE,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAgD,IAAI,MAAM,CAAC,CAAA;IAEvH,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,SAAS,CAAC;QACf,KAAK,SAAS,CAAC,CAAC,CAAC;YACf,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,IAAI,uBAAuB,CAAA;YACzF,MAAM,SAAS,GAAG,MAAM,CAAC,gBAAgB,IAAI,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,IAAI,EAAE,CAAA;YACpF,IAAI,CAAC,SAAS,EAAE,CAAC;gBACf,MAAM,IAAI,KAAK,CAAC,wEAAwE,CAAC,CAAA;YAC3F,CAAC;YACD,OAAO,iBAAiB,CAAC,EAAE,MAAM,EAAE,gBAAgB,EAAE,SAAS,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAA;QAClF,CAAC;QACD,KAAK,MAAM,CAAC;QACZ;YACE,OAAO,aAAa,EAAE,CAAA;IAC1B,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export type { IssueSdJwtVcParams, IssuedSdJwtVc, VerifySdJwtVcParams, VerificationResult, PresentSdJwtVcParams, PresentationResult, } from './types.js';
|
|
2
|
+
export { issueSdJwtVc } from './issue.js';
|
|
3
|
+
export { verifySdJwtVc } from './verify.js';
|
|
4
|
+
export { presentSdJwtVc } from './present.js';
|
|
5
|
+
export { createStatusListJwt } from './status-list.js';
|
|
6
|
+
export type { CreateStatusListJwtParams } from './status-list.js';
|
|
7
|
+
export { ed25519PublicKeyToJwk, ed25519PublicKeyFromJwk, type Ed25519Jwk, } from './signer.js';
|
|
8
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/sdjwt/index.ts"],"names":[],"mappings":"AAGA,YAAY,EACV,kBAAkB,EAClB,aAAa,EACb,mBAAmB,EACnB,kBAAkB,EAClB,oBAAoB,EACpB,kBAAkB,GACnB,MAAM,YAAY,CAAA;AAEnB,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAC3C,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAC7C,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAA;AACtD,YAAY,EAAE,yBAAyB,EAAE,MAAM,kBAAkB,CAAA;AACjE,OAAO,EACL,qBAAqB,EACrB,uBAAuB,EACvB,KAAK,UAAU,GAChB,MAAM,aAAa,CAAA"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
// SD-JWT VC integration for Solidus.
|
|
2
|
+
// See `.claude/plans/2026-05-09-sdjwt-vc-implementation.md`.
|
|
3
|
+
export { issueSdJwtVc } from './issue.js';
|
|
4
|
+
export { verifySdJwtVc } from './verify.js';
|
|
5
|
+
export { presentSdJwtVc } from './present.js';
|
|
6
|
+
export { createStatusListJwt } from './status-list.js';
|
|
7
|
+
export { ed25519PublicKeyToJwk, ed25519PublicKeyFromJwk, } from './signer.js';
|
|
8
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/sdjwt/index.ts"],"names":[],"mappings":"AAAA,qCAAqC;AACrC,6DAA6D;AAW7D,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAC3C,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAC7C,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAA;AAEtD,OAAO,EACL,qBAAqB,EACrB,uBAAuB,GAExB,MAAM,aAAa,CAAA"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Issue an SD-JWT VC (Selective-Disclosure JWT, VC profile).
|
|
3
|
+
*
|
|
4
|
+
* Wraps `@sd-jwt/sd-jwt-vc` with Solidus's Ed25519 / EdDSA conventions.
|
|
5
|
+
* The result is the compact-serialised form `<jws>~<d1>~<d2>~`, ready
|
|
6
|
+
* to hand off to a holder. Disclosure values stay attached to the
|
|
7
|
+
* compact form; selective revelation is a holder-side concern (see
|
|
8
|
+
* `present.ts` in a follow-up).
|
|
9
|
+
*/
|
|
10
|
+
import type { IssueSdJwtVcParams, IssuedSdJwtVc } from './types.js';
|
|
11
|
+
export declare function issueSdJwtVc(params: IssueSdJwtVcParams): Promise<IssuedSdJwtVc>;
|
|
12
|
+
//# sourceMappingURL=issue.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"issue.d.ts","sourceRoot":"","sources":["../../src/sdjwt/issue.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAYH,OAAO,KAAK,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAuDnE,wBAAsB,YAAY,CAChC,MAAM,EAAE,kBAAkB,GACzB,OAAO,CAAC,aAAa,CAAC,CA+ExB"}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Issue an SD-JWT VC (Selective-Disclosure JWT, VC profile).
|
|
3
|
+
*
|
|
4
|
+
* Wraps `@sd-jwt/sd-jwt-vc` with Solidus's Ed25519 / EdDSA conventions.
|
|
5
|
+
* The result is the compact-serialised form `<jws>~<d1>~<d2>~`, ready
|
|
6
|
+
* to hand off to a holder. Disclosure values stay attached to the
|
|
7
|
+
* compact form; selective revelation is a holder-side concern (see
|
|
8
|
+
* `present.ts` in a follow-up).
|
|
9
|
+
*/
|
|
10
|
+
import { SDJwtVcInstance } from '@sd-jwt/sd-jwt-vc';
|
|
11
|
+
import * as ed from '@noble/ed25519';
|
|
12
|
+
import { ed25519PublicKeyToJwk, makeEd25519Signer, sdJwtHasher, sdJwtSaltGenerator, } from './signer.js';
|
|
13
|
+
/**
|
|
14
|
+
* Build a sd-jwt-js DisclosureFrame from a list of disclosable claim
|
|
15
|
+
* paths (Phase 2c). Each path is a dot-separated string like
|
|
16
|
+
* `address.street`. The resulting frame is recursive — nested `_sd`
|
|
17
|
+
* arrays per object level — matching sd-jwt-js's DisclosureFrame type.
|
|
18
|
+
*
|
|
19
|
+
* Default behaviour (when `disclosable` is undefined): every top-level
|
|
20
|
+
* key except `id` is disclosable. Nested objects are NOT auto-expanded
|
|
21
|
+
* — callers who want nested disclosure must pass explicit paths.
|
|
22
|
+
*/
|
|
23
|
+
function buildDisclosureFrame(subject, disclosable) {
|
|
24
|
+
const paths = disclosable ?? Object.keys(subject).filter((k) => k !== 'id');
|
|
25
|
+
// Flat fast path: no dotted paths → original Phase 1 behaviour.
|
|
26
|
+
if (paths.every((p) => !p.includes('.'))) {
|
|
27
|
+
return { _sd: paths };
|
|
28
|
+
}
|
|
29
|
+
const root = { _sd: [] };
|
|
30
|
+
for (const path of paths) {
|
|
31
|
+
const segments = path.split('.');
|
|
32
|
+
let cursor = root;
|
|
33
|
+
for (let i = 0; i < segments.length; i++) {
|
|
34
|
+
const seg = segments[i];
|
|
35
|
+
if (i === segments.length - 1) {
|
|
36
|
+
cursor._sd.push(seg);
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
const existing = cursor[seg];
|
|
40
|
+
if (existing === undefined ||
|
|
41
|
+
Array.isArray(existing) ||
|
|
42
|
+
seg === '_sd') {
|
|
43
|
+
cursor[seg] = { _sd: [] };
|
|
44
|
+
}
|
|
45
|
+
cursor = cursor[seg];
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return root;
|
|
50
|
+
}
|
|
51
|
+
export async function issueSdJwtVc(params) {
|
|
52
|
+
if (params.issuerPrivateKey.length !== 32) {
|
|
53
|
+
throw new Error(`issuerPrivateKey must be 32 bytes, got ${params.issuerPrivateKey.length}`);
|
|
54
|
+
}
|
|
55
|
+
// Derive the public key once so the verifier callback can be
|
|
56
|
+
// attached at issuance time (sd-jwt-vc does not strictly need it for
|
|
57
|
+
// issue() but we keep symmetry with the verify path).
|
|
58
|
+
const issuerPublicKey = await ed.getPublicKeyAsync(params.issuerPrivateKey);
|
|
59
|
+
const sdjwt = new SDJwtVcInstance({
|
|
60
|
+
signer: makeEd25519Signer(params.issuerPrivateKey),
|
|
61
|
+
signAlg: 'EdDSA',
|
|
62
|
+
hasher: sdJwtHasher,
|
|
63
|
+
hashAlg: 'sha-256',
|
|
64
|
+
saltGenerator: sdJwtSaltGenerator,
|
|
65
|
+
// We don't load remote vct metadata in Phase 1 — the issuer is
|
|
66
|
+
// authoritative for the type and consumers can fetch metadata
|
|
67
|
+
// out-of-band when Phase 2 adds a metadata endpoint.
|
|
68
|
+
loadTypeMetadataFormat: false,
|
|
69
|
+
});
|
|
70
|
+
const now = Math.floor(Date.now() / 1000);
|
|
71
|
+
const subject = { ...params.subject };
|
|
72
|
+
const subjectId = typeof subject['id'] === 'string' ? subject['id'] : undefined;
|
|
73
|
+
// `id` is not part of the SD-JWT VC payload directly — `sub` carries
|
|
74
|
+
// the holder identifier per spec §3.2.2.2.
|
|
75
|
+
delete subject['id'];
|
|
76
|
+
const payload = {
|
|
77
|
+
iss: params.issuer,
|
|
78
|
+
vct: params.vct,
|
|
79
|
+
iat: now,
|
|
80
|
+
...subject,
|
|
81
|
+
};
|
|
82
|
+
if (subjectId !== undefined)
|
|
83
|
+
payload['sub'] = subjectId;
|
|
84
|
+
if (params.validFrom !== undefined) {
|
|
85
|
+
payload['nbf'] = Math.floor(new Date(params.validFrom).getTime() / 1000);
|
|
86
|
+
}
|
|
87
|
+
if (params.validUntil !== undefined) {
|
|
88
|
+
payload['exp'] = Math.floor(new Date(params.validUntil).getTime() / 1000);
|
|
89
|
+
}
|
|
90
|
+
// When a holder public key is supplied, bind the credential to that
|
|
91
|
+
// key via the W3C `cnf` claim (RFC 7800). The verifier checks the
|
|
92
|
+
// KB-JWT's signature against this key at presentation time.
|
|
93
|
+
if (params.holderPublicKey !== undefined) {
|
|
94
|
+
payload['cnf'] = { jwk: ed25519PublicKeyToJwk(params.holderPublicKey) };
|
|
95
|
+
}
|
|
96
|
+
// Optional status-list reference per draft-ietf-oauth-status-list.
|
|
97
|
+
if (params.status !== undefined) {
|
|
98
|
+
payload['status'] = {
|
|
99
|
+
status_list: { uri: params.status.uri, idx: params.status.idx },
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
const disclosureFrame = buildDisclosureFrame(subject, params.disclosable);
|
|
103
|
+
const compact = await sdjwt.issue(payload, disclosureFrame);
|
|
104
|
+
// Quick sanity check that we can derive a count of disclosures from
|
|
105
|
+
// the compact form: split on `~`, drop the leading JWS, and any
|
|
106
|
+
// trailing empty (which is the absent KB-JWT slot in Phase 1).
|
|
107
|
+
const parts = compact.split('~');
|
|
108
|
+
const disclosureCount = parts.slice(1).filter((p) => p.length > 0).length;
|
|
109
|
+
// Surface the public key on the result for callers that want to
|
|
110
|
+
// immediately store it alongside the compact form (e.g., a verify
|
|
111
|
+
// backend that records the issuer-key-at-issue-time).
|
|
112
|
+
void issuerPublicKey;
|
|
113
|
+
return {
|
|
114
|
+
compact,
|
|
115
|
+
payload,
|
|
116
|
+
disclosureCount,
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
//# sourceMappingURL=issue.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"issue.js","sourceRoot":"","sources":["../../src/sdjwt/issue.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Holder-side presentation API for SD-JWT VC.
|
|
3
|
+
*
|
|
4
|
+
* Phase 2. Takes an issued SD-JWT VC (with all disclosures attached)
|
|
5
|
+
* and returns a presentation that:
|
|
6
|
+
* - reveals only the disclosures the holder consents to,
|
|
7
|
+
* - is bound to a Key-Binding JWT signed by the holder's private key.
|
|
8
|
+
*
|
|
9
|
+
* The KB-JWT proves the holder controls the key referenced by the
|
|
10
|
+
* issuer-set `cnf.jwk` claim — without it, anyone with a copy of the
|
|
11
|
+
* compact form could replay the credential to a different verifier.
|
|
12
|
+
*/
|
|
13
|
+
import type { PresentSdJwtVcParams, PresentationResult } from './types.js';
|
|
14
|
+
export declare function presentSdJwtVc(params: PresentSdJwtVcParams): Promise<PresentationResult>;
|
|
15
|
+
//# sourceMappingURL=present.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"present.d.ts","sourceRoot":"","sources":["../../src/sdjwt/present.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAUH,OAAO,KAAK,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAA;AA6C1E,wBAAsB,cAAc,CAClC,MAAM,EAAE,oBAAoB,GAC3B,OAAO,CAAC,kBAAkB,CAAC,CAmC7B"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Holder-side presentation API for SD-JWT VC.
|
|
3
|
+
*
|
|
4
|
+
* Phase 2. Takes an issued SD-JWT VC (with all disclosures attached)
|
|
5
|
+
* and returns a presentation that:
|
|
6
|
+
* - reveals only the disclosures the holder consents to,
|
|
7
|
+
* - is bound to a Key-Binding JWT signed by the holder's private key.
|
|
8
|
+
*
|
|
9
|
+
* The KB-JWT proves the holder controls the key referenced by the
|
|
10
|
+
* issuer-set `cnf.jwk` claim — without it, anyone with a copy of the
|
|
11
|
+
* compact form could replay the credential to a different verifier.
|
|
12
|
+
*/
|
|
13
|
+
import { SDJwtVcInstance } from '@sd-jwt/sd-jwt-vc';
|
|
14
|
+
import { makeEd25519Signer, sdJwtHasher, sdJwtSaltGenerator, } from './signer.js';
|
|
15
|
+
/**
|
|
16
|
+
* Build a sd-jwt-js PresentationFrame from a list of claim paths
|
|
17
|
+
* (Phase 2c — supports nested paths via dot notation). Each path is
|
|
18
|
+
* either a top-level key (`'firstName'`) or a dotted path into a
|
|
19
|
+
* nested object (`'address.street'`). Result is a recursive map
|
|
20
|
+
* `{ key: true | { nestedKey: true } }` matching sd-jwt-js's
|
|
21
|
+
* PresentationFrame type.
|
|
22
|
+
*/
|
|
23
|
+
function buildPresentationFrame(reveal) {
|
|
24
|
+
// Flat fast path — preserves the original Phase 2 behaviour.
|
|
25
|
+
if (reveal.every((p) => !p.includes('.'))) {
|
|
26
|
+
const flat = {};
|
|
27
|
+
for (const k of reveal)
|
|
28
|
+
flat[k] = true;
|
|
29
|
+
return flat;
|
|
30
|
+
}
|
|
31
|
+
const root = {};
|
|
32
|
+
for (const path of reveal) {
|
|
33
|
+
const segments = path.split('.');
|
|
34
|
+
let cursor = root;
|
|
35
|
+
for (let i = 0; i < segments.length; i++) {
|
|
36
|
+
const seg = segments[i];
|
|
37
|
+
if (i === segments.length - 1) {
|
|
38
|
+
cursor[seg] = true;
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
// If a previous path already pinned this segment as `true`,
|
|
42
|
+
// upgrade to an object so we can attach the nested key.
|
|
43
|
+
const existing = cursor[seg];
|
|
44
|
+
if (existing === true || existing === undefined) {
|
|
45
|
+
cursor[seg] = {};
|
|
46
|
+
}
|
|
47
|
+
cursor = cursor[seg];
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return root;
|
|
52
|
+
}
|
|
53
|
+
export async function presentSdJwtVc(params) {
|
|
54
|
+
if (params.holderPrivateKey.length !== 32) {
|
|
55
|
+
throw new Error(`holderPrivateKey must be 32 bytes, got ${params.holderPrivateKey.length}`);
|
|
56
|
+
}
|
|
57
|
+
// Holder uses its own key as the KB-JWT signer. The issuer-side
|
|
58
|
+
// signer is irrelevant here — present() does not re-sign the SD-JWT,
|
|
59
|
+
// only the new KB-JWT.
|
|
60
|
+
const sdjwt = new SDJwtVcInstance({
|
|
61
|
+
hasher: sdJwtHasher,
|
|
62
|
+
saltGenerator: sdJwtSaltGenerator,
|
|
63
|
+
hashAlg: 'sha-256',
|
|
64
|
+
kbSigner: makeEd25519Signer(params.holderPrivateKey),
|
|
65
|
+
kbSignAlg: 'EdDSA',
|
|
66
|
+
loadTypeMetadataFormat: false,
|
|
67
|
+
});
|
|
68
|
+
const presentationFrame = buildPresentationFrame(params.claimsToReveal);
|
|
69
|
+
const compact = await sdjwt.present(params.compact, presentationFrame, {
|
|
70
|
+
kb: {
|
|
71
|
+
payload: {
|
|
72
|
+
iat: Math.floor(Date.now() / 1000),
|
|
73
|
+
aud: params.audience,
|
|
74
|
+
nonce: params.nonce,
|
|
75
|
+
},
|
|
76
|
+
},
|
|
77
|
+
});
|
|
78
|
+
return { compact };
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=present.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"present.js","sourceRoot":"","sources":["../../src/sdjwt/present.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAA;AAGnD,OAAO,EACL,iBAAiB,EACjB,WAAW,EACX,kBAAkB,GACnB,MAAM,aAAa,CAAA;AAGpB;;;;;;;GAOG;AACH,SAAS,sBAAsB,CAC7B,MAAgB;IAEhB,6DAA6D;IAC7D,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;QAC1C,MAAM,IAAI,GAAyB,EAAE,CAAA;QACrC,KAAK,MAAM,CAAC,IAAI,MAAM;YAAE,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAA;QACtC,OAAO,IAA6D,CAAA;IACtE,CAAC;IAKD,MAAM,IAAI,GAAc,EAAE,CAAA;IAC1B,KAAK,MAAM,IAAI,IAAI,MAAM,EAAE,CAAC;QAC1B,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;QAChC,IAAI,MAAM,GAAc,IAAI,CAAA;QAC5B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACzC,MAAM,GAAG,GAAG,QAAQ,CAAC,CAAC,CAAE,CAAA;YACxB,IAAI,CAAC,KAAK,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC9B,MAAM,CAAC,GAAG,CAAC,GAAG,IAAI,CAAA;YACpB,CAAC;iBAAM,CAAC;gBACN,4DAA4D;gBAC5D,wDAAwD;gBACxD,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC,CAAA;gBAC5B,IAAI,QAAQ,KAAK,IAAI,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;oBAChD,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,CAAA;gBAClB,CAAC;gBACD,MAAM,GAAG,MAAM,CAAC,GAAG,CAAc,CAAA;YACnC,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,IAA6D,CAAA;AACtE,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,MAA4B;IAE5B,IAAI,MAAM,CAAC,gBAAgB,CAAC,MAAM,KAAK,EAAE,EAAE,CAAC;QAC1C,MAAM,IAAI,KAAK,CACb,0CAA0C,MAAM,CAAC,gBAAgB,CAAC,MAAM,EAAE,CAC3E,CAAA;IACH,CAAC;IAED,gEAAgE;IAChE,qEAAqE;IACrE,uBAAuB;IACvB,MAAM,KAAK,GAAG,IAAI,eAAe,CAAC;QAChC,MAAM,EAAE,WAAW;QACnB,aAAa,EAAE,kBAAkB;QACjC,OAAO,EAAE,SAAS;QAClB,QAAQ,EAAE,iBAAiB,CAAC,MAAM,CAAC,gBAAgB,CAAC;QACpD,SAAS,EAAE,OAAO;QAClB,sBAAsB,EAAE,KAAK;KAC9B,CAAC,CAAA;IAEF,MAAM,iBAAiB,GAAG,sBAAsB,CAAC,MAAM,CAAC,cAAc,CAAC,CAAA;IACvE,MAAM,OAAO,GAAG,MAAM,KAAK,CAAC,OAAO,CACjC,MAAM,CAAC,OAAO,EACd,iBAAiB,EACjB;QACE,EAAE,EAAE;YACF,OAAO,EAAE;gBACP,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;gBAClC,GAAG,EAAE,MAAM,CAAC,QAAQ;gBACpB,KAAK,EAAE,MAAM,CAAC,KAAK;aACpB;SACF;KACF,CACF,CAAA;IAED,OAAO,EAAE,OAAO,EAAE,CAAA;AACpB,CAAC"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ed25519 signer/verifier adapters for `@sd-jwt/core`.
|
|
3
|
+
*
|
|
4
|
+
* sd-jwt-js expects callbacks shaped as `(data: string) => Promise<string>`
|
|
5
|
+
* for signing and `(data: string, signature: string) => Promise<boolean>`
|
|
6
|
+
* for verification. Both data and signature are compact-encoded bytes
|
|
7
|
+
* for SD-JWT (which uses base64url).
|
|
8
|
+
*
|
|
9
|
+
* This module wires those callbacks to `@noble/ed25519`, matching the
|
|
10
|
+
* EdDSA convention used elsewhere in Solidus (chain tx signing,
|
|
11
|
+
* `@solidus-network/jwt`). The hash algorithm is fixed at SHA-256 because the
|
|
12
|
+
* SD-JWT spec requires it for the disclosure-digest construction; the
|
|
13
|
+
* rest of Solidus (chain layer) uses BLAKE3, but disclosure hashes are
|
|
14
|
+
* client-interop boundary so we follow the spec.
|
|
15
|
+
*/
|
|
16
|
+
/**
|
|
17
|
+
* Construct a signer callback bound to the given Ed25519 private key.
|
|
18
|
+
*
|
|
19
|
+
* Returns the signature as a base64url-encoded string, matching what
|
|
20
|
+
* sd-jwt-js expects for the JWS `signature` segment.
|
|
21
|
+
*/
|
|
22
|
+
export declare function makeEd25519Signer(privateKey: Uint8Array): (data: string) => Promise<string>;
|
|
23
|
+
/** Construct a verifier callback bound to the given Ed25519 public key. */
|
|
24
|
+
export declare function makeEd25519Verifier(publicKey: Uint8Array): (data: string, signature: string) => Promise<boolean>;
|
|
25
|
+
/**
|
|
26
|
+
* Hasher in the shape `@sd-jwt/types` expects:
|
|
27
|
+
* `(data: string | ArrayBuffer, alg: string) => Uint8Array`.
|
|
28
|
+
*
|
|
29
|
+
* Honours the requested algorithm so callers can plug in others later;
|
|
30
|
+
* Phase 1 only supports `sha-256` (the SD-JWT spec default and the
|
|
31
|
+
* only algorithm sd-jwt-vc emits without explicit configuration).
|
|
32
|
+
*/
|
|
33
|
+
export declare function sdJwtHasher(data: string | ArrayBuffer, alg: string): Uint8Array;
|
|
34
|
+
/**
|
|
35
|
+
* Salt generator in the shape `@sd-jwt/types` expects:
|
|
36
|
+
* `(length: number) => string`.
|
|
37
|
+
*
|
|
38
|
+
* Returns a base64url-encoded random string of `length` bytes.
|
|
39
|
+
* SD-JWT spec recommends ≥128 bits (16 bytes) of entropy per salt;
|
|
40
|
+
* sd-jwt-js calls this with `length = 16` by default.
|
|
41
|
+
*/
|
|
42
|
+
export declare function sdJwtSaltGenerator(length: number): string;
|
|
43
|
+
/**
|
|
44
|
+
* JWK shape used in the SD-JWT VC `cnf` claim for an Ed25519 holder
|
|
45
|
+
* key. Matches RFC 8037 — Ed25519 → OKP curve, no `d` (private)
|
|
46
|
+
* component. The verifier reconstructs the raw 32-byte public key from
|
|
47
|
+
* `x`.
|
|
48
|
+
*/
|
|
49
|
+
export interface Ed25519Jwk {
|
|
50
|
+
kty: 'OKP';
|
|
51
|
+
crv: 'Ed25519';
|
|
52
|
+
x: string;
|
|
53
|
+
alg: 'EdDSA';
|
|
54
|
+
}
|
|
55
|
+
/** Convert a 32-byte Ed25519 public key into the canonical JWK form. */
|
|
56
|
+
export declare function ed25519PublicKeyToJwk(publicKey: Uint8Array): Ed25519Jwk;
|
|
57
|
+
/** Recover a 32-byte Ed25519 public key from its canonical JWK form. */
|
|
58
|
+
export declare function ed25519PublicKeyFromJwk(jwk: unknown): Uint8Array;
|
|
59
|
+
//# sourceMappingURL=signer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signer.d.ts","sourceRoot":"","sources":["../../src/sdjwt/signer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAqBH;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,UAAU,IAIxC,MAAM,MAAM,KAAG,OAAO,CAAC,MAAM,CAAC,CAI7C;AAED,2EAA2E;AAC3E,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,UAAU,IAIzC,MAAM,MAAM,EAAE,WAAW,MAAM,KAAG,OAAO,CAAC,OAAO,CAAC,CAWjE;AAED;;;;;;;GAOG;AACH,wBAAgB,WAAW,CACzB,IAAI,EAAE,MAAM,GAAG,WAAW,EAC1B,GAAG,EAAE,MAAM,GACV,UAAU,CASZ;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAQzD;AAED;;;;;GAKG;AACH,MAAM,WAAW,UAAU;IACzB,GAAG,EAAE,KAAK,CAAA;IACV,GAAG,EAAE,SAAS,CAAA;IACd,CAAC,EAAE,MAAM,CAAA;IACT,GAAG,EAAE,OAAO,CAAA;CACb;AAED,wEAAwE;AACxE,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,UAAU,GAAG,UAAU,CAUvE;AAED,wEAAwE;AACxE,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,OAAO,GAAG,UAAU,CAehE"}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ed25519 signer/verifier adapters for `@sd-jwt/core`.
|
|
3
|
+
*
|
|
4
|
+
* sd-jwt-js expects callbacks shaped as `(data: string) => Promise<string>`
|
|
5
|
+
* for signing and `(data: string, signature: string) => Promise<boolean>`
|
|
6
|
+
* for verification. Both data and signature are compact-encoded bytes
|
|
7
|
+
* for SD-JWT (which uses base64url).
|
|
8
|
+
*
|
|
9
|
+
* This module wires those callbacks to `@noble/ed25519`, matching the
|
|
10
|
+
* EdDSA convention used elsewhere in Solidus (chain tx signing,
|
|
11
|
+
* `@solidus-network/jwt`). The hash algorithm is fixed at SHA-256 because the
|
|
12
|
+
* SD-JWT spec requires it for the disclosure-digest construction; the
|
|
13
|
+
* rest of Solidus (chain layer) uses BLAKE3, but disclosure hashes are
|
|
14
|
+
* client-interop boundary so we follow the spec.
|
|
15
|
+
*/
|
|
16
|
+
import * as ed from '@noble/ed25519';
|
|
17
|
+
import { sha256 } from '@noble/hashes/sha2';
|
|
18
|
+
function fromBase64Url(input) {
|
|
19
|
+
const padded = input.replace(/-/g, '+').replace(/_/g, '/').padEnd(input.length + ((4 - (input.length % 4)) % 4), '=');
|
|
20
|
+
return new Uint8Array(Buffer.from(padded, 'base64'));
|
|
21
|
+
}
|
|
22
|
+
function toBase64Url(input) {
|
|
23
|
+
return Buffer.from(input)
|
|
24
|
+
.toString('base64')
|
|
25
|
+
.replace(/\+/g, '-')
|
|
26
|
+
.replace(/\//g, '_')
|
|
27
|
+
.replace(/=/g, '');
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Construct a signer callback bound to the given Ed25519 private key.
|
|
31
|
+
*
|
|
32
|
+
* Returns the signature as a base64url-encoded string, matching what
|
|
33
|
+
* sd-jwt-js expects for the JWS `signature` segment.
|
|
34
|
+
*/
|
|
35
|
+
export function makeEd25519Signer(privateKey) {
|
|
36
|
+
if (privateKey.length !== 32) {
|
|
37
|
+
throw new Error(`privateKey must be 32 bytes, got ${privateKey.length}`);
|
|
38
|
+
}
|
|
39
|
+
return async (data) => {
|
|
40
|
+
const sig = await ed.signAsync(new TextEncoder().encode(data), privateKey);
|
|
41
|
+
return toBase64Url(sig);
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
/** Construct a verifier callback bound to the given Ed25519 public key. */
|
|
45
|
+
export function makeEd25519Verifier(publicKey) {
|
|
46
|
+
if (publicKey.length !== 32) {
|
|
47
|
+
throw new Error(`publicKey must be 32 bytes, got ${publicKey.length}`);
|
|
48
|
+
}
|
|
49
|
+
return async (data, signature) => {
|
|
50
|
+
try {
|
|
51
|
+
return await ed.verifyAsync(fromBase64Url(signature), new TextEncoder().encode(data), publicKey);
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Hasher in the shape `@sd-jwt/types` expects:
|
|
60
|
+
* `(data: string | ArrayBuffer, alg: string) => Uint8Array`.
|
|
61
|
+
*
|
|
62
|
+
* Honours the requested algorithm so callers can plug in others later;
|
|
63
|
+
* Phase 1 only supports `sha-256` (the SD-JWT spec default and the
|
|
64
|
+
* only algorithm sd-jwt-vc emits without explicit configuration).
|
|
65
|
+
*/
|
|
66
|
+
export function sdJwtHasher(data, alg) {
|
|
67
|
+
if (alg !== 'sha-256') {
|
|
68
|
+
throw new Error(`unsupported SD-JWT hash algorithm: ${alg}`);
|
|
69
|
+
}
|
|
70
|
+
const bytes = typeof data === 'string'
|
|
71
|
+
? new TextEncoder().encode(data)
|
|
72
|
+
: new Uint8Array(data);
|
|
73
|
+
return sha256(bytes);
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Salt generator in the shape `@sd-jwt/types` expects:
|
|
77
|
+
* `(length: number) => string`.
|
|
78
|
+
*
|
|
79
|
+
* Returns a base64url-encoded random string of `length` bytes.
|
|
80
|
+
* SD-JWT spec recommends ≥128 bits (16 bytes) of entropy per salt;
|
|
81
|
+
* sd-jwt-js calls this with `length = 16` by default.
|
|
82
|
+
*/
|
|
83
|
+
export function sdJwtSaltGenerator(length) {
|
|
84
|
+
const bytes = new Uint8Array(length);
|
|
85
|
+
crypto.getRandomValues(bytes);
|
|
86
|
+
return Buffer.from(bytes)
|
|
87
|
+
.toString('base64')
|
|
88
|
+
.replace(/\+/g, '-')
|
|
89
|
+
.replace(/\//g, '_')
|
|
90
|
+
.replace(/=/g, '');
|
|
91
|
+
}
|
|
92
|
+
/** Convert a 32-byte Ed25519 public key into the canonical JWK form. */
|
|
93
|
+
export function ed25519PublicKeyToJwk(publicKey) {
|
|
94
|
+
if (publicKey.length !== 32) {
|
|
95
|
+
throw new Error(`publicKey must be 32 bytes, got ${publicKey.length}`);
|
|
96
|
+
}
|
|
97
|
+
return {
|
|
98
|
+
kty: 'OKP',
|
|
99
|
+
crv: 'Ed25519',
|
|
100
|
+
x: toBase64Url(publicKey),
|
|
101
|
+
alg: 'EdDSA',
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
/** Recover a 32-byte Ed25519 public key from its canonical JWK form. */
|
|
105
|
+
export function ed25519PublicKeyFromJwk(jwk) {
|
|
106
|
+
if (!jwk ||
|
|
107
|
+
typeof jwk !== 'object' ||
|
|
108
|
+
jwk.kty !== 'OKP' ||
|
|
109
|
+
jwk.crv !== 'Ed25519' ||
|
|
110
|
+
typeof jwk.x !== 'string') {
|
|
111
|
+
throw new Error('not an Ed25519 OKP JWK');
|
|
112
|
+
}
|
|
113
|
+
const bytes = fromBase64Url(jwk.x);
|
|
114
|
+
if (bytes.length !== 32) {
|
|
115
|
+
throw new Error(`JWK x must decode to 32 bytes, got ${bytes.length}`);
|
|
116
|
+
}
|
|
117
|
+
return bytes;
|
|
118
|
+
}
|
|
119
|
+
//# sourceMappingURL=signer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signer.js","sourceRoot":"","sources":["../../src/sdjwt/signer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Status list (draft-ietf-oauth-status-list) helper for issuers.
|
|
3
|
+
*
|
|
4
|
+
* The lifecycle:
|
|
5
|
+
* 1. Issuer creates a `StatusList` (a bitstring of N statuses,
|
|
6
|
+
* typically 1 bit per credential — 0 = active, 1 = revoked).
|
|
7
|
+
* 2. Issuer wraps it in a JWT signed by the issuer's key, served at
|
|
8
|
+
* a stable URL (e.g., `/status-lists/<id>`).
|
|
9
|
+
* 3. Each issued SD-JWT VC carries a `status.status_list.{uri, idx}`
|
|
10
|
+
* pointing at one bit in the list.
|
|
11
|
+
* 4. To revoke a credential, the issuer flips its bit and republishes
|
|
12
|
+
* the (now-updated) JWT at the same URL.
|
|
13
|
+
* 5. Verifiers refetch the list (cache-respecting) and check the bit.
|
|
14
|
+
*
|
|
15
|
+
* `createStatusListJwt` is a thin wrapper around `@sd-jwt/jwt-status-list`
|
|
16
|
+
* that uses Ed25519 / EdDSA to match the rest of Solidus's signing
|
|
17
|
+
* conventions.
|
|
18
|
+
*/
|
|
19
|
+
import { type BitsPerStatus } from '@sd-jwt/jwt-status-list';
|
|
20
|
+
export interface CreateStatusListJwtParams {
|
|
21
|
+
/** Issuer's raw 32-byte Ed25519 private key. */
|
|
22
|
+
issuerPrivateKey: Uint8Array;
|
|
23
|
+
/** Issuer DID — becomes the `iss` claim on the status-list JWT. */
|
|
24
|
+
issuer: string;
|
|
25
|
+
/**
|
|
26
|
+
* The URL where this status-list JWT will be served. Becomes the
|
|
27
|
+
* `sub` claim per draft-ietf-oauth-status-list §6.2 and is what
|
|
28
|
+
* issued credentials reference via `status.status_list.uri`.
|
|
29
|
+
*/
|
|
30
|
+
uri: string;
|
|
31
|
+
/**
|
|
32
|
+
* Total number of statuses in the list. Determines the bitstring
|
|
33
|
+
* size. Choose with growth in mind — once published, callers cannot
|
|
34
|
+
* shrink the list without breaking existing references.
|
|
35
|
+
*/
|
|
36
|
+
totalStatuses: number;
|
|
37
|
+
/**
|
|
38
|
+
* Bits per status. 1 = boolean (active/revoked); 2/4/8 add finer
|
|
39
|
+
* granularity (suspended, expired, etc.) per spec §6. Default 1.
|
|
40
|
+
*/
|
|
41
|
+
bitsPerStatus?: BitsPerStatus;
|
|
42
|
+
/**
|
|
43
|
+
* Indexes whose status should be set to non-zero. With `bitsPerStatus
|
|
44
|
+
* = 1`, listing an index here means "revoked". For higher bit
|
|
45
|
+
* widths, pass `[index, value]` tuples.
|
|
46
|
+
*/
|
|
47
|
+
revoked?: Array<number | [number, number]>;
|
|
48
|
+
/**
|
|
49
|
+
* Optional time-to-live in seconds — verifiers MAY use this to
|
|
50
|
+
* decide how long to cache the list. Per draft-ietf-oauth-status-list.
|
|
51
|
+
*/
|
|
52
|
+
ttlSeconds?: number;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Build a signed status-list JWT.
|
|
56
|
+
*
|
|
57
|
+
* Returns the JWT in compact form. Issuers serve this at the URL
|
|
58
|
+
* embedded in their issued SD-JWT VCs' `status.status_list.uri` claim.
|
|
59
|
+
*/
|
|
60
|
+
export declare function createStatusListJwt(params: CreateStatusListJwtParams): Promise<string>;
|
|
61
|
+
//# sourceMappingURL=status-list.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status-list.d.ts","sourceRoot":"","sources":["../../src/sdjwt/status-list.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAGH,OAAO,EAGL,KAAK,aAAa,EACnB,MAAM,yBAAyB,CAAA;AAUhC,MAAM,WAAW,yBAAyB;IACxC,gDAAgD;IAChD,gBAAgB,EAAE,UAAU,CAAA;IAE5B,mEAAmE;IACnE,MAAM,EAAE,MAAM,CAAA;IAEd;;;;OAIG;IACH,GAAG,EAAE,MAAM,CAAA;IAEX;;;;OAIG;IACH,aAAa,EAAE,MAAM,CAAA;IAErB;;;OAGG;IACH,aAAa,CAAC,EAAE,aAAa,CAAA;IAE7B;;;;OAIG;IACH,OAAO,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;IAE1C;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AAED;;;;;GAKG;AACH,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,yBAAyB,GAChC,OAAO,CAAC,MAAM,CAAC,CA8CjB"}
|