UNPKG

@nori-zk/ethprocessor

Version:

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

197 lines 12.3 kB
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) { if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); }; var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) { if (kind === "m") throw new TypeError("Private method is not writable"); if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value; }; var _MinaEthProcessorSubmitter_instances, _MinaEthProcessorSubmitter_zkApp, _MinaEthProcessorSubmitter_senderPrivateKey, _MinaEthProcessorSubmitter_zkAppPrivateKey, _MinaEthProcessorSubmitter_network, _MinaEthProcessorSubmitter_txFee, _MinaEthProcessorSubmitter_testMode, _MinaEthProcessorSubmitter_ethProcessorVerificationKey_get, _MinaEthProcessorSubmitter_ethVerifierVerificationKey_get; import 'dotenv/config'; import { AccountUpdate, Mina, PrivateKey, fetchAccount } from 'o1js'; import { Logger } from 'esm-iso-logger'; import { EthProcessor } from './ethProcessor.js'; import { EthVerifier, EthInput, ethVerifierVkHash, decodeConsensusMptProof, Bytes32FieldPair, NodeProofLeft, compileAndOptionallyVerifyContracts, } from '@nori-zk/o1js-zk-utils'; import { cacheFactory } from '@nori-zk/o1js-zk-utils/node'; import { ethProcessorVkHash } from './integrity/EthProcessor.VKHash.js'; const logger = new Logger('EthProcessorSubmitter'); export class MinaEthProcessorSubmitter { constructor(cache = undefined) { _MinaEthProcessorSubmitter_instances.add(this); this.cache = cache; _MinaEthProcessorSubmitter_zkApp.set(this, void 0); _MinaEthProcessorSubmitter_senderPrivateKey.set(this, void 0); _MinaEthProcessorSubmitter_zkAppPrivateKey.set(this, void 0); _MinaEthProcessorSubmitter_network.set(this, void 0); _MinaEthProcessorSubmitter_txFee.set(this, void 0); _MinaEthProcessorSubmitter_testMode.set(this, void 0); void __classPrivateFieldGet(this, _MinaEthProcessorSubmitter_instances, "a", _MinaEthProcessorSubmitter_ethVerifierVerificationKey_get); void __classPrivateFieldGet(this, _MinaEthProcessorSubmitter_testMode, "f"); logger.info(`🛠 MinaEthProcessorSubmitter constructor called!`); const errors = []; const senderPrivateKeyBase58 = process.env.SENDER_PRIVATE_KEY; const network = process.env.NETWORK; const zkAppPrivateKeyBase58 = process.env.ZKAPP_PRIVATE_KEY; const networkUrl = process.env.MINA_RPC_NETWORK_URL; if (!senderPrivateKeyBase58) errors.push('SENDER_PRIVATE_KEY is required'); if (!network) { errors.push('NETWORK is required'); } else if (!['devnet', 'mainnet', 'lightnet'].includes(network)) { errors.push(`NETWORK must be one of: devnet, mainnet, lightnet (got "${network}")`); } else { __classPrivateFieldSet(this, _MinaEthProcessorSubmitter_network, network, "f"); } if (!networkUrl) { errors.push('MINA_RPC_NETWORK_URL is required'); } if (!zkAppPrivateKeyBase58) { errors.push('ZKAPP_PRIVATE_KEY is required when not in lightnet mode'); } if (errors.length > 0) { throw `Configuration errors:\n- ${errors.join('\n- ')}`; } __classPrivateFieldSet(this, _MinaEthProcessorSubmitter_senderPrivateKey, PrivateKey.fromBase58(senderPrivateKeyBase58), "f"); __classPrivateFieldSet(this, _MinaEthProcessorSubmitter_zkAppPrivateKey, PrivateKey.fromBase58(zkAppPrivateKeyBase58), "f"); __classPrivateFieldSet(this, _MinaEthProcessorSubmitter_zkApp, new EthProcessor(__classPrivateFieldGet(this, _MinaEthProcessorSubmitter_zkAppPrivateKey, "f").toPublicKey()), "f"); __classPrivateFieldSet(this, _MinaEthProcessorSubmitter_txFee, Number(process.env.TX_FEE || 0.1) * 1e9, "f"); __classPrivateFieldSet(this, _MinaEthProcessorSubmitter_testMode, process.env.NETWORK === 'lightnet', "f"); this.minaRPCNetworkUrl = networkUrl; logger.log('Loaded constants from: .env'); } async networkSetUp() { logger.log(`Setting up ${__classPrivateFieldGet(this, _MinaEthProcessorSubmitter_network, "f")} network with RPC endpoint: '${this.minaRPCNetworkUrl}'.`); const networkId = __classPrivateFieldGet(this, _MinaEthProcessorSubmitter_network, "f") === 'mainnet' ? 'mainnet' : 'testnet'; const Network = Mina.Network({ networkId, mina: this.minaRPCNetworkUrl, }); Mina.setActiveInstance(Network); logger.log('Finished Mina network setup.'); } async compileContracts() { const fileSystemCache = this.cache ? await cacheFactory(this.cache) : undefined; logger.log('fileSystemCache', fileSystemCache, this.cache); const { ethVerifierVerificationKey, ethProcessorVerificationKey } = await compileAndOptionallyVerifyContracts(logger, [ { name: 'ethVerifier', program: EthVerifier, integrityHash: ethVerifierVkHash, }, { name: 'ethProcessor', program: EthProcessor, integrityHash: ethProcessorVkHash, }, ], fileSystemCache); Object.defineProperty(this, 'ethVerifierVerificationKey', { value: ethVerifierVerificationKey, writable: false, configurable: false, enumerable: true, }); Object.defineProperty(this, 'ethProcessorVerificationKey', { value: ethProcessorVerificationKey, writable: false, configurable: false, enumerable: true, }); } async deployContract(storeHash) { if (__classPrivateFieldGet(this, _MinaEthProcessorSubmitter_network, "f") !== 'lightnet') { throw new Error([ //prettier-ignore `Deploy is only supported in test mode, test mode was set to 'false'. Test mode is only possible when the configured network is 'lightnet' and the configured network is '${__classPrivateFieldGet(this, _MinaEthProcessorSubmitter_network, "f")}'.`, `Please see the README.md within the 'contracts/mina/eth-processor' workspace of the 'nori-bridge-sdk' repository and use the deploy script 'npm run deploy <storeHash>' instead of this method.`, ].join('\n')); } logger.log('Creating deploy update transaction.'); const senderPublicKey = __classPrivateFieldGet(this, _MinaEthProcessorSubmitter_senderPrivateKey, "f").toPublicKey(); const deployTx = await Mina.transaction({ sender: senderPublicKey, fee: __classPrivateFieldGet(this, _MinaEthProcessorSubmitter_txFee, "f") }, async () => { AccountUpdate.fundNewAccount(senderPublicKey); logger.log(`Deploying smart contract with verification key hash: '${__classPrivateFieldGet(this, _MinaEthProcessorSubmitter_instances, "a", _MinaEthProcessorSubmitter_ethProcessorVerificationKey_get).hash}'`); await __classPrivateFieldGet(this, _MinaEthProcessorSubmitter_zkApp, "f").deploy({ verificationKey: __classPrivateFieldGet(this, _MinaEthProcessorSubmitter_instances, "a", _MinaEthProcessorSubmitter_ethProcessorVerificationKey_get), }); logger.log(`Initializing with adminPublicKey '${senderPublicKey.toBase58()}' and store hash '${storeHash.toHex()}'.`); await __classPrivateFieldGet(this, _MinaEthProcessorSubmitter_zkApp, "f").initialize(senderPublicKey, Bytes32FieldPair.fromBytes32(storeHash)); }); logger.log('Deploy transaction created successfully. Proving...'); await deployTx.prove(); logger.log('Transaction proved. Signing and sending the transaction...'); await deployTx .sign([__classPrivateFieldGet(this, _MinaEthProcessorSubmitter_senderPrivateKey, "f"), __classPrivateFieldGet(this, _MinaEthProcessorSubmitter_zkAppPrivateKey, "f")]) .send() .wait(); logger.log('EthProcessor deployed successfully.'); } async createProof(proofArguments) { try { logger.log('Creating proof.'); const { sp1PlonkProof, conversionOutputProof } = proofArguments; const rawProof = await NodeProofLeft.fromJSON(conversionOutputProof.proofData); const ethSP1Proof = sp1PlonkProof; logger.log('Decoding converted proof and creating verification inputs.'); // Decode proof values and create input for verification. const input = new EthInput(decodeConsensusMptProof(ethSP1Proof)); // Compute and verify proof. logger.log('Computing proof.'); return EthVerifier.compute(input, rawProof); } catch (err) { logger.error(`Error computing proof: ${String(err)}`); throw err; } } async submit(ethProof) { logger.log('Submitting a proof.'); try { await fetchAccount({ publicKey: __classPrivateFieldGet(this, _MinaEthProcessorSubmitter_zkApp, "f").address }); await fetchAccount({ publicKey: __classPrivateFieldGet(this, _MinaEthProcessorSubmitter_senderPrivateKey, "f").toPublicKey(), }); logger.log('Fetched accounts.'); logger.log('Creating update transaction.'); const updateTx = await Mina.transaction({ sender: __classPrivateFieldGet(this, _MinaEthProcessorSubmitter_senderPrivateKey, "f").toPublicKey(), fee: __classPrivateFieldGet(this, _MinaEthProcessorSubmitter_txFee, "f"), memo: `State for slot ${ethProof.publicInput.outputSlot.toString()} set`, }, async () => { await __classPrivateFieldGet(this, _MinaEthProcessorSubmitter_zkApp, "f").update(ethProof); }); await updateTx.prove(); logger.log('Transaction proven.'); const tx = await updateTx.sign([__classPrivateFieldGet(this, _MinaEthProcessorSubmitter_senderPrivateKey, "f")]).send(); logger.log(`Transaction sent to '${__classPrivateFieldGet(this, _MinaEthProcessorSubmitter_network, "f")}'.`); if (!tx.data) { throw new Error('Transaction data is undefined'); } const txId = tx.data.sendZkapp.zkapp.id; const txHash = tx.data.sendZkapp.zkapp.hash; if (!txId) { throw new Error('txId is undefined'); } return { txId, txHash, }; } catch (err) { logger.error(`Error submitting proof: ${String(err)}`); throw err; } } } _MinaEthProcessorSubmitter_zkApp = new WeakMap(), _MinaEthProcessorSubmitter_senderPrivateKey = new WeakMap(), _MinaEthProcessorSubmitter_zkAppPrivateKey = new WeakMap(), _MinaEthProcessorSubmitter_network = new WeakMap(), _MinaEthProcessorSubmitter_txFee = new WeakMap(), _MinaEthProcessorSubmitter_testMode = new WeakMap(), _MinaEthProcessorSubmitter_instances = new WeakSet(), _MinaEthProcessorSubmitter_ethProcessorVerificationKey_get = function _MinaEthProcessorSubmitter_ethProcessorVerificationKey_get() { return this.ethProcessorVerificationKey; }, _MinaEthProcessorSubmitter_ethVerifierVerificationKey_get = function _MinaEthProcessorSubmitter_ethVerifierVerificationKey_get() { return this.ethVerifierVerificationKey; }; //# sourceMappingURL=proofSubmitter.js.map