refactor deployment scripts (#678)

This commit is contained in:
turnoffthiscomputer
2025-06-25 04:12:55 -04:00
committed by GitHub
parent e685991d75
commit 0a5cabde02
6 changed files with 370 additions and 625 deletions

View File

@@ -1,50 +1,47 @@
import { buildModule } from "@nomicfoundation/hardhat-ignition/modules";
import hre from "hardhat";
import fs from "fs";
import path from "path";
import { getSavedRepo, getDeployedAddresses, getContractAddress, log } from "../../../scripts/constants";
module.exports = buildModule("UpdateRegistryHubV2", (m) => {
const repo = hre.network.config.chainId === 42220 ? "prod" : "staging";
const deployedAddressesPath = path.join(__dirname, `../../deployments/${repo}/deployed_addresses.json`);
const chainId = hre.network.config.chainId;
const networkName = hre.network.name;
console.log(`Reading deployed addresses from: ${deployedAddressesPath}`);
const deployedAddresses = JSON.parse(fs.readFileSync(deployedAddressesPath, "utf8"));
log.info(`Network: ${networkName}, Chain ID: ${chainId}`);
const registryAddress = deployedAddresses["DeployRegistryModule#IdentityRegistry"];
const registryIdCardAddress = deployedAddresses["DeployIdCardRegistryModule#IdentityRegistryIdCard"];
const hubAddress = deployedAddresses["DeployHubV2#IdentityVerificationHub"];
const repoName = getSavedRepo(networkName);
const deployedAddresses = getDeployedAddresses(repoName);
// Validate addresses
if (!registryAddress) {
throw new Error("IdentityRegistry address not found in deployed addresses");
}
if (!registryIdCardAddress) {
throw new Error("IdentityRegistryIdCard address not found in deployed addresses");
}
if (!hubAddress) {
throw new Error("IdentityVerificationHub address not found in deployed addresses");
}
log.info(`Using repo: ${repoName}`);
console.log(`Registry address: ${registryAddress}`);
console.log(`Registry ID Card address: ${registryIdCardAddress}`);
console.log(`Hub address: ${hubAddress}`);
try {
const registryAddress = getContractAddress("DeployRegistryModule#IdentityRegistry", deployedAddresses);
const registryIdCardAddress = getContractAddress("DeployIdCardRegistryModule#IdentityRegistryIdCard", deployedAddresses);
const hubAddress = getContractAddress("DeployHubV2#IdentityVerificationHub", deployedAddresses);
const deployedRegistryInstance = m.contractAt("IdentityRegistryImplV1", registryAddress);
const deployedRegistryIdCardInstance = m.contractAt("IdentityRegistryIdCardImplV1", registryIdCardAddress);
log.info(`Registry address: ${registryAddress}`);
log.info(`Registry ID Card address: ${registryIdCardAddress}`);
log.info(`Hub address: ${hubAddress}`);
console.log("✓ Created registry contract instances");
const deployedRegistryInstance = m.contractAt("IdentityRegistryImplV1", registryAddress);
const deployedRegistryIdCardInstance = m.contractAt("IdentityRegistryIdCardImplV1", registryIdCardAddress);
log.success("Created registry contract instances");
// Execute the updateHub calls
console.log("Updating hub address on IdentityRegistry...");
m.call(deployedRegistryInstance, "updateHub", [hubAddress]);
log.step("Updating hub address on IdentityRegistry...");
m.call(deployedRegistryInstance, "updateHub", [hubAddress]);
console.log("Updating hub address on IdentityRegistryIdCard...");
m.call(deployedRegistryIdCardInstance, "updateHub", [hubAddress]);
log.step("Updating hub address on IdentityRegistryIdCard...");
m.call(deployedRegistryIdCardInstance, "updateHub", [hubAddress]);
console.log("Hub update calls initiated successfully");
log.success("Hub update calls initiated successfully");
return {
deployedRegistryInstance,
deployedRegistryIdCardInstance
};
deployedRegistryInstance,
deployedRegistryIdCardInstance
};
} catch (error) {
log.error(`Failed to update registry hub: ${error}`);
throw error;
}
});

View File

