@vess-id/ai-identity 0.0.1 → 0.0.2

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/index.js CHANGED
@@ -57,15 +57,20 @@ __export(index_exports, {
57
57
  checkPermissionWithVP: () => checkPermissionWithVP,
58
58
  configure: () => configure,
59
59
  createAjv: () => createAjv,
60
+ createDidJwk: () => createDidJwk,
60
61
  defaultConstraintEvaluator: () => defaultConstraintEvaluator,
61
62
  evaluateConstraints: () => evaluateConstraints,
63
+ extractPublicKey: () => extractPublicKey,
64
+ extractPublicKeyFromDid: () => extractPublicKeyFromDid,
62
65
  generateKeyPair: () => generateKeyPair,
63
66
  generateNonce: () => generateNonce,
64
67
  getClient: () => getClient,
68
+ getKeyIdFromDid: () => getKeyIdFromDid,
65
69
  getRequiredRelations: () => getRequiredRelations,
66
70
  getRequiredScopes: () => getRequiredScopes,
67
71
  indexActions: () => indexActions,
68
72
  indexCapabilities: () => indexCapabilities,
73
+ isValidDidJwk: () => isValidDidJwk,
69
74
  loadActionRegistryFromFile: () => loadActionRegistryFromFile,
70
75
  loadActionRegistryFromObject: () => loadActionRegistryFromObject,
71
76
  planDelegationForVC: () => planDelegationForVC,
@@ -427,7 +432,51 @@ async function getVerifier(publicKey) {
427
432
  };
428
433
  }
429
434
 
435
+ // src/did/did-utils.ts
436
+ function createDidJwk(publicKey) {
437
+ const publicJwk = {
438
+ kty: publicKey.kty,
439
+ crv: publicKey.crv,
440
+ x: publicKey.x,
441
+ y: publicKey.y,
442
+ use: publicKey.use,
443
+ alg: publicKey.alg
444
+ };
445
+ const cleanedJwk = Object.fromEntries(
446
+ Object.entries(publicJwk).filter(([_, v]) => v !== void 0)
447
+ );
448
+ const encoded = Buffer.from(JSON.stringify(cleanedJwk)).toString("base64url");
449
+ return `did:jwk:${encoded}`;
450
+ }
451
+ function extractPublicKey(privateKey) {
452
+ const { d, key_ops, ...publicKey } = privateKey;
453
+ return publicKey;
454
+ }
455
+ function extractPublicKeyFromDid(did) {
456
+ if (!did.startsWith("did:jwk:")) {
457
+ throw new Error("Only did:jwk format is supported");
458
+ }
459
+ const encoded = did.replace("did:jwk:", "");
460
+ return JSON.parse(Buffer.from(encoded, "base64url").toString());
461
+ }
462
+ function isValidDidJwk(did) {
463
+ if (!did.startsWith("did:jwk:")) {
464
+ return false;
465
+ }
466
+ try {
467
+ const encoded = did.replace("did:jwk:", "");
468
+ const decoded = JSON.parse(Buffer.from(encoded, "base64url").toString());
469
+ return typeof decoded === "object" && decoded.kty !== void 0;
470
+ } catch {
471
+ return false;
472
+ }
473
+ }
474
+ function getKeyIdFromDid(did) {
475
+ return `${did}#0`;
476
+ }
477
+
430
478
  // src/utils/sdjwt-client.ts
479
+ var import_node_crypto2 = require("crypto");
431
480
  var SDJwtClient = class {
432
481
  static instances = /* @__PURE__ */ new Map();
433
482
  static keyManager;
@@ -632,6 +681,212 @@ var SDJwtClient = class {
632
681
  verifierCount: this.verifierCache.size
633
682
  };
634
683
  }
684
+ /**
685
+ * Create a verifier function from an external public key
686
+ * This is used for verifying SD-JWTs when you don't have the private key
687
+ * (e.g., API side verifying credentials issued by MCP)
688
+ */
689
+ static async getVerifierFromPublicKey(publicKey) {
690
+ const key = await import_node_crypto2.subtle.importKey(
691
+ "jwk",
692
+ publicKey,
693
+ {
694
+ name: "ECDSA",
695
+ namedCurve: "P-256"
696
+ },
697
+ true,
698
+ ["verify"]
699
+ );
700
+ return async (data, signatureBase64url) => {
701
+ const encoder = new TextEncoder();
702
+ const signature = Uint8Array.from(
703
+ atob(signatureBase64url.replace(/-/g, "+").replace(/_/g, "/")),
704
+ (c) => c.charCodeAt(0)
705
+ );
706
+ const isValid = await import_node_crypto2.subtle.verify(
707
+ {
708
+ name: "ECDSA",
709
+ hash: { name: "SHA-256" }
710
+ },
711
+ key,
712
+ signature,
713
+ encoder.encode(data)
714
+ );
715
+ return isValid;
716
+ };
717
+ }
718
+ /**
719
+ * Get SDJwtVcInstance for verification with an external public key
720
+ * Used when verifying credentials without having the issuer's private key
721
+ */
722
+ static async getVerificationInstance(publicKey) {
723
+ const cacheKey = `verify:${JSON.stringify(publicKey)}`;
724
+ if (!this.instances.has(cacheKey)) {
725
+ const dummySigner = async () => "dummy";
726
+ const verifier = await this.getVerifierFromPublicKey(publicKey);
727
+ const instance = new import_sd_jwt_vc.SDJwtVcInstance({
728
+ signer: dummySigner,
729
+ verifier,
730
+ signAlg: import_crypto_nodejs.ES256.alg,
731
+ hasher: import_crypto_nodejs.digest,
732
+ hashAlg: "sha-256",
733
+ saltGenerator: import_crypto_nodejs.generateSalt
734
+ });
735
+ this.instances.set(cacheKey, instance);
736
+ }
737
+ return this.instances.get(cacheKey);
738
+ }
739
+ /**
740
+ * Get SDJwtVcInstance for decoding without verification
741
+ */
742
+ static async getDecodingInstance() {
743
+ const cacheKey = "decode:dummy";
744
+ if (!this.instances.has(cacheKey)) {
745
+ const dummySigner = async () => "dummy";
746
+ const dummyVerifier = async () => false;
747
+ const instance = new import_sd_jwt_vc.SDJwtVcInstance({
748
+ signer: dummySigner,
749
+ verifier: dummyVerifier,
750
+ signAlg: import_crypto_nodejs.ES256.alg,
751
+ hasher: import_crypto_nodejs.digest,
752
+ hashAlg: "sha-256",
753
+ saltGenerator: import_crypto_nodejs.generateSalt
754
+ });
755
+ this.instances.set(cacheKey, instance);
756
+ }
757
+ return this.instances.get(cacheKey);
758
+ }
759
+ /**
760
+ * Verify an SD-JWT with an external public key
761
+ * Use this when you have the issuer's public key but not their private key
762
+ *
763
+ * @param credential - The SD-JWT credential string
764
+ * @param publicKey - The issuer's public key (JWK format)
765
+ * @returns Verification result with valid flag and payload
766
+ *
767
+ * @example
768
+ * ```typescript
769
+ * const publicKey = extractPublicKeyFromDid(issuerDid)
770
+ * const result = await SDJwtClient.verifyWithExternalKey(credential, publicKey)
771
+ * if (result.valid) {
772
+ * console.log('Verified claims:', result.payload.claims)
773
+ * }
774
+ * ```
775
+ */
776
+ static async verifyWithExternalKey(credential, publicKey) {
777
+ try {
778
+ const sdJwtInstance = await this.getVerificationInstance(publicKey);
779
+ const verificationResult = await sdJwtInstance.verify(credential, {});
780
+ if (!verificationResult) {
781
+ return { valid: false, error: "Verification failed" };
782
+ }
783
+ const claims = await sdJwtInstance.getClaims(credential);
784
+ return {
785
+ valid: true,
786
+ payload: verificationResult.payload,
787
+ claims
788
+ };
789
+ } catch (error) {
790
+ return {
791
+ valid: false,
792
+ error: error.message
793
+ };
794
+ }
795
+ }
796
+ /**
797
+ * Verify an SD-JWT by extracting the issuer's public key from the DID
798
+ * Automatically resolves did:jwk DIDs
799
+ *
800
+ * @param credential - The SD-JWT credential string
801
+ * @returns Verification result with valid flag and payload
802
+ *
803
+ * @example
804
+ * ```typescript
805
+ * const result = await SDJwtClient.verifyWithIssuerDid(credential)
806
+ * if (result.valid) {
807
+ * console.log('Issuer:', result.payload.iss)
808
+ * }
809
+ * ```
810
+ */
811
+ static async verifyWithIssuerDid(credential) {
812
+ try {
813
+ const decoded = await this.decodeWithoutVerification(credential);
814
+ if (!decoded.payload) {
815
+ return { valid: false, error: "Failed to decode credential" };
816
+ }
817
+ const issuerDid = decoded.payload.iss || decoded.payload.issuer;
818
+ if (!issuerDid || typeof issuerDid !== "string") {
819
+ return { valid: false, error: "Issuer DID not found in credential" };
820
+ }
821
+ const publicKey = extractPublicKeyFromDid(issuerDid);
822
+ const result = await this.verifyWithExternalKey(credential, publicKey);
823
+ return {
824
+ ...result,
825
+ issuerDid
826
+ };
827
+ } catch (error) {
828
+ return {
829
+ valid: false,
830
+ error: error.message
831
+ };
832
+ }
833
+ }
834
+ /**
835
+ * Decode an SD-JWT without verification
836
+ * Use this when you need to inspect the credential before verification
837
+ * or when you don't have the issuer's public key
838
+ *
839
+ * WARNING: The returned payload has not been verified!
840
+ * Only use this for inspection purposes, not for authorization decisions.
841
+ *
842
+ * @param credential - The SD-JWT credential string
843
+ * @returns Decoded JWT payload, header, and disclosures
844
+ *
845
+ * @example
846
+ * ```typescript
847
+ * const decoded = await SDJwtClient.decodeWithoutVerification(credential)
848
+ * console.log('Issuer (unverified):', decoded.payload?.iss)
849
+ * console.log('Disclosures:', decoded.disclosures?.length)
850
+ * ```
851
+ */
852
+ static async decodeWithoutVerification(credential) {
853
+ try {
854
+ const sdJwtInstance = await this.getDecodingInstance();
855
+ const decoded = await sdJwtInstance.decode(credential);
856
+ if (!decoded || !decoded.jwt) {
857
+ return { error: "Failed to decode SD-JWT" };
858
+ }
859
+ const claims = await decoded.getClaims(import_crypto_nodejs.digest);
860
+ return {
861
+ payload: decoded.jwt.payload,
862
+ header: decoded.jwt.header,
863
+ disclosures: decoded.disclosures,
864
+ claims
865
+ };
866
+ } catch (error) {
867
+ return { error: error.message };
868
+ }
869
+ }
870
+ /**
871
+ * Extract issuer DID from an SD-JWT without verification
872
+ * Useful for determining the issuer before verification
873
+ *
874
+ * @param credential - The SD-JWT credential string
875
+ * @returns The issuer DID or null if not found
876
+ */
877
+ static extractIssuerDid(credential) {
878
+ try {
879
+ const parts = credential.split("~");
880
+ if (parts.length === 0) return null;
881
+ const jwt = parts[0];
882
+ const jwtParts = jwt.split(".");
883
+ if (jwtParts.length !== 3) return null;
884
+ const payload = JSON.parse(Buffer.from(jwtParts[1], "base64url").toString());
885
+ return payload.iss || payload.issuer || null;
886
+ } catch {
887
+ return null;
888
+ }
889
+ }
635
890
  };
