issuer field identifies who is accessing the data — the issuer must have been granted access on-chain via FHE.allow(handle, address). When a permit is used, CoFHE validates it against the ACL contract to confirm that the issuer has access to the requested encrypted handle.
Each permit includes a sealing keypair. The public key is sent to CoFHE so it can re-encrypt the data for the permit holder. The private key stays client-side and is used to unseal the returned data.
When do you need a permit?
decryptForView: always requires a permit.decryptForTx: depends on the contract’s ACL policy for thatctHash.- If the policy allows anyone to decrypt, you can use
.withoutPermit(). - If the policy restricts decryption, you must use
.withPermit(...).
- If the policy allows anyone to decrypt, you can use
Prerequisites
Create and connect a client. Permits are scoped to a chainId + account.Quick start
The examples below show two approaches. The
client.permits API is the recommended approach — it automatically signs permits with the connected wallet and manages the permit store. The PermitUtils API is a lower-level alternative that gives you direct control over signing and storage.decryptForView(...).execute()uses the active permit.decryptForTx(...).withPermit().execute()uses the active permit.
Permit types
- Permit
expirationis a unix timestamp in seconds. The default is 7 days from creation. - When a permit is created via
client.permits.*, it is automatically stored and set as the active permit.
Creating a self permit
A self permit lets you decrypt data that was allowed to your address.createSelf
getOrCreateSelfPermit
Returns the active self permit if one exists. Otherwise creates and signs a new one. This is the recommended approach for most applications.Sharing permits
Sharing permits let an issuer delegate their ACL access to a recipient. The recipient can then decrypt the issuer’s data without needing their ownFHE.allow.
1
Issuer creates a sharing permit
The issuer creates a sharing permit specifying the recipient’s address.
2
Issuer exports the permit
Export the permit as a JSON blob and share it with the recipient.
The exported JSON does not contain any sensitive data and can be shared via any channel.
3
Recipient imports and signs
The recipient imports the exported JSON and signs it with their wallet. On import, a new sealing key is generated for the recipient.
Active permit management
The SDK tracks all stored permits and an active permit hash perchainId + account. Creating or importing a permit via client.permits.* automatically stores it and selects it as active.
List stored permits
Read / select the active permit
Removing permits
Persistence and security
- The SDK persists permits in a store keyed by
chainId + account. - In web environments, this store uses
localStorageunder the keycofhesdk-permits. - A stored permit includes the sealing private key. Treat it like a secret.
- Never share serialized permits with other users.
- To share access, use
PermitUtils.export(...)which strips sensitive fields.