@@ -6,7 +6,7 @@ import * as path from "path";
const deployVerifiers = {
vcAndDiscloseVerifier: false,
vcAndDiscloseIdVerifier: true,
vcAndDiscloseIdVerifier: false,
registerIdVerifier: false,
registerVerifier: false,
dscVerifier: false,

View File

@@ -0,0 +1,48 @@
how to deploy and update the protocol
Main contracts:
- Hub
- Registries
- Passports
- ID cards
Hub and Registries are following an upgradeable proxy pattern.
Use only the Proxy address for everything.
Secondary contracts:
- vc_and_disclose verifiers
- vc_and_disclose_id verifiers
- register verifiers'
- register id verifiers
- dsc verifiers
How to update the protocol:
### Deploy the Hub V2 and the Identity registry
```
yarn deploy:hub:v2
```
```
deploy:registry:idcard
```
### Set the registries address in the hub
````
yarn set:hub:v2
````
Set the verifiers in the hub
```
yarn set:verifiers:v2
```
### Update the registries
````
yarn set:registry:hub:v2
```

View File

@@ -0,0 +1,75 @@
import * as path from "path";
import * as fs from "fs";
export const ATTESTATION_ID = {
E_PASSPORT: '0x0000000000000000000000000000000000000000000000000000000000000001',
EU_ID_CARD: '0x0000000000000000000000000000000000000000000000000000000000000002',
};
export const ATTESTATION_TO_REGISTRY = {
E_PASSPORT: 'DeployRegistryModule#IdentityRegistry',
EU_ID_CARD: 'DeployIdCardRegistryModule#IdentityRegistryIdCard',
}
export const NETWORK_TO_CHAIN_ID: Record<string, string> = {
localhost: '31337',
hardhat: '31337',
alfajores: '44787',
celoAlfajores: '44787',
celo: '42220',
mainnet: '42220',
staging: '44787',
};
export const CHAIN_ID_TO_SAVED_REPO: Record<string, string> = {
'42220' : 'prod',
'44787' : 'staging'
};
export const getChainId = (network: string): string => {
const chainId = NETWORK_TO_CHAIN_ID[network];
console.log(`Network '${network}' mapped to Chain ID: ${chainId}`);
return chainId;
};
export const getSavedRepo = (network: string): string => {
const repoName = CHAIN_ID_TO_SAVED_REPO[NETWORK_TO_CHAIN_ID[network]];
return repoName;
};
export const getDeployedAddresses = (repoName: string): any => {
const addresses_path = path.join(__dirname, `../ignition/deployments/${repoName}/deployed_addresses.json`);
return JSON.parse(fs.readFileSync(addresses_path, "utf-8"));
}
export const getContractAbi = (repoName: string, deploymentArtifactName: string): any => {
const abi_path = path.join(__dirname, `../ignition/deployments/${repoName}/artifacts/${deploymentArtifactName}.json`);
return JSON.parse(fs.readFileSync(abi_path, "utf-8")).abi;
}
export function getContractAddress(exactName: string, deployedAddresses : any): any {
if (exactName in deployedAddresses) {
return deployedAddresses[exactName];
}
throw Error(`No contract address found for ${exactName}`)
}
// Console colors
const colors = {
reset: '\x1b[0m',
red: '\x1b[31m',
green: '\x1b[32m',
yellow: '\x1b[33m',
blue: '\x1b[34m',
magenta: '\x1b[35m',
cyan: '\x1b[36m',
white: '\x1b[37m'
};
export const log = {
info: (msg: string) => console.log(`${colors.blue}[INFO]${colors.reset} ${msg}`),
success: (msg: string) => console.log(`${colors.green}[SUCCESS]${colors.reset} ${msg}`),
warning: (msg: string) => console.log(`${colors.yellow}[WARNING]${colors.reset} ${msg}`),
error: (msg: string) => console.log(`${colors.red}[ERROR]${colors.reset} ${msg}`),
step: (msg: string) => console.log(`${colors.magenta}[STEP]${colors.reset} ${msg}`)
};

View File

@@ -1,105 +1,38 @@
import { ethers } from "ethers";
import * as dotenv from "dotenv";
import * as fs from "fs";
import * as path from "path";
import { RegisterVerifierId, DscVerifierId } from "@selfxyz/common";
import { getDeployedAddresses, getContractAbi, getSavedRepo, getContractAddress, ATTESTATION_TO_REGISTRY, ATTESTATION_ID } from "./constants";
dotenv.config();
// Environment configuration
const NETWORK = process.env.NETWORK || "localhost"; // Default to staging
const RPC_URL_KEY = NETWORK === "celo" ? "CELO_RPC_URL" : "CELO_ALFAJORES_RPC_URL";
const setHubV2 = {
'E_PASSPORT' : false,
'EU_ID_CARD' : false,
}
const NETWORK = process.env.NETWORK;
const RPC_URL = process.env.RPC_URL;
const PRIVATE_KEY = process.env.PRIVATE_KEY;
// Network to Chain ID mapping
const NETWORK_TO_CHAIN_ID: Record<string, string> = {
localhost: "31337",
hardhat: "31337",
alfajores: "44787",
celoAlfajores: "44787",
celo: "42220",
mainnet: "42220",
staging: "44787", // Default staging to alfajores
};
if (!NETWORK){
throw new Error('One of the following parameter is null: NETWORK, RPC_URL, PRIVATE_KEY')
}
// Get chain ID from network name
const getChainId = (network: string): string => {
const chainId = NETWORK_TO_CHAIN_ID[network] || NETWORK_TO_CHAIN_ID["alfajores"];
console.log(`Network "${network}" mapped to Chain ID: ${chainId}`);
return chainId;
};
const CHAIN_ID = getChainId(NETWORK);
// Define AttestationId constants directly based on values from AttestationId.sol
const AttestationId = {
// Pad with zeros to create full 32 bytes length
E_PASSPORT: "0x0000000000000000000000000000000000000000000000000000000000000001",
EU_ID_CARD: "0x0000000000000000000000000000000000000000000000000000000000000002",
};
const repo = CHAIN_ID === "42220" ? "prod" : "staging";
// Dynamic paths based on chain ID
const deployedAddressesPath = path.join(__dirname, `../ignition/deployments/${repo}/deployed_addresses.json`);
const contractAbiPath = path.join(
__dirname,
`../ignition/deployments/${repo}/artifacts/DeployV2#IdentityVerificationHubImplV2.json`,
);
// Debug logs for paths and files
const repoName = getSavedRepo(NETWORK);
const deployedAddresses = getDeployedAddresses(repoName);
console.log("Network:", NETWORK);
console.log("Chain ID:", CHAIN_ID);
console.log("Repo:", repoName)
console.log("Current directory:", __dirname);
console.log("Deployed addresses path:", deployedAddressesPath);
console.log("Contract ABI path:", contractAbiPath);
// Debug logs for environment variables (redacted for security)
console.log(`${RPC_URL_KEY} configured:`, !!process.env[RPC_URL_KEY]);
console.log("PRIVATE_KEY configured:", !!PRIVATE_KEY);
try {
const deployedAddresses = JSON.parse(fs.readFileSync(deployedAddressesPath, "utf-8"));
console.log("Deployed addresses loaded:", deployedAddresses);
const identityVerificationHubAbiFile = fs.readFileSync(contractAbiPath, "utf-8");
console.log("ABI file loaded");
const identityVerificationHubAbi = JSON.parse(identityVerificationHubAbiFile).abi;
console.log("ABI parsed");
function getContractAddressByPartialName(partialName: string): string | unknown {
for (const [key, value] of Object.entries(deployedAddresses)) {
if (key.includes(partialName)) {
return value;
}
}
return undefined;
}
function getContractAddressByExactName(exactName: string): string | unknown {
if (exactName in deployedAddresses) {
return deployedAddresses[exactName];
}
return undefined;
}
function getAttestationIdBytes32(attestationIdName: string): string {
return AttestationId[attestationIdName as keyof typeof AttestationId];
}
const hubABI = getContractAbi(repoName,'DeployHubV2#IdentityVerificationHubImplV2')
async function main() {
const provider = new ethers.JsonRpcProvider(process.env[RPC_URL_KEY] as string);
console.log("Provider created");
const provider = new ethers.JsonRpcProvider(RPC_URL);
const wallet = new ethers.Wallet(PRIVATE_KEY as string, provider);
console.log("Wallet created");
// Get hub address from deployment files (PROXY, not implementation)
const hubAddress = (getContractAddressByExactName("DeployV2#IdentityVerificationHub") || // ← PROXY
getContractAddressByExactName("DeployHubV2#IdentityVerificationHub") ||
getContractAddressByExactName("DeployHub#IdentityVerificationHub") ||
getContractAddressByPartialName("IdentityVerificationHub")) as string;
const hubAddress = (getContractAddress("DeployHubV2#IdentityVerificationHub", deployedAddresses)) as string;
console.log("Hub address:", hubAddress);
@@ -108,20 +41,16 @@ try {
throw new Error("Hub address not found in deployed_addresses.json. Available contracts listed above.");
}
const identityVerificationHub = new ethers.Contract(hubAddress, identityVerificationHubAbi, wallet);
const identityVerificationHub = new ethers.Contract(hubAddress, hubABI, wallet);
console.log("Contract instance created");
// Update registry addresses for different attestation types
const attestationTypes = ["E_PASSPORT", "EU_ID_CARD"];
const attestationTypes = ["E_PASSPORT", "EU_ID_CARD"] as const;
for (const attestationType of attestationTypes) {
let registryName: any;
if (attestationType == "E_PASSPORT") {
registryName = "DeployRegistryModule#IdentityRegistry";
} else if (attestationType == "EU_ID_CARD") {
registryName = "DeployIdCardRegistryModule#IdentityRegistryIdCard";
}
const registryAddress = getContractAddressByExactName(registryName);
if (setHubV2[attestationType]){
const registryName = ATTESTATION_TO_REGISTRY[attestationType] as any
console.log('registry name:', registryName);
const registryAddress = getContractAddress(registryName, deployedAddresses);
console.log('registry address:', registryAddress);
if (!registryAddress) {
console.log(`Skipping registry update for ${attestationType} because no deployed address was found.`);
@@ -129,8 +58,7 @@ try {
}
console.log(`Updating registry for ${attestationType}`);
const attestationId = getAttestationIdBytes32(attestationType);
const attestationId = ATTESTATION_ID[attestationType];
try {
const tx = await identityVerificationHub.updateRegistry(attestationId, registryAddress);
const receipt = await tx.wait();
@@ -139,117 +67,11 @@ try {
console.error(`Error updating registry for ${attestationType}:`, error);
}
}
// Update VC and Disclose circuit verifiers for different attestation types
for (const attestationType of attestationTypes) {
let verifierName: any;
if (attestationType == "E_PASSPORT") {
verifierName = "DeployAllVerifiers#Verifier_vc_and_disclose";
} else if (attestationType == "EU_ID_CARD") {
verifierName = "DeployAllVerifiers#Verifier_vc_and_disclose_id";
}
const verifierAddress = getContractAddressByExactName(verifierName);
if (!verifierAddress) {
console.log(
`Skipping VC and Disclose circuit update for ${attestationType} because no deployed address was found.`,
);
continue;
}
console.log(`Updating VC and Disclose circuit for ${attestationType}`);
const attestationId = getAttestationIdBytes32(attestationType);
try {
const tx = await identityVerificationHub.updateVcAndDiscloseCircuit(attestationId, verifierAddress);
const receipt = await tx.wait();
console.log(`VC and Disclose circuit for ${attestationType} updated with tx: ${receipt.hash}`);
} catch (error) {
console.error(`Error updating VC and Disclose circuit for ${attestationType}:`, error);
}
}
// Batch update register circuit verifiers
const registerVerifierKeys = Object.keys(RegisterVerifierId).filter((key) => isNaN(Number(key)));
for (const attestationType of attestationTypes) {
const attestationId = getAttestationIdBytes32(attestationType);
const registerCircuitVerifierIds: number[] = [];
const registerCircuitVerifierAddresses: string[] = [];
for (const key of registerVerifierKeys) {
const verifierName = `Verifier_${key}`;
const verifierAddress = getContractAddressByPartialName(verifierName);
if (!verifierAddress) {
console.log(`Skipping ${verifierName} because no deployed address was found.`);
continue;
}
const verifierId = RegisterVerifierId[key as keyof typeof RegisterVerifierId];
registerCircuitVerifierIds.push(verifierId);
registerCircuitVerifierAddresses.push(verifierAddress as string);
}
if (registerCircuitVerifierIds.length > 0) {
console.log(`Batch updating register circuit verifiers for ${attestationType}`);
try {
const attestationIds = Array(registerCircuitVerifierIds.length).fill(attestationId);
const tx = await identityVerificationHub.batchUpdateRegisterCircuitVerifiers(
attestationIds,
registerCircuitVerifierIds,
registerCircuitVerifierAddresses,
);
const receipt = await tx.wait();
console.log(`Register circuit verifiers for ${attestationType} updated with tx: ${receipt.hash}`);
} catch (error) {
console.error(`Error batch updating register circuit verifiers for ${attestationType}:`, error);
}
}
}
// Batch update DSC circuit verifiers
const dscKeys = Object.keys(DscVerifierId).filter((key) => isNaN(Number(key)));
for (const attestationType of attestationTypes) {
const attestationId = getAttestationIdBytes32(attestationType);
const dscCircuitVerifierIds: number[] = [];
const dscCircuitVerifierAddresses: string[] = [];
for (const key of dscKeys) {
const verifierName = `Verifier_${key}`;
const verifierAddress = getContractAddressByPartialName(verifierName);
if (!verifierAddress) {
console.log(`Skipping ${verifierName} because no deployed address was found.`);
continue;
}
const verifierId = DscVerifierId[key as keyof typeof DscVerifierId];
dscCircuitVerifierIds.push(verifierId);
dscCircuitVerifierAddresses.push(verifierAddress as string);
}
if (dscCircuitVerifierIds.length > 0) {
console.log(`Batch updating DSC circuit verifiers for ${attestationType}`);
try {
const attestationIds = Array(dscCircuitVerifierIds.length).fill(attestationId);
const tx = await identityVerificationHub.batchUpdateDscCircuitVerifiers(
attestationIds,
dscCircuitVerifierIds,
dscCircuitVerifierAddresses,
);
const receipt = await tx.wait();
console.log(`DSC circuit verifiers for ${attestationType} updated with tx: ${receipt.hash}`);
} catch (error) {
console.error(`Error batch updating DSC circuit verifiers for ${attestationType}:`, error);
}
}
else {
console.log(`Skipping registry update for ${attestationType}`);
}
}
}
main().catch((error) => {
console.error("Execution error:", error);
process.exitCode = 1;

View File

@@ -1,464 +1,267 @@
import { ethers } from "ethers";
import * as dotenv from "dotenv";
import * as fs from "fs";
import * as path from "path";
import { RegisterVerifierId, DscVerifierId } from "@selfxyz/common";
import {
getContractAbi,
getDeployedAddresses,
getSavedRepo,
getContractAddress,
ATTESTATION_ID,
log
} from "./constants";
dotenv.config();
// Define AttestationId constants directly based on values from AttestationId.sol
const AttestationId = {
// Pad with zeros to create full 32 bytes length
E_PASSPORT: "0x0000000000000000000000000000000000000000000000000000000000000001",
EU_ID_CARD: "0x0000000000000000000000000000000000000000000000000000000000000002",
// Configuration for which verifiers to set
const setVerifiers = {
vcAndDisclose: true, // VC and Disclose verifier for E_PASSPORT
vcAndDiscloseId: true, // VC and Disclose ID verifier for EU_ID_CARD
register: true, // Register verifiers for E_PASSPORT
registerId: true, // Register ID verifiers for EU_ID_CARD
dsc: true, // DSC verifiers for both E_PASSPORT and EU_ID_CARD
};
console.log("🚀 Starting setVerifiersV2 script...");
console.log("================================");
// Debug logs for paths and files
console.log("📁 File paths:");
console.log(" Current directory:", __dirname);
console.log(
" Deployed addresses path:",
path.join(__dirname, "../ignition/deployments/staging/deployed_addresses.json"),
);
console.log(
" Contract ABI path:",
path.join(__dirname, "../ignition/deployments/staging/artifacts/DeployV2#IdentityVerificationHubImplV2.json"),
);
const NETWORK = process.env.NETWORK;
const RPC_URL = process.env.RPC_URL;
const PRIVATE_KEY = process.env.PRIVATE_KEY;
// Debug logs for environment variables (redacted for security)
console.log("🔐 Environment variables:");
console.log(" CELO_RPC_URL configured:", !!process.env.CELO_ALFAJORES_RPC_URL);
console.log(" PRIVATE_KEY configured:", !!process.env.PRIVATE_KEY);
console.log(" Network:", process.env.NETWORK || "not set");
if (!NETWORK){
throw new Error('One of the following parameter is null: NETWORK, RPC_URL, PRIVATE_KEY')
}
const repoName = getSavedRepo(NETWORK);
const deployedAddresses = getDeployedAddresses(repoName);
log.info(`Network: ${NETWORK}, Repo: ${repoName}`);
try {
console.log("\n📋 Loading deployment data...");
const deployedAddresses = JSON.parse(
fs.readFileSync(path.join(__dirname, "../ignition/deployments/staging/deployed_addresses.json"), "utf-8"),
);
console.log("✅ Deployed addresses loaded successfully");
console.log(` Found ${Object.keys(deployedAddresses).length} deployed contracts`);
const hubABI = getContractAbi(repoName,'DeployHubV2#IdentityVerificationHubImplV2')
// Log all available contracts for debugging
console.log("\n📦 Available deployed contracts:");
Object.keys(deployedAddresses).forEach((key, index) => {
console.log(` ${index + 1}. ${key} -> ${deployedAddresses[key]}`);
});
const identityVerificationHubAbiFile = fs.readFileSync(
path.join(__dirname, "../ignition/deployments/staging/artifacts/DeployV2#IdentityVerificationHubImplV2.json"),
"utf-8",
);
console.log("✅ ABI file loaded successfully");
const identityVerificationHubAbi = JSON.parse(identityVerificationHubAbiFile).abi;
console.log("✅ ABI parsed successfully");
function getContractAddressByPartialName(partialName: string): string | unknown {
function getContractAddressByPartialName(partialName: string): string | undefined {
console.log(`🔍 Searching for contract with partial name: "${partialName}"`);
for (const [key, value] of Object.entries(deployedAddresses)) {
if (key.includes(partialName)) {
console.log(` ✅ Found match: ${key} -> ${value}`);
return value;
return value as string;
}
}
console.log(` ❌ No match found for: "${partialName}"`);
return undefined;
}
function getContractAddressByExactName(exactName: string): string | unknown {
console.log(`🎯 Looking for exact contract name: "${exactName}"`);
if (exactName in deployedAddresses) {
console.log(` ✅ Found: ${exactName} -> ${deployedAddresses[exactName]}`);
return deployedAddresses[exactName];
}
console.log(` ❌ Not found: "${exactName}"`);
return undefined;
}
function getAttestationIdBytes32(attestationIdName: string): string {
const id = AttestationId[attestationIdName as keyof typeof AttestationId];
console.log(`🆔 Attestation ID for ${attestationIdName}: ${id}`);
return id;
}
async function main() {
console.log("\n🌐 Setting up blockchain connection...");
const provider = new ethers.JsonRpcProvider(process.env.CELO_ALFAJORES_RPC_URL as string);
console.log("✅ Provider created");
const wallet = new ethers.Wallet(process.env.PRIVATE_KEY as string, provider);
console.log("✅ Wallet created");
console.log(` Wallet address: ${wallet.address}`);
console.log("\n🏢 Setting up hub contract...");
const hubAddress = deployedAddresses["DeployHubV2#IdentityVerificationHub"];
console.log("🔍 Hub address lookup result:", hubAddress);
const provider = new ethers.JsonRpcProvider(RPC_URL as string);
const wallet = new ethers.Wallet(PRIVATE_KEY as string, provider);
console.log(`Wallet address: ${wallet.address}`);
const hubAddress = getContractAddress("DeployHubV2#IdentityVerificationHub", deployedAddresses);
if (!hubAddress) {
throw new Error("❌ Hub address not found in deployed_addresses.json");
}
const identityVerificationHub = new ethers.Contract(hubAddress, identityVerificationHubAbi, wallet);
console.log("✅ Contract instance created");
const identityVerificationHub = new ethers.Contract(hubAddress, hubABI, wallet);
console.log(` Hub contract address: ${hubAddress}`);
// Update registry addresses for different attestation types
console.log("\n📝 STEP 1: Updating registry addresses...");
console.log("==========================================");
const attestationTypes = ["E_PASSPORT", "EU_ID_CARD"];
for (const attestationType of attestationTypes) {
console.log(`\n🔄 Processing registry for ${attestationType}:`);
let totalUpdates = 0;
let successfulUpdates = 0;
let registryName: any;
if (attestationType == "E_PASSPORT") {
registryName = "DeployRegistryModule#IdentityRegistry";
} else if (attestationType == "EU_ID_CARD") {
registryName = "DeployIdCardRegistryModule#IdentityRegistryIdCard";
}
console.log(` Registry name to search: ${registryName}`);
const registryAddress = getContractAddressByExactName(registryName);
if (!registryAddress) {
console.log(` ⚠️ Skipping registry update for ${attestationType} because no deployed address was found.`);
continue;
}
console.log(` 📍 Registry address found: ${registryAddress}`);
const attestationId = getAttestationIdBytes32(attestationType);
// Update VC and Disclose verifier for E_PASSPORT
if (setVerifiers.vcAndDisclose) {
log.step("Updating VC and Disclose verifier for E_PASSPORT");
try {
console.log(` 📤 Sending updateRegistry transaction...`);
const tx = await identityVerificationHub.updateRegistry(attestationId, registryAddress);
console.log(` ⏳ Transaction sent: ${tx.hash}`);
console.log(` ⏳ Waiting for confirmation...`);
const verifierAddress = getContractAddress("DeployAllVerifiers#Verifier_vc_and_disclose", deployedAddresses);
const attestationId = ATTESTATION_ID.E_PASSPORT;
totalUpdates++;
const tx = await identityVerificationHub.updateVcAndDiscloseCircuit(attestationId, verifierAddress);
const receipt = await tx.wait();
console.log(` ✅ Registry for ${attestationType} updated successfully!`);
console.log(` Transaction hash: ${receipt.hash}`);
console.log(` Gas used: ${receipt.gasUsed}`);
log.success(`VC verifier for E_PASSPORT updated (tx: ${receipt.hash})`);
successfulUpdates++;
} catch (error) {
console.error(` ❌ Error updating registry for ${attestationType}:`, error);
log.error(`Failed to update VC verifier for E_PASSPORT: ${error}`);
}
}
// Update VC and Disclose circuit verifiers for different attestation types
console.log("\n📝 STEP 2: Updating VC and Disclose circuit verifiers...");
console.log("=======================================================");
for (const attestationType of attestationTypes) {
console.log(`\n🔄 Processing VC verifier for ${attestationType}:`);
let verifierName: any;
if (attestationType == "E_PASSPORT") {
verifierName = "DeployAllVerifiers#Verifier_vc_and_disclose";
} else if (attestationType == "EU_ID_CARD") {
verifierName = "DeployAllVerifiers#Verifier_vc_and_disclose_id";
}
console.log(` Verifier name to search: ${verifierName}`);
const verifierAddress = getContractAddressByExactName(verifierName);
if (!verifierAddress) {
console.log(` ⚠️ Skipping VC and Disclose circuit update for ${attestationType} because no deployed address was found.`);
continue;
}
console.log(` 📍 Verifier address found: ${verifierAddress}`);
const attestationId = getAttestationIdBytes32(attestationType);
// Update VC and Disclose ID verifier for EU_ID_CARD
if (setVerifiers.vcAndDiscloseId) {
log.step("Updating VC and Disclose ID verifier for EU_ID_CARD");
try {
console.log(` 📤 Sending updateVcAndDiscloseCircuit transaction...`);
const verifierAddress = getContractAddress("DeployAllVerifiers#Verifier_vc_and_disclose_id", deployedAddresses);
const attestationId = ATTESTATION_ID.EU_ID_CARD;
totalUpdates++;
const tx = await identityVerificationHub.updateVcAndDiscloseCircuit(attestationId, verifierAddress);
console.log(` ⏳ Transaction sent: ${tx.hash}`);
console.log(` ⏳ Waiting for confirmation...`);
const receipt = await tx.wait();
console.log(` ✅ VC and Disclose circuit for ${attestationType} updated successfully!`);
console.log(` Transaction hash: ${receipt.hash}`);
console.log(` Gas used: ${receipt.gasUsed}`);
log.success(`VC ID verifier for EU_ID_CARD updated (tx: ${receipt.hash})`);
successfulUpdates++;
} catch (error) {
console.error(` ❌ Error updating VC and Disclose circuit for ${attestationType}:`, error);
log.error(`Failed to update VC ID verifier for EU_ID_CARD: ${error}`);
}
}
// Batch update register circuit verifiers for E_PASSPORT
console.log("\n📝 STEP 3: Batch updating register circuit verifiers for E_PASSPORT...");
console.log("=====================================================================");
if (setVerifiers.register) {
log.step("Updating register circuit verifiers for E_PASSPORT");
console.log("🔍 Discovering register verifiers...");
const registerVerifierKeys = Object.keys(RegisterVerifierId).filter((key) => isNaN(Number(key)));
console.log(` Found ${registerVerifierKeys.length} register verifier keys in enum:`, registerVerifierKeys);
const registerVerifierKeys = Object.keys(RegisterVerifierId).filter((key) => isNaN(Number(key)));
const regularRegisterKeys = registerVerifierKeys.filter(key => !key.startsWith('register_id_'));
// Filter out register_id keys for E_PASSPORT (they should only be used for EU_ID_CARD)
const regularRegisterKeys = registerVerifierKeys.filter(key => !key.startsWith('register_id_'));
console.log(` Filtered to ${regularRegisterKeys.length} regular register keys (excluding register_id_*):`, regularRegisterKeys);
const registerAttestationIds: string[] = [];
const registerCircuitVerifierIds: number[] = [];
const registerCircuitVerifierAddresses: string[] = [];
const registerAttestationIds: string[] = [];
const registerCircuitVerifierIds: number[] = [];
const registerCircuitVerifierAddresses: string[] = [];
for (const key of regularRegisterKeys) {
const verifierName = `Verifier_${key}`;
const verifierAddress = getContractAddressByPartialName(verifierName);
for (const key of regularRegisterKeys) {
console.log(`\n 🔄 Processing register verifier: ${key}`);
const verifierName = `Verifier_${key}`;
console.log(` Searching for: ${verifierName}`);
const verifierAddress = getContractAddressByPartialName(verifierName);
if (!verifierAddress) {
log.warning(`Skipping ${verifierName} - not found`);
continue;
}
if (!verifierAddress) {
console.log(` ❌ Skipping ${verifierName} because no deployed address was found.`);
continue;
const verifierId = RegisterVerifierId[key as keyof typeof RegisterVerifierId];
registerAttestationIds.push(ATTESTATION_ID.E_PASSPORT);
registerCircuitVerifierIds.push(verifierId);
registerCircuitVerifierAddresses.push(verifierAddress);
}
const verifierId = RegisterVerifierId[key as keyof typeof RegisterVerifierId];
console.log(` ✅ Found verifier: ${verifierName} -> ${verifierAddress}`);
console.log(` 📋 Verifier ID: ${verifierId} (key: ${key})`);
registerAttestationIds.push(AttestationId.E_PASSPORT);
registerCircuitVerifierIds.push(verifierId);
registerCircuitVerifierAddresses.push(verifierAddress as string);
}
console.log(`\n📊 Register verifiers summary for E_PASSPORT:`);
console.log(` Total found: ${registerCircuitVerifierIds.length}`);
console.log(` Verifier IDs: [${registerCircuitVerifierIds.join(', ')}]`);
console.log(` Addresses: [${registerCircuitVerifierAddresses.map(addr => addr.slice(0, 10) + '...').join(', ')}]`);
if (registerCircuitVerifierIds.length > 0) {
try {
console.log(`📤 Sending batchUpdateRegisterCircuitVerifiers transaction for E_PASSPORT...`);
const tx = await identityVerificationHub.batchUpdateRegisterCircuitVerifiers(
registerAttestationIds,
registerCircuitVerifierIds,
registerCircuitVerifierAddresses,
);
console.log(`⏳ Transaction sent: ${tx.hash}`);
console.log(`⏳ Waiting for confirmation...`);
const receipt = await tx.wait();
console.log(`✅ Register circuit verifiers for E_PASSPORT updated successfully!`);
console.log(` Transaction hash: ${receipt.hash}`);
console.log(` Gas used: ${receipt.gasUsed}`);
} catch (error) {
console.error("❌ Error batch updating register circuit verifiers for E_PASSPORT:", error);
if (registerCircuitVerifierIds.length > 0) {
try {
totalUpdates++;
const tx = await identityVerificationHub.batchUpdateRegisterCircuitVerifiers(
registerAttestationIds,
registerCircuitVerifierIds,
registerCircuitVerifierAddresses,
);
const receipt = await tx.wait();
log.success(`Register verifiers for E_PASSPORT updated: ${registerCircuitVerifierIds.length} verifiers (tx: ${receipt.hash})`);
successfulUpdates++;
} catch (error) {
log.error(`Failed to update register verifiers for E_PASSPORT: ${error}`);
}
} else {
log.warning("No register circuit verifiers found for E_PASSPORT");
}
} else {
console.log("⚠️ No register circuit verifiers found for E_PASSPORT");
}
// Batch update register circuit verifiers for EU_ID_CARD (using register_id verifiers)
console.log("\n📝 STEP 4: Batch updating register circuit verifiers for EU_ID_CARD...");
console.log("====================================================================");
if (setVerifiers.registerId) {
log.step("Updating register_id circuit verifiers for EU_ID_CARD");
// Function to map register_id circuit names to their corresponding RegisterVerifierId
function getRegisterIdMapping(registerIdCircuitName: string): number | null {
console.log(` 🔄 Mapping register_id circuit: ${registerIdCircuitName}`);
// The register_id circuits should have their own entries in the RegisterVerifierId enum
// Look for exact match first
if (registerIdCircuitName in RegisterVerifierId) {
const verifierId = RegisterVerifierId[registerIdCircuitName as keyof typeof RegisterVerifierId];
console.log(` ✅ Found direct mapping: ${registerIdCircuitName} (ID: ${verifierId})`);
return verifierId as number;
// Get all register_id verifiers from deployed addresses
const registerIdVerifiers: string[] = [];
for (const key of Object.keys(deployedAddresses)) {
if (key.includes("Verifier_register_id_")) {
const circuitName = key.replace("DeployAllVerifiers#Verifier_", "");
registerIdVerifiers.push(circuitName);
}
}
console.warn(` ❌ No RegisterVerifierId mapping found for: ${registerIdCircuitName}`);
return null;
}
const registerIdAttestationIds: string[] = [];
const registerIdCircuitVerifierIds: number[] = [];
const registerIdCircuitVerifierAddresses: string[] = [];
// Get all register_id verifiers from deployed addresses
console.log("🔍 Discovering register_id verifiers...");
const registerIdVerifiers: string[] = [];
for (const key of Object.keys(deployedAddresses)) {
if (key.includes("Verifier_register_id_")) {
const circuitName = key.replace("DeployAllVerifiers#Verifier_", "");
registerIdVerifiers.push(circuitName);
console.log(` Found register_id verifier: ${circuitName}`);
for (const registerIdCircuitName of registerIdVerifiers) {
const verifierName = `DeployAllVerifiers#Verifier_${registerIdCircuitName}`;
try {
const verifierAddress = getContractAddress(verifierName, deployedAddresses);
// Map circuit name to RegisterVerifierId
if (registerIdCircuitName in RegisterVerifierId) {
const verifierId = RegisterVerifierId[registerIdCircuitName as keyof typeof RegisterVerifierId];
registerIdAttestationIds.push(ATTESTATION_ID.EU_ID_CARD);
registerIdCircuitVerifierIds.push(verifierId as number);
registerIdCircuitVerifierAddresses.push(verifierAddress);
} else {
log.warning(`No RegisterVerifierId mapping found for: ${registerIdCircuitName}`);
}
} catch (error) {
log.warning(`Skipping ${verifierName} - not found`);
}
}
if (registerIdCircuitVerifierIds.length > 0) {
try {
totalUpdates++;
const tx = await identityVerificationHub.batchUpdateRegisterCircuitVerifiers(
registerIdAttestationIds,
registerIdCircuitVerifierIds,
registerIdCircuitVerifierAddresses,
);
const receipt = await tx.wait();
log.success(`Register_id verifiers for EU_ID_CARD updated: ${registerIdCircuitVerifierIds.length} verifiers (tx: ${receipt.hash})`);
successfulUpdates++;
} catch (error) {
log.error(`Failed to update register_id verifiers for EU_ID_CARD: ${error}`);
}
} else {
log.warning("No register_id circuit verifiers found for EU_ID_CARD");
}
}
console.log(`📊 Found ${registerIdVerifiers.length} register_id verifier(s): [${registerIdVerifiers.join(', ')}]`);
// Batch update DSC circuit verifiers
if (setVerifiers.dsc) {
log.step("Updating DSC circuit verifiers");
const registerIdAttestationIds: string[] = [];
const registerIdCircuitVerifierIds: number[] = [];
const registerIdCircuitVerifierAddresses: string[] = [];
const dscKeys = Object.keys(DscVerifierId).filter((key) => isNaN(Number(key)));
for (const registerIdCircuitName of registerIdVerifiers) {
console.log(`\n 🔄 Processing register_id verifier: ${registerIdCircuitName}`);
const verifierName = `DeployAllVerifiers#Verifier_${registerIdCircuitName}`;
console.log(` Full verifier name: ${verifierName}`);
const verifierAddress = getContractAddressByExactName(verifierName);
// Update for both E_PASSPORT and EU_ID_CARD
const attestationTypes = ["E_PASSPORT", "EU_ID_CARD"] as const;
if (!verifierAddress) {
console.log(` ❌ Skipping ${verifierName} because no deployed address was found.`);
continue;
for (const attestationType of attestationTypes) {
const dscAttestationIds: string[] = [];
const dscCircuitVerifierIds: number[] = [];
const dscCircuitVerifierAddresses: string[] = [];
for (const key of dscKeys) {
const verifierName = `Verifier_${key}`;
const verifierAddress = getContractAddressByPartialName(verifierName);
if (!verifierAddress) {
log.warning(`Skipping ${verifierName} - not found`);
continue;
}
const verifierId = DscVerifierId[key as keyof typeof DscVerifierId];
dscAttestationIds.push(ATTESTATION_ID[attestationType]);
dscCircuitVerifierIds.push(verifierId);
dscCircuitVerifierAddresses.push(verifierAddress);
}
if (dscCircuitVerifierIds.length > 0) {
try {
totalUpdates++;
const tx = await identityVerificationHub.batchUpdateDscCircuitVerifiers(
dscAttestationIds,
dscCircuitVerifierIds,
dscCircuitVerifierAddresses,
);
const receipt = await tx.wait();
log.success(`DSC verifiers for ${attestationType} updated: ${dscCircuitVerifierIds.length} verifiers (tx: ${receipt.hash})`);
successfulUpdates++;
} catch (error) {
log.error(`Failed to update DSC verifiers for ${attestationType}: ${error}`);
}
} else {
log.warning(`No DSC circuit verifiers found for ${attestationType}`);
}
}
const verifierId = getRegisterIdMapping(registerIdCircuitName);
if (verifierId === null) {
console.log(` ❌ Skipping ${registerIdCircuitName} because no RegisterVerifierId mapping was found.`);
continue;
}
console.log(` ✅ Using register_id verifier: ${registerIdCircuitName} (ID: ${verifierId}) for EU_ID_CARD`);
console.log(` 📍 Address: ${verifierAddress}`);
registerIdAttestationIds.push(AttestationId.EU_ID_CARD);
registerIdCircuitVerifierIds.push(verifierId);
registerIdCircuitVerifierAddresses.push(verifierAddress as string);
}
console.log(`\n📊 Register_id verifiers summary for EU_ID_CARD:`);
console.log(` Total found: ${registerIdCircuitVerifierIds.length}`);
console.log(` Verifier IDs: [${registerIdCircuitVerifierIds.join(', ')}]`);
console.log(` Addresses: [${registerIdCircuitVerifierAddresses.map(addr => addr.slice(0, 10) + '...').join(', ')}]`);
if (registerIdCircuitVerifierIds.length > 0) {
try {
console.log(`📤 Sending batchUpdateRegisterCircuitVerifiers transaction for EU_ID_CARD...`);
const tx = await identityVerificationHub.batchUpdateRegisterCircuitVerifiers(
registerIdAttestationIds,
registerIdCircuitVerifierIds,
registerIdCircuitVerifierAddresses,
);
console.log(`⏳ Transaction sent: ${tx.hash}`);
console.log(`⏳ Waiting for confirmation...`);
const receipt = await tx.wait();
console.log(`✅ Register circuit verifiers for EU_ID_CARD updated successfully!`);
console.log(` Transaction hash: ${receipt.hash}`);
console.log(` Gas used: ${receipt.gasUsed}`);
console.log(` Updated ${registerIdCircuitVerifierIds.length} verifier(s) with IDs: [${registerIdCircuitVerifierIds.join(', ')}]`);
} catch (error) {
console.error("❌ Error batch updating register circuit verifiers for EU_ID_CARD:", error);
}
} else {
console.log("⚠️ No register_id circuit verifiers found to update for EU_ID_CARD");
}
// Batch update DSC circuit verifiers for E_PASSPORT
console.log("\n📝 STEP 5: Batch updating DSC circuit verifiers for E_PASSPORT...");
console.log("===============================================================");
console.log("🔍 Discovering DSC verifiers...");
const dscKeys = Object.keys(DscVerifierId).filter((key) => isNaN(Number(key)));
console.log(` Found ${dscKeys.length} DSC verifier keys in enum:`, dscKeys);
const dscAttestationIds: string[] = [];
const dscCircuitVerifierIds: number[] = [];
const dscCircuitVerifierAddresses: string[] = [];
for (const key of dscKeys) {
console.log(`\n 🔄 Processing DSC verifier: ${key}`);
const verifierName = `Verifier_${key}`;
console.log(` Searching for: ${verifierName}`);
const verifierAddress = getContractAddressByPartialName(verifierName);
if (!verifierAddress) {
console.log(` ❌ Skipping ${verifierName} because no deployed address was found.`);
continue;
}
const verifierId = DscVerifierId[key as keyof typeof DscVerifierId];
console.log(` ✅ Found verifier: ${verifierName} -> ${verifierAddress}`);
console.log(` 📋 Verifier ID: ${verifierId}`);
dscAttestationIds.push(AttestationId.E_PASSPORT);
dscCircuitVerifierIds.push(verifierId);
dscCircuitVerifierAddresses.push(verifierAddress as string);
}
console.log(`\n📊 DSC verifiers summary for E_PASSPORT:`);
console.log(` Total found: ${dscCircuitVerifierIds.length}`);
console.log(` Verifier IDs: [${dscCircuitVerifierIds.join(', ')}]`);
console.log(` Addresses: [${dscCircuitVerifierAddresses.map(addr => addr.slice(0, 10) + '...').join(', ')}]`);
if (dscCircuitVerifierIds.length > 0) {
try {
console.log(`📤 Sending batchUpdateDscCircuitVerifiers transaction for E_PASSPORT...`);
const tx = await identityVerificationHub.batchUpdateDscCircuitVerifiers(
dscAttestationIds,
dscCircuitVerifierIds,
dscCircuitVerifierAddresses,
);
console.log(`⏳ Transaction sent: ${tx.hash}`);
console.log(`⏳ Waiting for confirmation...`);
const receipt = await tx.wait();
console.log(`✅ DSC circuit verifiers for E_PASSPORT updated successfully!`);
console.log(` Transaction hash: ${receipt.hash}`);
console.log(` Gas used: ${receipt.gasUsed}`);
} catch (error) {
console.error("❌ Error batch updating DSC circuit verifiers for E_PASSPORT:", error);
}
} else {
console.log("⚠️ No DSC circuit verifiers found for E_PASSPORT");
}
// Batch update DSC circuit verifiers for EU_ID_CARD
console.log("\n📝 STEP 6: Batch updating DSC circuit verifiers for EU_ID_CARD...");
console.log("===============================================================");
const dscIdAttestationIds: string[] = [];
const dscIdCircuitVerifierIds: number[] = [];
const dscIdCircuitVerifierAddresses: string[] = [];
for (const key of dscKeys) {
console.log(`\n 🔄 Processing DSC verifier for EU_ID_CARD: ${key}`);
const verifierName = `Verifier_${key}`;
console.log(` Searching for: ${verifierName}`);
const verifierAddress = getContractAddressByPartialName(verifierName);
if (!verifierAddress) {
console.log(` ❌ Skipping ${verifierName} because no deployed address was found.`);
continue;
}
const verifierId = DscVerifierId[key as keyof typeof DscVerifierId];
console.log(` ✅ Found verifier: ${verifierName} -> ${verifierAddress}`);
console.log(` 📋 Verifier ID: ${verifierId}`);
dscIdAttestationIds.push(AttestationId.EU_ID_CARD);
dscIdCircuitVerifierIds.push(verifierId);
dscIdCircuitVerifierAddresses.push(verifierAddress as string);
}
console.log(`\n📊 DSC verifiers summary for EU_ID_CARD:`);
console.log(` Total found: ${dscIdCircuitVerifierIds.length}`);
console.log(` Verifier IDs: [${dscIdCircuitVerifierIds.join(', ')}]`);
console.log(` Addresses: [${dscIdCircuitVerifierAddresses.map(addr => addr.slice(0, 10) + '...').join(', ')}]`);
if (dscIdCircuitVerifierIds.length > 0) {
try {
console.log(`📤 Sending batchUpdateDscCircuitVerifiers transaction for EU_ID_CARD...`);
const tx = await identityVerificationHub.batchUpdateDscCircuitVerifiers(
dscIdAttestationIds,
dscIdCircuitVerifierIds,
dscIdCircuitVerifierAddresses,
);
console.log(`⏳ Transaction sent: ${tx.hash}`);
console.log(`⏳ Waiting for confirmation...`);
const receipt = await tx.wait();
console.log(`✅ DSC circuit verifiers for EU_ID_CARD updated successfully!`);
console.log(` Transaction hash: ${receipt.hash}`);
console.log(` Gas used: ${receipt.gasUsed}`);
} catch (error) {
console.error("❌ Error batch updating DSC circuit verifiers for EU_ID_CARD:", error);
}
} else {
console.log("⚠️ No DSC circuit verifiers found for EU_ID_CARD");
}
console.log("\n🎉 Script execution completed!");
console.log("===============================");
log.info(`Verifier update summary: ${successfulUpdates}/${totalUpdates} successful`);
}
main().catch((error) => {
console.error("💥 Execution error:", error);
if (error.reason) console.error(" Reason:", error.reason);
if (error.code) console.error(" Code:", error.code);
if (error.transaction) console.error(" Transaction:", error.transaction);
log.error(`Execution failed: ${error}`);
if (error.reason) log.error(`Reason: ${error.reason}`);
process.exitCode = 1;
});
} catch (error) {
console.error("💥 Initial setup error:", error);
log.error(`Setup failed: ${error}`);
process.exitCode = 1;
}