636
891
 
637
892
  // src/agent/agent-did-manager.ts
@@ -647,7 +902,7 @@ var AgentDIDManager = class {
647
902
  */
648
903
  async generateAgentDID(agentId) {
649
904
  const keyPair = await SDJwtClient.generateKeyPair();
650
- const did = this.createDidJwk(keyPair.publicKey);
905
+ const did = createDidJwk(keyPair.publicKey);
651
906
  await this.keyManager.storeKey(did, keyPair.privateKey);
652
907
  this.agentDIDMap.set(agentId, did);
653
908
  await this.saveAgentDIDMapping(agentId, did);
@@ -689,7 +944,7 @@ var AgentDIDManager = class {
689
944
  }
690
945
  return {
691
946
  privateKey,
692
- publicKey: this.extractPublicKey(privateKey)
947
+ publicKey: extractPublicKey(privateKey)
693
948
  };
694
949
  }
695
950
  /**
@@ -731,31 +986,6 @@ var AgentDIDManager = class {
731
986
  return [];
732
987
  }
733
988
  }
734
- /**
735
- * Create did:jwk from public key
736
- */
737
- createDidJwk(publicKey) {
738
- const publicJwk = {
739
- kty: publicKey.kty,
740
- crv: publicKey.crv,
741
- x: publicKey.x,
742
- y: publicKey.y,
743
- use: publicKey.use,
744
- alg: publicKey.alg
745
- };
746
- const encoded = Buffer.from(JSON.stringify(publicJwk)).toString("base64url");
747
- return `did:jwk:${encoded}`;
748
- }
749
- /**
750
- * Extract public key from private key
751
- */
752
- extractPublicKey(privateKey) {
753
- const { d, key_ops, ...publicKey } = privateKey;
754
- return {
755
- ...publicKey
756
- // Remove key_ops for public key
757
- };
758
- }
759
989
  /**
760
990
  * Save agent ID -> DID mapping to persistent storage
761
991
  */
@@ -972,7 +1202,7 @@ var UserIdentityManager = class {
972
1202
  */
973
1203
  async createUserDID() {
974
1204
  const keyPair = await SDJwtClient.generateKeyPair();
975
- const did = this.createDidJwk(keyPair.publicKey);
1205
+ const did = createDidJwk(keyPair.publicKey);
976
1206
  await this.keyManager.storeKey(did, keyPair.privateKey);
977
1207
  await this.saveUserDID(did);
978
1208
  this.currentUserDID = did;
@@ -989,7 +1219,7 @@ var UserIdentityManager = class {
989
1219
  }
990
1220
  return {
991
1221
  privateKey,
992
- publicKey: this.extractPublicKey(privateKey)
1222
+ publicKey: extractPublicKey(privateKey)
993
1223
  };
994
1224
  }
995
1225
  /**
@@ -1030,34 +1260,11 @@ var UserIdentityManager = class {
1030
1260
  await this.clearUserDID();
1031
1261
  return await this.createUserDID();
1032
1262
  }
1033
- /**
1034
- * Create did:jwk from public key
1035
- */
1036
- createDidJwk(publicKey) {
1037
- const publicJwk = {
1038
- kty: publicKey.kty,
1039
- crv: publicKey.crv,
1040
- x: publicKey.x,
1041
- y: publicKey.y,
1042
- use: publicKey.use,
1043
- alg: publicKey.alg
1044
- };
1045
- const encoded = Buffer.from(JSON.stringify(publicJwk)).toString("base64url");
1046
- return `did:jwk:${encoded}`;
1047
- }
1048
- /**
1049
- * Extract public key from private key
1050
- */
1051
- extractPublicKey(privateKey) {
1052
- const { d, key_ops, ...publicKey } = privateKey;
1053
- return publicKey;
1054
- }
1055
1263
  /**
1056
1264
  * Resolve did:jwk locally
1057
1265
  */
1058
1266
  resolveDidJwkLocally(did) {
1059
- const encoded = did.replace("did:jwk:", "");
1060
- const publicJwk = JSON.parse(Buffer.from(encoded, "base64url").toString());
1267
+ const publicJwk = extractPublicKeyFromDid(did);
1061
1268
  return this.createDidDocument(did, publicJwk);
1062
1269
  }
1063
1270
  /**
@@ -3028,7 +3235,7 @@ var MetricsManager = class {
3028
3235
  /**
3029
3236
  * End tracking an operation
3030
3237
  */
3031
- endOperation(operationId, success, error) {
3238
+ endOperation(_operationId, success, error) {
3032
3239
  const endTime = performance.now();
3033
3240
  const operation = this.operations[this.operations.length - 1];
3034
3241
  if (operation) {
@@ -4551,15 +4758,20 @@ var version = "0.0.1";
4551
4758
  checkPermissionWithVP,
4552
4759
  configure,
4553
4760
  createAjv,
4761
+ createDidJwk,
4554
4762
  defaultConstraintEvaluator,
4555
4763
  evaluateConstraints,
4764
+ extractPublicKey,
4765
+ extractPublicKeyFromDid,
4556
4766
  generateKeyPair,
4557
4767
  generateNonce,
4558
4768
  getClient,
4769
+ getKeyIdFromDid,
4559
4770
  getRequiredRelations,
4560
4771
  getRequiredScopes,
4561
4772
  indexActions,
4562
4773
  indexCapabilities,
4774
+ isValidDidJwk,
4563
4775
  loadActionRegistryFromFile,
4564
4776
  loadActionRegistryFromObject,
4565
4777
  planDelegationForVC,