"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); }) : (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 (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.Prover = void 0; const buffer_1 = require("buffer"); const os = __importStar(require("os")); const interfaces = __importStar(require("./interfaces")); class Prover { constructor(config, signer) { this.initialized = false; this.momiji = {}; this.mempool = { queue: [], gossip: {} }; this.stateRoot = { value: "0x00", index: 0 }; this.initialize = async () => { const txCircuit = this.txCircuit; const recCircuit = this.recCircuit; this.momiji.api = await interfaces.Barretenberg.new(this.threads); let _intermTx = new interfaces.BarretenbergBackend(this.txCircuit, { threads: this.threads }); let _intermRec = new interfaces.BarretenbergBackend(this.recCircuit, { threads: this.threads }); this.momiji = { api: this.momiji.api, contract: new interfaces.Contract(this.config.stateContract.address, JSON.stringify(this.config.stateContract.abi), this.provider), tree: this.config.tree, history: await this.MerkleTree(this.config.tree.stateDepth), transaction: { circuit: this.txCircuit, intermediate: _intermTx, final: new interfaces.Noir(this.txCircuit, _intermTx) }, recursion: { verifier: new interfaces.Contract(this.config.stateContract.address, JSON.stringify(this.config.recursionVerifier.abi), this.provider), circuit: this.recCircuit, intermediate: _intermRec, final: new interfaces.Noir(this.recCircuit, _intermRec) } }; await this.refreshState(); this.momiji.contract.on('TransactionSent', async (e) => { let thisTx = this.resultToTransaction(e); if (!(thisTx.current_root == this.momiji.history.root())) await this.fetchQueue(); this.enqueueLocally(thisTx); }); this.momiji.contract.on('BatchPublish', (event) => { this.clearQueue(); }); this.initialized = true; }; this.pedersen = async (input) => { const _bb = await interfaces.Barretenberg.new(32); if (!Array.isArray(input)) input = [input]; const _input = input; const _inputFr = _input.map(i => interfaces.Fr.fromBufferReduce(buffer_1.Buffer.from(i.slice(2), 'hex'))); let hash = await _bb.pedersenHashWithHashIndex(_inputFr, 0) .then((response) => response.toString()); await _bb.destroy(); return hash; }; this.randomBytesFr = (numBytes) => { return interfaces.Fr.fromBufferReduce(interfaces.randomBytes(numBytes)); }; this.toFixedHex = (number, pad0x, length = 32) => { let hexString = number.toString(16).padStart(length * 2, '0'); return (pad0x ? `0x` + hexString : hexString); }; this.resultToTransaction = (event) => { if (event) { return { current_root: event[0], deposit: event[1], tx_id: event[2], withdrawals: event.slice(3, 19), commitment_out: event.slice(19, 35), recipients: event.slice(35, 51), nullifier_hashes: event.slice(51, 67), proof: event.slice(67, 161), pi_contract_hash: event[161] }; } else { return { current_root: this.toFixedHex(0, true), deposit: this.toFixedHex(0, true), tx_id: this.toFixedHex(0, true), withdrawals: new Array(16).fill(this.toFixedHex(0, true)), commitment_out: new Array(16).fill(this.toFixedHex(0, true)), recipients: new Array(16).fill(this.toFixedHex(0, true)), nullifier_hashes: new Array(16).fill(this.toFixedHex(0, true)), proof: new Array(94).fill(this.toFixedHex(0, true)), pi_contract_hash: this.toFixedHex(0, true) }; } }; this.hasSigner = () => this.signer !== undefined; this.keccak256 = (data) => { let _dataBytes = new Uint8Array(buffer_1.Buffer.from(data.slice(2), 'hex')); let _hashModulo = interfaces.Fr.fromBufferReduce(buffer_1.Buffer.from(interfaces.ethers.keccak256(_dataBytes).slice(2), 'hex')); return _hashModulo.toString(); }; this.generateSecret = () => this.randomBytesFr(32); this.MerkleTree = async (depth, leaves) => { const _bb = await interfaces.Barretenberg.new(32); const tree = new interfaces.MerkleTree(depth, _bb, leaves); await tree.init(); await _bb.destroy(); return tree; }; this.toResult = (e) => { return e.args[0]; }; this.fetchQueue = async () => { const merkleRoot = await this.momiji.contract.merkleRoot(); const filter = this.momiji.contract.filters.TransactionSent(null, merkleRoot, null); const txEvents = await this.momiji.contract.queryFilter(filter); const txContractInputs = txEvents.map(e => this.resultToTransaction(this.toResult(e))); this.clearQueue(); this.enqueueLocally(txContractInputs); return txContractInputs; }; this.refreshState = async () => { let historic_roots = (await this.momiji.contract.getValidRoots()); this.stateRoot.value = (await this.momiji.contract.merkleRoot()); this.stateRoot.index = historic_roots.length - 1; this.momiji.history = (await this.MerkleTree(this.config.tree.stateDepth, historic_roots)); await this.fetchQueue(); }; this.clearQueue = () => { this.mempool.queue = []; this.refreshState(); }; this.enqueue = async (transaction) => { this.enqueueLocally(transaction); if (this.signer) for (let transaction of this.mempool.queue) await this.momiji.contract.enqueue(transaction); }; this.enqueueLocally = async (transaction) => { if (!Array.isArray(transaction)) transaction = [transaction]; this.mempool.queue.push(...transaction); }; if (!signer) { if (config.PRIVATE_KEY) this.signer = new interfaces.Wallet(config.PRIVATE_KEY, new interfaces.JsonRpcProvider(config.provider)); else this.signer = undefined; } else { this.signer = signer; } this.provider = new interfaces.JsonRpcProvider(config.provider); this.config = config; this.txCircuit = config.transactionCircuit; this.recCircuit = config.recursionCircuit; this.config.tree.treeSum = [this.config.tree.utxoDepth, this.config.tree.txDepth, this.config.tree.stateDepth].reduce((a, b) => a + b); this.abi = interfaces.AbiCoder.defaultAbiCoder(); this.threads = os.cpus().length - 2; } keccakHashArray(data) { } } exports.Prover = Prover;