Putting Everything Together

Finally, we will see how we can call our prover to generate an app proof, submit to Brevis, and have Brevis contracts calling our app contract with our circuit output.

Call Our Prover to Generate a Proof

Edit index.ts. Initialize two clients: one for talking to our prover, one for talking to Brevis.

const prover = new Prover('localhost:33247');
const brevis = new Brevis('appsdkv3.brevis.network:443');

Adding Data to Prove

To prove token transfer, we only need to add a receipt which emits the USDC Transfer event. In the below sample transaction receipt. We will use the first log in this receipt(LogPos 0). The second topic(FieldIndex 1) is "From" address. The first 32-byte data value(FieldIndex 0) is "TransferAmount". By adding these two Fields in receiptData, the prover service is able to check amount and generate corresponding application circuit output.

// initialize a proof request to our prover
const proofReq = new ProofRequest();

// adding the USDC transfer tx receipt
proofReq.addReceipt(
    new ReceiptData({
        tx_hash: '0x8a7fc50330533cd0adbf71e1cfb51b1b6bbe2170b4ce65c02678cf08c8b17737',
        fields: [
            // `From` value
            new Field({
                log_pos: 0,
                is_topic: true,
                field_index: 1, 
            }),
            // `Transfer Amount` value
            new Field({
                log_pos: 0,
                is_topic: false,
                field_index: 0,
            }),
        ],
    }),
);

Calling Our Prover

const proofRes = await prover.prove(proofReq);

index.ts#L63-L82 handles submitting proof request to our prover

Submitting Your Proof to Brevis

There are still several items left unproven in our custom circuit. They are:

  • How do we know if the transaction receipt is valid at all?

  • How do we know that the transaction is certainly on Ethereum?

  • How do we know the the transaction happened in block 21146236?

When you submit the proof generated by your circuit, Brevis's provers will wrap a proof around yours to further prove that the transaction is valid on the specified source chain and is certainly from the block we say it's from.

const brevisRes = await brevis.submit(
    proofReq, 
    proofRes, 
    1, 
    11155111, 
    QueryOption.ZK_MODE, 
    'BREVIS_PARTNER_KEY', // empty string if there is no partner key
    'CALLBACK_ADDRESS' // used for brevis partner flow only, empty string if there is no partner key
    );
await brevis.wait(brevisRes.queryKey, 1);

The arguments 1 and 11155111 are the chain ids of the data source chain and the "destination chain" that we want to post the final proof to, respectively

Now, run the program

ts-node index.ts 
    0x8a7fc50330533cd0adbf71e1cfb51b1b6bbe2170b4ce65c02678cf08c8b17737 
    TestVolume // brevis partner key: could be empty string
    0x9fc16c4918a4d69d885f2ea792048f13782a522d // callback address: could be empty string
Click to see console output
Send prove request for 0x8a7fc50330533cd0adbf71e1cfb51b1b6bbe2170b4ce65c02678cf08c8b17737
proof: 0x......
query: proofId 0x6f478f47319620692acf0d59241c9cbecdb9596f6f185309a11c6c4d75e83df2 nonce 1731300782 waiting for payment. call BrevisRequest.sendRequest to initiate the payment

BREVIS_PARTNER_KEY and CALLBACK_ADDRESS are NOT required to send requests to the Brevis gateway. Developers can leave them as empty string

As we can see, our request is assigned a request id and the fee we are going to pay is 0 (this is only zero for the testnet). Our program is currently waiting for us to pay the fee.

Now, you can call BrevisRequest.sendRequest on the destination chain to pay for the proof. For demo purposes, we will just send the transaction through the Sepolia explorer. You can find the address of BrevisRequest under Contract Addresses. You may also find the sample contract here.

After the transaction is sent, it takes around two minutes for the transaction to be confirmed and Brevis's final proof to be generated. We should see the console outputs keep updating.

...
query proofId 0x6f478f47319620692acf0d59241c9cbecdb9596f6f185309a11c6c4d75e83df2 nonce 1731300782 waiting for final tx
query proofId 0x6f478f47319620692acf0d59241c9cbecdb9596f6f185309a11c6c4d75e83df2 nonce 1731300782 success, tx 0x893098c7748d5d801e54bf64edb96383e26726ebdf9e25f54f56be7c532a7f8d

Last updated