@zama-fhe/react-sdk 1.0.0-alpha.2 → 1.0.0-alpha.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +100 -86
- package/dist/index.d.ts +936 -529
- package/dist/index.js +1 -3
- package/dist/index.js.map +1 -1
- package/dist/wagmi/index.d.ts +22 -7128
- package/dist/wagmi/index.js +1 -279
- package/dist/wagmi/index.js.map +1 -1
- package/package.json +8 -23
- package/dist/chunk-463DUSLG.js +0 -1005
- package/dist/chunk-463DUSLG.js.map +0 -1
- package/dist/ethers/index.d.ts +0 -142
- package/dist/ethers/index.js +0 -173
- package/dist/ethers/index.js.map +0 -1
- package/dist/use-approve-underlying-DAkxWhfm.d.ts +0 -784
- package/dist/viem/index.d.ts +0 -142
- package/dist/viem/index.js +0 -173
- package/dist/viem/index.js.map +0 -1
package/README.md
CHANGED
|
@@ -6,6 +6,10 @@ React hooks for confidential token operations, built on [React Query](https://ta
|
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
8
|
pnpm add @zama-fhe/react-sdk @tanstack/react-query
|
|
9
|
+
# or
|
|
10
|
+
npm install @zama-fhe/react-sdk @tanstack/react-query
|
|
11
|
+
# or
|
|
12
|
+
yarn add @zama-fhe/react-sdk @tanstack/react-query
|
|
9
13
|
```
|
|
10
14
|
|
|
11
15
|
`@zama-fhe/sdk` is included as a direct dependency — no need to install it separately.
|
|
@@ -148,8 +152,10 @@ import { ZamaProvider } from "@zama-fhe/react-sdk";
|
|
|
148
152
|
<ZamaProvider
|
|
149
153
|
relayer={relayer} // RelayerSDK (RelayerWeb or RelayerNode instance)
|
|
150
154
|
signer={signer} // GenericSigner (WagmiSigner, ViemSigner, EthersSigner, or custom)
|
|
151
|
-
storage={storage} //
|
|
152
|
-
|
|
155
|
+
storage={storage} // GenericStorage
|
|
156
|
+
sessionStorage={sessionStorage} // Optional. Session storage for wallet signatures. Default: in-memory (lost on reload).
|
|
157
|
+
keypairTTL={86400} // Optional. Seconds the ML-KEM keypair remains valid. Default: 86400 (1 day).
|
|
158
|
+
sessionTTL={2592000} // Optional. Seconds the session signature remains valid. Default: 2592000 (30 days). 0 = re-sign every operation.
|
|
153
159
|
onEvent={(event) => console.debug(event)} // Optional. Structured event listener for debugging.
|
|
154
160
|
>
|
|
155
161
|
{children}
|
|
@@ -169,36 +175,16 @@ const { mutateAsync: shield } = useShield({ tokenAddress });
|
|
|
169
175
|
await shield({ amount: 1000n }); // encryption + approval handled for you
|
|
170
176
|
```
|
|
171
177
|
|
|
172
|
-
**Use the library sub-path** (`/viem`, `/ethers`, `/wagmi`) when you need direct contract-level control without a provider. You handle encryption and cache management yourself:
|
|
173
|
-
|
|
174
178
|
```tsx
|
|
175
|
-
import {
|
|
176
|
-
|
|
177
|
-
const { mutateAsync: shield } = useShield();
|
|
178
|
-
await shield({ client: walletClient, wrapperAddress, to, amount }); // raw contract call
|
|
179
|
+
import { ViemSigner } from "@zama-fhe/sdk/viem";
|
|
180
|
+
import { EthersSigner } from "@zama-fhe/sdk/ethers";
|
|
179
181
|
```
|
|
180
182
|
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
Five hooks share names across both layers. Here's how they differ:
|
|
183
|
+
The `WagmiSigner` is the only adapter in the react-sdk since wagmi is React-specific:
|
|
184
184
|
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
| `useShield` | `mutate({ amount, approvalStrategy? })` — auto-approves | `mutate({ client, wrapper, to, amount })` — raw wrap call |
|
|
189
|
-
| `useShieldETH` | `mutate({ amount, value? })` — `value` defaults to `amount` | `mutate({ client, wrapper, to, amount, value })` — all fields required |
|
|
190
|
-
| `useUnwrap` | `mutate({ amount })` — auto-encrypts | `mutate({ client, token, from, to, encryptedAmount, inputProof })` — pre-encrypted |
|
|
191
|
-
| `useFinalizeUnwrap` | `mutate({ burnAmountHandle })` — fetches proof from relayer | `mutate({ client, wrapper, burntAmount, cleartext, proof })` — caller provides proof |
|
|
192
|
-
|
|
193
|
-
| Feature | Main | Sub-path |
|
|
194
|
-
| ----------------------- | ----------------------- | ----------------------------- |
|
|
195
|
-
| Requires `ZamaProvider` | Yes | No |
|
|
196
|
-
| FHE encryption | Automatic | Manual (caller pre-encrypts) |
|
|
197
|
-
| ERC-20 approval | Automatic (`useShield`) | None |
|
|
198
|
-
| Cache invalidation | Automatic | None |
|
|
199
|
-
| Return type | `TransactionResult` | Raw tx hash or wagmi mutation |
|
|
200
|
-
|
|
201
|
-
> **Rule of thumb:** If you're building a standard dApp UI, use the main import. If you're building custom transaction pipelines or need to compose with other wagmi hooks at the contract level, use the sub-path.
|
|
185
|
+
```tsx
|
|
186
|
+
import { WagmiSigner } from "@zama-fhe/react-sdk/wagmi";
|
|
187
|
+
```
|
|
202
188
|
|
|
203
189
|
## Hooks Reference
|
|
204
190
|
|
|
@@ -289,24 +275,55 @@ const tokenABalance = balances?.get("0xTokenA");
|
|
|
289
275
|
|
|
290
276
|
### Authorization
|
|
291
277
|
|
|
292
|
-
#### `
|
|
278
|
+
#### `useTokenAllow`
|
|
293
279
|
|
|
294
280
|
Pre-authorize FHE decrypt credentials for a list of token addresses with a single wallet signature. Call this early (e.g. after loading the token list) so that subsequent individual decrypt operations reuse cached credentials without prompting the wallet again.
|
|
295
281
|
|
|
296
282
|
```ts
|
|
297
|
-
function
|
|
283
|
+
function useTokenAllow(): UseMutationResult<void, Error, Address[]>;
|
|
298
284
|
```
|
|
299
285
|
|
|
300
286
|
```tsx
|
|
301
|
-
const { mutateAsync:
|
|
287
|
+
const { mutateAsync: tokenAllow, isPending } = useTokenAllow();
|
|
302
288
|
|
|
303
289
|
// Pre-authorize all known tokens up front
|
|
304
|
-
await
|
|
290
|
+
await tokenAllow(allTokenAddresses);
|
|
305
291
|
|
|
306
292
|
// Individual balance decrypts now reuse cached credentials
|
|
307
293
|
const { data: balance } = useConfidentialBalance("0xTokenA");
|
|
308
294
|
```
|
|
309
295
|
|
|
296
|
+
#### `useIsTokenAllowed`
|
|
297
|
+
|
|
298
|
+
Check whether a session signature is cached for a given token. Returns `true` if decrypt operations can proceed without a wallet prompt. Use this to conditionally enable UI elements (e.g. a "Reveal Balances" button).
|
|
299
|
+
|
|
300
|
+
```ts
|
|
301
|
+
function useIsTokenAllowed(tokenAddress: Address): UseQueryResult<boolean, Error>;
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
```tsx
|
|
305
|
+
const { data: allowed } = useIsTokenAllowed("0xTokenAddress");
|
|
306
|
+
|
|
307
|
+
<button disabled={!allowed}>Reveal Balance</button>;
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
Automatically invalidated when `useTokenAllow` or `useTokenRevoke` succeed.
|
|
311
|
+
|
|
312
|
+
#### `useTokenRevoke`
|
|
313
|
+
|
|
314
|
+
Revoke the session signature for the connected wallet. Stored credentials remain intact, but the next decrypt operation will require a fresh wallet signature.
|
|
315
|
+
|
|
316
|
+
```ts
|
|
317
|
+
function useTokenRevoke(): UseMutationResult<void, Error, Address[]>;
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
```tsx
|
|
321
|
+
const { mutate: tokenRevoke } = useTokenRevoke();
|
|
322
|
+
|
|
323
|
+
// Revoke session — addresses are included in the credentials:revoked event
|
|
324
|
+
tokenRevoke(["0xTokenA", "0xTokenB"]);
|
|
325
|
+
```
|
|
326
|
+
|
|
310
327
|
### Transfer Hooks
|
|
311
328
|
|
|
312
329
|
#### `useConfidentialTransfer`
|
|
@@ -581,7 +598,7 @@ function useConfidentialIsApproved(
|
|
|
581
598
|
|
|
582
599
|
#### `useUnderlyingAllowance`
|
|
583
600
|
|
|
584
|
-
Read the ERC-20 allowance
|
|
601
|
+
Read the underlying ERC-20 allowance granted to the wrapper.
|
|
585
602
|
|
|
586
603
|
```ts
|
|
587
604
|
function useUnderlyingAllowance(
|
|
@@ -777,44 +794,36 @@ const { data: value } = useUserDecryptedValue("0xHandleHash");
|
|
|
777
794
|
|
|
778
795
|
## Query Keys
|
|
779
796
|
|
|
780
|
-
|
|
797
|
+
Use `zamaQueryKeys` for manual cache management (invalidation, prefetching, removal).
|
|
781
798
|
|
|
782
799
|
```ts
|
|
783
|
-
import {
|
|
784
|
-
confidentialBalanceQueryKeys,
|
|
785
|
-
confidentialBalancesQueryKeys,
|
|
786
|
-
confidentialHandleQueryKeys,
|
|
787
|
-
confidentialHandlesQueryKeys,
|
|
788
|
-
underlyingAllowanceQueryKeys,
|
|
789
|
-
activityFeedQueryKeys,
|
|
790
|
-
feeQueryKeys,
|
|
791
|
-
decryptionKeys,
|
|
792
|
-
} from "@zama-fhe/react-sdk";
|
|
800
|
+
import { zamaQueryKeys, decryptionKeys } from "@zama-fhe/react-sdk";
|
|
793
801
|
```
|
|
794
802
|
|
|
795
|
-
| Factory
|
|
796
|
-
|
|
|
797
|
-
| `
|
|
798
|
-
| `
|
|
799
|
-
| `
|
|
800
|
-
| `
|
|
801
|
-
| `
|
|
802
|
-
| `
|
|
803
|
-
| `
|
|
804
|
-
| `
|
|
803
|
+
| Factory | Keys | Description |
|
|
804
|
+
| ------------------------------------ | ---------------------------------------------------------------------------------------- | ----------------------------------- |
|
|
805
|
+
| `zamaQueryKeys.confidentialBalance` | `.all`, `.token(address)`, `.owner(address, owner)` | Single-token decrypted balance. |
|
|
806
|
+
| `zamaQueryKeys.confidentialBalances` | `.all`, `.tokens(addresses, owner)` | Multi-token batch balances. |
|
|
807
|
+
| `zamaQueryKeys.confidentialHandle` | `.all`, `.token(address)`, `.owner(address, owner)` | Single-token encrypted handle. |
|
|
808
|
+
| `zamaQueryKeys.confidentialHandles` | `.all`, `.tokens(addresses, owner)` | Multi-token batch handles. |
|
|
809
|
+
| `zamaQueryKeys.isAllowed` | `.all` | Session signature status. |
|
|
810
|
+
| `zamaQueryKeys.underlyingAllowance` | `.all`, `.token(address)`, `.scope(address, owner, wrapper)` | Underlying ERC-20 allowance. |
|
|
811
|
+
| `zamaQueryKeys.activityFeed` | `.all`, `.token(address)`, `.scope(address, userAddress, logsKey, decrypt)` | Activity feed items. |
|
|
812
|
+
| `zamaQueryKeys.fees` | `.shieldFee(...)`, `.unshieldFee(...)`, `.batchTransferFee(addr)`, `.feeRecipient(addr)` | Fee manager queries. |
|
|
813
|
+
| `decryptionKeys` | `.value(handle)` | Individual decrypted handle values. |
|
|
805
814
|
|
|
806
815
|
```tsx
|
|
807
816
|
import { useQueryClient } from "@tanstack/react-query";
|
|
808
|
-
import {
|
|
817
|
+
import { zamaQueryKeys } from "@zama-fhe/react-sdk";
|
|
809
818
|
|
|
810
819
|
const queryClient = useQueryClient();
|
|
811
820
|
|
|
812
821
|
// Invalidate all balances
|
|
813
|
-
queryClient.invalidateQueries({ queryKey:
|
|
822
|
+
queryClient.invalidateQueries({ queryKey: zamaQueryKeys.confidentialBalance.all });
|
|
814
823
|
|
|
815
824
|
// Invalidate a specific token's balance
|
|
816
825
|
queryClient.invalidateQueries({
|
|
817
|
-
queryKey:
|
|
826
|
+
queryKey: zamaQueryKeys.confidentialBalance.token("0xTokenAddress"),
|
|
818
827
|
});
|
|
819
828
|
```
|
|
820
829
|
|
|
@@ -858,30 +867,13 @@ import { WagmiSigner } from "@zama-fhe/react-sdk/wagmi";
|
|
|
858
867
|
const signer = new WagmiSigner({ config: wagmiConfig });
|
|
859
868
|
```
|
|
860
869
|
|
|
861
|
-
##
|
|
862
|
-
|
|
863
|
-
Both `@zama-fhe/react-sdk/viem` and `@zama-fhe/react-sdk/ethers` export the same set of read/write hooks, but typed for their respective libraries. They also include `Suspense` variants of all read hooks.
|
|
864
|
-
|
|
865
|
-
### Read hooks
|
|
866
|
-
|
|
867
|
-
`useConfidentialBalanceOf`, `useWrapperForToken`, `useUnderlyingToken`, `useWrapperExists`, `useSupportsInterface` — plus `*Suspense` variants.
|
|
868
|
-
|
|
869
|
-
- **viem:** First parameter is `PublicClient`.
|
|
870
|
-
- **ethers:** First parameter is `Provider | Signer`.
|
|
871
|
-
|
|
872
|
-
### Write hooks
|
|
873
|
-
|
|
874
|
-
`useConfidentialTransfer`, `useConfidentialBatchTransfer`, `useUnwrap`, `useUnwrapFromBalance`, `useFinalizeUnwrap`, `useSetOperator`, `useShield`, `useShieldETH`.
|
|
870
|
+
## Signer Adapters
|
|
875
871
|
|
|
876
|
-
|
|
877
|
-
- **ethers:** Mutation params include `signer: Signer`.
|
|
878
|
-
|
|
879
|
-
### Signer adapters
|
|
872
|
+
Signer adapters are provided by the core SDK package:
|
|
880
873
|
|
|
881
874
|
```ts
|
|
882
|
-
|
|
883
|
-
import {
|
|
884
|
-
import { EthersSigner } from "@zama-fhe/react-sdk/ethers";
|
|
875
|
+
import { ViemSigner } from "@zama-fhe/sdk/viem";
|
|
876
|
+
import { EthersSigner } from "@zama-fhe/sdk/ethers";
|
|
885
877
|
```
|
|
886
878
|
|
|
887
879
|
## Wallet Integration Guide
|
|
@@ -900,12 +892,34 @@ Place `ZamaProvider` inside your client-only layout. Do **not** create the relay
|
|
|
900
892
|
|
|
901
893
|
### FHE Credentials Lifecycle
|
|
902
894
|
|
|
903
|
-
FHE decrypt credentials are generated once per wallet + token set and cached in the storage backend you provide (e.g. `IndexedDBStorage`). The lifecycle:
|
|
895
|
+
FHE decrypt credentials are generated once per wallet + token set and cached in the storage backend you provide (e.g. `IndexedDBStorage`). The wallet signature is kept **in memory only** — never persisted to disk. The lifecycle:
|
|
896
|
+
|
|
897
|
+
1. **First decrypt** — SDK generates an FHE keypair, creates EIP-712 typed data, and prompts the wallet to sign. The encrypted credential is stored; the signature is cached in memory.
|
|
898
|
+
2. **Same session** — Cached credentials and session signature are reused silently (no wallet prompt).
|
|
899
|
+
3. **Page reload** — Encrypted credentials are loaded from storage; the wallet is prompted once to re-sign for the session.
|
|
900
|
+
4. **Expiry** — Credentials expire based on `keypairTTL` (default: 86400s = 1 day). After expiry, the next decrypt regenerates and re-prompts.
|
|
901
|
+
5. **Pre-authorization** — Call `useTokenAllow(tokenAddresses)` early to batch-authorize all tokens in one wallet prompt, avoiding repeated popups.
|
|
902
|
+
6. **Check status** — Use `useIsTokenAllowed(tokenAddress)` to conditionally enable UI elements (e.g. disable "Reveal" until allowed).
|
|
903
|
+
7. **Disconnect** — Call `useTokenRevoke(tokenAddresses)` or `await credentials.revoke()` to clear the session signature from memory.
|
|
904
|
+
|
|
905
|
+
### Web Extension Support
|
|
906
|
+
|
|
907
|
+
By default, wallet signatures are stored in memory and lost on page reload (or service worker restart). For MV3 web extensions, use the built-in `chromeSessionStorage` singleton so signatures survive service worker restarts and are shared across popup, background, and content script contexts:
|
|
908
|
+
|
|
909
|
+
```tsx
|
|
910
|
+
import { chromeSessionStorage } from "@zama-fhe/react-sdk";
|
|
911
|
+
|
|
912
|
+
<ZamaProvider
|
|
913
|
+
relayer={relayer}
|
|
914
|
+
signer={signer}
|
|
915
|
+
storage={indexedDBStorage}
|
|
916
|
+
sessionStorage={chromeSessionStorage}
|
|
917
|
+
>
|
|
918
|
+
<App />
|
|
919
|
+
</ZamaProvider>;
|
|
920
|
+
```
|
|
904
921
|
|
|
905
|
-
|
|
906
|
-
2. **Subsequent decrypts** — If cached credentials cover the requested token, they're reused silently (no wallet prompt).
|
|
907
|
-
3. **Expiry** — Credentials expire based on `durationDays`. After expiry, the next decrypt re-prompts the wallet.
|
|
908
|
-
4. **Pre-authorization** — Call `useAuthorizeAll(tokenAddresses)` early to batch-authorize all tokens in one wallet prompt, avoiding repeated popups.
|
|
922
|
+
This keeps the encrypted credentials in IndexedDB (persistent) while the unlock signature lives in `chrome.storage.session` (ephemeral, cleared when the browser closes).
|
|
909
923
|
|
|
910
924
|
### Error-to-User-Message Mapping
|
|
911
925
|
|
|
@@ -960,7 +974,7 @@ To force a refresh:
|
|
|
960
974
|
|
|
961
975
|
```tsx
|
|
962
976
|
const queryClient = useQueryClient();
|
|
963
|
-
queryClient.invalidateQueries({ queryKey:
|
|
977
|
+
queryClient.invalidateQueries({ queryKey: zamaQueryKeys.confidentialBalance.all });
|
|
964
978
|
```
|
|
965
979
|
|
|
966
980
|
## Re-exports from Core SDK
|
|
@@ -973,9 +987,9 @@ All public exports from `@zama-fhe/sdk` are re-exported from the main entry poin
|
|
|
973
987
|
|
|
974
988
|
**Pending unshield:** `savePendingUnshield`, `loadPendingUnshield`, `clearPendingUnshield`.
|
|
975
989
|
|
|
976
|
-
**Types:** `Address`, `ZamaSDKConfig`, `ZamaConfig`, `ReadonlyTokenConfig`, `NetworkType`, `RelayerSDK`, `RelayerSDKStatus`, `EncryptResult`, `EncryptParams`, `UserDecryptParams`, `PublicDecryptResult`, `FHEKeypair`, `EIP712TypedData`, `DelegatedUserDecryptParams`, `KmsDelegatedUserDecryptEIP712Type`, `ZKProofLike`, `InputProofBytesType`, `BatchTransferData`, `StoredCredentials`, `GenericSigner`, `
|
|
990
|
+
**Types:** `Address`, `ZamaSDKConfig`, `ZamaConfig`, `ReadonlyTokenConfig`, `NetworkType`, `RelayerSDK`, `RelayerSDKStatus`, `EncryptResult`, `EncryptParams`, `UserDecryptParams`, `PublicDecryptResult`, `FHEKeypair`, `EIP712TypedData`, `DelegatedUserDecryptParams`, `KmsDelegatedUserDecryptEIP712Type`, `ZKProofLike`, `InputProofBytesType`, `BatchTransferData`, `StoredCredentials`, `GenericSigner`, `GenericStorage`, `ContractCallConfig`, `TransactionReceipt`, `TransactionResult`, `UnshieldCallbacks`.
|
|
977
991
|
|
|
978
|
-
**Errors:** `ZamaError`, `ZamaErrorCode`, `SigningRejectedError`, `SigningFailedError`, `EncryptionFailedError`, `DecryptionFailedError`, `ApprovalFailedError`, `TransactionRevertedError`, `
|
|
992
|
+
**Errors:** `ZamaError`, `ZamaErrorCode`, `SigningRejectedError`, `SigningFailedError`, `EncryptionFailedError`, `DecryptionFailedError`, `ApprovalFailedError`, `TransactionRevertedError`, `InvalidKeypairError`, `NoCiphertextError`, `RelayerRequestFailedError`, `matchZamaError`.
|
|
979
993
|
|
|
980
994
|
**Constants:** `ZERO_HANDLE`, `ERC7984_INTERFACE_ID`, `ERC7984_WRAPPER_INTERFACE_ID`.
|
|
981
995
|
|