UNPKG

anon-identity

Version:

Decentralized identity framework with DIDs, Verifiable Credentials, and privacy-preserving selective disclosure

371 lines 14.1 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); Object.defineProperty(exports, "__esModule", { value: true }); exports.IPFSStorageProvider = void 0; const uuid_1 = require("uuid"); class IPFSStorageProvider { constructor(config) { this.ipfsClient = null; this.localIndex = new Map(); // Maps IDs to IPFS CIDs this.localKeyStore = new Map(); // Keys are always stored locally if (!config.ipfs) { throw new Error('IPFS configuration is required'); } // Initialize IPFS client lazily to avoid import issues this.initializeIPFSClient(config.ipfs); } async initializeIPFSClient(ipfsConfig) { try { // Dynamic import to avoid ESM issues const { create } = await Promise.resolve().then(() => __importStar(require('kubo-rpc-client'))); this.ipfsClient = create({ host: ipfsConfig.host, port: ipfsConfig.port, protocol: ipfsConfig.protocol, }); } catch (error) { console.error('Failed to initialize Kubo RPC client:', error); throw new Error('Kubo RPC client initialization failed'); } } // Helper methods for IPFS operations async storeToIPFS(data) { if (!this.ipfsClient) { throw new Error('IPFS client not initialized'); } const jsonData = JSON.stringify(data); const result = await this.ipfsClient.add(jsonData); return result.cid.toString(); // Returns the IPFS CID } async retrieveFromIPFS(cid) { try { if (!this.ipfsClient) { throw new Error('IPFS client not initialized'); } const chunks = []; for await (const chunk of this.ipfsClient.cat(cid)) { chunks.push(chunk); } const data = Buffer.concat(chunks).toString('utf8'); return JSON.parse(data); } catch (error) { console.error('Error retrieving from IPFS:', error); return null; } } // DID Operations async storeDID(did, document) { const storedData = { type: 'did', data: document, metadata: { created: new Date().toISOString(), updated: new Date().toISOString(), version: '1.0', }, }; const cid = await this.storeToIPFS(storedData); this.localIndex.set(`did:${did}`, cid); } async resolveDID(did) { const cid = this.localIndex.get(`did:${did}`); if (!cid) return null; const storedData = await this.retrieveFromIPFS(cid); return storedData?.data || null; } async listDIDs(owner) { // Filter DIDs from local index const dids = []; for (const [key, _] of this.localIndex) { if (key.startsWith('did:')) { const did = key.substring(4); if (!owner) { dids.push(did); } else { // Need to retrieve and check ownership const document = await this.resolveDID(did); if (document?.verificationMethod?.some(vm => vm.controller === owner)) { dids.push(did); } } } } return dids; } // Credential Operations async storeCredential(credential) { const storedData = { type: 'credential', data: credential, metadata: { created: new Date().toISOString(), updated: new Date().toISOString(), version: '1.0', }, }; const cid = await this.storeToIPFS(storedData); this.localIndex.set(`credential:${credential.id}`, cid); // Also index by holder const holder = credential.credentialSubject.id; const holderKey = `holder:${holder}:credentials`; const holderCreds = this.localIndex.get(holderKey) || ''; const credIds = holderCreds ? holderCreds.split(',') : []; if (!credIds.includes(credential.id)) { credIds.push(credential.id); this.localIndex.set(holderKey, credIds.join(',')); } } async getCredential(id) { const cid = this.localIndex.get(`credential:${id}`); if (!cid) return null; const storedData = await this.retrieveFromIPFS(cid); return storedData?.data || null; } async listCredentials(holder) { const holderKey = `holder:${holder}:credentials`; const credIds = this.localIndex.get(holderKey)?.split(',') || []; const credentials = []; for (const credId of credIds) { if (credId) { const credential = await this.getCredential(credId); if (credential) { credentials.push(credential); } } } return credentials; } async deleteCredential(id) { const credential = await this.getCredential(id); if (credential) { // Remove from holder index const holder = credential.credentialSubject.id; const holderKey = `holder:${holder}:credentials`; const credIds = this.localIndex.get(holderKey)?.split(',') || []; const updatedIds = credIds.filter(cid => cid !== id); if (updatedIds.length > 0) { this.localIndex.set(holderKey, updatedIds.join(',')); } else { this.localIndex.delete(holderKey); } // Remove credential index this.localIndex.delete(`credential:${id}`); } } // Revocation Operations async publishRevocation(issuerDID, revocationList) { const storedData = { type: 'revocation', data: revocationList, metadata: { created: new Date().toISOString(), updated: new Date().toISOString(), version: '1.0', }, }; const cid = await this.storeToIPFS(storedData); this.localIndex.set(`revocation:${issuerDID}`, cid); } async checkRevocation(issuerDID, credentialId) { const revocationList = await this.getRevocationList(issuerDID); if (!revocationList) return false; return revocationList.revokedCredentialIds.includes(credentialId); } async getRevocationList(issuerDID) { const cid = this.localIndex.get(`revocation:${issuerDID}`); if (!cid) return null; const storedData = await this.retrieveFromIPFS(cid); return storedData?.data || null; } // Key Management (always local) async storeKeyPair(identifier, encryptedKeyPair) { this.localKeyStore.set(identifier, encryptedKeyPair); } async retrieveKeyPair(identifier) { return this.localKeyStore.get(identifier) || null; } async deleteKeyPair(identifier) { this.localKeyStore.delete(identifier); } // Schema Operations async registerSchema(schema) { const schemaId = schema.id || `schema:${(0, uuid_1.v4)()}`; const schemaWithId = { ...schema, id: schemaId }; const storedData = { type: 'schema', data: schemaWithId, metadata: { created: new Date().toISOString(), updated: new Date().toISOString(), version: '1.0', }, }; const cid = await this.storeToIPFS(storedData); this.localIndex.set(`schema:${schemaId}`, cid); // Index by issuer const issuerKey = `issuer:${schema.issuerDID}:schemas`; const issuerSchemas = this.localIndex.get(issuerKey) || ''; const schemaIds = issuerSchemas ? issuerSchemas.split(',') : []; if (!schemaIds.includes(schemaId)) { schemaIds.push(schemaId); this.localIndex.set(issuerKey, schemaIds.join(',')); } return schemaId; } async getSchema(schemaId) { const cid = this.localIndex.get(`schema:${schemaId}`); if (!cid) return null; const storedData = await this.retrieveFromIPFS(cid); return storedData?.data || null; } async listSchemas(issuerDID) { if (!issuerDID) { // List all schemas const schemas = []; for (const [key, cid] of this.localIndex) { if (key.startsWith('schema:')) { const storedData = await this.retrieveFromIPFS(cid); if (storedData?.data) { schemas.push(storedData.data); } } } return schemas; } // List schemas by issuer const issuerKey = `issuer:${issuerDID}:schemas`; const schemaIds = this.localIndex.get(issuerKey)?.split(',') || []; const schemas = []; for (const schemaId of schemaIds) { if (schemaId) { const schema = await this.getSchema(schemaId); if (schema) { schemas.push(schema); } } } return schemas; } // General operations async clear() { // Note: This doesn't remove data from IPFS (which is immutable) // It only clears the local index this.localIndex.clear(); this.localKeyStore.clear(); } // IPFS-specific methods async pin(cid) { if (!this.ipfsClient) { throw new Error('IPFS client not initialized'); } await this.ipfsClient.pin.add(cid); } async unpin(cid) { if (!this.ipfsClient) { throw new Error('IPFS client not initialized'); } await this.ipfsClient.pin.rm(cid); } async getStorageStats() { if (!this.ipfsClient) { throw new Error('IPFS client not initialized'); } const nodeInfo = await this.ipfsClient.id(); return { totalItems: this.localIndex.size, indexSize: JSON.stringify([...this.localIndex.entries()]).length, ipfsNodeInfo: nodeInfo, }; } // Phone Number Operations (not implemented for IPFS) async storePhoneNumber(userDID, phoneNumber) { throw new Error('Phone number storage not implemented for IPFS provider'); } async getPhoneNumber(userDID, phoneId) { throw new Error('Phone number storage not implemented for IPFS provider'); } async listPhoneNumbers(userDID) { throw new Error('Phone number storage not implemented for IPFS provider'); } async updatePhoneNumber(userDID, phoneId, phoneNumber) { throw new Error('Phone number storage not implemented for IPFS provider'); } async deletePhoneNumber(userDID, phoneId) { throw new Error('Phone number storage not implemented for IPFS provider'); } // Address Operations (not implemented for IPFS) async storeAddress(userDID, address) { throw new Error('Address storage not implemented for IPFS provider'); } async getAddress(userDID, addressId) { throw new Error('Address storage not implemented for IPFS provider'); } async listAddresses(userDID) { throw new Error('Address storage not implemented for IPFS provider'); } async updateAddress(userDID, addressId, address) { throw new Error('Address storage not implemented for IPFS provider'); } async deleteAddress(userDID, addressId) { throw new Error('Address storage not implemented for IPFS provider'); } // Email Address Operations (not implemented for IPFS) async storeEmailAddress(userDID, emailAddress) { throw new Error('Email address storage not implemented for IPFS provider'); } async getEmailAddress(userDID, emailId) { throw new Error('Email address storage not implemented for IPFS provider'); } async listEmailAddresses(userDID) { throw new Error('Email address storage not implemented for IPFS provider'); } async updateEmailAddress(userDID, emailId, emailAddress) { throw new Error('Email address storage not implemented for IPFS provider'); } async deleteEmailAddress(userDID, emailId) { throw new Error('Email address storage not implemented for IPFS provider'); } } exports.IPFSStorageProvider = IPFSStorageProvider; //# sourceMappingURL=ipfs-storage-provider.js.map