@swimmingkiim/trust-sdk 0.1.32 → 0.2.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/credentials/vc-handler.service.d.ts +20 -6
- package/dist/credentials/vc-handler.service.d.ts.map +1 -1
- package/dist/credentials/vc-handler.service.js +58 -34
- package/dist/credentials/vc-handler.service.js.map +1 -1
- package/dist/identity/did-manager.d.ts +28 -3
- package/dist/identity/did-manager.d.ts.map +1 -1
- package/dist/identity/did-manager.js +105 -16
- package/dist/identity/did-manager.js.map +1 -1
- package/dist/index.d.ts +5 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -17
- package/dist/index.js.map +1 -1
- package/dist/resolver.d.ts +13 -0
- package/dist/resolver.d.ts.map +1 -0
- package/dist/resolver.js +21 -0
- package/dist/resolver.js.map +1 -0
- package/package.json +7 -19
- package/src/credentials/vc-handler.service.ts +65 -38
- package/src/identity/did-manager.ts +131 -17
- package/src/index.ts +5 -3
- package/src/resolver.ts +26 -0
- package/test/identity.security.test.ts +44 -54
- package/test/identity.test.ts +59 -47
- package/test/stateless.test.ts +133 -0
- package/tsconfig.tsbuildinfo +1 -1
- package/src/agent.ts +0 -99
|
@@ -1,10 +1,24 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { Resolver } from 'did-resolver';
|
|
2
|
+
import type { EphemeralIdentity } from '../identity/did-manager';
|
|
3
3
|
export declare class VCHandler {
|
|
4
|
-
private
|
|
5
|
-
constructor(
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
private resolver;
|
|
5
|
+
constructor(resolver?: Resolver);
|
|
6
|
+
/**
|
|
7
|
+
* Creates a Verifiable Credential as a JWT string.
|
|
8
|
+
* Stateless: signs in-memory, no DB storage.
|
|
9
|
+
*
|
|
10
|
+
* @param issuerDid - DID of the issuer
|
|
11
|
+
* @param subjectDid - DID of the subject
|
|
12
|
+
* @param claims - Claims to include in the credential
|
|
13
|
+
* @param keyPair - Signing key pair (from IdentityManager.createEphemeralDID())
|
|
14
|
+
* @returns JWT string
|
|
15
|
+
*/
|
|
16
|
+
createCredential(issuerDid: string, subjectDid: string, claims: Record<string, any>, keyPair?: EphemeralIdentity['keyPair']): Promise<string>;
|
|
17
|
+
/**
|
|
18
|
+
* Verifies a Verifiable Credential JWT.
|
|
19
|
+
* Stateless: resolves issuer DID via blockchain/derivation/web,
|
|
20
|
+
* then verifies the JWT signature. No DB required.
|
|
21
|
+
*/
|
|
8
22
|
verifyCredential(vcJwt: string): Promise<boolean>;
|
|
9
23
|
}
|
|
10
24
|
//# sourceMappingURL=vc-handler.service.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vc-handler.service.d.ts","sourceRoot":"","sources":["../../src/credentials/vc-handler.service.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"vc-handler.service.d.ts","sourceRoot":"","sources":["../../src/credentials/vc-handler.service.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAA;AAEvC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAA;AAEhE,qBAAa,SAAS;IAClB,OAAO,CAAC,QAAQ,CAAU;gBAEd,QAAQ,CAAC,EAAE,QAAQ;IAI/B;;;;;;;;;OASG;IACG,gBAAgB,CAClB,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC3B,OAAO,CAAC,EAAE,iBAAiB,CAAC,SAAS,CAAC,GACvC,OAAO,CAAC,MAAM,CAAC;IA6BlB;;;;OAIG;IACG,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;CAwB1D"}
|
|
@@ -1,50 +1,74 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.VCHandler = void 0;
|
|
4
|
-
const
|
|
4
|
+
const did_jwt_vc_1 = require("did-jwt-vc");
|
|
5
|
+
const did_jwt_1 = require("did-jwt");
|
|
6
|
+
const resolver_1 = require("../resolver");
|
|
5
7
|
class VCHandler {
|
|
6
|
-
|
|
7
|
-
constructor(
|
|
8
|
-
this.
|
|
8
|
+
resolver;
|
|
9
|
+
constructor(resolver) {
|
|
10
|
+
this.resolver = resolver ?? (0, resolver_1.createResolver)();
|
|
9
11
|
}
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
12
|
+
/**
|
|
13
|
+
* Creates a Verifiable Credential as a JWT string.
|
|
14
|
+
* Stateless: signs in-memory, no DB storage.
|
|
15
|
+
*
|
|
16
|
+
* @param issuerDid - DID of the issuer
|
|
17
|
+
* @param subjectDid - DID of the subject
|
|
18
|
+
* @param claims - Claims to include in the credential
|
|
19
|
+
* @param keyPair - Signing key pair (from IdentityManager.createEphemeralDID())
|
|
20
|
+
* @returns JWT string
|
|
21
|
+
*/
|
|
22
|
+
async createCredential(issuerDid, subjectDid, claims, keyPair) {
|
|
23
|
+
if (!keyPair) {
|
|
24
|
+
throw new Error('keyPair is required for credential issuance. Use IdentityManager.createEphemeralDID() to generate one.');
|
|
25
|
+
}
|
|
26
|
+
const signer = (0, did_jwt_1.EdDSASigner)(keyPair.secretKey);
|
|
27
|
+
const vcPayload = {
|
|
28
|
+
sub: subjectDid,
|
|
29
|
+
nbf: Math.floor(Date.now() / 1000),
|
|
30
|
+
vc: {
|
|
31
|
+
'@context': ['https://www.w3.org/2018/credentials/v1'],
|
|
32
|
+
type: ['VerifiableCredential'],
|
|
20
33
|
credentialSubject: {
|
|
21
34
|
id: subjectDid,
|
|
22
|
-
...claims
|
|
23
|
-
}
|
|
35
|
+
...claims,
|
|
36
|
+
},
|
|
24
37
|
},
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
38
|
+
};
|
|
39
|
+
const issuer = {
|
|
40
|
+
did: issuerDid,
|
|
41
|
+
signer,
|
|
42
|
+
alg: 'EdDSA',
|
|
43
|
+
};
|
|
44
|
+
return await (0, did_jwt_vc_1.createVerifiableCredentialJwt)(vcPayload, issuer);
|
|
29
45
|
}
|
|
46
|
+
/**
|
|
47
|
+
* Verifies a Verifiable Credential JWT.
|
|
48
|
+
* Stateless: resolves issuer DID via blockchain/derivation/web,
|
|
49
|
+
* then verifies the JWT signature. No DB required.
|
|
50
|
+
*/
|
|
30
51
|
async verifyCredential(vcJwt) {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
if (!result.verified) {
|
|
36
|
-
console.error('Credential verification failed:', result.error);
|
|
37
|
-
return false;
|
|
38
|
-
}
|
|
39
|
-
// Explicit expiration check
|
|
40
|
-
if (result.verifiableCredential && result.verifiableCredential.expirationDate) {
|
|
41
|
-
const expirationDate = new Date(result.verifiableCredential.expirationDate);
|
|
42
|
-
if (expirationDate < new Date()) {
|
|
43
|
-
console.error(`Credential expired on ${expirationDate.toISOString()}`);
|
|
52
|
+
try {
|
|
53
|
+
const result = await (0, did_jwt_vc_1.verifyCredential)(vcJwt, this.resolver);
|
|
54
|
+
if (!result.verified) {
|
|
55
|
+
console.error('Credential verification failed:', result);
|
|
44
56
|
return false;
|
|
45
57
|
}
|
|
58
|
+
// Explicit expiration check
|
|
59
|
+
if (result.verifiableCredential?.expirationDate) {
|
|
60
|
+
const expirationDate = new Date(result.verifiableCredential.expirationDate);
|
|
61
|
+
if (expirationDate < new Date()) {
|
|
62
|
+
console.error(`Credential expired on ${expirationDate.toISOString()}`);
|
|
63
|
+
return false;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return true;
|
|
67
|
+
}
|
|
68
|
+
catch (error) {
|
|
69
|
+
console.error('VC verification error:', error);
|
|
70
|
+
return false;
|
|
46
71
|
}
|
|
47
|
-
return result.verified;
|
|
48
72
|
}
|
|
49
73
|
}
|
|
50
74
|
exports.VCHandler = VCHandler;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vc-handler.service.js","sourceRoot":"","sources":["../../src/credentials/vc-handler.service.ts"],"names":[],"mappings":";;;AAAA,
|
|
1
|
+
{"version":3,"file":"vc-handler.service.js","sourceRoot":"","sources":["../../src/credentials/vc-handler.service.ts"],"names":[],"mappings":";;;AAAA,2CAAwF;AACxF,qCAAqC;AAErC,0CAA4C;AAG5C,MAAa,SAAS;IACV,QAAQ,CAAU;IAE1B,YAAY,QAAmB;QAC3B,IAAI,CAAC,QAAQ,GAAG,QAAQ,IAAI,IAAA,yBAAc,GAAE,CAAA;IAChD,CAAC;IAED;;;;;;;;;OASG;IACH,KAAK,CAAC,gBAAgB,CAClB,SAAiB,EACjB,UAAkB,EAClB,MAA2B,EAC3B,OAAsC;QAEtC,IAAI,CAAC,OAAO,EAAE,CAAC;YACX,MAAM,IAAI,KAAK,CAAC,wGAAwG,CAAC,CAAA;QAC7H,CAAC;QAED,MAAM,MAAM,GAAG,IAAA,qBAAW,EAAC,OAAO,CAAC,SAAS,CAAC,CAAA;QAE7C,MAAM,SAAS,GAAG;YACd,GAAG,EAAE,UAAU;YACf,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;YAClC,EAAE,EAAE;gBACA,UAAU,EAAE,CAAC,wCAAwC,CAAC;gBACtD,IAAI,EAAE,CAAC,sBAAsB,CAAC;gBAC9B,iBAAiB,EAAE;oBACf,EAAE,EAAE,UAAU;oBACd,GAAG,MAAM;iBACZ;aACJ;SACJ,CAAA;QAED,MAAM,MAAM,GAAG;YACX,GAAG,EAAE,SAAS;YACd,MAAM;YACN,GAAG,EAAE,OAAgB;SACxB,CAAA;QAED,OAAO,MAAM,IAAA,0CAA6B,EAAC,SAAS,EAAE,MAAM,CAAC,CAAA;IACjE,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,gBAAgB,CAAC,KAAa;QAChC,IAAI,CAAC;YACD,MAAM,MAAM,GAAG,MAAM,IAAA,6BAAQ,EAAC,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAA;YAEnD,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;gBACnB,OAAO,CAAC,KAAK,CAAC,iCAAiC,EAAE,MAAM,CAAC,CAAA;gBACxD,OAAO,KAAK,CAAA;YAChB,CAAC;YAED,4BAA4B;YAC5B,IAAI,MAAM,CAAC,oBAAoB,EAAE,cAAc,EAAE,CAAC;gBAC9C,MAAM,cAAc,GAAG,IAAI,IAAI,CAAC,MAAM,CAAC,oBAAoB,CAAC,cAAc,CAAC,CAAA;gBAC3E,IAAI,cAAc,GAAG,IAAI,IAAI,EAAE,EAAE,CAAC;oBAC9B,OAAO,CAAC,KAAK,CAAC,yBAAyB,cAAc,CAAC,WAAW,EAAE,EAAE,CAAC,CAAA;oBACtE,OAAO,KAAK,CAAA;gBAChB,CAAC;YACL,CAAC;YAED,OAAO,IAAI,CAAA;QACf,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,wBAAwB,EAAE,KAAK,CAAC,CAAA;YAC9C,OAAO,KAAK,CAAA;QAChB,CAAC;IACL,CAAC;CACJ;AAhFD,8BAgFC"}
|
|
@@ -1,6 +1,31 @@
|
|
|
1
|
+
import { Resolver } from 'did-resolver';
|
|
2
|
+
export interface EphemeralIdentity {
|
|
3
|
+
did: string;
|
|
4
|
+
keyPair: {
|
|
5
|
+
publicKey: Uint8Array;
|
|
6
|
+
secretKey: Uint8Array;
|
|
7
|
+
};
|
|
8
|
+
}
|
|
1
9
|
export declare class IdentityManager {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
10
|
+
private resolver;
|
|
11
|
+
constructor(resolver?: Resolver);
|
|
12
|
+
/**
|
|
13
|
+
* Creates an ephemeral (in-memory) did:key identity.
|
|
14
|
+
* Uses Node.js built-in crypto — no external dependencies, no database.
|
|
15
|
+
*/
|
|
16
|
+
createEphemeralDID(): Promise<EphemeralIdentity>;
|
|
17
|
+
/**
|
|
18
|
+
* Resolves a DID to its DID Document.
|
|
19
|
+
* Stateless: uses blockchain (did:ethr) or derivation (did:key).
|
|
20
|
+
*/
|
|
21
|
+
resolveDID(did: string): Promise<any>;
|
|
22
|
+
/**
|
|
23
|
+
* Imports an existing Ed25519 secret key and derives the DID.
|
|
24
|
+
* Use this when you already have a fixed key (e.g., from did_keys.json).
|
|
25
|
+
*
|
|
26
|
+
* @param secretKey - 32-byte Ed25519 secret key as hex string or Uint8Array
|
|
27
|
+
* @returns EphemeralIdentity with the derived DID and key pair
|
|
28
|
+
*/
|
|
29
|
+
fromSecretKey(secretKey: string | Uint8Array): Promise<EphemeralIdentity>;
|
|
5
30
|
}
|
|
6
31
|
//# sourceMappingURL=did-manager.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"did-manager.d.ts","sourceRoot":"","sources":["../../src/identity/did-manager.ts"],"names":[],"mappings":"AAEA,qBAAa,eAAe;
|
|
1
|
+
{"version":3,"file":"did-manager.d.ts","sourceRoot":"","sources":["../../src/identity/did-manager.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAA;AAEvC,MAAM,WAAW,iBAAiB;IAC9B,GAAG,EAAE,MAAM,CAAA;IACX,OAAO,EAAE;QACL,SAAS,EAAE,UAAU,CAAA;QACrB,SAAS,EAAE,UAAU,CAAA;KACxB,CAAA;CACJ;AAgDD,qBAAa,eAAe;IACxB,OAAO,CAAC,QAAQ,CAAU;gBAEd,QAAQ,CAAC,EAAE,QAAQ;IAI/B;;;OAGG;IACG,kBAAkB,IAAI,OAAO,CAAC,iBAAiB,CAAC;IAoBtD;;;OAGG;IACG,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC;IAI3C;;;;;;OAMG;IACG,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,UAAU,GAAG,OAAO,CAAC,iBAAiB,CAAC;CAkClF"}
|
|
@@ -1,26 +1,115 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
6
|
exports.IdentityManager = void 0;
|
|
4
|
-
const
|
|
7
|
+
const crypto_1 = __importDefault(require("crypto"));
|
|
8
|
+
const resolver_1 = require("../resolver");
|
|
9
|
+
// Ed25519 multicodec prefix (0xed01)
|
|
10
|
+
const ED25519_MULTICODEC_PREFIX = new Uint8Array([0xed, 0x01]);
|
|
11
|
+
// Base58btc alphabet (Bitcoin alphabet)
|
|
12
|
+
const BASE58_ALPHABET = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz';
|
|
13
|
+
/**
|
|
14
|
+
* Encodes a Uint8Array to base58btc string.
|
|
15
|
+
* Pure implementation with no external dependencies.
|
|
16
|
+
*/
|
|
17
|
+
function base58btcEncode(bytes) {
|
|
18
|
+
// Count leading zeros
|
|
19
|
+
let leadingZeros = 0;
|
|
20
|
+
for (let i = 0; i < bytes.length && bytes[i] === 0; i++) {
|
|
21
|
+
leadingZeros++;
|
|
22
|
+
}
|
|
23
|
+
// Convert to BigInt for base conversion
|
|
24
|
+
let num = BigInt('0x' + Buffer.from(bytes).toString('hex'));
|
|
25
|
+
const chars = [];
|
|
26
|
+
while (num > 0n) {
|
|
27
|
+
const remainder = Number(num % 58n);
|
|
28
|
+
chars.unshift(BASE58_ALPHABET[remainder]);
|
|
29
|
+
num = num / 58n;
|
|
30
|
+
}
|
|
31
|
+
// Add '1' for each leading zero byte
|
|
32
|
+
for (let i = 0; i < leadingZeros; i++) {
|
|
33
|
+
chars.unshift('1');
|
|
34
|
+
}
|
|
35
|
+
return chars.join('');
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Encodes an Ed25519 public key as a did:key identifier.
|
|
39
|
+
* Format: did:key:z + base58btc(multicodec_prefix + public_key)
|
|
40
|
+
*/
|
|
41
|
+
function publicKeyToDidKey(publicKey) {
|
|
42
|
+
const multicodecKey = new Uint8Array(ED25519_MULTICODEC_PREFIX.length + publicKey.length);
|
|
43
|
+
multicodecKey.set(ED25519_MULTICODEC_PREFIX);
|
|
44
|
+
multicodecKey.set(publicKey, ED25519_MULTICODEC_PREFIX.length);
|
|
45
|
+
return `did:key:z${base58btcEncode(multicodecKey)}`;
|
|
46
|
+
}
|
|
5
47
|
class IdentityManager {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
provider: 'did:key'
|
|
10
|
-
});
|
|
11
|
-
return identifier;
|
|
48
|
+
resolver;
|
|
49
|
+
constructor(resolver) {
|
|
50
|
+
this.resolver = resolver ?? (0, resolver_1.createResolver)();
|
|
12
51
|
}
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
});
|
|
19
|
-
|
|
52
|
+
/**
|
|
53
|
+
* Creates an ephemeral (in-memory) did:key identity.
|
|
54
|
+
* Uses Node.js built-in crypto — no external dependencies, no database.
|
|
55
|
+
*/
|
|
56
|
+
async createEphemeralDID() {
|
|
57
|
+
const { publicKey, privateKey } = crypto_1.default.generateKeyPairSync('ed25519');
|
|
58
|
+
// Export raw key bytes from DER format
|
|
59
|
+
const pubDer = publicKey.export({ type: 'spki', format: 'der' });
|
|
60
|
+
const privDer = privateKey.export({ type: 'pkcs8', format: 'der' });
|
|
61
|
+
// Ed25519 SPKI DER: 12-byte header + 32-byte key
|
|
62
|
+
const rawPublicKey = new Uint8Array(pubDer.subarray(pubDer.length - 32));
|
|
63
|
+
// Ed25519 PKCS8 DER: 16-byte header + 32-byte key
|
|
64
|
+
const rawSecretKey = new Uint8Array(privDer.subarray(privDer.length - 32));
|
|
65
|
+
const did = publicKeyToDidKey(rawPublicKey);
|
|
66
|
+
return {
|
|
67
|
+
did,
|
|
68
|
+
keyPair: { publicKey: rawPublicKey, secretKey: rawSecretKey },
|
|
69
|
+
};
|
|
20
70
|
}
|
|
71
|
+
/**
|
|
72
|
+
* Resolves a DID to its DID Document.
|
|
73
|
+
* Stateless: uses blockchain (did:ethr) or derivation (did:key).
|
|
74
|
+
*/
|
|
21
75
|
async resolveDID(did) {
|
|
22
|
-
|
|
23
|
-
|
|
76
|
+
return await this.resolver.resolve(did);
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Imports an existing Ed25519 secret key and derives the DID.
|
|
80
|
+
* Use this when you already have a fixed key (e.g., from did_keys.json).
|
|
81
|
+
*
|
|
82
|
+
* @param secretKey - 32-byte Ed25519 secret key as hex string or Uint8Array
|
|
83
|
+
* @returns EphemeralIdentity with the derived DID and key pair
|
|
84
|
+
*/
|
|
85
|
+
async fromSecretKey(secretKey) {
|
|
86
|
+
const rawSecretKey = typeof secretKey === 'string'
|
|
87
|
+
? new Uint8Array(Buffer.from(secretKey.replace(/^0x/, ''), 'hex'))
|
|
88
|
+
: secretKey;
|
|
89
|
+
if (rawSecretKey.length !== 32) {
|
|
90
|
+
throw new Error(`Invalid Ed25519 secret key length: expected 32 bytes, got ${rawSecretKey.length}`);
|
|
91
|
+
}
|
|
92
|
+
// Reconstruct Node.js KeyObject from raw bytes
|
|
93
|
+
// Ed25519 PKCS8 DER = fixed 16-byte header + 32-byte raw key
|
|
94
|
+
const pkcs8Header = Buffer.from([
|
|
95
|
+
0x30, 0x2e, 0x02, 0x01, 0x00, 0x30, 0x05, 0x06,
|
|
96
|
+
0x03, 0x2b, 0x65, 0x70, 0x04, 0x22, 0x04, 0x20,
|
|
97
|
+
]);
|
|
98
|
+
const pkcs8Der = Buffer.concat([pkcs8Header, Buffer.from(rawSecretKey)]);
|
|
99
|
+
const privateKeyObject = crypto_1.default.createPrivateKey({
|
|
100
|
+
key: pkcs8Der,
|
|
101
|
+
format: 'der',
|
|
102
|
+
type: 'pkcs8',
|
|
103
|
+
});
|
|
104
|
+
// Derive public key
|
|
105
|
+
const publicKeyObject = crypto_1.default.createPublicKey(privateKeyObject);
|
|
106
|
+
const pubDer = publicKeyObject.export({ type: 'spki', format: 'der' });
|
|
107
|
+
const rawPublicKey = new Uint8Array(pubDer.subarray(pubDer.length - 32));
|
|
108
|
+
const did = publicKeyToDidKey(rawPublicKey);
|
|
109
|
+
return {
|
|
110
|
+
did,
|
|
111
|
+
keyPair: { publicKey: rawPublicKey, secretKey: rawSecretKey },
|
|
112
|
+
};
|
|
24
113
|
}
|
|
25
114
|
}
|
|
26
115
|
exports.IdentityManager = IdentityManager;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"did-manager.js","sourceRoot":"","sources":["../../src/identity/did-manager.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"did-manager.js","sourceRoot":"","sources":["../../src/identity/did-manager.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
export
|
|
2
|
-
export
|
|
3
|
-
export
|
|
1
|
+
export { IdentityManager } from './identity/did-manager';
|
|
2
|
+
export type { EphemeralIdentity } from './identity/did-manager';
|
|
3
|
+
export { VCHandler } from './credentials/vc-handler.service';
|
|
4
|
+
export { createResolver } from './resolver';
|
|
5
|
+
export type { ResolverOptions } from './resolver';
|
|
4
6
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA;AACxD,YAAY,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAA;AAC/D,OAAO,EAAE,SAAS,EAAE,MAAM,kCAAkC,CAAA;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAC3C,YAAY,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -1,20 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
-
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
-
};
|
|
16
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
3
|
+
exports.createResolver = exports.VCHandler = exports.IdentityManager = void 0;
|
|
4
|
+
var did_manager_1 = require("./identity/did-manager");
|
|
5
|
+
Object.defineProperty(exports, "IdentityManager", { enumerable: true, get: function () { return did_manager_1.IdentityManager; } });
|
|
6
|
+
var vc_handler_service_1 = require("./credentials/vc-handler.service");
|
|
7
|
+
Object.defineProperty(exports, "VCHandler", { enumerable: true, get: function () { return vc_handler_service_1.VCHandler; } });
|
|
8
|
+
var resolver_1 = require("./resolver");
|
|
9
|
+
Object.defineProperty(exports, "createResolver", { enumerable: true, get: function () { return resolver_1.createResolver; } });
|
|
20
10
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,sDAAwD;AAA/C,8GAAA,eAAe,OAAA;AAExB,uEAA4D;AAAnD,+GAAA,SAAS,OAAA;AAClB,uCAA2C;AAAlC,0GAAA,cAAc,OAAA"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Resolver } from 'did-resolver';
|
|
2
|
+
export interface ResolverOptions {
|
|
3
|
+
/** Ethereum network name for did:ethr (default: 'base') */
|
|
4
|
+
ethNetwork?: string;
|
|
5
|
+
/** RPC URL for did:ethr resolution */
|
|
6
|
+
rpcUrl?: string;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Creates a stateless DID Resolver.
|
|
10
|
+
* No database, no state — only blockchain/key-based resolution.
|
|
11
|
+
*/
|
|
12
|
+
export declare function createResolver(options?: ResolverOptions): Resolver;
|
|
13
|
+
//# sourceMappingURL=resolver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolver.d.ts","sourceRoot":"","sources":["../src/resolver.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAA;AAIvC,MAAM,WAAW,eAAe;IAC5B,2DAA2D;IAC3D,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,sCAAsC;IACtC,MAAM,CAAC,EAAE,MAAM,CAAA;CAClB;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,OAAO,CAAC,EAAE,eAAe,GAAG,QAAQ,CAUlE"}
|
package/dist/resolver.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createResolver = createResolver;
|
|
4
|
+
const did_resolver_1 = require("did-resolver");
|
|
5
|
+
const key_did_resolver_1 = require("key-did-resolver");
|
|
6
|
+
const ethr_did_resolver_1 = require("ethr-did-resolver");
|
|
7
|
+
/**
|
|
8
|
+
* Creates a stateless DID Resolver.
|
|
9
|
+
* No database, no state — only blockchain/key-based resolution.
|
|
10
|
+
*/
|
|
11
|
+
function createResolver(options) {
|
|
12
|
+
const ethNetwork = options?.ethNetwork || 'base';
|
|
13
|
+
const rpcUrl = options?.rpcUrl || 'https://mainnet.base.org';
|
|
14
|
+
return new did_resolver_1.Resolver({
|
|
15
|
+
...(0, key_did_resolver_1.getResolver)(),
|
|
16
|
+
...(0, ethr_did_resolver_1.getResolver)({
|
|
17
|
+
networks: [{ name: ethNetwork, rpcUrl }],
|
|
18
|
+
}),
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=resolver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolver.js","sourceRoot":"","sources":["../src/resolver.ts"],"names":[],"mappings":";;AAeA,wCAUC;AAzBD,+CAAuC;AACvC,uDAAgE;AAChE,yDAAkE;AASlE;;;GAGG;AACH,SAAgB,cAAc,CAAC,OAAyB;IACpD,MAAM,UAAU,GAAG,OAAO,EAAE,UAAU,IAAI,MAAM,CAAA;IAChD,MAAM,MAAM,GAAG,OAAO,EAAE,MAAM,IAAI,0BAA0B,CAAA;IAE5D,OAAO,IAAI,uBAAQ,CAAC;QAChB,GAAG,IAAA,8BAAc,GAAE;QACnB,GAAG,IAAA,+BAAe,EAAC;YACf,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,CAAC;SAC3C,CAAC;KACL,CAAC,CAAA;AACN,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@swimmingkiim/trust-sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.2",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "git+https://github.com/swimmingkiim/a2a-project.git"
|
|
@@ -15,31 +15,19 @@
|
|
|
15
15
|
}
|
|
16
16
|
},
|
|
17
17
|
"dependencies": {
|
|
18
|
-
"
|
|
19
|
-
"
|
|
20
|
-
"@veramo/data-store": "^6.0.2",
|
|
21
|
-
"@veramo/did-manager": "^6.0.2",
|
|
22
|
-
"@veramo/did-provider-ethr": "^6.0.2",
|
|
23
|
-
"@veramo/did-provider-key": "^6.0.2",
|
|
24
|
-
"@veramo/did-resolver": "^6.0.2",
|
|
25
|
-
"@veramo/key-manager": "^6.0.2",
|
|
26
|
-
"@veramo/kms-local": "^6.0.2",
|
|
27
|
-
"did-jwt-vc": "^3.2.0",
|
|
18
|
+
"did-jwt": "^8.0.9",
|
|
19
|
+
"did-jwt-vc": "^4.0.8",
|
|
28
20
|
"did-resolver": "^4.1.0",
|
|
29
|
-
"ethers": "^6.11.1",
|
|
30
21
|
"ethr-did-resolver": "^11.0.5",
|
|
31
|
-
"key-did-resolver": "^4.0.0"
|
|
32
|
-
"reflect-metadata": "^0.2.2",
|
|
33
|
-
"sqlite3": "^5.1.7",
|
|
34
|
-
"ts-node": "^10.9.2",
|
|
35
|
-
"typeorm": "^0.3.28"
|
|
22
|
+
"key-did-resolver": "^4.0.0"
|
|
36
23
|
},
|
|
37
24
|
"devDependencies": {
|
|
38
25
|
"tsx": "^4.21.0",
|
|
39
|
-
"typescript": "^5.3.3"
|
|
26
|
+
"typescript": "^5.3.3",
|
|
27
|
+
"vitest": "^4.0.18"
|
|
40
28
|
},
|
|
41
29
|
"scripts": {
|
|
42
30
|
"build": "tsc",
|
|
43
|
-
"test": "
|
|
31
|
+
"test": "vitest run"
|
|
44
32
|
}
|
|
45
33
|
}
|
|
@@ -1,60 +1,87 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { createVerifiableCredentialJwt, verifyCredential as verifyVC } from 'did-jwt-vc'
|
|
2
|
+
import { EdDSASigner } from 'did-jwt'
|
|
3
|
+
import { Resolver } from 'did-resolver'
|
|
4
|
+
import { createResolver } from '../resolver'
|
|
5
|
+
import type { EphemeralIdentity } from '../identity/did-manager'
|
|
3
6
|
|
|
4
7
|
export class VCHandler {
|
|
5
|
-
private
|
|
8
|
+
private resolver: Resolver
|
|
6
9
|
|
|
7
|
-
constructor(
|
|
8
|
-
this.
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
private async getAgent(): Promise<Agent> {
|
|
12
|
-
if (this.agent) return this.agent
|
|
13
|
-
return await initAgent()
|
|
10
|
+
constructor(resolver?: Resolver) {
|
|
11
|
+
this.resolver = resolver ?? createResolver()
|
|
14
12
|
}
|
|
15
13
|
|
|
14
|
+
/**
|
|
15
|
+
* Creates a Verifiable Credential as a JWT string.
|
|
16
|
+
* Stateless: signs in-memory, no DB storage.
|
|
17
|
+
*
|
|
18
|
+
* @param issuerDid - DID of the issuer
|
|
19
|
+
* @param subjectDid - DID of the subject
|
|
20
|
+
* @param claims - Claims to include in the credential
|
|
21
|
+
* @param keyPair - Signing key pair (from IdentityManager.createEphemeralDID())
|
|
22
|
+
* @returns JWT string
|
|
23
|
+
*/
|
|
16
24
|
async createCredential(
|
|
17
25
|
issuerDid: string,
|
|
18
26
|
subjectDid: string,
|
|
19
|
-
claims: Record<string, any
|
|
20
|
-
|
|
21
|
-
|
|
27
|
+
claims: Record<string, any>,
|
|
28
|
+
keyPair?: EphemeralIdentity['keyPair']
|
|
29
|
+
): Promise<string> {
|
|
30
|
+
if (!keyPair) {
|
|
31
|
+
throw new Error('keyPair is required for credential issuance. Use IdentityManager.createEphemeralDID() to generate one.')
|
|
32
|
+
}
|
|
22
33
|
|
|
23
|
-
const
|
|
24
|
-
|
|
25
|
-
|
|
34
|
+
const signer = EdDSASigner(keyPair.secretKey)
|
|
35
|
+
|
|
36
|
+
const vcPayload = {
|
|
37
|
+
sub: subjectDid,
|
|
38
|
+
nbf: Math.floor(Date.now() / 1000),
|
|
39
|
+
vc: {
|
|
40
|
+
'@context': ['https://www.w3.org/2018/credentials/v1'],
|
|
41
|
+
type: ['VerifiableCredential'],
|
|
26
42
|
credentialSubject: {
|
|
27
43
|
id: subjectDid,
|
|
28
|
-
...claims
|
|
29
|
-
}
|
|
44
|
+
...claims,
|
|
45
|
+
},
|
|
30
46
|
},
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const issuer = {
|
|
50
|
+
did: issuerDid,
|
|
51
|
+
signer,
|
|
52
|
+
alg: 'EdDSA' as const,
|
|
53
|
+
}
|
|
34
54
|
|
|
35
|
-
return
|
|
55
|
+
return await createVerifiableCredentialJwt(vcPayload, issuer)
|
|
36
56
|
}
|
|
37
57
|
|
|
58
|
+
/**
|
|
59
|
+
* Verifies a Verifiable Credential JWT.
|
|
60
|
+
* Stateless: resolves issuer DID via blockchain/derivation/web,
|
|
61
|
+
* then verifies the JWT signature. No DB required.
|
|
62
|
+
*/
|
|
38
63
|
async verifyCredential(vcJwt: string): Promise<boolean> {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
credential: vcJwt
|
|
42
|
-
})
|
|
64
|
+
try {
|
|
65
|
+
const result = await verifyVC(vcJwt, this.resolver)
|
|
43
66
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
return false
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
// Explicit expiration check
|
|
50
|
-
if (result.verifiableCredential && result.verifiableCredential.expirationDate) {
|
|
51
|
-
const expirationDate = new Date(result.verifiableCredential.expirationDate)
|
|
52
|
-
if (expirationDate < new Date()) {
|
|
53
|
-
console.error(`Credential expired on ${expirationDate.toISOString()}`)
|
|
67
|
+
if (!result.verified) {
|
|
68
|
+
console.error('Credential verification failed:', result)
|
|
54
69
|
return false
|
|
55
70
|
}
|
|
56
|
-
}
|
|
57
71
|
|
|
58
|
-
|
|
72
|
+
// Explicit expiration check
|
|
73
|
+
if (result.verifiableCredential?.expirationDate) {
|
|
74
|
+
const expirationDate = new Date(result.verifiableCredential.expirationDate)
|
|
75
|
+
if (expirationDate < new Date()) {
|
|
76
|
+
console.error(`Credential expired on ${expirationDate.toISOString()}`)
|
|
77
|
+
return false
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
return true
|
|
82
|
+
} catch (error) {
|
|
83
|
+
console.error('VC verification error:', error)
|
|
84
|
+
return false
|
|
85
|
+
}
|
|
59
86
|
}
|
|
60
87
|
}
|