UNPKG

@nori-zk/ethprocessor

Version:

zkApp for verifying SP1 Helios Nori proof and storing latest execution state root on Mina

120 lines 4.95 kB
// Load environment variables from .env file import 'dotenv/config'; // Other imports import { Mina, PrivateKey, AccountUpdate, fetchAccount } from 'o1js'; import { Logger, LogPrinter } from '@nori-zk/proof-conversion'; import { writeFileSync } from 'fs'; import { resolve } from 'path'; import { rootDir, compileAndVerifyContracts } from '../utils.js'; import { EthProcessor } from '../EthProcessor.js'; import { Bytes32, Bytes32FieldPair } from '../types.js'; const logger = new Logger('Deploy'); new LogPrinter('[NoriEthProcessor]', [ 'log', 'info', 'warn', 'error', 'debug', 'fatal', 'verbose', ]); const missingEnvVariables = []; // Declare sender private key const deployerKeyBase58 = process.env.SENDER_PRIVATE_KEY; // Get or generate a zkAppPrivateKey let zkAppPrivateKeyWasCreated = false; if (!process.env.ZKAPP_PRIVATE_KEY) { zkAppPrivateKeyWasCreated = true; logger.log('ZKAPP_PRIVATE_KEY not set, generating a random key.'); } let zkAppPrivateKeyBase58 = process.env.ZKAPP_PRIVATE_KEY ?? PrivateKey.random().toBase58(); if (zkAppPrivateKeyWasCreated) { logger.log(`Created a new ZKAppPrivate key.`); process.env.ZKAPP_PRIVATE_KEY = zkAppPrivateKeyBase58; } // Validate if (!deployerKeyBase58) missingEnvVariables.push('SENDER_PRIVATE_KEY'); if (!zkAppPrivateKeyBase58) missingEnvVariables.push('ZKAPP_PRIVATE_KEY'); if (missingEnvVariables.length > 0) { logger.fatal(`Missing required environment variable(s): ${missingEnvVariables.join(' and ')}`); process.exit(1); } // Network configuration const networkUrl = process.env.MINA_RPC_NETWORK_URL || 'http://localhost:3000/graphql'; // Should probably validate here the network type. FIXME const fee = Number(process.env.TX_FEE || 0.1) * 1e9; // in nanomina (1 billion = 1.0 mina) // Get cli argument const storeHashHex = process.argv[2]; console.log('storeHashHex', storeHashHex); const storeHash = storeHashHex ? Bytes32.fromHex(storeHashHex) : undefined; // No 0x function writeSuccessDetailsToEnvFileFile(zkAppAddressBase58) { // Write env file. const env = { ZKAPP_PRIVATE_KEY: zkAppPrivateKeyBase58, ZKAPP_ADDRESS: zkAppAddressBase58, }; const envFileStr = Object.entries(env) .map(([key, value]) => `${key}=${value}`) .join('\n') + `\n`; const envFileOutputPath = resolve(rootDir, '..', '..', '.env.nori-eth-processor'); logger.info(`Writing env file with the details: '${envFileOutputPath}'`); writeFileSync(envFileOutputPath, envFileStr, 'utf8'); logger.log(`Wrote '${envFileOutputPath}' successfully.`); } async function deploy() { // Initialize keys const deployerKey = PrivateKey.fromBase58(deployerKeyBase58); const zkAppPrivateKey = PrivateKey.fromBase58(zkAppPrivateKeyBase58); const deployerAccount = deployerKey.toPublicKey(); const zkAppAddress = zkAppPrivateKey.toPublicKey(); const zkAppAddressBase58 = zkAppAddress.toBase58(); logger.log(`Deployer address: '${deployerAccount.toBase58()}'.`); logger.log(`ZkApp contract address: '${zkAppAddressBase58}'.`); // Configure Mina network const Network = Mina.Network({ networkId: 'testnet', mina: networkUrl, }); Mina.setActiveInstance(Network); // Compile and verify const { ethProcessorVerificationKey } = await compileAndVerifyContracts(logger); // Initialize contract const zkApp = new EthProcessor(zkAppAddress); // Deploy transaction logger.log('Creating deployment transaction...'); const txn = await Mina.transaction({ fee, sender: deployerAccount }, async () => { AccountUpdate.fundNewAccount(deployerAccount); if (storeHash) { logger.log('Deploying with an updated storeHash and verification key.'); await zkApp.deploy({ verificationKey: ethProcessorVerificationKey, storeHash: Bytes32FieldPair.fromBytes32(storeHash), }); } else { logger.log('Deploying with an updated verification key.'); await zkApp.deploy({ verificationKey: ethProcessorVerificationKey, }); } }); logger.log('Proving transaction'); await txn.prove(); const signedTx = txn.sign([deployerKey, zkAppPrivateKey]); logger.log('Sending transaction...'); const pendingTx = await signedTx.send(); logger.log('Waiting for transaction to be included in a block...'); await pendingTx.wait(); await fetchAccount({ publicKey: zkAppAddress }); const currentAdmin = await zkApp.admin.fetch(); logger.log('Deployment successful!'); logger.log(`Contract admin: '${currentAdmin?.toBase58()}'.`); writeSuccessDetailsToEnvFileFile(zkAppAddressBase58); } // Execute deployment deploy().catch((err) => { logger.fatal(`Deploy function encountered an error.\n${String(err)}`); process.exit(1); }); //# sourceMappingURL=deploy.js.map