The reencryption process involves converting a ciphertext that was encrypted with the FHE blockchain key into one that is encrypted with the NaCl public key generated by the dApp.
First, your contract needs to implement a view function to return the ciphertext to reencrypt:
Then, you can implement the client side code. This example would run in a browser:
import abi from"./abi.json";import { Contract, BrowserProvider } from"ethers";import { createInstance } from"fhevmjs";constCONTRACT_ADDRESS="";constprovider=newBrowserProvider(window.ethereum);constaccounts=awaitprovider.send("eth_requestAccounts", []);constUSER_ADDRESS= accounts[0];// Create a fhevmjs instance using the Zama's network and the Zama's Gatewayconstinstance=awaitcreateInstance({ aclAddress:'0x2Fb4341027eb1d2aD8B5D9708187df8633cAFA92', chainId:9000, networkUrl:"https://devnet.zama.ai", gatewayUrl:"https://gateway.zama.ai",});// Generate the private and public key, used for the reencryptionconst { publicKey,privateKey } =instance.generateKeypair();// Create an EIP712 object for the user to sign.consteip712=instance.createEIP712(publicKey,CONTRACT_ADDRESS);// Request the user's signature on the public keyconstparams= [USER_ADDRESS,JSON.stringify(eip712)];constsignature=awaitwindow.ethereum.request({ method:"eth_signTypedData_v4", params });// Get the ciphertext to reencryptconstencryptedERC20=newContract(CONTRACT_ADDRESS, abi, signer).connect(provider);constencryptedBalance=encryptedERC20.balanceOf(userAddress);// This function will call the gateway and decrypt the received value with the provided private keyconstuserBalance=instance.reencrypt( encryptedBalance,// 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 keyCONTRACT_ADDRESS,// The contract address where the ciphertext isUSER_ADDRESS,// The user address where the ciphertext is);console.log(userBalance);