@zama-fhe/react-sdk 1.0.0 → 1.0.1
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 +383 -114
- package/dist/index.d.ts +771 -1102
- package/dist/index.js +1 -977
- package/dist/index.js.map +1 -1
- package/dist/wagmi/index.d.ts +25 -7125
- package/dist/wagmi/index.js +1 -268
- package/dist/wagmi/index.js.map +1 -1
- package/package.json +13 -27
- package/dist/ethers/index.d.ts +0 -162
- package/dist/ethers/index.js +0 -173
- package/dist/ethers/index.js.map +0 -1
- package/dist/viem/index.d.ts +0 -162
- 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.
|
|
@@ -28,11 +32,9 @@ pnpm add @zama-fhe/react-sdk @tanstack/react-query
|
|
|
28
32
|
import { WagmiProvider, createConfig, http } from "wagmi";
|
|
29
33
|
import { mainnet, sepolia } from "wagmi/chains";
|
|
30
34
|
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
|
31
|
-
import {
|
|
35
|
+
import { ZamaProvider, RelayerWeb, indexedDBStorage } from "@zama-fhe/react-sdk";
|
|
32
36
|
import { WagmiSigner } from "@zama-fhe/react-sdk/wagmi";
|
|
33
37
|
|
|
34
|
-
const queryClient = new QueryClient();
|
|
35
|
-
|
|
36
38
|
const wagmiConfig = createConfig({
|
|
37
39
|
chains: [mainnet, sepolia],
|
|
38
40
|
transports: {
|
|
@@ -41,36 +43,38 @@ const wagmiConfig = createConfig({
|
|
|
41
43
|
},
|
|
42
44
|
});
|
|
43
45
|
|
|
44
|
-
const signer = new WagmiSigner(wagmiConfig);
|
|
46
|
+
const signer = new WagmiSigner({ config: wagmiConfig });
|
|
45
47
|
|
|
46
48
|
const relayer = new RelayerWeb({
|
|
47
49
|
getChainId: () => signer.getChainId(),
|
|
48
50
|
transports: {
|
|
49
|
-
[
|
|
50
|
-
relayerUrl: "https://relayer
|
|
51
|
+
[mainnet.id]: {
|
|
52
|
+
relayerUrl: "https://your-app.com/api/relayer/1",
|
|
51
53
|
network: "https://mainnet.infura.io/v3/YOUR_KEY",
|
|
52
54
|
},
|
|
53
|
-
[
|
|
54
|
-
relayerUrl: "https://relayer
|
|
55
|
+
[sepolia.id]: {
|
|
56
|
+
relayerUrl: "https://your-app.com/api/relayer/11155111",
|
|
55
57
|
network: "https://sepolia.infura.io/v3/YOUR_KEY",
|
|
56
58
|
},
|
|
57
59
|
},
|
|
58
60
|
});
|
|
59
61
|
|
|
62
|
+
const queryClient = new QueryClient();
|
|
63
|
+
|
|
60
64
|
function App() {
|
|
61
65
|
return (
|
|
62
66
|
<WagmiProvider config={wagmiConfig}>
|
|
63
67
|
<QueryClientProvider client={queryClient}>
|
|
64
|
-
<
|
|
68
|
+
<ZamaProvider relayer={relayer} signer={signer} storage={indexedDBStorage}>
|
|
65
69
|
<TokenBalance />
|
|
66
|
-
</
|
|
70
|
+
</ZamaProvider>
|
|
67
71
|
</QueryClientProvider>
|
|
68
72
|
</WagmiProvider>
|
|
69
73
|
);
|
|
70
74
|
}
|
|
71
75
|
|
|
72
76
|
function TokenBalance() {
|
|
73
|
-
const { data: balance, isLoading } = useConfidentialBalance("0xTokenAddress");
|
|
77
|
+
const { data: balance, isLoading } = useConfidentialBalance({ tokenAddress: "0xTokenAddress" });
|
|
74
78
|
|
|
75
79
|
if (isLoading) return <p>Decrypting balance...</p>;
|
|
76
80
|
return <p>Balance: {balance?.toString()}</p>;
|
|
@@ -81,42 +85,43 @@ function TokenBalance() {
|
|
|
81
85
|
|
|
82
86
|
```tsx
|
|
83
87
|
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
|
88
|
+
import { mainnet, sepolia } from "wagmi/chains"; // or define your own chain IDs
|
|
84
89
|
import {
|
|
85
|
-
|
|
90
|
+
ZamaProvider,
|
|
86
91
|
RelayerWeb,
|
|
87
92
|
useConfidentialBalance,
|
|
88
93
|
useConfidentialTransfer,
|
|
89
|
-
|
|
94
|
+
memoryStorage,
|
|
90
95
|
} from "@zama-fhe/react-sdk";
|
|
91
96
|
|
|
92
|
-
const queryClient = new QueryClient();
|
|
93
|
-
|
|
94
97
|
const relayer = new RelayerWeb({
|
|
95
98
|
getChainId: () => yourCustomSigner.getChainId(),
|
|
96
99
|
transports: {
|
|
97
|
-
[
|
|
98
|
-
relayerUrl: "https://relayer
|
|
100
|
+
[mainnet.id]: {
|
|
101
|
+
relayerUrl: "https://your-app.com/api/relayer/1",
|
|
99
102
|
network: "https://mainnet.infura.io/v3/YOUR_KEY",
|
|
100
103
|
},
|
|
101
|
-
[
|
|
102
|
-
relayerUrl: "https://relayer
|
|
104
|
+
[sepolia.id]: {
|
|
105
|
+
relayerUrl: "https://your-app.com/api/relayer/11155111",
|
|
103
106
|
network: "https://sepolia.infura.io/v3/YOUR_KEY",
|
|
104
107
|
},
|
|
105
108
|
},
|
|
106
109
|
});
|
|
107
110
|
|
|
111
|
+
const queryClient = new QueryClient();
|
|
112
|
+
|
|
108
113
|
function App() {
|
|
109
114
|
return (
|
|
110
115
|
<QueryClientProvider client={queryClient}>
|
|
111
|
-
<
|
|
116
|
+
<ZamaProvider relayer={relayer} signer={yourCustomSigner} storage={memoryStorage}>
|
|
112
117
|
<TransferForm />
|
|
113
|
-
</
|
|
118
|
+
</ZamaProvider>
|
|
114
119
|
</QueryClientProvider>
|
|
115
120
|
);
|
|
116
121
|
}
|
|
117
122
|
|
|
118
123
|
function TransferForm() {
|
|
119
|
-
const { data: balance } = useConfidentialBalance("0xTokenAddress");
|
|
124
|
+
const { data: balance } = useConfidentialBalance({ tokenAddress: "0xTokenAddress" });
|
|
120
125
|
const { mutateAsync: transfer, isPending } = useConfidentialTransfer({
|
|
121
126
|
tokenAddress: "0xTokenAddress",
|
|
122
127
|
});
|
|
@@ -139,32 +144,60 @@ function TransferForm() {
|
|
|
139
144
|
|
|
140
145
|
## Provider Setup
|
|
141
146
|
|
|
142
|
-
All setups use `
|
|
147
|
+
All setups use `ZamaProvider`. Create a signer with the adapter for your library, then pass it directly.
|
|
143
148
|
|
|
144
149
|
```tsx
|
|
145
|
-
import {
|
|
150
|
+
import { ZamaProvider } from "@zama-fhe/react-sdk";
|
|
146
151
|
|
|
147
|
-
<
|
|
152
|
+
<ZamaProvider
|
|
148
153
|
relayer={relayer} // RelayerSDK (RelayerWeb or RelayerNode instance)
|
|
149
154
|
signer={signer} // GenericSigner (WagmiSigner, ViemSigner, EthersSigner, or custom)
|
|
150
|
-
storage={storage} //
|
|
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.
|
|
159
|
+
onEvent={(event) => console.debug(event)} // Optional. Structured event listener for debugging.
|
|
151
160
|
>
|
|
152
161
|
{children}
|
|
153
|
-
</
|
|
162
|
+
</ZamaProvider>;
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
## Which Hooks Should I Use?
|
|
166
|
+
|
|
167
|
+
The React SDK exports hooks from two layers. **Pick one layer per operation — never mix them.**
|
|
168
|
+
|
|
169
|
+
**Use the main import** (`@zama-fhe/react-sdk`) when you have a `ZamaProvider` in your component tree. These hooks handle FHE encryption, cache invalidation, and error wrapping automatically:
|
|
170
|
+
|
|
171
|
+
```tsx
|
|
172
|
+
import { useShield, useConfidentialTransfer } from "@zama-fhe/react-sdk";
|
|
173
|
+
|
|
174
|
+
const { mutateAsync: shield } = useShield({ tokenAddress });
|
|
175
|
+
await shield({ amount: 1000n }); // encryption + approval handled for you
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
```tsx
|
|
179
|
+
import { ViemSigner } from "@zama-fhe/sdk/viem";
|
|
180
|
+
import { EthersSigner } from "@zama-fhe/sdk/ethers";
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
The `WagmiSigner` is the only adapter in the react-sdk since wagmi is React-specific:
|
|
184
|
+
|
|
185
|
+
```tsx
|
|
186
|
+
import { WagmiSigner } from "@zama-fhe/react-sdk/wagmi";
|
|
154
187
|
```
|
|
155
188
|
|
|
156
189
|
## Hooks Reference
|
|
157
190
|
|
|
158
|
-
All hooks require a `
|
|
191
|
+
All hooks require a `ZamaProvider` (or one of its variants) in the component tree.
|
|
159
192
|
|
|
160
193
|
### SDK Access
|
|
161
194
|
|
|
162
|
-
#### `
|
|
195
|
+
#### `useZamaSDK`
|
|
163
196
|
|
|
164
|
-
Returns the `
|
|
197
|
+
Returns the `ZamaSDK` instance from context. Use this when you need direct access to the SDK (e.g. for low-level relayer operations).
|
|
165
198
|
|
|
166
199
|
```ts
|
|
167
|
-
function
|
|
200
|
+
function useZamaSDK(): ZamaSDK;
|
|
168
201
|
```
|
|
169
202
|
|
|
170
203
|
#### `useToken`
|
|
@@ -191,28 +224,27 @@ Single-token balance with automatic decryption. Uses two-phase polling: polls th
|
|
|
191
224
|
|
|
192
225
|
```ts
|
|
193
226
|
function useConfidentialBalance(
|
|
194
|
-
|
|
195
|
-
owner?: Address, // defaults to connected wallet
|
|
227
|
+
config: UseConfidentialBalanceConfig,
|
|
196
228
|
options?: UseConfidentialBalanceOptions,
|
|
197
229
|
): UseQueryResult<bigint, Error>;
|
|
198
|
-
```
|
|
199
230
|
|
|
200
|
-
|
|
231
|
+
interface UseConfidentialBalanceConfig {
|
|
232
|
+
tokenAddress: Address;
|
|
233
|
+
handleRefetchInterval?: number; // default: 10000ms
|
|
234
|
+
}
|
|
235
|
+
```
|
|
201
236
|
|
|
202
|
-
|
|
203
|
-
| ----------------------- | -------- | ------- | ----------------------------------------------- |
|
|
204
|
-
| `handleRefetchInterval` | `number` | `10000` | Polling interval (ms) for the encrypted handle. |
|
|
237
|
+
Options extend `UseQueryOptions`.
|
|
205
238
|
|
|
206
239
|
```tsx
|
|
207
240
|
const {
|
|
208
241
|
data: balance,
|
|
209
242
|
isLoading,
|
|
210
243
|
error,
|
|
211
|
-
} = useConfidentialBalance(
|
|
212
|
-
"0xTokenAddress",
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
);
|
|
244
|
+
} = useConfidentialBalance({
|
|
245
|
+
tokenAddress: "0xTokenAddress",
|
|
246
|
+
handleRefetchInterval: 5_000,
|
|
247
|
+
});
|
|
216
248
|
```
|
|
217
249
|
|
|
218
250
|
#### `useConfidentialBalances`
|
|
@@ -221,14 +253,21 @@ Multi-token batch balance. Same two-phase polling pattern.
|
|
|
221
253
|
|
|
222
254
|
```ts
|
|
223
255
|
function useConfidentialBalances(
|
|
224
|
-
|
|
225
|
-
owner?: Address,
|
|
256
|
+
config: UseConfidentialBalancesConfig,
|
|
226
257
|
options?: UseConfidentialBalancesOptions,
|
|
227
258
|
): UseQueryResult<Map<Address, bigint>, Error>;
|
|
259
|
+
|
|
260
|
+
interface UseConfidentialBalancesConfig {
|
|
261
|
+
tokenAddresses: Address[];
|
|
262
|
+
handleRefetchInterval?: number;
|
|
263
|
+
maxConcurrency?: number;
|
|
264
|
+
}
|
|
228
265
|
```
|
|
229
266
|
|
|
230
267
|
```tsx
|
|
231
|
-
const { data: balances } = useConfidentialBalances(
|
|
268
|
+
const { data: balances } = useConfidentialBalances({
|
|
269
|
+
tokenAddresses: ["0xTokenA", "0xTokenB", "0xTokenC"],
|
|
270
|
+
});
|
|
232
271
|
|
|
233
272
|
// balances is a Map<Address, bigint>
|
|
234
273
|
const tokenABalance = balances?.get("0xTokenA");
|
|
@@ -236,24 +275,55 @@ const tokenABalance = balances?.get("0xTokenA");
|
|
|
236
275
|
|
|
237
276
|
### Authorization
|
|
238
277
|
|
|
239
|
-
#### `
|
|
278
|
+
#### `useTokenAllow`
|
|
240
279
|
|
|
241
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.
|
|
242
281
|
|
|
243
282
|
```ts
|
|
244
|
-
function
|
|
283
|
+
function useTokenAllow(): UseMutationResult<void, Error, Address[]>;
|
|
245
284
|
```
|
|
246
285
|
|
|
247
286
|
```tsx
|
|
248
|
-
const { mutateAsync:
|
|
287
|
+
const { mutateAsync: tokenAllow, isPending } = useTokenAllow();
|
|
249
288
|
|
|
250
289
|
// Pre-authorize all known tokens up front
|
|
251
|
-
await
|
|
290
|
+
await tokenAllow(allTokenAddresses);
|
|
252
291
|
|
|
253
292
|
// Individual balance decrypts now reuse cached credentials
|
|
254
293
|
const { data: balance } = useConfidentialBalance("0xTokenA");
|
|
255
294
|
```
|
|
256
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
|
+
|
|
257
327
|
### Transfer Hooks
|
|
258
328
|
|
|
259
329
|
#### `useConfidentialTransfer`
|
|
@@ -262,7 +332,7 @@ Encrypted transfer. Encrypts the amount and calls the contract. Automatically in
|
|
|
262
332
|
|
|
263
333
|
```ts
|
|
264
334
|
function useConfidentialTransfer(
|
|
265
|
-
config:
|
|
335
|
+
config: UseZamaConfig,
|
|
266
336
|
options?: UseMutationOptions<Address, Error, ConfidentialTransferParams>,
|
|
267
337
|
): UseMutationResult<Address, Error, ConfidentialTransferParams>;
|
|
268
338
|
|
|
@@ -286,7 +356,7 @@ Operator transfer on behalf of another address.
|
|
|
286
356
|
|
|
287
357
|
```ts
|
|
288
358
|
function useConfidentialTransferFrom(
|
|
289
|
-
config:
|
|
359
|
+
config: UseZamaConfig,
|
|
290
360
|
options?: UseMutationOptions<Address, Error, ConfidentialTransferFromParams>,
|
|
291
361
|
): UseMutationResult<Address, Error, ConfidentialTransferFromParams>;
|
|
292
362
|
|
|
@@ -299,13 +369,13 @@ interface ConfidentialTransferFromParams {
|
|
|
299
369
|
|
|
300
370
|
### Shield Hooks
|
|
301
371
|
|
|
302
|
-
#### `useShield`
|
|
372
|
+
#### `useShield`
|
|
303
373
|
|
|
304
374
|
Shield public ERC-20 tokens into confidential tokens. Handles ERC-20 approval automatically.
|
|
305
375
|
|
|
306
376
|
```ts
|
|
307
377
|
function useShield(
|
|
308
|
-
config:
|
|
378
|
+
config: UseZamaConfig,
|
|
309
379
|
options?: UseMutationOptions<Address, Error, ShieldParams>,
|
|
310
380
|
): UseMutationResult<Address, Error, ShieldParams>;
|
|
311
381
|
|
|
@@ -325,13 +395,13 @@ await shield({ amount: 1000n });
|
|
|
325
395
|
await shield({ amount: 1000n, approvalStrategy: "max" });
|
|
326
396
|
```
|
|
327
397
|
|
|
328
|
-
#### `useShieldETH`
|
|
398
|
+
#### `useShieldETH`
|
|
329
399
|
|
|
330
400
|
Shield native ETH into confidential tokens. Use when the underlying token is the zero address (native ETH).
|
|
331
401
|
|
|
332
402
|
```ts
|
|
333
403
|
function useShieldETH(
|
|
334
|
-
config:
|
|
404
|
+
config: UseZamaConfig,
|
|
335
405
|
options?: UseMutationOptions<Address, Error, ShieldETHParams>,
|
|
336
406
|
): UseMutationResult<Address, Error, ShieldETHParams>;
|
|
337
407
|
|
|
@@ -347,16 +417,17 @@ These hooks orchestrate the full unshield flow in a single call: unwrap → wait
|
|
|
347
417
|
|
|
348
418
|
#### `useUnshield`
|
|
349
419
|
|
|
350
|
-
Unshield a specific amount. Handles the entire unwrap + finalize flow.
|
|
420
|
+
Unshield a specific amount. Handles the entire unwrap + finalize flow. Supports optional progress callbacks to track each step.
|
|
351
421
|
|
|
352
422
|
```ts
|
|
353
423
|
function useUnshield(
|
|
354
|
-
config:
|
|
424
|
+
config: UseZamaConfig,
|
|
355
425
|
options?: UseMutationOptions<Address, Error, UnshieldParams>,
|
|
356
426
|
): UseMutationResult<Address, Error, UnshieldParams>;
|
|
357
427
|
|
|
358
428
|
interface UnshieldParams {
|
|
359
429
|
amount: bigint;
|
|
430
|
+
callbacks?: UnshieldCallbacks;
|
|
360
431
|
}
|
|
361
432
|
```
|
|
362
433
|
|
|
@@ -365,18 +436,29 @@ const { mutateAsync: unshield, isPending } = useUnshield({
|
|
|
365
436
|
tokenAddress: "0xTokenAddress",
|
|
366
437
|
});
|
|
367
438
|
|
|
368
|
-
const finalizeTxHash = await unshield({
|
|
439
|
+
const finalizeTxHash = await unshield({
|
|
440
|
+
amount: 500n,
|
|
441
|
+
callbacks: {
|
|
442
|
+
onUnwrapSubmitted: (txHash) => console.log("Unwrap tx:", txHash),
|
|
443
|
+
onFinalizing: () => console.log("Finalizing..."),
|
|
444
|
+
onFinalizeSubmitted: (txHash) => console.log("Finalize tx:", txHash),
|
|
445
|
+
},
|
|
446
|
+
});
|
|
369
447
|
```
|
|
370
448
|
|
|
371
449
|
#### `useUnshieldAll`
|
|
372
450
|
|
|
373
|
-
Unshield the entire balance. Handles the entire unwrap + finalize flow.
|
|
451
|
+
Unshield the entire balance. Handles the entire unwrap + finalize flow. Supports optional progress callbacks.
|
|
374
452
|
|
|
375
453
|
```ts
|
|
376
454
|
function useUnshieldAll(
|
|
377
|
-
config:
|
|
378
|
-
options?: UseMutationOptions<Address, Error, void>,
|
|
379
|
-
): UseMutationResult<Address, Error, void>;
|
|
455
|
+
config: UseZamaConfig,
|
|
456
|
+
options?: UseMutationOptions<Address, Error, UnshieldAllParams | void>,
|
|
457
|
+
): UseMutationResult<Address, Error, UnshieldAllParams | void>;
|
|
458
|
+
|
|
459
|
+
interface UnshieldAllParams {
|
|
460
|
+
callbacks?: UnshieldCallbacks;
|
|
461
|
+
}
|
|
380
462
|
```
|
|
381
463
|
|
|
382
464
|
```tsx
|
|
@@ -387,6 +469,58 @@ const { mutateAsync: unshieldAll } = useUnshieldAll({
|
|
|
387
469
|
const finalizeTxHash = await unshieldAll();
|
|
388
470
|
```
|
|
389
471
|
|
|
472
|
+
#### `useResumeUnshield`
|
|
473
|
+
|
|
474
|
+
Resume an interrupted unshield from a saved unwrap tx hash. Useful when the user submitted the unwrap but the finalize step was interrupted (e.g. page reload, network error). Pair with the `savePendingUnshield`/`loadPendingUnshield`/`clearPendingUnshield` utilities for persistence.
|
|
475
|
+
|
|
476
|
+
```ts
|
|
477
|
+
function useResumeUnshield(
|
|
478
|
+
config: UseZamaConfig,
|
|
479
|
+
options?: UseMutationOptions<Address, Error, ResumeUnshieldParams>,
|
|
480
|
+
): UseMutationResult<Address, Error, ResumeUnshieldParams>;
|
|
481
|
+
|
|
482
|
+
interface ResumeUnshieldParams {
|
|
483
|
+
unwrapTxHash: Hex;
|
|
484
|
+
callbacks?: UnshieldCallbacks;
|
|
485
|
+
}
|
|
486
|
+
```
|
|
487
|
+
|
|
488
|
+
```tsx
|
|
489
|
+
import { loadPendingUnshield, clearPendingUnshield } from "@zama-fhe/react-sdk";
|
|
490
|
+
|
|
491
|
+
const { mutateAsync: resumeUnshield } = useResumeUnshield({
|
|
492
|
+
tokenAddress: "0xTokenAddress",
|
|
493
|
+
});
|
|
494
|
+
|
|
495
|
+
// On mount, check for interrupted unshields
|
|
496
|
+
const pending = await loadPendingUnshield(storage, wrapperAddress);
|
|
497
|
+
if (pending) {
|
|
498
|
+
await resumeUnshield({ unwrapTxHash: pending });
|
|
499
|
+
await clearPendingUnshield(storage, wrapperAddress);
|
|
500
|
+
}
|
|
501
|
+
```
|
|
502
|
+
|
|
503
|
+
#### Pending Unshield Persistence
|
|
504
|
+
|
|
505
|
+
Save the unwrap tx hash before finalization so interrupted unshields can be resumed after page reloads:
|
|
506
|
+
|
|
507
|
+
```ts
|
|
508
|
+
import {
|
|
509
|
+
savePendingUnshield,
|
|
510
|
+
loadPendingUnshield,
|
|
511
|
+
clearPendingUnshield,
|
|
512
|
+
} from "@zama-fhe/react-sdk";
|
|
513
|
+
|
|
514
|
+
// Save before the finalize step
|
|
515
|
+
await savePendingUnshield(storage, wrapperAddress, unwrapTxHash);
|
|
516
|
+
|
|
517
|
+
// Load on next visit
|
|
518
|
+
const pending = await loadPendingUnshield(storage, wrapperAddress);
|
|
519
|
+
|
|
520
|
+
// Clear after successful finalization
|
|
521
|
+
await clearPendingUnshield(storage, wrapperAddress);
|
|
522
|
+
```
|
|
523
|
+
|
|
390
524
|
### Unwrap Hooks (Low-Level)
|
|
391
525
|
|
|
392
526
|
These hooks expose the individual unwrap steps. Use them when you need fine-grained control over the flow.
|
|
@@ -397,7 +531,7 @@ Request unwrap for a specific amount (requires manual finalization via `useFinal
|
|
|
397
531
|
|
|
398
532
|
```ts
|
|
399
533
|
function useUnwrap(
|
|
400
|
-
config:
|
|
534
|
+
config: UseZamaConfig,
|
|
401
535
|
options?: UseMutationOptions<Address, Error, UnwrapParams>,
|
|
402
536
|
): UseMutationResult<Address, Error, UnwrapParams>;
|
|
403
537
|
|
|
@@ -412,7 +546,7 @@ Request unwrap for the entire balance (requires manual finalization).
|
|
|
412
546
|
|
|
413
547
|
```ts
|
|
414
548
|
function useUnwrapAll(
|
|
415
|
-
config:
|
|
549
|
+
config: UseZamaConfig,
|
|
416
550
|
options?: UseMutationOptions<Address, Error, void>,
|
|
417
551
|
): UseMutationResult<Address, Error, void>;
|
|
418
552
|
```
|
|
@@ -423,7 +557,7 @@ Complete an unwrap by providing the decryption proof.
|
|
|
423
557
|
|
|
424
558
|
```ts
|
|
425
559
|
function useFinalizeUnwrap(
|
|
426
|
-
config:
|
|
560
|
+
config: UseZamaConfig,
|
|
427
561
|
options?: UseMutationOptions<Address, Error, FinalizeUnwrapParams>,
|
|
428
562
|
): UseMutationResult<Address, Error, FinalizeUnwrapParams>;
|
|
429
563
|
|
|
@@ -440,7 +574,7 @@ Set operator approval for the confidential token.
|
|
|
440
574
|
|
|
441
575
|
```ts
|
|
442
576
|
function useConfidentialApprove(
|
|
443
|
-
config:
|
|
577
|
+
config: UseZamaConfig,
|
|
444
578
|
options?: UseMutationOptions<Address, Error, ConfidentialApproveParams>,
|
|
445
579
|
): UseMutationResult<Address, Error, ConfidentialApproveParams>;
|
|
446
580
|
|
|
@@ -456,7 +590,7 @@ Check if a spender is an approved operator. Enabled only when `spender` is defin
|
|
|
456
590
|
|
|
457
591
|
```ts
|
|
458
592
|
function useConfidentialIsApproved(
|
|
459
|
-
config:
|
|
593
|
+
config: UseZamaConfig,
|
|
460
594
|
spender: Address | undefined,
|
|
461
595
|
options?: Omit<UseQueryOptions<boolean, Error>, "queryKey" | "queryFn">,
|
|
462
596
|
): UseQueryResult<boolean, Error>;
|
|
@@ -464,7 +598,7 @@ function useConfidentialIsApproved(
|
|
|
464
598
|
|
|
465
599
|
#### `useUnderlyingAllowance`
|
|
466
600
|
|
|
467
|
-
Read the ERC-20 allowance
|
|
601
|
+
Read the underlying ERC-20 allowance granted to the wrapper.
|
|
468
602
|
|
|
469
603
|
```ts
|
|
470
604
|
function useUnderlyingAllowance(
|
|
@@ -550,6 +684,61 @@ feed?.forEach((item) => {
|
|
|
550
684
|
});
|
|
551
685
|
```
|
|
552
686
|
|
|
687
|
+
### Fee Hooks
|
|
688
|
+
|
|
689
|
+
#### `useShieldFee`
|
|
690
|
+
|
|
691
|
+
Read the shield (wrap) fee for a given amount and address pair.
|
|
692
|
+
|
|
693
|
+
```ts
|
|
694
|
+
function useShieldFee(
|
|
695
|
+
config: UseFeeConfig,
|
|
696
|
+
options?: Omit<UseQueryOptions<bigint, Error>, "queryKey" | "queryFn">,
|
|
697
|
+
): UseQueryResult<bigint, Error>;
|
|
698
|
+
|
|
699
|
+
interface UseFeeConfig {
|
|
700
|
+
feeManagerAddress: Address;
|
|
701
|
+
amount: bigint;
|
|
702
|
+
from: Address;
|
|
703
|
+
to: Address;
|
|
704
|
+
}
|
|
705
|
+
```
|
|
706
|
+
|
|
707
|
+
```tsx
|
|
708
|
+
const { data: fee } = useShieldFee({
|
|
709
|
+
feeManagerAddress: "0xFeeManager",
|
|
710
|
+
amount: 1000n,
|
|
711
|
+
from: "0xSender",
|
|
712
|
+
to: "0xReceiver",
|
|
713
|
+
});
|
|
714
|
+
```
|
|
715
|
+
|
|
716
|
+
#### `useUnshieldFee`
|
|
717
|
+
|
|
718
|
+
Read the unshield (unwrap) fee for a given amount and address pair. Same signature as `useShieldFee`.
|
|
719
|
+
|
|
720
|
+
#### `useBatchTransferFee`
|
|
721
|
+
|
|
722
|
+
Read the batch transfer fee from the fee manager.
|
|
723
|
+
|
|
724
|
+
```ts
|
|
725
|
+
function useBatchTransferFee(
|
|
726
|
+
feeManagerAddress: Address,
|
|
727
|
+
options?: Omit<UseQueryOptions<bigint, Error>, "queryKey" | "queryFn">,
|
|
728
|
+
): UseQueryResult<bigint, Error>;
|
|
729
|
+
```
|
|
730
|
+
|
|
731
|
+
#### `useFeeRecipient`
|
|
732
|
+
|
|
733
|
+
Read the fee recipient address from the fee manager.
|
|
734
|
+
|
|
735
|
+
```ts
|
|
736
|
+
function useFeeRecipient(
|
|
737
|
+
feeManagerAddress: Address,
|
|
738
|
+
options?: Omit<UseQueryOptions<Address, Error>, "queryKey" | "queryFn">,
|
|
739
|
+
): UseQueryResult<Address, Error>;
|
|
740
|
+
```
|
|
741
|
+
|
|
553
742
|
### Low-Level FHE Hooks
|
|
554
743
|
|
|
555
744
|
These hooks expose the raw `RelayerSDK` operations as React Query mutations.
|
|
@@ -605,42 +794,36 @@ const { data: value } = useUserDecryptedValue("0xHandleHash");
|
|
|
605
794
|
|
|
606
795
|
## Query Keys
|
|
607
796
|
|
|
608
|
-
|
|
797
|
+
Use `zamaQueryKeys` for manual cache management (invalidation, prefetching, removal).
|
|
609
798
|
|
|
610
799
|
```ts
|
|
611
|
-
import {
|
|
612
|
-
confidentialBalanceQueryKeys,
|
|
613
|
-
confidentialBalancesQueryKeys,
|
|
614
|
-
confidentialHandleQueryKeys,
|
|
615
|
-
confidentialHandlesQueryKeys,
|
|
616
|
-
underlyingAllowanceQueryKeys,
|
|
617
|
-
activityFeedQueryKeys,
|
|
618
|
-
decryptionKeys,
|
|
619
|
-
} from "@zama-fhe/react-sdk";
|
|
800
|
+
import { zamaQueryKeys, decryptionKeys } from "@zama-fhe/react-sdk";
|
|
620
801
|
```
|
|
621
802
|
|
|
622
|
-
| Factory
|
|
623
|
-
|
|
|
624
|
-
| `
|
|
625
|
-
| `
|
|
626
|
-
| `
|
|
627
|
-
| `
|
|
628
|
-
| `
|
|
629
|
-
| `
|
|
630
|
-
| `
|
|
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. |
|
|
631
814
|
|
|
632
815
|
```tsx
|
|
633
816
|
import { useQueryClient } from "@tanstack/react-query";
|
|
634
|
-
import {
|
|
817
|
+
import { zamaQueryKeys } from "@zama-fhe/react-sdk";
|
|
635
818
|
|
|
636
819
|
const queryClient = useQueryClient();
|
|
637
820
|
|
|
638
821
|
// Invalidate all balances
|
|
639
|
-
queryClient.invalidateQueries({ queryKey:
|
|
822
|
+
queryClient.invalidateQueries({ queryKey: zamaQueryKeys.confidentialBalance.all });
|
|
640
823
|
|
|
641
824
|
// Invalidate a specific token's balance
|
|
642
825
|
queryClient.invalidateQueries({
|
|
643
|
-
queryKey:
|
|
826
|
+
queryKey: zamaQueryKeys.confidentialBalance.token("0xTokenAddress"),
|
|
644
827
|
});
|
|
645
828
|
```
|
|
646
829
|
|
|
@@ -673,62 +856,148 @@ All write hooks return `{ mutate, mutateAsync, ...mutation }` from wagmi's `useW
|
|
|
673
856
|
| `useUnwrapFromBalance()` | `(token, from, to, encryptedBalance)` | Unwrap using on-chain handle. |
|
|
674
857
|
| `useFinalizeUnwrap()` | `(wrapper, burntAmount, cleartext, proof)` | Finalize unwrap. |
|
|
675
858
|
| `useSetOperator()` | `(token, spender, timestamp?)` | Set operator approval. |
|
|
676
|
-
| `
|
|
677
|
-
| `
|
|
859
|
+
| `useShield()` | `(wrapper, to, amount)` | Shield ERC-20 tokens. |
|
|
860
|
+
| `useShieldETH()` | `(wrapper, to, amount, value)` | Shield native ETH. |
|
|
678
861
|
|
|
679
862
|
### Wagmi Signer Adapter
|
|
680
863
|
|
|
681
864
|
```ts
|
|
682
865
|
import { WagmiSigner } from "@zama-fhe/react-sdk/wagmi";
|
|
683
866
|
|
|
684
|
-
const signer = new WagmiSigner(wagmiConfig);
|
|
867
|
+
const signer = new WagmiSigner({ config: wagmiConfig });
|
|
685
868
|
```
|
|
686
869
|
|
|
687
|
-
##
|
|
870
|
+
## Signer Adapters
|
|
688
871
|
|
|
689
|
-
|
|
872
|
+
Signer adapters are provided by the core SDK package:
|
|
690
873
|
|
|
691
|
-
|
|
874
|
+
```ts
|
|
875
|
+
import { ViemSigner } from "@zama-fhe/sdk/viem";
|
|
876
|
+
import { EthersSigner } from "@zama-fhe/sdk/ethers";
|
|
877
|
+
```
|
|
692
878
|
|
|
693
|
-
|
|
879
|
+
## Wallet Integration Guide
|
|
694
880
|
|
|
695
|
-
|
|
696
|
-
- **ethers:** First parameter is `Provider | Signer`.
|
|
881
|
+
### SSR / Next.js
|
|
697
882
|
|
|
698
|
-
|
|
883
|
+
All components using SDK hooks must be client components. Add `"use client"` at the top of files that import from `@zama-fhe/react-sdk`. FHE operations (encryption, decryption) run in a Web Worker and require browser APIs — they cannot execute on the server.
|
|
699
884
|
|
|
700
|
-
|
|
885
|
+
```tsx
|
|
886
|
+
"use client";
|
|
701
887
|
|
|
702
|
-
|
|
703
|
-
|
|
888
|
+
import { useConfidentialBalance } from "@zama-fhe/react-sdk";
|
|
889
|
+
```
|
|
704
890
|
|
|
705
|
-
|
|
891
|
+
Place `ZamaProvider` inside your client-only layout. Do **not** create the relayer or signer at the module level in a server component — wrap them in a client component or use lazy initialization.
|
|
706
892
|
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
893
|
+
### FHE Credentials Lifecycle
|
|
894
|
+
|
|
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
|
+
```
|
|
921
|
+
|
|
922
|
+
This keeps the encrypted credentials in IndexedDB (persistent) while the unlock signature lives in `chrome.storage.session` (ephemeral, cleared when the browser closes).
|
|
923
|
+
|
|
924
|
+
### Error-to-User-Message Mapping
|
|
925
|
+
|
|
926
|
+
Map SDK errors to user-friendly messages in your UI:
|
|
927
|
+
|
|
928
|
+
```tsx
|
|
929
|
+
import {
|
|
930
|
+
SigningRejectedError,
|
|
931
|
+
EncryptionFailedError,
|
|
932
|
+
DecryptionFailedError,
|
|
933
|
+
TransactionRevertedError,
|
|
934
|
+
ApprovalFailedError,
|
|
935
|
+
} from "@zama-fhe/react-sdk";
|
|
936
|
+
|
|
937
|
+
function getUserMessage(error: Error): string {
|
|
938
|
+
if (error instanceof SigningRejectedError)
|
|
939
|
+
return "Transaction cancelled — please approve in your wallet.";
|
|
940
|
+
if (error instanceof EncryptionFailedError) return "Encryption failed — please try again.";
|
|
941
|
+
if (error instanceof DecryptionFailedError) return "Decryption failed — please try again.";
|
|
942
|
+
if (error instanceof ApprovalFailedError) return "Token approval failed — please try again.";
|
|
943
|
+
if (error instanceof TransactionRevertedError)
|
|
944
|
+
return "Transaction failed on-chain — check your balance.";
|
|
945
|
+
return "An unexpected error occurred.";
|
|
946
|
+
}
|
|
947
|
+
```
|
|
948
|
+
|
|
949
|
+
Or use `matchZamaError` for a more concise pattern:
|
|
950
|
+
|
|
951
|
+
```tsx
|
|
952
|
+
import { matchZamaError } from "@zama-fhe/react-sdk";
|
|
953
|
+
|
|
954
|
+
const message = matchZamaError(error, {
|
|
955
|
+
SIGNING_REJECTED: () => "Transaction cancelled — please approve in your wallet.",
|
|
956
|
+
ENCRYPTION_FAILED: () => "Encryption failed — please try again.",
|
|
957
|
+
DECRYPTION_FAILED: () => "Decryption failed — please try again.",
|
|
958
|
+
APPROVAL_FAILED: () => "Token approval failed — please try again.",
|
|
959
|
+
TRANSACTION_REVERTED: () => "Transaction failed on-chain — check your balance.",
|
|
960
|
+
_: () => "An unexpected error occurred.",
|
|
961
|
+
});
|
|
962
|
+
```
|
|
963
|
+
|
|
964
|
+
### Balance Caching and Refresh
|
|
965
|
+
|
|
966
|
+
Balance queries use two-phase polling:
|
|
967
|
+
|
|
968
|
+
1. **Phase 1 (cheap)** — Polls the encrypted balance handle via a read-only RPC call at `handleRefetchInterval` (default: 10s).
|
|
969
|
+
2. **Phase 2 (expensive)** — Only when the handle changes (i.e. balance updated on-chain), triggers an FHE decryption via the relayer.
|
|
970
|
+
|
|
971
|
+
This means balances update within `handleRefetchInterval` ms of any on-chain change, without wasting decryption resources. Mutation hooks (`useConfidentialTransfer`, `useShield`, `useUnshield`, etc.) automatically invalidate the relevant caches on success, so the UI updates immediately after user actions.
|
|
972
|
+
|
|
973
|
+
To force a refresh:
|
|
974
|
+
|
|
975
|
+
```tsx
|
|
976
|
+
const queryClient = useQueryClient();
|
|
977
|
+
queryClient.invalidateQueries({ queryKey: zamaQueryKeys.confidentialBalance.all });
|
|
711
978
|
```
|
|
712
979
|
|
|
713
980
|
## Re-exports from Core SDK
|
|
714
981
|
|
|
715
982
|
All public exports from `@zama-fhe/sdk` are re-exported from the main entry point. You never need to import from the core package directly.
|
|
716
983
|
|
|
717
|
-
**Classes:** `RelayerWeb`, `
|
|
984
|
+
**Classes:** `RelayerWeb`, `ZamaSDK`, `Token`, `ReadonlyToken`, `MemoryStorage`, `memoryStorage`, `IndexedDBStorage`, `indexedDBStorage`, `CredentialsManager`.
|
|
718
985
|
|
|
719
986
|
**Network configs:** `SepoliaConfig`, `MainnetConfig`, `HardhatConfig`.
|
|
720
987
|
|
|
721
|
-
**
|
|
988
|
+
**Pending unshield:** `savePendingUnshield`, `loadPendingUnshield`, `clearPendingUnshield`.
|
|
989
|
+
|
|
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`.
|
|
722
991
|
|
|
723
|
-
**Errors:** `
|
|
992
|
+
**Errors:** `ZamaError`, `ZamaErrorCode`, `SigningRejectedError`, `SigningFailedError`, `EncryptionFailedError`, `DecryptionFailedError`, `ApprovalFailedError`, `TransactionRevertedError`, `InvalidKeypairError`, `NoCiphertextError`, `RelayerRequestFailedError`, `matchZamaError`.
|
|
724
993
|
|
|
725
994
|
**Constants:** `ZERO_HANDLE`, `ERC7984_INTERFACE_ID`, `ERC7984_WRAPPER_INTERFACE_ID`.
|
|
726
995
|
|
|
727
996
|
**ABIs:** `ERC20_ABI`, `ERC20_METADATA_ABI`, `DEPLOYMENT_COORDINATOR_ABI`, `ERC165_ABI`, `ENCRYPTION_ABI`, `FEE_MANAGER_ABI`, `TRANSFER_BATCHER_ABI`, `WRAPPER_ABI`, `BATCH_SWAP_ABI`.
|
|
728
997
|
|
|
729
|
-
**Events:** `RawLog`, `ConfidentialTransferEvent`, `WrappedEvent`, `UnwrapRequestedEvent`, `UnwrappedFinalizedEvent`, `UnwrappedStartedEvent`, `
|
|
998
|
+
**Events:** `RawLog`, `ConfidentialTransferEvent`, `WrappedEvent`, `UnwrapRequestedEvent`, `UnwrappedFinalizedEvent`, `UnwrappedStartedEvent`, `OnChainEvent`, `Topics`, `TOKEN_TOPICS`.
|
|
730
999
|
|
|
731
|
-
**Event decoders:** `decodeConfidentialTransfer`, `decodeWrapped`, `decodeUnwrapRequested`, `decodeUnwrappedFinalized`, `decodeUnwrappedStarted`, `
|
|
1000
|
+
**Event decoders:** `decodeConfidentialTransfer`, `decodeWrapped`, `decodeUnwrapRequested`, `decodeUnwrappedFinalized`, `decodeUnwrappedStarted`, `decodeOnChainEvent`, `decodeOnChainEvents`, `findUnwrapRequested`, `findWrapped`.
|
|
732
1001
|
|
|
733
1002
|
**Activity feed:** `ActivityDirection`, `ActivityType`, `ActivityAmount`, `ActivityLogMetadata`, `ActivityItem`, `parseActivityFeed`, `extractEncryptedHandles`, `applyDecryptedValues`, `sortByBlockNumber`.
|
|
734
1003
|
|