Reencryption issue - Gateway didn't response correctly

Hello, I’m trying to run a simple addition operation on the smart contract and the decrypted result after re-encryption. However I’m having getting an error “Gateway didn’t response correctly” when I call the reencrypt method through js. Following is my code:

const getInstance = async () => {
return createInstance({
chainId: 9000,
networkUrl: “https://devnet.zama.ai/”,
gatewayUrl: “https://gateway.zama.ai”,
aclAddress: ‘0x2Fb4341027eb1d2aD8B5D9708187df8633cAFA92’,
});
};

const interact = async () => {
try{
const contract = new Contract(CONTRACT_ADDRESS, abi, signer);
const instance = await getInstance();
const { publicKey, privateKey } = instance.generateKeypair();

const eip712 = instance.createEIP712(publicKey, CONTRACT_ADDRESS);

const signature = await signer.signTypedData(
eip712.domain,
{ Reencrypt: eip712.types.Reencrypt },
eip712.message,
);

const input = instance.createEncryptedInput(CONTRACT_ADDRESS, USER_ADDRESS);
input.add16(5);
input.add16(20);
const encinputs = input.encrypt();
let input_proof = encinputs.inputProof;

const transaction = await contract.receiveInput(encinputs.handles[0], encinputs.handles[1], input_proof);
await transaction.wait();

const transaction_one = await contract.calculateSum();
await transaction_one.wait();

const enc_sum = await contract.returnSum();

try {
const dec_sum = await instance.reencrypt(
enc_sum, // the encrypted balance
privateKey, // the private key generated by the dApp
publicKey, // the public key generated by the dApp
signature, // the user’s signature of the public key
CONTRACT_ADDRESS, // The contract address where the ciphertext is
USER_ADDRESS, // The user address where the ciphertext is
);
console.log(dec_sum);
} catch(error){
console.log(error);
}

Following is the output of parameters provided to reencrypt method
sum: 99292914124165378992032534236339290868945609897006041906242294352104744092416
private key: 2000000000000000cffb2ea8a265a29ae7a665442cfc6b8e54114c37fd9addd9c512b764243cf453
public key: 2000000000000000093a6e0e58a450ecf998eafd2a19630ec0c1912cd649ea82fa0e0510dd89a328
signature: 0x7598df1c4e7487f84c995e2fe8bb0b72353a309f0319a39e3d244e694c524cab5a7d8754e59006fa0c683e7dd02ab12d124cf7a92d05b1d5ca6cb79b5c7b56b31c
Contract Address:
0xf12Ad7433FE69aaEC66A7Eff816664EE3E58E75c
User Address:
0x6E7C2603d4DabD2C9bBd15993775073C581B54c7

The documentation contains and example of generating signature using the browser but I’m using console (node js). Is there a problem with the signature or am I missing something? Thanks

Hey :wave:

One thing I spotted right away is that you are using zama’s old devnet, which we stopped supporting. Could you try deploying on sepolia testnet, reencryption works quite well there.

You can check the newer docs here: Welcome to fhEVM | fhEVM

And in case you have some more issues and need faster answers you can join our telegram group for fhevm devs Telegram: Contact @zamadevs :blush:

Hi @poppyseeddev

Thanks for the update. I eventually updated fhevm and fhevmjs to 0.6 so I’m using sepolia for contract deployment through remix. However, I’m still having some issues. I’m using node js so I’m not sure how to setup the provider. Is it going to be ‘https://devnet.zama.ai’?

const { createInstance } = require(“fhevmjs”);
const { Wallet, JsonRpcProvider, Contract } = require(“ethers”);
const ethers = require(“ethers”);

const provider = new JsonRpcProvider(https://devnet.zama.ai/);

// private key of the wallet
const signer = new Wallet(“privatekey”, provider);

return createInstance({
gatewayUrl: “https://gateway.sepolia.zama.ai/”,
chainId: 11155111, // Sepolia chain ID
networkUrl: “https://eth-sepolia.public.blastapi.io”, // Sepolia RPC URL
gatewayUrl: “https://gateway.sepolia.zama.ai/”,
kmsContractAddress: “0x9D6891A6240D6130c54ae243d8005063D05fE14b”,
aclContractAddress: “0xFee8407e2f5e3Ee68ad77cAE98c434e637f516e5”,

});
};

this is my code for creating the signature

const contract = new Contract(CONTRACT_ADDRESS, abi, signer);
const instance = await getInstance();
const { publicKey, privateKey } = instance.generateKeypair();

  const eip712 = instance.createEIP712(publicKey, CONTRACT_ADDRESS);

  // Request the user's signature on the public key
  const params = [USER_ADDRESS, JSON.stringify(eip712)];
  // const eip712 = instance.createEIP712(publicKey, CONTRACT_ADDRESS);
  const signature = await signer.signTypedData(
  	eip712.domain,
  	{ Reencrypt: eip712.types.Reencrypt }, // Need to remove EIP712Domain from types
  	eip712.message,
  );

the error I’m getting is
Initialization failed TypeError: Cannot read properties of undefined (reading ‘0’)

const input = instance.createEncryptedInput(CONTRACT_ADDRESS, USER_ADDRESS);
input.add16(5);
input.add16(20);
const encinputs = input.encrypt();
let input_proof = encinputs.inputProof;

    const transaction = await contract.receiveInput(encinputs.handles[0], encinputs.handles[1], input_proof);
    await transaction.wait();

Before you start developing on the frontend, I strongly suggest you to test out your smart contract on hardhat and deploy your contract on Sepolia testnet.

After that you can help yourself with checking out how things are configured in: GitHub - zama-ai/fhevm-react-template :slight_smile:. or another example would be the docs on page: https://docs.zama.ai/fhevm/fundamentals/decryption/reencryption#step-2-re-encrypt-the-ciphertext

the provider in this case would be window.ethereum and should connect to the wallet with the testnet on Sepolia, see:

const provider = new BrowserProvider(window.ethereum);

I have deployed the contract using remix (web) on sepolia and have been able to interact with the methods containing plaintext logic (get/set plaintext number).

I’m using node js and running my scripts through a terminal so I can’t use BrowserProvider.

my current code for provider is:

const provider = new JsonRpcProvider(“https://sepolia.infura.io/v3/my-api-key”);

This is how I’m creating my instance:

const getInstance = async () => {
return createInstance({
gatewayUrl: “https://gateway.sepolia.zama.ai/”,
chainId: 11155111, // Sepolia chain ID
networkUrl: “https://eth-sepolia.public.blastapi.io”, // Sepolia RPC URL
kmsContractAddress: “0x9D6891A6240D6130c54ae243d8005063D05fE14b”,
aclContractAddress: “0xFee8407e2f5e3Ee68ad77cAE98c434e637f516e5”,
});
};

It’s taking a really long time for the instance to be created and the error seems to be related to the instance as well:

 const input = instance.createEncryptedInput(CONTRACT_ADDRESS, USER_ADDRESS);
 input.add16(5);
    input.add16(20);
    const encinputs = input.encrypt();
    let input_proof = encinputs.inputProof;
    console.log(encinputs.handles[0]);

Initialization failed TypeError: Cannot read properties of undefined (reading ‘0’)

First, it’s normal if it takes time on NodeJS because you are proving the encryption on a single core. It’s faster in a browser because it is multithreaded using WebWorker.

encrypt() function returns a Promise, so you need to write

    const encinputs = await input.encrypt();
    let input_proof = encinputs.inputProof;
    console.log(encinputs.handles[0]);

Or use classic way with then

    input.encrypt().then(encinputs => {
      console.log(encinputs.handles[0]);
    });

why not use workers in NodeJS?