@zama-fhe/sdk 3.6.0 → 3.7.0-alpha.2
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/dist/cjs/base-signer.cjs +1 -1
- package/dist/cjs/base-signer.cjs.map +1 -1
- package/dist/cjs/chains.cjs +1 -1
- package/dist/cjs/chains.cjs.map +1 -1
- package/dist/cjs/ethers/index.cjs +1 -1
- package/dist/cjs/ethers/index.cjs.map +1 -1
- package/dist/cjs/fhevm-relayer.cjs +2 -2
- package/dist/cjs/fhevm-relayer.cjs.map +1 -1
- package/dist/cjs/index.cjs +1 -1
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/query/index.cjs +1 -1
- package/dist/cjs/query/index.cjs.map +1 -1
- package/dist/cjs/relayer.cjs +1 -1
- package/dist/cjs/relayer.cjs.map +1 -1
- package/dist/cjs/token.cjs +1 -1
- package/dist/cjs/token.cjs.map +1 -1
- package/dist/cjs/viem/index.cjs +1 -1
- package/dist/cjs/viem/index.cjs.map +1 -1
- package/dist/cjs/wrappers-registry.cjs +1 -1
- package/dist/cjs/wrappers-registry.cjs.map +1 -1
- package/dist/esm/base-signer--sBO2qJp.js +2 -0
- package/dist/esm/base-signer--sBO2qJp.js.map +1 -0
- package/dist/esm/{base-signer-Iu5Lszrf.d.ts → base-signer-S2Ogf6L4.d.ts} +2 -2
- package/dist/esm/chains/index.d.ts +1 -1
- package/dist/esm/chains/index.js +1 -1
- package/dist/esm/chains-DEpKup1n.js +2 -0
- package/dist/esm/chains-DEpKup1n.js.map +1 -0
- package/dist/esm/cleartext/index.d.ts +2 -2
- package/dist/esm/cleartext/index.js +1 -1
- package/dist/esm/{cleartext-iE4sWgSP.js → cleartext-DcbDCDXj.js} +2 -2
- package/dist/esm/{cleartext-iE4sWgSP.js.map → cleartext-DcbDCDXj.js.map} +1 -1
- package/dist/esm/{cleartext-B2DI8fgm.d.ts → cleartext-pv2blbFU.d.ts} +2 -2
- package/dist/esm/encrypt.worker.js +51 -51
- package/dist/esm/{encryption-BKoalB4o.js → encryption-DJljZ2oV.js} +2 -2
- package/dist/esm/{encryption-BKoalB4o.js.map → encryption-DJljZ2oV.js.map} +1 -1
- package/dist/esm/ethers/index.d.ts +5 -5
- package/dist/esm/ethers/index.js +1 -1
- package/dist/esm/ethers/index.js.map +1 -1
- package/dist/esm/fhevm-relayer-CPmCytDX.js +8 -0
- package/dist/esm/fhevm-relayer-CPmCytDX.js.map +1 -0
- package/dist/esm/{index-BCh3VaZo.d.ts → index-DRrrBtMX.d.ts} +2000 -1115
- package/dist/esm/{index-ijgDL4IC.d.ts → index-Gk1S0gjO.d.ts} +14 -1
- package/dist/esm/{index-S6QjPkZE.d.ts → index-tfvbrVa2.d.ts} +4 -4
- package/dist/esm/index.d.ts +108 -8
- package/dist/esm/index.js +1 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/node/index.d.ts +4 -4
- package/dist/esm/node/index.js +1 -1
- package/dist/esm/query/index.d.ts +4 -537
- package/dist/esm/query/index.js +1 -1
- package/dist/esm/query/index.js.map +1 -1
- package/dist/esm/relayer-B6Zo6EkX.js +2 -0
- package/dist/esm/relayer-B6Zo6EkX.js.map +1 -0
- package/dist/esm/token-BMQ6xlrk.js +2 -0
- package/dist/esm/{token-BejFVO8m.js.map → token-BMQ6xlrk.js.map} +1 -1
- package/dist/esm/{types-D3W3J65M.d.ts → types-BOyFfG7D.d.ts} +42 -7
- package/dist/esm/{types-Ce9Lhvrf.d.ts → types-BRIpBy9n.d.ts} +3 -3
- package/dist/esm/{types-CFDG6lIJ.d.ts → types-OXQqX_kH.d.ts} +3 -3
- package/dist/esm/{validation-BRu06AM_.js → validation-DWe2k89s.js} +2 -2
- package/dist/esm/{validation-BRu06AM_.js.map → validation-DWe2k89s.js.map} +1 -1
- package/dist/esm/viem/index.d.ts +5 -5
- package/dist/esm/viem/index.js +1 -1
- package/dist/esm/viem/index.js.map +1 -1
- package/dist/esm/web/index.d.ts +1 -1
- package/dist/esm/web/index.js +1 -1
- package/dist/esm/wrappers-registry-BfQr2QHn.js +2 -0
- package/dist/esm/wrappers-registry-BfQr2QHn.js.map +1 -0
- package/package.json +2 -2
- package/dist/esm/base-signer-DGIEzavu.js +0 -2
- package/dist/esm/base-signer-DGIEzavu.js.map +0 -1
- package/dist/esm/chains-ByyCdrrd.js +0 -2
- package/dist/esm/chains-ByyCdrrd.js.map +0 -1
- package/dist/esm/fhevm-relayer-Cm-ZR1vP.js +0 -8
- package/dist/esm/fhevm-relayer-Cm-ZR1vP.js.map +0 -1
- package/dist/esm/relayer-CVKO9GmQ.js +0 -2
- package/dist/esm/relayer-CVKO9GmQ.js.map +0 -1
- package/dist/esm/token-BejFVO8m.js +0 -2
- package/dist/esm/wrappers-registry-BLe7PkZi.js +0 -2
- package/dist/esm/wrappers-registry-BLe7PkZi.js.map +0 -1
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{i as e,r as t}from"./relayer-
|
|
2
|
-
//# sourceMappingURL=encryption-
|
|
1
|
+
import{i as e,r as t}from"./relayer-B6Zo6EkX.js";var n=class extends t{constructor(t,n){super(e.EncryptionFailed,t,n),this.name=`EncryptionFailedError`}},r=class extends t{constructor(t,n){super(e.EncryptOffloadUnavailable,t,n),this.name=`EncryptOffloadUnavailableError`}},i=class extends t{constructor(t,n){super(e.DecryptionFailed,t,n),this.name=`DecryptionFailedError`}};export{r as n,n as r,i as t};
|
|
2
|
+
//# sourceMappingURL=encryption-DJljZ2oV.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"encryption-
|
|
1
|
+
{"version":3,"file":"encryption-DJljZ2oV.js","names":[],"sources":["../../src/errors/encryption.ts"],"sourcesContent":["import { ZamaError, ZamaErrorCode } from \"./base\";\n\n/** FHE encryption failed. */\nexport class EncryptionFailedError extends ZamaError {\n constructor(message: string, options?: ErrorOptions) {\n super(ZamaErrorCode.EncryptionFailed, message, options);\n this.name = \"EncryptionFailedError\";\n }\n}\n\n/**\n * Encryption offload was required but the worker could not be used.\n *\n * Only `web({ offloadEncrypt: true })` throws this: the strict mode refuses to\n * silently finish the operation on the calling thread. With `\"auto\"` the same\n * conditions warn and fall back instead.\n */\nexport class EncryptOffloadUnavailableError extends ZamaError {\n constructor(message: string, options?: ErrorOptions) {\n super(ZamaErrorCode.EncryptOffloadUnavailable, message, options);\n this.name = \"EncryptOffloadUnavailableError\";\n }\n}\n\n/** FHE decryption failed. */\nexport class DecryptionFailedError extends ZamaError {\n constructor(message: string, options?: ErrorOptions) {\n super(ZamaErrorCode.DecryptionFailed, message, options);\n this.name = \"DecryptionFailedError\";\n }\n}\n"],"mappings":"iDAGA,IAAa,EAAb,cAA2C,CAAU,CACnD,YAAY,EAAiB,EAAwB,CACnD,MAAM,EAAc,iBAAkB,EAAS,CAAO,EACtD,KAAK,KAAO,uBACd,CACF,EASa,EAAb,cAAoD,CAAU,CAC5D,YAAY,EAAiB,EAAwB,CACnD,MAAM,EAAc,0BAA2B,EAAS,CAAO,EAC/D,KAAK,KAAO,gCACd,CACF,EAGa,EAAb,cAA2C,CAAU,CACnD,YAAY,EAAiB,EAAwB,CACnD,MAAM,EAAc,iBAAkB,EAAS,CAAO,EACtD,KAAK,KAAO,uBACd,CACF"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { d as AtLeastOneChain, f as FheChain, p as FheChainAuth } from "../index-
|
|
2
|
-
import { $ as
|
|
3
|
-
import { t as ZamaConfigEthers } from "../types-
|
|
4
|
-
import { n as MutableWalletAccountStore, t as BaseSigner } from "../base-signer-
|
|
1
|
+
import { d as AtLeastOneChain, f as FheChain, p as FheChainAuth } from "../index-Gk1S0gjO.js";
|
|
2
|
+
import { $ as RevokeDelegationSubmittedEvent, A as WalletAccountListener, B as ApproveUnderlyingSubmittedEvent, D as GenericSigner, F as ReadContractReturnType, G as DelegationSubmittedEvent, H as DecryptEndEvent, I as ReadFunctionName, J as EncryptStartEvent, K as EncryptEndEvent, L as WriteContractArgs, M as ContractAbi, N as ReadContractArgs, O as WalletAccount, P as ReadContractConfig, Q as PermitOperation, Qt as TransactionReceipt, R as WriteContractConfig, U as DecryptErrorEvent, V as BaseEvent, W as DecryptStartEvent, X as InvalidateDecryptionSignaturesSubmittedEvent, Y as FinalizeUnwrapSubmittedEvent, Z as PermitErrorEvent, Zt as RawLog, _t as ShieldPath, a as ZamaConfigBase, at as TransferSubmittedEvent, c as GenericStorage, ct as UnshieldPhase2SubmittedEvent, dn as FhevmRuntimeConfig, dt as ZamaSDKEvent, en as ClearValue, et as SetOperatorSubmittedEvent, ft as ZamaSDKEventListener, i as ZamaConfig, it as TransferFromSubmittedEvent, j as WalletAccountStore, k as WalletAccountChange, l as GenericProvider, lt as UnwrapSubmittedEvent, mt as ZamaSDKEvents, n as RelayerConfig, nt as TransactionErrorEvent, ot as UnshieldPhase1SubmittedEvent, pt as ZamaSDKEventType, q as EncryptErrorEvent, rn as EIP712TypedData, rt as TransactionOperation, s as GenericLogger, sn as EncryptedValue, st as UnshieldPhase2StartedEvent, tt as ShieldSubmittedEvent, ut as WrapSubmittedEvent, z as WriteFunctionName } from "../types-BOyFfG7D.js";
|
|
3
|
+
import { t as ZamaConfigEthers } from "../types-OXQqX_kH.js";
|
|
4
|
+
import { n as MutableWalletAccountStore, t as BaseSigner } from "../base-signer-S2Ogf6L4.js";
|
|
5
5
|
import { Abi, Address, ContractFunctionArgs, ContractFunctionName, ContractFunctionReturnType, EIP1193EventMap, EIP1193Events, EIP1193Provider, EIP1193Provider as EIP1193Provider$1, Hex, Hex as Hex$1, ProviderConnectInfo, ProviderMessage, ProviderRpcError } from "viem";
|
|
6
6
|
import { Signer, ethers } from "ethers";
|
|
7
7
|
//#region src/ethers/config.d.ts
|
|
@@ -182,5 +182,5 @@ declare function readTokenAddressContract(provider: EthersCallProvider, registry
|
|
|
182
182
|
/** Reads whether a confidential token is registered and valid in a wrappers registry via an ethers provider. */
|
|
183
183
|
declare function readIsConfidentialTokenValidContract(provider: EthersCallProvider, registry: Address, confidentialTokenAddress: Address): Promise<unknown>;
|
|
184
184
|
//#endregion
|
|
185
|
-
export { type ApproveUnderlyingSubmittedEvent, type AtLeastOneChain, type BaseEvent, BaseSigner, type ClearValue, type ContractAbi, type DecryptEndEvent, type DecryptErrorEvent, type DecryptStartEvent, type DelegationSubmittedEvent, type EIP1193EventMap, type EIP1193Events, type EIP1193Provider, type EIP712TypedData, type EncryptEndEvent, type EncryptErrorEvent, type EncryptStartEvent, type EncryptedValue, type EthersCallProvider, EthersProvider, type EthersProviderConfig, EthersSigner, type EthersSignerConfig, type EthersTransactionRequest, type EthersTransactionResponse, type EthersTransactionSigner, type FheChain, type FheChainAuth, type FhevmRuntimeConfig, type FinalizeUnwrapSubmittedEvent, type GenericLogger, type GenericProvider, type GenericSigner, type GenericStorage, type Hex, type MutableWalletAccountStore, type PermitErrorEvent, type PermitOperation, type ProviderConnectInfo, type ProviderMessage, ProviderRpcError, type RawLog, type ReadContractArgs, type ReadContractConfig, type ReadContractReturnType, type ReadFunctionName, type RelayerConfig, type RevokeDelegationSubmittedEvent, type SetOperatorSubmittedEvent, type ShieldPath, type ShieldSubmittedEvent, type TransactionErrorEvent, type TransactionOperation, type TransactionReceipt, type TransferFromSubmittedEvent, type TransferSubmittedEvent, type UnshieldPhase1SubmittedEvent, type UnshieldPhase2StartedEvent, type UnshieldPhase2SubmittedEvent, type UnwrapSubmittedEvent, type WalletAccount, type WalletAccountChange, type WalletAccountListener, type WalletAccountStore, type WrapSubmittedEvent, type WriteContractArgs, type WriteContractConfig, type WriteFunctionName, type ZamaConfig, type ZamaConfigBase, type ZamaConfigEthers, type ZamaSDKEvent, type ZamaSDKEventListener, type ZamaSDKEventType, ZamaSDKEvents, createConfig, readConfidentialBalanceOfContract, readConfidentialTokenAddressContract, readIsConfidentialTokenValidContract, readSupportsInterfaceContract, readTokenAddressContract, readTokenPairContract, readTokenPairsContract, readTokenPairsLengthContract, readTokenPairsSliceContract, readUnderlyingTokenContract, writeConfidentialTransferContract, writeFinalizeUnwrapContract, writeSetOperatorContract, writeUnwrapContract, writeUnwrapFromBalanceContract, writeWrapContract };
|
|
185
|
+
export { type ApproveUnderlyingSubmittedEvent, type AtLeastOneChain, type BaseEvent, BaseSigner, type ClearValue, type ContractAbi, type DecryptEndEvent, type DecryptErrorEvent, type DecryptStartEvent, type DelegationSubmittedEvent, type EIP1193EventMap, type EIP1193Events, type EIP1193Provider, type EIP712TypedData, type EncryptEndEvent, type EncryptErrorEvent, type EncryptStartEvent, type EncryptedValue, type EthersCallProvider, EthersProvider, type EthersProviderConfig, EthersSigner, type EthersSignerConfig, type EthersTransactionRequest, type EthersTransactionResponse, type EthersTransactionSigner, type FheChain, type FheChainAuth, type FhevmRuntimeConfig, type FinalizeUnwrapSubmittedEvent, type GenericLogger, type GenericProvider, type GenericSigner, type GenericStorage, type Hex, type InvalidateDecryptionSignaturesSubmittedEvent, type MutableWalletAccountStore, type PermitErrorEvent, type PermitOperation, type ProviderConnectInfo, type ProviderMessage, ProviderRpcError, type RawLog, type ReadContractArgs, type ReadContractConfig, type ReadContractReturnType, type ReadFunctionName, type RelayerConfig, type RevokeDelegationSubmittedEvent, type SetOperatorSubmittedEvent, type ShieldPath, type ShieldSubmittedEvent, type TransactionErrorEvent, type TransactionOperation, type TransactionReceipt, type TransferFromSubmittedEvent, type TransferSubmittedEvent, type UnshieldPhase1SubmittedEvent, type UnshieldPhase2StartedEvent, type UnshieldPhase2SubmittedEvent, type UnwrapSubmittedEvent, type WalletAccount, type WalletAccountChange, type WalletAccountListener, type WalletAccountStore, type WrapSubmittedEvent, type WriteContractArgs, type WriteContractConfig, type WriteFunctionName, type ZamaConfig, type ZamaConfigBase, type ZamaConfigEthers, type ZamaSDKEvent, type ZamaSDKEventListener, type ZamaSDKEventType, ZamaSDKEvents, createConfig, readConfidentialBalanceOfContract, readConfidentialTokenAddressContract, readIsConfidentialTokenValidContract, readSupportsInterfaceContract, readTokenAddressContract, readTokenPairContract, readTokenPairsContract, readTokenPairsLengthContract, readTokenPairsSliceContract, readUnderlyingTokenContract, writeConfidentialTransferContract, writeFinalizeUnwrapContract, writeSetOperatorContract, writeUnwrapContract, writeUnwrapFromBalanceContract, writeWrapContract };
|
|
186
186
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/esm/ethers/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{t as e}from"../relayer-
|
|
1
|
+
import{t as e}from"../relayer-B6Zo6EkX.js";import{$ as t,F as n,L as r,M as i,N as a,O as o,P as s,S as c,T as l,U as u,Z as d,a as f,i as p,it as m,m as h,n as g,nt as _,o as v,r as y,s as b,t as ee,tt as te}from"../wrappers-registry-BfQr2QHn.js";import{i as x,t as S}from"../base-signer--sBO2qJp.js";import{n as C}from"../assertions-Ca1ePdRJ.js";import{t as w}from"../eip1193-subscribe-CNxVHW6y.js";import{ProviderRpcError as T,decodeFunctionResult as E,encodeFunctionData as D,getAddress as O,isHex as k}from"viem";import{BrowserProvider as A,Contract as j,Transaction as M,ethers as N}from"ethers";function P(e){return{to:e.address,data:D({abi:e.abi,functionName:e.functionName,args:e.args}),...e.gas===void 0?{}:{gasLimit:e.gas},...e.value===void 0?{}:{value:e.value}}}async function F(e,t){let n=await e.call(P(t));if(!k(n))throw TypeError(`Expected hex string, got: ${n}`);return E({abi:t.abi,functionName:t.functionName,data:n})}async function I(e,t){let n=await e.sendTransaction(P(t));if(!k(n.hash))throw TypeError(`Expected hex string, got: ${n.hash}`);return n.hash}function L(e,t,n){return F(e,c(t,n))}function R(e,t){return F(e,a(t))}function z(e,t,n){return F(e,h(t,n))}function B(e,t,n,r,i){return I(e,l(t,n,r,i))}function V(e,t,n,r,i,a){return I(e,s(t,n,r,i,a))}function H(e,t,r,i,a){return I(e,n(t,r,i,a))}function U(e,t,n,r,i){return I(e,o(t,n,r,i))}function W(e,t,n,r){return I(e,i(t,n,r))}function G(e,t,n,i){return I(e,r(t,n,i))}function K(e,t){return F(e,p(t))}function q(e,t){return F(e,f(t))}function J(e,t,n,r){return F(e,v(t,n,r))}function Y(e,t,n){return F(e,y(t,n))}function X(e,t,n){return F(e,ee(t,n))}function Z(e,t,n){return F(e,g(t,n))}function ne(e,t,n){return F(e,b(t,n))}var Q=class{#e;constructor(e){`ethereum`in e?this.#e=new A(e.ethereum):this.#e=e.provider}async getChainId(){let e=await this.#e.getNetwork();return Number(e.chainId)}async readContract(e){return F(this.#e,{address:e.address,abi:e.abi,functionName:e.functionName,args:e.args})}async getBlockTimestamp(){let t=await this.#e.getBlock(`latest`);if(!t)throw new e(`EthersProvider.getBlockTimestamp: failed to fetch latest block`);if(t.timestamp===null)throw new e(`EthersProvider.getBlockTimestamp: latest block has no timestamp`);return BigInt(t.timestamp)}async waitForTransactionReceipt(e){let t=await this.#e.waitForTransaction(e);if(!t)throw new m(`EthersProvider.waitForTransactionReceipt: no receipt found for tx ${e}. The transaction may have been dropped from the mempool, or the RPC's wait timeout elapsed.`);return{logs:t.logs.map(e=>({address:e.address,topics:e.topics.filter(e=>e!==null),data:e.data}))}}async prepareTransaction(t){let{from:n,calldata:r}=t,i=new N.Interface(r.abi),a=[];i.forEachFunction(e=>{e.name===r.functionName&&a.push(e)});let o=r.args.length,s=a.length===1?a[0]:a.find(e=>e.inputs.length===o);if(!s)throw Error(`Function ${r.functionName}(${o} args) not found in ABI`);let c=i.encodeFunctionData(s,r.args);C(c,`data`);let l=r.value??0n,u=this.#e.getNetwork(),d=t.nonce===void 0?this.#e.getTransactionCount(n,`pending`):Promise.resolve(t.nonce),f=t.gasLimit===void 0?r.gas??this.#e.estimateGas({from:n,to:r.address,data:c,value:l}).catch(e=>{throw new m(`EthersProvider.prepareTransaction: gas estimation reverted for ${r.functionName} on ${r.address}`,{cause:e})}):Promise.resolve(t.gasLimit),p=t.fees??this.#e.getFeeData(),[h,g,_,v]=await Promise.all([u,d,f,p]),y=v.maxFeePerGas,b=v.maxPriorityFeePerGas;if(y===null||b===null)throw new e(`EthersProvider.prepareTransaction: EIP-1559 fee data unavailable (provider returned null maxFeePerGas). The connected chain may not support EIP-1559 type-2 transactions.`);return M.from({type:2,chainId:Number(h.chainId),nonce:g,to:r.address,data:c,value:l,gasLimit:_,maxFeePerGas:y,maxPriorityFeePerGas:b}).unsignedSerialized}},$=class extends S{#e;#t;#n;#r;#i;constructor(e){super(),`ethereum`in e?(this.#e=new A(e.ethereum),this.#n=e.ethereum,this.#r=w({provider:e.ethereum,getInitialWalletAccount:()=>this.#l(),onWalletAccountChange:({next:e})=>{this.walletAccount.setSnapshot(e)}})):(this.#t=e.signer,this.#r=()=>{},u(`refresh wallet account`,async()=>{await this.refreshWalletAccount()}))}requireWalletAccount(e){let t=this.walletAccount.getSnapshot();if(!t&&!this.walletAccount.isReady())throw new te(e);if(!t)throw new _(e);return t}refreshWalletAccount(){return this.#n?this.#c():this.#t?this.#s(this.#t):Promise.resolve(void 0)}onDispose(){this.#r()}async#a(){if(this.#t)return this.#t;if(!this.#e)throw new t(`resolveSigner`);return this.#e.getSigner()}async#o(e){let t=e.provider;if(!t)return;let[n,r]=await Promise.all([e.getAddress(),t.getNetwork()]);return{address:O(n),chainId:Number(r.chainId)}}async signTypedData(e){let t=await this.#a(),{domain:n,types:r,message:i}=e,{EIP712Domain:a,...o}=r,s=Object.fromEntries(Object.entries(o).map(([e,t])=>[e,[...t]])),c=await t.signTypedData(n,s,i);if(!k(c))throw TypeError(`Expected hex string, got: ${c}`);return c}async writeContract(e){let t=await this.#a(),n=new j(e.address,e.abi,t),r={};e.value!==void 0&&(r.value=e.value),e.gas!==void 0&&(r.gasLimit=e.gas);let i=await n.getFunction(e.functionName)(...e.args,r);if(!k(i.hash))throw TypeError(`Expected hex string, got: ${i.hash}`);return i.hash}async#s(e){return this.#i??=this.#o(e).then(e=>(this.walletAccount.setSnapshot(e),e)).finally(()=>{this.#i=void 0}),this.#i}async#c(){let e=await this.#l();return this.walletAccount.setSnapshot(e),e}async#l(){let e=this.#n;if(!e)return;let[t,n]=await Promise.all([e.request({method:`eth_accounts`}),e.request({method:`eth_chainId`})]);if(!Array.isArray(t)||typeof t[0]!=`string`)return;let r=Number(n);if(!(!Number.isSafeInteger(r)||r<=0))return{address:O(t[0]),chainId:r}}};function re(e){if(`signer`in e&&e.signer){let t=new $({signer:e.signer});if(!e.signer.provider)throw Error(`createConfig requires a Signer with an attached provider for chain reads`);return x(t,new Q({provider:e.signer.provider}),e)}return x(new $({ethereum:e.ethereum}),`provider`in e&&e.provider?new Q({provider:e.provider}):new Q({ethereum:e.ethereum}),e)}export{S as BaseSigner,Q as EthersProvider,$ as EthersSigner,T as ProviderRpcError,d as ZamaSDKEvents,re as createConfig,L as readConfidentialBalanceOfContract,X as readConfidentialTokenAddressContract,ne as readIsConfidentialTokenValidContract,z as readSupportsInterfaceContract,Z as readTokenAddressContract,Y as readTokenPairContract,K as readTokenPairsContract,q as readTokenPairsLengthContract,J as readTokenPairsSliceContract,R as readUnderlyingTokenContract,B as writeConfidentialTransferContract,U as writeFinalizeUnwrapContract,W as writeSetOperatorContract,V as writeUnwrapContract,H as writeUnwrapFromBalanceContract,G as writeWrapContract};
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["#readProvider","#browserProvider","#directSigner","#eip1193","#unsubscribeProvider","#loadBrowserWalletAccount","#refreshFromEthereum","#refreshFromSigner","#resolveSigner","#walletAccountFromSigner","#accountPromise"],"sources":["../../../src/ethers/contracts.ts","../../../src/ethers/ethers-provider.ts","../../../src/ethers/ethers-signer.ts","../../../src/ethers/config.ts"],"sourcesContent":["import {\n decodeFunctionResult,\n encodeFunctionData,\n isHex,\n type Abi,\n type Address,\n type Hex,\n} from \"viem\";\n\nimport type { EncryptedValue } from \"../relayer/types\";\n\nimport {\n confidentialBalanceOfContract,\n confidentialTransferContract,\n finalizeUnwrapContract,\n setOperatorContract,\n supportsInterfaceContract,\n underlyingContract,\n unwrapContract,\n unwrapFromBalanceContract,\n wrapContract,\n getTokenPairsContract,\n getTokenPairsLengthContract,\n getTokenPairsSliceContract,\n getTokenPairContract,\n getConfidentialTokenAddressContract,\n getTokenAddressContract,\n isConfidentialTokenValidContract,\n} from \"../contracts\";\n\ninterface TransactionRequestConfig {\n address: Address;\n abi: readonly unknown[];\n functionName: string;\n args: readonly unknown[];\n gas?: bigint;\n value?: bigint;\n}\n\n/** Minimal transaction request accepted by the ethers contract helpers. */\nexport interface EthersTransactionRequest {\n /** Target contract address. */\n to: Address;\n /** ABI-encoded call data. */\n data: Hex;\n /** Optional gas limit for the transaction. */\n gasLimit?: bigint;\n /** Optional native-token value to send with the call, in wei. */\n value?: bigint;\n}\n\n/** Minimal transaction response returned by an {@link EthersTransactionSigner}. */\nexport interface EthersTransactionResponse {\n /** Hash of the submitted transaction. */\n hash: string;\n}\n\n/** Minimal read-only ethers provider shape used by the read contract helpers. */\nexport interface EthersCallProvider {\n /** Performs an `eth_call` and resolves to the raw hex return data. */\n call(tx: EthersTransactionRequest): Promise<string>;\n}\n\n/** Minimal ethers signer shape used by the write contract helpers. */\nexport interface EthersTransactionSigner extends EthersCallProvider {\n /** Signs and broadcasts a transaction, resolving to the transaction response. */\n sendTransaction(tx: EthersTransactionRequest): Promise<EthersTransactionResponse>;\n}\n\nfunction toTransactionRequest(config: TransactionRequestConfig): EthersTransactionRequest {\n return {\n to: config.address,\n data: encodeFunctionData({\n abi: config.abi as Abi,\n functionName: config.functionName as never,\n args: config.args as never,\n }),\n ...(config.gas !== undefined ? { gasLimit: config.gas } : {}),\n ...(config.value !== undefined ? { value: config.value } : {}),\n };\n}\n\n/**\n * Performs an `eth_call` through an ethers provider and decodes the result with viem, so every\n * ethers-backed read — the generic {@link EthersProvider.readContract} and the pre-built\n * `readXxxContract` helpers alike — produces viem-identical shapes (small ints as `number`, named\n * tuples as keyed objects, empty output as `undefined`). ethers is the transport only; viem owns\n * encoding and decoding.\n *\n * @internal\n */\nexport async function ethersRead<T>(\n provider: EthersCallProvider,\n config: TransactionRequestConfig,\n): Promise<T> {\n const data = await provider.call(toTransactionRequest(config));\n if (!isHex(data)) {\n throw new TypeError(`Expected hex string, got: ${data}`);\n }\n return decodeFunctionResult({\n abi: config.abi as Abi,\n functionName: config.functionName as never,\n data,\n }) as T;\n}\n\nasync function ethersWrite(\n signer: EthersTransactionSigner,\n config: TransactionRequestConfig,\n): Promise<Hex> {\n const tx = await signer.sendTransaction(toTransactionRequest(config));\n if (!isHex(tx.hash)) {\n throw new TypeError(`Expected hex string, got: ${tx.hash}`);\n }\n return tx.hash;\n}\n\n// ── Read helpers ────────────────────────────────────────────\n\n/** Reads a token's confidential (encrypted) balance handle for `userAddress` via an ethers provider. */\nexport function readConfidentialBalanceOfContract(\n provider: EthersCallProvider,\n tokenAddress: Address,\n userAddress: Address,\n) {\n return ethersRead(provider, confidentialBalanceOfContract(tokenAddress, userAddress));\n}\n\n/** Reads the underlying ERC-20 address wrapped by a confidential wrapper via an ethers provider. */\nexport function readUnderlyingTokenContract(provider: EthersCallProvider, wrapperAddress: Address) {\n return ethersRead(provider, underlyingContract(wrapperAddress));\n}\n\n/** Reads whether a token implements the given ERC-165 interface id via an ethers provider. */\nexport function readSupportsInterfaceContract(\n provider: EthersCallProvider,\n tokenAddress: Address,\n interfaceId: Address,\n) {\n return ethersRead(provider, supportsInterfaceContract(tokenAddress, interfaceId));\n}\n\n// ── Write helpers ───────────────────────────────────────────\n\n/** Submits a confidential transfer of an encrypted amount to `to` via an ethers signer. */\nexport function writeConfidentialTransferContract(\n signer: EthersTransactionSigner,\n tokenAddress: Address,\n to: Address,\n encryptedAmount: EncryptedValue,\n inputProof: Hex,\n) {\n return ethersWrite(\n signer,\n confidentialTransferContract(tokenAddress, to, encryptedAmount, inputProof),\n );\n}\n\n/** Submits an unwrap of an encrypted amount from `from` to `to` on a confidential ERC-20 via an ethers signer. */\nexport function writeUnwrapContract(\n signer: EthersTransactionSigner,\n encryptedErc20: Address,\n from: Address,\n to: Address,\n encryptedAmount: EncryptedValue,\n inputProof: Hex,\n) {\n return ethersWrite(signer, unwrapContract(encryptedErc20, from, to, encryptedAmount, inputProof));\n}\n\n/** Submits an unwrap of the full encrypted balance from `from` to `to` via an ethers signer. */\nexport function writeUnwrapFromBalanceContract(\n signer: EthersTransactionSigner,\n encryptedErc20: Address,\n from: Address,\n to: Address,\n encryptedBalance: EncryptedValue,\n) {\n return ethersWrite(signer, unwrapFromBalanceContract(encryptedErc20, from, to, encryptedBalance));\n}\n\n/** Finalizes a pending unwrap request with the decrypted amount and decryption proof via an ethers signer. */\nexport function writeFinalizeUnwrapContract(\n signer: EthersTransactionSigner,\n wrapper: Address,\n unwrapRequestId: EncryptedValue,\n unwrapAmountCleartext: bigint,\n decryptionProof: Hex,\n) {\n return ethersWrite(\n signer,\n finalizeUnwrapContract(wrapper, unwrapRequestId, unwrapAmountCleartext, decryptionProof),\n );\n}\n\n/** Authorizes `operator` on a token, until an optional expiry timestamp, via an ethers signer. */\nexport function writeSetOperatorContract(\n signer: EthersTransactionSigner,\n tokenAddress: Address,\n operator: Address,\n until?: number,\n) {\n return ethersWrite(signer, setOperatorContract(tokenAddress, operator, until));\n}\n\n/** Wraps `amount` of the underlying ERC-20 into confidential tokens credited to `to` via an ethers signer. */\nexport function writeWrapContract(\n signer: EthersTransactionSigner,\n wrapperAddress: Address,\n to: Address,\n amount: bigint,\n) {\n return ethersWrite(signer, wrapContract(wrapperAddress, to, amount));\n}\n\n// ── Registry read helpers ──────────────────────────────────\n\n/** Reads all underlying/confidential token pairs from a wrappers registry via an ethers provider. */\nexport function readTokenPairsContract(provider: EthersCallProvider, registry: Address) {\n return ethersRead(provider, getTokenPairsContract(registry));\n}\n\n/** Reads the number of token pairs in a wrappers registry via an ethers provider. */\nexport function readTokenPairsLengthContract(provider: EthersCallProvider, registry: Address) {\n return ethersRead(provider, getTokenPairsLengthContract(registry));\n}\n\n/** Reads a slice of token pairs (`fromIndex` to `toIndex`) from a wrappers registry via an ethers provider. */\nexport function readTokenPairsSliceContract(\n provider: EthersCallProvider,\n registry: Address,\n fromIndex: bigint,\n toIndex: bigint,\n) {\n return ethersRead(provider, getTokenPairsSliceContract(registry, fromIndex, toIndex));\n}\n\n/** Reads the token pair at `index` from a wrappers registry via an ethers provider. */\nexport function readTokenPairContract(\n provider: EthersCallProvider,\n registry: Address,\n index: bigint,\n) {\n return ethersRead(provider, getTokenPairContract(registry, index));\n}\n\n/** Reads the confidential token registered for a given underlying token in a wrappers registry via an ethers provider. */\nexport function readConfidentialTokenAddressContract(\n provider: EthersCallProvider,\n registry: Address,\n tokenAddress: Address,\n) {\n return ethersRead(provider, getConfidentialTokenAddressContract(registry, tokenAddress));\n}\n\n/** Reads the underlying token registered for a given confidential token in a wrappers registry via an ethers provider. */\nexport function readTokenAddressContract(\n provider: EthersCallProvider,\n registry: Address,\n confidentialTokenAddress: Address,\n) {\n return ethersRead(provider, getTokenAddressContract(registry, confidentialTokenAddress));\n}\n\n/** Reads whether a confidential token is registered and valid in a wrappers registry via an ethers provider. */\nexport function readIsConfidentialTokenValidContract(\n provider: EthersCallProvider,\n registry: Address,\n confidentialTokenAddress: Address,\n) {\n return ethersRead(provider, isConfidentialTokenValidContract(registry, confidentialTokenAddress));\n}\n","import { ethers, BrowserProvider, Transaction } from \"ethers\";\nimport type {\n Abi,\n Address,\n ContractFunctionArgs,\n ContractFunctionName,\n ContractFunctionReturnType,\n EIP1193Provider,\n Hex,\n} from \"viem\";\nimport { ConfigurationError, TransactionRevertedError } from \"../errors\";\nimport type {\n ContractAbi,\n GenericProvider,\n ReadContractConfig,\n TransactionReceipt,\n WriteContractArgs,\n WriteContractConfig,\n WriteFunctionName,\n} from \"../types\";\nimport { assertHex } from \"../utils/assertions\";\nimport { ethersRead } from \"./contracts\";\n\n/**\n * Configuration for {@link EthersProvider}.\n *\n * Two variants:\n *\n * - **EIP-1193** — `{ ethereum }`: pass the raw EIP-1193 provider (e.g. `window.ethereum`).\n * A `BrowserProvider` is created internally.\n *\n * - **Pre-built** — `{ provider }`: pass any ethers `Provider`\n * (e.g. `JsonRpcProvider`, `WebSocketProvider`).\n */\nexport type EthersProviderConfig = { ethereum: EIP1193Provider } | { provider: ethers.Provider };\n\n/**\n * Read-only {@link GenericProvider} backed by ethers v6.\n *\n * Use this for integrations that only need public chain reads before the user has connected their\n * wallet.\n *\n * @example\n * ```ts\n * // Dedicated RPC\n * const provider = new EthersProvider({\n * provider: new ethers.JsonRpcProvider(ALCHEMY_URL),\n * });\n *\n * // Wallet-sourced RPC (shares transport with EthersSigner)\n * const provider = new EthersProvider({ ethereum: window.ethereum });\n * ```\n */\nexport class EthersProvider implements GenericProvider {\n readonly #readProvider: ethers.Provider;\n\n constructor(config: EthersProviderConfig) {\n if (\"ethereum\" in config) {\n this.#readProvider = new BrowserProvider(config.ethereum);\n } else {\n this.#readProvider = config.provider;\n }\n }\n\n /** Return the chain ID of the connected network. */\n async getChainId(): Promise<number> {\n const network = await this.#readProvider.getNetwork();\n return Number(network.chainId);\n }\n\n /**\n * Execute a read-only call and return the decoded result.\n *\n * ethers is the transport only: the call goes out over `provider.call`, and viem does the\n * encoding and decoding (via {@link ethersRead}). That keeps the result identical to\n * `ViemProvider` — the return-type contract both providers implement — rather than re-deriving\n * viem's decoding rules (small ints as `number`, named tuples as keyed objects, empty output as\n * `undefined`) from ethers' own decoded values.\n */\n async readContract<\n const TAbi extends Abi | readonly unknown[],\n TFunctionName extends ContractFunctionName<TAbi, \"pure\" | \"view\">,\n const TArgs extends ContractFunctionArgs<TAbi, \"pure\" | \"view\", TFunctionName>,\n >(\n config: ReadContractConfig<TAbi, TFunctionName, TArgs>,\n ): Promise<ContractFunctionReturnType<TAbi, \"pure\" | \"view\", TFunctionName, TArgs>> {\n return ethersRead(this.#readProvider, {\n address: config.address,\n abi: config.abi as readonly unknown[],\n functionName: config.functionName,\n args: config.args as readonly unknown[],\n });\n }\n\n /** Return the latest block timestamp in seconds. */\n async getBlockTimestamp(): Promise<bigint> {\n const block = await this.#readProvider.getBlock(\"latest\");\n if (!block) {\n throw new ConfigurationError(\n \"EthersProvider.getBlockTimestamp: failed to fetch latest block\",\n );\n }\n if (block.timestamp === null) {\n throw new ConfigurationError(\n \"EthersProvider.getBlockTimestamp: latest block has no timestamp\",\n );\n }\n return BigInt(block.timestamp);\n }\n\n /** Wait for a transaction to be mined and return its receipt. */\n async waitForTransactionReceipt(hash: Hex): Promise<TransactionReceipt> {\n const receipt = await this.#readProvider.waitForTransaction(hash);\n if (!receipt) {\n throw new TransactionRevertedError(\n `EthersProvider.waitForTransactionReceipt: no receipt found for tx ${hash}. ` +\n \"The transaction may have been dropped from the mempool, or the RPC's wait timeout elapsed.\",\n );\n }\n return {\n logs: receipt.logs.map((log) => ({\n address: log.address as Hex,\n topics: log.topics.filter((t): t is Hex => t !== null),\n data: log.data as Hex,\n })),\n };\n }\n\n /** Build a fully-populated, RLP-encoded unsigned transaction ready to be signed offline. */\n async prepareTransaction<\n const TAbi extends ContractAbi,\n TFunctionName extends WriteFunctionName<TAbi>,\n const TArgs extends WriteContractArgs<TAbi, TFunctionName>,\n >(args: {\n from: Address;\n calldata: WriteContractConfig<TAbi, TFunctionName, TArgs>;\n nonce?: number;\n gasLimit?: bigint;\n fees?: { maxFeePerGas: bigint; maxPriorityFeePerGas: bigint };\n }): Promise<Hex> {\n const { from, calldata } = args;\n const iface = new ethers.Interface(calldata.abi as unknown as ethers.InterfaceAbi);\n // Resolve overloaded ABI entries by name + arity. ethers'\n // `getFunction(key, values)` allows for an \"overrides\" object as the\n // last arg, so a 2-arg fragment still matches a 3-value call and\n // overloads like ERC-7984 `confidentialTransfer(address,bytes32)` vs\n // `confidentialTransfer(address,bytes32,bytes)` aren't disambiguated.\n const candidates: ethers.FunctionFragment[] = [];\n iface.forEachFunction((frag) => {\n if (frag.name === calldata.functionName) {\n candidates.push(frag);\n }\n });\n const argLength = (calldata.args as readonly unknown[]).length;\n const fragment =\n candidates.length === 1\n ? candidates[0]\n : candidates.find((frag) => frag.inputs.length === argLength);\n if (!fragment) {\n throw new Error(`Function ${calldata.functionName}(${argLength} args) not found in ABI`);\n }\n const data = iface.encodeFunctionData(fragment, calldata.args as readonly unknown[]);\n assertHex(data, \"data\");\n\n const value = calldata.value ?? 0n;\n // Wrap estimateGas — pre-flight revert is the high-value failure mode.\n // Skip the network round-trips entirely when the caller supplied\n // overrides — useful for custodians with their own nonce/fee managers.\n const networkPromise = this.#readProvider.getNetwork();\n const noncePromise =\n args.nonce !== undefined\n ? Promise.resolve(args.nonce)\n : this.#readProvider.getTransactionCount(from, \"pending\");\n const gasPromise =\n args.gasLimit !== undefined\n ? Promise.resolve(args.gasLimit)\n : (calldata.gas ??\n this.#readProvider\n .estimateGas({ from, to: calldata.address, data, value })\n .catch((error: unknown) => {\n throw new TransactionRevertedError(\n `EthersProvider.prepareTransaction: gas estimation reverted for ${calldata.functionName as string} on ${calldata.address}`,\n { cause: error },\n );\n }));\n const feeDataPromise = args.fees ?? this.#readProvider.getFeeData();\n const [network, nonce, gasLimit, feeData] = await Promise.all([\n networkPromise,\n noncePromise,\n gasPromise,\n feeDataPromise,\n ]);\n const maxFeePerGas = feeData.maxFeePerGas;\n const maxPriorityFeePerGas = feeData.maxPriorityFeePerGas;\n if (maxFeePerGas === null || maxPriorityFeePerGas === null) {\n throw new ConfigurationError(\n \"EthersProvider.prepareTransaction: EIP-1559 fee data unavailable (provider returned null maxFeePerGas). \" +\n \"The connected chain may not support EIP-1559 type-2 transactions.\",\n );\n }\n const tx = Transaction.from({\n type: 2,\n chainId: Number(network.chainId),\n nonce,\n to: calldata.address,\n data,\n value,\n gasLimit,\n maxFeePerGas,\n maxPriorityFeePerGas,\n });\n return tx.unsignedSerialized as Hex;\n }\n}\n","import {\n BrowserProvider,\n Contract,\n type InterfaceAbi,\n type Signer,\n type TypedDataDomain,\n} from \"ethers\";\nimport {\n getAddress,\n isHex,\n type Abi,\n type ContractFunctionArgs,\n type ContractFunctionName,\n type EIP1193Provider,\n type Hex,\n} from \"viem\";\nimport {\n SignerNotConfiguredError,\n WalletAccountNotReadyError,\n WalletNotConnectedError,\n} from \"../errors\";\nimport type { EIP712TypedData } from \"../relayer/types\";\nimport { BaseSigner } from \"../signer/base-signer\";\nimport { eip1193Subscribe } from \"../signer/eip1193-subscribe\";\nimport type { WalletAccount, WriteContractConfig } from \"../types\";\nimport { swallow } from \"../utils\";\n\n/**\n * Configuration for {@link EthersSigner}.\n *\n * Two variants:\n *\n * - **Browser** — `{ ethereum }`: pass the raw EIP-1193 provider (e.g. `window.ethereum`).\n * A `BrowserProvider` is created internally and wallet events update `walletAccount`.\n *\n * - **Node / direct signer** — `{ signer }`: pass an ethers `Signer` (e.g. `Wallet`).\n * The initial wallet account is discovered asynchronously and emitted through\n * `walletAccount` once available.\n *\n * For public chain reads, construct a separate {@link EthersProvider}.\n */\nexport type EthersSignerConfig = { ethereum: EIP1193Provider } | { signer: Signer };\n\n/**\n * GenericSigner backed by ethers.\n *\n * Accepts either a raw EIP-1193 provider (`{ ethereum }`) which creates a\n * `BrowserProvider` internally, or a `Signer` directly (`{ signer }`)\n * for Node.js scripts.\n *\n * @param config - {@link EthersSignerConfig}\n */\nexport class EthersSigner extends BaseSigner {\n readonly #browserProvider?: BrowserProvider;\n readonly #directSigner?: Signer;\n readonly #eip1193?: EIP1193Provider;\n readonly #unsubscribeProvider: () => void;\n #accountPromise: Promise<WalletAccount | undefined> | undefined;\n\n constructor(config: EthersSignerConfig) {\n super();\n if (\"ethereum\" in config) {\n this.#browserProvider = new BrowserProvider(config.ethereum);\n this.#eip1193 = config.ethereum;\n this.#unsubscribeProvider = eip1193Subscribe({\n provider: config.ethereum,\n getInitialWalletAccount: () => this.#loadBrowserWalletAccount(),\n onWalletAccountChange: ({ next }) => {\n this.walletAccount.setSnapshot(next);\n },\n });\n } else {\n this.#directSigner = config.signer;\n this.#unsubscribeProvider = () => {};\n // The signer is constructed before `createConfig`, so it cannot reach the\n // SDK-wide logger; this best-effort refresh stays silent. A failed refresh\n // still surfaces via the typed WalletAccountNotReadyError on next use.\n void swallow(\"refresh wallet account\", async () => {\n await this.refreshWalletAccount();\n });\n }\n }\n\n /**\n * Return the connected wallet account, or throw {@link WalletAccountNotReadyError}\n * while the initial async lookup is pending, or {@link WalletNotConnectedError}\n * when no wallet is connected.\n */\n override requireWalletAccount(operation: string): WalletAccount {\n const account = this.walletAccount.getSnapshot();\n if (!account && !this.walletAccount.isReady()) {\n throw new WalletAccountNotReadyError(operation);\n }\n if (!account) {\n throw new WalletNotConnectedError(operation);\n }\n return account;\n }\n\n /** Re-fetch the wallet account from the provider or signer and update `walletAccount`. */\n refreshWalletAccount(): Promise<WalletAccount | undefined> {\n if (this.#eip1193) {\n return this.#refreshFromEthereum();\n }\n if (this.#directSigner) {\n return this.#refreshFromSigner(this.#directSigner);\n }\n return Promise.resolve(undefined);\n }\n\n /** Unsubscribe from the EIP-1193 provider's wallet lifecycle events. */\n protected override onDispose(): void {\n this.#unsubscribeProvider();\n }\n\n async #resolveSigner(): Promise<Signer> {\n if (this.#directSigner) {\n return this.#directSigner;\n }\n if (!this.#browserProvider) {\n throw new SignerNotConfiguredError(\"resolveSigner\");\n }\n return this.#browserProvider.getSigner();\n }\n\n async #walletAccountFromSigner(signer: Signer): Promise<WalletAccount | undefined> {\n const provider = signer.provider;\n if (!provider) {\n return undefined;\n }\n const [address, network] = await Promise.all([signer.getAddress(), provider.getNetwork()]);\n return { address: getAddress(address), chainId: Number(network.chainId) };\n }\n\n /** Sign EIP-712 typed data (used for decrypt authorization). */\n async signTypedData(typedData: EIP712TypedData): Promise<Hex> {\n const signer = await this.#resolveSigner();\n const { domain, types, message } = typedData;\n const { EIP712Domain: _, ...sigTypes } = types;\n const mutableSigTypes = Object.fromEntries(\n Object.entries(sigTypes).map(([name, fields]) => [name, [...fields]]),\n );\n const sig = await signer.signTypedData(domain as TypedDataDomain, mutableSigTypes, message);\n if (!isHex(sig)) {\n throw new TypeError(`Expected hex string, got: ${sig}`);\n }\n return sig;\n }\n\n /** Send a write transaction and return the tx hash. */\n async writeContract<\n const TAbi extends Abi | readonly unknown[],\n TFunctionName extends ContractFunctionName<TAbi, \"nonpayable\" | \"payable\">,\n const TArgs extends ContractFunctionArgs<TAbi, \"nonpayable\" | \"payable\", TFunctionName>,\n >(config: WriteContractConfig<TAbi, TFunctionName, TArgs>): Promise<Hex> {\n const signer = await this.#resolveSigner();\n const contract = new Contract(config.address, config.abi as InterfaceAbi, signer);\n const overrides: { gasLimit?: bigint; value?: bigint } = {};\n if (config.value !== undefined) {\n overrides.value = config.value;\n }\n if (config.gas !== undefined) {\n overrides.gasLimit = config.gas;\n }\n const fn = contract.getFunction(config.functionName);\n const tx = await fn(...(config.args as readonly unknown[]), overrides);\n if (!isHex(tx.hash)) {\n throw new TypeError(`Expected hex string, got: ${tx.hash}`);\n }\n return tx.hash;\n }\n\n async #refreshFromSigner(signer: Signer): Promise<WalletAccount | undefined> {\n this.#accountPromise ??= this.#walletAccountFromSigner(signer)\n .then((account) => {\n this.walletAccount.setSnapshot(account);\n return account;\n })\n .finally(() => {\n this.#accountPromise = undefined;\n });\n return this.#accountPromise;\n }\n\n async #refreshFromEthereum(): Promise<WalletAccount | undefined> {\n const account = await this.#loadBrowserWalletAccount();\n this.walletAccount.setSnapshot(account);\n return account;\n }\n\n async #loadBrowserWalletAccount(): Promise<WalletAccount | undefined> {\n const ethereum = this.#eip1193;\n if (!ethereum) {\n return undefined;\n }\n const [accounts, chainIdValue] = await Promise.all([\n ethereum.request({ method: \"eth_accounts\" }),\n ethereum.request({ method: \"eth_chainId\" }),\n ]);\n if (!Array.isArray(accounts) || typeof accounts[0] !== \"string\") {\n return undefined;\n }\n const chainId = Number(chainIdValue);\n if (!Number.isSafeInteger(chainId) || chainId <= 0) {\n return undefined;\n }\n return { address: getAddress(accounts[0]), chainId };\n }\n}\n","import type { FheChain } from \"../chains\";\nimport { buildZamaConfig } from \"../config/build\";\nimport type { ZamaConfig } from \"../config/types\";\nimport { EthersProvider } from \"./ethers-provider\";\nimport { EthersSigner } from \"./ethers-signer\";\nimport type { ZamaConfigEthers } from \"./types\";\n\n/** Create a {@link ZamaConfig} from ethers types. */\nexport function createConfig<const TChains extends readonly [FheChain, ...FheChain[]]>(\n params: ZamaConfigEthers<TChains>,\n): ZamaConfig {\n if (\"signer\" in params && params.signer) {\n const signer = new EthersSigner({ signer: params.signer });\n if (!params.signer.provider) {\n throw new Error(\"createConfig requires a Signer with an attached provider for chain reads\");\n }\n const provider = new EthersProvider({ provider: params.signer.provider });\n return buildZamaConfig(signer, provider, params);\n }\n\n const signer = new EthersSigner({ ethereum: params.ethereum });\n const provider =\n \"provider\" in params && params.provider\n ? new EthersProvider({ provider: params.provider })\n : new EthersProvider({ ethereum: params.ethereum });\n return buildZamaConfig(signer, provider, params);\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["#readProvider","#browserProvider","#directSigner","#eip1193","#unsubscribeProvider","#loadBrowserWalletAccount","#refreshFromEthereum","#refreshFromSigner","#resolveSigner","#walletAccountFromSigner","#accountPromise"],"sources":["../../../src/ethers/contracts.ts","../../../src/ethers/ethers-provider.ts","../../../src/ethers/ethers-signer.ts","../../../src/ethers/config.ts"],"sourcesContent":["import {\n decodeFunctionResult,\n encodeFunctionData,\n isHex,\n type Abi,\n type Address,\n type Hex,\n} from \"viem\";\n\nimport type { EncryptedValue } from \"../relayer/types\";\n\nimport {\n confidentialBalanceOfContract,\n confidentialTransferContract,\n finalizeUnwrapContract,\n setOperatorContract,\n supportsInterfaceContract,\n underlyingContract,\n unwrapContract,\n unwrapFromBalanceContract,\n wrapContract,\n getTokenPairsContract,\n getTokenPairsLengthContract,\n getTokenPairsSliceContract,\n getTokenPairContract,\n getConfidentialTokenAddressContract,\n getTokenAddressContract,\n isConfidentialTokenValidContract,\n} from \"../contracts\";\n\ninterface TransactionRequestConfig {\n address: Address;\n abi: readonly unknown[];\n functionName: string;\n args: readonly unknown[];\n gas?: bigint;\n value?: bigint;\n}\n\n/** Minimal transaction request accepted by the ethers contract helpers. */\nexport interface EthersTransactionRequest {\n /** Target contract address. */\n to: Address;\n /** ABI-encoded call data. */\n data: Hex;\n /** Optional gas limit for the transaction. */\n gasLimit?: bigint;\n /** Optional native-token value to send with the call, in wei. */\n value?: bigint;\n}\n\n/** Minimal transaction response returned by an {@link EthersTransactionSigner}. */\nexport interface EthersTransactionResponse {\n /** Hash of the submitted transaction. */\n hash: string;\n}\n\n/** Minimal read-only ethers provider shape used by the read contract helpers. */\nexport interface EthersCallProvider {\n /** Performs an `eth_call` and resolves to the raw hex return data. */\n call(tx: EthersTransactionRequest): Promise<string>;\n}\n\n/** Minimal ethers signer shape used by the write contract helpers. */\nexport interface EthersTransactionSigner extends EthersCallProvider {\n /** Signs and broadcasts a transaction, resolving to the transaction response. */\n sendTransaction(tx: EthersTransactionRequest): Promise<EthersTransactionResponse>;\n}\n\nfunction toTransactionRequest(config: TransactionRequestConfig): EthersTransactionRequest {\n return {\n to: config.address,\n data: encodeFunctionData({\n abi: config.abi as Abi,\n functionName: config.functionName as never,\n args: config.args as never,\n }),\n ...(config.gas !== undefined ? { gasLimit: config.gas } : {}),\n ...(config.value !== undefined ? { value: config.value } : {}),\n };\n}\n\n/**\n * Performs an `eth_call` through an ethers provider and decodes the result with viem, so every\n * ethers-backed read — the generic {@link EthersProvider.readContract} and the pre-built\n * `readXxxContract` helpers alike — produces viem-identical shapes (small ints as `number`, named\n * tuples as keyed objects, empty output as `undefined`). ethers is the transport only; viem owns\n * encoding and decoding.\n *\n * @internal\n */\nexport async function ethersRead<T>(\n provider: EthersCallProvider,\n config: TransactionRequestConfig,\n): Promise<T> {\n const data = await provider.call(toTransactionRequest(config));\n if (!isHex(data)) {\n throw new TypeError(`Expected hex string, got: ${data}`);\n }\n return decodeFunctionResult({\n abi: config.abi as Abi,\n functionName: config.functionName as never,\n data,\n }) as T;\n}\n\nasync function ethersWrite(\n signer: EthersTransactionSigner,\n config: TransactionRequestConfig,\n): Promise<Hex> {\n const tx = await signer.sendTransaction(toTransactionRequest(config));\n if (!isHex(tx.hash)) {\n throw new TypeError(`Expected hex string, got: ${tx.hash}`);\n }\n return tx.hash;\n}\n\n// ── Read helpers ────────────────────────────────────────────\n\n/** Reads a token's confidential (encrypted) balance handle for `userAddress` via an ethers provider. */\nexport function readConfidentialBalanceOfContract(\n provider: EthersCallProvider,\n tokenAddress: Address,\n userAddress: Address,\n) {\n return ethersRead(provider, confidentialBalanceOfContract(tokenAddress, userAddress));\n}\n\n/** Reads the underlying ERC-20 address wrapped by a confidential wrapper via an ethers provider. */\nexport function readUnderlyingTokenContract(provider: EthersCallProvider, wrapperAddress: Address) {\n return ethersRead(provider, underlyingContract(wrapperAddress));\n}\n\n/** Reads whether a token implements the given ERC-165 interface id via an ethers provider. */\nexport function readSupportsInterfaceContract(\n provider: EthersCallProvider,\n tokenAddress: Address,\n interfaceId: Address,\n) {\n return ethersRead(provider, supportsInterfaceContract(tokenAddress, interfaceId));\n}\n\n// ── Write helpers ───────────────────────────────────────────\n\n/** Submits a confidential transfer of an encrypted amount to `to` via an ethers signer. */\nexport function writeConfidentialTransferContract(\n signer: EthersTransactionSigner,\n tokenAddress: Address,\n to: Address,\n encryptedAmount: EncryptedValue,\n inputProof: Hex,\n) {\n return ethersWrite(\n signer,\n confidentialTransferContract(tokenAddress, to, encryptedAmount, inputProof),\n );\n}\n\n/** Submits an unwrap of an encrypted amount from `from` to `to` on a confidential ERC-20 via an ethers signer. */\nexport function writeUnwrapContract(\n signer: EthersTransactionSigner,\n encryptedErc20: Address,\n from: Address,\n to: Address,\n encryptedAmount: EncryptedValue,\n inputProof: Hex,\n) {\n return ethersWrite(signer, unwrapContract(encryptedErc20, from, to, encryptedAmount, inputProof));\n}\n\n/** Submits an unwrap of the full encrypted balance from `from` to `to` via an ethers signer. */\nexport function writeUnwrapFromBalanceContract(\n signer: EthersTransactionSigner,\n encryptedErc20: Address,\n from: Address,\n to: Address,\n encryptedBalance: EncryptedValue,\n) {\n return ethersWrite(signer, unwrapFromBalanceContract(encryptedErc20, from, to, encryptedBalance));\n}\n\n/** Finalizes a pending unwrap request with the decrypted amount and decryption proof via an ethers signer. */\nexport function writeFinalizeUnwrapContract(\n signer: EthersTransactionSigner,\n wrapper: Address,\n unwrapRequestId: EncryptedValue,\n unwrapAmountCleartext: bigint,\n decryptionProof: Hex,\n) {\n return ethersWrite(\n signer,\n finalizeUnwrapContract(wrapper, unwrapRequestId, unwrapAmountCleartext, decryptionProof),\n );\n}\n\n/** Authorizes `operator` on a token, until an optional expiry timestamp, via an ethers signer. */\nexport function writeSetOperatorContract(\n signer: EthersTransactionSigner,\n tokenAddress: Address,\n operator: Address,\n until?: number,\n) {\n return ethersWrite(signer, setOperatorContract(tokenAddress, operator, until));\n}\n\n/** Wraps `amount` of the underlying ERC-20 into confidential tokens credited to `to` via an ethers signer. */\nexport function writeWrapContract(\n signer: EthersTransactionSigner,\n wrapperAddress: Address,\n to: Address,\n amount: bigint,\n) {\n return ethersWrite(signer, wrapContract(wrapperAddress, to, amount));\n}\n\n// ── Registry read helpers ──────────────────────────────────\n\n/** Reads all underlying/confidential token pairs from a wrappers registry via an ethers provider. */\nexport function readTokenPairsContract(provider: EthersCallProvider, registry: Address) {\n return ethersRead(provider, getTokenPairsContract(registry));\n}\n\n/** Reads the number of token pairs in a wrappers registry via an ethers provider. */\nexport function readTokenPairsLengthContract(provider: EthersCallProvider, registry: Address) {\n return ethersRead(provider, getTokenPairsLengthContract(registry));\n}\n\n/** Reads a slice of token pairs (`fromIndex` to `toIndex`) from a wrappers registry via an ethers provider. */\nexport function readTokenPairsSliceContract(\n provider: EthersCallProvider,\n registry: Address,\n fromIndex: bigint,\n toIndex: bigint,\n) {\n return ethersRead(provider, getTokenPairsSliceContract(registry, fromIndex, toIndex));\n}\n\n/** Reads the token pair at `index` from a wrappers registry via an ethers provider. */\nexport function readTokenPairContract(\n provider: EthersCallProvider,\n registry: Address,\n index: bigint,\n) {\n return ethersRead(provider, getTokenPairContract(registry, index));\n}\n\n/** Reads the confidential token registered for a given underlying token in a wrappers registry via an ethers provider. */\nexport function readConfidentialTokenAddressContract(\n provider: EthersCallProvider,\n registry: Address,\n tokenAddress: Address,\n) {\n return ethersRead(provider, getConfidentialTokenAddressContract(registry, tokenAddress));\n}\n\n/** Reads the underlying token registered for a given confidential token in a wrappers registry via an ethers provider. */\nexport function readTokenAddressContract(\n provider: EthersCallProvider,\n registry: Address,\n confidentialTokenAddress: Address,\n) {\n return ethersRead(provider, getTokenAddressContract(registry, confidentialTokenAddress));\n}\n\n/** Reads whether a confidential token is registered and valid in a wrappers registry via an ethers provider. */\nexport function readIsConfidentialTokenValidContract(\n provider: EthersCallProvider,\n registry: Address,\n confidentialTokenAddress: Address,\n) {\n return ethersRead(provider, isConfidentialTokenValidContract(registry, confidentialTokenAddress));\n}\n","import { ethers, BrowserProvider, Transaction } from \"ethers\";\nimport type {\n Abi,\n Address,\n ContractFunctionArgs,\n ContractFunctionName,\n ContractFunctionReturnType,\n EIP1193Provider,\n Hex,\n} from \"viem\";\nimport { ConfigurationError, TransactionRevertedError } from \"../errors\";\nimport type {\n ContractAbi,\n GenericProvider,\n ReadContractConfig,\n TransactionReceipt,\n WriteContractArgs,\n WriteContractConfig,\n WriteFunctionName,\n} from \"../types\";\nimport { assertHex } from \"../utils/assertions\";\nimport { ethersRead } from \"./contracts\";\n\n/**\n * Configuration for {@link EthersProvider}.\n *\n * Two variants:\n *\n * - **EIP-1193** — `{ ethereum }`: pass the raw EIP-1193 provider (e.g. `window.ethereum`).\n * A `BrowserProvider` is created internally.\n *\n * - **Pre-built** — `{ provider }`: pass any ethers `Provider`\n * (e.g. `JsonRpcProvider`, `WebSocketProvider`).\n */\nexport type EthersProviderConfig = { ethereum: EIP1193Provider } | { provider: ethers.Provider };\n\n/**\n * Read-only {@link GenericProvider} backed by ethers v6.\n *\n * Use this for integrations that only need public chain reads before the user has connected their\n * wallet.\n *\n * @example\n * ```ts\n * // Dedicated RPC\n * const provider = new EthersProvider({\n * provider: new ethers.JsonRpcProvider(ALCHEMY_URL),\n * });\n *\n * // Wallet-sourced RPC (shares transport with EthersSigner)\n * const provider = new EthersProvider({ ethereum: window.ethereum });\n * ```\n */\nexport class EthersProvider implements GenericProvider {\n readonly #readProvider: ethers.Provider;\n\n constructor(config: EthersProviderConfig) {\n if (\"ethereum\" in config) {\n this.#readProvider = new BrowserProvider(config.ethereum);\n } else {\n this.#readProvider = config.provider;\n }\n }\n\n /** Return the chain ID of the connected network. */\n async getChainId(): Promise<number> {\n const network = await this.#readProvider.getNetwork();\n return Number(network.chainId);\n }\n\n /**\n * Execute a read-only call and return the decoded result.\n *\n * ethers is the transport only: the call goes out over `provider.call`, and viem does the\n * encoding and decoding (via {@link ethersRead}). That keeps the result identical to\n * `ViemProvider` — the return-type contract both providers implement — rather than re-deriving\n * viem's decoding rules (small ints as `number`, named tuples as keyed objects, empty output as\n * `undefined`) from ethers' own decoded values.\n */\n async readContract<\n const TAbi extends Abi | readonly unknown[],\n TFunctionName extends ContractFunctionName<TAbi, \"pure\" | \"view\">,\n const TArgs extends ContractFunctionArgs<TAbi, \"pure\" | \"view\", TFunctionName>,\n >(\n config: ReadContractConfig<TAbi, TFunctionName, TArgs>,\n ): Promise<ContractFunctionReturnType<TAbi, \"pure\" | \"view\", TFunctionName, TArgs>> {\n return ethersRead(this.#readProvider, {\n address: config.address,\n abi: config.abi as readonly unknown[],\n functionName: config.functionName,\n args: config.args as readonly unknown[],\n });\n }\n\n /** Return the latest block timestamp in seconds. */\n async getBlockTimestamp(): Promise<bigint> {\n const block = await this.#readProvider.getBlock(\"latest\");\n if (!block) {\n throw new ConfigurationError(\n \"EthersProvider.getBlockTimestamp: failed to fetch latest block\",\n );\n }\n if (block.timestamp === null) {\n throw new ConfigurationError(\n \"EthersProvider.getBlockTimestamp: latest block has no timestamp\",\n );\n }\n return BigInt(block.timestamp);\n }\n\n /** Wait for a transaction to be mined and return its receipt. */\n async waitForTransactionReceipt(hash: Hex): Promise<TransactionReceipt> {\n const receipt = await this.#readProvider.waitForTransaction(hash);\n if (!receipt) {\n throw new TransactionRevertedError(\n `EthersProvider.waitForTransactionReceipt: no receipt found for tx ${hash}. ` +\n \"The transaction may have been dropped from the mempool, or the RPC's wait timeout elapsed.\",\n );\n }\n return {\n logs: receipt.logs.map((log) => ({\n address: log.address as Hex,\n topics: log.topics.filter((t): t is Hex => t !== null),\n data: log.data as Hex,\n })),\n };\n }\n\n /** Build a fully-populated, RLP-encoded unsigned transaction ready to be signed offline. */\n async prepareTransaction<\n const TAbi extends ContractAbi,\n TFunctionName extends WriteFunctionName<TAbi>,\n const TArgs extends WriteContractArgs<TAbi, TFunctionName>,\n >(args: {\n from: Address;\n calldata: WriteContractConfig<TAbi, TFunctionName, TArgs>;\n nonce?: number;\n gasLimit?: bigint;\n fees?: { maxFeePerGas: bigint; maxPriorityFeePerGas: bigint };\n }): Promise<Hex> {\n const { from, calldata } = args;\n const iface = new ethers.Interface(calldata.abi as unknown as ethers.InterfaceAbi);\n // Resolve overloaded ABI entries by name + arity. ethers'\n // `getFunction(key, values)` allows for an \"overrides\" object as the\n // last arg, so a 2-arg fragment still matches a 3-value call and\n // overloads like ERC-7984 `confidentialTransfer(address,bytes32)` vs\n // `confidentialTransfer(address,bytes32,bytes)` aren't disambiguated.\n const candidates: ethers.FunctionFragment[] = [];\n iface.forEachFunction((frag) => {\n if (frag.name === calldata.functionName) {\n candidates.push(frag);\n }\n });\n const argLength = (calldata.args as readonly unknown[]).length;\n const fragment =\n candidates.length === 1\n ? candidates[0]\n : candidates.find((frag) => frag.inputs.length === argLength);\n if (!fragment) {\n throw new Error(`Function ${calldata.functionName}(${argLength} args) not found in ABI`);\n }\n const data = iface.encodeFunctionData(fragment, calldata.args as readonly unknown[]);\n assertHex(data, \"data\");\n\n const value = calldata.value ?? 0n;\n // Wrap estimateGas — pre-flight revert is the high-value failure mode.\n // Skip the network round-trips entirely when the caller supplied\n // overrides — useful for custodians with their own nonce/fee managers.\n const networkPromise = this.#readProvider.getNetwork();\n const noncePromise =\n args.nonce !== undefined\n ? Promise.resolve(args.nonce)\n : this.#readProvider.getTransactionCount(from, \"pending\");\n const gasPromise =\n args.gasLimit !== undefined\n ? Promise.resolve(args.gasLimit)\n : (calldata.gas ??\n this.#readProvider\n .estimateGas({ from, to: calldata.address, data, value })\n .catch((error: unknown) => {\n throw new TransactionRevertedError(\n `EthersProvider.prepareTransaction: gas estimation reverted for ${calldata.functionName as string} on ${calldata.address}`,\n { cause: error },\n );\n }));\n const feeDataPromise = args.fees ?? this.#readProvider.getFeeData();\n const [network, nonce, gasLimit, feeData] = await Promise.all([\n networkPromise,\n noncePromise,\n gasPromise,\n feeDataPromise,\n ]);\n const maxFeePerGas = feeData.maxFeePerGas;\n const maxPriorityFeePerGas = feeData.maxPriorityFeePerGas;\n if (maxFeePerGas === null || maxPriorityFeePerGas === null) {\n throw new ConfigurationError(\n \"EthersProvider.prepareTransaction: EIP-1559 fee data unavailable (provider returned null maxFeePerGas). \" +\n \"The connected chain may not support EIP-1559 type-2 transactions.\",\n );\n }\n const tx = Transaction.from({\n type: 2,\n chainId: Number(network.chainId),\n nonce,\n to: calldata.address,\n data,\n value,\n gasLimit,\n maxFeePerGas,\n maxPriorityFeePerGas,\n });\n return tx.unsignedSerialized as Hex;\n }\n}\n","import {\n BrowserProvider,\n Contract,\n type InterfaceAbi,\n type Signer,\n type TypedDataDomain,\n} from \"ethers\";\nimport {\n getAddress,\n isHex,\n type Abi,\n type ContractFunctionArgs,\n type ContractFunctionName,\n type EIP1193Provider,\n type Hex,\n} from \"viem\";\nimport {\n SignerNotConfiguredError,\n WalletAccountNotReadyError,\n WalletNotConnectedError,\n} from \"../errors\";\nimport type { EIP712TypedData } from \"../relayer/types\";\nimport { BaseSigner } from \"../signer/base-signer\";\nimport { eip1193Subscribe } from \"../signer/eip1193-subscribe\";\nimport type { WalletAccount, WriteContractConfig } from \"../types\";\nimport { swallow } from \"../utils\";\n\n/**\n * Configuration for {@link EthersSigner}.\n *\n * Two variants:\n *\n * - **Browser** — `{ ethereum }`: pass the raw EIP-1193 provider (e.g. `window.ethereum`).\n * A `BrowserProvider` is created internally and wallet events update `walletAccount`.\n *\n * - **Node / direct signer** — `{ signer }`: pass an ethers `Signer` (e.g. `Wallet`).\n * The initial wallet account is discovered asynchronously and emitted through\n * `walletAccount` once available.\n *\n * For public chain reads, construct a separate {@link EthersProvider}.\n */\nexport type EthersSignerConfig = { ethereum: EIP1193Provider } | { signer: Signer };\n\n/**\n * GenericSigner backed by ethers.\n *\n * Accepts either a raw EIP-1193 provider (`{ ethereum }`) which creates a\n * `BrowserProvider` internally, or a `Signer` directly (`{ signer }`)\n * for Node.js scripts.\n *\n * @param config - {@link EthersSignerConfig}\n */\nexport class EthersSigner extends BaseSigner {\n readonly #browserProvider?: BrowserProvider;\n readonly #directSigner?: Signer;\n readonly #eip1193?: EIP1193Provider;\n readonly #unsubscribeProvider: () => void;\n #accountPromise: Promise<WalletAccount | undefined> | undefined;\n\n constructor(config: EthersSignerConfig) {\n super();\n if (\"ethereum\" in config) {\n this.#browserProvider = new BrowserProvider(config.ethereum);\n this.#eip1193 = config.ethereum;\n this.#unsubscribeProvider = eip1193Subscribe({\n provider: config.ethereum,\n getInitialWalletAccount: () => this.#loadBrowserWalletAccount(),\n onWalletAccountChange: ({ next }) => {\n this.walletAccount.setSnapshot(next);\n },\n });\n } else {\n this.#directSigner = config.signer;\n this.#unsubscribeProvider = () => {};\n // The signer is constructed before `createConfig`, so it cannot reach the\n // SDK-wide logger; this best-effort refresh stays silent. A failed refresh\n // still surfaces via the typed WalletAccountNotReadyError on next use.\n void swallow(\"refresh wallet account\", async () => {\n await this.refreshWalletAccount();\n });\n }\n }\n\n /**\n * Return the connected wallet account, or throw {@link WalletAccountNotReadyError}\n * while the initial async lookup is pending, or {@link WalletNotConnectedError}\n * when no wallet is connected.\n */\n override requireWalletAccount(operation: string): WalletAccount {\n const account = this.walletAccount.getSnapshot();\n if (!account && !this.walletAccount.isReady()) {\n throw new WalletAccountNotReadyError(operation);\n }\n if (!account) {\n throw new WalletNotConnectedError(operation);\n }\n return account;\n }\n\n /** Re-fetch the wallet account from the provider or signer and update `walletAccount`. */\n refreshWalletAccount(): Promise<WalletAccount | undefined> {\n if (this.#eip1193) {\n return this.#refreshFromEthereum();\n }\n if (this.#directSigner) {\n return this.#refreshFromSigner(this.#directSigner);\n }\n return Promise.resolve(undefined);\n }\n\n /** Unsubscribe from the EIP-1193 provider's wallet lifecycle events. */\n protected override onDispose(): void {\n this.#unsubscribeProvider();\n }\n\n async #resolveSigner(): Promise<Signer> {\n if (this.#directSigner) {\n return this.#directSigner;\n }\n if (!this.#browserProvider) {\n throw new SignerNotConfiguredError(\"resolveSigner\");\n }\n return this.#browserProvider.getSigner();\n }\n\n async #walletAccountFromSigner(signer: Signer): Promise<WalletAccount | undefined> {\n const provider = signer.provider;\n if (!provider) {\n return undefined;\n }\n const [address, network] = await Promise.all([signer.getAddress(), provider.getNetwork()]);\n return { address: getAddress(address), chainId: Number(network.chainId) };\n }\n\n /** Sign EIP-712 typed data (used for decrypt authorization). */\n async signTypedData(typedData: EIP712TypedData): Promise<Hex> {\n const signer = await this.#resolveSigner();\n const { domain, types, message } = typedData;\n const { EIP712Domain: _, ...sigTypes } = types;\n const mutableSigTypes = Object.fromEntries(\n Object.entries(sigTypes).map(([name, fields]) => [name, [...fields]]),\n );\n const sig = await signer.signTypedData(domain as TypedDataDomain, mutableSigTypes, message);\n if (!isHex(sig)) {\n throw new TypeError(`Expected hex string, got: ${sig}`);\n }\n return sig;\n }\n\n /** Send a write transaction and return the tx hash. */\n async writeContract<\n const TAbi extends Abi | readonly unknown[],\n TFunctionName extends ContractFunctionName<TAbi, \"nonpayable\" | \"payable\">,\n const TArgs extends ContractFunctionArgs<TAbi, \"nonpayable\" | \"payable\", TFunctionName>,\n >(config: WriteContractConfig<TAbi, TFunctionName, TArgs>): Promise<Hex> {\n const signer = await this.#resolveSigner();\n const contract = new Contract(config.address, config.abi as InterfaceAbi, signer);\n const overrides: { gasLimit?: bigint; value?: bigint } = {};\n if (config.value !== undefined) {\n overrides.value = config.value;\n }\n if (config.gas !== undefined) {\n overrides.gasLimit = config.gas;\n }\n const fn = contract.getFunction(config.functionName);\n const tx = await fn(...(config.args as readonly unknown[]), overrides);\n if (!isHex(tx.hash)) {\n throw new TypeError(`Expected hex string, got: ${tx.hash}`);\n }\n return tx.hash;\n }\n\n async #refreshFromSigner(signer: Signer): Promise<WalletAccount | undefined> {\n this.#accountPromise ??= this.#walletAccountFromSigner(signer)\n .then((account) => {\n this.walletAccount.setSnapshot(account);\n return account;\n })\n .finally(() => {\n this.#accountPromise = undefined;\n });\n return this.#accountPromise;\n }\n\n async #refreshFromEthereum(): Promise<WalletAccount | undefined> {\n const account = await this.#loadBrowserWalletAccount();\n this.walletAccount.setSnapshot(account);\n return account;\n }\n\n async #loadBrowserWalletAccount(): Promise<WalletAccount | undefined> {\n const ethereum = this.#eip1193;\n if (!ethereum) {\n return undefined;\n }\n const [accounts, chainIdValue] = await Promise.all([\n ethereum.request({ method: \"eth_accounts\" }),\n ethereum.request({ method: \"eth_chainId\" }),\n ]);\n if (!Array.isArray(accounts) || typeof accounts[0] !== \"string\") {\n return undefined;\n }\n const chainId = Number(chainIdValue);\n if (!Number.isSafeInteger(chainId) || chainId <= 0) {\n return undefined;\n }\n return { address: getAddress(accounts[0]), chainId };\n }\n}\n","import type { FheChain } from \"../chains\";\nimport { buildZamaConfig } from \"../config/build\";\nimport type { ZamaConfig } from \"../config/types\";\nimport { EthersProvider } from \"./ethers-provider\";\nimport { EthersSigner } from \"./ethers-signer\";\nimport type { ZamaConfigEthers } from \"./types\";\n\n/** Create a {@link ZamaConfig} from ethers types. */\nexport function createConfig<const TChains extends readonly [FheChain, ...FheChain[]]>(\n params: ZamaConfigEthers<TChains>,\n): ZamaConfig {\n if (\"signer\" in params && params.signer) {\n const signer = new EthersSigner({ signer: params.signer });\n if (!params.signer.provider) {\n throw new Error(\"createConfig requires a Signer with an attached provider for chain reads\");\n }\n const provider = new EthersProvider({ provider: params.signer.provider });\n return buildZamaConfig(signer, provider, params);\n }\n\n const signer = new EthersSigner({ ethereum: params.ethereum });\n const provider =\n \"provider\" in params && params.provider\n ? new EthersProvider({ provider: params.provider })\n : new EthersProvider({ ethereum: params.ethereum });\n return buildZamaConfig(signer, provider, params);\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import{C as e,t,x as n}from"./relayer-B6Zo6EkX.js";import{n as r}from"./encryption-DJljZ2oV.js";import{n as i,t as a}from"./applied-runtime-3fzqBC2V.js";import{createPublicClient as o,custom as s,http as c}from"viem";import{canUseUnifiedDecryptionPermit as l,createUnsignedLegacyDecryptionPermitEip712 as u,createUnsignedUnifiedDecryptionPermitEip712 as d}from"@fhevm/sdk/actions/base";import{createFhevmBaseClient as f,createFhevmDecryptClient as p,createFhevmEncryptClient as m,hasFhevmRuntimeConfig as h}from"@fhevm/sdk/viem";import{createFhevmCleartextBaseClient as ee,createFhevmCleartextDecryptClient as te,createFhevmCleartextEncryptClient as ne}from"@fhevm/sdk/viem/cleartext";function g(e){return{id:e.id,fhevm:{contracts:{acl:{address:e.aclContractAddress},inputVerifier:{address:e.inputVerifierContractAddress},kmsVerifier:{address:e.kmsContractAddress},protocolConfig:e.protocolConfigContractAddress?{address:e.protocolConfigContractAddress}:void 0},relayerUrl:e.relayerUrl,gateway:{id:e.gatewayChainId,contracts:{decryption:{address:e.verifyingContractAddressDecryption},inputVerification:{address:e.verifyingContractAddressInputVerification}}}}}}
|
|
2
|
+
/**
|
|
3
|
+
* @license
|
|
4
|
+
* Copyright 2019 Google LLC
|
|
5
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
6
|
+
*/
|
|
7
|
+
const _=Symbol(`Comlink.proxy`),v=Symbol(`Comlink.endpoint`),y=Symbol(`Comlink.releaseProxy`),b=Symbol(`Comlink.finalizer`),x=Symbol(`Comlink.thrown`),S=e=>typeof e==`object`&&!!e||typeof e==`function`,C=new Map([[`proxy`,{canHandle:e=>S(e)&&e[_],serialize(e){let{port1:t,port2:n}=new MessageChannel;return w(e,t),[n,[n]]},deserialize(e){return e.start(),E(e)}}],[`throw`,{canHandle:e=>S(e)&&x in e,serialize({value:e}){let t;return t=e instanceof Error?{isError:!0,value:{message:e.message,name:e.name,stack:e.stack}}:{isError:!1,value:e},[t,[]]},deserialize(e){throw e.isError?Object.assign(Error(e.value.message),e.value):e.value}}]]);function re(e,t){for(let n of e)if(t===n||n===`*`||n instanceof RegExp&&n.test(t))return!0;return!1}function w(e,t=globalThis,n=[`*`]){t.addEventListener(`message`,function r(i){if(!i||!i.data)return;if(!re(n,i.origin)){console.warn(`Invalid origin '${i.origin}' for comlink proxy`);return}let{id:a,type:o,path:s}=Object.assign({path:[]},i.data),c=(i.data.argumentList||[]).map(L),l;try{let t=s.slice(0,-1).reduce((e,t)=>e[t],e),n=s.reduce((e,t)=>e[t],e);switch(o){case`GET`:l=n;break;case`SET`:t[s.slice(-1)[0]]=L(i.data.value),l=!0;break;case`APPLY`:l=n.apply(t,c);break;case`CONSTRUCT`:l=F(new n(...c));break;case`ENDPOINT`:{let{port1:t,port2:n}=new MessageChannel;w(e,n),l=P(t,[t])}break;case`RELEASE`:l=void 0;break;default:return}}catch(e){l={value:e,[x]:0}}Promise.resolve(l).catch(e=>({value:e,[x]:0})).then(n=>{let[i,s]=I(n);t.postMessage(Object.assign(Object.assign({},i),{id:a}),s),o===`RELEASE`&&(t.removeEventListener(`message`,r),T(t),b in e&&typeof e[b]==`function`&&e[b]())}).catch(e=>{let[n,r]=I({value:TypeError(`Unserializable return value`),[x]:0});t.postMessage(Object.assign(Object.assign({},n),{id:a}),r)})}),t.start&&t.start()}function ie(e){return e.constructor.name===`MessagePort`}function T(e){ie(e)&&e.close()}function E(e,t){let n=new Map;return e.addEventListener(`message`,function(e){let{data:t}=e;if(!t||!t.id)return;let r=n.get(t.id);if(r)try{r(t)}finally{n.delete(t.id)}}),j(e,n,[],t)}function D(e){if(e)throw Error(`Proxy has been released and is not useable`)}function O(e){return R(e,new Map,{type:`RELEASE`}).then(()=>{T(e)})}const k=new WeakMap,A=`FinalizationRegistry`in globalThis&&new FinalizationRegistry(e=>{let t=(k.get(e)||0)-1;k.set(e,t),t===0&&O(e)});function ae(e,t){let n=(k.get(t)||0)+1;k.set(t,n),A&&A.register(e,t,e)}function oe(e){A&&A.unregister(e)}function j(e,t,n=[],r=function(){}){let i=!1,a=new Proxy(r,{get(r,o){if(D(i),o===y)return()=>{oe(a),O(e),t.clear(),i=!0};if(o===`then`){if(n.length===0)return{then:()=>a};let r=R(e,t,{type:`GET`,path:n.map(e=>e.toString())}).then(L);return r.then.bind(r)}return j(e,t,[...n,o])},set(r,a,o){D(i);let[s,c]=I(o);return R(e,t,{type:`SET`,path:[...n,a].map(e=>e.toString()),value:s},c).then(L)},apply(r,a,o){D(i);let s=n[n.length-1];if(s===v)return R(e,t,{type:`ENDPOINT`}).then(L);if(s===`bind`)return j(e,t,n.slice(0,-1));let[c,l]=M(o);return R(e,t,{type:`APPLY`,path:n.map(e=>e.toString()),argumentList:c},l).then(L)},construct(r,a){D(i);let[o,s]=M(a);return R(e,t,{type:`CONSTRUCT`,path:n.map(e=>e.toString()),argumentList:o},s).then(L)}});return ae(a,e),a}function se(e){return Array.prototype.concat.apply([],e)}function M(e){let t=e.map(I);return[t.map(e=>e[0]),se(t.map(e=>e[1]))]}const N=new WeakMap;function P(e,t){return N.set(e,t),e}function F(e){return Object.assign(e,{[_]:!0})}function I(e){for(let[t,n]of C)if(n.canHandle(e)){let[r,i]=n.serialize(e);return[{type:`HANDLER`,name:t,value:r},i]}return[{type:`RAW`,value:e},N.get(e)||[]]}function L(e){switch(e.type){case`HANDLER`:return C.get(e.name).deserialize(e.value);case`RAW`:return e.value}}function R(e,t,n,r){return new Promise(i=>{let a=z();t.set(a,i),e.start&&e.start(),e.postMessage(Object.assign({id:a},n),r)})}function z(){return[,,,,].fill(0).map(()=>Math.floor(Math.random()*(2**53-1)).toString(16)).join(`-`)}function B(e){return typeof e==`object`&&!!e&&e.wireError===!0}const V=[`statusCode`,`status`,`retryAfter`,`timeoutMs`,`relayerApiError`,`code`,`data`,`shortMessage`,`details`,`error`,`info`];function H(e){try{return structuredClone(e),!0}catch{return!1}}function U(t){let n=t.response;return e(n?.headers)}function W(e){try{return JSON.stringify(e)??String(e)}catch{return String(e)}}function G(e){let t={};for(let n of V){let r=e[n];r!==void 0&&H(r)&&(t[n]=r)}if(!n(t.retryAfter)){let n=U(e);n!==void 0&&(t.retryAfter=n)}return t}function K(e,t=6){if(B(e))return e;let n=e=>t>0&&e!==void 0?K(e,t-1):void 0;if(e instanceof Error)return{wireError:!0,name:e.name,message:e.message,stack:e.stack,props:G(e),cause:n(e.cause)};if(typeof e==`object`&&e){let{message:t,cause:r}=e;return{wireError:!0,name:`Error`,message:typeof t==`string`?t:W(e),stack:void 0,props:G(e),cause:n(r)}}return{wireError:!0,name:`Error`,message:typeof e==`string`?e:W(e),stack:void 0,props:{},cause:void 0}}function q(e){let t=Error(e.message,e.cause?{cause:q(e.cause)}:{});return t.name=e.name,e.stack!==void 0&&(t.stack=e.stack),Object.assign(t,e.props),t}function ce(){return new Worker(new URL(`./encrypt.worker.js`,import.meta.url),{type:`module`,name:`zama-fhe-encrypt`})}const J={spawn:1e4,init:3e5},Y=new WeakSet;var X=class extends Error{crashed;constructor(e,t){super(e,t),this.name=`WorkerUnavailableError`,this.crashed=t?.crashed??!1}};function Z(e){if(typeof e!=`object`||!e)return!1;let{name:t,message:n}=e;return t===`DataCloneError`||t===`TypeError`&&typeof n==`string`&&n.includes(`Unserializable return value`)}function Q(e){if(e?.aborted)throw e.reason??new DOMException(`The operation was aborted.`,`AbortError`)}const $={count:0,last:void 0,warnedFor:-1};function le(e){if(e===void 0)return{key:e,transfers:[]};let t=e.publicKeyBytes.bytes,n=e.crsBytes.bytes;if(!(t instanceof Uint8Array)||!(n instanceof Uint8Array))return{key:e,transfers:[]};let r=t.slice(),i=n.slice();return{key:{...e,publicKeyBytes:{...e.publicKeyBytes,bytes:r},crsBytes:{...e.crsBytes,bytes:i}},transfers:[r.buffer,i.buffer]}}function ue(){let e,t=new Promise((t,n)=>{e=n});return t.catch(()=>{}),{initPromise:void 0,worker:void 0,api:void 0,doomed:t,doom:e}}var de=class{#e;#t;#n=!1;#r=$;#i=0;#a=new Map;#o;#s=0;#c=!1;constructor(e){this.#e=e}init=()=>{let e=this.#t??=ue();if(e.initPromise===void 0){let t=this.#f(()=>this.#u(e)).catch(n=>{throw e.initPromise===t&&(e.initPromise=void 0),n});e.initPromise=t}return e.initPromise};encryptValue=e=>this.#f(()=>this.#l(t=>t.encryptValue(e),(t,n,r)=>t.encryptValue(n,{...e,options:r}),e.options));encryptValues=e=>this.#f(()=>this.#l(t=>t.encryptValues(e),(t,n,r)=>t.encryptValues(n,{...e,options:r}),e.options));dispose(){this.#c=!0,this.#p()}async#l(e,t,n){let{signal:r,onProgress:i,...a}=n??{};Q(r),await this.init(),Q(r);let o=this.#t,s=o?.api;if(this.#o!==void 0&&(this.#n||s===void 0))return e(await this.#o);if(o===void 0||s===void 0)return e(await this.#b(o,this.#r.last??new X(`Encrypt worker not running.`)));let c=this.#i++,l=()=>void s.abort(c).catch(()=>{});r?.addEventListener(`abort`,l,{once:!0}),i&&this.#a.set(c,i);try{let e=await this.#v(o,t(s,c,a));return this.#r=$,e}catch(t){if(t instanceof X)return e(await this.#b(o,t));throw t}finally{this.#a.delete(c),r?.removeEventListener(`abort`,l)}}async#u(e){if(this.#n)return;let t=this.#e.blockedReason;if(t!==void 0){await this.#b(e,new X(t));return}let n=await this.#e.prefetchKey();try{let t=await this.#h(e),r=this.#e.network,i=typeof r==`string`?null:F(async e=>{try{return await r.request(e)}catch(e){throw K(e)}}),a=F((e,t)=>{try{this.#e.logger[e](t)}catch(e){this.#d(`logger`,e)}}),o=F((e,t)=>{try{this.#a.get(e)?.(t)}catch(e){this.#d(`onProgress`,e)}}),s=le(n);await this.#v(e,t.init(P({...this.#e.initPayload,clientOptions:{...this.#e.initPayload.clientOptions,fheEncryptionKey:s.key},rpcUrl:typeof r==`string`?r:void 0},s.transfers),i,a,o),{ms:this.#e.timeouts.init,operation:`init`}),e.api=t,this.#r={...this.#r,last:void 0}}catch(t){if(!(t instanceof X))throw this.#y(e,new X(`Encrypt worker init failed.`)),t;await this.#b(e,t)}}#d(e,t){let n=t instanceof Error?t.message:String(t);try{this.#e.logger.warn(`Encrypt offload ${e} callback threw: ${n}`)}catch{}}async#f(e){this.#s++;try{return await e()}finally{this.#s--,this.#p()}}#p(){!this.#c||this.#s>0||(this.#c=!1,this.#t?.worker?.terminate(),this.#t=void 0,this.#o=void 0,this.#n=!1,this.#r=$)}#m(){let e=this.#e.workerSource;if(e===void 0)return ce();if(typeof e==`function`){let t=e();return Y.has(t)&&this.#e.logger.warnAlways(`The offloadWorker factory returned a worker it already handed out; each call must construct a fresh Worker.`),Y.add(t),t}return new Worker(e,{type:`module`,name:`zama-fhe-encrypt`})}async#h(e){let t;try{t=this.#m()}catch(e){throw new X(e instanceof Error?e.message:String(e),{cause:e})}e.worker=t;let n=await this.#g(e,t);return this.#_(e,t),n}#g(e,t){return new Promise((n,r)=>{let i=()=>{clearTimeout(a),t.removeEventListener(`message`,o),t.removeEventListener(`error`,s)},a=setTimeout(()=>{i(),r(new X(`Encrypt worker did not start within ${this.#e.timeouts.spawn}ms.`))},this.#e.timeouts.spawn),o=e=>{e.data===`zama-encrypt-worker-ready`&&(i(),n(E(t)))},s=t=>{i();let n=t.message||`Encrypt worker error.`;r(new X(n)),this.#y(e,new X(n))};t.addEventListener(`message`,o),t.addEventListener(`error`,s)})}#_(e,t){t.addEventListener(`error`,t=>{if(this.#t!==e)return;let n=new X(t.message||`Encrypt worker error.`,{crashed:!0});this.#r={...this.#r,count:this.#r.count+1,last:n},this.#y(e,n)})}async#v(e,t,n){let r=n===void 0?void 0:setTimeout(()=>{this.#y(e,new X(`Encrypt worker ${n.operation} timed out after ${n.ms}ms.`))},n.ms);try{return await Promise.race([t.catch(e=>{let t=B(e)?q(e):e;throw Z(t)?new X(t.message,{cause:t}):t}),e.doomed])}finally{r!==void 0&&clearTimeout(r)}}#y(e,t){e!==void 0&&(this.#t===e&&(this.#t=void 0),e.worker?.terminate(),e.worker=void 0,e.api=void 0,e.initPromise=void 0,e.doom(t))}async#b(e,t){let n=t instanceof Error?t.message:String(t);if(this.#e.strict)throw this.#y(e,new X(`Encrypt worker unavailable.`)),new r(`Encrypt offload required (offloadEncrypt: true) but unavailable: ${n}`,{cause:t});let{transient:i,pinning:a}=this.#x(t);if(this.#n||=!i,this.#y(e,new X(`Encrypt worker degraded to inline.`)),this.#S(n,i,a),this.#o===void 0){let e=(async()=>{let e=this.#e.createInlineClient();return await e.init(),e})().catch(t=>{throw this.#o===e&&(this.#o=void 0),this.#e.logger.warnAlways(`Encrypt inline fallback failed to initialize: ${t instanceof Error?t.message:String(t)}`),t});this.#o=e}return this.#o}#x(e){let t=e instanceof X&&e.crashed&&this.#r.count<2;return{transient:t,pinning:!t&&!this.#n}}#S(e,t,n){if(!n&&this.#r.warnedFor===this.#r.count)return;this.#r={...this.#r,warnedFor:this.#r.count};let r=t?`in-flight encryption falls back`:`encryption falls back`;this.#e.logger.warnAlways(`Encrypt offload unavailable, ${r} to the calling thread: ${e}`)}},fe=class{#e;#t;#n;#r;#i;#a;constructor(e){this.#e=e.chain;let{timeout:t,debug:n,batchRpcCalls:r,moduleVersions:i,fheEncryptionKey:a}=e.options??{},l=this.#e.auth?me(this.#e.auth):void 0,u={publicClient:o({transport:typeof this.#e.network==`string`?c(this.#e.network):s(this.#e.network)}),chain:g(this.#e),options:{batchRpcCalls:r,moduleVersions:i,fheEncryptionKey:a}};this.#i={...l!==void 0&&{auth:l},...t!==void 0&&{timeout:t},...n!==void 0&&{debug:n}};let d=()=>this.#t.fetchFheEncryptionKeyBytes({options:this.#i}),h=e=>({init:async()=>{await d(),await e.init()},encryptValue:t=>e.encryptValue(t),encryptValues:t=>e.encryptValues(t),fetchFheEncryptionKeyBytes:t=>e.fetchFheEncryptionKeyBytes(t)});e.cleartext?(this.#t=ee(u),this.#n=te(u),this.#r=h(ne(u))):(this.#t=f(u),this.#n=p(u),this.#r=this.#o(e,u,{prefetchKey:d,createInlineClient:()=>h(m(u))}))}#o(e,t,n){let r=e.offloadEncrypt??!1,i=r===!0,o=typeof Worker==`function`&&(e.offloadWorker!==void 0||!0);if(r===!1||!(i||o))return n.createInlineClient();let s=a(),c=pe(s);if(c!==void 0&&!i)return e.logger.warnAlways(`Encryption runs on the calling thread: ${c}.`),n.createInlineClient();let l=new de({initPayload:{chain:t.chain,clientOptions:t.options,runtime:s??{}},network:this.#e.network,prefetchKey:n.prefetchKey,createInlineClient:n.createInlineClient,logger:e.logger,timeouts:e.offloadTimeouts??J,workerSource:e.offloadWorker,blockedReason:c,strict:i});return{init:()=>l.init(),encryptValue:e=>l.encryptValue(e),encryptValues:e=>l.encryptValues(e),fetchFheEncryptionKeyBytes:e=>this.#t.fetchFheEncryptionKeyBytes(e),dispose:()=>l.dispose()}}get chain(){return this.#e}#s=()=>(this.#a??=this.#r.init().catch(e=>{throw this.#a=void 0,e}),this.#a);dispose=()=>{this.#a=void 0,this.#r.dispose?.()};decryptPublicValue=async e=>(await this.#t.init(),this.#t.decryptPublicValue({...e,options:{...this.#i,...e.options}}));decryptPublicValues=async e=>(await this.#t.init(),this.#t.decryptPublicValues({...e,options:{...this.#i,...e.options}}));decryptPublicValuesWithSignatures=async e=>(await this.#t.init(),this.#t.decryptPublicValuesWithSignatures({...e,options:{...this.#i,...e.options}}));encryptValue=async e=>(await this.#s(),this.#r.encryptValue({...e,options:{...this.#i,...e.options}}));encryptValues=async e=>(await this.#s(),this.#r.encryptValues({...e,options:{...this.#i,...e.options}}));decryptValue=async e=>(await this.#n.init(),this.#n.decryptValue({...e,options:{...this.#i,...e.options}}));decryptValues=async e=>(await this.#n.init(),this.#n.decryptValues({...e,options:{...this.#i,...e.options}}));decryptValuesFromPairs=async e=>(await this.#n.init(),this.#n.decryptValuesFromPairs({...e,options:{...this.#i,...e.options}}));fetchFheEncryptionKeyBytes=async e=>(await this.#t.init(),this.#t.fetchFheEncryptionKeyBytes({...e,options:{...this.#i,...e?.options}}));signDecryptionPermit=async e=>(await this.#t.init(),this.#t.signDecryptionPermit(e));signUnifiedDecryptionPermit=async e=>(await this.#t.init(),this.#t.signUnifiedDecryptionPermit(e));createUnsignedLegacyDecryptionPermitEip712=e=>u(this.#t,e);createUnsignedUnifiedDecryptionPermitEip712=e=>d(this.#t,e);canUseUnifiedDecryptionPermit=e=>l(this.#t,{options:{...this.#i,...e?.options}});serializeTransportKeyPair=e=>this.#n.serializeTransportKeyPair(e);serializeSignedDecryptionPermit=e=>this.#t.serializeSignedDecryptionPermit(e);parseTransportKeyPair=async e=>(await this.#n.init(),this.#n.parseTransportKeyPair(e));parseSignedDecryptionPermit=async e=>(await this.#t.init(),this.#t.parseSignedDecryptionPermit(e));generateTransportKeyPair=async()=>(await this.#n.init(),this.#n.generateTransportKeyPair())};function pe(e){if(i())return`a runtime locateFile cannot cross the encrypt worker boundary`;if(e===void 0&&h())return`a runtime config set outside createConfig cannot be replicated in the encrypt worker realm`}function me(e){let n=e.__type;switch(n){case`ApiKeyHeader`:return{type:n,value:e.value,header:e.header};case`ApiKeyCookie`:return{type:n,value:e.value,cookie:e.cookie};case`BearerToken`:return{type:n,token:e.token};default:throw new t(`Unknown auth type: ${String(n)}`)}}export{J as n,fe as t};
|
|
8
|
+
//# sourceMappingURL=fhevm-relayer-CPmCytDX.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fhevm-relayer-CPmCytDX.js","names":["#config","#progressListeners","#generation","#withActive","#initOnce","#dispatch","#releaseRequested","#releaseIfIdle","#degradePromise","#pinnedInline","#degrade","#crashes","#sequence","#overBoundary","#spawn","#warnCallbackThrew","#teardown","#active","#createWorker","#raceReady","#armCrashHandler","#classifyDegrade","#warnDegraded","#chain","#base","#decrypt","#encrypt","#defaultOptions","#buildEncryptBackend","#encryptInitPromise","#initEncrypt","createUnsignedLegacyDecryptionPermitEip712Action","createUnsignedUnifiedDecryptionPermitEip712Action","canUseUnifiedDecryptionPermitAction"],"sources":["../../src/chains/to-fhevm-chain.ts","../../../../node_modules/.pnpm/comlink@4.4.2/node_modules/comlink/dist/esm/comlink.mjs","../../src/worker/protocol.ts","../../src/worker/spawn.ts","../../src/worker/encrypt-worker-client.ts","../../src/relayer/fhevm-relayer.ts"],"sourcesContent":["import type { FhevmChain } from \"@fhevm/sdk/chains\";\nimport type { FheChain } from \"./types\";\n\n/**\n * Derive an `@fhevm/sdk` {@link FhevmChain} from zama-sdk's richer\n * {@link FheChain}.\n *\n * `FheChain` carries fields `@fhevm/sdk` does not model (RPC `network`,\n * `registryAddress`, `executorAddress`, cleartext signer keys); those stay on\n * `FheChain` for the token layer. This adapter projects only the subset the\n * FHE runtime needs: contract addresses, relayer URL, and gateway.\n */\nexport function toFhevmChain(chain: FheChain): FhevmChain {\n return {\n id: chain.id,\n fhevm: {\n contracts: {\n acl: { address: chain.aclContractAddress },\n inputVerifier: { address: chain.inputVerifierContractAddress },\n kmsVerifier: { address: chain.kmsContractAddress },\n protocolConfig: chain.protocolConfigContractAddress\n ? { address: chain.protocolConfigContractAddress }\n : undefined,\n },\n relayerUrl: chain.relayerUrl,\n gateway: {\n id: chain.gatewayChainId,\n contracts: {\n decryption: { address: chain.verifyingContractAddressDecryption },\n inputVerification: { address: chain.verifyingContractAddressInputVerification },\n },\n },\n },\n } satisfies FhevmChain;\n}\n","/**\n * @license\n * Copyright 2019 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\nconst proxyMarker = Symbol(\"Comlink.proxy\");\nconst createEndpoint = Symbol(\"Comlink.endpoint\");\nconst releaseProxy = Symbol(\"Comlink.releaseProxy\");\nconst finalizer = Symbol(\"Comlink.finalizer\");\nconst throwMarker = Symbol(\"Comlink.thrown\");\nconst isObject = (val) => (typeof val === \"object\" && val !== null) || typeof val === \"function\";\n/**\n * Internal transfer handle to handle objects marked to proxy.\n */\nconst proxyTransferHandler = {\n canHandle: (val) => isObject(val) && val[proxyMarker],\n serialize(obj) {\n const { port1, port2 } = new MessageChannel();\n expose(obj, port1);\n return [port2, [port2]];\n },\n deserialize(port) {\n port.start();\n return wrap(port);\n },\n};\n/**\n * Internal transfer handler to handle thrown exceptions.\n */\nconst throwTransferHandler = {\n canHandle: (value) => isObject(value) && throwMarker in value,\n serialize({ value }) {\n let serialized;\n if (value instanceof Error) {\n serialized = {\n isError: true,\n value: {\n message: value.message,\n name: value.name,\n stack: value.stack,\n },\n };\n }\n else {\n serialized = { isError: false, value };\n }\n return [serialized, []];\n },\n deserialize(serialized) {\n if (serialized.isError) {\n throw Object.assign(new Error(serialized.value.message), serialized.value);\n }\n throw serialized.value;\n },\n};\n/**\n * Allows customizing the serialization of certain values.\n */\nconst transferHandlers = new Map([\n [\"proxy\", proxyTransferHandler],\n [\"throw\", throwTransferHandler],\n]);\nfunction isAllowedOrigin(allowedOrigins, origin) {\n for (const allowedOrigin of allowedOrigins) {\n if (origin === allowedOrigin || allowedOrigin === \"*\") {\n return true;\n }\n if (allowedOrigin instanceof RegExp && allowedOrigin.test(origin)) {\n return true;\n }\n }\n return false;\n}\nfunction expose(obj, ep = globalThis, allowedOrigins = [\"*\"]) {\n ep.addEventListener(\"message\", function callback(ev) {\n if (!ev || !ev.data) {\n return;\n }\n if (!isAllowedOrigin(allowedOrigins, ev.origin)) {\n console.warn(`Invalid origin '${ev.origin}' for comlink proxy`);\n return;\n }\n const { id, type, path } = Object.assign({ path: [] }, ev.data);\n const argumentList = (ev.data.argumentList || []).map(fromWireValue);\n let returnValue;\n try {\n const parent = path.slice(0, -1).reduce((obj, prop) => obj[prop], obj);\n const rawValue = path.reduce((obj, prop) => obj[prop], obj);\n switch (type) {\n case \"GET\" /* MessageType.GET */:\n {\n returnValue = rawValue;\n }\n break;\n case \"SET\" /* MessageType.SET */:\n {\n parent[path.slice(-1)[0]] = fromWireValue(ev.data.value);\n returnValue = true;\n }\n break;\n case \"APPLY\" /* MessageType.APPLY */:\n {\n returnValue = rawValue.apply(parent, argumentList);\n }\n break;\n case \"CONSTRUCT\" /* MessageType.CONSTRUCT */:\n {\n const value = new rawValue(...argumentList);\n returnValue = proxy(value);\n }\n break;\n case \"ENDPOINT\" /* MessageType.ENDPOINT */:\n {\n const { port1, port2 } = new MessageChannel();\n expose(obj, port2);\n returnValue = transfer(port1, [port1]);\n }\n break;\n case \"RELEASE\" /* MessageType.RELEASE */:\n {\n returnValue = undefined;\n }\n break;\n default:\n return;\n }\n }\n catch (value) {\n returnValue = { value, [throwMarker]: 0 };\n }\n Promise.resolve(returnValue)\n .catch((value) => {\n return { value, [throwMarker]: 0 };\n })\n .then((returnValue) => {\n const [wireValue, transferables] = toWireValue(returnValue);\n ep.postMessage(Object.assign(Object.assign({}, wireValue), { id }), transferables);\n if (type === \"RELEASE\" /* MessageType.RELEASE */) {\n // detach and deactive after sending release response above.\n ep.removeEventListener(\"message\", callback);\n closeEndPoint(ep);\n if (finalizer in obj && typeof obj[finalizer] === \"function\") {\n obj[finalizer]();\n }\n }\n })\n .catch((error) => {\n // Send Serialization Error To Caller\n const [wireValue, transferables] = toWireValue({\n value: new TypeError(\"Unserializable return value\"),\n [throwMarker]: 0,\n });\n ep.postMessage(Object.assign(Object.assign({}, wireValue), { id }), transferables);\n });\n });\n if (ep.start) {\n ep.start();\n }\n}\nfunction isMessagePort(endpoint) {\n return endpoint.constructor.name === \"MessagePort\";\n}\nfunction closeEndPoint(endpoint) {\n if (isMessagePort(endpoint))\n endpoint.close();\n}\nfunction wrap(ep, target) {\n const pendingListeners = new Map();\n ep.addEventListener(\"message\", function handleMessage(ev) {\n const { data } = ev;\n if (!data || !data.id) {\n return;\n }\n const resolver = pendingListeners.get(data.id);\n if (!resolver) {\n return;\n }\n try {\n resolver(data);\n }\n finally {\n pendingListeners.delete(data.id);\n }\n });\n return createProxy(ep, pendingListeners, [], target);\n}\nfunction throwIfProxyReleased(isReleased) {\n if (isReleased) {\n throw new Error(\"Proxy has been released and is not useable\");\n }\n}\nfunction releaseEndpoint(ep) {\n return requestResponseMessage(ep, new Map(), {\n type: \"RELEASE\" /* MessageType.RELEASE */,\n }).then(() => {\n closeEndPoint(ep);\n });\n}\nconst proxyCounter = new WeakMap();\nconst proxyFinalizers = \"FinalizationRegistry\" in globalThis &&\n new FinalizationRegistry((ep) => {\n const newCount = (proxyCounter.get(ep) || 0) - 1;\n proxyCounter.set(ep, newCount);\n if (newCount === 0) {\n releaseEndpoint(ep);\n }\n });\nfunction registerProxy(proxy, ep) {\n const newCount = (proxyCounter.get(ep) || 0) + 1;\n proxyCounter.set(ep, newCount);\n if (proxyFinalizers) {\n proxyFinalizers.register(proxy, ep, proxy);\n }\n}\nfunction unregisterProxy(proxy) {\n if (proxyFinalizers) {\n proxyFinalizers.unregister(proxy);\n }\n}\nfunction createProxy(ep, pendingListeners, path = [], target = function () { }) {\n let isProxyReleased = false;\n const proxy = new Proxy(target, {\n get(_target, prop) {\n throwIfProxyReleased(isProxyReleased);\n if (prop === releaseProxy) {\n return () => {\n unregisterProxy(proxy);\n releaseEndpoint(ep);\n pendingListeners.clear();\n isProxyReleased = true;\n };\n }\n if (prop === \"then\") {\n if (path.length === 0) {\n return { then: () => proxy };\n }\n const r = requestResponseMessage(ep, pendingListeners, {\n type: \"GET\" /* MessageType.GET */,\n path: path.map((p) => p.toString()),\n }).then(fromWireValue);\n return r.then.bind(r);\n }\n return createProxy(ep, pendingListeners, [...path, prop]);\n },\n set(_target, prop, rawValue) {\n throwIfProxyReleased(isProxyReleased);\n // FIXME: ES6 Proxy Handler `set` methods are supposed to return a\n // boolean. To show good will, we return true asynchronously ¯\\_(ツ)_/¯\n const [value, transferables] = toWireValue(rawValue);\n return requestResponseMessage(ep, pendingListeners, {\n type: \"SET\" /* MessageType.SET */,\n path: [...path, prop].map((p) => p.toString()),\n value,\n }, transferables).then(fromWireValue);\n },\n apply(_target, _thisArg, rawArgumentList) {\n throwIfProxyReleased(isProxyReleased);\n const last = path[path.length - 1];\n if (last === createEndpoint) {\n return requestResponseMessage(ep, pendingListeners, {\n type: \"ENDPOINT\" /* MessageType.ENDPOINT */,\n }).then(fromWireValue);\n }\n // We just pretend that `bind()` didn’t happen.\n if (last === \"bind\") {\n return createProxy(ep, pendingListeners, path.slice(0, -1));\n }\n const [argumentList, transferables] = processArguments(rawArgumentList);\n return requestResponseMessage(ep, pendingListeners, {\n type: \"APPLY\" /* MessageType.APPLY */,\n path: path.map((p) => p.toString()),\n argumentList,\n }, transferables).then(fromWireValue);\n },\n construct(_target, rawArgumentList) {\n throwIfProxyReleased(isProxyReleased);\n const [argumentList, transferables] = processArguments(rawArgumentList);\n return requestResponseMessage(ep, pendingListeners, {\n type: \"CONSTRUCT\" /* MessageType.CONSTRUCT */,\n path: path.map((p) => p.toString()),\n argumentList,\n }, transferables).then(fromWireValue);\n },\n });\n registerProxy(proxy, ep);\n return proxy;\n}\nfunction myFlat(arr) {\n return Array.prototype.concat.apply([], arr);\n}\nfunction processArguments(argumentList) {\n const processed = argumentList.map(toWireValue);\n return [processed.map((v) => v[0]), myFlat(processed.map((v) => v[1]))];\n}\nconst transferCache = new WeakMap();\nfunction transfer(obj, transfers) {\n transferCache.set(obj, transfers);\n return obj;\n}\nfunction proxy(obj) {\n return Object.assign(obj, { [proxyMarker]: true });\n}\nfunction windowEndpoint(w, context = globalThis, targetOrigin = \"*\") {\n return {\n postMessage: (msg, transferables) => w.postMessage(msg, targetOrigin, transferables),\n addEventListener: context.addEventListener.bind(context),\n removeEventListener: context.removeEventListener.bind(context),\n };\n}\nfunction toWireValue(value) {\n for (const [name, handler] of transferHandlers) {\n if (handler.canHandle(value)) {\n const [serializedValue, transferables] = handler.serialize(value);\n return [\n {\n type: \"HANDLER\" /* WireValueType.HANDLER */,\n name,\n value: serializedValue,\n },\n transferables,\n ];\n }\n }\n return [\n {\n type: \"RAW\" /* WireValueType.RAW */,\n value,\n },\n transferCache.get(value) || [],\n ];\n}\nfunction fromWireValue(value) {\n switch (value.type) {\n case \"HANDLER\" /* WireValueType.HANDLER */:\n return transferHandlers.get(value.name).deserialize(value.value);\n case \"RAW\" /* WireValueType.RAW */:\n return value.value;\n }\n}\nfunction requestResponseMessage(ep, pendingListeners, msg, transfers) {\n return new Promise((resolve) => {\n const id = generateUUID();\n pendingListeners.set(id, resolve);\n if (ep.start) {\n ep.start();\n }\n ep.postMessage(Object.assign({ id }, msg), transfers);\n });\n}\nfunction generateUUID() {\n return new Array(4)\n .fill(0)\n .map(() => Math.floor(Math.random() * Number.MAX_SAFE_INTEGER).toString(16))\n .join(\"-\");\n}\n\nexport { createEndpoint, expose, finalizer, proxy, proxyMarker, releaseProxy, transfer, transferHandlers, windowEndpoint, wrap };\n//# sourceMappingURL=comlink.mjs.map\n","/**\n * Shared contract between the main-thread encrypt client and the encrypt\n * worker, spoken over Comlink. Every payload must survive `structuredClone`:\n * no `AbortSignal`, no class instances; callbacks cross as Comlink proxies.\n */\n\nimport type { FhevmChain } from \"@fhevm/sdk/chains\";\nimport type {\n FhevmClientOptions,\n FhevmEncryptBackend,\n FhevmRelayerOptions,\n WireRuntimeConfig,\n} from \"../relayer/types\";\nimport { isValidRetryAfterSeconds, readRetryAfterHeader } from \"../utils/error\";\n\ntype EncryptParameters = Parameters<FhevmEncryptBackend[\"encryptValue\"]>[0];\ntype EncryptsParameters = Parameters<FhevmEncryptBackend[\"encryptValues\"]>[0];\n\n/**\n * What the worker offloads, and all the encrypt client's surface the worker\n * client implements. Key fetches stay on the calling thread, where the chain's\n * auth applies and the key never crosses back out.\n */\nexport type EncryptOffloadBackend = Pick<\n FhevmEncryptBackend,\n \"init\" | \"encryptValue\" | \"encryptValues\"\n>;\n\n/** Per-request options minus `signal`, the one non-cloneable member of the set. */\nexport type WireRequestOptions = Omit<FhevmRelayerOptions, \"signal\">;\n\nexport type WireProgressEvent = Parameters<\n NonNullable<NonNullable<EncryptParameters[\"options\"]>[\"onProgress\"]>\n>[0];\n\nexport type WireInitPayload = {\n readonly chain: FhevmChain;\n /** RPC URL for host-chain reads; absent when reads proxy through `rpcRequest`. */\n readonly rpcUrl: string | undefined;\n /** Carries `fheEncryptionKey`, prefetched on the main thread so the worker skips the download. */\n readonly clientOptions: FhevmClientOptions;\n readonly runtime: WireRuntimeConfig;\n};\n\n/** Main-thread callback the worker uses for host-chain reads when the chain's network is an injected provider. */\nexport type WireRpcRequest = (args: { method: string; params?: unknown }) => Promise<unknown>;\n\n/**\n * Main-thread callback receiving every operation's progress events, routed on\n * `id`. One channel per worker avoids minting a `MessageChannel` per call, whose\n * local port and listener would linger until garbage collection after terminate.\n * Returns `unknown`: a Comlink proxy call answers with a promise.\n */\nexport type WireProgressCallback = (id: number, event: WireProgressEvent) => unknown;\n\nexport type WireLogCallback = (level: \"debug\" | \"warn\" | \"error\", message: string) => unknown;\n\n/**\n * The API the worker exposes over Comlink. `id` correlates an in-flight\n * operation with `abort` and with its progress events, since neither an\n * `AbortSignal` nor a per-call callback can cross the boundary cheaply. The\n * `init` callback parameters must be passed as Comlink proxies (or `null`).\n */\nexport type EncryptWorkerApi = {\n init(\n payload: WireInitPayload,\n rpcRequest: WireRpcRequest | null,\n log: WireLogCallback,\n onProgress: WireProgressCallback,\n ): Promise<void>;\n encryptValue(\n id: number,\n parameters: {\n readonly value: EncryptParameters[\"value\"];\n readonly contractAddress: string;\n readonly userAddress: string;\n readonly options: WireRequestOptions | undefined;\n },\n ): ReturnType<FhevmEncryptBackend[\"encryptValue\"]>;\n encryptValues(\n id: number,\n parameters: {\n readonly values: EncryptsParameters[\"values\"];\n readonly contractAddress: string;\n readonly userAddress: string;\n readonly options: WireRequestOptions | undefined;\n },\n ): ReturnType<FhevmEncryptBackend[\"encryptValues\"]>;\n abort(id: number): void;\n};\n\n/** Raw message the worker posts once its module graph has loaded, before Comlink traffic. */\nexport const WORKER_READY_MESSAGE = \"zama-encrypt-worker-ready\";\n\n/**\n * An `Error` flattened for the boundary crossing, thrown by the worker as a\n * plain object so it survives structured clone intact. `props` carries the\n * fields the SDK's duck-typed classifiers read (`statusCode`, `retryAfter`,\n * `code`, …); a cloned `Error` instance would drop them with the prototype.\n * Reading them through the prototype chain is deliberate: upstream's `status`\n * and `relayerApiError` are prototype getters, not own fields.\n */\nexport type WireError = {\n readonly wireError: true;\n readonly name: string;\n readonly message: string;\n readonly stack: string | undefined;\n readonly props: Record<string, unknown>;\n readonly cause: WireError | undefined;\n};\n\nexport function isWireError(value: unknown): value is WireError {\n // Exact `true`, not presence: an `Error` subclass carrying the key must not be\n // rehydrated as a flattened one.\n return (\n typeof value === \"object\" &&\n value !== null &&\n (value as { wireError?: unknown }).wireError === true\n );\n}\n\n/**\n * Fields preserved across the boundary: what the error classifiers read off\n * `@fhevm/sdk`, relayer, and JSON-RPC errors, plus the `error`/`info` nesting\n * keys those classifiers walk alongside `cause`.\n */\nconst WIRE_ERROR_PROPS = [\n \"statusCode\",\n \"status\",\n \"retryAfter\",\n \"timeoutMs\",\n \"relayerApiError\",\n \"code\",\n \"data\",\n \"shortMessage\",\n \"details\",\n \"error\",\n \"info\",\n] as const;\n\nconst MAX_CAUSE_DEPTH = 6;\n\n/** A probe is exact where a structural walk only approximates. */\nfunction isCloneSafe(value: unknown): boolean {\n try {\n structuredClone(value);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * The `Retry-After` header survives as a plain number of seconds; the\n * `Response` object it lives on cannot cross the boundary.\n */\nfunction retryAfterFromResponse(error: object): number | undefined {\n const response = (error as { response?: { headers?: unknown } }).response;\n return readRetryAfterHeader(response?.headers);\n}\n\n/**\n * `JSON.stringify` throws instead of returning `undefined` on a bigint or a\n * circular value; a non-Error thrown value must never fail error handling itself.\n */\nfunction stringifyNonError(error: unknown): string {\n try {\n return JSON.stringify(error) ?? String(error);\n } catch {\n return String(error);\n }\n}\n\n/** The classifier fields readable off one thrown value, `Error` or plain object alike. */\nfunction extractWireProps(source: object): Record<string, unknown> {\n const props: Record<string, unknown> = {};\n for (const key of WIRE_ERROR_PROPS) {\n const value = (source as Record<string, unknown>)[key];\n if (value !== undefined && isCloneSafe(value)) {\n props[key] = value;\n }\n }\n // The header wins over a malformed own delay (`0`, negative, `NaN`), as the\n // inline extractor in `utils/error.ts` decides it.\n if (!isValidRetryAfterSeconds(props[\"retryAfter\"])) {\n const fromHeader = retryAfterFromResponse(source);\n if (fromHeader !== undefined) {\n props[\"retryAfter\"] = fromHeader;\n }\n }\n return props;\n}\n\nexport function toWireError(error: unknown, depth: number = MAX_CAUSE_DEPTH): WireError {\n if (isWireError(error)) {\n return error;\n }\n const nest = (cause: unknown): WireError | undefined =>\n depth > 0 && cause !== undefined ? toWireError(cause, depth - 1) : undefined;\n if (error instanceof Error) {\n return {\n wireError: true,\n name: error.name,\n message: error.message,\n stack: error.stack,\n props: extractWireProps(error),\n cause: nest(error.cause),\n };\n }\n if (typeof error === \"object\" && error !== null) {\n // Wallets reject with a plain `{ code, message, data }`; dropping `code`\n // would break viem's classification inside the worker.\n const { message, cause } = error as { message?: unknown; cause?: unknown };\n return {\n wireError: true,\n name: \"Error\",\n message: typeof message === \"string\" ? message : stringifyNonError(error),\n stack: undefined,\n props: extractWireProps(error),\n cause: nest(cause),\n };\n }\n return {\n wireError: true,\n name: \"Error\",\n message: typeof error === \"string\" ? error : stringifyNonError(error),\n stack: undefined,\n props: {},\n cause: undefined,\n };\n}\n\n/**\n * Rebuilds a plain `Error` carrying the original `name`, own fields, and cause\n * chain, so name-based classification and status/retry-after extraction behave\n * as if the error had been thrown on this thread.\n */\nexport function fromWireError(wire: WireError): Error {\n const error = new Error(wire.message, wire.cause ? { cause: fromWireError(wire.cause) } : {});\n error.name = wire.name;\n if (wire.stack !== undefined) {\n error.stack = wire.stack;\n }\n Object.assign(error, wire.props);\n return error;\n}\n","/** Isolated so the CJS build can replace worker construction with an inert stub. */\n\n/** False in the CJS stub, which ships no worker chunk; a caller-supplied `offloadWorker` source works in either build. */\nexport const BUNDLED_ENCRYPT_WORKER = true;\n\nexport function createEncryptWorker(): Worker {\n // Keep the `new Worker(new URL(...))` expression exactly in this inline\n // form: bundlers detect it statically to emit and rewrite the worker chunk,\n // and lose it if the URL is hoisted into a variable.\n return new Worker(new URL(\"./encrypt.worker.js\", import.meta.url), {\n type: \"module\",\n name: \"zama-fhe-encrypt\",\n });\n}\n","import { proxy, transfer, wrap, type Remote } from \"comlink\";\nimport type { EIP1193Provider } from \"viem\";\nimport { EncryptOffloadUnavailableError } from \"../errors/encryption\";\nimport type { FhevmClientOptions } from \"../relayer/types\";\nimport type { LoggerService } from \"../services/logger-service\";\nimport type {\n EncryptOffloadBackend,\n EncryptWorkerApi,\n WireInitPayload,\n WireProgressEvent,\n WireRequestOptions,\n} from \"./protocol\";\nimport { WORKER_READY_MESSAGE, fromWireError, isWireError, toWireError } from \"./protocol\";\nimport { createEncryptWorker } from \"./spawn\";\n\n/**\n * Watchdog deadlines, in milliseconds, for worker lifecycle steps: each is a\n * ceiling on \"the worker never answered\", not on legitimate slow work. Encrypt\n * operations themselves are not watched: nothing bounds local WASM compute, so\n * a proof may run for as long as it needs.\n */\nexport type EncryptWorkerTimeouts = {\n /** Worker startup + module-graph load; a bundler that mishandled the worker URL fails here. */\n readonly spawn: number;\n /** Client init inside the worker realm: chain reads and WASM compilation. */\n readonly init: number;\n};\n\nexport const DEFAULT_ENCRYPT_WORKER_TIMEOUTS: EncryptWorkerTimeouts = {\n spawn: 10_000,\n init: 300_000,\n};\n\n/** Second crash pins the client to the calling thread. */\nconst CRASH_PIN_THRESHOLD = 2;\n\n/** Stable prefix of every degrade warning. */\nexport const ENCRYPT_OFFLOAD_WARN_PREFIX = \"Encrypt offload unavailable\";\n\n/** Workers already returned by an `offloadWorker` factory, to catch a factory that hands out one worker forever. */\nconst handedOutWorkers = new WeakSet<Worker>();\n\n/** Internal signal: the worker infrastructure failed; the operation itself was not rejected. */\nclass WorkerUnavailableError extends Error {\n /** True when a worker that had already signalled ready died under us, so a respawn is worth trying. */\n readonly crashed: boolean;\n\n constructor(message: string, options?: ErrorOptions & { readonly crashed?: boolean }) {\n super(message, options);\n this.name = \"WorkerUnavailableError\";\n this.crashed = options?.crashed ?? false;\n }\n}\n\n/**\n * A payload Comlink could not clone into the worker (`DataCloneError`) or could\n * not return out of it (its own `TypeError`): a boundary failure, so it degrades\n * rather than reaching the caller as an application error.\n */\nfunction isCloneFailure(error: unknown): boolean {\n if (typeof error !== \"object\" || error === null) {\n return false;\n }\n const { name, message } = error as { name?: unknown; message?: unknown };\n return (\n name === \"DataCloneError\" ||\n (name === \"TypeError\" &&\n typeof message === \"string\" &&\n message.includes(\"Unserializable return value\"))\n );\n}\n\nfunction throwIfAborted(signal: AbortSignal | undefined): void {\n if (signal?.aborted) {\n throw signal.reason ?? new DOMException(\"The operation was aborted.\", \"AbortError\");\n }\n}\n\n/** What the client remembers about worker crashes, dropped whole by a worker answer and by a release. */\ntype CrashHistory = {\n readonly count: number;\n /** The crash that killed the current worker, so a call landing after it degrades as a crash too. */\n readonly last: WorkerUnavailableError | undefined;\n /** Crash count the degrade warning was last emitted for, so one failure warns once. */\n readonly warnedFor: number;\n};\n\nconst NO_CRASHES: CrashHistory = { count: 0, last: undefined, warnedFor: -1 };\n\n/**\n * The key copied for the crossing plus the buffers to transfer, so the wire copy\n * is moved instead of cloned. Anything but the known binary shape crosses\n * unchanged.\n */\nfunction keyForTransfer(key: FhevmClientOptions[\"fheEncryptionKey\"]): {\n readonly key: FhevmClientOptions[\"fheEncryptionKey\"];\n readonly transfers: Transferable[];\n} {\n if (key === undefined) {\n return { key, transfers: [] };\n }\n const publicKeyBytes = key.publicKeyBytes.bytes;\n const crsBytes = key.crsBytes.bytes;\n if (!(publicKeyBytes instanceof Uint8Array) || !(crsBytes instanceof Uint8Array)) {\n return { key, transfers: [] };\n }\n // `slice` yields a fresh exactly-sized buffer, so transferring it leaves this\n // thread's cached key intact.\n const publicKeyCopy = publicKeyBytes.slice();\n const crsCopy = crsBytes.slice();\n return {\n key: {\n ...key,\n publicKeyBytes: { ...key.publicKeyBytes, bytes: publicKeyCopy },\n crsBytes: { ...key.crsBytes, bytes: crsCopy },\n },\n transfers: [publicKeyCopy.buffer as ArrayBuffer, crsCopy.buffer as ArrayBuffer],\n };\n}\n\n/**\n * Per-call options: `signal` is forwarded as an `abort` call, `onProgress` is\n * served from the worker's shared progress channel, and `never` keeps the\n * callback contravariantly compatible with each operation's own event type.\n */\ntype CallOptions = WireRequestOptions & {\n readonly signal?: AbortSignal;\n readonly onProgress?: (args: never) => void;\n};\n\n/**\n * Everything scoped to one spawned worker, created by the init that spawns it\n * and dropped whole by a teardown. A late event carrying its own generation can\n * therefore only settle that generation, never the worker running in its place.\n */\ntype WorkerGeneration = {\n /** Memoized bring-up for this worker; it dies with the generation, so the next call re-runs it. */\n initPromise: Promise<void> | undefined;\n worker: Worker | undefined;\n api: Remote<EncryptWorkerApi> | undefined;\n /** Never resolves; teardown rejects it, and every boundary crossing races it so all of them settle together. */\n readonly doomed: Promise<never>;\n /** Rejects `doomed` with the teardown's `WorkerUnavailableError`. */\n readonly doom: (error: WorkerUnavailableError) => void;\n};\n\nfunction createWorkerGeneration(): WorkerGeneration {\n let doom!: (error: WorkerUnavailableError) => void;\n const doomed = new Promise<never>((_resolve, reject) => {\n doom = reject;\n });\n // An idle teardown dooms a generation with no crossing racing it; this\n // handler keeps that from surfacing as an unhandled rejection.\n doomed.catch(() => {});\n return { initPromise: undefined, worker: undefined, api: undefined, doomed, doom };\n}\n\nexport type EncryptWorkerClientConfig = {\n readonly initPayload: Omit<WireInitPayload, \"rpcUrl\">;\n /** The chain's RPC endpoint: a URL crosses into the worker; a provider is proxied per request. */\n readonly network: EIP1193Provider | string;\n /** Fetches the FHE key on the calling thread, where the chain's auth applies; the worker realm never downloads it itself. */\n readonly prefetchKey: () => Promise<FhevmClientOptions[\"fheEncryptionKey\"]>;\n readonly createInlineClient: () => EncryptOffloadBackend;\n readonly logger: LoggerService;\n readonly timeouts: EncryptWorkerTimeouts;\n /** A string or `URL` is spawned with the SDK's worker options; a factory is called for the worker itself. */\n readonly workerSource?: string | URL | (() => Worker);\n /**\n * A pre-known reason offload cannot work in this session: init degrades with\n * it immediately, so strict rejects at call time rather than at config time.\n */\n readonly blockedReason?: string;\n /**\n * Strict offload (`offloadEncrypt: true`): never run encryption on the\n * calling thread. Every path that would degrade rejects with\n * {@link EncryptOffloadUnavailableError} instead.\n */\n readonly strict: boolean;\n};\n\n/**\n * Encrypt backend that runs `@fhevm/sdk` in a dedicated module worker so proof\n * generation never blocks the main thread. Only infrastructure failure degrades\n * to inline (or rejects under `strict`); worker-reported errors are rethrown,\n * since inline would fail the same way.\n */\nexport class EncryptWorkerClient implements EncryptOffloadBackend {\n readonly #config: EncryptWorkerClientConfig;\n /** Resources of the worker currently being brought up or served; undefined while none runs. */\n #generation: WorkerGeneration | undefined;\n /** True once the client runs inline for the rest of its life, with no further spawn attempts. */\n #pinnedInline = false;\n #crashes: CrashHistory = NO_CRASHES;\n /** Wire ids, allocated across generations so a late reply can never be read as a live operation. */\n #sequence = 0;\n /** Per-operation `onProgress`, keyed by wire id and routed over one channel registered at init: one channel per worker avoids minting a `MessageChannel` per call, whose local port and listener would linger until garbage collection after terminate. */\n readonly #progressListeners = new Map<number, (event: WireProgressEvent) => void>();\n /** Memoized inline backend. Kept, with its key copy, across a worker recovery so a later degrade skips the refetch. */\n #degradePromise: Promise<EncryptOffloadBackend> | undefined;\n /** Operations that must drain before a requested release terminates the worker. */\n #active = 0;\n #releaseRequested = false;\n\n constructor(config: EncryptWorkerClientConfig) {\n this.#config = config;\n }\n\n init = (): Promise<void> => {\n // A call landing mid-drain rides the worker being released rather than\n // canceling the release: the drain still completes, and the call after it\n // spawns a fresh worker.\n const generation = (this.#generation ??= createWorkerGeneration());\n if (generation.initPromise === undefined) {\n // Only a successful cycle is memoized: a failure a retry could clear must\n // not be replayed to every later call.\n const attempt: Promise<void> = this.#withActive(() => this.#initOnce(generation)).catch(\n (error: unknown) => {\n if (generation.initPromise === attempt) {\n generation.initPromise = undefined;\n }\n throw error;\n },\n );\n generation.initPromise = attempt;\n }\n return generation.initPromise;\n };\n\n encryptValue: EncryptOffloadBackend[\"encryptValue\"] = (parameters) =>\n this.#withActive(() =>\n this.#dispatch(\n (backend) => backend.encryptValue(parameters),\n // Spread, so a field upstream adds to the parameters still crosses; the\n // stripped `options` replaces the caller's, which carries `signal`.\n (api, id, options) => api.encryptValue(id, { ...parameters, options }),\n parameters.options,\n ),\n );\n\n encryptValues: EncryptOffloadBackend[\"encryptValues\"] = (parameters) =>\n this.#withActive(() =>\n this.#dispatch(\n (backend) => backend.encryptValues(parameters),\n (api, id, options) => api.encryptValues(id, { ...parameters, options }),\n parameters.options,\n ),\n );\n\n /**\n * Releases the worker without changing what callers observe: in-flight\n * operations (an init included) run to completion over the worker, and the\n * worker is terminated as soon as the last one settles, immediately if the\n * client is idle. The client is not spent: the release resets it whole, so a\n * later call re-fetches the key and spawns a fresh worker exactly like the\n * first one, even if the client had degraded to the calling thread. The drain\n * is not bounded: a worker wedged inside an operation is only terminated once\n * that operation settles.\n */\n dispose(): void {\n this.#releaseRequested = true;\n this.#releaseIfIdle();\n }\n\n /**\n * The one place that decides between the worker and the calling thread:\n * inline once pinned or while no worker is running; otherwise the worker,\n * falling back to inline on infrastructure failure while application errors\n * pass through.\n */\n async #dispatch<T>(\n invoke: (backend: EncryptOffloadBackend) => Promise<T>,\n overWorker: (\n api: Remote<EncryptWorkerApi>,\n id: number,\n options: WireRequestOptions,\n ) => Promise<T>,\n callOptions: CallOptions | undefined,\n ): Promise<T> {\n const { signal, onProgress, ...options } = callOptions ?? {};\n // The worker dequeues an abort only after the proof, so a dispatched call always runs whole.\n throwIfAborted(signal);\n await this.init();\n // A listener added after the abort never fires, so an abort during init needs this recheck.\n throwIfAborted(signal);\n const generation = this.#generation;\n const api = generation?.api;\n // An existing degrade attempt already carries the decision that created it,\n // and its inline backend caches the key, so reuse it rather than degrading again.\n if (this.#degradePromise !== undefined && (this.#pinnedInline || api === undefined)) {\n return invoke(await this.#degradePromise);\n }\n if (generation === undefined || api === undefined) {\n return invoke(\n await this.#degrade(\n generation,\n this.#crashes.last ?? new WorkerUnavailableError(\"Encrypt worker not running.\"),\n ),\n );\n }\n const id = this.#sequence++;\n const onAbort = () => void api.abort(id).catch(() => {});\n signal?.addEventListener(\"abort\", onAbort, { once: true });\n if (onProgress) {\n this.#progressListeners.set(id, onProgress as (event: WireProgressEvent) => void);\n }\n try {\n const result = await this.#overBoundary(generation, overWorker(api, id, options));\n // A worker operation that answered clears the crash history: two unrelated\n // crashes far apart must not add up to a permanent degrade.\n this.#crashes = NO_CRASHES;\n return result;\n } catch (error) {\n if (error instanceof WorkerUnavailableError) {\n return invoke(await this.#degrade(generation, error));\n }\n throw error;\n } finally {\n this.#progressListeners.delete(id);\n signal?.removeEventListener(\"abort\", onAbort);\n }\n }\n\n async #initOnce(generation: WorkerGeneration): Promise<void> {\n if (this.#pinnedInline) {\n // The degrade that pinned the client already initialized the backend every call now runs on.\n return;\n }\n const blockedReason = this.#config.blockedReason;\n if (blockedReason !== undefined) {\n // Handled before any resource is spent: non-strict callers never get here\n // (the relayer inlines directly), and strict throws out of the degrade.\n await this.#degrade(generation, new WorkerUnavailableError(blockedReason));\n return;\n }\n // Outside the degrade guard: a failed key fetch is an application/network\n // error, and the inline backend would refetch the same key from the same\n // relayer. It rejects out of init exactly as the inline arm's would.\n const fheEncryptionKey = await this.#config.prefetchKey();\n try {\n const api = await this.#spawn(generation);\n const network = this.#config.network;\n const rpcRequest =\n typeof network === \"string\"\n ? null\n : proxy(async (args: { method: string; params?: unknown }) => {\n try {\n return await network.request(args as Parameters<EIP1193Provider[\"request\"]>[0]);\n } catch (error) {\n // Comlink keeps only name/message/stack on a thrown error, which\n // would strip the provider's `code` (4001, -32005) the worker's\n // classifiers read; flatten it so those fields cross.\n throw toWireError(error);\n }\n });\n // A callback that throws would reject the Comlink proxy call back in the\n // worker realm, where nothing can report it, so it is contained here.\n const log = proxy((level: \"debug\" | \"warn\" | \"error\", message: string) => {\n try {\n this.#config.logger[level](message);\n } catch (error) {\n this.#warnCallbackThrew(\"logger\", error);\n }\n });\n const onProgress = proxy((id: number, event: WireProgressEvent) => {\n try {\n this.#progressListeners.get(id)?.(event);\n } catch (error) {\n this.#warnCallbackThrew(\"onProgress\", error);\n }\n });\n // The copy stays on this thread so a later degrade to inline reuses the\n // key instead of refetching; transferring the wire copy avoids a third\n // in-transit copy of it.\n const wireKey = keyForTransfer(fheEncryptionKey);\n await this.#overBoundary(\n generation,\n api.init(\n transfer(\n {\n ...this.#config.initPayload,\n clientOptions: {\n ...this.#config.initPayload.clientOptions,\n fheEncryptionKey: wireKey.key,\n },\n rpcUrl: typeof network === \"string\" ? network : undefined,\n },\n wireKey.transfers,\n ),\n rpcRequest,\n log,\n onProgress,\n ),\n { ms: this.#config.timeouts.init, operation: \"init\" },\n );\n generation.api = api;\n this.#crashes = { ...this.#crashes, last: undefined };\n } catch (error) {\n // Only \"the worker never answered or crashed\" is infrastructure. An error\n // the worker itself reported (a chain read, bad key material) would fail\n // the same way inline, so it reaches the caller unchanged.\n if (!(error instanceof WorkerUnavailableError)) {\n this.#teardown(generation, new WorkerUnavailableError(\"Encrypt worker init failed.\"));\n throw error;\n }\n await this.#degrade(generation, error);\n }\n }\n\n /** Reports a caller callback that threw; the reporting itself must not throw back into the worker. */\n #warnCallbackThrew(callback: string, error: unknown): void {\n const reason = error instanceof Error ? error.message : String(error);\n try {\n this.#config.logger.warn(`Encrypt offload ${callback} callback threw: ${reason}`);\n } catch {\n // A logger that throws on its own warning leaves nowhere left to report.\n }\n }\n\n /**\n * The count spans a whole public entry, its init included, so a release\n * requested mid-call cannot terminate the worker between the init and the\n * operation.\n */\n async #withActive<T>(work: () => Promise<T>): Promise<T> {\n this.#active++;\n try {\n return await work();\n } finally {\n this.#active--;\n this.#releaseIfIdle();\n }\n }\n\n #releaseIfIdle(): void {\n if (!this.#releaseRequested || this.#active > 0) {\n return;\n }\n this.#releaseRequested = false;\n this.#generation?.worker?.terminate();\n // A full reset, so a release is the recovery lever for a degraded client:\n // the next call re-fetches the key and spawns a fresh worker either way.\n this.#generation = undefined;\n this.#degradePromise = undefined;\n this.#pinnedInline = false;\n this.#crashes = NO_CRASHES;\n }\n\n #createWorker(): Worker {\n const source = this.#config.workerSource;\n if (source === undefined) {\n return createEncryptWorker();\n }\n if (typeof source === \"function\") {\n const worker = source();\n // A memoized factory would hand the client a worker it already terminated,\n // so the contract is one fresh Worker per call.\n if (handedOutWorkers.has(worker)) {\n this.#config.logger.warnAlways(\n \"The offloadWorker factory returned a worker it already handed out; each call must construct a fresh Worker.\",\n );\n }\n handedOutWorkers.add(worker);\n return worker;\n }\n return new Worker(source, { type: \"module\", name: \"zama-fhe-encrypt\" });\n }\n\n /** Resolves once the worker's module graph has loaded. */\n async #spawn(generation: WorkerGeneration): Promise<Remote<EncryptWorkerApi>> {\n let worker: Worker;\n try {\n worker = this.#createWorker();\n } catch (error) {\n // A blocked construction is infrastructure, so it must reach the\n // degrade path as such rather than as the raw thrown error.\n throw new WorkerUnavailableError(error instanceof Error ? error.message : String(error), {\n cause: error,\n });\n }\n generation.worker = worker;\n const api = await this.#raceReady(generation, worker);\n this.#armCrashHandler(generation, worker);\n return api;\n }\n\n /** Resolves with the Comlink API on the worker's ready message; rejects on the spawn deadline or a pre-ready error. */\n #raceReady(generation: WorkerGeneration, worker: Worker): Promise<Remote<EncryptWorkerApi>> {\n return new Promise<Remote<EncryptWorkerApi>>((resolve, reject) => {\n const settle = () => {\n clearTimeout(timer);\n worker.removeEventListener(\"message\", onReady);\n worker.removeEventListener(\"error\", onError);\n };\n const timer = setTimeout(() => {\n settle();\n reject(\n new WorkerUnavailableError(\n `Encrypt worker did not start within ${this.#config.timeouts.spawn}ms.`,\n ),\n );\n }, this.#config.timeouts.spawn);\n const onReady = (event: MessageEvent) => {\n if (event.data === WORKER_READY_MESSAGE) {\n settle();\n resolve(wrap<EncryptWorkerApi>(worker));\n }\n };\n const onError = (event: ErrorEvent) => {\n settle();\n const message = event.message || \"Encrypt worker error.\";\n // A worker that never came up is not worth respawning per call, so\n // this failure is not flagged as a crash.\n reject(new WorkerUnavailableError(message));\n this.#teardown(generation, new WorkerUnavailableError(message));\n };\n worker.addEventListener(\"message\", onReady);\n worker.addEventListener(\"error\", onError);\n });\n }\n\n /** Permanent crash detector, armed only after ready so a pre-ready failure never counts as a crash. */\n #armCrashHandler(generation: WorkerGeneration, worker: Worker): void {\n worker.addEventListener(\"error\", (event: ErrorEvent) => {\n // A generation already torn down cannot crash the client again: nothing\n // is waiting on it, and the worker running in its place is unaffected.\n if (this.#generation !== generation) {\n return;\n }\n // A ready worker died under us: the teardown drops the memoized init so\n // the next call spawns a fresh one, and the operations it took down\n // finish inline.\n const crash = new WorkerUnavailableError(event.message || \"Encrypt worker error.\", {\n crashed: true,\n });\n this.#crashes = { ...this.#crashes, count: this.#crashes.count + 1, last: crash };\n this.#teardown(generation, crash);\n });\n }\n\n /**\n * Awaits one promise crossing the worker boundary, racing the generation's\n * `doomed` promise so a teardown settles it with the teardown's\n * `WorkerUnavailableError`, which degrades it inline. Without a `deadline` it\n * settles whenever the worker answers; a `deadline` bounds a lifecycle step,\n * and missing it means the worker is presumed stuck, so the generation is\n * torn down whole.\n */\n async #overBoundary<T>(\n generation: WorkerGeneration,\n work: Promise<T>,\n deadline?: { readonly ms: number; readonly operation: string },\n ): Promise<T> {\n const timer =\n deadline === undefined\n ? undefined\n : setTimeout(() => {\n this.#teardown(\n generation,\n new WorkerUnavailableError(\n `Encrypt worker ${deadline.operation} timed out after ${deadline.ms}ms.`,\n ),\n );\n }, deadline.ms);\n try {\n return await Promise.race([\n work.catch((error: unknown) => {\n const failure = isWireError(error) ? fromWireError(error) : (error as Error);\n // A payload Comlink could not carry is infrastructure, so it degrades\n // instead of reaching the caller as the operation's own failure.\n throw isCloneFailure(failure)\n ? new WorkerUnavailableError(failure.message, { cause: failure })\n : failure;\n }),\n generation.doomed,\n ]);\n } finally {\n if (timer !== undefined) {\n clearTimeout(timer);\n }\n }\n }\n\n /**\n * Rejects and drops one generation whole: its worker, its memoized init, and\n * every crossing racing its `doomed` promise. The next call therefore re-runs\n * the cycle on a fresh generation, so a spurious teardown costs a respawn\n * rather than a permanent degrade.\n */\n #teardown(generation: WorkerGeneration | undefined, error: WorkerUnavailableError): void {\n if (generation === undefined) {\n return;\n }\n if (this.#generation === generation) {\n this.#generation = undefined;\n }\n generation.worker?.terminate();\n generation.worker = undefined;\n generation.api = undefined;\n generation.initPromise = undefined;\n generation.doom(error);\n }\n\n async #degrade(\n generation: WorkerGeneration | undefined,\n cause: unknown,\n ): Promise<EncryptOffloadBackend> {\n const reason = cause instanceof Error ? cause.message : String(cause);\n if (this.#config.strict) {\n this.#teardown(generation, new WorkerUnavailableError(\"Encrypt worker unavailable.\"));\n throw new EncryptOffloadUnavailableError(\n `Encrypt offload required (offloadEncrypt: true) but unavailable: ${reason}`,\n { cause },\n );\n }\n const { transient, pinning } = this.#classifyDegrade(cause);\n this.#pinnedInline ||= !transient;\n this.#teardown(generation, new WorkerUnavailableError(\"Encrypt worker degraded to inline.\"));\n this.#warnDegraded(reason, transient, pinning);\n if (this.#degradePromise === undefined) {\n // Only a live backend is memoized: an inline init is a key refetch, and a\n // transient failure there must not close the degrade path for the session.\n const attempt: Promise<EncryptOffloadBackend> = (async () => {\n const inline = this.#config.createInlineClient();\n await inline.init();\n return inline;\n })().catch((error: unknown) => {\n if (this.#degradePromise === attempt) {\n this.#degradePromise = undefined;\n }\n this.#config.logger.warnAlways(\n `Encrypt inline fallback failed to initialize: ${error instanceof Error ? error.message : String(error)}`,\n );\n throw error;\n });\n this.#degradePromise = attempt;\n }\n return this.#degradePromise;\n }\n\n /**\n * How one failure degrades, read off the state before the degrade mutates it:\n * `transient` diverts only this call, `pinning` settles the client inline now.\n * One crash is treated as transient; a repeat crash, or a worker that never\n * came up, settles the client inline rather than spawning a replacement per call.\n */\n #classifyDegrade(cause: unknown): { readonly transient: boolean; readonly pinning: boolean } {\n const transient =\n cause instanceof WorkerUnavailableError &&\n cause.crashed &&\n this.#crashes.count < CRASH_PIN_THRESHOLD;\n return { transient, pinning: !transient && !this.#pinnedInline };\n }\n\n /** One warning per failure, whether it pins the client inline or only diverts this call. */\n #warnDegraded(reason: string, transient: boolean, pinning: boolean): void {\n if (!pinning && this.#crashes.warnedFor === this.#crashes.count) {\n return;\n }\n this.#crashes = { ...this.#crashes, warnedFor: this.#crashes.count };\n const scope = transient ? \"in-flight encryption falls back\" : \"encryption falls back\";\n // Always on the console: a silent return to main-thread encryption is the\n // freeze this offload prevents.\n this.#config.logger.warnAlways(\n `${ENCRYPT_OFFLOAD_WARN_PREFIX}, ${scope} to the calling thread: ${reason}`,\n );\n }\n}\n","import {\n canUseUnifiedDecryptionPermit as canUseUnifiedDecryptionPermitAction,\n createUnsignedLegacyDecryptionPermitEip712 as createUnsignedLegacyDecryptionPermitEip712Action,\n createUnsignedUnifiedDecryptionPermitEip712 as createUnsignedUnifiedDecryptionPermitEip712Action,\n} from \"@fhevm/sdk/actions/base\";\nimport {\n createFhevmBaseClient,\n createFhevmDecryptClient,\n createFhevmEncryptClient,\n hasFhevmRuntimeConfig,\n} from \"@fhevm/sdk/viem\";\nimport {\n createFhevmCleartextBaseClient,\n createFhevmCleartextDecryptClient,\n createFhevmCleartextEncryptClient,\n} from \"@fhevm/sdk/viem/cleartext\";\nimport { createPublicClient, custom, http } from \"viem\";\nimport { toFhevmChain } from \"../chains/to-fhevm-chain\";\nimport type { FheChain } from \"../chains/types\";\nimport { ConfigurationError } from \"../errors\";\nimport { getAppliedWireRuntime, hasAppliedLocateFile } from \"./applied-runtime\";\nimport type { LoggerService } from \"../services/logger-service\";\nimport {\n DEFAULT_ENCRYPT_WORKER_TIMEOUTS,\n EncryptWorkerClient,\n type EncryptWorkerClientConfig,\n type EncryptWorkerTimeouts,\n} from \"../worker/encrypt-worker-client\";\nimport { BUNDLED_ENCRYPT_WORKER } from \"../worker/spawn\";\nimport type {\n FhevmBaseClient,\n FhevmClient,\n FhevmDecryptClient,\n FhevmEncryptBackend,\n FhevmRelayerOptions,\n RelayerSDK,\n RelayerOptions,\n WireRuntimeConfig,\n} from \"./types\";\n\n/** The `@fhevm/sdk` client inputs the worker realm rebuilds its own client from. */\ntype EncryptInitPayload = EncryptWorkerClientConfig[\"initPayload\"];\n\n/** Construction config for {@link FhevmRelayer}. */\nexport interface FhevmRelayerConfig {\n /** FHE chain configuration. */\n chain: FheChain;\n /**\n * Cleartext mode for local dev/test chains without FHE infrastructure — reads\n * mock cleartexts from the on-chain executor (discovered automatically)\n * instead of calling the relayer.\n */\n cleartext?: boolean;\n /**\n * Per-transport {@link RelayerOptions}: `@fhevm/sdk` client options plus a\n * default request `timeout` applied to every relayer round-trip on the chain.\n */\n options?: RelayerOptions;\n /** Encrypt-worker offload mode; see `web()`'s `offloadEncrypt` option. */\n offloadEncrypt?: \"auto\" | boolean;\n /** Watchdog deadlines for the encrypt worker; `web()` defaults every field before it gets here. */\n offloadTimeouts?: EncryptWorkerTimeouts;\n /** Custom source for the encrypt worker; see `web()`'s `offloadWorker` option. */\n offloadWorker?: string | URL | (() => Worker);\n /** Receives worker log lines and offload-fallback warnings. */\n logger: LoggerService;\n}\n\n/**\n * Single-chain FHE backend that drives `@fhevm/sdk` on the calling thread with\n * capability-scoped lazy initialization.\n * EIP-712 signing is done by the signer layer; this backend builds the typed\n * data and, on decrypt, reassembles the new SDK's signed permit from the\n * interface's params + the previously returned signature.\n *\n * @remarks\n * Each method delegates to the narrowest base, decrypt, or encrypt client,\n * adding two cross-cutting behaviors that the delegated signatures don't\n * express:\n *\n * - **Lazy init.** Each operation initializes only the capability it requires.\n * Public decrypt avoids WASM, private decrypt loads TKMS only, and encryption\n * alone loads TFHE and the FHE encryption key.\n * - **Option merging.** The chain's default options (`auth`, `timeout`, `debug`)\n * are spread in first, then the per-call `options`, so a per-call value always\n * wins over the chain default. Serialization helpers make no relayer\n * round-trip, so they inject no options.\n *\n * @internal\n */\nexport class FhevmRelayer implements RelayerSDK {\n readonly #chain: FheChain;\n readonly #base: FhevmBaseClient;\n readonly #decrypt: FhevmDecryptClient;\n readonly #encrypt: FhevmEncryptBackend;\n readonly #defaultOptions: Partial<FhevmRelayerOptions>;\n #encryptInitPromise: Promise<void> | undefined;\n\n /**\n * Builds capability-scoped `@fhevm/sdk` clients for the chain and captures\n * the chain's `auth`/`timeout`/`debug` as request defaults. Construction is\n * cheap; each client's one-time init is deferred to its first operation.\n */\n constructor(config: FhevmRelayerConfig) {\n this.#chain = config.chain;\n const { timeout, debug, batchRpcCalls, moduleVersions, fheEncryptionKey } =\n config.options ?? {};\n const auth = this.#chain.auth ? toFhevmAuth(this.#chain.auth) : undefined;\n const transport =\n typeof this.#chain.network === \"string\"\n ? http(this.#chain.network)\n : custom(this.#chain.network);\n const params = {\n publicClient: createPublicClient({ transport }),\n chain: toFhevmChain(this.#chain),\n options: { batchRpcCalls, moduleVersions, fheEncryptionKey },\n };\n this.#defaultOptions = {\n ...(auth !== undefined && { auth }),\n ...(timeout !== undefined && { timeout }),\n ...(debug !== undefined && { debug }),\n };\n // The FHE key is always fetched here, on the calling thread, so the chain's\n // default request options (auth in particular) apply; a worker realm has no\n // access to them.\n const prefetchKey = () =>\n this.#base.fetchFheEncryptionKeyBytes({ options: this.#defaultOptions });\n // Re-listed rather than spread: the upstream client exposes an enumerable\n // `ready` getter, and a spread would call it, starting init at construction.\n const withInlineInit = (client: FhevmEncryptBackend): FhevmEncryptBackend => ({\n init: async () => {\n await prefetchKey();\n await client.init();\n },\n encryptValue: (parameters) => client.encryptValue(parameters),\n encryptValues: (parameters) => client.encryptValues(parameters),\n fetchFheEncryptionKeyBytes: (parameters) => client.fetchFheEncryptionKeyBytes(parameters),\n });\n if (config.cleartext) {\n this.#base = createFhevmCleartextBaseClient(params);\n this.#decrypt = createFhevmCleartextDecryptClient(params);\n this.#encrypt = withInlineInit(createFhevmCleartextEncryptClient(params));\n } else {\n this.#base = createFhevmBaseClient(params);\n this.#decrypt = createFhevmDecryptClient(params);\n this.#encrypt = this.#buildEncryptBackend(config, params, {\n prefetchKey,\n createInlineClient: () => withInlineInit(createFhevmEncryptClient(params)),\n });\n }\n }\n\n /**\n * Picks the encrypt backend for a non-cleartext chain: the worker client when\n * offload is on and reachable, the inline calling-thread client otherwise.\n */\n #buildEncryptBackend(\n config: FhevmRelayerConfig,\n params: { chain: EncryptInitPayload[\"chain\"]; options: EncryptInitPayload[\"clientOptions\"] },\n inline: {\n prefetchKey: EncryptWorkerClientConfig[\"prefetchKey\"];\n createInlineClient: () => FhevmEncryptBackend;\n },\n ): FhevmEncryptBackend {\n const offload = config.offloadEncrypt ?? false;\n const strict = offload === true;\n const workerAvailable =\n typeof Worker === \"function\" &&\n (config.offloadWorker !== undefined || BUNDLED_ENCRYPT_WORKER);\n // Silent both ways: offload off is what the caller asked for, and a realm\n // with no Worker is an environment fact that would warn on every SSR\n // render. Strict skips the capability check, since construction runs during\n // that render and the failure must surface at call time instead.\n if (offload === false || !(strict || workerAvailable)) {\n return inline.createInlineClient();\n }\n const runtime = getAppliedWireRuntime();\n const blocker = encryptOffloadBlocker(runtime);\n if (blocker !== undefined && !strict) {\n // Always on the console: the alternative is an opaque rejection at\n // encrypt time, or WASM assets silently resolved from the default URLs.\n config.logger.warnAlways(`Encryption runs on the calling thread: ${blocker}.`);\n return inline.createInlineClient();\n }\n const workerClient = new EncryptWorkerClient({\n initPayload: { chain: params.chain, clientOptions: params.options, runtime: runtime ?? {} },\n network: this.#chain.network,\n prefetchKey: inline.prefetchKey,\n createInlineClient: inline.createInlineClient,\n logger: config.logger,\n timeouts: config.offloadTimeouts ?? DEFAULT_ENCRYPT_WORKER_TIMEOUTS,\n workerSource: config.offloadWorker,\n // Strict with a blocker: the client degrades at init, which rejects at\n // call time rather than at config time.\n blockedReason: blocker,\n strict,\n });\n return {\n init: () => workerClient.init(),\n encryptValue: (parameters) => workerClient.encryptValue(parameters),\n encryptValues: (parameters) => workerClient.encryptValues(parameters),\n // Served from the calling thread: routing it through the worker would\n // structured-clone the ~50 MB key back out on every call. `ignoreCache`\n // therefore refreshes this thread's cache, not the worker's seeded key.\n fetchFheEncryptionKeyBytes: (parameters) => this.#base.fetchFheEncryptionKeyBytes(parameters),\n dispose: () => workerClient.dispose(),\n };\n }\n\n /** The FHE chain this backend is bound to. */\n get chain() {\n return this.#chain;\n }\n\n // Only a fulfilled init is memoized: a rejection clears the memo so the next\n // encryption retries instead of inheriting a transient key-fetch failure.\n #initEncrypt = (): Promise<void> => {\n this.#encryptInitPromise ??= this.#encrypt.init().catch((error: unknown) => {\n this.#encryptInitPromise = undefined;\n throw error;\n });\n return this.#encryptInitPromise;\n };\n\n /**\n * Releases the encrypt worker once in-flight encryptions settle and drops the\n * memoized init; the next encryption spawns a fresh worker and re-initializes.\n */\n dispose = (): void => {\n this.#encryptInitPromise = undefined;\n this.#encrypt.dispose?.();\n };\n\n /**\n * Decrypts a single publicly-decryptable value — one whose contract granted\n * public access, so no permit or key pair is needed — into its typed clear\n * value.\n *\n * @example\n * ```ts\n * const { type, value } = await relayer.decryptPublicValue({\n * encryptedValue: handle, // a bytes32 ciphertext reference\n * });\n * ```\n */\n decryptPublicValue: FhevmClient[\"decryptPublicValue\"] = async (parameters) => {\n await this.#base.init();\n return this.#base.decryptPublicValue({\n ...parameters,\n options: { ...this.#defaultOptions, ...parameters.options },\n });\n };\n\n /**\n * Batch form of {@link decryptPublicValue}: decrypts many publicly-decryptable\n * values in one relayer round-trip, returning their typed clear values in\n * order.\n *\n * @example\n * ```ts\n * const values = await relayer.decryptPublicValues({\n * encryptedValues: [handleA, handleB],\n * });\n * ```\n */\n decryptPublicValues: FhevmClient[\"decryptPublicValues\"] = async (parameters) => {\n await this.#base.init();\n return this.#base.decryptPublicValues({\n ...parameters,\n options: { ...this.#defaultOptions, ...parameters.options },\n });\n };\n\n /**\n * Like {@link decryptPublicValues}, but also returns the KMS signature bundle —\n * the handles list, ABI-encoded cleartexts, and decryption proof — needed to\n * verify or replay the result on-chain.\n *\n * @example\n * ```ts\n * const { clearValues, checkSignaturesArgs } =\n * await relayer.decryptPublicValuesWithSignatures({ encryptedValues: [handle] });\n * // checkSignaturesArgs: { handlesList, abiEncodedCleartexts, decryptionProof }\n * ```\n */\n decryptPublicValuesWithSignatures: FhevmClient[\"decryptPublicValuesWithSignatures\"] = async (\n parameters,\n ) => {\n await this.#base.init();\n return this.#base.decryptPublicValuesWithSignatures({\n ...parameters,\n options: { ...this.#defaultOptions, ...parameters.options },\n });\n };\n\n /**\n * Encrypts one typed input under the chain's FHE key, bound to the contract it\n * targets and the user submitting it, and returns the ciphertext handle plus\n * the input proof the contract verifies on-chain. `type` is the FHE type\n * with the `e` prefix (`\"euint64\"`, `\"ebool\"`, `\"eaddress\"`).\n *\n * @example\n * ```ts\n * const { encryptedValue, inputProof } = await relayer.encryptValue({\n * value: { type: \"euint64\", value: 1000n },\n * contractAddress: \"0xToken…\",\n * userAddress: \"0xUser…\",\n * });\n * ```\n */\n encryptValue: FhevmClient[\"encryptValue\"] = async (parameters) => {\n await this.#initEncrypt();\n return this.#encrypt.encryptValue({\n ...parameters,\n options: { ...this.#defaultOptions, ...parameters.options },\n });\n };\n\n /**\n * Batch form of {@link encryptValue}: encrypts several inputs for the same\n * contract and user in one call, returning all ciphertext handles under a\n * single shared input proof.\n *\n * @example\n * ```ts\n * const { encryptedValues, inputProof } = await relayer.encryptValues({\n * values: [\n * { type: \"euint64\", value: 1000n },\n * { type: \"ebool\", value: true },\n * ],\n * contractAddress: \"0xToken…\",\n * userAddress: \"0xUser…\",\n * });\n * ```\n */\n encryptValues: FhevmClient[\"encryptValues\"] = async (parameters) => {\n await this.#initEncrypt();\n return this.#encrypt.encryptValues({\n ...parameters,\n options: { ...this.#defaultOptions, ...parameters.options },\n });\n };\n\n /**\n * User-decrypts a single access-controlled value: the relayer re-encrypts it\n * to the ephemeral transport key pair, gated by the signed permit, and this\n * returns the typed clear value. Build the key pair with\n * {@link generateTransportKeyPair} and the permit with\n * {@link signDecryptionPermit}.\n *\n * @example\n * ```ts\n * const { type, value } = await relayer.decryptValue({\n * encryptedValue: handle,\n * contractAddress: \"0xToken…\",\n * transportKeyPair,\n * signedPermit,\n * });\n * ```\n */\n decryptValue: FhevmClient[\"decryptValue\"] = async (parameters) => {\n await this.#decrypt.init();\n return this.#decrypt.decryptValue({\n ...parameters,\n options: { ...this.#defaultOptions, ...parameters.options },\n });\n };\n\n /**\n * Batch form of {@link decryptValue} for values that all belong to the same\n * contract; returns the typed clear values positionally. For values spanning\n * multiple contracts, use {@link decryptValuesFromPairs}.\n *\n * @example\n * ```ts\n * const values = await relayer.decryptValues({\n * encryptedValues: [handleA, handleB],\n * contractAddress: \"0xToken…\",\n * transportKeyPair,\n * signedPermit,\n * });\n * ```\n */\n decryptValues: FhevmClient[\"decryptValues\"] = async (parameters) => {\n await this.#decrypt.init();\n return this.#decrypt.decryptValues({\n ...parameters,\n options: { ...this.#defaultOptions, ...parameters.options },\n });\n };\n\n /**\n * User-decrypts values that span multiple contracts: each pair carries its own\n * `contractAddress`, so one permit covering those contracts decrypts them all\n * in a single round-trip. Returns the typed clear values positionally.\n *\n * @example\n * ```ts\n * const values = await relayer.decryptValuesFromPairs({\n * pairs: [\n * { encryptedValue: handleA, contractAddress: \"0xTokenA…\" },\n * { encryptedValue: handleB, contractAddress: \"0xTokenB…\" },\n * ],\n * transportKeyPair,\n * signedPermit,\n * });\n * ```\n */\n decryptValuesFromPairs: FhevmClient[\"decryptValuesFromPairs\"] = async (parameters) => {\n await this.#decrypt.init();\n return this.#decrypt.decryptValuesFromPairs({\n ...parameters,\n options: { ...this.#defaultOptions, ...parameters.options },\n });\n };\n\n /**\n * Fetches the chain's raw FHE public-key bytes — the key encryption uses —\n * served from cache unless `ignoreCache` forces a refetch. Rarely called\n * directly: {@link encryptValue}/{@link encryptValues} fetch the key for you.\n *\n * @example\n * ```ts\n * const keyBytes = await relayer.fetchFheEncryptionKeyBytes();\n * const fresh = await relayer.fetchFheEncryptionKeyBytes({ ignoreCache: true });\n * ```\n */\n fetchFheEncryptionKeyBytes: FhevmClient[\"fetchFheEncryptionKeyBytes\"] = async (parameters) => {\n // Served from the base client, which shares the key cache with the encrypt\n // client: initializing encryption here would spawn the encrypt worker and\n // wait out its bring-up for a key this thread fetches itself.\n await this.#base.init();\n return this.#base.fetchFheEncryptionKeyBytes({\n ...parameters,\n options: { ...this.#defaultOptions, ...parameters?.options },\n });\n };\n\n /**\n * Builds the EIP-712 user-decrypt permit and signs it with the given signer,\n * authorizing the transport key pair to decrypt the listed contracts' values\n * for `durationSeconds` starting at `startTimestamp`. Pass `delegatorAddress`\n * to sign a delegated permit — decrypting values owned by that account instead\n * of the signer's own. Persist the result via\n * {@link serializeSignedDecryptionPermit}.\n *\n * @example\n * ```ts\n * const signedPermit = await relayer.signDecryptionPermit({\n * transportKeyPair,\n * contractAddresses: [\"0xToken…\"],\n * startTimestamp: Math.floor(Date.now() / 1000),\n * durationSeconds: 60 * 60 * 24,\n * signerAddress: \"0xUser…\",\n * signer,\n * // delegatorAddress: \"0xOwner…\", // omit for a self permit\n * });\n * ```\n */\n signDecryptionPermit: FhevmClient[\"signDecryptionPermit\"] = async (parameters) => {\n await this.#base.init();\n return this.#base.signDecryptionPermit(parameters);\n };\n\n /**\n * Builds the unified (V2) EIP-712 user-decrypt permit and signs it, authorizing\n * the transport key pair to decrypt the listed contracts' values — or, when\n * `contractAddresses` is empty, every contract (a wildcard/permissive permit) —\n * for `durationSeconds` starting at `startTimestamp`. Pass `delegatorAddress` to\n * sign a delegated permit. Requires a chain on protocol v0.14+; throws otherwise.\n *\n * @example\n * ```ts\n * const signedPermit = await relayer.signUnifiedDecryptionPermit({\n * transportKeyPair,\n * contractAddresses: [], // wildcard: covers every contract\n * startTimestamp: Math.floor(Date.now() / 1000),\n * durationSeconds: 60 * 60 * 24,\n * signerAddress: \"0xUser…\",\n * signer,\n * });\n * ```\n */\n signUnifiedDecryptionPermit: FhevmClient[\"signUnifiedDecryptionPermit\"] = async (parameters) => {\n await this.#base.init();\n return this.#base.signUnifiedDecryptionPermit(parameters);\n };\n\n /**\n * Builds the unsigned EIP-712 typed data for a V1 decryption permit, without\n * signing it — the signer-less counterpart to {@link signDecryptionPermit}.\n * Hand the result to an out-of-process signer for `eth_signTypedData_v4`,\n * then verify the returned signature via {@link parseSignedDecryptionPermit}.\n *\n * Not on `@fhevm/sdk`'s client decorator, so it's called directly against\n * the base client rather than through a decorated method.\n *\n * @example\n * ```ts\n * const eip712 = await relayer.createUnsignedLegacyDecryptionPermitEip712({\n * transportKeyPair,\n * contractAddresses: [\"0xToken…\"],\n * startTimestamp: Math.floor(Date.now() / 1000),\n * durationSeconds: 60 * 60 * 24,\n * // delegatorAddress: \"0xOwner…\", // omit for a self permit\n * });\n * ```\n */\n createUnsignedLegacyDecryptionPermitEip712: RelayerSDK[\"createUnsignedLegacyDecryptionPermitEip712\"] =\n (parameters) => createUnsignedLegacyDecryptionPermitEip712Action(this.#base, parameters);\n\n /**\n * Builds the unsigned EIP-712 typed data for a V2 (unified) decryption\n * permit, without signing it — the signer-less counterpart to\n * {@link signUnifiedDecryptionPermit}. Hand the result to an out-of-process\n * signer for `eth_signTypedData_v4`, then verify the returned signature via\n * {@link parseSignedDecryptionPermit}.\n *\n * Not on `@fhevm/sdk`'s client decorator, so it's called directly against\n * the base client rather than through a decorated method.\n *\n * @example\n * ```ts\n * const eip712 = await relayer.createUnsignedUnifiedDecryptionPermitEip712({\n * transportKeyPair,\n * contractAddresses: [\"0xToken…\"], // [] for a wildcard permit\n * startTimestamp: Math.floor(Date.now() / 1000),\n * durationSeconds: 60 * 60 * 24,\n * signerAddress: \"0xSigner…\",\n * });\n * ```\n */\n createUnsignedUnifiedDecryptionPermitEip712: RelayerSDK[\"createUnsignedUnifiedDecryptionPermitEip712\"] =\n (parameters) => createUnsignedUnifiedDecryptionPermitEip712Action(this.#base, parameters);\n\n /**\n * Reports whether the connected relayer supports V2 (unified) decryption\n * permits — used to decide whether a newly-issued permit should be V1 or V2.\n *\n * @example\n * ```ts\n * const supportsV2 = await relayer.canUseUnifiedDecryptionPermit();\n * ```\n */\n canUseUnifiedDecryptionPermit: RelayerSDK[\"canUseUnifiedDecryptionPermit\"] = (parameters) =>\n canUseUnifiedDecryptionPermitAction(this.#base, {\n options: { ...this.#defaultOptions, ...parameters?.options },\n });\n\n // Permit/key-pair helpers carry no request options. Parsing explicitly\n // initializes the capability that validates the restored value; serialization\n // resolves the frozen context internally (via initPublicAction), which reads\n // on-chain state.\n\n /**\n * Serializes a transport key pair to a hex `{ publicKey, privateKey }` pair for\n * storage or transport, so a decryption session can resume without regenerating\n * keys. Reverse of {@link parseTransportKeyPair}.\n *\n * @example\n * ```ts\n * const stored = await relayer.serializeTransportKeyPair({ transportKeyPair });\n * // { publicKey: \"0x…\", privateKey: \"0x…\" }\n * ```\n */\n serializeTransportKeyPair: FhevmClient[\"serializeTransportKeyPair\"] = (parameters) =>\n this.#decrypt.serializeTransportKeyPair(parameters);\n\n /**\n * Serializes a signed permit to a plain, JSON-stringifiable object (version,\n * EIP-712 payload, signature, signer) for caching or transport. Reverse of\n * {@link parseSignedDecryptionPermit}.\n *\n * @example\n * ```ts\n * const serialized = await relayer.serializeSignedDecryptionPermit({ signedPermit });\n * localStorage.setItem(\"permit\", JSON.stringify(serialized));\n * ```\n */\n serializeSignedDecryptionPermit: FhevmClient[\"serializeSignedDecryptionPermit\"] = (parameters) =>\n this.#base.serializeSignedDecryptionPermit(parameters);\n\n /**\n * Rebuilds a transport key pair from its serialized hex\n * `{ publicKey, privateKey }` form. Reverse of {@link serializeTransportKeyPair}.\n *\n * @example\n * ```ts\n * const transportKeyPair = await relayer.parseTransportKeyPair({\n * publicKey: stored.publicKey,\n * privateKey: stored.privateKey,\n * });\n * ```\n */\n parseTransportKeyPair: FhevmClient[\"parseTransportKeyPair\"] = async (parameters) => {\n await this.#decrypt.init();\n return this.#decrypt.parseTransportKeyPair(parameters);\n };\n\n /**\n * Rebuilds a signed permit from its serialized form and validates it: checks\n * the EIP-712 structure, verifies the signature against the on-chain verifier,\n * and confirms the permit's public key matches `transportKeyPair`. Reverse of\n * {@link serializeSignedDecryptionPermit}.\n *\n * @throws if the permit is malformed, expired, or its signature is invalid.\n *\n * @example\n * ```ts\n * const signedPermit = await relayer.parseSignedDecryptionPermit({\n * serializedPermit,\n * transportKeyPair,\n * });\n * ```\n */\n parseSignedDecryptionPermit: FhevmClient[\"parseSignedDecryptionPermit\"] = async (parameters) => {\n await this.#base.init();\n return this.#base.parseSignedDecryptionPermit(parameters);\n };\n\n /**\n * Generates a fresh ephemeral transport key pair for a user-decrypt session.\n * The relayer re-encrypts decrypted values to this pair's public key, so only\n * the holder of the private key can read them; bind it to a permit via\n * {@link signDecryptionPermit}.\n *\n * @example\n * ```ts\n * const transportKeyPair = await relayer.generateTransportKeyPair();\n * ```\n */\n generateTransportKeyPair: FhevmClient[\"generateTransportKeyPair\"] = async () => {\n await this.#decrypt.init();\n return this.#decrypt.generateTransportKeyPair();\n };\n}\n\n/**\n * The one reason, if any, this thread's configuration cannot be reproduced in\n * the worker realm, so offload is worse than inline there.\n */\nfunction encryptOffloadBlocker(runtime: WireRuntimeConfig | undefined): string | undefined {\n // A runtime `locateFile` is a function: it cannot be cloned into the worker\n // realm, which would silently resolve WASM assets from the default URLs.\n if (hasAppliedLocateFile()) {\n return \"a runtime locateFile cannot cross the encrypt worker boundary\";\n }\n // Unreadable here, so the worker would run on fhevm defaults: an auth it\n // carries would 401 inside the worker as an application error, which never degrades.\n if (runtime === undefined && hasFhevmRuntimeConfig()) {\n return \"a runtime config set outside createConfig cannot be replicated in the encrypt worker realm\";\n }\n return undefined;\n}\n\n/**\n * Translates the SDK's public {@link FheChain.auth} shape (discriminated by\n * `__type`) into the `type`-discriminated `auth` that `@fhevm/sdk` expects.\n *\n * @throws if the auth discriminator is not one of the supported kinds.\n */\nfunction toFhevmAuth(\n auth: NonNullable<FheChain[\"auth\"]>,\n): NonNullable<FhevmRelayerOptions[\"auth\"]> {\n const type = auth[\"__type\"];\n switch (type) {\n case \"ApiKeyHeader\":\n return { type, value: auth.value, header: auth.header };\n case \"ApiKeyCookie\":\n return { type, value: auth.value, cookie: auth.cookie };\n case \"BearerToken\":\n return { type, token: auth.token };\n default:\n throw new ConfigurationError(`Unknown auth type: ${String(type)}`);\n }\n}\n"],"x_google_ignoreList":[1],"mappings":"6qBAYA,SAAgB,EAAa,EAA6B,CACxD,MAAO,CACL,GAAI,EAAM,GACV,MAAO,CACL,UAAW,CACT,IAAK,CAAE,QAAS,EAAM,kBAAmB,EACzC,cAAe,CAAE,QAAS,EAAM,4BAA6B,EAC7D,YAAa,CAAE,QAAS,EAAM,kBAAmB,EACjD,eAAgB,EAAM,8BAClB,CAAE,QAAS,EAAM,6BAA8B,EAC/C,IAAA,EACN,EACA,WAAY,EAAM,WAClB,QAAS,CACP,GAAI,EAAM,eACV,UAAW,CACT,WAAY,CAAE,QAAS,EAAM,kCAAmC,EAChE,kBAAmB,CAAE,QAAS,EAAM,yCAA0C,CAChF,CACF,CACF,CACF,CACF;;;;;;AC7BA,MAAM,EAAc,OAAO,eAAe,EACpC,EAAiB,OAAO,kBAAkB,EAC1C,EAAe,OAAO,sBAAsB,EAC5C,EAAY,OAAO,mBAAmB,EACtC,EAAc,OAAO,gBAAgB,EACrC,EAAY,GAAS,OAAO,GAAQ,YAAY,GAAiB,OAAO,GAAQ,WAgDhF,EAAmB,IAAI,IAAI,CAC7B,CAAC,QAAS,CA5CV,UAAY,GAAQ,EAAS,CAAG,GAAK,EAAI,GACzC,UAAU,EAAK,CACX,GAAM,CAAE,QAAO,SAAU,IAAI,eAE7B,OADA,EAAO,EAAK,CAAK,EACV,CAAC,EAAO,CAAC,CAAK,CAAC,CAC1B,EACA,YAAY,EAAM,CAEd,OADA,EAAK,MAAM,EACJ,EAAK,CAAI,CACpB,CAmC6B,CAAC,EAC9B,CAAC,QAAS,CA9BV,UAAY,GAAU,EAAS,CAAK,GAAK,KAAe,EACxD,UAAU,CAAE,SAAS,CACjB,IAAI,EAcJ,MAbA,CAWI,EAXA,aAAiB,MACJ,CACT,QAAS,GACT,MAAO,CACH,QAAS,EAAM,QACf,KAAM,EAAM,KACZ,MAAO,EAAM,KACjB,CACJ,EAGa,CAAE,QAAS,GAAO,OAAM,EAElC,CAAC,EAAY,CAAC,CAAC,CAC1B,EACA,YAAY,EAAY,CAIpB,MAHI,EAAW,QACL,OAAO,OAAW,MAAM,EAAW,MAAM,OAAO,EAAG,EAAW,KAAK,EAEvE,EAAW,KACrB,CAO6B,CAAC,CAClC,CAAC,EACD,SAAS,GAAgB,EAAgB,EAAQ,CAC7C,IAAK,IAAM,KAAiB,EAIxB,GAHI,IAAW,GAAiB,IAAkB,KAG9C,aAAyB,QAAU,EAAc,KAAK,CAAM,EAC5D,MAAO,GAGf,MAAO,EACX,CACA,SAAS,EAAO,EAAK,EAAK,WAAY,EAAiB,CAAC,GAAG,EAAG,CAC1D,EAAG,iBAAiB,UAAW,SAAS,EAAS,EAAI,CACjD,GAAI,CAAC,GAAM,CAAC,EAAG,KACX,OAEJ,GAAI,CAAC,GAAgB,EAAgB,EAAG,MAAM,EAAG,CAC7C,QAAQ,KAAK,mBAAmB,EAAG,OAAO,oBAAoB,EAC9D,MACJ,CACA,GAAM,CAAE,KAAI,OAAM,QAAS,OAAO,OAAO,CAAE,KAAM,CAAC,CAAE,EAAG,EAAG,IAAI,EACxD,GAAgB,EAAG,KAAK,cAAgB,CAAC,EAAA,CAAG,IAAI,CAAa,EAC/D,EACJ,GAAI,CACA,IAAM,EAAS,EAAK,MAAM,EAAG,EAAE,CAAC,CAAC,QAAQ,EAAK,IAAS,EAAI,GAAO,CAAG,EAC/D,EAAW,EAAK,QAAQ,EAAK,IAAS,EAAI,GAAO,CAAG,EAC1D,OAAQ,EAAR,CACI,IAAK,MAEG,EAAc,EAElB,MACJ,IAAK,MAEG,EAAO,EAAK,MAAM,EAAE,CAAC,CAAC,IAAM,EAAc,EAAG,KAAK,KAAK,EACvD,EAAc,GAElB,MACJ,IAAK,QAEG,EAAc,EAAS,MAAM,EAAQ,CAAY,EAErD,MACJ,IAAK,YAGG,EAAc,EAAM,IADF,EAAS,GAAG,CACN,CAAC,EAE7B,MACJ,IAAK,WACD,CACI,GAAM,CAAE,QAAO,SAAU,IAAI,eAC7B,EAAO,EAAK,CAAK,EACjB,EAAc,EAAS,EAAO,CAAC,CAAK,CAAC,CACzC,CACA,MACJ,IAAK,UAEG,EAAc,IAAA,GAElB,MACJ,QACI,MACR,CACJ,OACO,EAAO,CACV,EAAc,CAAE,SAAQ,GAAc,CAAE,CAC5C,CACA,QAAQ,QAAQ,CAAW,CAAC,CACvB,MAAO,IACD,CAAE,SAAQ,GAAc,CAAE,EACpC,CAAC,CACG,KAAM,GAAgB,CACvB,GAAM,CAAC,EAAW,GAAiB,EAAY,CAAW,EAC1D,EAAG,YAAY,OAAO,OAAO,OAAO,OAAO,CAAC,EAAG,CAAS,EAAG,CAAE,IAAG,CAAC,EAAG,CAAa,EAC7E,IAAS,YAET,EAAG,oBAAoB,UAAW,CAAQ,EAC1C,EAAc,CAAE,EACZ,KAAa,GAAO,OAAO,EAAI,IAAe,YAC9C,EAAI,EAAU,CAAC,EAG3B,CAAC,CAAC,CACG,MAAO,GAAU,CAElB,GAAM,CAAC,EAAW,GAAiB,EAAY,CAC3C,MAAW,UAAU,6BAA6B,GACjD,GAAc,CACnB,CAAC,EACD,EAAG,YAAY,OAAO,OAAO,OAAO,OAAO,CAAC,EAAG,CAAS,EAAG,CAAE,IAAG,CAAC,EAAG,CAAa,CACrF,CAAC,CACL,CAAC,EACG,EAAG,OACH,EAAG,MAAM,CAEjB,CACA,SAAS,GAAc,EAAU,CAC7B,OAAO,EAAS,YAAY,OAAS,aACzC,CACA,SAAS,EAAc,EAAU,CACzB,GAAc,CAAQ,GACtB,EAAS,MAAM,CACvB,CACA,SAAS,EAAK,EAAI,EAAQ,CACtB,IAAM,EAAmB,IAAI,IAiB7B,OAhBA,EAAG,iBAAiB,UAAW,SAAuB,EAAI,CACtD,GAAM,CAAE,QAAS,EACjB,GAAI,CAAC,GAAQ,CAAC,EAAK,GACf,OAEJ,IAAM,EAAW,EAAiB,IAAI,EAAK,EAAE,EACxC,KAGL,GAAI,CACA,EAAS,CAAI,CACjB,QACQ,CACJ,EAAiB,OAAO,EAAK,EAAE,CACnC,CACJ,CAAC,EACM,EAAY,EAAI,EAAkB,CAAC,EAAG,CAAM,CACvD,CACA,SAAS,EAAqB,EAAY,CACtC,GAAI,EACA,MAAU,MAAM,4CAA4C,CAEpE,CACA,SAAS,EAAgB,EAAI,CACzB,OAAO,EAAuB,EAAI,IAAI,IAAO,CACzC,KAAM,SACV,CAAC,CAAC,CAAC,SAAW,CACV,EAAc,CAAE,CACpB,CAAC,CACL,CACA,MAAM,EAAe,IAAI,QACnB,EAAkB,yBAA0B,YAC9C,IAAI,qBAAsB,GAAO,CAC7B,IAAM,GAAY,EAAa,IAAI,CAAE,GAAK,GAAK,EAC/C,EAAa,IAAI,EAAI,CAAQ,EACzB,IAAa,GACb,EAAgB,CAAE,CAE1B,CAAC,EACL,SAAS,GAAc,EAAO,EAAI,CAC9B,IAAM,GAAY,EAAa,IAAI,CAAE,GAAK,GAAK,EAC/C,EAAa,IAAI,EAAI,CAAQ,EACzB,GACA,EAAgB,SAAS,EAAO,EAAI,CAAK,CAEjD,CACA,SAAS,GAAgB,EAAO,CACxB,GACA,EAAgB,WAAW,CAAK,CAExC,CACA,SAAS,EAAY,EAAI,EAAkB,EAAO,CAAC,EAAG,EAAS,UAAY,CAAE,EAAG,CAC5E,IAAI,EAAkB,GAChB,EAAQ,IAAI,MAAM,EAAQ,CAC5B,IAAI,EAAS,EAAM,CAEf,GADA,EAAqB,CAAe,EAChC,IAAS,EACT,UAAa,CACT,GAAgB,CAAK,EACrB,EAAgB,CAAE,EAClB,EAAiB,MAAM,EACvB,EAAkB,EACtB,EAEJ,GAAI,IAAS,OAAQ,CACjB,GAAI,EAAK,SAAW,EAChB,MAAO,CAAE,SAAY,CAAM,EAE/B,IAAM,EAAI,EAAuB,EAAI,EAAkB,CACnD,KAAM,MACN,KAAM,EAAK,IAAK,GAAM,EAAE,SAAS,CAAC,CACtC,CAAC,CAAC,CAAC,KAAK,CAAa,EACrB,OAAO,EAAE,KAAK,KAAK,CAAC,CACxB,CACA,OAAO,EAAY,EAAI,EAAkB,CAAC,GAAG,EAAM,CAAI,CAAC,CAC5D,EACA,IAAI,EAAS,EAAM,EAAU,CACzB,EAAqB,CAAe,EAGpC,GAAM,CAAC,EAAO,GAAiB,EAAY,CAAQ,EACnD,OAAO,EAAuB,EAAI,EAAkB,CAChD,KAAM,MACN,KAAM,CAAC,GAAG,EAAM,CAAI,CAAC,CAAC,IAAK,GAAM,EAAE,SAAS,CAAC,EAC7C,OACJ,EAAG,CAAa,CAAC,CAAC,KAAK,CAAa,CACxC,EACA,MAAM,EAAS,EAAU,EAAiB,CACtC,EAAqB,CAAe,EACpC,IAAM,EAAO,EAAK,EAAK,OAAS,GAChC,GAAI,IAAS,EACT,OAAO,EAAuB,EAAI,EAAkB,CAChD,KAAM,UACV,CAAC,CAAC,CAAC,KAAK,CAAa,EAGzB,GAAI,IAAS,OACT,OAAO,EAAY,EAAI,EAAkB,EAAK,MAAM,EAAG,EAAE,CAAC,EAE9D,GAAM,CAAC,EAAc,GAAiB,EAAiB,CAAe,EACtE,OAAO,EAAuB,EAAI,EAAkB,CAChD,KAAM,QACN,KAAM,EAAK,IAAK,GAAM,EAAE,SAAS,CAAC,EAClC,cACJ,EAAG,CAAa,CAAC,CAAC,KAAK,CAAa,CACxC,EACA,UAAU,EAAS,EAAiB,CAChC,EAAqB,CAAe,EACpC,GAAM,CAAC,EAAc,GAAiB,EAAiB,CAAe,EACtE,OAAO,EAAuB,EAAI,EAAkB,CAChD,KAAM,YACN,KAAM,EAAK,IAAK,GAAM,EAAE,SAAS,CAAC,EAClC,cACJ,EAAG,CAAa,CAAC,CAAC,KAAK,CAAa,CACxC,CACJ,CAAC,EAED,OADA,GAAc,EAAO,CAAE,EAChB,CACX,CACA,SAAS,GAAO,EAAK,CACjB,OAAO,MAAM,UAAU,OAAO,MAAM,CAAC,EAAG,CAAG,CAC/C,CACA,SAAS,EAAiB,EAAc,CACpC,IAAM,EAAY,EAAa,IAAI,CAAW,EAC9C,MAAO,CAAC,EAAU,IAAK,GAAM,EAAE,EAAE,EAAG,GAAO,EAAU,IAAK,GAAM,EAAE,EAAE,CAAC,CAAC,CAC1E,CACA,MAAM,EAAgB,IAAI,QAC1B,SAAS,EAAS,EAAK,EAAW,CAE9B,OADA,EAAc,IAAI,EAAK,CAAS,EACzB,CACX,CACA,SAAS,EAAM,EAAK,CAChB,OAAO,OAAO,OAAO,EAAK,EAAG,GAAc,EAAK,CAAC,CACrD,CAQA,SAAS,EAAY,EAAO,CACxB,IAAK,GAAM,CAAC,EAAM,KAAY,EAC1B,GAAI,EAAQ,UAAU,CAAK,EAAG,CAC1B,GAAM,CAAC,EAAiB,GAAiB,EAAQ,UAAU,CAAK,EAChE,MAAO,CACH,CACI,KAAM,UACN,OACA,MAAO,CACX,EACA,CACJ,CACJ,CAEJ,MAAO,CACH,CACI,KAAM,MACN,OACJ,EACA,EAAc,IAAI,CAAK,GAAK,CAAC,CACjC,CACJ,CACA,SAAS,EAAc,EAAO,CAC1B,OAAQ,EAAM,KAAd,CACI,IAAK,UACD,OAAO,EAAiB,IAAI,EAAM,IAAI,CAAC,CAAC,YAAY,EAAM,KAAK,EACnE,IAAK,MACD,OAAO,EAAM,KACrB,CACJ,CACA,SAAS,EAAuB,EAAI,EAAkB,EAAK,EAAW,CAClE,OAAO,IAAI,QAAS,GAAY,CAC5B,IAAM,EAAK,EAAa,EACxB,EAAiB,IAAI,EAAI,CAAO,EAC5B,EAAG,OACH,EAAG,MAAM,EAEb,EAAG,YAAY,OAAO,OAAO,CAAE,IAAG,EAAG,CAAG,EAAG,CAAS,CACxD,CAAC,CACL,CACA,SAAS,GAAe,CACpB,MAAO,KAAW,CAAC,CACd,KAAK,CAAC,CAAC,CACP,QAAU,KAAK,MAAM,KAAK,OAAO,WAA2B,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAC3E,KAAK,GAAG,CACjB,CCnPA,SAAgB,EAAY,EAAoC,CAG9D,OACE,OAAO,GAAU,YACjB,GACC,EAAkC,YAAc,EAErD,CAOA,MAAM,EAAmB,CACvB,aACA,SACA,aACA,YACA,kBACA,OACA,OACA,eACA,UACA,QACA,MACF,EAKA,SAAS,EAAY,EAAyB,CAC5C,GAAI,CAEF,OADA,gBAAgB,CAAK,EACd,EACT,MAAQ,CACN,MAAO,EACT,CACF,CAMA,SAAS,EAAuB,EAAmC,CACjE,IAAM,EAAY,EAA+C,SACjE,OAAO,EAAqB,GAAU,OAAO,CAC/C,CAMA,SAAS,EAAkB,EAAwB,CACjD,GAAI,CACF,OAAO,KAAK,UAAU,CAAK,GAAK,OAAO,CAAK,CAC9C,MAAQ,CACN,OAAO,OAAO,CAAK,CACrB,CACF,CAGA,SAAS,EAAiB,EAAyC,CACjE,IAAM,EAAiC,CAAC,EACxC,IAAK,IAAM,KAAO,EAAkB,CAClC,IAAM,EAAS,EAAmC,GAC9C,IAAU,IAAA,IAAa,EAAY,CAAK,IAC1C,EAAM,GAAO,EAEjB,CAGA,GAAI,CAAC,EAAyB,EAAM,UAAa,EAAG,CAClD,IAAM,EAAa,EAAuB,CAAM,EAC5C,IAAe,IAAA,KACjB,EAAM,WAAgB,EAE1B,CACA,OAAO,CACT,CAEA,SAAgB,EAAY,EAAgB,EAAgB,EAA4B,CACtF,GAAI,EAAY,CAAK,EACnB,OAAO,EAET,IAAM,EAAQ,GACZ,EAAQ,GAAK,IAAU,IAAA,GAAY,EAAY,EAAO,EAAQ,CAAC,EAAI,IAAA,GACrE,GAAI,aAAiB,MACnB,MAAO,CACL,UAAW,GACX,KAAM,EAAM,KACZ,QAAS,EAAM,QACf,MAAO,EAAM,MACb,MAAO,EAAiB,CAAK,EAC7B,MAAO,EAAK,EAAM,KAAK,CACzB,EAEF,GAAI,OAAO,GAAU,UAAY,EAAgB,CAG/C,GAAM,CAAE,UAAS,SAAU,EAC3B,MAAO,CACL,UAAW,GACX,KAAM,QACN,QAAS,OAAO,GAAY,SAAW,EAAU,EAAkB,CAAK,EACxE,MAAO,IAAA,GACP,MAAO,EAAiB,CAAK,EAC7B,MAAO,EAAK,CAAK,CACnB,CACF,CACA,MAAO,CACL,UAAW,GACX,KAAM,QACN,QAAS,OAAO,GAAU,SAAW,EAAQ,EAAkB,CAAK,EACpE,MAAO,IAAA,GACP,MAAO,CAAC,EACR,MAAO,IAAA,EACT,CACF,CAOA,SAAgB,EAAc,EAAwB,CACpD,IAAM,EAAY,MAAM,EAAK,QAAS,EAAK,MAAQ,CAAE,MAAO,EAAc,EAAK,KAAK,CAAE,EAAI,CAAC,CAAC,EAM5F,MALA,GAAM,KAAO,EAAK,KACd,EAAK,QAAU,IAAA,KACjB,EAAM,MAAQ,EAAK,OAErB,OAAO,OAAO,EAAO,EAAK,KAAK,EACxB,CACT,CChPA,SAAgB,IAA8B,CAI5C,OAAO,IAAI,OAAO,IAAI,IAAI,sBAAuB,OAAO,KAAK,GAAG,EAAG,CACjE,KAAM,SACN,KAAM,kBACR,CAAC,CACH,CCeA,MAAa,EAAyD,CACpE,MAAO,IACP,KAAM,GACR,EASM,EAAmB,IAAI,QAG7B,IAAM,EAAN,cAAqC,KAAM,CAEzC,QAEA,YAAY,EAAiB,EAAyD,CACpF,MAAM,EAAS,CAAO,EACtB,KAAK,KAAO,yBACZ,KAAK,QAAU,GAAS,SAAW,EACrC,CACF,EAOA,SAAS,EAAe,EAAyB,CAC/C,GAAI,OAAO,GAAU,WAAY,EAC/B,MAAO,GAET,GAAM,CAAE,OAAM,WAAY,EAC1B,OACE,IAAS,kBACR,IAAS,aACR,OAAO,GAAY,UACnB,EAAQ,SAAS,6BAA6B,CAEpD,CAEA,SAAS,EAAe,EAAuC,CAC7D,GAAI,GAAQ,QACV,MAAM,EAAO,QAAU,IAAI,aAAa,6BAA8B,YAAY,CAEtF,CAWA,MAAM,EAA2B,CAAE,MAAO,EAAG,KAAM,IAAA,GAAW,UAAW,EAAG,EAO5E,SAAS,GAAe,EAGtB,CACA,GAAI,IAAQ,IAAA,GACV,MAAO,CAAE,MAAK,UAAW,CAAC,CAAE,EAE9B,IAAM,EAAiB,EAAI,eAAe,MACpC,EAAW,EAAI,SAAS,MAC9B,GAAI,EAAE,aAA0B,aAAe,EAAE,aAAoB,YACnE,MAAO,CAAE,MAAK,UAAW,CAAC,CAAE,EAI9B,IAAM,EAAgB,EAAe,MAAM,EACrC,EAAU,EAAS,MAAM,EAC/B,MAAO,CACL,IAAK,CACH,GAAG,EACH,eAAgB,CAAE,GAAG,EAAI,eAAgB,MAAO,CAAc,EAC9D,SAAU,CAAE,GAAG,EAAI,SAAU,MAAO,CAAQ,CAC9C,EACA,UAAW,CAAC,EAAc,OAAuB,EAAQ,MAAqB,CAChF,CACF,CA4BA,SAAS,IAA2C,CAClD,IAAI,EACE,EAAS,IAAI,SAAgB,EAAU,IAAW,CACtD,EAAO,CACT,CAAC,EAID,OADA,EAAO,UAAY,CAAC,CAAC,EACd,CAAE,YAAa,IAAA,GAAW,OAAQ,IAAA,GAAW,IAAK,IAAA,GAAW,SAAQ,MAAK,CACnF,CAgCA,IAAa,GAAb,KAAkE,CAChE,GAEA,GAEA,GAAgB,GAChB,GAAyB,EAEzB,GAAY,EAEZ,GAA8B,IAAI,IAElC,GAEA,GAAU,EACV,GAAoB,GAEpB,YAAY,EAAmC,CAC7C,KAAKA,GAAU,CACjB,CAEA,SAA4B,CAI1B,IAAM,EAAc,KAAKE,KAAgB,GAAuB,EAChE,GAAI,EAAW,cAAgB,IAAA,GAAW,CAGxC,IAAM,EAAyB,KAAKC,OAAkB,KAAKC,GAAU,CAAU,CAAC,CAAC,CAAC,MAC/E,GAAmB,CAIlB,MAHI,EAAW,cAAgB,IAC7B,EAAW,YAAc,IAAA,IAErB,CACR,CACF,EACA,EAAW,YAAc,CAC3B,CACA,OAAO,EAAW,WACpB,EAEA,aAAuD,GACrD,KAAKD,OACH,KAAKE,GACF,GAAY,EAAQ,aAAa,CAAU,GAG3C,EAAK,EAAI,IAAY,EAAI,aAAa,EAAI,CAAE,GAAG,EAAY,SAAQ,CAAC,EACrE,EAAW,OACb,CACF,EAEF,cAAyD,GACvD,KAAKF,OACH,KAAKE,GACF,GAAY,EAAQ,cAAc,CAAU,GAC5C,EAAK,EAAI,IAAY,EAAI,cAAc,EAAI,CAAE,GAAG,EAAY,SAAQ,CAAC,EACtE,EAAW,OACb,CACF,EAYF,SAAgB,CACd,KAAKC,GAAoB,GACzB,KAAKC,GAAe,CACtB,CAQA,KAAMF,GACJ,EACA,EAKA,EACY,CACZ,GAAM,CAAE,SAAQ,aAAY,GAAG,GAAY,GAAe,CAAC,EAE3D,EAAe,CAAM,EACrB,MAAM,KAAK,KAAK,EAEhB,EAAe,CAAM,EACrB,IAAM,EAAa,KAAKH,GAClB,EAAM,GAAY,IAGxB,GAAI,KAAKM,KAAoB,IAAA,KAAc,KAAKC,IAAiB,IAAQ,IAAA,IACvE,OAAO,EAAO,MAAM,KAAKD,EAAe,EAE1C,GAAI,IAAe,IAAA,IAAa,IAAQ,IAAA,GACtC,OAAO,EACL,MAAM,KAAKE,GACT,EACA,KAAKC,GAAS,MAAQ,IAAI,EAAuB,6BAA6B,CAChF,CACF,EAEF,IAAM,EAAK,KAAKC,KACV,MAAgB,KAAK,EAAI,MAAM,CAAE,CAAC,CAAC,UAAY,CAAC,CAAC,EACvD,GAAQ,iBAAiB,QAAS,EAAS,CAAE,KAAM,EAAK,CAAC,EACrD,GACF,KAAKX,GAAmB,IAAI,EAAI,CAAgD,EAElF,GAAI,CACF,IAAM,EAAS,MAAM,KAAKY,GAAc,EAAY,EAAW,EAAK,EAAI,CAAO,CAAC,EAIhF,MADA,MAAKF,GAAW,EACT,CACT,OAAS,EAAO,CACd,GAAI,aAAiB,EACnB,OAAO,EAAO,MAAM,KAAKD,GAAS,EAAY,CAAK,CAAC,EAEtD,MAAM,CACR,QAAU,CACR,KAAKT,GAAmB,OAAO,CAAE,EACjC,GAAQ,oBAAoB,QAAS,CAAO,CAC9C,CACF,CAEA,KAAMG,GAAU,EAA6C,CAC3D,GAAI,KAAKK,GAEP,OAEF,IAAM,EAAgB,KAAKT,GAAQ,cACnC,GAAI,IAAkB,IAAA,GAAW,CAG/B,MAAM,KAAKU,GAAS,EAAY,IAAI,EAAuB,CAAa,CAAC,EACzE,MACF,CAIA,IAAM,EAAmB,MAAM,KAAKV,GAAQ,YAAY,EACxD,GAAI,CACF,IAAM,EAAM,MAAM,KAAKc,GAAO,CAAU,EAClC,EAAU,KAAKd,GAAQ,QACvB,EACJ,OAAO,GAAY,SACf,KACA,EAAM,KAAO,IAA+C,CAC1D,GAAI,CACF,OAAO,MAAM,EAAQ,QAAQ,CAAiD,CAChF,OAAS,EAAO,CAId,MAAM,EAAY,CAAK,CACzB,CACF,CAAC,EAGD,EAAM,GAAO,EAAmC,IAAoB,CACxE,GAAI,CACF,KAAKA,GAAQ,OAAO,EAAM,CAAC,CAAO,CACpC,OAAS,EAAO,CACd,KAAKe,GAAmB,SAAU,CAAK,CACzC,CACF,CAAC,EACK,EAAa,GAAO,EAAY,IAA6B,CACjE,GAAI,CACF,KAAKd,GAAmB,IAAI,CAAE,CAAC,GAAG,CAAK,CACzC,OAAS,EAAO,CACd,KAAKc,GAAmB,aAAc,CAAK,CAC7C,CACF,CAAC,EAIK,EAAU,GAAe,CAAgB,EAC/C,MAAM,KAAKF,GACT,EACA,EAAI,KACF,EACE,CACE,GAAG,KAAKb,GAAQ,YAChB,cAAe,CACb,GAAG,KAAKA,GAAQ,YAAY,cAC5B,iBAAkB,EAAQ,GAC5B,EACA,OAAQ,OAAO,GAAY,SAAW,EAAU,IAAA,EAClD,EACA,EAAQ,SACV,EACA,EACA,EACA,CACF,EACA,CAAE,GAAI,KAAKA,GAAQ,SAAS,KAAM,UAAW,MAAO,CACtD,EACA,EAAW,IAAM,EACjB,KAAKW,GAAW,CAAE,GAAG,KAAKA,GAAU,KAAM,IAAA,EAAU,CACtD,OAAS,EAAO,CAId,GAAI,EAAE,aAAiB,GAErB,MADA,KAAKK,GAAU,EAAY,IAAI,EAAuB,6BAA6B,CAAC,EAC9E,EAER,MAAM,KAAKN,GAAS,EAAY,CAAK,CACvC,CACF,CAGA,GAAmB,EAAkB,EAAsB,CACzD,IAAM,EAAS,aAAiB,MAAQ,EAAM,QAAU,OAAO,CAAK,EACpE,GAAI,CACF,KAAKV,GAAQ,OAAO,KAAK,mBAAmB,EAAS,mBAAmB,GAAQ,CAClF,MAAQ,CAER,CACF,CAOA,KAAMG,GAAe,EAAoC,CACvD,KAAKc,KACL,GAAI,CACF,OAAO,MAAM,EAAK,CACpB,QAAU,CACR,KAAKA,KACL,KAAKV,GAAe,CACtB,CACF,CAEA,IAAuB,CACjB,CAAC,KAAKD,IAAqB,KAAKW,GAAU,IAG9C,KAAKX,GAAoB,GACzB,KAAKJ,IAAa,QAAQ,UAAU,EAGpC,KAAKA,GAAc,IAAA,GACnB,KAAKM,GAAkB,IAAA,GACvB,KAAKC,GAAgB,GACrB,KAAKE,GAAW,EAClB,CAEA,IAAwB,CACtB,IAAM,EAAS,KAAKX,GAAQ,aAC5B,GAAI,IAAW,IAAA,GACb,OAAO,GAAoB,EAE7B,GAAI,OAAO,GAAW,WAAY,CAChC,IAAM,EAAS,EAAO,EAStB,OANI,EAAiB,IAAI,CAAM,GAC7B,KAAKA,GAAQ,OAAO,WAClB,6GACF,EAEF,EAAiB,IAAI,CAAM,EACpB,CACT,CACA,OAAO,IAAI,OAAO,EAAQ,CAAE,KAAM,SAAU,KAAM,kBAAmB,CAAC,CACxE,CAGA,KAAMc,GAAO,EAAiE,CAC5E,IAAI,EACJ,GAAI,CACF,EAAS,KAAKI,GAAc,CAC9B,OAAS,EAAO,CAGd,MAAM,IAAI,EAAuB,aAAiB,MAAQ,EAAM,QAAU,OAAO,CAAK,EAAG,CACvF,MAAO,CACT,CAAC,CACH,CACA,EAAW,OAAS,EACpB,IAAM,EAAM,MAAM,KAAKC,GAAW,EAAY,CAAM,EAEpD,OADA,KAAKC,GAAiB,EAAY,CAAM,EACjC,CACT,CAGA,GAAW,EAA8B,EAAmD,CAC1F,OAAO,IAAI,SAAmC,EAAS,IAAW,CAChE,IAAM,MAAe,CACnB,aAAa,CAAK,EAClB,EAAO,oBAAoB,UAAW,CAAO,EAC7C,EAAO,oBAAoB,QAAS,CAAO,CAC7C,EACM,EAAQ,eAAiB,CAC7B,EAAO,EACP,EACE,IAAI,EACF,uCAAuC,KAAKpB,GAAQ,SAAS,MAAM,IACrE,CACF,CACF,EAAG,KAAKA,GAAQ,SAAS,KAAK,EACxB,EAAW,GAAwB,CACnC,EAAM,OAAA,8BACR,EAAO,EACP,EAAQ,EAAuB,CAAM,CAAC,EAE1C,EACM,EAAW,GAAsB,CACrC,EAAO,EACP,IAAM,EAAU,EAAM,SAAW,wBAGjC,EAAO,IAAI,EAAuB,CAAO,CAAC,EAC1C,KAAKgB,GAAU,EAAY,IAAI,EAAuB,CAAO,CAAC,CAChE,EACA,EAAO,iBAAiB,UAAW,CAAO,EAC1C,EAAO,iBAAiB,QAAS,CAAO,CAC1C,CAAC,CACH,CAGA,GAAiB,EAA8B,EAAsB,CACnE,EAAO,iBAAiB,QAAU,GAAsB,CAGtD,GAAI,KAAKd,KAAgB,EACvB,OAKF,IAAM,EAAQ,IAAI,EAAuB,EAAM,SAAW,wBAAyB,CACjF,QAAS,EACX,CAAC,EACD,KAAKS,GAAW,CAAE,GAAG,KAAKA,GAAU,MAAO,KAAKA,GAAS,MAAQ,EAAG,KAAM,CAAM,EAChF,KAAKK,GAAU,EAAY,CAAK,CAClC,CAAC,CACH,CAUA,KAAMH,GACJ,EACA,EACA,EACY,CACZ,IAAM,EACJ,IAAa,IAAA,GACT,IAAA,GACA,eAAiB,CACf,KAAKG,GACH,EACA,IAAI,EACF,kBAAkB,EAAS,UAAU,mBAAmB,EAAS,GAAG,IACtE,CACF,CACF,EAAG,EAAS,EAAE,EACpB,GAAI,CACF,OAAO,MAAM,QAAQ,KAAK,CACxB,EAAK,MAAO,GAAmB,CAC7B,IAAM,EAAU,EAAY,CAAK,EAAI,EAAc,CAAK,EAAK,EAG7D,MAAM,EAAe,CAAO,EACxB,IAAI,EAAuB,EAAQ,QAAS,CAAE,MAAO,CAAQ,CAAC,EAC9D,CACN,CAAC,EACD,EAAW,MACb,CAAC,CACH,QAAU,CACJ,IAAU,IAAA,IACZ,aAAa,CAAK,CAEtB,CACF,CAQA,GAAU,EAA0C,EAAqC,CACnF,IAAe,IAAA,KAGf,KAAKd,KAAgB,IACvB,KAAKA,GAAc,IAAA,IAErB,EAAW,QAAQ,UAAU,EAC7B,EAAW,OAAS,IAAA,GACpB,EAAW,IAAM,IAAA,GACjB,EAAW,YAAc,IAAA,GACzB,EAAW,KAAK,CAAK,EACvB,CAEA,KAAMQ,GACJ,EACA,EACgC,CAChC,IAAM,EAAS,aAAiB,MAAQ,EAAM,QAAU,OAAO,CAAK,EACpE,GAAI,KAAKV,GAAQ,OAEf,MADA,KAAKgB,GAAU,EAAY,IAAI,EAAuB,6BAA6B,CAAC,EAC9E,IAAI,EACR,oEAAoE,IACpE,CAAE,OAAM,CACV,EAEF,GAAM,CAAE,YAAW,WAAY,KAAKK,GAAiB,CAAK,EAI1D,GAHA,KAAKZ,KAAkB,CAAC,EACxB,KAAKO,GAAU,EAAY,IAAI,EAAuB,oCAAoC,CAAC,EAC3F,KAAKM,GAAc,EAAQ,EAAW,CAAO,EACzC,KAAKd,KAAoB,IAAA,GAAW,CAGtC,IAAM,GAA2C,SAAY,CAC3D,IAAM,EAAS,KAAKR,GAAQ,mBAAmB,EAE/C,OADA,MAAM,EAAO,KAAK,EACX,CACT,EAAA,CAAG,CAAC,CAAC,MAAO,GAAmB,CAO7B,MANI,KAAKQ,KAAoB,IAC3B,KAAKA,GAAkB,IAAA,IAEzB,KAAKR,GAAQ,OAAO,WAClB,iDAAiD,aAAiB,MAAQ,EAAM,QAAU,OAAO,CAAK,GACxG,EACM,CACR,CAAC,EACD,KAAKQ,GAAkB,CACzB,CACA,OAAO,KAAKA,EACd,CAQA,GAAiB,EAA4E,CAC3F,IAAM,EACJ,aAAiB,GACjB,EAAM,SACN,KAAKG,GAAS,MAAQ,EACxB,MAAO,CAAE,YAAW,QAAS,CAAC,GAAa,CAAC,KAAKF,EAAc,CACjE,CAGA,GAAc,EAAgB,EAAoB,EAAwB,CACxE,GAAI,CAAC,GAAW,KAAKE,GAAS,YAAc,KAAKA,GAAS,MACxD,OAEF,KAAKA,GAAW,CAAE,GAAG,KAAKA,GAAU,UAAW,KAAKA,GAAS,KAAM,EACnE,IAAM,EAAQ,EAAY,kCAAoC,wBAG9D,KAAKX,GAAQ,OAAO,WAClB,gCAAmC,EAAM,0BAA0B,GACrE,CACF,CACF,ECjkBa,GAAb,KAAgD,CAC9C,GACA,GACA,GACA,GACA,GACA,GAOA,YAAY,EAA4B,CACtC,KAAKuB,GAAS,EAAO,MACrB,GAAM,CAAE,UAAS,QAAO,gBAAe,iBAAgB,oBACrD,EAAO,SAAW,CAAC,EACf,EAAO,KAAKA,GAAO,KAAO,GAAY,KAAKA,GAAO,IAAI,EAAI,IAAA,GAK1D,EAAS,CACb,aAAc,EAAmB,CAAE,UAJnC,OAAO,KAAKA,GAAO,SAAY,SAC3B,EAAK,KAAKA,GAAO,OAAO,EACxB,EAAO,KAAKA,GAAO,OAAO,CAEe,CAAC,EAC9C,MAAO,EAAa,KAAKA,EAAM,EAC/B,QAAS,CAAE,gBAAe,iBAAgB,kBAAiB,CAC7D,EACA,KAAKI,GAAkB,CACrB,GAAI,IAAS,IAAA,IAAa,CAAE,MAAK,EACjC,GAAI,IAAY,IAAA,IAAa,CAAE,SAAQ,EACvC,GAAI,IAAU,IAAA,IAAa,CAAE,OAAM,CACrC,EAIA,IAAM,MACJ,KAAKH,GAAM,2BAA2B,CAAE,QAAS,KAAKG,EAAgB,CAAC,EAGnE,EAAkB,IAAsD,CAC5E,KAAM,SAAY,CAChB,MAAM,EAAY,EAClB,MAAM,EAAO,KAAK,CACpB,EACA,aAAe,GAAe,EAAO,aAAa,CAAU,EAC5D,cAAgB,GAAe,EAAO,cAAc,CAAU,EAC9D,2BAA6B,GAAe,EAAO,2BAA2B,CAAU,CAC1F,GACI,EAAO,WACT,KAAKH,GAAQ,GAA+B,CAAM,EAClD,KAAKC,GAAW,GAAkC,CAAM,EACxD,KAAKC,GAAW,EAAe,GAAkC,CAAM,CAAC,IAExE,KAAKF,GAAQ,EAAsB,CAAM,EACzC,KAAKC,GAAW,EAAyB,CAAM,EAC/C,KAAKC,GAAW,KAAKE,GAAqB,EAAQ,EAAQ,CACxD,cACA,uBAA0B,EAAe,EAAyB,CAAM,CAAC,CAC3E,CAAC,EAEL,CAMA,GACE,EACA,EACA,EAIqB,CACrB,IAAM,EAAU,EAAO,gBAAkB,GACnC,EAAS,IAAY,GACrB,EACJ,OAAO,QAAW,aACjB,EAAO,gBAAkB,IAAA,IAAA,IAK5B,GAAI,IAAY,IAAS,EAAE,GAAU,GACnC,OAAO,EAAO,mBAAmB,EAEnC,IAAM,EAAU,EAAsB,EAChC,EAAU,GAAsB,CAAO,EAC7C,GAAI,IAAY,IAAA,IAAa,CAAC,EAI5B,OADA,EAAO,OAAO,WAAW,0CAA0C,EAAQ,EAAE,EACtE,EAAO,mBAAmB,EAEnC,IAAM,EAAe,IAAI,GAAoB,CAC3C,YAAa,CAAE,MAAO,EAAO,MAAO,cAAe,EAAO,QAAS,QAAS,GAAW,CAAC,CAAE,EAC1F,QAAS,KAAKL,GAAO,QACrB,YAAa,EAAO,YACpB,mBAAoB,EAAO,mBAC3B,OAAQ,EAAO,OACf,SAAU,EAAO,iBAAmB,EACpC,aAAc,EAAO,cAGrB,cAAe,EACf,QACF,CAAC,EACD,MAAO,CACL,SAAY,EAAa,KAAK,EAC9B,aAAe,GAAe,EAAa,aAAa,CAAU,EAClE,cAAgB,GAAe,EAAa,cAAc,CAAU,EAIpE,2BAA6B,GAAe,KAAKC,GAAM,2BAA2B,CAAU,EAC5F,YAAe,EAAa,QAAQ,CACtC,CACF,CAGA,IAAI,OAAQ,CACV,OAAO,KAAKD,EACd,CAIA,QACE,KAAKM,KAAwB,KAAKH,GAAS,KAAK,CAAC,CAAC,MAAO,GAAmB,CAE1E,KADA,MAAKG,GAAsB,IAAA,GACrB,CACR,CAAC,EACM,KAAKA,IAOd,YAAsB,CACpB,KAAKA,GAAsB,IAAA,GAC3B,KAAKH,GAAS,UAAU,CAC1B,EAcA,mBAAwD,KAAO,KAC7D,MAAM,KAAKF,GAAM,KAAK,EACf,KAAKA,GAAM,mBAAmB,CACnC,GAAG,EACH,QAAS,CAAE,GAAG,KAAKG,GAAiB,GAAG,EAAW,OAAQ,CAC5D,CAAC,GAeH,oBAA0D,KAAO,KAC/D,MAAM,KAAKH,GAAM,KAAK,EACf,KAAKA,GAAM,oBAAoB,CACpC,GAAG,EACH,QAAS,CAAE,GAAG,KAAKG,GAAiB,GAAG,EAAW,OAAQ,CAC5D,CAAC,GAeH,kCAAsF,KACpF,KAEA,MAAM,KAAKH,GAAM,KAAK,EACf,KAAKA,GAAM,kCAAkC,CAClD,GAAG,EACH,QAAS,CAAE,GAAG,KAAKG,GAAiB,GAAG,EAAW,OAAQ,CAC5D,CAAC,GAkBH,aAA4C,KAAO,KACjD,MAAM,KAAKG,GAAa,EACjB,KAAKJ,GAAS,aAAa,CAChC,GAAG,EACH,QAAS,CAAE,GAAG,KAAKC,GAAiB,GAAG,EAAW,OAAQ,CAC5D,CAAC,GAoBH,cAA8C,KAAO,KACnD,MAAM,KAAKG,GAAa,EACjB,KAAKJ,GAAS,cAAc,CACjC,GAAG,EACH,QAAS,CAAE,GAAG,KAAKC,GAAiB,GAAG,EAAW,OAAQ,CAC5D,CAAC,GAoBH,aAA4C,KAAO,KACjD,MAAM,KAAKF,GAAS,KAAK,EAClB,KAAKA,GAAS,aAAa,CAChC,GAAG,EACH,QAAS,CAAE,GAAG,KAAKE,GAAiB,GAAG,EAAW,OAAQ,CAC5D,CAAC,GAkBH,cAA8C,KAAO,KACnD,MAAM,KAAKF,GAAS,KAAK,EAClB,KAAKA,GAAS,cAAc,CACjC,GAAG,EACH,QAAS,CAAE,GAAG,KAAKE,GAAiB,GAAG,EAAW,OAAQ,CAC5D,CAAC,GAoBH,uBAAgE,KAAO,KACrE,MAAM,KAAKF,GAAS,KAAK,EAClB,KAAKA,GAAS,uBAAuB,CAC1C,GAAG,EACH,QAAS,CAAE,GAAG,KAAKE,GAAiB,GAAG,EAAW,OAAQ,CAC5D,CAAC,GAcH,2BAAwE,KAAO,KAI7E,MAAM,KAAKH,GAAM,KAAK,EACf,KAAKA,GAAM,2BAA2B,CAC3C,GAAG,EACH,QAAS,CAAE,GAAG,KAAKG,GAAiB,GAAG,GAAY,OAAQ,CAC7D,CAAC,GAwBH,qBAA4D,KAAO,KACjE,MAAM,KAAKH,GAAM,KAAK,EACf,KAAKA,GAAM,qBAAqB,CAAU,GAsBnD,4BAA0E,KAAO,KAC/E,MAAM,KAAKA,GAAM,KAAK,EACf,KAAKA,GAAM,4BAA4B,CAAU,GAuB1D,2CACG,GAAeO,EAAiD,KAAKP,GAAO,CAAU,EAuBzF,4CACG,GAAeQ,EAAkD,KAAKR,GAAO,CAAU,EAW1F,8BAA8E,GAC5ES,EAAoC,KAAKT,GAAO,CAC9C,QAAS,CAAE,GAAG,KAAKG,GAAiB,GAAG,GAAY,OAAQ,CAC7D,CAAC,EAkBH,0BAAuE,GACrE,KAAKF,GAAS,0BAA0B,CAAU,EAapD,gCAAmF,GACjF,KAAKD,GAAM,gCAAgC,CAAU,EAcvD,sBAA8D,KAAO,KACnE,MAAM,KAAKC,GAAS,KAAK,EAClB,KAAKA,GAAS,sBAAsB,CAAU,GAmBvD,4BAA0E,KAAO,KAC/E,MAAM,KAAKD,GAAM,KAAK,EACf,KAAKA,GAAM,4BAA4B,CAAU,GAc1D,yBAAoE,UAClE,MAAM,KAAKC,GAAS,KAAK,EAClB,KAAKA,GAAS,yBAAyB,EAElD,EAMA,SAAS,GAAsB,EAA4D,CAGzF,GAAI,EAAqB,EACvB,MAAO,gEAIT,GAAI,IAAY,IAAA,IAAa,EAAsB,EACjD,MAAO,4FAGX,CAQA,SAAS,GACP,EAC0C,CAC1C,IAAM,EAAO,EAAK,OAClB,OAAQ,EAAR,CACE,IAAK,eACH,MAAO,CAAE,OAAM,MAAO,EAAK,MAAO,OAAQ,EAAK,MAAO,EACxD,IAAK,eACH,MAAO,CAAE,OAAM,MAAO,EAAK,MAAO,OAAQ,EAAK,MAAO,EACxD,IAAK,cACH,MAAO,CAAE,OAAM,MAAO,EAAK,KAAM,EACnC,QACE,MAAM,IAAI,EAAmB,sBAAsB,OAAO,CAAI,GAAG,CACrE,CACF"}
|