@synet/did
Version:
Secure, minimal, standards-compliant DID library for production environments. Supports did:key and did:web methods with strict validation and cryptographic security.
166 lines (158 loc) • 4.83 kB
JavaScript
;
/**
* DID Unit - Minimalistic DID generation unit
* Pure Unit Architecture - learns from any unit that can teach key capabilities.
*
* Design principles:
* - Pure Unit Architecture: uses teach/learn pattern only*
* - Dynamic capability checking with capableOf()
* - Minimal and flexible
*
* @author Synet Team
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.DID = void 0;
const unit_1 = require("@synet/unit");
const create_1 = require("./create");
const VERSION = '1.0.6';
/**
* DID Unit - Minimalistic DID generation using pure Unit Architecture
* Learns key capabilities through standard teach/learn pattern
*/
class DID extends unit_1.Unit {
constructor(props) {
// Create unit with proper ID for Unit 1.0.4 architecture
super(props);
}
/**
* Create DID unit with public key and key type
*/
static create(config) {
// Validate hex format
if (!DID.isHex(config.publicKeyHex)) {
throw new Error(`Invalid public key format: expected hex string, got ${typeof config.publicKeyHex}`);
}
const props = {
dna: (0, unit_1.createUnitSchema)({
id: "did",
version: VERSION,
}),
created: new Date(),
metadata: config.metadata || {},
publicKeyHex: config.publicKeyHex.toLowerCase(),
keyType: config.keyType
};
return new DID(props);
}
/**
* Generate DID based on options
*/
generate(options = {}) {
const { method = 'key', domain, path } = options;
if (method === 'key') {
return this.generateKey();
}
if (method === 'web') {
if (!domain) {
throw new Error('Domain is required for did:web');
}
return this.generateWeb(domain, path);
}
throw new Error(`Unsupported DID method: ${method}`);
}
/**
* Generate did:key from stored public key and key type
* Simple, deterministic operation - no learning required
*/
generateKey() {
return (0, create_1.createDIDKey)(this.props.publicKeyHex, this.props.keyType);
}
/**
* Generate did:web
* Uses exceptions for error handling (simple operation pattern)
*/
generateWeb(domain, path) {
if (!domain) {
throw new Error('Domain is required for did:web');
}
return (0, create_1.createDIDWeb)(domain, path);
}
/**
* Validate if string is valid hex format
*/
static isHex(str) {
if (!str || typeof str !== 'string') {
return false;
}
const trimmed = str.trim();
// Check if it's a valid hex string (only hex characters, even length)
return /^[0-9a-fA-F]+$/.test(trimmed) && trimmed.length % 2 === 0;
}
// Unit implementation
whoami() {
return `DID Unit v${this.props.dna.version} - Key: ${this.props.keyType}, Hex: ${this.props.publicKeyHex.substring(0, 8)}...`;
}
capabilities() {
return ['generate', 'generateKey', 'generateWeb', 'canGenerateKey'];
}
help() {
console.log(`
DID Unit - Minimalistic DID Generation
I am: ${this.whoami()}
Params:
- PublicKeyHex
- KeyType
Core Capabilities:
- generate(options): Generate DID (key or web method)
- generateKey(): Generate did:key from learned capabilities
- generateWeb(domain, path?): Generate did:web
- canGenerateKey(): Check if ready to generate did:key
- toJSON(): Export unit information
Learning Pattern:
To generate did:key, this unit needs to learn from a key unit:
const signer = Signer.generate('ed25519');
const key = signer.createKey();
const didUnit = DID.create(
{
publicKeyHex: key.publicKeyHex,
keyType: key.keyType
}
);
// Now generate did:key
const did = didUnit.generate({ method: 'key' });
`);
}
teach() {
return {
unitId: this.props.dna.id,
capabilities: {
generate: (...args) => this.generate(args[0]),
generateKey: () => this.generateKey(),
generateWeb: (...args) => this.generateWeb(args[0], args[1]),
}
};
}
toJSON() {
return {
id: this.props.dna.id,
publicKeyHex: this.props.publicKeyHex,
keyType: this.props.keyType,
dna: this.props.dna,
metadata: this.props.metadata,
};
}
// Getters
get id() {
return this.props.dna.id;
}
get metadata() {
return { ...this.props.metadata };
}
get publicKeyHex() {
return this.props.publicKeyHex;
}
get keyType() {
return this.props.keyType;
}
}
exports.DID = DID;