# Solution Proposal: zk-SNARK Conversion Tool UltraPlonk → ZKVerify

## 1. **Executive Summary**

Currently, developers using the Noir/Nargo stack with the UltraPlonk backend face a critical limitation: **the lack of tools to convert zk-SNARK proofs generated via CLI (`bb`) into a format compatible with ZKVerify**. This prevents direct frontend integrations with modern verifiers.

I have developed a **functional Proof of Concept (PoC/MVP)** that performs this conversion **natively in node.js (Backend) and in the browser (Frontend)**, allowing proofs to be submitted directly to ZKVerify without manual CLI steps.

---

## 2. **Current Problem**

Developers working with UltraPlonk face the following barriers:

- Proofs generated by `bb prove` are binary (`.bin`) and incompatible with ZKVerify.
- Conversion to hex format is only possible via CLI, preventing frontend/browser usage.
- There is no official solution for runtime conversion via JavaScript.

<!-- ![](./problem.png) -->
<img width="50%" alt="problem" src="https://github.com/user-attachments/assets/764ccb54-c7b9-43fa-97bd-17c6239da7d0" />

---

## 3. **Proposed Solution**

Creation of an **open-source JavaScript/TypeScript library** that:

- Converts proofs and `Uint8Array` keys generated by `@aztec/bb.js` to `hex` in Node.js or browser environments.
- Generates the proof format accepted by ZKVerify from the UltraPlonk structure.
- Provides a user-friendly API for Web3 developers, DApps, and ZK tools.

> This library **is already functional as a PoC**, with successful proof submissions to ZKVerify.

<!-- ![](./solution.png) -->

<!-- ![](./solution2.png) -->

<p align="center">  
  <img src="https://github.com/user-attachments/assets/a8bc6885-754d-483d-9b83-2d20505816d8" alt="solution" width="45%" />  
  <img src="https://github.com/user-attachments/assets/d20373c5-67b1-4002-8d11-f7a0519200db" alt="solution2" width="50%" />  
</p>

---

## 4. **Proof of Feasibility**

The developed PoC already demonstrates that:

- Conversion can be done entirely in Node.js without CLI.
- The converted format is accepted by ZKVerify's API.
- It can run in Node.js backend.

[Zk Verify Proof Submitted](https://zkverify-testnet.subscan.io/extrinsic/0x29371536bbabbbe0dd17eed201ef966ff2dc7e8d2875938c65522016e0b3c344)

## 5. **How to use**

### Backend side:

```js
import ultraplonk from "olivmath-zkverify";
```

Apply in your flow:

```js
// POST
app.post("/", async (req, res) => {
  // 1. Receive proof, public inputs and vk
  // 2. Convertendo proof e vk para Uint8Array
  // 3. Load ZK circuit
  // 4. Instantiate UltraPlonkBackend from @aztec/bb.js;
  // 5. Verify proofs + public inputs locally with UltraPlonkBackend
  // 6. Convert proofs & vk to ZkVerify compatible format
  const convertedProof = ultraplonk.convert_proof(proof, 1); // <- 1 is the number of public inputs
  const convertedVk = ultraplonk.convert_verification_key(vk);
  // 7. Submit to ZkVerify
  const session = await zkVerifySession
    .start()
    .Volta()
    .withAccount("your seed here");

  const { events } = await session
    .verify()
    .ultraplonk()
    .execute({
      proofData: {
        publicSignals: publicInputs,
        proof: convertedProof,
        vk: convertedVk,
      },
    });

  await new Promise((resolve) => {
    events.on(ZkVerifyEvents.Finalized, (data) => {
      console.log("Proof finalized on zkVerify. ✅", data);
      resolve(data);
    });
  });
});
```

### Backend side:

Comingo soon
