anon-identity
Version:
Decentralized identity framework with DIDs, Verifiable Credentials, and privacy-preserving selective disclosure
258 lines • 12.2 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ContractClient = void 0;
const ethers_1 = require("ethers");
// Import contract ABIs (these will be generated by Hardhat)
const DIDRegistry_json_1 = __importDefault(require("../../artifacts/contracts/DIDRegistry.sol/DIDRegistry.json"));
const RevocationRegistry_json_1 = __importDefault(require("../../artifacts/contracts/RevocationRegistry.sol/RevocationRegistry.json"));
const SchemaRegistry_json_1 = __importDefault(require("../../artifacts/contracts/SchemaRegistry.sol/SchemaRegistry.json"));
class ContractClient {
constructor(rpcUrlOrConfig, privateKey, contractAddresses) {
// Handle both constructor signatures
if (typeof rpcUrlOrConfig === 'string') {
// New signature: (rpcUrl, privateKey, contractAddresses)
this.provider = new ethers_1.ethers.JsonRpcProvider(rpcUrlOrConfig);
if (privateKey) {
this.signer = new ethers_1.ethers.Wallet(privateKey, this.provider);
}
if (!contractAddresses) {
throw new Error('Contract addresses required when using RPC URL constructor');
}
const signerOrProvider = this.signer || this.provider;
this.contracts = {
didRegistry: new ethers_1.ethers.Contract(contractAddresses.didRegistry, DIDRegistry_json_1.default.abi, signerOrProvider),
revocationRegistry: new ethers_1.ethers.Contract(contractAddresses.revocationRegistry, RevocationRegistry_json_1.default.abi, signerOrProvider),
schemaRegistry: new ethers_1.ethers.Contract(contractAddresses.schemaRegistry, SchemaRegistry_json_1.default.abi, signerOrProvider),
};
}
else {
// Original signature: (config)
const config = rpcUrlOrConfig;
this.provider = new ethers_1.ethers.JsonRpcProvider(config.rpcUrl);
if (config.privateKey) {
this.signer = new ethers_1.ethers.Wallet(config.privateKey, this.provider);
}
const signerOrProvider = this.signer || this.provider;
this.contracts = {
didRegistry: new ethers_1.ethers.Contract(config.contracts.didRegistry, DIDRegistry_json_1.default.abi, signerOrProvider),
revocationRegistry: new ethers_1.ethers.Contract(config.contracts.revocationRegistry, RevocationRegistry_json_1.default.abi, signerOrProvider),
schemaRegistry: new ethers_1.ethers.Contract(config.contracts.schemaRegistry, SchemaRegistry_json_1.default.abi, signerOrProvider),
};
}
}
// DID Registry methods
async registerDID(did, publicKey, documentHash = '') {
if (!this.signer) {
throw new Error('Signer required for write operations');
}
return await this.contracts.didRegistry.registerDID(did, publicKey, documentHash);
}
async updateDID(did, newPublicKey, documentHash = '') {
if (!this.signer) {
throw new Error('Signer required for write operations');
}
return await this.contracts.didRegistry.updateDID(did, newPublicKey, documentHash);
}
async deactivateDID(did) {
if (!this.signer) {
throw new Error('Signer required for write operations');
}
return await this.contracts.didRegistry.deactivateDID(did);
}
async transferDID(did, newOwner) {
if (!this.signer) {
throw new Error('Signer required for write operations');
}
return await this.contracts.didRegistry.transferDID(did, newOwner);
}
async resolveDID(did) {
return await this.contracts.didRegistry.resolveDID(did);
}
async didExists(did) {
return await this.contracts.didRegistry.didExists(did);
}
async getDIDsByOwner(owner) {
return await this.contracts.didRegistry.getDIDsByOwner(owner);
}
// Revocation Registry methods
async authorizeIssuer(issuerDID) {
if (!this.signer) {
throw new Error('Signer required for write operations');
}
return await this.contracts.revocationRegistry.authorizeIssuer(issuerDID);
}
async deauthorizeIssuer(issuerDID) {
if (!this.signer) {
throw new Error('Signer required for write operations');
}
return await this.contracts.revocationRegistry.deauthorizeIssuer(issuerDID);
}
async publishRevocationList(issuerDID, credentialHashes, signature, merkleRoot = ethers_1.ethers.ZeroHash) {
if (!this.signer) {
throw new Error('Signer required for write operations');
}
return await this.contracts.revocationRegistry.publishRevocationList(issuerDID, credentialHashes, signature, merkleRoot);
}
async revokeCredentials(issuerDID, credentialHashes, signature) {
if (!this.signer) {
throw new Error('Signer required for write operations');
}
return await this.contracts.revocationRegistry.revokeCredentials(issuerDID, credentialHashes, signature);
}
async isCredentialRevoked(issuerDID, credentialId) {
return await this.contracts.revocationRegistry.isCredentialRevoked(issuerDID, credentialId);
}
async isCredentialRevokedByHash(issuerHash, credentialHash) {
return await this.contracts.revocationRegistry.isCredentialRevokedByHash(issuerHash, credentialHash);
}
async getRevocationList(issuerDID) {
return await this.contracts.revocationRegistry.getRevocationList(issuerDID);
}
async getRevokedCredentialCount(issuerDID) {
return await this.contracts.revocationRegistry.getRevokedCredentialCount(issuerDID);
}
async verifyRevocationProof(issuerDID, credentialHash, merkleProof) {
return await this.contracts.revocationRegistry.verifyRevocationProof(issuerDID, credentialHash, merkleProof);
}
// Schema Registry methods
async registerSchema(name, description, schemaHash, issuerDID, version, schemaType, dependencies = []) {
if (!this.signer) {
throw new Error('Signer required for write operations');
}
return await this.contracts.schemaRegistry.registerSchema(name, description, schemaHash, issuerDID, version, schemaType, dependencies);
}
async updateSchema(schemaId, description, schemaHash, newVersion, dependencies = []) {
if (!this.signer) {
throw new Error('Signer required for write operations');
}
return await this.contracts.schemaRegistry.updateSchema(schemaId, description, schemaHash, newVersion, dependencies);
}
async deactivateSchema(schemaId) {
if (!this.signer) {
throw new Error('Signer required for write operations');
}
return await this.contracts.schemaRegistry.deactivateSchema(schemaId);
}
async transferSchema(schemaId, newOwner) {
if (!this.signer) {
throw new Error('Signer required for write operations');
}
return await this.contracts.schemaRegistry.transferSchema(schemaId, newOwner);
}
async getSchemasByIssuer(issuerDID) {
return await this.contracts.schemaRegistry.getSchemasByIssuer(issuerDID);
}
async getSchemaIdByName(issuerDID, name) {
return await this.contracts.schemaRegistry.getSchemaIdByName(issuerDID, name);
}
async getSchemasByType(schemaType) {
return await this.contracts.schemaRegistry.getSchemasByType(schemaType);
}
async schemaExists(schemaId) {
return await this.contracts.schemaRegistry.schemaExists(schemaId);
}
async getTotalSchemaCount() {
return await this.contracts.schemaRegistry.getTotalSchemaCount();
}
async getSchemaDependencies(schemaId) {
return await this.contracts.schemaRegistry.getSchemaDependencies(schemaId);
}
async hasCircularDependencies(schemaId) {
return await this.contracts.schemaRegistry.hasCircularDependencies(schemaId);
}
// Utility methods
async getGasPrice() {
const feeData = await this.provider.getFeeData();
return feeData.gasPrice || 0n;
}
async estimateGas(method, ...args) {
// This would need to be implemented based on the specific method
// For now, return a default estimate
return 100000n;
}
async waitForTransaction(txHash) {
return await this.provider.waitForTransaction(txHash);
}
getAddress() {
return this.signer?.address || null;
}
async getBalance(address) {
const addr = address || this.signer?.address;
if (!addr) {
throw new Error('No address provided and no signer available');
}
return await this.provider.getBalance(addr);
}
// Event listening
onDIDRegistered(callback) {
this.contracts.didRegistry.on('DIDRegistered', callback);
}
onDIDUpdated(callback) {
this.contracts.didRegistry.on('DIDUpdated', callback);
}
onRevocationListPublished(callback) {
this.contracts.revocationRegistry.on('RevocationListPublished', callback);
}
onCredentialRevoked(callback) {
this.contracts.revocationRegistry.on('CredentialRevoked', callback);
}
onSchemaRegistered(callback) {
this.contracts.schemaRegistry.on('SchemaRegistered', callback);
}
// Clean up event listeners
removeAllListeners() {
this.contracts.didRegistry.removeAllListeners();
this.contracts.revocationRegistry.removeAllListeners();
this.contracts.schemaRegistry.removeAllListeners();
}
// Query events
async queryDIDEvents(filter) {
const eventFilter = this.contracts.didRegistry.filters.DIDRegistered();
const events = await this.contracts.didRegistry.queryFilter(eventFilter, filter.fromBlock || 0, filter.toBlock || 'latest');
return events;
}
async querySchemaEvents(filter) {
const eventFilter = filter.issuerDID
? this.contracts.schemaRegistry.filters.SchemaRegistered(null, filter.issuerDID)
: this.contracts.schemaRegistry.filters.SchemaRegistered();
const events = await this.contracts.schemaRegistry.queryFilter(eventFilter, filter.fromBlock || 0, filter.toBlock || 'latest');
return events;
}
async queryRevocationEvents(filter) {
const eventFilter = filter.issuerDID
? this.contracts.revocationRegistry.filters.RevocationListPublished(null, filter.issuerDID)
: this.contracts.revocationRegistry.filters.RevocationListPublished();
const events = await this.contracts.revocationRegistry.queryFilter(eventFilter, filter.fromBlock || 0, filter.toBlock || 'latest');
return events;
}
// Additional helper methods for BlockchainStorageProvider
async checkRevocation(issuerDID, credentialHash) {
return await this.isCredentialRevokedByHash(ethers_1.ethers.keccak256(ethers_1.ethers.toUtf8Bytes(issuerDID)), credentialHash);
}
async getSchema(schemaIdOrName) {
if (typeof schemaIdOrName === 'number') {
return await this.contracts.schemaRegistry.getSchema(schemaIdOrName);
}
// Try to parse as schema:uuid format
if (schemaIdOrName.startsWith('schema:')) {
// This is a named schema, need to find it by querying events
const events = await this.querySchemaEvents({
fromBlock: 0,
toBlock: 'latest'
});
for (const event of events) {
const schemaId = event.args.schemaId;
const schema = await this.contracts.schemaRegistry.getSchema(schemaId);
if (schema.name === schemaIdOrName.substring(7)) {
return schema;
}
}
}
return null;
}
}
exports.ContractClient = ContractClient;
//# sourceMappingURL=contract-client.js.map