fhevmjs function specifications
fhevmjs is designed to assist in creating encrypted inputs and retrieving reencryption data off-chain through a gateway. The library works with any fhEVM and fhEVM Coprocessors.
Init (browser)
If you are using fhevmjs
in a web application, you need to initialize it before creating an instance. To do this, you should call initFhevm
and wait for the promise to resolve.
import { initFhevm, createInstance } from "fhevmjs";
initFhevm().then(() => {
const instance = await createInstance({
aclAddress: '0x2Fb4341027eb1d2aD8B5D9708187df8633cAFA92',
chainId: 9000,
networkUrl: "https://devnet.zama.ai/",
gatewayUrl: "https://gateway.zama.ai/",
});
});
Create instance
This function returns an instance of fhevmjs, which accepts an object containing:
chainId
(optional): the chainId of the networknetwork
(optional): the Eip1193 object provided bywindow.ethereum
(used to fetch the public key and/or chain id)networkUrl
(optional): the URL of the network (used to fetch the public key and/or chain id)publicKey
(optional): if the public key has been fetched separately (cache), you can provide itgatewayUrl
(optional): the URL of the gateway to retrieve a reencryptioncoprocessorUrl
(optional): the URL of the coprocessor
import { createInstance } from "fhevmjs";
const instance = await createInstance({
aclAddress: '0x2Fb4341027eb1d2aD8B5D9708187df8633cAFA92',
networkUrl: "https://devnet.zama.ai/",
gatewayUrl: "https://gateway.zama.ai/",
});
Using window.ethereum
object:
import { createInstance } from "fhevmjs";
const instance = await createInstance({
aclAddress: '0x2Fb4341027eb1d2aD8B5D9708187df8633cAFA92',
network: window.ethereum,
gatewayUrl: "https://gateway.zama.ai/",
});
Input
This method creates an encrypted input and returns an input object. It requires both the user address and the contract address to ensure the encrypted input isn't reused inappropriately in a different context. An input can include multiple values of various types, resulting in a single ciphertext that packs these values.
const userAddress = "0xa5e1defb98EFe38EBb2D958CEe052410247F4c80";
const contractAddress = "0xfCefe53c7012a075b8a711df391100d9c431c468";
const input = instance.createEncryptedInput(contractAddress, userAddress);
input.addBool, input.add8, ...
Input object has different method to add values:
addBool
add4
add8
add16
add32
add64
addAddress
const input = instance.createEncryptedInput(contractAddress, userAddress);
input.addBool(true);
input.add16(239);
input.addAddress("0xa5e1defb98EFe38EBb2D958CEe052410247F4c80");
input.addBool(true);
input.encrypt and input.send
These methods process values and return the necessary data for use on the blockchain. The encrypt
method encrypts these values and provides parameters for use. The send
method encrypts, dispatches the ciphertext and proof to the coprocessor, and returns the required parameters.
input.addBool(true);
input.addBool(true);
input.add8(4);
const inputs = input.encrypt(); // or input.send() if using a coprocessor
contract.myExample(
"0xa5e1defb98EFe38EBb2D958CEe052410247F4c80",
inputs.handles[0],
32,
inputs.handles[1],
inputs.handles[2],
true,
inputs.inputProof,
);
Reencryption
Keypair
A keypair consists of a private key and a public key, both generated by the dApp. These keys are used to reencrypt a blockchain ciphertext, allowing it to be securely transferred to user-specific keypairs.
// Generate the private and public key, used for the reencryption
const { publicKey, privateKey } = instance.generateKeypair();
Verifying that the public key used in the reencryption process belongs to the user requires the user to sign the public key linked to a specific contract address. This signature allows any ciphertext allowed for the user and the contract can be reencrypted using the signed public key. To streamline user interaction during the signature process, we utilize the EIP712 standard as the object to be signed.
// Create an EIP712 object for the user to sign.
const eip712 = instance.createEIP712(publicKey, CONTRACT_ADDRESS);
This eip712
can be signed using eth_signTypedData_v4
for example in a browser:
const params = [USER_ADDRESS, JSON.stringify(eip712)];
const signature = await window.ethereum.request({ method: "eth_signTypedData_v4", params });
Note: it is recommended to store the keypair and the signature in the user's browser to avoid re-requesting signature on every user connection.
Reencryption
Reencrypt method will use the gatewayUrl
to get the reencryption of a ciphertext and decrypt it.
const handle = await erc20.balanceOf(userAddress); // returns the handle of hte ciphertext as a uint256 (bigint)
const myBalance = await instance.reencrypt(handle, privateKey, publicKey, signature, contractAddress, userAddress);
Last updated
Was this helpful?