@tokenops/sdk 1.1.1 → 1.6.0
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/CHANGELOG.md +158 -2
- package/README.md +18 -8
- package/SECURITY.md +7 -1
- package/dist/{chunk-56UI7LUR.cjs → chunk-2RNW4MIJ.cjs} +37 -0
- package/dist/{chunk-VDXVNZCO.cjs → chunk-43RFBQ73.cjs} +85 -29
- package/dist/{chunk-BE2AIZ3K.js → chunk-46T67CE2.js} +1 -1
- package/dist/{chunk-WRCUDSUJ.js → chunk-4KJ66YRH.js} +61 -3
- package/dist/{chunk-ITQ7WKVC.cjs → chunk-4ZCXK4VI.cjs} +68 -8
- package/dist/{chunk-JFLEEXKP.js → chunk-6WSNS3UV.js} +58 -2
- package/dist/{chunk-W7JHOK7G.cjs → chunk-7G7UOQV4.cjs} +4 -4
- package/dist/{chunk-5KHIQG7Y.cjs → chunk-AYGRYDBX.cjs} +35 -36
- package/dist/{chunk-5SGMJADP.cjs → chunk-BD4LZBVF.cjs} +85 -9
- package/dist/{chunk-OYLZEEHF.cjs → chunk-BK7YIVLK.cjs} +304 -179
- package/dist/{chunk-SEKC7H5Y.cjs → chunk-CBRL2PJA.cjs} +12 -11
- package/dist/{chunk-XWDVPV42.js → chunk-CNP4L3GF.js} +4 -4
- package/dist/{chunk-IVE3QEGD.js → chunk-DRSPMIZ7.js} +28 -1
- package/dist/{chunk-SAGJIEQK.cjs → chunk-EUKPOXWR.cjs} +15 -16
- package/dist/chunk-FT4LNBOS.js +11 -0
- package/dist/{chunk-ITQBDRWX.js → chunk-HETNKZEE.js} +1 -1
- package/dist/{chunk-JJ4R5QXF.js → chunk-KSDSXJ34.js} +1 -1
- package/dist/{chunk-SYHXDHWX.cjs → chunk-LBWRFZR3.cjs} +218 -31
- package/dist/{chunk-ZXCOJY2Z.js → chunk-NFW7AUEX.js} +1 -1
- package/dist/{chunk-FPQBFIUW.cjs → chunk-OL6SHN3D.cjs} +3 -3
- package/dist/{chunk-XSNLAS5M.js → chunk-PD7ME2BT.js} +75 -2
- package/dist/{chunk-FXCW7LVB.js → chunk-QET3Q4JP.js} +94 -9
- package/dist/{chunk-M7V2EDPB.js → chunk-QKKBBH7I.js} +2 -2
- package/dist/{chunk-XXXDQSHE.js → chunk-S2XD75JM.js} +12 -3
- package/dist/{chunk-5SA2HF2W.cjs → chunk-SPGSO5SO.cjs} +31 -22
- package/dist/{chunk-Q7ARQSUH.cjs → chunk-SYHNZSZZ.cjs} +3 -3
- package/dist/{chunk-X56UVEXS.js → chunk-TN65XNTI.js} +248 -120
- package/dist/chunk-U57COLUE.js +56 -0
- package/dist/{chunk-OQZAZIAS.js → chunk-UE5XK2SY.js} +193 -6
- package/dist/{chunk-NS44KBV5.cjs → chunk-UJS4N2XM.cjs} +12 -12
- package/dist/{chunk-IR5AK5U5.js → chunk-V5D7BHW3.js} +4 -5
- package/dist/{chunk-3PQ2RFPC.js → chunk-VHSNYUYV.js} +5 -4
- package/dist/{chunk-CQIPRNS7.cjs → chunk-VR3FREBX.cjs} +3 -3
- package/dist/{chunk-G7G75C46.cjs → chunk-WO72UBQD.cjs} +11 -11
- package/dist/chunk-WOEETTH7.cjs +59 -0
- package/dist/{chunk-QE7ZONJ2.js → chunk-WTK6JDSI.js} +4 -5
- package/dist/{chunk-3ZRHDTEX.cjs → chunk-WUXUWTFW.cjs} +3 -3
- package/dist/{chunk-23F7JIK5.cjs → chunk-YFIWCYHC.cjs} +141 -54
- package/dist/{chunk-FYQ2UW4T.js → chunk-YPYCWLYP.js} +1 -1
- package/dist/chunk-ZQUE2B3Q.cjs +33 -0
- package/dist/core/addresses.d.ts +1 -1
- package/dist/core/errors.d.ts +41 -1
- package/dist/core/revert-mapper.d.ts +77 -0
- package/dist/core/wagmi-compat.d.ts +40 -0
- package/dist/fhe/index.cjs +134 -68
- package/dist/fhe/index.d.cts +2 -1
- package/dist/fhe/index.d.ts +2 -1
- package/dist/fhe/index.js +64 -10
- package/dist/fhe/mock-erc7984.d.ts +4 -4
- package/dist/fhe/operators.d.ts +142 -2
- package/dist/fhe/react/index.cjs +21 -8
- package/dist/fhe/react/index.d.cts +2 -0
- package/dist/fhe/react/index.d.ts +2 -0
- package/dist/fhe/react/index.js +8 -3
- package/dist/fhe/react/useEnsureOperator.d.ts +56 -0
- package/dist/fhe/react/useIsOperator.d.ts +54 -0
- package/dist/fhe/sepolia-encryptor-web.d.ts +45 -4
- package/dist/fhe/sepolia-encryptor.d.ts +38 -0
- package/dist/fhe-airdrop/advanced/index.cjs +9 -9
- package/dist/fhe-airdrop/advanced/index.js +7 -7
- package/dist/fhe-airdrop/advanced/react/index.cjs +14 -14
- package/dist/fhe-airdrop/advanced/react/index.js +10 -10
- package/dist/fhe-airdrop/airdrop.d.ts +9 -0
- package/dist/fhe-airdrop/encryption.d.ts +8 -0
- package/dist/fhe-airdrop/factory.d.ts +86 -1
- package/dist/fhe-airdrop/index.cjs +69 -66
- package/dist/fhe-airdrop/index.d.cts +3 -3
- package/dist/fhe-airdrop/index.d.ts +3 -3
- package/dist/fhe-airdrop/index.js +7 -8
- package/dist/fhe-airdrop/react/index.cjs +176 -135
- package/dist/fhe-airdrop/react/index.d.cts +7 -4
- package/dist/fhe-airdrop/react/index.d.ts +7 -4
- package/dist/fhe-airdrop/react/index.js +43 -16
- package/dist/fhe-airdrop/react/useAccessClaimAmount.d.ts +17 -11
- package/dist/fhe-airdrop/react/useAirdropIsSignatureValid.d.ts +3 -2
- package/dist/fhe-airdrop/react/useClaim.d.ts +10 -0
- package/dist/fhe-airdrop/react/useCreateAndFundConfidentialAirdrop.d.ts +8 -0
- package/dist/fhe-airdrop/react/useCreateAndFundConfidentialAirdropAndGetAddress.d.ts +8 -0
- package/dist/fhe-airdrop/react/useFundConfidentialAirdrop.d.ts +8 -0
- package/dist/fhe-airdrop/react/usePreflightCreateAirdrop.d.ts +51 -0
- package/dist/fhe-airdrop/react/useSignClaimAuthorization.d.ts +1 -1
- package/dist/fhe-airdrop/types.d.ts +56 -0
- package/dist/fhe-disperse/encryption.d.ts +8 -0
- package/dist/fhe-disperse/errors.d.ts +55 -0
- package/dist/fhe-disperse/index.cjs +77 -66
- package/dist/fhe-disperse/index.d.cts +2 -2
- package/dist/fhe-disperse/index.d.ts +2 -2
- package/dist/fhe-disperse/index.js +8 -9
- package/dist/fhe-disperse/react/index.cjs +108 -87
- package/dist/fhe-disperse/react/index.d.cts +4 -2
- package/dist/fhe-disperse/react/index.d.ts +4 -2
- package/dist/fhe-disperse/react/index.js +12 -11
- package/dist/fhe-disperse/react/useCalculateFee.d.ts +7 -0
- package/dist/fhe-disperse/react/useDisperse.d.ts +9 -0
- package/dist/fhe-disperse/react/usePreflightDisperse.d.ts +7 -0
- package/dist/fhe-disperse/react/useSingletonCalculateFee.d.ts +7 -0
- package/dist/fhe-disperse/react/useSingletonWithdrawTokenFee.d.ts +6 -0
- package/dist/fhe-disperse/react/useWithdrawTokenFee.d.ts +6 -0
- package/dist/fhe-disperse/singleton.d.ts +29 -0
- package/dist/fhe-disperse/subtotals.d.ts +6 -0
- package/dist/fhe-vesting/advanced/index.cjs +8 -9
- package/dist/fhe-vesting/advanced/index.js +6 -7
- package/dist/fhe-vesting/advanced/react/index.cjs +15 -15
- package/dist/fhe-vesting/advanced/react/index.js +12 -12
- package/dist/fhe-vesting/encryption.d.ts +8 -0
- package/dist/fhe-vesting/index.cjs +82 -79
- package/dist/fhe-vesting/index.d.cts +2 -2
- package/dist/fhe-vesting/index.d.ts +2 -2
- package/dist/fhe-vesting/index.js +9 -10
- package/dist/fhe-vesting/manager.d.ts +119 -1
- package/dist/fhe-vesting/react/index.cjs +264 -224
- package/dist/fhe-vesting/react/index.d.cts +9 -6
- package/dist/fhe-vesting/react/index.d.ts +9 -6
- package/dist/fhe-vesting/react/index.js +44 -21
- package/dist/fhe-vesting/react/useAccessClaimableAmount.d.ts +11 -3
- package/dist/fhe-vesting/react/useAccessSettledAmount.d.ts +11 -3
- package/dist/fhe-vesting/react/useAccessTotalAllocation.d.ts +11 -3
- package/dist/fhe-vesting/react/useAccessVestedAmount.d.ts +11 -3
- package/dist/fhe-vesting/react/useAdminClaim.d.ts +2 -0
- package/dist/fhe-vesting/react/useAdminGetClaimableAmount.d.ts +1 -1
- package/dist/fhe-vesting/react/useAdminGetSettledAmount.d.ts +1 -1
- package/dist/fhe-vesting/react/useAdminGetTotalAllocation.d.ts +1 -1
- package/dist/fhe-vesting/react/useAdminGetVestedAmount.d.ts +1 -1
- package/dist/fhe-vesting/react/useAdminPartialClaim.d.ts +10 -0
- package/dist/fhe-vesting/react/useBatchCreateVesting.d.ts +8 -0
- package/dist/fhe-vesting/react/useClaim.d.ts +3 -1
- package/dist/fhe-vesting/react/useCreateVesting.d.ts +8 -0
- package/dist/fhe-vesting/react/useDiscloseHandleToParty.d.ts +1 -1
- package/dist/fhe-vesting/react/useManagerDiscloseHandleToParty.d.ts +1 -1
- package/dist/fhe-vesting/react/useManagerWithdrawTokenFee.d.ts +6 -0
- package/dist/fhe-vesting/react/usePartialClaim.d.ts +9 -1
- package/dist/fhe-vesting/react/usePreflightCreateVesting.d.ts +37 -0
- package/dist/fhe-vesting/react/useVestingClaim.d.ts +2 -0
- package/dist/fhe-vesting/react/useVestingInfo.d.ts +1 -1
- package/dist/fhe-vesting/react/useWithdrawAdmin.d.ts +6 -0
- package/dist/fhe-vesting/react/useWithdrawTokenFee.d.ts +6 -0
- package/dist/fhe-vesting/types.d.ts +45 -0
- package/dist/index.cjs +93 -86
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +2 -3
- package/dist/testnet-faucet/index.cjs +58 -55
- package/dist/testnet-faucet/index.d.cts +1 -1
- package/dist/testnet-faucet/index.d.ts +1 -1
- package/dist/testnet-faucet/index.js +5 -6
- package/dist/testnet-faucet/react/index.cjs +60 -56
- package/dist/testnet-faucet/react/index.d.cts +3 -2
- package/dist/testnet-faucet/react/index.d.ts +3 -2
- package/dist/testnet-faucet/react/index.js +11 -11
- package/dist/testnet-faucet/react/useConfidentialBalance.d.ts +3 -2
- package/dist/testnet-faucet/react/useUnderlyingBalance.d.ts +2 -2
- package/package.json +14 -8
- package/dist/chunk-66IHPTOK.cjs +0 -20
- package/dist/chunk-KWFFIJYX.js +0 -11
- package/dist/fhe-airdrop/react/useAirdropClaim.d.ts +0 -25
- package/dist/fhe-airdrop/react/useGetClaimAmount.d.ts +0 -30
- package/dist/fhe-vesting/react/useGetClaimableAmount.d.ts +0 -13
- package/dist/fhe-vesting/react/useGetSettledAmount.d.ts +0 -14
- package/dist/fhe-vesting/react/useGetTotalAllocation.d.ts +0 -13
- package/dist/fhe-vesting/react/useGetVestedAmount.d.ts +0 -25
package/dist/fhe/index.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
export { ERC7984_OPERATOR_MAX_DEADLINE, ERC7984_SET_OPERATOR_ABI, revokeOperator, setOperator } from '../chunk-
|
|
1
|
+
export { ERC7984_OPERATOR_MAX_DEADLINE, ERC7984_SET_OPERATOR_ABI, ensureOperator, isOperator, revokeOperator, setOperator } from '../chunk-4KJ66YRH.js';
|
|
2
|
+
export { FHE_SPLIT_DENOMINATOR, scaleRatio, share } from '../chunk-PD7ME2BT.js';
|
|
3
|
+
export { ACL_ALLOWED_EVENT, FHEVM_ACL_ADDRESS_BY_CHAIN, getFhevmAclAddress, requireFhevmAclAddress } from '../chunk-YPYCWLYP.js';
|
|
2
4
|
export { erc7984OperatorAbi } from '../chunk-7VELUOMI.js';
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
5
|
+
import { normaliseAddress } from '../chunk-46T67CE2.js';
|
|
6
|
+
import { TokenOpsContractError } from '../chunk-DRSPMIZ7.js';
|
|
7
|
+
export { AccessDeniedError, AlreadyInitializedError, BatchTooLargeError, ContractRevertError, DecryptionFailedError, DeploymentAddressUnavailableError, EncryptionFailedError, FeatureDisabledError, FheHandleNotAllowedError, InsufficientBalanceError, InsufficientFeeError, InsufficientGasFundsError, InvalidArgumentError, InvalidSignatureError, MissingAccountError, MissingClientError, MissingEncryptorError, MissingPublicClientError, MissingWalletClientError, NetworkError, OperatorNotApprovedError, PausedError, ReceiptEventAmbiguousError, ReceiptEventNotFoundError, ReentrancyError, RelayerUnreachableError, SigningFailedError, TokenOpsContractError, TokenOpsSdkError, TokenOpsValidationError, TransferFailedError, UnknownWriteFailureError, UnsupportedChainError, UserDecryptNotAllowedError, UserRejectedSignatureError, WalletChainMismatchError, WalletRejectedError, isTokenOpsSdkError } from '../chunk-DRSPMIZ7.js';
|
|
6
8
|
import { withTelemetry } from '../chunk-Q2GP5UDC.js';
|
|
7
|
-
import { TokenOpsContractError } from '../chunk-IVE3QEGD.js';
|
|
8
|
-
export { AccessDeniedError, AlreadyInitializedError, BatchTooLargeError, ContractRevertError, DecryptionFailedError, DeploymentAddressUnavailableError, EncryptionFailedError, FeatureDisabledError, FheHandleNotAllowedError, InsufficientBalanceError, InsufficientFeeError, InsufficientGasFundsError, InvalidArgumentError, InvalidSignatureError, MissingAccountError, MissingClientError, MissingEncryptorError, MissingPublicClientError, MissingWalletClientError, NetworkError, PausedError, ReceiptEventAmbiguousError, ReceiptEventNotFoundError, ReentrancyError, RelayerUnreachableError, SigningFailedError, TokenOpsContractError, TokenOpsSdkError, TokenOpsValidationError, TransferFailedError, UnknownWriteFailureError, UnsupportedChainError, UserDecryptNotAllowedError, UserRejectedSignatureError, WalletChainMismatchError, WalletRejectedError, isTokenOpsSdkError } from '../chunk-IVE3QEGD.js';
|
|
9
9
|
import { RelayerWeb, MainnetConfig, SepoliaConfig } from '@zama-fhe/sdk';
|
|
10
10
|
|
|
11
11
|
// src/fhe/mock-encryptor.ts
|
|
@@ -22,7 +22,8 @@ async function requirePeerDep(spec, hint) {
|
|
|
22
22
|
throw new Error(
|
|
23
23
|
`@tokenops/sdk: peer dependency "${spec}" is required for createMockEncryptor.
|
|
24
24
|
install it with: ${hint}
|
|
25
|
-
underlying error: ${String(err)}
|
|
25
|
+
underlying error: ${String(err)}`,
|
|
26
|
+
{ cause: err }
|
|
26
27
|
);
|
|
27
28
|
}
|
|
28
29
|
}
|
|
@@ -302,12 +303,21 @@ async function requirePeerDep2(spec, hint) {
|
|
|
302
303
|
throw new Error(
|
|
303
304
|
`@tokenops/sdk: peer dependency "${spec}" is required for createSepoliaEncryptor.
|
|
304
305
|
install it with: ${hint}
|
|
305
|
-
underlying error: ${String(err)}
|
|
306
|
+
underlying error: ${String(err)}`,
|
|
307
|
+
{ cause: err }
|
|
306
308
|
);
|
|
307
309
|
}
|
|
308
310
|
}
|
|
309
311
|
async function createSepoliaEncryptor(options = {}) {
|
|
310
312
|
const chainId = options.chainId ?? SEPOLIA_CHAIN_ID;
|
|
313
|
+
const firePhase = (phase) => {
|
|
314
|
+
if (!options.onPhase) return;
|
|
315
|
+
try {
|
|
316
|
+
options.onPhase(phase);
|
|
317
|
+
} catch {
|
|
318
|
+
}
|
|
319
|
+
};
|
|
320
|
+
firePhase("initializing");
|
|
311
321
|
const zamaSdkNode = await requirePeerDep2(
|
|
312
322
|
"@zama-fhe/sdk/node",
|
|
313
323
|
"pnpm add @zama-fhe/sdk@^3"
|
|
@@ -336,11 +346,29 @@ async function createSepoliaEncryptor(options = {}) {
|
|
|
336
346
|
fheArtifactStorage: options.fheArtifactStorage,
|
|
337
347
|
fheArtifactCacheTTL: options.fheArtifactCacheTTL
|
|
338
348
|
});
|
|
349
|
+
let initState = "idle";
|
|
339
350
|
return {
|
|
340
351
|
instance,
|
|
341
352
|
chainId,
|
|
342
353
|
async encrypt({ values, contractAddress, userAddress }) {
|
|
343
|
-
|
|
354
|
+
const startedInit = initState === "idle";
|
|
355
|
+
if (startedInit) {
|
|
356
|
+
initState = "in-flight";
|
|
357
|
+
firePhase("downloading-params");
|
|
358
|
+
}
|
|
359
|
+
try {
|
|
360
|
+
const result = await instance.encrypt({ values, contractAddress, userAddress });
|
|
361
|
+
if (initState !== "ready") {
|
|
362
|
+
initState = "ready";
|
|
363
|
+
firePhase("ready");
|
|
364
|
+
}
|
|
365
|
+
return result;
|
|
366
|
+
} catch (err) {
|
|
367
|
+
if (startedInit && initState === "in-flight") {
|
|
368
|
+
initState = "idle";
|
|
369
|
+
}
|
|
370
|
+
throw err;
|
|
371
|
+
}
|
|
344
372
|
},
|
|
345
373
|
terminate() {
|
|
346
374
|
instance.terminate();
|
|
@@ -374,10 +402,36 @@ function createSepoliaEncryptorWeb(opts) {
|
|
|
374
402
|
},
|
|
375
403
|
...opts.logger
|
|
376
404
|
} : void 0;
|
|
405
|
+
const firePhase = (phase) => {
|
|
406
|
+
if (!opts.onPhase) return;
|
|
407
|
+
try {
|
|
408
|
+
opts.onPhase(phase);
|
|
409
|
+
} catch {
|
|
410
|
+
}
|
|
411
|
+
};
|
|
412
|
+
firePhase("initializing");
|
|
413
|
+
const onStatusChange = opts.onPhase ? (status) => {
|
|
414
|
+
if (status === "initializing") {
|
|
415
|
+
firePhase("downloading-params");
|
|
416
|
+
} else if (status === "ready") {
|
|
417
|
+
firePhase("ready");
|
|
418
|
+
}
|
|
419
|
+
} : void 0;
|
|
420
|
+
if (opts.threads !== void 0 && opts.threads > 1) {
|
|
421
|
+
const isolated = globalThis.crossOriginIsolated === true;
|
|
422
|
+
if (!isolated) {
|
|
423
|
+
const warn = safeLogger?.warn ?? console.warn;
|
|
424
|
+
warn(
|
|
425
|
+
`@tokenops/sdk: createSepoliaEncryptorWeb({ threads: ${opts.threads} }) \u2014 this page is NOT cross-origin isolated, so SharedArrayBuffer is unavailable and encryption will run single-threaded. Serve \`Cross-Origin-Opener-Policy: same-origin\` + \`Cross-Origin-Embedder-Policy: require-corp\` to enable the worker pool, or omit \`threads\`.`
|
|
426
|
+
);
|
|
427
|
+
}
|
|
428
|
+
}
|
|
377
429
|
const instance = new RelayerWeb({
|
|
378
430
|
transports: { [chainId]: transportConfig },
|
|
379
431
|
getChainId: () => Promise.resolve(chainId),
|
|
380
|
-
logger: safeLogger
|
|
432
|
+
logger: safeLogger,
|
|
433
|
+
onStatusChange,
|
|
434
|
+
...opts.threads !== void 0 ? { threads: opts.threads } : {}
|
|
381
435
|
});
|
|
382
436
|
return Promise.resolve({
|
|
383
437
|
instance,
|
|
@@ -76,12 +76,12 @@ export interface MintMockERC7984Result {
|
|
|
76
76
|
*
|
|
77
77
|
* @example
|
|
78
78
|
* ```ts
|
|
79
|
-
* import { mintMockERC7984
|
|
79
|
+
* import { mintMockERC7984 } from "@tokenops/sdk/fhe";
|
|
80
80
|
*
|
|
81
81
|
* const { hash, blockNumber } = await mintMockERC7984({
|
|
82
82
|
* publicClient,
|
|
83
83
|
* walletClient,
|
|
84
|
-
* token:
|
|
84
|
+
* token: "0xYourMockToken", // MockERC7984Token address
|
|
85
85
|
* to: walletClient.account!.address,
|
|
86
86
|
* amount: 1_000_000n,
|
|
87
87
|
* });
|
|
@@ -119,12 +119,12 @@ export interface MockErc7984Client {
|
|
|
119
119
|
*
|
|
120
120
|
* @example
|
|
121
121
|
* ```ts
|
|
122
|
-
* import { createMockErc7984Client
|
|
122
|
+
* import { createMockErc7984Client } from "@tokenops/sdk/fhe";
|
|
123
123
|
*
|
|
124
124
|
* const token = createMockErc7984Client({
|
|
125
125
|
* publicClient,
|
|
126
126
|
* walletClient,
|
|
127
|
-
* address:
|
|
127
|
+
* address: "0xYourMockToken", // MockERC7984Token address
|
|
128
128
|
* });
|
|
129
129
|
*
|
|
130
130
|
* await token.mint({ to: alice, amount: 1_000_000n });
|
package/dist/fhe/operators.d.ts
CHANGED
|
@@ -108,7 +108,7 @@ export interface SetOperatorArgs {
|
|
|
108
108
|
* await setOperator({
|
|
109
109
|
* publicClient,
|
|
110
110
|
* walletClient,
|
|
111
|
-
* token:
|
|
111
|
+
* token: "0xYourToken", // ERC-7984 token address
|
|
112
112
|
* spender: manager,
|
|
113
113
|
* // deadline defaults to ERC7984_OPERATOR_MAX_DEADLINE (forever).
|
|
114
114
|
* });
|
|
@@ -177,7 +177,7 @@ export interface RevokeOperatorArgs {
|
|
|
177
177
|
* await revokeOperator({
|
|
178
178
|
* publicClient,
|
|
179
179
|
* walletClient,
|
|
180
|
-
* token:
|
|
180
|
+
* token: "0xYourToken", // ERC-7984 token address
|
|
181
181
|
* spender: staleManager, // old manager clone after deploying a new one
|
|
182
182
|
* });
|
|
183
183
|
* // `staleManager` can no longer call `confidentialTransferFrom` against
|
|
@@ -188,3 +188,143 @@ export interface RevokeOperatorArgs {
|
|
|
188
188
|
* step throws. The original viem error is attached as the cause.
|
|
189
189
|
*/
|
|
190
190
|
export declare function revokeOperator(args: RevokeOperatorArgs): Promise<Hex>;
|
|
191
|
+
/** Arguments for {@link isOperator}. Read-only — no wallet required. */
|
|
192
|
+
export interface IsOperatorArgs {
|
|
193
|
+
/** Read-only viem client the `isOperator` view call goes through. */
|
|
194
|
+
publicClient: PublicClient;
|
|
195
|
+
/** ERC-7984 token contract address. */
|
|
196
|
+
token: Address;
|
|
197
|
+
/** Account that owns the tokens (the operator-authorization granter). */
|
|
198
|
+
holder: Address;
|
|
199
|
+
/**
|
|
200
|
+
* Address whose operator status is being checked — typically a manager
|
|
201
|
+
* clone (`/fhe-vesting`), an airdrop clone/factory (`/fhe-airdrop`), or
|
|
202
|
+
* the disperse singleton (`/fhe-disperse`).
|
|
203
|
+
*/
|
|
204
|
+
spender: Address;
|
|
205
|
+
/** Optional telemetry sink — span emits as `fhe.isOperator`. */
|
|
206
|
+
telemetry?: SdkTelemetry;
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Check whether `spender` is currently an authorized ERC-7984 operator for
|
|
210
|
+
* `holder` on `token`. Read-only sibling of {@link setOperator} — the
|
|
211
|
+
* contract-side check is `until >= block.timestamp`, so an expired grant
|
|
212
|
+
* reads `false` here without any revoke transaction having happened.
|
|
213
|
+
*
|
|
214
|
+
* Use this to gate UX ("Approve operator" button vs "Create vesting" button)
|
|
215
|
+
* or as a cheap pre-check before flows that would otherwise fail with
|
|
216
|
+
* {@link OperatorNotApprovedError} — the SDK's mapping of the on-chain
|
|
217
|
+
* `ERC7984UnauthorizedSpender` revert, whose message is the canonical
|
|
218
|
+
* {@link OPERATOR_NOT_APPROVED_REMEDIATION} copy. For a check-then-set in
|
|
219
|
+
* one call, see {@link ensureOperator}.
|
|
220
|
+
*
|
|
221
|
+
* @example
|
|
222
|
+
* ```ts
|
|
223
|
+
* import { isOperator } from "@tokenops/sdk/fhe";
|
|
224
|
+
*
|
|
225
|
+
* const authorized = await isOperator({
|
|
226
|
+
* publicClient,
|
|
227
|
+
* token,
|
|
228
|
+
* holder: account.address,
|
|
229
|
+
* spender: manager,
|
|
230
|
+
* });
|
|
231
|
+
* if (!authorized) {
|
|
232
|
+
* // prompt the user to run setOperator / ensureOperator first
|
|
233
|
+
* }
|
|
234
|
+
* ```
|
|
235
|
+
*
|
|
236
|
+
* @throws {@link TokenOpsContractError} if the read call itself fails (RPC
|
|
237
|
+
* error, non-ERC-7984 token). The original viem error is attached as the
|
|
238
|
+
* cause.
|
|
239
|
+
*/
|
|
240
|
+
export declare function isOperator(args: IsOperatorArgs): Promise<boolean>;
|
|
241
|
+
/**
|
|
242
|
+
* Arguments for {@link ensureOperator}. Same shape as {@link SetOperatorArgs}
|
|
243
|
+
* except `deadline` is **required**: `ensureOperator` only sends a
|
|
244
|
+
* transaction when the authorization is missing, so the expiry it would
|
|
245
|
+
* grant must be an explicit caller decision — the SDK refuses to default a
|
|
246
|
+
* security-sensitive approval window (a silent
|
|
247
|
+
* {@link ERC7984_OPERATOR_MAX_DEADLINE} would grant "forever").
|
|
248
|
+
*/
|
|
249
|
+
export interface EnsureOperatorArgs {
|
|
250
|
+
/** Read-only viem client for the `isOperator` pre-check + receipt waiting. */
|
|
251
|
+
publicClient: PublicClient;
|
|
252
|
+
/** Wallet client used to send the `setOperator` call (only when needed). */
|
|
253
|
+
walletClient: WalletClient;
|
|
254
|
+
/**
|
|
255
|
+
* Account that owns the tokens. Same `Account | Address` semantics and
|
|
256
|
+
* fallback hierarchy as {@link SetOperatorArgs} — also used to derive the
|
|
257
|
+
* `holder` for the read-side `isOperator` pre-check.
|
|
258
|
+
*/
|
|
259
|
+
account?: Account | Address;
|
|
260
|
+
/** ERC-7984 token contract address. */
|
|
261
|
+
token: Address;
|
|
262
|
+
/** Address being authorized to pull tokens. */
|
|
263
|
+
spender: Address;
|
|
264
|
+
/**
|
|
265
|
+
* `uint48` unix timestamp after which the operator authorization expires.
|
|
266
|
+
* Required — scope it to the expected operation window (e.g.
|
|
267
|
+
* `BigInt(Math.floor(Date.now() / 1000) + 3600)` for one hour). Pass
|
|
268
|
+
* {@link ERC7984_OPERATOR_MAX_DEADLINE} only when you explicitly want a
|
|
269
|
+
* never-expiring grant (local dev loops, test fixtures).
|
|
270
|
+
*/
|
|
271
|
+
deadline: bigint;
|
|
272
|
+
/**
|
|
273
|
+
* If `true` (default), waits for the transaction to be mined before
|
|
274
|
+
* returning. Only relevant when a transaction is actually sent.
|
|
275
|
+
*/
|
|
276
|
+
waitForReceipt?: boolean;
|
|
277
|
+
/** Optional telemetry sink — span emits as `fhe.ensureOperator`. */
|
|
278
|
+
telemetry?: SdkTelemetry;
|
|
279
|
+
}
|
|
280
|
+
/** Result of {@link ensureOperator}. */
|
|
281
|
+
export interface EnsureOperatorResult {
|
|
282
|
+
/**
|
|
283
|
+
* `true` when the authorization was already in place and no transaction
|
|
284
|
+
* was sent; `false` when this call performed the `setOperator` write.
|
|
285
|
+
*/
|
|
286
|
+
alreadyOperator: boolean;
|
|
287
|
+
/**
|
|
288
|
+
* Transaction hash of the `setOperator` call, or `null` when no
|
|
289
|
+
* transaction was needed (`alreadyOperator === true`).
|
|
290
|
+
*/
|
|
291
|
+
hash: Hex | null;
|
|
292
|
+
}
|
|
293
|
+
/**
|
|
294
|
+
* Idempotent operator authorization: check {@link isOperator} first and call
|
|
295
|
+
* {@link setOperator} only when the grant is missing. The no-op path sends
|
|
296
|
+
* no transaction and costs one `eth_call`.
|
|
297
|
+
*
|
|
298
|
+
* This is the recommended pre-step before any flow that pulls tokens from
|
|
299
|
+
* the caller's balance (`createVesting` / `batchCreateVesting`,
|
|
300
|
+
* `fundConfidentialAirdrop` / `createAndFundConfidentialAirdrop`, disperse
|
|
301
|
+
* registration) — skipping it fails with {@link OperatorNotApprovedError},
|
|
302
|
+
* the SDK's mapping of the on-chain `ERC7984UnauthorizedSpender` revert,
|
|
303
|
+
* whose message is the canonical {@link OPERATOR_NOT_APPROVED_REMEDIATION}
|
|
304
|
+
* copy.
|
|
305
|
+
*
|
|
306
|
+
* **Note on expiry:** the pre-check only tells you the grant is currently
|
|
307
|
+
* active, not until when. If an existing grant expires mid-flow,
|
|
308
|
+
* `ensureOperator` will not have refreshed it — pass a fresh
|
|
309
|
+
* {@link setOperator} call instead when you need to extend a window.
|
|
310
|
+
*
|
|
311
|
+
* @example
|
|
312
|
+
* ```ts
|
|
313
|
+
* import { ensureOperator } from "@tokenops/sdk/fhe";
|
|
314
|
+
*
|
|
315
|
+
* const oneHour = BigInt(Math.floor(Date.now() / 1000) + 3600);
|
|
316
|
+
* const { alreadyOperator, hash } = await ensureOperator({
|
|
317
|
+
* publicClient,
|
|
318
|
+
* walletClient,
|
|
319
|
+
* token,
|
|
320
|
+
* spender: manager,
|
|
321
|
+
* deadline: oneHour,
|
|
322
|
+
* });
|
|
323
|
+
* // Now safe to call manager.createVesting / factory.fundConfidentialAirdrop / etc.
|
|
324
|
+
* ```
|
|
325
|
+
*
|
|
326
|
+
* @throws {@link TokenOpsContractError} if no holder account can be
|
|
327
|
+
* resolved, if `deadline` is outside `(0, 2**48 - 1]`, or if the
|
|
328
|
+
* read/write/receipt step fails.
|
|
329
|
+
*/
|
|
330
|
+
export declare function ensureOperator(args: EnsureOperatorArgs): Promise<EnsureOperatorResult>;
|
package/dist/fhe/react/index.cjs
CHANGED
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
require('../../chunk-
|
|
4
|
-
|
|
3
|
+
var chunkWOEETTH7_cjs = require('../../chunk-WOEETTH7.cjs');
|
|
4
|
+
require('../../chunk-ZQUE2B3Q.cjs');
|
|
5
|
+
require('../../chunk-4ZCXK4VI.cjs');
|
|
6
|
+
require('../../chunk-FWHYQZ5E.cjs');
|
|
7
|
+
require('../../chunk-VR3FREBX.cjs');
|
|
8
|
+
var chunk2RNW4MIJ_cjs = require('../../chunk-2RNW4MIJ.cjs');
|
|
9
|
+
require('../../chunk-VJKZWYYJ.cjs');
|
|
5
10
|
var react = require('react');
|
|
6
11
|
|
|
7
12
|
function resolveUserDecryptor(source) {
|
|
@@ -35,7 +40,7 @@ function useDecryptedHandle(opts) {
|
|
|
35
40
|
setState({
|
|
36
41
|
status: "error",
|
|
37
42
|
value: void 0,
|
|
38
|
-
error: new
|
|
43
|
+
error: new chunk2RNW4MIJ_cjs.TokenOpsValidationError(
|
|
39
44
|
"useDecryptedHandle: no `userDecryptor` resolved \u2014 pass `userDecryptor: () => useZamaSDK().relayer` (or an eager RelayerSDK / MockFhevmInstance).",
|
|
40
45
|
{ method: "useDecryptedHandle" }
|
|
41
46
|
)
|
|
@@ -52,7 +57,7 @@ function useDecryptedHandle(opts) {
|
|
|
52
57
|
});
|
|
53
58
|
const plain = result[handleStr];
|
|
54
59
|
if (plain === void 0) {
|
|
55
|
-
throw new
|
|
60
|
+
throw new chunk2RNW4MIJ_cjs.TokenOpsValidationError(
|
|
56
61
|
`useDecryptedHandle: relayer returned no value for handle ${handleStr} on contract ${contractStr} \u2014 check ACL grant + (handle, contractAddress, userAddress) triple`,
|
|
57
62
|
{ method: "useDecryptedHandle", contractAddress: contractStr }
|
|
58
63
|
);
|
|
@@ -83,20 +88,28 @@ function serializableSlice(v) {
|
|
|
83
88
|
return out;
|
|
84
89
|
}
|
|
85
90
|
|
|
91
|
+
Object.defineProperty(exports, "useEnsureOperator", {
|
|
92
|
+
enumerable: true,
|
|
93
|
+
get: function () { return chunkWOEETTH7_cjs.useEnsureOperator; }
|
|
94
|
+
});
|
|
95
|
+
Object.defineProperty(exports, "useIsOperator", {
|
|
96
|
+
enumerable: true,
|
|
97
|
+
get: function () { return chunkWOEETTH7_cjs.useIsOperator; }
|
|
98
|
+
});
|
|
86
99
|
Object.defineProperty(exports, "TokenOpsContractError", {
|
|
87
100
|
enumerable: true,
|
|
88
|
-
get: function () { return
|
|
101
|
+
get: function () { return chunk2RNW4MIJ_cjs.TokenOpsContractError; }
|
|
89
102
|
});
|
|
90
103
|
Object.defineProperty(exports, "TokenOpsSdkError", {
|
|
91
104
|
enumerable: true,
|
|
92
|
-
get: function () { return
|
|
105
|
+
get: function () { return chunk2RNW4MIJ_cjs.TokenOpsSdkError; }
|
|
93
106
|
});
|
|
94
107
|
Object.defineProperty(exports, "TokenOpsValidationError", {
|
|
95
108
|
enumerable: true,
|
|
96
|
-
get: function () { return
|
|
109
|
+
get: function () { return chunk2RNW4MIJ_cjs.TokenOpsValidationError; }
|
|
97
110
|
});
|
|
98
111
|
Object.defineProperty(exports, "isTokenOpsSdkError", {
|
|
99
112
|
enumerable: true,
|
|
100
|
-
get: function () { return
|
|
113
|
+
get: function () { return chunk2RNW4MIJ_cjs.isTokenOpsSdkError; }
|
|
101
114
|
});
|
|
102
115
|
exports.useDecryptedHandle = useDecryptedHandle;
|
|
@@ -7,4 +7,6 @@
|
|
|
7
7
|
* `EncryptedHandle` return value).
|
|
8
8
|
*/
|
|
9
9
|
export { useDecryptedHandle, type UseDecryptedHandleOptions, type UseDecryptedHandleResult, type UserDecryptor, type UserDecryptorSource, } from "./use-decrypted-handle.js";
|
|
10
|
+
export { useIsOperator, type UseIsOperatorOptions } from "./useIsOperator.js";
|
|
11
|
+
export { useEnsureOperator, type UseEnsureOperatorOptions, type EnsureOperatorVariables, } from "./useEnsureOperator.js";
|
|
10
12
|
export { TokenOpsSdkError, isTokenOpsSdkError, TokenOpsValidationError, TokenOpsContractError, } from "../../core/errors.js";
|
|
@@ -7,4 +7,6 @@
|
|
|
7
7
|
* `EncryptedHandle` return value).
|
|
8
8
|
*/
|
|
9
9
|
export { useDecryptedHandle, type UseDecryptedHandleOptions, type UseDecryptedHandleResult, type UserDecryptor, type UserDecryptorSource, } from "./use-decrypted-handle.js";
|
|
10
|
+
export { useIsOperator, type UseIsOperatorOptions } from "./useIsOperator.js";
|
|
11
|
+
export { useEnsureOperator, type UseEnsureOperatorOptions, type EnsureOperatorVariables, } from "./useEnsureOperator.js";
|
|
10
12
|
export { TokenOpsSdkError, isTokenOpsSdkError, TokenOpsValidationError, TokenOpsContractError, } from "../../core/errors.js";
|
package/dist/fhe/react/index.js
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
import
|
|
3
|
-
|
|
1
|
+
export { useEnsureOperator, useIsOperator } from '../../chunk-U57COLUE.js';
|
|
2
|
+
import '../../chunk-FT4LNBOS.js';
|
|
3
|
+
import '../../chunk-4KJ66YRH.js';
|
|
4
|
+
import '../../chunk-7VELUOMI.js';
|
|
5
|
+
import '../../chunk-46T67CE2.js';
|
|
6
|
+
import { TokenOpsValidationError } from '../../chunk-DRSPMIZ7.js';
|
|
7
|
+
export { TokenOpsContractError, TokenOpsSdkError, TokenOpsValidationError, isTokenOpsSdkError } from '../../chunk-DRSPMIZ7.js';
|
|
8
|
+
import '../../chunk-Q2GP5UDC.js';
|
|
4
9
|
import { useState, useRef, useEffect } from 'react';
|
|
5
10
|
|
|
6
11
|
function resolveUserDecryptor(source) {
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cross-product mutation hook over {@link ensureOperator} — check-then-set
|
|
3
|
+
* operator authorization that sends no transaction when the grant already
|
|
4
|
+
* exists.
|
|
5
|
+
*
|
|
6
|
+
* Lives in `/fhe/react` (not a product subpath) because the operator
|
|
7
|
+
* prerequisite is identical across all three product flows; the product
|
|
8
|
+
* `react/` barrels re-export it for discoverability.
|
|
9
|
+
*/
|
|
10
|
+
import { type UseMutationResult } from "@tanstack/react-query";
|
|
11
|
+
import type { Account, Address } from "viem";
|
|
12
|
+
import type { SdkTelemetry } from "../../core/telemetry.js";
|
|
13
|
+
import { type EnsureOperatorResult } from "../operators.js";
|
|
14
|
+
/** Hook-level options for {@link useEnsureOperator}. */
|
|
15
|
+
export interface UseEnsureOperatorOptions {
|
|
16
|
+
/** Override the chain id used for client resolution. */
|
|
17
|
+
chainId?: number | undefined;
|
|
18
|
+
/** Optional telemetry adapter — forwarded to the headless helper. */
|
|
19
|
+
telemetry?: SdkTelemetry | undefined;
|
|
20
|
+
}
|
|
21
|
+
/** Per-mutation variables for {@link useEnsureOperator}. */
|
|
22
|
+
export interface EnsureOperatorVariables {
|
|
23
|
+
/** ERC-7984 token contract address. */
|
|
24
|
+
token: Address;
|
|
25
|
+
/** Address being authorized to pull tokens. */
|
|
26
|
+
spender: Address;
|
|
27
|
+
/**
|
|
28
|
+
* `uint48` unix timestamp after which the authorization expires. Required
|
|
29
|
+
* — the expiry window is an explicit caller decision (see
|
|
30
|
+
* {@link ensureOperator}). Pass `ERC7984_OPERATOR_MAX_DEADLINE` only when
|
|
31
|
+
* you explicitly want a never-expiring grant.
|
|
32
|
+
*/
|
|
33
|
+
deadline: bigint;
|
|
34
|
+
/** Override the from-account; defaults to the connected wallet's account. */
|
|
35
|
+
account?: Account | Address;
|
|
36
|
+
/** If `true` (default), waits for the transaction to be mined. */
|
|
37
|
+
waitForReceipt?: boolean;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Ensure `spender` is an ERC-7984 operator for the connected account on
|
|
41
|
+
* `token`, sending a `setOperator` transaction only when the grant is
|
|
42
|
+
* missing. Resolves to `{ alreadyOperator, hash }` — `hash` is `null` on
|
|
43
|
+
* the no-op path.
|
|
44
|
+
*
|
|
45
|
+
* This is the mutation half of the operator-prerequisite pair; use
|
|
46
|
+
* {@link useIsOperator} for the read side, and invalidate/refetch it after
|
|
47
|
+
* this mutation succeeds.
|
|
48
|
+
*
|
|
49
|
+
* @example
|
|
50
|
+
* ```tsx
|
|
51
|
+
* const ensure = useEnsureOperator();
|
|
52
|
+
* const oneHour = BigInt(Math.floor(Date.now() / 1000) + 3600);
|
|
53
|
+
* ensure.mutate({ token, spender: manager, deadline: oneHour });
|
|
54
|
+
* ```
|
|
55
|
+
*/
|
|
56
|
+
export declare function useEnsureOperator(options?: UseEnsureOperatorOptions): UseMutationResult<EnsureOperatorResult, Error, EnsureOperatorVariables>;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cross-product query hook over {@link isOperator} — "is `spender` currently
|
|
3
|
+
* an authorized ERC-7984 operator for `holder` on `token`?".
|
|
4
|
+
*
|
|
5
|
+
* Lives in `/fhe/react` (not a product subpath) because the operator
|
|
6
|
+
* prerequisite is identical across all three product flows; the product
|
|
7
|
+
* `react/` barrels re-export it for discoverability.
|
|
8
|
+
*/
|
|
9
|
+
import { type UseQueryResult } from "@tanstack/react-query";
|
|
10
|
+
import type { Address } from "viem";
|
|
11
|
+
import type { SdkTelemetry } from "../../core/telemetry.js";
|
|
12
|
+
/** Options accepted by {@link useIsOperator}. */
|
|
13
|
+
export interface UseIsOperatorOptions {
|
|
14
|
+
/** ERC-7984 token contract address. Query stays disabled while `undefined`. */
|
|
15
|
+
token?: Address | undefined;
|
|
16
|
+
/**
|
|
17
|
+
* Address whose operator status is being checked — typically a manager
|
|
18
|
+
* clone, an airdrop factory/clone, or the disperse singleton. Query stays
|
|
19
|
+
* disabled while `undefined`.
|
|
20
|
+
*/
|
|
21
|
+
spender?: Address | undefined;
|
|
22
|
+
/**
|
|
23
|
+
* Account that owns the tokens. Defaults to the connected wallet's
|
|
24
|
+
* account. Query stays disabled while neither is available.
|
|
25
|
+
*/
|
|
26
|
+
holder?: Address | undefined;
|
|
27
|
+
/** Override the chain id used for client resolution. */
|
|
28
|
+
chainId?: number | undefined;
|
|
29
|
+
/** Set `false` to pause the query without unmounting. Defaults to `true`. */
|
|
30
|
+
enabled?: boolean | undefined;
|
|
31
|
+
/** Optional telemetry adapter — forwarded to the headless helper. */
|
|
32
|
+
telemetry?: SdkTelemetry | undefined;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Read `spender`'s ERC-7984 operator status for `holder` on `token`.
|
|
36
|
+
*
|
|
37
|
+
* Typical use: gate the "create" call-to-action behind the operator
|
|
38
|
+
* prerequisite so builders never hit {@link OperatorNotApprovedError} — the
|
|
39
|
+
* SDK's mapping of the on-chain `ERC7984UnauthorizedSpender` revert, whose
|
|
40
|
+
* message is the canonical {@link OPERATOR_NOT_APPROVED_REMEDIATION} copy:
|
|
41
|
+
*
|
|
42
|
+
* @example
|
|
43
|
+
* ```tsx
|
|
44
|
+
* const { data: authorized } = useIsOperator({ token, spender: manager });
|
|
45
|
+
* return authorized
|
|
46
|
+
* ? <CreateVestingButton />
|
|
47
|
+
* : <ApproveOperatorButton />; // wire to useEnsureOperator
|
|
48
|
+
* ```
|
|
49
|
+
*
|
|
50
|
+
* After a successful {@link useEnsureOperator} / `setOperator` mutation,
|
|
51
|
+
* invalidate this query (its key starts with
|
|
52
|
+
* `["tokenops-sdk", "fhe", "isOperator", ...]`) or refetch it.
|
|
53
|
+
*/
|
|
54
|
+
export declare function useIsOperator(options?: UseIsOperatorOptions): UseQueryResult<boolean, Error>;
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import type { PublicClient, WalletClient } from "viem";
|
|
2
2
|
import type { Encryptor } from "../fhe-vesting/encryption.js";
|
|
3
|
-
import { type SepoliaEncryptorLogger } from "./sepolia-encryptor.js";
|
|
3
|
+
import { type EncryptorInitPhase, type SepoliaEncryptorLogger } from "./sepolia-encryptor.js";
|
|
4
4
|
/**
|
|
5
5
|
* Configuration for {@link createSepoliaEncryptorWeb}. Minimal by design:
|
|
6
|
-
* the browser path doesn't expose
|
|
7
|
-
*
|
|
8
|
-
*
|
|
6
|
+
* the browser path doesn't expose storage knobs (`RelayerWeb` already
|
|
7
|
+
* defaults to `IndexedDBStorage` for FHE artifact caching). Worker-pool
|
|
8
|
+
* sizing is the one opt-in performance knob — see `threads`; the default
|
|
9
|
+
* stays single-threaded so no special headers are required.
|
|
9
10
|
*/
|
|
10
11
|
export interface CreateSepoliaEncryptorWebOpts {
|
|
11
12
|
/** Viem `PublicClient` — used only to resolve the chain id for the
|
|
@@ -42,6 +43,46 @@ export interface CreateSepoliaEncryptorWebOpts {
|
|
|
42
43
|
* background on why).
|
|
43
44
|
*/
|
|
44
45
|
logger?: SepoliaEncryptorLogger;
|
|
46
|
+
/**
|
|
47
|
+
* Observe the encryptor's initialization lifecycle (see
|
|
48
|
+
* {@link EncryptorInitPhase}) — the signal to drive a loading state around
|
|
49
|
+
* the first in-browser encryption, which downloads several MB of FHE
|
|
50
|
+
* public material.
|
|
51
|
+
*
|
|
52
|
+
* `RelayerWeb` initializes lazily (Web Worker spawn + FHE param fetch
|
|
53
|
+
* happen inside the first operation), so phases map onto its REAL status
|
|
54
|
+
* events, not timers:
|
|
55
|
+
*
|
|
56
|
+
* - `"initializing"` fires synchronously while this helper constructs the
|
|
57
|
+
* `RelayerWeb` instance.
|
|
58
|
+
* - `"downloading-params"` fires when the worker's lazy init actually
|
|
59
|
+
* starts (upstream status `"initializing"`) — worker bring-up plus the
|
|
60
|
+
* FHE public key + params fetch. Near-instant when the IndexedDB
|
|
61
|
+
* artifact cache is warm.
|
|
62
|
+
* - `"ready"` fires when upstream reports `"ready"`.
|
|
63
|
+
*
|
|
64
|
+
* `"downloading-params"` / `"ready"` can fire again if the underlying
|
|
65
|
+
* relayer re-initializes (chain switch, stale artifact cache). Init
|
|
66
|
+
* failures surface as rejections from the pending operation — there is no
|
|
67
|
+
* error phase. No fake progress: no percentages, byte counts, or timers —
|
|
68
|
+
* upstream exposes no download-progress API. Callback exceptions are
|
|
69
|
+
* swallowed so a UI observer can never break encryption.
|
|
70
|
+
*/
|
|
71
|
+
onPhase?: (phase: EncryptorInitPhase) => void;
|
|
72
|
+
/**
|
|
73
|
+
* Opt-in WASM worker-pool size for multi-threaded encryption (forwarded
|
|
74
|
+
* to `RelayerWeb`'s config). `4`–`8` gives ~2–3× faster encryption but
|
|
75
|
+
* requires the page to be **cross-origin isolated** — headers
|
|
76
|
+
* `Cross-Origin-Opener-Policy: same-origin` and
|
|
77
|
+
* `Cross-Origin-Embedder-Policy: require-corp` — without which browsers
|
|
78
|
+
* hide `SharedArrayBuffer` and encryption silently falls back to
|
|
79
|
+
* single-threaded. The SDK logs a loud warning when `threads > 1` is set
|
|
80
|
+
* on a non-isolated page.
|
|
81
|
+
*
|
|
82
|
+
* Omit for the default single-threaded worker — no special headers
|
|
83
|
+
* required.
|
|
84
|
+
*/
|
|
85
|
+
threads?: number;
|
|
45
86
|
}
|
|
46
87
|
/**
|
|
47
88
|
* Returned by {@link createSepoliaEncryptorWeb}. Same structural
|
|
@@ -5,6 +5,24 @@ import type { Encryptor } from "../fhe-vesting/encryption.js";
|
|
|
5
5
|
export declare const SEPOLIA_CHAIN_ID: 11155111;
|
|
6
6
|
/** Mainnet chain id (`1`). Same use as {@link SEPOLIA_CHAIN_ID}. */
|
|
7
7
|
export declare const MAINNET_CHAIN_ID: 1;
|
|
8
|
+
/**
|
|
9
|
+
* Lifecycle phase reported by the `onPhase` callback of
|
|
10
|
+
* {@link createSepoliaEncryptor} / `createSepoliaEncryptorWeb`.
|
|
11
|
+
*
|
|
12
|
+
* - `"initializing"` — the helper started constructing the underlying Zama
|
|
13
|
+
* relayer instance (module resolution + constructor; cheap and local).
|
|
14
|
+
* - `"downloading-params"` — the relayer's real lazy initialization began:
|
|
15
|
+
* worker bring-up plus fetching the FHE public key and public params
|
|
16
|
+
* (several MB on a cold cache; near-instant when served from cache).
|
|
17
|
+
* - `"ready"` — initialization completed; subsequent encrypts skip the
|
|
18
|
+
* download entirely.
|
|
19
|
+
*
|
|
20
|
+
* Phases carry **no** percentages, byte counts, or time estimates — neither
|
|
21
|
+
* `@zama-fhe/sdk@3` nor the underlying relayer SDK exposes any
|
|
22
|
+
* download-progress API, so anything finer-grained would be fabricated.
|
|
23
|
+
* If upstream later exposes real progress this union will widen.
|
|
24
|
+
*/
|
|
25
|
+
export type EncryptorInitPhase = "initializing" | "downloading-params" | "ready";
|
|
8
26
|
/** Subset of `@zama-fhe/sdk/node`'s `GenericLogger` we accept. Mirrored
|
|
9
27
|
* structurally so consumers don't need to import the optional peer dep just
|
|
10
28
|
* to type-narrow a logger arg. */
|
|
@@ -69,6 +87,26 @@ export interface CreateSepoliaEncryptorOptions {
|
|
|
69
87
|
* that want to exercise the fetch path).
|
|
70
88
|
*/
|
|
71
89
|
fheArtifactCacheTTL?: number;
|
|
90
|
+
/**
|
|
91
|
+
* Observe the encryptor's initialization lifecycle (see
|
|
92
|
+
* {@link EncryptorInitPhase}). `RelayerNode` initializes its worker pool
|
|
93
|
+
* lazily and exposes no status events, so the phases bracket the first
|
|
94
|
+
* operation that triggers the real init:
|
|
95
|
+
*
|
|
96
|
+
* - `"initializing"` fires when this helper starts (module load +
|
|
97
|
+
* `RelayerNode` construction).
|
|
98
|
+
* - `"downloading-params"` fires immediately before the first `encrypt`
|
|
99
|
+
* call, which is what actually spawns the worker pool and fetches the
|
|
100
|
+
* FHE public key + params.
|
|
101
|
+
* - `"ready"` fires once that first `encrypt` resolves. If it rejects,
|
|
102
|
+
* `"ready"` is not fired and the next attempt re-fires
|
|
103
|
+
* `"downloading-params"` (the underlying SDK retries init from scratch).
|
|
104
|
+
*
|
|
105
|
+
* No fake progress: no percentages, byte counts, or timers — upstream
|
|
106
|
+
* exposes no download-progress API. Callback exceptions are swallowed so
|
|
107
|
+
* a UI observer can never break encryption.
|
|
108
|
+
*/
|
|
109
|
+
onPhase?: (phase: EncryptorInitPhase) => void;
|
|
72
110
|
}
|
|
73
111
|
/**
|
|
74
112
|
* Returned by {@link createSepoliaEncryptor}. Carries the underlying
|