@zama-fhe/sdk 3.0.0-alpha.33 → 3.0.0-alpha.35
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/ethers/index.cjs +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/sdk-events.cjs +2 -0
- package/dist/cjs/sdk-events.cjs.map +1 -0
- package/dist/cjs/viem/index.cjs +1 -1
- package/dist/cjs/wrappers-registry.cjs +1 -1
- package/dist/cjs/wrappers-registry.cjs.map +1 -1
- package/dist/esm/base-signer-_SHBbx__.js +2 -0
- package/dist/esm/base-signer-_SHBbx__.js.map +1 -0
- package/dist/esm/cleartext/index.js +1 -1
- package/dist/esm/{cleartext-P_TtxaYu.js → cleartext-BYuaZXRn.js} +2 -2
- package/dist/esm/{cleartext-P_TtxaYu.js.map → cleartext-BYuaZXRn.js.map} +1 -1
- package/dist/esm/ethers/index.js +1 -1
- package/dist/esm/{index-Bj1e7zqN.d.ts → index-9ZSvu6a6.d.ts} +4 -16
- package/dist/esm/index.d.ts +1 -1
- package/dist/esm/index.js +1 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/node/index.js +1 -1
- package/dist/esm/query/index.d.ts +1 -1
- package/dist/esm/query/index.js +1 -1
- package/dist/esm/query/index.js.map +1 -1
- package/dist/esm/{relayer-cleartext-C3vXrcLF.js → relayer-cleartext-T0I-wWO6.js} +1 -1
- package/dist/esm/{relayer-cleartext-C3vXrcLF.js.map → relayer-cleartext-T0I-wWO6.js.map} +1 -1
- package/dist/esm/sdk-events-BFtimjdE.js +2 -0
- package/dist/esm/sdk-events-BFtimjdE.js.map +1 -0
- package/dist/esm/viem/index.js +1 -1
- package/dist/esm/wrappers-registry-Gw7mDeM5.js +2 -0
- package/dist/esm/wrappers-registry-Gw7mDeM5.js.map +1 -0
- package/package.json +1 -1
- package/dist/cjs/readonly-token.cjs +0 -2
- package/dist/cjs/readonly-token.cjs.map +0 -1
- package/dist/esm/base-signer-CPqkySep.js +0 -2
- package/dist/esm/base-signer-CPqkySep.js.map +0 -1
- package/dist/esm/readonly-token-nop0sTRZ.js +0 -2
- package/dist/esm/readonly-token-nop0sTRZ.js.map +0 -1
- package/dist/esm/wrappers-registry-DSD9IMX9.js +0 -2
- package/dist/esm/wrappers-registry-DSD9IMX9.js.map +0 -1
package/dist/cjs/base-signer.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const e=require(`./relayer.cjs`),t=require(`./wrappers-registry.cjs`),n=require(`./validation.cjs`),r=require(`./assertions.cjs`),i=require(`./chains.cjs`);let a=require(`viem`);var o=class extends e.r{operation;constructor(e,t,n,r){super(e,n,r),this.name=`SignerRequiredError`,this.operation=t}},s=class extends o{constructor(t,n){super(e.i.SignerNotConfigured,t,`Cannot ${t} without a signer. Configure one via createConfig({ signer: ... }) or <ZamaProvider config={createConfig({ signer: ... })}>.`,n),this.name=`SignerNotConfiguredError`}},c=class extends o{constructor(t,n){super(e.i.WalletNotConnected,t,`Cannot ${t} without a connected wallet account.`,n),this.name=`WalletNotConnectedError`}},l=class extends o{constructor(t,n){super(e.i.WalletAccountNotReady,t,`Cannot ${t} before the wallet account is ready.`,n),this.name=`WalletAccountNotReadyError`}};async function u(e,t){try{await t()}catch(t){console.warn(`[zama-sdk] ${e} failed:`,t)}}function d(e){return`keypair:${e}`}function f(e){return`permits:${e.signerAddress}:${e.chainId}:${e.delegatorAddress}`}function p(e){return`permits-index:${e}`}function m(e){return(0,a.getAddress)(e)}const h=n.d().refine(e=>(0,a.isHex)(e,{strict:!0}),`expected 0x-prefixed hex string`),g=n.d().refine(e=>(0,a.isAddress)(e,{strict:!1}),`expected EVM address`).transform(m),_=n.c().int().nonnegative(),ee=n.c().int().positive(),v=n.c().int().nonnegative(),y=n.c().int().positive(),b=n.c().int().positive(),x=86400;function S(){return Math.floor(Date.now()/1e3)}function C(e){return[...new Set(e.map(m))].toSorted()}const w=`keypairTTL must be a positive integer number of seconds`,T=`permitTTL must be a positive integer number of days`,E=365*x,D=n.c(w).finite(w).int(w).positive(w).max(E,`keypairTTL must not exceed the fhevm ACL maximum of ${E}s (365 days)`),O=n.c(T).finite(T).int(T).positive(T),k=n.l({publicKey:h,privateKey:h,createdAt:_,expiresAt:ee}),A=n.l({keypairPublicKey:h,signerAddress:g,delegatorAddress:g,chainId:b,signedContractAddresses:n.i(g).max(10),signature:h,startTimestamp:_,durationDays:y}),j=n.i(A),M=n.i(n.d());var N=class{#e;#t;#n;#r=new Map;constructor(e){this.#e=e.generator,this.#t=e.storage,this.#n=e.ttl}async readStored(e){let t=d(e),n=await this.#t.get(t);if(n==null)return null;let r=k.safeParse(n);if(!r.success)return await u(`delete keypair entry`,()=>this.#t.delete(t)),null;let i=r.data;return S()>=i.expiresAt?(await u(`delete keypair entry`,()=>this.#t.delete(t)),null):i}async getOrCreate(e){let t=this.#r.get(e);if(t)return t;let n=(async()=>{let t=await this.readStored(e);if(t!==null)return t;let n=await this.#e(),r=S(),i={publicKey:n.publicKey,privateKey:n.privateKey,createdAt:r,expiresAt:r+this.#n},a=d(e);return await u(`persist keypair`,()=>this.#t.set(a,i)),i})().finally(()=>{this.#r.delete(e)});return this.#r.set(e,n),n}async clear(e){let t=d(e);await u(`delete keypair entry`,()=>this.#t.delete(t))}};function P(e,t){let n=new Set(e.flatMap(e=>e.signedContractAddresses));return t.filter(e=>!n.has(e))}function F(e){let t=[];for(let n=0;n<e.length;n+=10)t.push(e.slice(n,n+10));return t}function I(e,t,n){return e.filter(e=>e.keypairPublicKey===t&&n<e.startTimestamp+e.durationDays*86400)}function L(e,t){let n=new Set(t);return e.filter(e=>!e.signedContractAddresses.some(e=>n.has(e)))}var R=class{#e;constructor(e){this.#e=e.storage}async list(e){let t=f(e),n=await this.#e.get(t);if(n==null)return[];let r=j.safeParse(n);return r.success?r.data:(await this.#i(t),await this.#r(e),[])}async listUsableAndPrune(e,t){let n=await this.list(e),r=I(n,t,Math.floor(Date.now()/1e3));if(r.length!==n.length){let t=f(e);r.length===0?(await this.#i(t),await this.#r(e)):await u(`update permit entry`,()=>this.#e.set(t,r))}return r}async append(e,t){if(t.length===0)return;let n=t.map(e=>A.parse(e)),r=await this.list(e);await this.#e.set(f(e),[...r,...n]),await this.#n(e)}async deletePermitsTouching(e,t){let n=await this.list(e);if(n.length===0)return;let r=f(e),i=L(n,t);i.length===0?(await this.#i(r),await this.#r(e)):await this.#e.set(r,i)}async clearAllForSigner(e){let t=p(e),n=await this.#t(t);await Promise.all(n.map(e=>this.#i(e))),await u(`delete permit index`,()=>this.#e.delete(t))}async#t(e){let t=await this.#e.get(e);if(t==null)return[];let n=M.safeParse(t);return n.success?n.data:(await u(`delete permit index`,()=>this.#e.delete(e)),[])}async#n(e){let t=p(e.signerAddress),n=f(e),r=await this.#t(t);r.includes(n)||await this.#e.set(t,[...r,n])}async#r(e){let t=p(e.signerAddress),n=f(e),r=await this.#t(t),i=r.filter(e=>e!==n);i.length!==r.length&&(i.length===0?await u(`delete permit index`,()=>this.#e.delete(t)):await u(`update permit index`,()=>this.#e.set(t,i)))}async#i(e){await u(`delete permit entry`,()=>this.#e.delete(e))}};30*x;var z=class{#e;#t;#n;#r;#i;constructor(e){this.#e=new N({generator:()=>e.relayer.generateKeypair(),storage:e.storage,ttl:e.keypairTTL}),this.#t=new R({storage:e.permitStorage??e.storage}),this.#n=e.relayer,this.#r=e.signer,this.#i=e.permitTTL}async allow(e,t){let n=this.#r.requireWalletAccount(`allow`),r=m(n.address),i=C(e),a=await this.#e.getOrCreate(r);if(i.length===0)return{keypair:a,permits:[]};let o={signerAddress:r,chainId:n.chainId,delegatorAddress:t?m(t):r},s=await this.#t.listUsableAndPrune(o,a.publicKey);for(let e of F(P(s,i))){let t=await this.#a({chunk:e,keypair:a,scope:o});s.push(t),await u(`persist permit`,()=>this.#t.append(o,[t]))}let c=new Set(i);return{keypair:a,permits:s.filter(e=>e.signedContractAddresses.some(e=>c.has(e)))}}async isAllowed(e,t){if(e.length===0)return!0;let n=this.#r.walletAccount.getSnapshot();if(!n)return!1;let r=m(n.address),i=await this.#e.readStored(r);if(i===null)return!1;let a={signerAddress:r,chainId:n.chainId,delegatorAddress:t?m(t):r};return P(await this.#t.listUsableAndPrune(a,i.publicKey),C(e)).length===0}async revokePermits(e){let t=this.#r.requireWalletAccount(`revokePermits`),n=m(t.address);if(e===void 0){await this.#t.clearAllForSigner(n);return}let r=C(e);if(r.length===0)return;let i=t.chainId;await this.#t.deletePermitsTouching({signerAddress:n,chainId:i,delegatorAddress:n},r)}async clearCredentials(){let e=m(this.#r.requireWalletAccount(`clearCredentials`).address);await this.#e.clear(e),await this.#t.clearAllForSigner(e)}async handleWalletAccountChange(e,t){let n=e?m(e.address):void 0,r=t?m(t.address):void 0;n!==r&&(n&&(await this.#e.clear(n),await this.#t.clearAllForSigner(n)),r&&await u(`warm keypair`,async()=>{await this.#e.getOrCreate(r)}))}async#a(n){let{chunk:r,keypair:i,scope:a}=n,o=S(),s=a.delegatorAddress!==a.signerAddress;try{let e=s?await this.#n.createDelegatedUserDecryptEIP712(i.publicKey,r,a.delegatorAddress,o,this.#i):await this.#n.createEIP712(i.publicKey,r,o,this.#i),t=await this.#r.signTypedData(e);return{keypairPublicKey:i.publicKey,signerAddress:a.signerAddress,delegatorAddress:a.delegatorAddress,chainId:a.chainId,signedContractAddresses:r,signature:t,startTimestamp:o,durationDays:this.#i}}catch(n){throw n instanceof e.r?n:t.z(n,`Credential signing failed`)}}},B=class{#e=new Map;async get(e){return this.#e.get(e)??null}async set(e,t){this.#e.set(e,t)}async delete(e){this.#e.delete(e)}};const V=new B;function H(){return typeof window<`u`?new n.n(`CredentialStore`):new B}function U(e=H(),t=e){return{storage:e,permitStorage:t}}function W(t,n){let r=new Map(t.map(e=>[e.id,e]));if(r.size!==t.length){let n=t.map(e=>e.id);throw new e.t(`Duplicate chain id(s) [${[...new Set(n.filter((e,t)=>n.indexOf(e)!==t))].join(`, `)}] in the chains array. Each chain id must appear only once. Note: hardhat and anvil are aliases (both use 31337).`)}let i=new Map(Object.entries(n)),a=new Map;for(let t of r.keys()){let n=r.get(t),o=i.get(String(t));if(!o)throw new e.t(`Chain ${t} has no relayer configured. Add a relayer entry: relayers: { [${t}]: web() }`);if(!n)throw new e.t(`Chain ${t} has a relayer configured but no entry in the chains array. Add the chain config to the chains array.`);a.set(t,{chain:n,relayer:o})}let o=new Set(Object.keys(n).map(Number)),s=new Set([...o].filter(e=>!r.has(e)));if(s.size>0)throw new e.t(`Relayer entries for chain(s) [${[...s].join(`, `)}] have no matching entry in the chains array. Remove them or add the corresponding chain config.`);return a}var G=class{#e;#t;#n;#r;constructor(t,n){if(t.length===0)throw new e.t(`At least one chain is required.`);this.#e=new Map(t.map(e=>[e.id,e])),this.#r=t[0].id;let r=W(t,n),i=new Map;for(let[e,t]of r){let n=t.relayer,r=i.get(n);r||(r=[],i.set(n,r)),r.push([e,t.chain])}let a=new Map,o=[];try{for(let[e,t]of i){let n=t.map(([,e])=>e),r=e.createWorker?.(n);r&&o.push(r);for(let[n,i]of t)a.set(n,e.createRelayer(i,r))}}catch(e){for(let e of o)try{e.terminate()}catch{}throw e}this.#t=a,this.#n=o}get chains(){return[...this.#e.values()]}get chain(){let e=this.#e.get(this.#r);return r.r(e,`RelayerDispatcher: chain`),e}switchChain(t){if(!this.#e.has(t))throw new e.t(`No relayer configured for chain ${t}. Add it to the chains array.`);this.#r=t}get#i(){let e=this.#t.get(this.#r);return r.r(e,`RelayerDispatcher: relayer`),e}generateKeypair(){return this.#i.generateKeypair()}createEIP712(e,t,n,r){return this.#i.createEIP712(e,t,n,r)}encrypt(e){return this.#i.encrypt(e)}userDecrypt(e){return this.#i.userDecrypt(e)}publicDecrypt(e){return this.#i.publicDecrypt(e)}createDelegatedUserDecryptEIP712(e,t,n,r,i){return this.#i.createDelegatedUserDecryptEIP712(e,t,n,r,i)}delegatedUserDecrypt(e){return this.#i.delegatedUserDecrypt(e)}requestZKProofVerification(e){return this.#i.requestZKProofVerification(e)}getPublicKey(){return this.#i.getPublicKey()}getPublicParams(e){return this.#i.getPublicParams(e)}getAclAddress(){return this.#i.getAclAddress()}terminate(){let e=[];for(let t of new Set(this.#t.values()))try{t.terminate()}catch(t){e.push(r.s(t))}for(let t of new Set(this.#n))try{t.terminate()}catch(t){e.push(r.s(t))}if(e.length>0)throw AggregateError(e,`Failed to terminate relayer resources`)}[Symbol.dispose](){this.terminate()}};const K={[i.a.id]:i.a.registryAddress,[i.o.id]:i.o.registryAddress,[i.i.id]:i.i.registryAddress},q=n.u(n.d().regex(/^\d+$/,`expected numeric chain id key`),g),J=v,Y=300*1e3;var X=class{provider;#e;#t;#n=new Map;constructor(e){this.provider=e.provider,this.#e=Object.assign({},K,n.t(q.optional(),e.registryAddresses)),this.#t=n.t(J,e.registryTTL??86400)*1e3}getAddress(e){return this.#e[e]}#r(e){let t=this.#n.get(e);if(t){if(Date.now()>=t.expiresAt){this.#n.delete(e);return}return t.data}}#i(e,t,n=this.#t){return this.#n.set(e,{data:t,expiresAt:Date.now()+n}),t}refresh(){this.#n.clear()}get ttlMs(){return this.#t}async getRegistryAddress(){let t=await this.provider.getChainId(),n=this.#e[t];if(!n)throw new e.t(`No wrappers registry address configured for chain ${t}.\nPass a registryAddresses entry for this chain.`);return(0,a.getAddress)(n)}async listPairs(n={}){let r=n.page??1,i=n.pageSize??100,a=n.metadata??!1;if(r<1)throw new e.t(`page must be >= 1, got ${r}`);if(i<1)throw new e.t(`pageSize must be >= 1, got ${i}`);let o=await this.getRegistryAddress(),s=`total:${o}`,c=this.#r(s);if(c===void 0){let e=await this.provider.readContract(t.a(o));c=this.#i(s,Number(e))}let l=BigInt((r-1)*i),u=l+BigInt(i)>BigInt(c)?BigInt(c):l+BigInt(i);if(l>=BigInt(c))return{items:[],total:c,page:r,pageSize:i};let d=`slice:${o}:${l}:${u}`,f=this.#r(d);if(f===void 0){let e=await this.provider.readContract(t.o(o,l,u));f=this.#i(d,[...e])}if(!a)return{items:f,total:c,page:r,pageSize:i};let p=`metadata:${o}:${l}:${u}`,m=this.#r(p);if(m===void 0){let e=await Promise.allSettled(f.map(e=>this.#a(e))),t=e.some(e=>e.status===`rejected`),n=e.map((e,t)=>e.status===`fulfilled`?e.value:Object.assign({},f[t],{metadataFailed:!0,underlying:{name:`Unknown`,symbol:`???`,decimals:0,totalSupply:0n},confidential:{name:`Unknown`,symbol:`???`,decimals:0}}));m=this.#i(p,n,t?Y:void 0)}return{items:m,total:c,page:r,pageSize:i}}async#a(e){let[n,r,i,a,o,s,c]=await Promise.all([this.provider.readContract(t.x(e.tokenAddress)),this.provider.readContract(t.S(e.tokenAddress)),this.provider.readContract(t.y(e.tokenAddress)),this.provider.readContract(t.b(e.tokenAddress)),this.provider.readContract(t.x(e.confidentialTokenAddress)),this.provider.readContract(t.S(e.confidentialTokenAddress)),this.provider.readContract(t.y(e.confidentialTokenAddress))]);return{...e,underlying:{name:n,symbol:r,decimals:i,totalSupply:a},confidential:{name:o,symbol:s,decimals:c}}}async getConfidentialToken(e){let n=await this.getRegistryAddress(),r=(0,a.getAddress)(e),i=`ct:${n}:${r}`,o=this.#r(i);if(o!==void 0)return o;let[s,c]=await this.provider.readContract(t.t(n,r));return c===a.zeroAddress?this.#i(i,null,Y):this.#i(i,{confidentialTokenAddress:c,isValid:s})}async getUnderlyingToken(e){let n=await this.getRegistryAddress(),r=(0,a.getAddress)(e),i=`ut:${n}:${r}`,o=this.#r(i);if(o!==void 0)return o;let[s,c]=await this.provider.readContract(t.n(n,r));return c===a.zeroAddress?this.#i(i,null,Y):this.#i(i,{tokenAddress:c,isValid:s})}async getTokenPairs(){let e=await this.getRegistryAddress();return this.provider.readContract(t.i(e))}async getTokenPairsLength(){let e=await this.getRegistryAddress();return this.provider.readContract(t.a(e))}async getTokenPairsSlice(e,n){let r=await this.getRegistryAddress();return this.provider.readContract(t.o(r,e,n))}async getTokenPair(e){let n=await this.getRegistryAddress();return this.provider.readContract(t.r(n,e))}async getConfidentialTokenAddress(e){let n=await this.getRegistryAddress();return this.provider.readContract(t.t(n,(0,a.getAddress)(e)))}async getTokenAddress(e){let n=await this.getRegistryAddress();return this.provider.readContract(t.n(n,(0,a.getAddress)(e)))}async isConfidentialTokenValid(e){let n=await this.getRegistryAddress();return this.provider.readContract(t.s(n,(0,a.getAddress)(e)))}};function Z(e,t,r){let{storage:i,permitStorage:a}=U(r.storage,r.permitStorage),o=new G(r.chains,r.relayers);return{chains:r.chains,relayer:o,provider:t,signer:e,storage:i,permitStorage:a,keypairTTL:n.t(D,r.keypairTTL??2592e3),permitTTL:n.t(O,r.permitTTL??30),registryTTL:n.t(J,r.registryTTL??86400),onEvent:r.onEvent}}function Q(e,t){return e?.address===t?.address&&e?.chainId===t?.chainId}var $=class{#e=new Set;#t;#n;constructor(e){this.#t=e,this.#n=e!==void 0}getSnapshot(){return this.#t}isReady(){return this.#n}setSnapshot(e){this.#n=!0;let t=this.#t;Q(t,e)||(this.#t=e,this.#r({previous:t,next:e}))}subscribe(e){this.#e.add(e);let t=this.#t;return t&&e({previous:void 0,next:t}),()=>{this.#e.delete(e)}}#r(e){for(let t of this.#e)t(e)}};function te(e){return new $(e)}var ne=class{walletAccount;#e=!1;constructor(e){this.walletAccount=new $(e)}requireWalletAccount(e){let t=this.walletAccount.getSnapshot();if(!t)throw new c(e);return t}dispose(){this.#e||(this.#e=!0,this.onDispose())}[Symbol.dispose](){this.dispose()}onDispose(){}};Object.defineProperty(exports,`_`,{enumerable:!0,get:function(){return o}}),Object.defineProperty(exports,`a`,{enumerable:!0,get:function(){return K}}),Object.defineProperty(exports,`c`,{enumerable:!0,get:function(){return U}}),Object.defineProperty(exports,`d`,{enumerable:!0,get:function(){return z}}),Object.defineProperty(exports,`f`,{enumerable:!0,get:function(){return m}}),Object.defineProperty(exports,`g`,{enumerable:!0,get:function(){return s}}),Object.defineProperty(exports,`h`,{enumerable:!0,get:function(){return u}}),Object.defineProperty(exports,`i`,{enumerable:!0,get:function(){return Z}}),Object.defineProperty(exports,`l`,{enumerable:!0,get:function(){return B}}),Object.defineProperty(exports,`m`,{enumerable:!0,get:function(){return h}}),Object.defineProperty(exports,`n`,{enumerable:!0,get:function(){return $}}),Object.defineProperty(exports,`o`,{enumerable:!0,get:function(){return X}}),Object.defineProperty(exports,`p`,{enumerable:!0,get:function(){return g}}),Object.defineProperty(exports,`r`,{enumerable:!0,get:function(){return te}}),Object.defineProperty(exports,`s`,{enumerable:!0,get:function(){return W}}),Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return ne}}),Object.defineProperty(exports,`u`,{enumerable:!0,get:function(){return V}}),Object.defineProperty(exports,`v`,{enumerable:!0,get:function(){return l}}),Object.defineProperty(exports,`y`,{enumerable:!0,get:function(){return c}});
|
|
1
|
+
const e=require(`./relayer.cjs`),t=require(`./wrappers-registry.cjs`),n=require(`./validation.cjs`),r=require(`./assertions.cjs`),i=require(`./chains.cjs`);let a=require(`viem`);async function o(e,t){try{await t()}catch(t){console.warn(`[zama-sdk] ${e} failed:`,t)}}function s(e){return`keypair:${e}`}function c(e){return`permits:${e.signerAddress}:${e.chainId}:${e.delegatorAddress}`}function l(e){return`permits-index:${e}`}function u(e){return(0,a.getAddress)(e)}const d=n.d().refine(e=>(0,a.isHex)(e,{strict:!0}),`expected 0x-prefixed hex string`),f=n.d().refine(e=>(0,a.isAddress)(e,{strict:!1}),`expected EVM address`).transform(u),p=n.c().int().nonnegative(),m=n.c().int().positive(),h=n.c().int().nonnegative(),g=n.c().int().positive(),_=n.c().int().positive(),v=86400;function y(){return Math.floor(Date.now()/1e3)}function b(e){return[...new Set(e.map(u))].toSorted()}const x=`keypairTTL must be a positive integer number of seconds`,S=`permitTTL must be a positive integer number of days`,C=365*v,w=n.c(x).finite(x).int(x).positive(x).max(C,`keypairTTL must not exceed the fhevm ACL maximum of ${C}s (365 days)`),T=n.c(S).finite(S).int(S).positive(S),E=n.l({publicKey:d,privateKey:d,createdAt:p,expiresAt:m}),D=n.l({keypairPublicKey:d,signerAddress:f,delegatorAddress:f,chainId:_,signedContractAddresses:n.i(f).max(10),signature:d,startTimestamp:p,durationDays:g}),O=n.i(D),k=n.i(n.d());var A=class{#e;#t;#n;#r=new Map;constructor(e){this.#e=e.generator,this.#t=e.storage,this.#n=e.ttl}async readStored(e){let t=s(e),n=await this.#t.get(t);if(n==null)return null;let r=E.safeParse(n);if(!r.success)return await o(`delete keypair entry`,()=>this.#t.delete(t)),null;let i=r.data;return y()>=i.expiresAt?(await o(`delete keypair entry`,()=>this.#t.delete(t)),null):i}async getOrCreate(e){let t=this.#r.get(e);if(t)return t;let n=(async()=>{let t=await this.readStored(e);if(t!==null)return t;let n=await this.#e(),r=y(),i={publicKey:n.publicKey,privateKey:n.privateKey,createdAt:r,expiresAt:r+this.#n},a=s(e);return await o(`persist keypair`,()=>this.#t.set(a,i)),i})().finally(()=>{this.#r.delete(e)});return this.#r.set(e,n),n}async clear(e){let t=s(e);await o(`delete keypair entry`,()=>this.#t.delete(t))}};function j(e,t){let n=new Set(e.flatMap(e=>e.signedContractAddresses));return t.filter(e=>!n.has(e))}function M(e){let t=[];for(let n=0;n<e.length;n+=10)t.push(e.slice(n,n+10));return t}function N(e,t,n){return e.filter(e=>e.keypairPublicKey===t&&n<e.startTimestamp+e.durationDays*86400)}function P(e,t){let n=new Set(t);return e.filter(e=>!e.signedContractAddresses.some(e=>n.has(e)))}var F=class{#e;constructor(e){this.#e=e.storage}async list(e){let t=c(e),n=await this.#e.get(t);if(n==null)return[];let r=O.safeParse(n);return r.success?r.data:(await this.#i(t),await this.#r(e),[])}async listUsableAndPrune(e,t){let n=await this.list(e),r=N(n,t,Math.floor(Date.now()/1e3));if(r.length!==n.length){let t=c(e);r.length===0?(await this.#i(t),await this.#r(e)):await o(`update permit entry`,()=>this.#e.set(t,r))}return r}async append(e,t){if(t.length===0)return;let n=t.map(e=>D.parse(e)),r=await this.list(e);await this.#e.set(c(e),[...r,...n]),await this.#n(e)}async deletePermitsTouching(e,t){let n=await this.list(e);if(n.length===0)return;let r=c(e),i=P(n,t);i.length===0?(await this.#i(r),await this.#r(e)):await this.#e.set(r,i)}async clearAllForSigner(e){let t=l(e),n=await this.#t(t);await Promise.all(n.map(e=>this.#i(e))),await o(`delete permit index`,()=>this.#e.delete(t))}async#t(e){let t=await this.#e.get(e);if(t==null)return[];let n=k.safeParse(t);return n.success?n.data:(await o(`delete permit index`,()=>this.#e.delete(e)),[])}async#n(e){let t=l(e.signerAddress),n=c(e),r=await this.#t(t);r.includes(n)||await this.#e.set(t,[...r,n])}async#r(e){let t=l(e.signerAddress),n=c(e),r=await this.#t(t),i=r.filter(e=>e!==n);i.length!==r.length&&(i.length===0?await o(`delete permit index`,()=>this.#e.delete(t)):await o(`update permit index`,()=>this.#e.set(t,i)))}async#i(e){await o(`delete permit entry`,()=>this.#e.delete(e))}};30*v;var I=class{#e;#t;#n;#r;#i;constructor(e){this.#e=new A({generator:()=>e.relayer.generateKeypair(),storage:e.storage,ttl:e.keypairTTL}),this.#t=new F({storage:e.permitStorage??e.storage}),this.#n=e.relayer,this.#r=e.signer,this.#i=e.permitTTL}async allow(e,t){let n=this.#r.requireWalletAccount(`allow`),r=u(n.address),i=b(e),a=await this.#e.getOrCreate(r);if(i.length===0)return{keypair:a,permits:[]};let s={signerAddress:r,chainId:n.chainId,delegatorAddress:t?u(t):r},c=await this.#t.listUsableAndPrune(s,a.publicKey);for(let e of M(j(c,i))){let t=await this.#a({chunk:e,keypair:a,scope:s});c.push(t),await o(`persist permit`,()=>this.#t.append(s,[t]))}let l=new Set(i);return{keypair:a,permits:c.filter(e=>e.signedContractAddresses.some(e=>l.has(e)))}}async isAllowed(e,t){if(e.length===0)return!0;let n=this.#r.walletAccount.getSnapshot();if(!n)return!1;let r=u(n.address),i=await this.#e.readStored(r);if(i===null)return!1;let a={signerAddress:r,chainId:n.chainId,delegatorAddress:t?u(t):r};return j(await this.#t.listUsableAndPrune(a,i.publicKey),b(e)).length===0}async revokePermits(e){let t=this.#r.requireWalletAccount(`revokePermits`),n=u(t.address);if(e===void 0){await this.#t.clearAllForSigner(n);return}let r=b(e);if(r.length===0)return;let i=t.chainId;await this.#t.deletePermitsTouching({signerAddress:n,chainId:i,delegatorAddress:n},r)}async clearCredentials(){let e=u(this.#r.requireWalletAccount(`clearCredentials`).address);await this.#e.clear(e),await this.#t.clearAllForSigner(e)}async handleWalletAccountChange(e,t){let n=e?u(e.address):void 0,r=t?u(t.address):void 0;n!==r&&(n&&(await this.#e.clear(n),await this.#t.clearAllForSigner(n)),r&&await o(`warm keypair`,async()=>{await this.#e.getOrCreate(r)}))}async#a(n){let{chunk:r,keypair:i,scope:a}=n,o=y(),s=a.delegatorAddress!==a.signerAddress;try{let e=s?await this.#n.createDelegatedUserDecryptEIP712(i.publicKey,r,a.delegatorAddress,o,this.#i):await this.#n.createEIP712(i.publicKey,r,o,this.#i),t=await this.#r.signTypedData(e);return{keypairPublicKey:i.publicKey,signerAddress:a.signerAddress,delegatorAddress:a.delegatorAddress,chainId:a.chainId,signedContractAddresses:r,signature:t,startTimestamp:o,durationDays:this.#i}}catch(n){throw n instanceof e.r?n:t.U(n,`Credential signing failed`)}}},L=class{#e=new Map;async get(e){return this.#e.get(e)??null}async set(e,t){this.#e.set(e,t)}async delete(e){this.#e.delete(e)}};const R=new L;function z(){return typeof window<`u`?new n.n(`CredentialStore`):new L}function B(e=z(),t=e){return{storage:e,permitStorage:t}}function V(t,n){let r=new Map(t.map(e=>[e.id,e]));if(r.size!==t.length){let n=t.map(e=>e.id);throw new e.t(`Duplicate chain id(s) [${[...new Set(n.filter((e,t)=>n.indexOf(e)!==t))].join(`, `)}] in the chains array. Each chain id must appear only once. Note: hardhat and anvil are aliases (both use 31337).`)}let i=new Map(Object.entries(n)),a=new Map;for(let t of r.keys()){let n=r.get(t),o=i.get(String(t));if(!o)throw new e.t(`Chain ${t} has no relayer configured. Add a relayer entry: relayers: { [${t}]: web() }`);if(!n)throw new e.t(`Chain ${t} has a relayer configured but no entry in the chains array. Add the chain config to the chains array.`);a.set(t,{chain:n,relayer:o})}let o=new Set(Object.keys(n).map(Number)),s=new Set([...o].filter(e=>!r.has(e)));if(s.size>0)throw new e.t(`Relayer entries for chain(s) [${[...s].join(`, `)}] have no matching entry in the chains array. Remove them or add the corresponding chain config.`);return a}var H=class{#e;#t;#n;#r;constructor(t,n){if(t.length===0)throw new e.t(`At least one chain is required.`);this.#e=new Map(t.map(e=>[e.id,e])),this.#r=t[0].id;let r=V(t,n),i=new Map;for(let[e,t]of r){let n=t.relayer,r=i.get(n);r||(r=[],i.set(n,r)),r.push([e,t.chain])}let a=new Map,o=[];try{for(let[e,t]of i){let n=t.map(([,e])=>e),r=e.createWorker?.(n);r&&o.push(r);for(let[n,i]of t)a.set(n,e.createRelayer(i,r))}}catch(e){for(let e of o)try{e.terminate()}catch{}throw e}this.#t=a,this.#n=o}get chains(){return[...this.#e.values()]}get chain(){let e=this.#e.get(this.#r);return r.r(e,`RelayerDispatcher: chain`),e}switchChain(t){if(!this.#e.has(t))throw new e.t(`No relayer configured for chain ${t}. Add it to the chains array.`);this.#r=t}get#i(){let e=this.#t.get(this.#r);return r.r(e,`RelayerDispatcher: relayer`),e}generateKeypair(){return this.#i.generateKeypair()}createEIP712(e,t,n,r){return this.#i.createEIP712(e,t,n,r)}encrypt(e){return this.#i.encrypt(e)}userDecrypt(e){return this.#i.userDecrypt(e)}publicDecrypt(e){return this.#i.publicDecrypt(e)}createDelegatedUserDecryptEIP712(e,t,n,r,i){return this.#i.createDelegatedUserDecryptEIP712(e,t,n,r,i)}delegatedUserDecrypt(e){return this.#i.delegatedUserDecrypt(e)}requestZKProofVerification(e){return this.#i.requestZKProofVerification(e)}getPublicKey(){return this.#i.getPublicKey()}getPublicParams(e){return this.#i.getPublicParams(e)}getAclAddress(){return this.#i.getAclAddress()}terminate(){let e=[];for(let t of new Set(this.#t.values()))try{t.terminate()}catch(t){e.push(r.s(t))}for(let t of new Set(this.#n))try{t.terminate()}catch(t){e.push(r.s(t))}if(e.length>0)throw AggregateError(e,`Failed to terminate relayer resources`)}[Symbol.dispose](){this.terminate()}};const U={[i.a.id]:i.a.registryAddress,[i.o.id]:i.o.registryAddress,[i.i.id]:i.i.registryAddress},W=n.u(n.d().regex(/^\d+$/,`expected numeric chain id key`),f),G=h,K=300*1e3;var q=class{provider;#e;#t;#n=new Map;constructor(e){this.provider=e.provider,this.#e=Object.assign({},U,n.t(W.optional(),e.registryAddresses)),this.#t=n.t(G,e.registryTTL??86400)*1e3}getAddress(e){return this.#e[e]}#r(e){let t=this.#n.get(e);if(t){if(Date.now()>=t.expiresAt){this.#n.delete(e);return}return t.data}}#i(e,t,n=this.#t){return this.#n.set(e,{data:t,expiresAt:Date.now()+n}),t}refresh(){this.#n.clear()}get ttlMs(){return this.#t}async getRegistryAddress(){let t=await this.provider.getChainId(),n=this.#e[t];if(!n)throw new e.t(`No wrappers registry address configured for chain ${t}.\nPass a registryAddresses entry for this chain.`);return(0,a.getAddress)(n)}async listPairs(n={}){let r=n.page??1,i=n.pageSize??100,a=n.metadata??!1;if(r<1)throw new e.t(`page must be >= 1, got ${r}`);if(i<1)throw new e.t(`pageSize must be >= 1, got ${i}`);let o=await this.getRegistryAddress(),s=`total:${o}`,c=this.#r(s);if(c===void 0){let e=await this.provider.readContract(t.a(o));c=this.#i(s,Number(e))}let l=BigInt((r-1)*i),u=l+BigInt(i)>BigInt(c)?BigInt(c):l+BigInt(i);if(l>=BigInt(c))return{items:[],total:c,page:r,pageSize:i};let d=`slice:${o}:${l}:${u}`,f=this.#r(d);if(f===void 0){let e=await this.provider.readContract(t.o(o,l,u));f=this.#i(d,[...e])}if(!a)return{items:f,total:c,page:r,pageSize:i};let p=`metadata:${o}:${l}:${u}`,m=this.#r(p);if(m===void 0){let e=await Promise.allSettled(f.map(e=>this.#a(e))),t=e.some(e=>e.status===`rejected`),n=e.map((e,t)=>e.status===`fulfilled`?e.value:Object.assign({},f[t],{metadataFailed:!0,underlying:{name:`Unknown`,symbol:`???`,decimals:0,totalSupply:0n},confidential:{name:`Unknown`,symbol:`???`,decimals:0}}));m=this.#i(p,n,t?K:void 0)}return{items:m,total:c,page:r,pageSize:i}}async#a(e){let[n,r,i,a,o,s,c]=await Promise.all([this.provider.readContract(t.x(e.tokenAddress)),this.provider.readContract(t.S(e.tokenAddress)),this.provider.readContract(t.y(e.tokenAddress)),this.provider.readContract(t.b(e.tokenAddress)),this.provider.readContract(t.x(e.confidentialTokenAddress)),this.provider.readContract(t.S(e.confidentialTokenAddress)),this.provider.readContract(t.y(e.confidentialTokenAddress))]);return{...e,underlying:{name:n,symbol:r,decimals:i,totalSupply:a},confidential:{name:o,symbol:s,decimals:c}}}async getConfidentialToken(e){let n=await this.getRegistryAddress(),r=(0,a.getAddress)(e),i=`ct:${n}:${r}`,o=this.#r(i);if(o!==void 0)return o;let[s,c]=await this.provider.readContract(t.t(n,r));return c===a.zeroAddress?this.#i(i,null,K):this.#i(i,{confidentialTokenAddress:c,isValid:s})}async getUnderlyingToken(e){let n=await this.getRegistryAddress(),r=(0,a.getAddress)(e),i=`ut:${n}:${r}`,o=this.#r(i);if(o!==void 0)return o;let[s,c]=await this.provider.readContract(t.n(n,r));return c===a.zeroAddress?this.#i(i,null,K):this.#i(i,{tokenAddress:c,isValid:s})}async getTokenPairs(){let e=await this.getRegistryAddress();return this.provider.readContract(t.i(e))}async getTokenPairsLength(){let e=await this.getRegistryAddress();return this.provider.readContract(t.a(e))}async getTokenPairsSlice(e,n){let r=await this.getRegistryAddress();return this.provider.readContract(t.o(r,e,n))}async getTokenPair(e){let n=await this.getRegistryAddress();return this.provider.readContract(t.r(n,e))}async getConfidentialTokenAddress(e){let n=await this.getRegistryAddress();return this.provider.readContract(t.t(n,(0,a.getAddress)(e)))}async getTokenAddress(e){let n=await this.getRegistryAddress();return this.provider.readContract(t.n(n,(0,a.getAddress)(e)))}async isConfidentialTokenValid(e){let n=await this.getRegistryAddress();return this.provider.readContract(t.s(n,(0,a.getAddress)(e)))}};function J(e,t,r){let{storage:i,permitStorage:a}=B(r.storage,r.permitStorage),o=new H(r.chains,r.relayers);return{chains:r.chains,relayer:o,provider:t,signer:e,storage:i,permitStorage:a,keypairTTL:n.t(w,r.keypairTTL??2592e3),permitTTL:n.t(T,r.permitTTL??30),registryTTL:n.t(G,r.registryTTL??86400),onEvent:r.onEvent}}function Y(e,t){return e?.address===t?.address&&e?.chainId===t?.chainId}var X=class{#e=new Set;#t;#n;constructor(e){this.#t=e,this.#n=e!==void 0}getSnapshot(){return this.#t}isReady(){return this.#n}setSnapshot(e){this.#n=!0;let t=this.#t;Y(t,e)||(this.#t=e,this.#r({previous:t,next:e}))}subscribe(e){this.#e.add(e);let t=this.#t;return t&&e({previous:void 0,next:t}),()=>{this.#e.delete(e)}}#r(e){for(let t of this.#e)t(e)}};function Z(e){return new X(e)}var Q=class{walletAccount;#e=!1;constructor(e){this.walletAccount=new X(e)}requireWalletAccount(e){let n=this.walletAccount.getSnapshot();if(!n)throw new t.B(e);return n}dispose(){this.#e||(this.#e=!0,this.onDispose())}[Symbol.dispose](){this.dispose()}onDispose(){}};Object.defineProperty(exports,`a`,{enumerable:!0,get:function(){return U}}),Object.defineProperty(exports,`c`,{enumerable:!0,get:function(){return B}}),Object.defineProperty(exports,`d`,{enumerable:!0,get:function(){return I}}),Object.defineProperty(exports,`f`,{enumerable:!0,get:function(){return u}}),Object.defineProperty(exports,`h`,{enumerable:!0,get:function(){return o}}),Object.defineProperty(exports,`i`,{enumerable:!0,get:function(){return J}}),Object.defineProperty(exports,`l`,{enumerable:!0,get:function(){return L}}),Object.defineProperty(exports,`m`,{enumerable:!0,get:function(){return d}}),Object.defineProperty(exports,`n`,{enumerable:!0,get:function(){return X}}),Object.defineProperty(exports,`o`,{enumerable:!0,get:function(){return q}}),Object.defineProperty(exports,`p`,{enumerable:!0,get:function(){return f}}),Object.defineProperty(exports,`r`,{enumerable:!0,get:function(){return Z}}),Object.defineProperty(exports,`s`,{enumerable:!0,get:function(){return V}}),Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return Q}}),Object.defineProperty(exports,`u`,{enumerable:!0,get:function(){return R}});
|
|
2
2
|
//# sourceMappingURL=base-signer.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base-signer.cjs","names":["ZamaError","ZamaErrorCode","#generator","#storage","#ttl","#pending","#storage","#deleteScope","#untrackScope","#trackScope","#readIndex","#vault","#store","#relayer","#signer","#permitTTL","#signPermit","ZamaError","wrapSigningError","#map","IndexedDBStorage","ConfigurationError","#chains","#relayers","#workers","ConfigurationError","#chainId","#active","toError","mainnet","sepolia","hoodi","#addresses","#ttlMs","#cache","parseConfiguration","ConfigurationError","#getCached","getTokenPairsLengthContract","#setCached","getTokenPairsSliceContract","#pairWithMetadata","nameContract","symbolContract","decimalsContract","erc20TotalSupplyContract","getConfidentialTokenAddressContract","zeroAddress","getTokenAddressContract","getTokenPairsContract","getTokenPairContract","isConfidentialTokenValidContract","parseConfiguration","#listeners","#snapshot","#resolved","#emit","#disposed"],"sources":["../../src/errors/signer.ts","../../src/utils/swallow.ts","../../src/credentials/storage-keys.ts","../../src/schemas/primitives.ts","../../src/credentials/utils.ts","../../src/credentials/schemas.ts","../../src/credentials/keypair-vault.ts","../../src/credentials/permissions.ts","../../src/credentials/permission-store.ts","../../src/credentials/credential-service.ts","../../src/storage/memory-storage.ts","../../src/config/resolve.ts","../../src/relayer/relayer-dispatcher.ts","../../src/wrappers-registry.ts","../../src/config/build.ts","../../src/signer/wallet-account-store.ts","../../src/signer/base-signer.ts"],"sourcesContent":["import { ZamaError, ZamaErrorCode } from \"./base\";\n\n/**\n * Base class for signer/account readiness failures.\n */\nexport class SignerRequiredError extends ZamaError {\n readonly operation: string;\n\n constructor(code: ZamaErrorCode, operation: string, message: string, options?: ErrorOptions) {\n super(code, message, options);\n this.name = \"SignerRequiredError\";\n this.operation = operation;\n }\n}\n\n/**\n * Thrown when an operation requires a signer but none is configured.\n *\n * The SDK can be constructed without a signer. Operations that need wallet\n * authority throw this before probing wallet state.\n *\n * @example\n * ```ts\n * try {\n * await token.confidentialTransfer(\"0xTo\", 100n);\n * } catch (e) {\n * if (e instanceof SignerNotConfiguredError) {\n * // Fix SDK/provider configuration.\n * }\n * }\n * ```\n */\nexport class SignerNotConfiguredError extends SignerRequiredError {\n constructor(operation: string, options?: ErrorOptions) {\n super(\n ZamaErrorCode.SignerNotConfigured,\n operation,\n `Cannot ${operation} without a signer. Configure one via createConfig({ signer: ... }) or <ZamaProvider config={createConfig({ signer: ... })}>.`,\n options,\n );\n this.name = \"SignerNotConfiguredError\";\n }\n}\n\n/** Thrown when a signer exists but no wallet account is currently connected. */\nexport class WalletNotConnectedError extends SignerRequiredError {\n constructor(operation: string, options?: ErrorOptions) {\n super(\n ZamaErrorCode.WalletNotConnected,\n operation,\n `Cannot ${operation} without a connected wallet account.`,\n options,\n );\n this.name = \"WalletNotConnectedError\";\n }\n}\n\n/** Thrown when an async adapter has not resolved its initial wallet account yet. */\nexport class WalletAccountNotReadyError extends SignerRequiredError {\n constructor(operation: string, options?: ErrorOptions) {\n super(\n ZamaErrorCode.WalletAccountNotReady,\n operation,\n `Cannot ${operation} before the wallet account is ready.`,\n options,\n );\n this.name = \"WalletAccountNotReadyError\";\n }\n}\n","/**\n * Runs a function and swallows any errors.\n */\nexport async function swallow(label: string, fn: () => Promise<void> | void): Promise<void> {\n try {\n await fn();\n } catch (error) {\n // oxlint-disable-next-line no-console\n console.warn(`[zama-sdk] ${label} failed:`, error);\n }\n}\n","import type { ChecksummedAddress } from \"../schemas/primitives\";\n\nexport interface PermissionScope {\n signerAddress: ChecksummedAddress;\n chainId: number;\n delegatorAddress: ChecksummedAddress;\n}\n\nexport function keypairStorageKey(signerAddress: ChecksummedAddress): string {\n return `keypair:${signerAddress}`;\n}\n\nexport function permissionScopeKey(scope: PermissionScope): string {\n return `permits:${scope.signerAddress}:${scope.chainId}:${scope.delegatorAddress}`;\n}\n\nexport function permissionIndexKey(signerAddress: ChecksummedAddress): string {\n return `permits-index:${signerAddress}`;\n}\n","import { type Address, getAddress, isAddress, isHex, type Hex } from \"viem\";\nimport { z } from \"zod\";\n\ndeclare const checksummedTag: unique symbol;\n\n/** An EVM address that has been put through `getAddress` (EIP-55 checksum form). */\nexport type ChecksummedAddress = Address & { readonly [checksummedTag]: true };\n\n/** Stamp the brand on an arbitrary `Address` after normalizing it. */\nexport function checksum(value: Address): ChecksummedAddress {\n return getAddress(value) as ChecksummedAddress;\n}\n\n/** `0x`-prefixed hex string. */\nexport const hex = z\n .string()\n .refine((v): v is Hex => isHex(v, { strict: true }), \"expected 0x-prefixed hex string\");\n\n/** Validates an EVM address string. Output type is `Address` (`` `0x${string}` ``). */\nexport const evmAddress = z\n .string()\n .refine((v): v is Address => isAddress(v, { strict: false }), \"expected EVM address\");\n\n/** Validates and EIP-55 checksums an EVM address. Output is {@link ChecksummedAddress}. */\nexport const checksummedAddress = evmAddress.transform(checksum);\n\n/** Non-negative integer Unix timestamp in seconds. */\nexport const unixSeconds = z.number().int().nonnegative();\n\n/** Positive integer count of seconds (e.g. a TTL). */\nexport const positiveSeconds = z.number().int().positive();\n\n/** Non-negative integer count of seconds (e.g. a cache TTL where 0 disables caching). */\nexport const nonNegativeSeconds = z.number().int().nonnegative();\n\n/** Positive integer count of days (e.g. a permit duration). */\nexport const positiveDays = z.number().int().positive();\n\n/** Positive integer EVM chain ID. */\nexport const chainId = z.number().int().positive();\n","import type { Address } from \"viem\";\nimport { type ChecksummedAddress, checksum } from \"../schemas/primitives\";\nexport { checksum, type ChecksummedAddress };\n\n/** Maximum number of contract addresses a single permit may bind, enforced by the FHE protocol. */\nexport const MAX_CONTRACTS_PER_PERMIT = 10;\n\nexport const SECONDS_PER_DAY = 86400;\n\n/** Current Unix time in whole seconds. */\nexport function nowSeconds(): number {\n return Math.floor(Date.now() / 1000);\n}\n\n/** Deduplicate and sort a list of addresses by their checksummed form. */\nexport function normalizeAddresses(addresses: readonly Address[]): ChecksummedAddress[] {\n return [...new Set(addresses.map(checksum))].toSorted();\n}\n","import { z } from \"zod\";\nimport {\n checksummedAddress,\n chainId,\n hex,\n positiveDays,\n positiveSeconds,\n unixSeconds,\n} from \"../schemas/primitives\";\nimport { MAX_CONTRACTS_PER_PERMIT, SECONDS_PER_DAY } from \"./utils\";\n\nconst keypairTTLError = \"keypairTTL must be a positive integer number of seconds\";\nconst permitTTLError = \"permitTTL must be a positive integer number of days\";\n\n/** Maximum keypairTTL accepted by the fhevm ACL contract (365 days, in seconds). */\nexport const MAX_KEYPAIR_TTL_SECONDS = 365 * SECONDS_PER_DAY;\n\nexport const KeypairTTLSchema = z\n .number(keypairTTLError)\n .finite(keypairTTLError)\n .int(keypairTTLError)\n .positive(keypairTTLError)\n .max(\n MAX_KEYPAIR_TTL_SECONDS,\n `keypairTTL must not exceed the fhevm ACL maximum of ${MAX_KEYPAIR_TTL_SECONDS}s (365 days)`,\n );\n\nexport const PermitTTLSchema = z\n .number(permitTTLError)\n .finite(permitTTLError)\n .int(permitTTLError)\n .positive(permitTTLError);\n\nexport const StoredKeypairSchema = z.object({\n publicKey: hex,\n privateKey: hex,\n createdAt: unixSeconds,\n expiresAt: positiveSeconds,\n});\n\nexport const PermissionSchema = z.object({\n keypairPublicKey: hex,\n signerAddress: checksummedAddress,\n delegatorAddress: checksummedAddress,\n chainId,\n signedContractAddresses: z.array(checksummedAddress).max(MAX_CONTRACTS_PER_PERMIT),\n signature: hex,\n startTimestamp: unixSeconds,\n durationDays: positiveDays,\n});\n\nexport const PermissionListSchema = z.array(PermissionSchema);\n\nexport const ScopeIndexSchema = z.array(z.string());\n","import type { GenericStorage } from \"../types\";\nimport { swallow } from \"../utils/swallow\";\nimport { keypairStorageKey } from \"./storage-keys\";\nimport { StoredKeypairSchema } from \"./schemas\";\nimport type { Keypair, StoredKeypair } from \"./types\";\nimport type { ChecksummedAddress } from \"../schemas/primitives\";\nimport { nowSeconds } from \"./utils\";\n\ninterface KeypairVaultConfig {\n generator: () => Promise<Keypair>;\n storage: GenericStorage;\n /** Keypair lifetime in seconds. Pre-validated by the caller. */\n ttl: number;\n}\n\n/**\n * Identity-scoped, chain-independent vault for ML-KEM keypairs.\n *\n * One keypair per signer address; the keypair survives chain switches and\n * permit revocations. Storage entries are keyed only by the signer address.\n */\nexport class KeypairVault {\n readonly #generator: () => Promise<Keypair>;\n readonly #storage: GenericStorage;\n readonly #ttl: number;\n readonly #pending = new Map<ChecksummedAddress, Promise<StoredKeypair>>();\n\n constructor(config: KeypairVaultConfig) {\n this.#generator = config.generator;\n this.#storage = config.storage;\n this.#ttl = config.ttl;\n }\n\n async readStored(signerAddress: ChecksummedAddress): Promise<StoredKeypair | null> {\n const key = keypairStorageKey(signerAddress);\n const raw = await this.#storage.get(key);\n if (raw === null || raw === undefined) {\n return null;\n }\n const parsed = StoredKeypairSchema.safeParse(raw);\n if (!parsed.success) {\n await swallow(\"delete keypair entry\", () => this.#storage.delete(key));\n return null;\n }\n const stored = parsed.data;\n if (nowSeconds() >= stored.expiresAt) {\n await swallow(\"delete keypair entry\", () => this.#storage.delete(key));\n return null;\n }\n return stored;\n }\n\n /**\n * Return the cached keypair, generating and persisting a fresh one if absent or expired.\n *\n * @remarks Deduplicates concurrent calls — simultaneous requests share one generation promise.\n */\n async getOrCreate(signerAddress: ChecksummedAddress): Promise<StoredKeypair> {\n const existing = this.#pending.get(signerAddress);\n if (existing) {\n return existing;\n }\n\n const promise = (async () => {\n const cached = await this.readStored(signerAddress);\n if (cached !== null) {\n return cached;\n }\n const fresh = await this.#generator();\n const createdAt = nowSeconds();\n const stored: StoredKeypair = {\n publicKey: fresh.publicKey,\n privateKey: fresh.privateKey,\n createdAt,\n expiresAt: createdAt + this.#ttl,\n };\n const key = keypairStorageKey(signerAddress);\n await swallow(\"persist keypair\", () => this.#storage.set(key, stored));\n return stored;\n })().finally(() => {\n this.#pending.delete(signerAddress);\n });\n\n this.#pending.set(signerAddress, promise);\n return promise;\n }\n\n /** Delete the stored keypair for the given address. */\n async clear(signerAddress: ChecksummedAddress): Promise<void> {\n const key = keypairStorageKey(signerAddress);\n await swallow(\"delete keypair entry\", () => this.#storage.delete(key));\n }\n}\n","import type { Hex } from \"viem\";\nimport type { Permission } from \"./types\";\nimport type { ChecksummedAddress } from \"../schemas/primitives\";\nimport { MAX_CONTRACTS_PER_PERMIT, SECONDS_PER_DAY } from \"./utils\";\n\n/** Contracts in `requested` not covered by the signed payload of any permission. */\nexport function uncoveredContracts(\n permissions: readonly Permission[],\n requested: readonly ChecksummedAddress[],\n): ChecksummedAddress[] {\n const covered = new Set(permissions.flatMap((p) => p.signedContractAddresses));\n return requested.filter((addr) => !covered.has(addr));\n}\n\n/** Split a list of addresses into permit-sized chunks (≤ {@link MAX_CONTRACTS_PER_PERMIT}). */\nexport function chunkContracts(addresses: readonly ChecksummedAddress[]): ChecksummedAddress[][] {\n const chunks: ChecksummedAddress[][] = [];\n for (let i = 0; i < addresses.length; i += MAX_CONTRACTS_PER_PERMIT) {\n chunks.push(addresses.slice(i, i + MAX_CONTRACTS_PER_PERMIT));\n }\n return chunks;\n}\n\n/** Drop permissions that are time-expired or bound to a stale keypair. */\nexport function pruneUnusable(\n permissions: readonly Permission[],\n keypairPublicKey: Hex,\n nowSeconds: number,\n): Permission[] {\n return permissions.filter(\n (p) =>\n p.keypairPublicKey === keypairPublicKey &&\n nowSeconds < p.startTimestamp + p.durationDays * SECONDS_PER_DAY,\n );\n}\n\n/** Drop every permission whose signed payload touches any address in `contracts`. */\nexport function withoutPermitsTouching(\n permissions: readonly Permission[],\n contracts: readonly ChecksummedAddress[],\n): Permission[] {\n const removeSet = new Set(contracts);\n return permissions.filter((p) => !p.signedContractAddresses.some((a) => removeSet.has(a)));\n}\n","import type { Hex } from \"viem\";\nimport type { GenericStorage } from \"../types\";\nimport { swallow } from \"../utils/swallow\";\nimport { pruneUnusable, withoutPermitsTouching } from \"./permissions\";\nimport { PermissionListSchema, PermissionSchema, ScopeIndexSchema } from \"./schemas\";\nimport { permissionIndexKey, permissionScopeKey, type PermissionScope } from \"./storage-keys\";\nimport type { Permission } from \"./types\";\nimport type { ChecksummedAddress } from \"../schemas/primitives\";\n\nexport type { PermissionScope };\n\ninterface PermissionStoreConfig {\n storage: GenericStorage;\n}\n\n/**\n * Chain-scoped, 1-to-many store of EIP-712 permits.\n *\n * Permits are grouped by `(signerAddress, chainId, delegatorAddress)` so that\n * direct (`delegator === signer`) and delegated permits never collide. An\n * auxiliary per-signer index lists every scope so `clearAllForSigner` can\n * cascade across chains and delegators without enumerating storage keys.\n */\nexport class PermissionStore {\n readonly #storage: GenericStorage;\n\n constructor(config: PermissionStoreConfig) {\n this.#storage = config.storage;\n }\n\n /** Read all stored permissions for the given scope. Returns `[]` if none. */\n async list(scope: PermissionScope): Promise<Permission[]> {\n const key = permissionScopeKey(scope);\n const raw = await this.#storage.get(key);\n if (raw === null || raw === undefined) {\n return [];\n }\n const parsed = PermissionListSchema.safeParse(raw);\n if (!parsed.success) {\n await this.#deleteScope(key);\n await this.#untrackScope(scope);\n return [];\n }\n return parsed.data;\n }\n\n /**\n * Return permissions still live and bound to the current keypair.\n * Expired or stale-keypair permissions are pruned in one storage pass.\n */\n async listUsableAndPrune(scope: PermissionScope, keypairPublicKey: Hex): Promise<Permission[]> {\n const all = await this.list(scope);\n const usable = pruneUnusable(all, keypairPublicKey, Math.floor(Date.now() / 1000));\n\n if (usable.length !== all.length) {\n const key = permissionScopeKey(scope);\n if (usable.length === 0) {\n await this.#deleteScope(key);\n await this.#untrackScope(scope);\n } else {\n await swallow(\"update permit entry\", () => this.#storage.set(key, usable));\n }\n }\n return usable;\n }\n\n /**\n * Append signed permits to the given scope. Every permission is run through\n * `PermissionSchema` so the schema is the single normalization point for both\n * read and write paths. Signed payloads themselves are immutable and never\n * edited — only addresses and types are normalized.\n */\n async append(scope: PermissionScope, permissions: readonly Permission[]): Promise<void> {\n if (permissions.length === 0) {\n return;\n }\n const validated = permissions.map((p) => PermissionSchema.parse(p));\n const existing = await this.list(scope);\n await this.#storage.set(permissionScopeKey(scope), [...existing, ...validated]);\n await this.#trackScope(scope);\n }\n\n /**\n * Delete every permit whose signed payload touches any listed contract.\n *\n * The store never edits `signedContractAddresses`, because that field is part\n * of the EIP-712 payload covered by `signature`.\n */\n async deletePermitsTouching(\n scope: PermissionScope,\n contractsToRemove: ChecksummedAddress[],\n ): Promise<void> {\n const existing = await this.list(scope);\n if (existing.length === 0) {\n return;\n }\n const key = permissionScopeKey(scope);\n const next = withoutPermitsTouching(existing, contractsToRemove);\n if (next.length === 0) {\n await this.#deleteScope(key);\n await this.#untrackScope(scope);\n } else {\n await this.#storage.set(key, next);\n }\n }\n\n /**\n * Delete every permission for the given signer across all chains and delegators.\n * Uses the per-signer scope index to cascade without enumerating all storage keys.\n */\n async clearAllForSigner(signerAddress: ChecksummedAddress): Promise<void> {\n const indexKey = permissionIndexKey(signerAddress);\n const scopeKeys = await this.#readIndex(indexKey);\n await Promise.all(scopeKeys.map((k) => this.#deleteScope(k)));\n await swallow(\"delete permit index\", () => this.#storage.delete(indexKey));\n }\n\n async #readIndex(indexKey: string): Promise<string[]> {\n const raw = await this.#storage.get(indexKey);\n if (raw === null || raw === undefined) {\n return [];\n }\n const parsed = ScopeIndexSchema.safeParse(raw);\n if (!parsed.success) {\n await swallow(\"delete permit index\", () => this.#storage.delete(indexKey));\n return [];\n }\n return parsed.data;\n }\n\n async #trackScope(scope: PermissionScope): Promise<void> {\n const indexKey = permissionIndexKey(scope.signerAddress);\n const scopeKey = permissionScopeKey(scope);\n const list = await this.#readIndex(indexKey);\n if (list.includes(scopeKey)) {\n return;\n }\n await this.#storage.set(indexKey, [...list, scopeKey]);\n }\n\n async #untrackScope(scope: PermissionScope): Promise<void> {\n const indexKey = permissionIndexKey(scope.signerAddress);\n const scopeKey = permissionScopeKey(scope);\n const list = await this.#readIndex(indexKey);\n const next = list.filter((entry) => entry !== scopeKey);\n if (next.length === list.length) {\n return;\n }\n if (next.length === 0) {\n await swallow(\"delete permit index\", () => this.#storage.delete(indexKey));\n } else {\n await swallow(\"update permit index\", () => this.#storage.set(indexKey, next));\n }\n }\n\n async #deleteScope(scopeKey: string): Promise<void> {\n await swallow(\"delete permit entry\", () => this.#storage.delete(scopeKey));\n }\n}\n","import type { Address } from \"viem\";\nimport type { GenericSigner, GenericStorage } from \"../types\";\nimport type { RelayerDispatcher } from \"../relayer/relayer-dispatcher\";\nimport { ZamaError } from \"../errors/base\";\nimport { wrapSigningError } from \"../errors/signing\";\nimport { swallow } from \"../utils/swallow\";\nimport { KeypairVault } from \"./keypair-vault\";\nimport { chunkContracts, uncoveredContracts } from \"./permissions\";\nimport { PermissionStore } from \"./permission-store\";\nimport type { PermissionScope } from \"./storage-keys\";\nimport type { CredentialBundle, Permission, StoredKeypair } from \"./types\";\nimport type { ChecksummedAddress } from \"../schemas/primitives\";\nimport { checksum } from \"../schemas/primitives\";\nimport { normalizeAddresses, nowSeconds, SECONDS_PER_DAY } from \"./utils\";\n\nexport const DEFAULT_KEYPAIR_TTL_SECONDS = 30 * SECONDS_PER_DAY;\nexport const DEFAULT_PERMIT_DURATION_DAYS = 30;\n\n/** Configuration for {@link CredentialService}. TTLs are pre-validated by the caller. */\nexport interface CredentialServiceConfig {\n relayer: RelayerDispatcher;\n signer: GenericSigner;\n /** Keypair lifetime in seconds. Pre-validated. */\n keypairTTL: number;\n /** Permit lifetime in days. Pre-validated. */\n permitTTL: number;\n /** Backing storage for keypairs (and permits if `permitStorage` is omitted). */\n storage: GenericStorage;\n /** Optional dedicated storage for permits; defaults to `storage`. */\n permitStorage?: GenericStorage;\n}\n\n/**\n * Single facade coordinating the keypair vault and the permission store.\n *\n * `CredentialService` is the only credentials object held by `ZamaSDK`. It accepts identity\n * transitions via `handleWalletAccountChange`.\n */\nexport class CredentialService {\n readonly #vault: KeypairVault;\n readonly #store: PermissionStore;\n readonly #relayer: RelayerDispatcher;\n readonly #signer: GenericSigner;\n readonly #permitTTL: number;\n\n constructor(config: CredentialServiceConfig) {\n this.#vault = new KeypairVault({\n generator: () => config.relayer.generateKeypair(),\n storage: config.storage,\n ttl: config.keypairTTL,\n });\n this.#store = new PermissionStore({\n storage: config.permitStorage ?? config.storage,\n });\n this.#relayer = config.relayer;\n this.#signer = config.signer;\n this.#permitTTL = config.permitTTL;\n }\n\n /**\n * Resolve a keypair and the permissions covering `contracts`.\n *\n * Passing an empty contract list warms the keypair without creating signed\n * permits.\n *\n * If existing permissions already cover the requested set, no wallet prompt\n * occurs. Otherwise the uncovered subset is chunked into groups of ≤10 and\n * one permit per chunk is signed sequentially. Each signed chunk is persisted\n * before the next prompt, and newly signed permits are returned in-memory even\n * when best-effort persistence fails.\n *\n * @returns The resolved keypair and permits covering the requested contracts.\n * @throws {@link SigningRejectedError} if the user rejects a wallet signature prompt.\n * @throws {@link SigningFailedError} if signing fails for any other reason.\n */\n async allow(contracts: readonly Address[], delegator?: Address): Promise<CredentialBundle> {\n const account = this.#signer.requireWalletAccount(\"allow\");\n const signerAddress = checksum(account.address);\n const requested = normalizeAddresses(contracts);\n const keypair = await this.#vault.getOrCreate(signerAddress);\n if (requested.length === 0) {\n return { keypair, permits: [] };\n }\n\n const chainId = account.chainId;\n const scope: PermissionScope = {\n signerAddress,\n chainId,\n delegatorAddress: delegator ? checksum(delegator) : signerAddress,\n };\n const permits = await this.#store.listUsableAndPrune(scope, keypair.publicKey);\n\n for (const chunk of chunkContracts(uncoveredContracts(permits, requested))) {\n const permission = await this.#signPermit({ chunk, keypair, scope });\n permits.push(permission);\n await swallow(\"persist permit\", () => this.#store.append(scope, [permission]));\n }\n\n const requestedSet = new Set(requested);\n return {\n keypair,\n permits: permits.filter((p) => p.signedContractAddresses.some((a) => requestedSet.has(a))),\n };\n }\n\n /**\n * Pure store lookup: are stored permits sufficient to cover `contracts`? No wallet prompt.\n *\n * @returns `true` if cached permits cover all requested contracts (vacuously\n * true for an empty list); `false` if no keypair exists or coverage is\n * incomplete.\n */\n async isAllowed(contracts: readonly Address[], delegator?: Address): Promise<boolean> {\n if (contracts.length === 0) {\n return true;\n }\n const account = this.#signer.walletAccount.getSnapshot();\n if (!account) {\n return false;\n }\n const signerAddress = checksum(account.address);\n const keypair = await this.#vault.readStored(signerAddress);\n if (keypair === null) {\n return false;\n }\n const chainId = account.chainId;\n const delegatorAddress = delegator ? checksum(delegator) : signerAddress;\n const scope: PermissionScope = { signerAddress, chainId, delegatorAddress };\n const permits = await this.#store.listUsableAndPrune(scope, keypair.publicKey);\n return uncoveredContracts(permits, normalizeAddresses(contracts)).length === 0;\n }\n\n /**\n * Wipe FHE permits for the current signer.\n *\n * - With no argument: every permit referencing this signer is removed across\n * all chains and delegators. The keypair survives — use\n * {@link clearCredentials} to also wipe the keypair.\n * - With a contract list: every signed permit in the direct-decrypt scope\n * (current chain) whose immutable payload touches any listed address is\n * removed. Delegated permits are not touched in this mode.\n *\n * @throws {@link SigningFailedError} if reading the signer address fails.\n */\n async revokePermits(contracts?: readonly Address[]): Promise<void> {\n const account = this.#signer.requireWalletAccount(\"revokePermits\");\n const signerAddress = checksum(account.address);\n if (contracts === undefined) {\n await this.#store.clearAllForSigner(signerAddress);\n return;\n }\n const normalized = normalizeAddresses(contracts);\n if (normalized.length === 0) {\n return;\n }\n const chainId = account.chainId;\n await this.#store.deletePermitsTouching(\n { signerAddress, chainId, delegatorAddress: signerAddress },\n normalized,\n );\n }\n\n /**\n * Wipe the keypair for the current signer and cascade-delete every\n * permission referencing it across all chains and delegators.\n *\n * @throws {@link SigningFailedError} if reading the signer address fails.\n */\n async clearCredentials(): Promise<void> {\n const account = this.#signer.requireWalletAccount(\"clearCredentials\");\n const signerAddress = checksum(account.address);\n await this.#vault.clear(signerAddress);\n await this.#store.clearAllForSigner(signerAddress);\n }\n\n /**\n * Apply a wallet account transition.\n *\n * Address change clears persisted credentials for the previous account and\n * eagerly warms a keypair for the new one so the first decrypt does not stall\n * on key generation. Chain-only changes keep credentials intact because\n * permits are chain-scoped already and stale decrypt plaintext is cleared by\n * `ZamaSDK`.\n */\n async handleWalletAccountChange(\n prev?: { address: Address },\n next?: { address: Address },\n ): Promise<void> {\n const prevAddr = prev ? checksum(prev.address) : undefined;\n const nextAddr = next ? checksum(next.address) : undefined;\n if (prevAddr === nextAddr) {\n return;\n }\n if (prevAddr) {\n await this.#vault.clear(prevAddr);\n await this.#store.clearAllForSigner(prevAddr);\n }\n if (nextAddr) {\n await swallow(\"warm keypair\", async () => {\n await this.#vault.getOrCreate(nextAddr);\n });\n }\n }\n\n async #signPermit(input: {\n chunk: ChecksummedAddress[];\n keypair: StoredKeypair;\n scope: PermissionScope;\n }): Promise<Permission> {\n const { chunk, keypair, scope } = input;\n const startTimestamp = nowSeconds();\n const isDelegated = scope.delegatorAddress !== scope.signerAddress;\n\n try {\n const eip712 = isDelegated\n ? await this.#relayer.createDelegatedUserDecryptEIP712(\n keypair.publicKey,\n chunk,\n scope.delegatorAddress,\n startTimestamp,\n this.#permitTTL,\n )\n : await this.#relayer.createEIP712(\n keypair.publicKey,\n chunk,\n startTimestamp,\n this.#permitTTL,\n );\n\n const signature = await this.#signer.signTypedData(eip712);\n\n return {\n keypairPublicKey: keypair.publicKey,\n signerAddress: scope.signerAddress,\n delegatorAddress: scope.delegatorAddress,\n chainId: scope.chainId,\n signedContractAddresses: chunk,\n signature,\n startTimestamp,\n durationDays: this.#permitTTL,\n };\n } catch (error) {\n if (error instanceof ZamaError) {\n throw error;\n }\n throw wrapSigningError(error, \"Credential signing failed\");\n }\n }\n}\n","import type { GenericStorage } from \"../types\";\n\n/** In-memory credential store. Credentials are lost on page reload. */\nexport class MemoryStorage implements GenericStorage {\n #map = new Map<string, unknown>();\n\n async get<T = unknown>(key: string): Promise<T | null> {\n return (this.#map.get(key) as T) ?? null;\n }\n\n async set<T = unknown>(key: string, value: T): Promise<void> {\n this.#map.set(key, value);\n }\n\n async delete(key: string): Promise<void> {\n this.#map.delete(key);\n }\n}\n\n/** Default singleton for application-wide use. */\nexport const memoryStorage = new MemoryStorage();\n","import type { FheChain } from \"../chains\";\nimport { ConfigurationError } from \"../errors\";\nimport { IndexedDBStorage } from \"../storage/indexeddb-storage\";\nimport { MemoryStorage } from \"../storage/memory-storage\";\nimport type { GenericStorage } from \"../types\";\nimport type { RelayerConfig } from \"./types\";\n\n// ── Storage defaults ─────────────────────────────────────────────────────────\n\nfunction getDefaultStorage(): GenericStorage {\n return typeof window !== \"undefined\"\n ? new IndexedDBStorage(\"CredentialStore\")\n : new MemoryStorage();\n}\n\nexport function resolveStorage(\n storage: GenericStorage | undefined = getDefaultStorage(),\n permitStorage: GenericStorage | undefined = storage,\n): { storage: GenericStorage; permitStorage: GenericStorage } {\n return { storage, permitStorage };\n}\n\n// ── Chain relayer resolution ────────────────────────────────────────────────\n\nexport interface ResolvedChainRelayer {\n chain: FheChain;\n relayer: RelayerConfig;\n}\n\nexport function resolveChainRelayers(\n chains: readonly FheChain[],\n relayers: Readonly<Record<number, RelayerConfig>>,\n): Map<number, ResolvedChainRelayer> {\n const chainMap = new Map(chains.map((c) => [c.id, c]));\n if (chainMap.size !== chains.length) {\n const ids = chains.map((c) => c.id);\n const dupes = [...new Set(ids.filter((id, i) => ids.indexOf(id) !== i))];\n throw new ConfigurationError(\n `Duplicate chain id(s) [${dupes.join(\", \")}] in the chains array. ` +\n `Each chain id must appear only once. Note: hardhat and anvil are aliases (both use 31337).`,\n );\n }\n const relayerMap = new Map(Object.entries(relayers));\n const result = new Map<number, ResolvedChainRelayer>();\n\n for (const id of chainMap.keys()) {\n const chainConfig = chainMap.get(id);\n const relayerConfig = relayerMap.get(String(id));\n\n if (!relayerConfig) {\n throw new ConfigurationError(\n `Chain ${id} has no relayer configured. ` +\n `Add a relayer entry: relayers: { [${id}]: web() }`,\n );\n }\n\n if (!chainConfig) {\n throw new ConfigurationError(\n `Chain ${id} has a relayer configured but no entry in the chains array. ` +\n `Add the chain config to the chains array.`,\n );\n }\n\n result.set(id, {\n chain: chainConfig,\n relayer: relayerConfig,\n });\n }\n\n const relayerIdSet = new Set(Object.keys(relayers).map(Number));\n const orphaned = new Set([...relayerIdSet].filter((id) => !chainMap.has(id)));\n if (orphaned.size > 0) {\n throw new ConfigurationError(\n `Relayer entries for chain(s) [${[...orphaned].join(\", \")}] have no matching entry ` +\n `in the chains array. Remove them or add the corresponding chain config.`,\n );\n }\n\n return result;\n}\n","import type {\n InputProofBytesType,\n KeypairType,\n KmsDelegatedUserDecryptEIP712Type,\n ZKProofLike,\n} from \"@zama-fhe/relayer-sdk/bundle\";\nimport type { Address, Hex } from \"viem\";\nimport type { FheChain } from \"../chains/types\";\nimport type { RelayerConfig } from \"../config/types\";\nimport { resolveChainRelayers } from \"../config/resolve\";\nimport { ConfigurationError } from \"../errors\";\nimport { assertNonNullable, toError } from \"../utils\";\nimport type { RelayerSDK } from \"./relayer-sdk\";\nimport type {\n ClearValueType,\n DelegatedUserDecryptParams,\n EIP712TypedData,\n EncryptParams,\n EncryptResult,\n Handle,\n PublicDecryptResult,\n PublicKeyData,\n PublicParamsData,\n UserDecryptParams,\n} from \"./relayer-sdk.types\";\n\n/** Anything with a synchronous `terminate()` method (workers, pools). */\nexport interface WorkerLike {\n terminate(): void;\n}\n\n/**\n * Owns chain management (chains / activeChain / switchChain) and delegates\n * every {@link RelayerSDK} operation to the relayer for the currently active\n * chain.\n *\n * Groups chains by relayer config reference identity, calls `createWorker`\n * once per group with all chain configs, then calls `createRelayer`\n * per chain with the shared worker.\n *\n * Workers/pools are held separately from relayers so the dispatcher can\n * terminate them directly — relayers never own worker lifecycle.\n */\nexport class RelayerDispatcher implements RelayerSDK, Disposable {\n readonly #chains: Map<number, FheChain>;\n readonly #relayers: Map<number, RelayerSDK>;\n readonly #workers: readonly WorkerLike[];\n #chainId: number;\n\n constructor(\n chains: readonly [FheChain, ...FheChain[]],\n configs: Readonly<Record<number, RelayerConfig>>,\n ) {\n if (chains.length === 0) {\n throw new ConfigurationError(\"At least one chain is required.\");\n }\n this.#chains = new Map(chains.map((c) => [c.id, c]));\n this.#chainId = chains[0].id;\n\n const chainRelayers = resolveChainRelayers(chains, configs);\n\n // Group chains by relayer config reference — same object = same group = shared worker.\n const groups = new Map<RelayerConfig, Array<[number, FheChain]>>();\n for (const [chainId, config] of chainRelayers) {\n const key = config.relayer;\n let group = groups.get(key);\n if (!group) {\n group = [];\n groups.set(key, group);\n }\n group.push([chainId, config.chain]);\n }\n\n // For each group: create shared worker once, then create per-chain relayers.\n const relayers = new Map<number, RelayerSDK>();\n const workers: WorkerLike[] = [];\n try {\n for (const [relayerCfg, groupChains] of groups) {\n const allChainConfigs = groupChains.map(([, chain]) => chain);\n const worker = relayerCfg.createWorker?.(allChainConfigs);\n if (worker) {\n workers.push(worker);\n }\n for (const [chainId, chain] of groupChains) {\n relayers.set(chainId, relayerCfg.createRelayer(chain, worker));\n }\n }\n } catch (error) {\n for (const w of workers) {\n try {\n w.terminate();\n } catch {\n /* best-effort cleanup */\n }\n }\n throw error;\n }\n\n this.#relayers = relayers;\n this.#workers = workers;\n }\n\n get chains(): readonly FheChain[] {\n return [...this.#chains.values()];\n }\n\n get chain(): FheChain {\n const chain = this.#chains.get(this.#chainId);\n assertNonNullable(chain, \"RelayerDispatcher: chain\");\n return chain;\n }\n\n switchChain(chainId: number): void {\n if (!this.#chains.has(chainId)) {\n throw new ConfigurationError(\n `No relayer configured for chain ${chainId}. Add it to the chains array.`,\n );\n }\n this.#chainId = chainId;\n }\n\n get #active(): RelayerSDK {\n const relayer = this.#relayers.get(this.#chainId);\n assertNonNullable(relayer, \"RelayerDispatcher: relayer\");\n return relayer;\n }\n\n generateKeypair(): Promise<KeypairType<Hex>> {\n return this.#active.generateKeypair();\n }\n\n createEIP712(\n publicKey: Hex,\n contractAddresses: Address[],\n startTimestamp: number,\n durationDays?: number,\n ): Promise<EIP712TypedData> {\n return this.#active.createEIP712(publicKey, contractAddresses, startTimestamp, durationDays);\n }\n\n encrypt(params: EncryptParams): Promise<EncryptResult> {\n return this.#active.encrypt(params);\n }\n\n userDecrypt(params: UserDecryptParams): Promise<Readonly<Record<Handle, ClearValueType>>> {\n return this.#active.userDecrypt(params);\n }\n\n publicDecrypt(handles: Handle[]): Promise<PublicDecryptResult> {\n return this.#active.publicDecrypt(handles);\n }\n\n createDelegatedUserDecryptEIP712(\n publicKey: Hex,\n contractAddresses: Address[],\n delegatorAddress: Address,\n startTimestamp: number,\n durationDays?: number,\n ): Promise<KmsDelegatedUserDecryptEIP712Type> {\n return this.#active.createDelegatedUserDecryptEIP712(\n publicKey,\n contractAddresses,\n delegatorAddress,\n startTimestamp,\n durationDays,\n );\n }\n\n delegatedUserDecrypt(\n params: DelegatedUserDecryptParams,\n ): Promise<Readonly<Record<Handle, ClearValueType>>> {\n return this.#active.delegatedUserDecrypt(params);\n }\n\n requestZKProofVerification(zkProof: ZKProofLike): Promise<InputProofBytesType> {\n return this.#active.requestZKProofVerification(zkProof);\n }\n\n getPublicKey(): Promise<PublicKeyData | null> {\n return this.#active.getPublicKey();\n }\n\n getPublicParams(bits: number): Promise<PublicParamsData | null> {\n return this.#active.getPublicParams(bits);\n }\n\n getAclAddress(): Promise<Address> {\n return this.#active.getAclAddress();\n }\n\n terminate(): void {\n const errors: Error[] = [];\n\n // Clean up relayer-owned caches (no worker termination).\n for (const r of new Set(this.#relayers.values())) {\n try {\n r.terminate();\n } catch (e) {\n errors.push(toError(e));\n }\n }\n\n // Terminate the actual workers/pools (deduplicated).\n for (const w of new Set(this.#workers)) {\n try {\n w.terminate();\n } catch (e) {\n errors.push(toError(e));\n }\n }\n\n if (errors.length > 0) {\n throw new AggregateError(errors, \"Failed to terminate relayer resources\");\n }\n }\n\n [Symbol.dispose](): void {\n this.terminate();\n }\n}\n","import { type Address, getAddress, zeroAddress } from \"viem\";\nimport { z } from \"zod\";\nimport type { TokenWrapperPairWithMetadata, PaginatedResult, TokenWrapperPair } from \"./contracts\";\nimport {\n decimalsContract,\n erc20TotalSupplyContract,\n getConfidentialTokenAddressContract,\n getTokenAddressContract,\n getTokenPairContract,\n getTokenPairsContract,\n getTokenPairsLengthContract,\n getTokenPairsSliceContract,\n isConfidentialTokenValidContract,\n nameContract,\n symbolContract,\n} from \"./contracts\";\nimport { ConfigurationError } from \"./errors/relayer\";\nimport { mainnet, sepolia, hoodi } from \"./chains\";\nimport { checksummedAddress, nonNegativeSeconds } from \"./schemas/primitives\";\nimport type { GenericProvider } from \"./types/provider\";\nimport { parseConfiguration } from \"./validation\";\n\n/**\n * Default wrappers registry addresses for known chains.\n * Only includes chains where a registry is deployed (excludes Hardhat).\n */\nexport const DefaultRegistryAddresses: Record<number, Address> = {\n [mainnet.id]: mainnet.registryAddress,\n [sepolia.id]: sepolia.registryAddress,\n [hoodi.id]: hoodi.registryAddress,\n};\n\n/** Default registry TTL in seconds (24 hours). */\nexport const DEFAULT_REGISTRY_TTL_SECONDS = 86_400;\n\n/** Per-chain wrappers-registry address overrides. */\nexport const RegistryAddressesSchema = z.record(\n z.string().regex(/^\\d+$/, \"expected numeric chain id key\"),\n checksummedAddress,\n);\n\n/** TTL (seconds) for cached registry results. `0` means entries expire immediately. */\nexport const RegistryTTLSchema = nonNegativeSeconds;\n\n/** Default page size for {@link WrappersRegistry.listPairs}. */\nconst DEFAULT_PAGE_SIZE = 100;\n\n/** Configuration for {@link WrappersRegistry}. */\nexport interface WrappersRegistryConfig {\n /** Read-only chain provider used for every registry lookup. */\n provider: GenericProvider;\n /**\n * Per-chain registry address overrides, merged on top of\n * {@link DefaultRegistryAddresses}. Use this to supply a registry\n * address for custom or local chains (e.g. Hardhat).\n *\n * @example\n * ```ts\n * new WrappersRegistry({\n * provider,\n * registryAddresses: { [31337]: \"0xYourHardhatRegistry\" },\n * });\n * ```\n */\n registryAddresses?: Record<number, Address>;\n /**\n * How long cached registry results remain valid, in seconds.\n * Default: `86400` (24 hours).\n */\n registryTTL?: number;\n}\n\n/** Options for {@link WrappersRegistry.listPairs}. */\nexport interface ListPairsOptions {\n /** Page number (1-indexed). Default: `1`. */\n page?: number;\n /** Number of items per page. Default: `100`. */\n pageSize?: number;\n /**\n * When `true`, fetches on-chain metadata (name, symbol, decimals) for both\n * the ERC-20 and confidential token, plus totalSupply for the ERC-20.\n * Default: `false`.\n */\n metadata?: boolean;\n}\n\n/** Shorter TTL for negative lookups (5 minutes) so newly registered tokens are discoverable quickly. */\nconst NEGATIVE_CACHE_TTL_MS = 5 * 60 * 1000;\n\n/** Cache entry with expiry timestamp. */\ninterface CacheEntry<T> {\n data: T;\n expiresAt: number;\n}\n\n/**\n * High-level interface for the on-chain token wrappers registry.\n *\n * Uses the configured {@link GenericProvider} to resolve the correct registry\n * contract address for the current chain and exposes typed read helpers for\n * every registry query. Results are cached in memory with a configurable TTL\n * (default 24 hours).\n *\n * @example\n * ```ts\n * const registry = new WrappersRegistry({ provider });\n *\n * // Paginated listing\n * const page1 = await registry.listPairs({ page: 1, pageSize: 20 });\n *\n * // Structured lookups\n * const result = await registry.getConfidentialToken(erc20Address);\n * if (result) console.log(result.confidentialTokenAddress);\n *\n * // Force refresh\n * registry.refresh();\n * ```\n */\nexport class WrappersRegistry {\n readonly provider: GenericProvider;\n readonly #addresses: Record<number, Address>;\n readonly #ttlMs: number;\n readonly #cache = new Map<string, CacheEntry<unknown>>();\n\n constructor(config: WrappersRegistryConfig) {\n this.provider = config.provider;\n this.#addresses = Object.assign(\n {},\n DefaultRegistryAddresses,\n parseConfiguration(RegistryAddressesSchema.optional(), config.registryAddresses),\n );\n this.#ttlMs =\n parseConfiguration(RegistryTTLSchema, config.registryTTL ?? DEFAULT_REGISTRY_TTL_SECONDS) *\n 1000;\n }\n\n /**\n * Synchronous lookup of the registry address for a given chain ID.\n * Returns `undefined` if no address is configured for that chain.\n */\n getAddress(chainId: number): Address | undefined {\n return this.#addresses[chainId];\n }\n\n // ---------------------------------------------------------------------------\n // Cache helpers\n // ---------------------------------------------------------------------------\n\n #getCached<T>(key: string): T | undefined {\n const entry = this.#cache.get(key);\n if (!entry) {\n return undefined;\n }\n if (Date.now() >= entry.expiresAt) {\n this.#cache.delete(key);\n return undefined;\n }\n return entry.data as T;\n }\n\n #setCached<T>(key: string, data: T, ttlMs = this.#ttlMs): T {\n this.#cache.set(key, {\n data,\n expiresAt: Date.now() + ttlMs,\n });\n return data;\n }\n\n /**\n * Force-invalidate the in-memory cache. The next call to any read method\n * will fetch fresh data from the chain.\n */\n refresh(): void {\n this.#cache.clear();\n }\n\n /**\n * The cache TTL in milliseconds.\n * Exposed so query option factories can set a matching `staleTime`.\n */\n get ttlMs(): number {\n return this.#ttlMs;\n }\n\n // ---------------------------------------------------------------------------\n // Registry address resolution\n // ---------------------------------------------------------------------------\n\n /**\n * Resolve the registry contract address for the current chain.\n *\n * Priority: `registryAddresses[chainId]` \\> built-in default.\n *\n * @returns The registry contract address for the connected chain.\n * @throws {@link ConfigurationError} if no address is configured for the chain.\n */\n async getRegistryAddress(): Promise<Address> {\n const chainId = await this.provider.getChainId();\n const address = this.#addresses[chainId];\n\n if (!address) {\n throw new ConfigurationError(\n `No wrappers registry address configured for chain ${chainId}.\\n` +\n `Pass a registryAddresses entry for this chain.`,\n );\n }\n\n return getAddress(address);\n }\n\n // ---------------------------------------------------------------------------\n // Paginated listing\n // ---------------------------------------------------------------------------\n\n /**\n * List token wrapper pairs with page-based pagination.\n *\n * Internally maps to `getTokenConfidentialTokenPairsSlice` on-chain.\n *\n * @param options - Pagination and enrichment options.\n * @returns A {@link PaginatedResult} of pairs.\n *\n * @example\n * ```ts\n * const result = await registry.listPairs({ page: 1, pageSize: 20 });\n * console.log(`${result.total} pairs, showing page ${result.page}`);\n *\n * // With on-chain metadata\n * const withMeta = await registry.listPairs({ metadata: true, pageSize: 10 });\n * for (const pair of withMeta.items) {\n * console.log(pair.underlying.symbol, \"→\", pair.confidential.symbol);\n * }\n * ```\n */\n async listPairs(\n options: ListPairsOptions & { metadata: true },\n ): Promise<PaginatedResult<TokenWrapperPairWithMetadata>>;\n async listPairs(options?: ListPairsOptions): Promise<PaginatedResult<TokenWrapperPair>>;\n async listPairs(\n options: ListPairsOptions = {},\n ): Promise<PaginatedResult<TokenWrapperPair | TokenWrapperPairWithMetadata>> {\n const page = options.page ?? 1;\n const pageSize = options.pageSize ?? DEFAULT_PAGE_SIZE;\n const metadata = options.metadata ?? false;\n\n if (page < 1) {\n throw new ConfigurationError(`page must be >= 1, got ${page}`);\n }\n if (pageSize < 1) {\n throw new ConfigurationError(`pageSize must be >= 1, got ${pageSize}`);\n }\n\n const registry = await this.getRegistryAddress();\n\n // Fetch total (cached)\n const totalCacheKey = `total:${registry}`;\n let total = this.#getCached<number>(totalCacheKey);\n if (total === undefined) {\n const raw = await this.provider.readContract(getTokenPairsLengthContract(registry));\n total = this.#setCached(totalCacheKey, Number(raw));\n }\n\n // Compute slice indices, clamping toIndex to total\n const fromIndex = BigInt((page - 1) * pageSize);\n const clampedToIndex =\n fromIndex + BigInt(pageSize) > BigInt(total) ? BigInt(total) : fromIndex + BigInt(pageSize);\n\n // Page beyond total — return empty\n if (fromIndex >= BigInt(total)) {\n return { items: [], total, page, pageSize };\n }\n\n // Fetch slice (cached)\n const sliceCacheKey = `slice:${registry}:${fromIndex}:${clampedToIndex}`;\n let items = this.#getCached<TokenWrapperPair[]>(sliceCacheKey);\n if (items === undefined) {\n const raw = await this.provider.readContract(\n getTokenPairsSliceContract(registry, fromIndex, clampedToIndex),\n );\n items = this.#setCached(sliceCacheKey, [...raw]);\n }\n\n if (!metadata) {\n return { items, total, page, pageSize };\n }\n\n // Enrich with on-chain metadata (resilient — individual failures don't break the batch)\n const metadataCacheKey = `metadata:${registry}:${fromIndex}:${clampedToIndex}`;\n let metadataItems = this.#getCached<TokenWrapperPairWithMetadata[]>(metadataCacheKey);\n if (metadataItems === undefined) {\n const settled = await Promise.allSettled(items.map((pair) => this.#pairWithMetadata(pair)));\n const hasFailures = settled.some((r) => r.status === \"rejected\");\n const enriched = settled.map((result, i) =>\n result.status === \"fulfilled\"\n ? result.value\n : Object.assign({}, items[i], {\n metadataFailed: true as const,\n underlying: {\n name: \"Unknown\",\n symbol: \"???\",\n decimals: 0,\n totalSupply: 0n,\n },\n confidential: { name: \"Unknown\", symbol: \"???\", decimals: 0 },\n }),\n );\n // Use negative cache TTL when any metadata fetch failed so retries happen sooner\n metadataItems = this.#setCached(\n metadataCacheKey,\n enriched,\n hasFailures ? NEGATIVE_CACHE_TTL_MS : undefined,\n );\n }\n\n return { items: metadataItems, total, page, pageSize };\n }\n\n async #pairWithMetadata(pair: TokenWrapperPair): Promise<TokenWrapperPairWithMetadata> {\n const [uName, uSymbol, uDecimals, uTotalSupply, cName, cSymbol, cDecimals] = await Promise.all([\n this.provider.readContract(nameContract(pair.tokenAddress)),\n this.provider.readContract(symbolContract(pair.tokenAddress)),\n this.provider.readContract(decimalsContract(pair.tokenAddress)),\n this.provider.readContract(erc20TotalSupplyContract(pair.tokenAddress)),\n this.provider.readContract(nameContract(pair.confidentialTokenAddress)),\n this.provider.readContract(symbolContract(pair.confidentialTokenAddress)),\n this.provider.readContract(decimalsContract(pair.confidentialTokenAddress)),\n ]);\n\n return {\n ...pair,\n underlying: {\n name: uName,\n symbol: uSymbol,\n decimals: uDecimals,\n totalSupply: uTotalSupply,\n },\n confidential: { name: cName, symbol: cSymbol, decimals: cDecimals },\n };\n }\n\n // ---------------------------------------------------------------------------\n // Structured single-pair lookups\n // ---------------------------------------------------------------------------\n\n /**\n * Look up the confidential token for a given plain ERC-20 address.\n *\n * @param tokenAddress - The plain ERC-20 token address.\n * @returns The lookup result, or `null` if the token has never been registered.\n * **Note:** revoked tokens (registered then invalidated) return a non-null result\n * with `isValid: false`. Check `result.isValid` explicitly rather than using\n * `if (result)` to guard against processing revoked tokens.\n *\n * @example\n * ```ts\n * const result = await registry.getConfidentialToken(usdcAddress);\n * if (result?.isValid) {\n * console.log(result.confidentialTokenAddress);\n * }\n * ```\n */\n async getConfidentialToken(\n tokenAddress: Address,\n ): Promise<{ confidentialTokenAddress: Address; isValid: boolean } | null> {\n const registry = await this.getRegistryAddress();\n const normalized = getAddress(tokenAddress);\n\n const cacheKey = `ct:${registry}:${normalized}`;\n const cached = this.#getCached<{\n confidentialTokenAddress: Address;\n isValid: boolean;\n } | null>(cacheKey);\n if (cached !== undefined) {\n return cached;\n }\n\n const [isValid, confidentialTokenAddress] = await this.provider.readContract(\n getConfidentialTokenAddressContract(registry, normalized),\n );\n\n // Zero address means the token is not registered at all (never seen by the registry).\n // A non-zero address with isValid=false means it was registered but later revoked.\n if (confidentialTokenAddress === zeroAddress) {\n return this.#setCached(cacheKey, null, NEGATIVE_CACHE_TTL_MS);\n }\n\n return this.#setCached(cacheKey, { confidentialTokenAddress, isValid });\n }\n\n /**\n * Reverse lookup — find the plain ERC-20 for a given confidential token.\n *\n * @param confidentialTokenAddress - The confidential token address.\n * @returns The lookup result, or `null` if no pair is registered.\n *\n * @example\n * ```ts\n * const result = await registry.getUnderlyingToken(cUsdcAddress);\n * if (result) {\n * console.log(result.tokenAddress, result.isValid);\n * }\n * ```\n */\n async getUnderlyingToken(\n confidentialTokenAddress: Address,\n ): Promise<{ tokenAddress: Address; isValid: boolean } | null> {\n const registry = await this.getRegistryAddress();\n const normalized = getAddress(confidentialTokenAddress);\n\n const cacheKey = `ut:${registry}:${normalized}`;\n const cached = this.#getCached<{\n tokenAddress: Address;\n isValid: boolean;\n } | null>(cacheKey);\n if (cached !== undefined) {\n return cached;\n }\n\n const [isValid, tokenAddress] = await this.provider.readContract(\n getTokenAddressContract(registry, normalized),\n );\n\n // Zero address means the confidential token is not registered at all.\n // A non-zero address with isValid=false means it was registered but later revoked.\n if (tokenAddress === zeroAddress) {\n return this.#setCached(cacheKey, null, NEGATIVE_CACHE_TTL_MS);\n }\n\n return this.#setCached(cacheKey, { tokenAddress, isValid });\n }\n\n // ---------------------------------------------------------------------------\n // Low-level pass-through methods (backward compatible)\n // ---------------------------------------------------------------------------\n\n /**\n * Fetch all token wrapper pairs from the registry.\n *\n * @returns All registered `TokenWrapperPair` entries.\n */\n async getTokenPairs(): Promise<readonly TokenWrapperPair[]> {\n const registry = await this.getRegistryAddress();\n return this.provider.readContract(getTokenPairsContract(registry));\n }\n\n /**\n * Get the total number of token wrapper pairs.\n *\n * @returns The count as a bigint.\n */\n async getTokenPairsLength(): Promise<bigint> {\n const registry = await this.getRegistryAddress();\n return this.provider.readContract(getTokenPairsLengthContract(registry));\n }\n\n /**\n * Fetch a range of token wrapper pairs (paginated by index).\n *\n * @param fromIndex - Start index (inclusive).\n * @param toIndex - End index (exclusive).\n * @returns The slice of `TokenWrapperPair` entries.\n */\n async getTokenPairsSlice(\n fromIndex: bigint,\n toIndex: bigint,\n ): Promise<readonly TokenWrapperPair[]> {\n const registry = await this.getRegistryAddress();\n return this.provider.readContract(getTokenPairsSliceContract(registry, fromIndex, toIndex));\n }\n\n /**\n * Fetch a single token wrapper pair by index.\n *\n * @param index - Zero-based pair index.\n * @returns The `TokenWrapperPair` at that index.\n */\n async getTokenPair(index: bigint): Promise<TokenWrapperPair> {\n const registry = await this.getRegistryAddress();\n return this.provider.readContract(getTokenPairContract(registry, index));\n }\n\n /**\n * Look up the confidential token address for a given plain ERC-20 token.\n *\n * @param tokenAddress - The plain ERC-20 token address.\n * @returns A tuple `[isValid, confidentialTokenAddress]`. `isValid` is `true` only for a\n * registered, non-revoked wrapper. The address is the zero address when no pair is registered.\n * A non-zero address with `isValid=false` means the wrapper was registered but later revoked.\n */\n async getConfidentialTokenAddress(tokenAddress: Address): Promise<readonly [boolean, Address]> {\n const registry = await this.getRegistryAddress();\n return this.provider.readContract(\n getConfidentialTokenAddressContract(registry, getAddress(tokenAddress)),\n );\n }\n\n /**\n * Reverse lookup — find the plain ERC-20 for a given confidential token.\n *\n * @param confidentialTokenAddress - The confidential token address.\n * @returns A tuple `[isValid, tokenAddress]`. `isValid` is `true` only for a registered,\n * non-revoked wrapper. The address is the zero address when no pair is registered.\n * A non-zero address with `isValid=false` means the wrapper was registered but later revoked.\n */\n async getTokenAddress(confidentialTokenAddress: Address): Promise<readonly [boolean, Address]> {\n const registry = await this.getRegistryAddress();\n return this.provider.readContract(\n getTokenAddressContract(registry, getAddress(confidentialTokenAddress)),\n );\n }\n\n /**\n * Check whether a confidential token is registered and valid.\n *\n * @param confidentialTokenAddress - The confidential token address to check.\n * @returns `true` if the token is a known valid wrapper in the registry.\n */\n async isConfidentialTokenValid(confidentialTokenAddress: Address): Promise<boolean> {\n const registry = await this.getRegistryAddress();\n return this.provider.readContract(\n isConfidentialTokenValidContract(registry, getAddress(confidentialTokenAddress)),\n );\n }\n}\n","import {\n DEFAULT_KEYPAIR_TTL_SECONDS,\n DEFAULT_PERMIT_DURATION_DAYS,\n} from \"../credentials/credential-service\";\nimport { KeypairTTLSchema, PermitTTLSchema } from \"../credentials/schemas\";\nimport { RelayerDispatcher } from \"../relayer/relayer-dispatcher\";\nimport type { GenericProvider, GenericSigner } from \"../types\";\nimport { DEFAULT_REGISTRY_TTL_SECONDS, RegistryTTLSchema } from \"../wrappers-registry\";\nimport { parseConfiguration } from \"../validation\";\nimport { resolveStorage } from \"./resolve\";\nimport type { ZamaConfig, ZamaConfigBase } from \"./types\";\n\n/**\n * @internal Shared config builder — not part of the public API.\n *\n * Applies defaults, validates TTLs, and resolves storage so the\n * returned config is fully populated and ready for `ZamaSDK`.\n */\nexport function buildZamaConfig(\n signer: GenericSigner | undefined,\n provider: GenericProvider,\n params: ZamaConfigBase,\n): ZamaConfig {\n const { storage, permitStorage } = resolveStorage(params.storage, params.permitStorage);\n const relayer = new RelayerDispatcher(params.chains, params.relayers);\n\n return {\n chains: params.chains,\n relayer,\n provider,\n signer,\n storage,\n permitStorage,\n keypairTTL: parseConfiguration(\n KeypairTTLSchema,\n params.keypairTTL ?? DEFAULT_KEYPAIR_TTL_SECONDS,\n ),\n permitTTL: parseConfiguration(\n PermitTTLSchema,\n params.permitTTL ?? DEFAULT_PERMIT_DURATION_DAYS,\n ),\n registryTTL: parseConfiguration(\n RegistryTTLSchema,\n params.registryTTL ?? DEFAULT_REGISTRY_TTL_SECONDS,\n ),\n onEvent: params.onEvent,\n } as unknown as ZamaConfig;\n}\n","import type {\n WalletAccount,\n WalletAccountChange,\n WalletAccountListener,\n WalletAccountStore,\n} from \"../types\";\n\nexport function walletAccountsEqual(\n a: WalletAccount | undefined,\n b: WalletAccount | undefined,\n): boolean {\n return a?.address === b?.address && a?.chainId === b?.chainId;\n}\n\n/**\n * Writable {@link WalletAccountStore} for custom signer adapters. Adapters call\n * {@link MutableWalletAccountStore.setSnapshot} when their underlying wallet\n * provider notifies of a connect, disconnect, account change, or chain change.\n *\n * Most custom adapters should use the {@link createWalletAccountStore} factory\n * rather than instantiating this class directly.\n */\nexport class MutableWalletAccountStore implements WalletAccountStore {\n readonly #listeners = new Set<WalletAccountListener>();\n #snapshot: WalletAccount | undefined;\n #resolved: boolean;\n\n constructor(initial?: WalletAccount) {\n this.#snapshot = initial;\n this.#resolved = initial !== undefined;\n }\n\n getSnapshot(): WalletAccount | undefined {\n return this.#snapshot;\n }\n\n /**\n * Whether the store has received at least one snapshot (via the constructor\n * or {@link setSnapshot}). Adapters whose initial account is only available\n * asynchronously start unresolved; callers can distinguish \"still loading\"\n * from \"wallet not connected\".\n */\n isReady(): boolean {\n return this.#resolved;\n }\n\n /**\n * Push a new wallet account snapshot. No-op when the next value is\n * value-equal to the current one. Emits `{ previous, next }` to every\n * subscriber otherwise.\n */\n setSnapshot(next: WalletAccount | undefined): void {\n this.#resolved = true;\n const previous = this.#snapshot;\n if (walletAccountsEqual(previous, next)) {\n return;\n }\n this.#snapshot = next;\n this.#emit({ previous, next });\n }\n\n subscribe(listener: WalletAccountListener): () => void {\n this.#listeners.add(listener);\n const snapshot = this.#snapshot;\n if (snapshot) {\n listener({ previous: undefined, next: snapshot });\n }\n return () => {\n this.#listeners.delete(listener);\n };\n }\n\n #emit(change: WalletAccountChange): void {\n for (const listener of this.#listeners) {\n listener(change);\n }\n }\n}\n\n/**\n * Create a {@link MutableWalletAccountStore} for a custom {@link GenericSigner}\n * adapter.\n *\n * @param initial - Optional initial wallet account snapshot.\n */\nexport function createWalletAccountStore(initial?: WalletAccount): MutableWalletAccountStore {\n return new MutableWalletAccountStore(initial);\n}\n","import type { Hex } from \"viem\";\nimport { WalletNotConnectedError } from \"../errors\";\nimport type { EIP712TypedData } from \"../relayer/relayer-sdk.types\";\nimport type {\n ContractAbi,\n GenericSigner,\n WalletAccount,\n WriteContractArgs,\n WriteContractConfig,\n WriteFunctionName,\n} from \"../types\";\nimport { MutableWalletAccountStore } from \"./wallet-account-store\";\n\n/**\n * Abstract base class that implements the shared {@link GenericSigner}\n * boilerplate: wallet-account store, `requireWalletAccount`, idempotent\n * `dispose` / `Disposable`. Subclasses provide `signTypedData`,\n * `writeContract`, and optionally override `onDispose` for cleanup.\n *\n * Using this class is optional — implementing {@link GenericSigner} directly\n * with {@link createWalletAccountStore} remains fully supported.\n */\nexport abstract class BaseSigner implements GenericSigner, Disposable {\n readonly walletAccount: MutableWalletAccountStore;\n #disposed = false;\n\n constructor(initial?: WalletAccount) {\n this.walletAccount = new MutableWalletAccountStore(initial);\n }\n\n requireWalletAccount(operation: string): WalletAccount {\n const account = this.walletAccount.getSnapshot();\n if (!account) {\n throw new WalletNotConnectedError(operation);\n }\n return account;\n }\n\n abstract signTypedData(typedData: EIP712TypedData): Promise<Hex>;\n\n abstract writeContract<\n const TAbi extends ContractAbi,\n TFunctionName extends WriteFunctionName<TAbi>,\n const TArgs extends WriteContractArgs<TAbi, TFunctionName>,\n >(config: WriteContractConfig<TAbi, TFunctionName, TArgs>): Promise<Hex>;\n\n dispose(): void {\n if (this.#disposed) {\n return;\n }\n this.#disposed = true;\n this.onDispose();\n }\n\n [Symbol.dispose](): void {\n this.dispose();\n }\n\n protected onDispose(): void {}\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"base-signer.cjs","names":["#generator","#storage","#ttl","#pending","#storage","#deleteScope","#untrackScope","#trackScope","#readIndex","#vault","#store","#relayer","#signer","#permitTTL","#signPermit","ZamaError","wrapSigningError","#map","IndexedDBStorage","ConfigurationError","#chains","#relayers","#workers","ConfigurationError","#chainId","#active","toError","mainnet","sepolia","hoodi","#addresses","#ttlMs","#cache","parseConfiguration","ConfigurationError","#getCached","getTokenPairsLengthContract","#setCached","getTokenPairsSliceContract","#pairWithMetadata","nameContract","symbolContract","decimalsContract","erc20TotalSupplyContract","getConfidentialTokenAddressContract","zeroAddress","getTokenAddressContract","getTokenPairsContract","getTokenPairContract","isConfidentialTokenValidContract","parseConfiguration","#listeners","#snapshot","#resolved","#emit","WalletNotConnectedError","#disposed"],"sources":["../../src/utils/swallow.ts","../../src/credentials/storage-keys.ts","../../src/schemas/primitives.ts","../../src/credentials/utils.ts","../../src/credentials/schemas.ts","../../src/credentials/keypair-vault.ts","../../src/credentials/permissions.ts","../../src/credentials/permission-store.ts","../../src/credentials/credential-service.ts","../../src/storage/memory-storage.ts","../../src/config/resolve.ts","../../src/relayer/relayer-dispatcher.ts","../../src/wrappers-registry.ts","../../src/config/build.ts","../../src/signer/wallet-account-store.ts","../../src/signer/base-signer.ts"],"sourcesContent":["/**\n * Runs a function and swallows any errors.\n */\nexport async function swallow(label: string, fn: () => Promise<void> | void): Promise<void> {\n try {\n await fn();\n } catch (error) {\n // oxlint-disable-next-line no-console\n console.warn(`[zama-sdk] ${label} failed:`, error);\n }\n}\n","import type { ChecksummedAddress } from \"../schemas/primitives\";\n\nexport interface PermissionScope {\n signerAddress: ChecksummedAddress;\n chainId: number;\n delegatorAddress: ChecksummedAddress;\n}\n\nexport function keypairStorageKey(signerAddress: ChecksummedAddress): string {\n return `keypair:${signerAddress}`;\n}\n\nexport function permissionScopeKey(scope: PermissionScope): string {\n return `permits:${scope.signerAddress}:${scope.chainId}:${scope.delegatorAddress}`;\n}\n\nexport function permissionIndexKey(signerAddress: ChecksummedAddress): string {\n return `permits-index:${signerAddress}`;\n}\n","import { type Address, getAddress, isAddress, isHex, type Hex } from \"viem\";\nimport { z } from \"zod\";\n\ndeclare const checksummedTag: unique symbol;\n\n/** An EVM address that has been put through `getAddress` (EIP-55 checksum form). */\nexport type ChecksummedAddress = Address & { readonly [checksummedTag]: true };\n\n/** Stamp the brand on an arbitrary `Address` after normalizing it. */\nexport function checksum(value: Address): ChecksummedAddress {\n return getAddress(value) as ChecksummedAddress;\n}\n\n/** `0x`-prefixed hex string. */\nexport const hex = z\n .string()\n .refine((v): v is Hex => isHex(v, { strict: true }), \"expected 0x-prefixed hex string\");\n\n/** Validates an EVM address string. Output type is `Address` (`` `0x${string}` ``). */\nexport const evmAddress = z\n .string()\n .refine((v): v is Address => isAddress(v, { strict: false }), \"expected EVM address\");\n\n/** Validates and EIP-55 checksums an EVM address. Output is {@link ChecksummedAddress}. */\nexport const checksummedAddress = evmAddress.transform(checksum);\n\n/** Non-negative integer Unix timestamp in seconds. */\nexport const unixSeconds = z.number().int().nonnegative();\n\n/** Positive integer count of seconds (e.g. a TTL). */\nexport const positiveSeconds = z.number().int().positive();\n\n/** Non-negative integer count of seconds (e.g. a cache TTL where 0 disables caching). */\nexport const nonNegativeSeconds = z.number().int().nonnegative();\n\n/** Positive integer count of days (e.g. a permit duration). */\nexport const positiveDays = z.number().int().positive();\n\n/** Positive integer EVM chain ID. */\nexport const chainId = z.number().int().positive();\n","import type { Address } from \"viem\";\nimport { type ChecksummedAddress, checksum } from \"../schemas/primitives\";\nexport { checksum, type ChecksummedAddress };\n\n/** Maximum number of contract addresses a single permit may bind, enforced by the FHE protocol. */\nexport const MAX_CONTRACTS_PER_PERMIT = 10;\n\nexport const SECONDS_PER_DAY = 86400;\n\n/** Current Unix time in whole seconds. */\nexport function nowSeconds(): number {\n return Math.floor(Date.now() / 1000);\n}\n\n/** Deduplicate and sort a list of addresses by their checksummed form. */\nexport function normalizeAddresses(addresses: readonly Address[]): ChecksummedAddress[] {\n return [...new Set(addresses.map(checksum))].toSorted();\n}\n","import { z } from \"zod\";\nimport {\n checksummedAddress,\n chainId,\n hex,\n positiveDays,\n positiveSeconds,\n unixSeconds,\n} from \"../schemas/primitives\";\nimport { MAX_CONTRACTS_PER_PERMIT, SECONDS_PER_DAY } from \"./utils\";\n\nconst keypairTTLError = \"keypairTTL must be a positive integer number of seconds\";\nconst permitTTLError = \"permitTTL must be a positive integer number of days\";\n\n/** Maximum keypairTTL accepted by the fhevm ACL contract (365 days, in seconds). */\nexport const MAX_KEYPAIR_TTL_SECONDS = 365 * SECONDS_PER_DAY;\n\nexport const KeypairTTLSchema = z\n .number(keypairTTLError)\n .finite(keypairTTLError)\n .int(keypairTTLError)\n .positive(keypairTTLError)\n .max(\n MAX_KEYPAIR_TTL_SECONDS,\n `keypairTTL must not exceed the fhevm ACL maximum of ${MAX_KEYPAIR_TTL_SECONDS}s (365 days)`,\n );\n\nexport const PermitTTLSchema = z\n .number(permitTTLError)\n .finite(permitTTLError)\n .int(permitTTLError)\n .positive(permitTTLError);\n\nexport const StoredKeypairSchema = z.object({\n publicKey: hex,\n privateKey: hex,\n createdAt: unixSeconds,\n expiresAt: positiveSeconds,\n});\n\nexport const PermissionSchema = z.object({\n keypairPublicKey: hex,\n signerAddress: checksummedAddress,\n delegatorAddress: checksummedAddress,\n chainId,\n signedContractAddresses: z.array(checksummedAddress).max(MAX_CONTRACTS_PER_PERMIT),\n signature: hex,\n startTimestamp: unixSeconds,\n durationDays: positiveDays,\n});\n\nexport const PermissionListSchema = z.array(PermissionSchema);\n\nexport const ScopeIndexSchema = z.array(z.string());\n","import type { GenericStorage } from \"../types\";\nimport { swallow } from \"../utils/swallow\";\nimport { keypairStorageKey } from \"./storage-keys\";\nimport { StoredKeypairSchema } from \"./schemas\";\nimport type { Keypair, StoredKeypair } from \"./types\";\nimport type { ChecksummedAddress } from \"../schemas/primitives\";\nimport { nowSeconds } from \"./utils\";\n\ninterface KeypairVaultConfig {\n generator: () => Promise<Keypair>;\n storage: GenericStorage;\n /** Keypair lifetime in seconds. Pre-validated by the caller. */\n ttl: number;\n}\n\n/**\n * Identity-scoped, chain-independent vault for ML-KEM keypairs.\n *\n * One keypair per signer address; the keypair survives chain switches and\n * permit revocations. Storage entries are keyed only by the signer address.\n */\nexport class KeypairVault {\n readonly #generator: () => Promise<Keypair>;\n readonly #storage: GenericStorage;\n readonly #ttl: number;\n readonly #pending = new Map<ChecksummedAddress, Promise<StoredKeypair>>();\n\n constructor(config: KeypairVaultConfig) {\n this.#generator = config.generator;\n this.#storage = config.storage;\n this.#ttl = config.ttl;\n }\n\n async readStored(signerAddress: ChecksummedAddress): Promise<StoredKeypair | null> {\n const key = keypairStorageKey(signerAddress);\n const raw = await this.#storage.get(key);\n if (raw === null || raw === undefined) {\n return null;\n }\n const parsed = StoredKeypairSchema.safeParse(raw);\n if (!parsed.success) {\n await swallow(\"delete keypair entry\", () => this.#storage.delete(key));\n return null;\n }\n const stored = parsed.data;\n if (nowSeconds() >= stored.expiresAt) {\n await swallow(\"delete keypair entry\", () => this.#storage.delete(key));\n return null;\n }\n return stored;\n }\n\n /**\n * Return the cached keypair, generating and persisting a fresh one if absent or expired.\n *\n * @remarks Deduplicates concurrent calls — simultaneous requests share one generation promise.\n */\n async getOrCreate(signerAddress: ChecksummedAddress): Promise<StoredKeypair> {\n const existing = this.#pending.get(signerAddress);\n if (existing) {\n return existing;\n }\n\n const promise = (async () => {\n const cached = await this.readStored(signerAddress);\n if (cached !== null) {\n return cached;\n }\n const fresh = await this.#generator();\n const createdAt = nowSeconds();\n const stored: StoredKeypair = {\n publicKey: fresh.publicKey,\n privateKey: fresh.privateKey,\n createdAt,\n expiresAt: createdAt + this.#ttl,\n };\n const key = keypairStorageKey(signerAddress);\n await swallow(\"persist keypair\", () => this.#storage.set(key, stored));\n return stored;\n })().finally(() => {\n this.#pending.delete(signerAddress);\n });\n\n this.#pending.set(signerAddress, promise);\n return promise;\n }\n\n /** Delete the stored keypair for the given address. */\n async clear(signerAddress: ChecksummedAddress): Promise<void> {\n const key = keypairStorageKey(signerAddress);\n await swallow(\"delete keypair entry\", () => this.#storage.delete(key));\n }\n}\n","import type { Hex } from \"viem\";\nimport type { Permission } from \"./types\";\nimport type { ChecksummedAddress } from \"../schemas/primitives\";\nimport { MAX_CONTRACTS_PER_PERMIT, SECONDS_PER_DAY } from \"./utils\";\n\n/** Contracts in `requested` not covered by the signed payload of any permission. */\nexport function uncoveredContracts(\n permissions: readonly Permission[],\n requested: readonly ChecksummedAddress[],\n): ChecksummedAddress[] {\n const covered = new Set(permissions.flatMap((p) => p.signedContractAddresses));\n return requested.filter((addr) => !covered.has(addr));\n}\n\n/** Split a list of addresses into permit-sized chunks (≤ {@link MAX_CONTRACTS_PER_PERMIT}). */\nexport function chunkContracts(addresses: readonly ChecksummedAddress[]): ChecksummedAddress[][] {\n const chunks: ChecksummedAddress[][] = [];\n for (let i = 0; i < addresses.length; i += MAX_CONTRACTS_PER_PERMIT) {\n chunks.push(addresses.slice(i, i + MAX_CONTRACTS_PER_PERMIT));\n }\n return chunks;\n}\n\n/** Drop permissions that are time-expired or bound to a stale keypair. */\nexport function pruneUnusable(\n permissions: readonly Permission[],\n keypairPublicKey: Hex,\n nowSeconds: number,\n): Permission[] {\n return permissions.filter(\n (p) =>\n p.keypairPublicKey === keypairPublicKey &&\n nowSeconds < p.startTimestamp + p.durationDays * SECONDS_PER_DAY,\n );\n}\n\n/** Drop every permission whose signed payload touches any address in `contracts`. */\nexport function withoutPermitsTouching(\n permissions: readonly Permission[],\n contracts: readonly ChecksummedAddress[],\n): Permission[] {\n const removeSet = new Set(contracts);\n return permissions.filter((p) => !p.signedContractAddresses.some((a) => removeSet.has(a)));\n}\n","import type { Hex } from \"viem\";\nimport type { GenericStorage } from \"../types\";\nimport { swallow } from \"../utils/swallow\";\nimport { pruneUnusable, withoutPermitsTouching } from \"./permissions\";\nimport { PermissionListSchema, PermissionSchema, ScopeIndexSchema } from \"./schemas\";\nimport { permissionIndexKey, permissionScopeKey, type PermissionScope } from \"./storage-keys\";\nimport type { Permission } from \"./types\";\nimport type { ChecksummedAddress } from \"../schemas/primitives\";\n\nexport type { PermissionScope };\n\ninterface PermissionStoreConfig {\n storage: GenericStorage;\n}\n\n/**\n * Chain-scoped, 1-to-many store of EIP-712 permits.\n *\n * Permits are grouped by `(signerAddress, chainId, delegatorAddress)` so that\n * direct (`delegator === signer`) and delegated permits never collide. An\n * auxiliary per-signer index lists every scope so `clearAllForSigner` can\n * cascade across chains and delegators without enumerating storage keys.\n */\nexport class PermissionStore {\n readonly #storage: GenericStorage;\n\n constructor(config: PermissionStoreConfig) {\n this.#storage = config.storage;\n }\n\n /** Read all stored permissions for the given scope. Returns `[]` if none. */\n async list(scope: PermissionScope): Promise<Permission[]> {\n const key = permissionScopeKey(scope);\n const raw = await this.#storage.get(key);\n if (raw === null || raw === undefined) {\n return [];\n }\n const parsed = PermissionListSchema.safeParse(raw);\n if (!parsed.success) {\n await this.#deleteScope(key);\n await this.#untrackScope(scope);\n return [];\n }\n return parsed.data;\n }\n\n /**\n * Return permissions still live and bound to the current keypair.\n * Expired or stale-keypair permissions are pruned in one storage pass.\n */\n async listUsableAndPrune(scope: PermissionScope, keypairPublicKey: Hex): Promise<Permission[]> {\n const all = await this.list(scope);\n const usable = pruneUnusable(all, keypairPublicKey, Math.floor(Date.now() / 1000));\n\n if (usable.length !== all.length) {\n const key = permissionScopeKey(scope);\n if (usable.length === 0) {\n await this.#deleteScope(key);\n await this.#untrackScope(scope);\n } else {\n await swallow(\"update permit entry\", () => this.#storage.set(key, usable));\n }\n }\n return usable;\n }\n\n /**\n * Append signed permits to the given scope. Every permission is run through\n * `PermissionSchema` so the schema is the single normalization point for both\n * read and write paths. Signed payloads themselves are immutable and never\n * edited — only addresses and types are normalized.\n */\n async append(scope: PermissionScope, permissions: readonly Permission[]): Promise<void> {\n if (permissions.length === 0) {\n return;\n }\n const validated = permissions.map((p) => PermissionSchema.parse(p));\n const existing = await this.list(scope);\n await this.#storage.set(permissionScopeKey(scope), [...existing, ...validated]);\n await this.#trackScope(scope);\n }\n\n /**\n * Delete every permit whose signed payload touches any listed contract.\n *\n * The store never edits `signedContractAddresses`, because that field is part\n * of the EIP-712 payload covered by `signature`.\n */\n async deletePermitsTouching(\n scope: PermissionScope,\n contractsToRemove: ChecksummedAddress[],\n ): Promise<void> {\n const existing = await this.list(scope);\n if (existing.length === 0) {\n return;\n }\n const key = permissionScopeKey(scope);\n const next = withoutPermitsTouching(existing, contractsToRemove);\n if (next.length === 0) {\n await this.#deleteScope(key);\n await this.#untrackScope(scope);\n } else {\n await this.#storage.set(key, next);\n }\n }\n\n /**\n * Delete every permission for the given signer across all chains and delegators.\n * Uses the per-signer scope index to cascade without enumerating all storage keys.\n */\n async clearAllForSigner(signerAddress: ChecksummedAddress): Promise<void> {\n const indexKey = permissionIndexKey(signerAddress);\n const scopeKeys = await this.#readIndex(indexKey);\n await Promise.all(scopeKeys.map((k) => this.#deleteScope(k)));\n await swallow(\"delete permit index\", () => this.#storage.delete(indexKey));\n }\n\n async #readIndex(indexKey: string): Promise<string[]> {\n const raw = await this.#storage.get(indexKey);\n if (raw === null || raw === undefined) {\n return [];\n }\n const parsed = ScopeIndexSchema.safeParse(raw);\n if (!parsed.success) {\n await swallow(\"delete permit index\", () => this.#storage.delete(indexKey));\n return [];\n }\n return parsed.data;\n }\n\n async #trackScope(scope: PermissionScope): Promise<void> {\n const indexKey = permissionIndexKey(scope.signerAddress);\n const scopeKey = permissionScopeKey(scope);\n const list = await this.#readIndex(indexKey);\n if (list.includes(scopeKey)) {\n return;\n }\n await this.#storage.set(indexKey, [...list, scopeKey]);\n }\n\n async #untrackScope(scope: PermissionScope): Promise<void> {\n const indexKey = permissionIndexKey(scope.signerAddress);\n const scopeKey = permissionScopeKey(scope);\n const list = await this.#readIndex(indexKey);\n const next = list.filter((entry) => entry !== scopeKey);\n if (next.length === list.length) {\n return;\n }\n if (next.length === 0) {\n await swallow(\"delete permit index\", () => this.#storage.delete(indexKey));\n } else {\n await swallow(\"update permit index\", () => this.#storage.set(indexKey, next));\n }\n }\n\n async #deleteScope(scopeKey: string): Promise<void> {\n await swallow(\"delete permit entry\", () => this.#storage.delete(scopeKey));\n }\n}\n","import type { Address } from \"viem\";\nimport type { GenericSigner, GenericStorage } from \"../types\";\nimport type { RelayerDispatcher } from \"../relayer/relayer-dispatcher\";\nimport { ZamaError } from \"../errors/base\";\nimport { wrapSigningError } from \"../errors/signing\";\nimport { swallow } from \"../utils/swallow\";\nimport { KeypairVault } from \"./keypair-vault\";\nimport { chunkContracts, uncoveredContracts } from \"./permissions\";\nimport { PermissionStore } from \"./permission-store\";\nimport type { PermissionScope } from \"./storage-keys\";\nimport type { CredentialBundle, Permission, StoredKeypair } from \"./types\";\nimport type { ChecksummedAddress } from \"../schemas/primitives\";\nimport { checksum } from \"../schemas/primitives\";\nimport { normalizeAddresses, nowSeconds, SECONDS_PER_DAY } from \"./utils\";\n\nexport const DEFAULT_KEYPAIR_TTL_SECONDS = 30 * SECONDS_PER_DAY;\nexport const DEFAULT_PERMIT_DURATION_DAYS = 30;\n\n/** Configuration for {@link CredentialService}. TTLs are pre-validated by the caller. */\nexport interface CredentialServiceConfig {\n relayer: RelayerDispatcher;\n signer: GenericSigner;\n /** Keypair lifetime in seconds. Pre-validated. */\n keypairTTL: number;\n /** Permit lifetime in days. Pre-validated. */\n permitTTL: number;\n /** Backing storage for keypairs (and permits if `permitStorage` is omitted). */\n storage: GenericStorage;\n /** Optional dedicated storage for permits; defaults to `storage`. */\n permitStorage?: GenericStorage;\n}\n\n/**\n * Single facade coordinating the keypair vault and the permission store.\n *\n * `CredentialService` is the only credentials object held by `ZamaSDK`. It accepts identity\n * transitions via `handleWalletAccountChange`.\n */\nexport class CredentialService {\n readonly #vault: KeypairVault;\n readonly #store: PermissionStore;\n readonly #relayer: RelayerDispatcher;\n readonly #signer: GenericSigner;\n readonly #permitTTL: number;\n\n constructor(config: CredentialServiceConfig) {\n this.#vault = new KeypairVault({\n generator: () => config.relayer.generateKeypair(),\n storage: config.storage,\n ttl: config.keypairTTL,\n });\n this.#store = new PermissionStore({\n storage: config.permitStorage ?? config.storage,\n });\n this.#relayer = config.relayer;\n this.#signer = config.signer;\n this.#permitTTL = config.permitTTL;\n }\n\n /**\n * Resolve a keypair and the permissions covering `contracts`.\n *\n * Passing an empty contract list warms the keypair without creating signed\n * permits.\n *\n * If existing permissions already cover the requested set, no wallet prompt\n * occurs. Otherwise the uncovered subset is chunked into groups of ≤10 and\n * one permit per chunk is signed sequentially. Each signed chunk is persisted\n * before the next prompt, and newly signed permits are returned in-memory even\n * when best-effort persistence fails.\n *\n * @returns The resolved keypair and permits covering the requested contracts.\n * @throws {@link SigningRejectedError} if the user rejects a wallet signature prompt.\n * @throws {@link SigningFailedError} if signing fails for any other reason.\n */\n async allow(contracts: readonly Address[], delegator?: Address): Promise<CredentialBundle> {\n const account = this.#signer.requireWalletAccount(\"allow\");\n const signerAddress = checksum(account.address);\n const requested = normalizeAddresses(contracts);\n const keypair = await this.#vault.getOrCreate(signerAddress);\n if (requested.length === 0) {\n return { keypair, permits: [] };\n }\n\n const chainId = account.chainId;\n const scope: PermissionScope = {\n signerAddress,\n chainId,\n delegatorAddress: delegator ? checksum(delegator) : signerAddress,\n };\n const permits = await this.#store.listUsableAndPrune(scope, keypair.publicKey);\n\n for (const chunk of chunkContracts(uncoveredContracts(permits, requested))) {\n const permission = await this.#signPermit({ chunk, keypair, scope });\n permits.push(permission);\n await swallow(\"persist permit\", () => this.#store.append(scope, [permission]));\n }\n\n const requestedSet = new Set(requested);\n return {\n keypair,\n permits: permits.filter((p) => p.signedContractAddresses.some((a) => requestedSet.has(a))),\n };\n }\n\n /**\n * Pure store lookup: are stored permits sufficient to cover `contracts`? No wallet prompt.\n *\n * @returns `true` if cached permits cover all requested contracts (vacuously\n * true for an empty list); `false` if no keypair exists or coverage is\n * incomplete.\n */\n async isAllowed(contracts: readonly Address[], delegator?: Address): Promise<boolean> {\n if (contracts.length === 0) {\n return true;\n }\n const account = this.#signer.walletAccount.getSnapshot();\n if (!account) {\n return false;\n }\n const signerAddress = checksum(account.address);\n const keypair = await this.#vault.readStored(signerAddress);\n if (keypair === null) {\n return false;\n }\n const chainId = account.chainId;\n const delegatorAddress = delegator ? checksum(delegator) : signerAddress;\n const scope: PermissionScope = { signerAddress, chainId, delegatorAddress };\n const permits = await this.#store.listUsableAndPrune(scope, keypair.publicKey);\n return uncoveredContracts(permits, normalizeAddresses(contracts)).length === 0;\n }\n\n /**\n * Wipe FHE permits for the current signer.\n *\n * - With no argument: every permit referencing this signer is removed across\n * all chains and delegators. The keypair survives — use\n * {@link clearCredentials} to also wipe the keypair.\n * - With a contract list: every signed permit in the direct-decrypt scope\n * (current chain) whose immutable payload touches any listed address is\n * removed. Delegated permits are not touched in this mode.\n *\n * @throws {@link SigningFailedError} if reading the signer address fails.\n */\n async revokePermits(contracts?: readonly Address[]): Promise<void> {\n const account = this.#signer.requireWalletAccount(\"revokePermits\");\n const signerAddress = checksum(account.address);\n if (contracts === undefined) {\n await this.#store.clearAllForSigner(signerAddress);\n return;\n }\n const normalized = normalizeAddresses(contracts);\n if (normalized.length === 0) {\n return;\n }\n const chainId = account.chainId;\n await this.#store.deletePermitsTouching(\n { signerAddress, chainId, delegatorAddress: signerAddress },\n normalized,\n );\n }\n\n /**\n * Wipe the keypair for the current signer and cascade-delete every\n * permission referencing it across all chains and delegators.\n *\n * @throws {@link SigningFailedError} if reading the signer address fails.\n */\n async clearCredentials(): Promise<void> {\n const account = this.#signer.requireWalletAccount(\"clearCredentials\");\n const signerAddress = checksum(account.address);\n await this.#vault.clear(signerAddress);\n await this.#store.clearAllForSigner(signerAddress);\n }\n\n /**\n * Apply a wallet account transition.\n *\n * Address change clears persisted credentials for the previous account and\n * eagerly warms a keypair for the new one so the first decrypt does not stall\n * on key generation. Chain-only changes keep credentials intact because\n * permits are chain-scoped already and stale decrypt plaintext is cleared by\n * `ZamaSDK`.\n */\n async handleWalletAccountChange(\n prev?: { address: Address },\n next?: { address: Address },\n ): Promise<void> {\n const prevAddr = prev ? checksum(prev.address) : undefined;\n const nextAddr = next ? checksum(next.address) : undefined;\n if (prevAddr === nextAddr) {\n return;\n }\n if (prevAddr) {\n await this.#vault.clear(prevAddr);\n await this.#store.clearAllForSigner(prevAddr);\n }\n if (nextAddr) {\n await swallow(\"warm keypair\", async () => {\n await this.#vault.getOrCreate(nextAddr);\n });\n }\n }\n\n async #signPermit(input: {\n chunk: ChecksummedAddress[];\n keypair: StoredKeypair;\n scope: PermissionScope;\n }): Promise<Permission> {\n const { chunk, keypair, scope } = input;\n const startTimestamp = nowSeconds();\n const isDelegated = scope.delegatorAddress !== scope.signerAddress;\n\n try {\n const eip712 = isDelegated\n ? await this.#relayer.createDelegatedUserDecryptEIP712(\n keypair.publicKey,\n chunk,\n scope.delegatorAddress,\n startTimestamp,\n this.#permitTTL,\n )\n : await this.#relayer.createEIP712(\n keypair.publicKey,\n chunk,\n startTimestamp,\n this.#permitTTL,\n );\n\n const signature = await this.#signer.signTypedData(eip712);\n\n return {\n keypairPublicKey: keypair.publicKey,\n signerAddress: scope.signerAddress,\n delegatorAddress: scope.delegatorAddress,\n chainId: scope.chainId,\n signedContractAddresses: chunk,\n signature,\n startTimestamp,\n durationDays: this.#permitTTL,\n };\n } catch (error) {\n if (error instanceof ZamaError) {\n throw error;\n }\n throw wrapSigningError(error, \"Credential signing failed\");\n }\n }\n}\n","import type { GenericStorage } from \"../types\";\n\n/** In-memory credential store. Credentials are lost on page reload. */\nexport class MemoryStorage implements GenericStorage {\n #map = new Map<string, unknown>();\n\n async get<T = unknown>(key: string): Promise<T | null> {\n return (this.#map.get(key) as T) ?? null;\n }\n\n async set<T = unknown>(key: string, value: T): Promise<void> {\n this.#map.set(key, value);\n }\n\n async delete(key: string): Promise<void> {\n this.#map.delete(key);\n }\n}\n\n/** Default singleton for application-wide use. */\nexport const memoryStorage = new MemoryStorage();\n","import type { FheChain } from \"../chains\";\nimport { ConfigurationError } from \"../errors\";\nimport { IndexedDBStorage } from \"../storage/indexeddb-storage\";\nimport { MemoryStorage } from \"../storage/memory-storage\";\nimport type { GenericStorage } from \"../types\";\nimport type { RelayerConfig } from \"./types\";\n\n// ── Storage defaults ─────────────────────────────────────────────────────────\n\nfunction getDefaultStorage(): GenericStorage {\n return typeof window !== \"undefined\"\n ? new IndexedDBStorage(\"CredentialStore\")\n : new MemoryStorage();\n}\n\nexport function resolveStorage(\n storage: GenericStorage | undefined = getDefaultStorage(),\n permitStorage: GenericStorage | undefined = storage,\n): { storage: GenericStorage; permitStorage: GenericStorage } {\n return { storage, permitStorage };\n}\n\n// ── Chain relayer resolution ────────────────────────────────────────────────\n\nexport interface ResolvedChainRelayer {\n chain: FheChain;\n relayer: RelayerConfig;\n}\n\nexport function resolveChainRelayers(\n chains: readonly FheChain[],\n relayers: Readonly<Record<number, RelayerConfig>>,\n): Map<number, ResolvedChainRelayer> {\n const chainMap = new Map(chains.map((c) => [c.id, c]));\n if (chainMap.size !== chains.length) {\n const ids = chains.map((c) => c.id);\n const dupes = [...new Set(ids.filter((id, i) => ids.indexOf(id) !== i))];\n throw new ConfigurationError(\n `Duplicate chain id(s) [${dupes.join(\", \")}] in the chains array. ` +\n `Each chain id must appear only once. Note: hardhat and anvil are aliases (both use 31337).`,\n );\n }\n const relayerMap = new Map(Object.entries(relayers));\n const result = new Map<number, ResolvedChainRelayer>();\n\n for (const id of chainMap.keys()) {\n const chainConfig = chainMap.get(id);\n const relayerConfig = relayerMap.get(String(id));\n\n if (!relayerConfig) {\n throw new ConfigurationError(\n `Chain ${id} has no relayer configured. ` +\n `Add a relayer entry: relayers: { [${id}]: web() }`,\n );\n }\n\n if (!chainConfig) {\n throw new ConfigurationError(\n `Chain ${id} has a relayer configured but no entry in the chains array. ` +\n `Add the chain config to the chains array.`,\n );\n }\n\n result.set(id, {\n chain: chainConfig,\n relayer: relayerConfig,\n });\n }\n\n const relayerIdSet = new Set(Object.keys(relayers).map(Number));\n const orphaned = new Set([...relayerIdSet].filter((id) => !chainMap.has(id)));\n if (orphaned.size > 0) {\n throw new ConfigurationError(\n `Relayer entries for chain(s) [${[...orphaned].join(\", \")}] have no matching entry ` +\n `in the chains array. Remove them or add the corresponding chain config.`,\n );\n }\n\n return result;\n}\n","import type {\n InputProofBytesType,\n KeypairType,\n KmsDelegatedUserDecryptEIP712Type,\n ZKProofLike,\n} from \"@zama-fhe/relayer-sdk/bundle\";\nimport type { Address, Hex } from \"viem\";\nimport type { FheChain } from \"../chains/types\";\nimport type { RelayerConfig } from \"../config/types\";\nimport { resolveChainRelayers } from \"../config/resolve\";\nimport { ConfigurationError } from \"../errors\";\nimport { assertNonNullable, toError } from \"../utils\";\nimport type { RelayerSDK } from \"./relayer-sdk\";\nimport type {\n ClearValueType,\n DelegatedUserDecryptParams,\n EIP712TypedData,\n EncryptParams,\n EncryptResult,\n Handle,\n PublicDecryptResult,\n PublicKeyData,\n PublicParamsData,\n UserDecryptParams,\n} from \"./relayer-sdk.types\";\n\n/** Anything with a synchronous `terminate()` method (workers, pools). */\nexport interface WorkerLike {\n terminate(): void;\n}\n\n/**\n * Owns chain management (chains / activeChain / switchChain) and delegates\n * every {@link RelayerSDK} operation to the relayer for the currently active\n * chain.\n *\n * Groups chains by relayer config reference identity, calls `createWorker`\n * once per group with all chain configs, then calls `createRelayer`\n * per chain with the shared worker.\n *\n * Workers/pools are held separately from relayers so the dispatcher can\n * terminate them directly — relayers never own worker lifecycle.\n */\nexport class RelayerDispatcher implements RelayerSDK, Disposable {\n readonly #chains: Map<number, FheChain>;\n readonly #relayers: Map<number, RelayerSDK>;\n readonly #workers: readonly WorkerLike[];\n #chainId: number;\n\n constructor(\n chains: readonly [FheChain, ...FheChain[]],\n configs: Readonly<Record<number, RelayerConfig>>,\n ) {\n if (chains.length === 0) {\n throw new ConfigurationError(\"At least one chain is required.\");\n }\n this.#chains = new Map(chains.map((c) => [c.id, c]));\n this.#chainId = chains[0].id;\n\n const chainRelayers = resolveChainRelayers(chains, configs);\n\n // Group chains by relayer config reference — same object = same group = shared worker.\n const groups = new Map<RelayerConfig, Array<[number, FheChain]>>();\n for (const [chainId, config] of chainRelayers) {\n const key = config.relayer;\n let group = groups.get(key);\n if (!group) {\n group = [];\n groups.set(key, group);\n }\n group.push([chainId, config.chain]);\n }\n\n // For each group: create shared worker once, then create per-chain relayers.\n const relayers = new Map<number, RelayerSDK>();\n const workers: WorkerLike[] = [];\n try {\n for (const [relayerCfg, groupChains] of groups) {\n const allChainConfigs = groupChains.map(([, chain]) => chain);\n const worker = relayerCfg.createWorker?.(allChainConfigs);\n if (worker) {\n workers.push(worker);\n }\n for (const [chainId, chain] of groupChains) {\n relayers.set(chainId, relayerCfg.createRelayer(chain, worker));\n }\n }\n } catch (error) {\n for (const w of workers) {\n try {\n w.terminate();\n } catch {\n /* best-effort cleanup */\n }\n }\n throw error;\n }\n\n this.#relayers = relayers;\n this.#workers = workers;\n }\n\n get chains(): readonly FheChain[] {\n return [...this.#chains.values()];\n }\n\n get chain(): FheChain {\n const chain = this.#chains.get(this.#chainId);\n assertNonNullable(chain, \"RelayerDispatcher: chain\");\n return chain;\n }\n\n switchChain(chainId: number): void {\n if (!this.#chains.has(chainId)) {\n throw new ConfigurationError(\n `No relayer configured for chain ${chainId}. Add it to the chains array.`,\n );\n }\n this.#chainId = chainId;\n }\n\n get #active(): RelayerSDK {\n const relayer = this.#relayers.get(this.#chainId);\n assertNonNullable(relayer, \"RelayerDispatcher: relayer\");\n return relayer;\n }\n\n generateKeypair(): Promise<KeypairType<Hex>> {\n return this.#active.generateKeypair();\n }\n\n createEIP712(\n publicKey: Hex,\n contractAddresses: Address[],\n startTimestamp: number,\n durationDays?: number,\n ): Promise<EIP712TypedData> {\n return this.#active.createEIP712(publicKey, contractAddresses, startTimestamp, durationDays);\n }\n\n encrypt(params: EncryptParams): Promise<EncryptResult> {\n return this.#active.encrypt(params);\n }\n\n userDecrypt(params: UserDecryptParams): Promise<Readonly<Record<Handle, ClearValueType>>> {\n return this.#active.userDecrypt(params);\n }\n\n publicDecrypt(handles: Handle[]): Promise<PublicDecryptResult> {\n return this.#active.publicDecrypt(handles);\n }\n\n createDelegatedUserDecryptEIP712(\n publicKey: Hex,\n contractAddresses: Address[],\n delegatorAddress: Address,\n startTimestamp: number,\n durationDays?: number,\n ): Promise<KmsDelegatedUserDecryptEIP712Type> {\n return this.#active.createDelegatedUserDecryptEIP712(\n publicKey,\n contractAddresses,\n delegatorAddress,\n startTimestamp,\n durationDays,\n );\n }\n\n delegatedUserDecrypt(\n params: DelegatedUserDecryptParams,\n ): Promise<Readonly<Record<Handle, ClearValueType>>> {\n return this.#active.delegatedUserDecrypt(params);\n }\n\n requestZKProofVerification(zkProof: ZKProofLike): Promise<InputProofBytesType> {\n return this.#active.requestZKProofVerification(zkProof);\n }\n\n getPublicKey(): Promise<PublicKeyData | null> {\n return this.#active.getPublicKey();\n }\n\n getPublicParams(bits: number): Promise<PublicParamsData | null> {\n return this.#active.getPublicParams(bits);\n }\n\n getAclAddress(): Promise<Address> {\n return this.#active.getAclAddress();\n }\n\n terminate(): void {\n const errors: Error[] = [];\n\n // Clean up relayer-owned caches (no worker termination).\n for (const r of new Set(this.#relayers.values())) {\n try {\n r.terminate();\n } catch (e) {\n errors.push(toError(e));\n }\n }\n\n // Terminate the actual workers/pools (deduplicated).\n for (const w of new Set(this.#workers)) {\n try {\n w.terminate();\n } catch (e) {\n errors.push(toError(e));\n }\n }\n\n if (errors.length > 0) {\n throw new AggregateError(errors, \"Failed to terminate relayer resources\");\n }\n }\n\n [Symbol.dispose](): void {\n this.terminate();\n }\n}\n","import { type Address, getAddress, zeroAddress } from \"viem\";\nimport { z } from \"zod\";\nimport type { TokenWrapperPairWithMetadata, PaginatedResult, TokenWrapperPair } from \"./contracts\";\nimport {\n decimalsContract,\n erc20TotalSupplyContract,\n getConfidentialTokenAddressContract,\n getTokenAddressContract,\n getTokenPairContract,\n getTokenPairsContract,\n getTokenPairsLengthContract,\n getTokenPairsSliceContract,\n isConfidentialTokenValidContract,\n nameContract,\n symbolContract,\n} from \"./contracts\";\nimport { ConfigurationError } from \"./errors/relayer\";\nimport { mainnet, sepolia, hoodi } from \"./chains\";\nimport { checksummedAddress, nonNegativeSeconds } from \"./schemas/primitives\";\nimport type { GenericProvider } from \"./types/provider\";\nimport { parseConfiguration } from \"./validation\";\n\n/**\n * Default wrappers registry addresses for known chains.\n * Only includes chains where a registry is deployed (excludes Hardhat).\n */\nexport const DefaultRegistryAddresses: Record<number, Address> = {\n [mainnet.id]: mainnet.registryAddress,\n [sepolia.id]: sepolia.registryAddress,\n [hoodi.id]: hoodi.registryAddress,\n};\n\n/** Default registry TTL in seconds (24 hours). */\nexport const DEFAULT_REGISTRY_TTL_SECONDS = 86_400;\n\n/** Per-chain wrappers-registry address overrides. */\nexport const RegistryAddressesSchema = z.record(\n z.string().regex(/^\\d+$/, \"expected numeric chain id key\"),\n checksummedAddress,\n);\n\n/** TTL (seconds) for cached registry results. `0` means entries expire immediately. */\nexport const RegistryTTLSchema = nonNegativeSeconds;\n\n/** Default page size for {@link WrappersRegistry.listPairs}. */\nconst DEFAULT_PAGE_SIZE = 100;\n\n/** Configuration for {@link WrappersRegistry}. */\nexport interface WrappersRegistryConfig {\n /** Read-only chain provider used for every registry lookup. */\n provider: GenericProvider;\n /**\n * Per-chain registry address overrides, merged on top of\n * {@link DefaultRegistryAddresses}. Use this to supply a registry\n * address for custom or local chains (e.g. Hardhat).\n *\n * @example\n * ```ts\n * new WrappersRegistry({\n * provider,\n * registryAddresses: { [31337]: \"0xYourHardhatRegistry\" },\n * });\n * ```\n */\n registryAddresses?: Record<number, Address>;\n /**\n * How long cached registry results remain valid, in seconds.\n * Default: `86400` (24 hours).\n */\n registryTTL?: number;\n}\n\n/** Options for {@link WrappersRegistry.listPairs}. */\nexport interface ListPairsOptions {\n /** Page number (1-indexed). Default: `1`. */\n page?: number;\n /** Number of items per page. Default: `100`. */\n pageSize?: number;\n /**\n * When `true`, fetches on-chain metadata (name, symbol, decimals) for both\n * the ERC-20 and confidential token, plus totalSupply for the ERC-20.\n * Default: `false`.\n */\n metadata?: boolean;\n}\n\n/** Shorter TTL for negative lookups (5 minutes) so newly registered tokens are discoverable quickly. */\nconst NEGATIVE_CACHE_TTL_MS = 5 * 60 * 1000;\n\n/** Cache entry with expiry timestamp. */\ninterface CacheEntry<T> {\n data: T;\n expiresAt: number;\n}\n\n/**\n * High-level interface for the on-chain token wrappers registry.\n *\n * Uses the configured {@link GenericProvider} to resolve the correct registry\n * contract address for the current chain and exposes typed read helpers for\n * every registry query. Results are cached in memory with a configurable TTL\n * (default 24 hours).\n *\n * @example\n * ```ts\n * const registry = new WrappersRegistry({ provider });\n *\n * // Paginated listing\n * const page1 = await registry.listPairs({ page: 1, pageSize: 20 });\n *\n * // Structured lookups\n * const result = await registry.getConfidentialToken(erc20Address);\n * if (result) console.log(result.confidentialTokenAddress);\n *\n * // Force refresh\n * registry.refresh();\n * ```\n */\nexport class WrappersRegistry {\n readonly provider: GenericProvider;\n readonly #addresses: Record<number, Address>;\n readonly #ttlMs: number;\n readonly #cache = new Map<string, CacheEntry<unknown>>();\n\n constructor(config: WrappersRegistryConfig) {\n this.provider = config.provider;\n this.#addresses = Object.assign(\n {},\n DefaultRegistryAddresses,\n parseConfiguration(RegistryAddressesSchema.optional(), config.registryAddresses),\n );\n this.#ttlMs =\n parseConfiguration(RegistryTTLSchema, config.registryTTL ?? DEFAULT_REGISTRY_TTL_SECONDS) *\n 1000;\n }\n\n /**\n * Synchronous lookup of the registry address for a given chain ID.\n * Returns `undefined` if no address is configured for that chain.\n */\n getAddress(chainId: number): Address | undefined {\n return this.#addresses[chainId];\n }\n\n // ---------------------------------------------------------------------------\n // Cache helpers\n // ---------------------------------------------------------------------------\n\n #getCached<T>(key: string): T | undefined {\n const entry = this.#cache.get(key);\n if (!entry) {\n return undefined;\n }\n if (Date.now() >= entry.expiresAt) {\n this.#cache.delete(key);\n return undefined;\n }\n return entry.data as T;\n }\n\n #setCached<T>(key: string, data: T, ttlMs = this.#ttlMs): T {\n this.#cache.set(key, {\n data,\n expiresAt: Date.now() + ttlMs,\n });\n return data;\n }\n\n /**\n * Force-invalidate the in-memory cache. The next call to any read method\n * will fetch fresh data from the chain.\n */\n refresh(): void {\n this.#cache.clear();\n }\n\n /**\n * The cache TTL in milliseconds.\n * Exposed so query option factories can set a matching `staleTime`.\n */\n get ttlMs(): number {\n return this.#ttlMs;\n }\n\n // ---------------------------------------------------------------------------\n // Registry address resolution\n // ---------------------------------------------------------------------------\n\n /**\n * Resolve the registry contract address for the current chain.\n *\n * Priority: `registryAddresses[chainId]` \\> built-in default.\n *\n * @returns The registry contract address for the connected chain.\n * @throws {@link ConfigurationError} if no address is configured for the chain.\n */\n async getRegistryAddress(): Promise<Address> {\n const chainId = await this.provider.getChainId();\n const address = this.#addresses[chainId];\n\n if (!address) {\n throw new ConfigurationError(\n `No wrappers registry address configured for chain ${chainId}.\\n` +\n `Pass a registryAddresses entry for this chain.`,\n );\n }\n\n return getAddress(address);\n }\n\n // ---------------------------------------------------------------------------\n // Paginated listing\n // ---------------------------------------------------------------------------\n\n /**\n * List token wrapper pairs with page-based pagination.\n *\n * Internally maps to `getTokenConfidentialTokenPairsSlice` on-chain.\n *\n * @param options - Pagination and enrichment options.\n * @returns A {@link PaginatedResult} of pairs.\n *\n * @example\n * ```ts\n * const result = await registry.listPairs({ page: 1, pageSize: 20 });\n * console.log(`${result.total} pairs, showing page ${result.page}`);\n *\n * // With on-chain metadata\n * const withMeta = await registry.listPairs({ metadata: true, pageSize: 10 });\n * for (const pair of withMeta.items) {\n * console.log(pair.underlying.symbol, \"→\", pair.confidential.symbol);\n * }\n * ```\n */\n async listPairs(\n options: ListPairsOptions & { metadata: true },\n ): Promise<PaginatedResult<TokenWrapperPairWithMetadata>>;\n async listPairs(options?: ListPairsOptions): Promise<PaginatedResult<TokenWrapperPair>>;\n async listPairs(\n options: ListPairsOptions = {},\n ): Promise<PaginatedResult<TokenWrapperPair | TokenWrapperPairWithMetadata>> {\n const page = options.page ?? 1;\n const pageSize = options.pageSize ?? DEFAULT_PAGE_SIZE;\n const metadata = options.metadata ?? false;\n\n if (page < 1) {\n throw new ConfigurationError(`page must be >= 1, got ${page}`);\n }\n if (pageSize < 1) {\n throw new ConfigurationError(`pageSize must be >= 1, got ${pageSize}`);\n }\n\n const registry = await this.getRegistryAddress();\n\n // Fetch total (cached)\n const totalCacheKey = `total:${registry}`;\n let total = this.#getCached<number>(totalCacheKey);\n if (total === undefined) {\n const raw = await this.provider.readContract(getTokenPairsLengthContract(registry));\n total = this.#setCached(totalCacheKey, Number(raw));\n }\n\n // Compute slice indices, clamping toIndex to total\n const fromIndex = BigInt((page - 1) * pageSize);\n const clampedToIndex =\n fromIndex + BigInt(pageSize) > BigInt(total) ? BigInt(total) : fromIndex + BigInt(pageSize);\n\n // Page beyond total — return empty\n if (fromIndex >= BigInt(total)) {\n return { items: [], total, page, pageSize };\n }\n\n // Fetch slice (cached)\n const sliceCacheKey = `slice:${registry}:${fromIndex}:${clampedToIndex}`;\n let items = this.#getCached<TokenWrapperPair[]>(sliceCacheKey);\n if (items === undefined) {\n const raw = await this.provider.readContract(\n getTokenPairsSliceContract(registry, fromIndex, clampedToIndex),\n );\n items = this.#setCached(sliceCacheKey, [...raw]);\n }\n\n if (!metadata) {\n return { items, total, page, pageSize };\n }\n\n // Enrich with on-chain metadata (resilient — individual failures don't break the batch)\n const metadataCacheKey = `metadata:${registry}:${fromIndex}:${clampedToIndex}`;\n let metadataItems = this.#getCached<TokenWrapperPairWithMetadata[]>(metadataCacheKey);\n if (metadataItems === undefined) {\n const settled = await Promise.allSettled(items.map((pair) => this.#pairWithMetadata(pair)));\n const hasFailures = settled.some((r) => r.status === \"rejected\");\n const enriched = settled.map((result, i) =>\n result.status === \"fulfilled\"\n ? result.value\n : Object.assign({}, items[i], {\n metadataFailed: true as const,\n underlying: {\n name: \"Unknown\",\n symbol: \"???\",\n decimals: 0,\n totalSupply: 0n,\n },\n confidential: { name: \"Unknown\", symbol: \"???\", decimals: 0 },\n }),\n );\n // Use negative cache TTL when any metadata fetch failed so retries happen sooner\n metadataItems = this.#setCached(\n metadataCacheKey,\n enriched,\n hasFailures ? NEGATIVE_CACHE_TTL_MS : undefined,\n );\n }\n\n return { items: metadataItems, total, page, pageSize };\n }\n\n async #pairWithMetadata(pair: TokenWrapperPair): Promise<TokenWrapperPairWithMetadata> {\n const [uName, uSymbol, uDecimals, uTotalSupply, cName, cSymbol, cDecimals] = await Promise.all([\n this.provider.readContract(nameContract(pair.tokenAddress)),\n this.provider.readContract(symbolContract(pair.tokenAddress)),\n this.provider.readContract(decimalsContract(pair.tokenAddress)),\n this.provider.readContract(erc20TotalSupplyContract(pair.tokenAddress)),\n this.provider.readContract(nameContract(pair.confidentialTokenAddress)),\n this.provider.readContract(symbolContract(pair.confidentialTokenAddress)),\n this.provider.readContract(decimalsContract(pair.confidentialTokenAddress)),\n ]);\n\n return {\n ...pair,\n underlying: {\n name: uName,\n symbol: uSymbol,\n decimals: uDecimals,\n totalSupply: uTotalSupply,\n },\n confidential: { name: cName, symbol: cSymbol, decimals: cDecimals },\n };\n }\n\n // ---------------------------------------------------------------------------\n // Structured single-pair lookups\n // ---------------------------------------------------------------------------\n\n /**\n * Look up the confidential token for a given plain ERC-20 address.\n *\n * @param tokenAddress - The plain ERC-20 token address.\n * @returns The lookup result, or `null` if the token has never been registered.\n * **Note:** revoked tokens (registered then invalidated) return a non-null result\n * with `isValid: false`. Check `result.isValid` explicitly rather than using\n * `if (result)` to guard against processing revoked tokens.\n *\n * @example\n * ```ts\n * const result = await registry.getConfidentialToken(usdcAddress);\n * if (result?.isValid) {\n * console.log(result.confidentialTokenAddress);\n * }\n * ```\n */\n async getConfidentialToken(\n tokenAddress: Address,\n ): Promise<{ confidentialTokenAddress: Address; isValid: boolean } | null> {\n const registry = await this.getRegistryAddress();\n const normalized = getAddress(tokenAddress);\n\n const cacheKey = `ct:${registry}:${normalized}`;\n const cached = this.#getCached<{\n confidentialTokenAddress: Address;\n isValid: boolean;\n } | null>(cacheKey);\n if (cached !== undefined) {\n return cached;\n }\n\n const [isValid, confidentialTokenAddress] = await this.provider.readContract(\n getConfidentialTokenAddressContract(registry, normalized),\n );\n\n // Zero address means the token is not registered at all (never seen by the registry).\n // A non-zero address with isValid=false means it was registered but later revoked.\n if (confidentialTokenAddress === zeroAddress) {\n return this.#setCached(cacheKey, null, NEGATIVE_CACHE_TTL_MS);\n }\n\n return this.#setCached(cacheKey, { confidentialTokenAddress, isValid });\n }\n\n /**\n * Reverse lookup — find the plain ERC-20 for a given confidential token.\n *\n * @param confidentialTokenAddress - The confidential token address.\n * @returns The lookup result, or `null` if no pair is registered.\n *\n * @example\n * ```ts\n * const result = await registry.getUnderlyingToken(cUsdcAddress);\n * if (result) {\n * console.log(result.tokenAddress, result.isValid);\n * }\n * ```\n */\n async getUnderlyingToken(\n confidentialTokenAddress: Address,\n ): Promise<{ tokenAddress: Address; isValid: boolean } | null> {\n const registry = await this.getRegistryAddress();\n const normalized = getAddress(confidentialTokenAddress);\n\n const cacheKey = `ut:${registry}:${normalized}`;\n const cached = this.#getCached<{\n tokenAddress: Address;\n isValid: boolean;\n } | null>(cacheKey);\n if (cached !== undefined) {\n return cached;\n }\n\n const [isValid, tokenAddress] = await this.provider.readContract(\n getTokenAddressContract(registry, normalized),\n );\n\n // Zero address means the confidential token is not registered at all.\n // A non-zero address with isValid=false means it was registered but later revoked.\n if (tokenAddress === zeroAddress) {\n return this.#setCached(cacheKey, null, NEGATIVE_CACHE_TTL_MS);\n }\n\n return this.#setCached(cacheKey, { tokenAddress, isValid });\n }\n\n // ---------------------------------------------------------------------------\n // Low-level pass-through methods (backward compatible)\n // ---------------------------------------------------------------------------\n\n /**\n * Fetch all token wrapper pairs from the registry.\n *\n * @returns All registered `TokenWrapperPair` entries.\n */\n async getTokenPairs(): Promise<readonly TokenWrapperPair[]> {\n const registry = await this.getRegistryAddress();\n return this.provider.readContract(getTokenPairsContract(registry));\n }\n\n /**\n * Get the total number of token wrapper pairs.\n *\n * @returns The count as a bigint.\n */\n async getTokenPairsLength(): Promise<bigint> {\n const registry = await this.getRegistryAddress();\n return this.provider.readContract(getTokenPairsLengthContract(registry));\n }\n\n /**\n * Fetch a range of token wrapper pairs (paginated by index).\n *\n * @param fromIndex - Start index (inclusive).\n * @param toIndex - End index (exclusive).\n * @returns The slice of `TokenWrapperPair` entries.\n */\n async getTokenPairsSlice(\n fromIndex: bigint,\n toIndex: bigint,\n ): Promise<readonly TokenWrapperPair[]> {\n const registry = await this.getRegistryAddress();\n return this.provider.readContract(getTokenPairsSliceContract(registry, fromIndex, toIndex));\n }\n\n /**\n * Fetch a single token wrapper pair by index.\n *\n * @param index - Zero-based pair index.\n * @returns The `TokenWrapperPair` at that index.\n */\n async getTokenPair(index: bigint): Promise<TokenWrapperPair> {\n const registry = await this.getRegistryAddress();\n return this.provider.readContract(getTokenPairContract(registry, index));\n }\n\n /**\n * Look up the confidential token address for a given plain ERC-20 token.\n *\n * @param tokenAddress - The plain ERC-20 token address.\n * @returns A tuple `[isValid, confidentialTokenAddress]`. `isValid` is `true` only for a\n * registered, non-revoked wrapper. The address is the zero address when no pair is registered.\n * A non-zero address with `isValid=false` means the wrapper was registered but later revoked.\n */\n async getConfidentialTokenAddress(tokenAddress: Address): Promise<readonly [boolean, Address]> {\n const registry = await this.getRegistryAddress();\n return this.provider.readContract(\n getConfidentialTokenAddressContract(registry, getAddress(tokenAddress)),\n );\n }\n\n /**\n * Reverse lookup — find the plain ERC-20 for a given confidential token.\n *\n * @param confidentialTokenAddress - The confidential token address.\n * @returns A tuple `[isValid, tokenAddress]`. `isValid` is `true` only for a registered,\n * non-revoked wrapper. The address is the zero address when no pair is registered.\n * A non-zero address with `isValid=false` means the wrapper was registered but later revoked.\n */\n async getTokenAddress(confidentialTokenAddress: Address): Promise<readonly [boolean, Address]> {\n const registry = await this.getRegistryAddress();\n return this.provider.readContract(\n getTokenAddressContract(registry, getAddress(confidentialTokenAddress)),\n );\n }\n\n /**\n * Check whether a confidential token is registered and valid.\n *\n * @param confidentialTokenAddress - The confidential token address to check.\n * @returns `true` if the token is a known valid wrapper in the registry.\n */\n async isConfidentialTokenValid(confidentialTokenAddress: Address): Promise<boolean> {\n const registry = await this.getRegistryAddress();\n return this.provider.readContract(\n isConfidentialTokenValidContract(registry, getAddress(confidentialTokenAddress)),\n );\n }\n}\n","import {\n DEFAULT_KEYPAIR_TTL_SECONDS,\n DEFAULT_PERMIT_DURATION_DAYS,\n} from \"../credentials/credential-service\";\nimport { KeypairTTLSchema, PermitTTLSchema } from \"../credentials/schemas\";\nimport { RelayerDispatcher } from \"../relayer/relayer-dispatcher\";\nimport type { GenericProvider, GenericSigner } from \"../types\";\nimport { DEFAULT_REGISTRY_TTL_SECONDS, RegistryTTLSchema } from \"../wrappers-registry\";\nimport { parseConfiguration } from \"../validation\";\nimport { resolveStorage } from \"./resolve\";\nimport type { ZamaConfig, ZamaConfigBase } from \"./types\";\n\n/**\n * @internal Shared config builder — not part of the public API.\n *\n * Applies defaults, validates TTLs, and resolves storage so the\n * returned config is fully populated and ready for `ZamaSDK`.\n */\nexport function buildZamaConfig(\n signer: GenericSigner | undefined,\n provider: GenericProvider,\n params: ZamaConfigBase,\n): ZamaConfig {\n const { storage, permitStorage } = resolveStorage(params.storage, params.permitStorage);\n const relayer = new RelayerDispatcher(params.chains, params.relayers);\n\n return {\n chains: params.chains,\n relayer,\n provider,\n signer,\n storage,\n permitStorage,\n keypairTTL: parseConfiguration(\n KeypairTTLSchema,\n params.keypairTTL ?? DEFAULT_KEYPAIR_TTL_SECONDS,\n ),\n permitTTL: parseConfiguration(\n PermitTTLSchema,\n params.permitTTL ?? DEFAULT_PERMIT_DURATION_DAYS,\n ),\n registryTTL: parseConfiguration(\n RegistryTTLSchema,\n params.registryTTL ?? DEFAULT_REGISTRY_TTL_SECONDS,\n ),\n onEvent: params.onEvent,\n } as unknown as ZamaConfig;\n}\n","import type {\n WalletAccount,\n WalletAccountChange,\n WalletAccountListener,\n WalletAccountStore,\n} from \"../types\";\n\nexport function walletAccountsEqual(\n a: WalletAccount | undefined,\n b: WalletAccount | undefined,\n): boolean {\n return a?.address === b?.address && a?.chainId === b?.chainId;\n}\n\n/**\n * Writable {@link WalletAccountStore} for custom signer adapters. Adapters call\n * {@link MutableWalletAccountStore.setSnapshot} when their underlying wallet\n * provider notifies of a connect, disconnect, account change, or chain change.\n *\n * Most custom adapters should use the {@link createWalletAccountStore} factory\n * rather than instantiating this class directly.\n */\nexport class MutableWalletAccountStore implements WalletAccountStore {\n readonly #listeners = new Set<WalletAccountListener>();\n #snapshot: WalletAccount | undefined;\n #resolved: boolean;\n\n constructor(initial?: WalletAccount) {\n this.#snapshot = initial;\n this.#resolved = initial !== undefined;\n }\n\n getSnapshot(): WalletAccount | undefined {\n return this.#snapshot;\n }\n\n /**\n * Whether the store has received at least one snapshot (via the constructor\n * or {@link setSnapshot}). Adapters whose initial account is only available\n * asynchronously start unresolved; callers can distinguish \"still loading\"\n * from \"wallet not connected\".\n */\n isReady(): boolean {\n return this.#resolved;\n }\n\n /**\n * Push a new wallet account snapshot. No-op when the next value is\n * value-equal to the current one. Emits `{ previous, next }` to every\n * subscriber otherwise.\n */\n setSnapshot(next: WalletAccount | undefined): void {\n this.#resolved = true;\n const previous = this.#snapshot;\n if (walletAccountsEqual(previous, next)) {\n return;\n }\n this.#snapshot = next;\n this.#emit({ previous, next });\n }\n\n subscribe(listener: WalletAccountListener): () => void {\n this.#listeners.add(listener);\n const snapshot = this.#snapshot;\n if (snapshot) {\n listener({ previous: undefined, next: snapshot });\n }\n return () => {\n this.#listeners.delete(listener);\n };\n }\n\n #emit(change: WalletAccountChange): void {\n for (const listener of this.#listeners) {\n listener(change);\n }\n }\n}\n\n/**\n * Create a {@link MutableWalletAccountStore} for a custom {@link GenericSigner}\n * adapter.\n *\n * @param initial - Optional initial wallet account snapshot.\n */\nexport function createWalletAccountStore(initial?: WalletAccount): MutableWalletAccountStore {\n return new MutableWalletAccountStore(initial);\n}\n","import type { Hex } from \"viem\";\nimport { WalletNotConnectedError } from \"../errors\";\nimport type { EIP712TypedData } from \"../relayer/relayer-sdk.types\";\nimport type {\n ContractAbi,\n GenericSigner,\n WalletAccount,\n WriteContractArgs,\n WriteContractConfig,\n WriteFunctionName,\n} from \"../types\";\nimport { MutableWalletAccountStore } from \"./wallet-account-store\";\n\n/**\n * Abstract base class that implements the shared {@link GenericSigner}\n * boilerplate: wallet-account store, `requireWalletAccount`, idempotent\n * `dispose` / `Disposable`. Subclasses provide `signTypedData`,\n * `writeContract`, and optionally override `onDispose` for cleanup.\n *\n * Using this class is optional — implementing {@link GenericSigner} directly\n * with {@link createWalletAccountStore} remains fully supported.\n */\nexport abstract class BaseSigner implements GenericSigner, Disposable {\n readonly walletAccount: MutableWalletAccountStore;\n #disposed = false;\n\n constructor(initial?: WalletAccount) {\n this.walletAccount = new MutableWalletAccountStore(initial);\n }\n\n requireWalletAccount(operation: string): WalletAccount {\n const account = this.walletAccount.getSnapshot();\n if (!account) {\n throw new WalletNotConnectedError(operation);\n }\n return account;\n }\n\n abstract signTypedData(typedData: EIP712TypedData): Promise<Hex>;\n\n abstract writeContract<\n const TAbi extends ContractAbi,\n TFunctionName extends WriteFunctionName<TAbi>,\n const TArgs extends WriteContractArgs<TAbi, TFunctionName>,\n >(config: WriteContractConfig<TAbi, TFunctionName, TArgs>): Promise<Hex>;\n\n dispose(): void {\n if (this.#disposed) {\n return;\n }\n this.#disposed = true;\n this.onDispose();\n }\n\n [Symbol.dispose](): void {\n this.dispose();\n }\n\n protected onDispose(): void {}\n}\n"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`../wrappers-registry.cjs`),t=require(`../base-signer.cjs`),n=require(`../eip1193-subscribe.cjs`);let r=require(`viem`),i=require(`ethers`);var a=class{#e;constructor(e){`ethereum`in e?this.#e=new i.BrowserProvider(e.ethereum):this.#e=e.provider}async getChainId(){let e=await this.#e.getNetwork();return Number(e.chainId)}async readContract(e){return new i.ethers.Contract(e.address,e.abi,this.#e).getFunction(e.functionName)(...e.args)}async getBlockTimestamp(){let e=await this.#e.getBlock(`latest`);if(!e)throw Error(`Failed to fetch latest block`);if(e.timestamp===null)throw Error(`Latest block has no timestamp`);return BigInt(e.timestamp)}async waitForTransactionReceipt(e){let t=await this.#e.waitForTransaction(e);if(!t)throw Error(`Transaction receipt not found`);return{logs:t.logs.map(e=>({topics:e.topics.filter(e=>e!==null),data:e.data}))}}},o=class extends t.t{#e;#t;#n;#r;#i;constructor(e){super(),`ethereum`in e?(this.#e=new i.BrowserProvider(e.ethereum),this.#n=e.ethereum,this.#r=n.t({provider:e.ethereum,getInitialWalletAccount:()=>this.#l(),onWalletAccountChange:({next:e})=>{this.walletAccount.setSnapshot(e)}})):(this.#t=e.signer,this.#r=()=>{},t.h(`refresh wallet account`,async()=>{await this.refreshWalletAccount()}))}requireWalletAccount(
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`../wrappers-registry.cjs`),t=require(`../base-signer.cjs`),n=require(`../eip1193-subscribe.cjs`);let r=require(`viem`),i=require(`ethers`);var a=class{#e;constructor(e){`ethereum`in e?this.#e=new i.BrowserProvider(e.ethereum):this.#e=e.provider}async getChainId(){let e=await this.#e.getNetwork();return Number(e.chainId)}async readContract(e){return new i.ethers.Contract(e.address,e.abi,this.#e).getFunction(e.functionName)(...e.args)}async getBlockTimestamp(){let e=await this.#e.getBlock(`latest`);if(!e)throw Error(`Failed to fetch latest block`);if(e.timestamp===null)throw Error(`Latest block has no timestamp`);return BigInt(e.timestamp)}async waitForTransactionReceipt(e){let t=await this.#e.waitForTransaction(e);if(!t)throw Error(`Transaction receipt not found`);return{logs:t.logs.map(e=>({topics:e.topics.filter(e=>e!==null),data:e.data}))}}},o=class extends t.t{#e;#t;#n;#r;#i;constructor(e){super(),`ethereum`in e?(this.#e=new i.BrowserProvider(e.ethereum),this.#n=e.ethereum,this.#r=n.t({provider:e.ethereum,getInitialWalletAccount:()=>this.#l(),onWalletAccountChange:({next:e})=>{this.walletAccount.setSnapshot(e)}})):(this.#t=e.signer,this.#r=()=>{},t.h(`refresh wallet account`,async()=>{await this.refreshWalletAccount()}))}requireWalletAccount(t){let n=this.walletAccount.getSnapshot();if(!n&&!this.walletAccount.isReady())throw new e.z(t);if(!n)throw new e.B(t);return n}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 e.L(`resolveSigner`);return this.#e.getSigner()}async#o(e){let t=e.provider;if(!t)return;let[n,i]=await Promise.all([e.getAddress(),t.getNetwork()]);return{address:(0,r.getAddress)(n),chainId:Number(i.chainId)}}async signTypedData(e){let t=await this.#a(),{domain:n,types:i,message:a}=e,{EIP712Domain:o,...s}=i,c=Object.fromEntries(Object.entries(s).map(([e,t])=>[e,[...t]])),l=await t.signTypedData(n,c,a);if(!(0,r.isHex)(l))throw TypeError(`Expected hex string, got: ${l}`);return l}async writeContract(e){let t=await this.#a(),n=new i.Contract(e.address,e.abi,t),a={};e.value!==void 0&&(a.value=e.value),e.gas!==void 0&&(a.gasLimit=e.gas);let o=await n.getFunction(e.functionName)(...e.args,a);if(!(0,r.isHex)(o.hash))throw TypeError(`Expected hex string, got: ${o.hash}`);return o.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 i=Number(n);if(!(!Number.isSafeInteger(i)||i<=0))return{address:(0,r.getAddress)(t[0]),chainId:i}}};function s(e){if(`signer`in e&&e.signer){let n=new o({signer:e.signer});if(!e.signer.provider)throw Error(`createConfig requires a Signer with an attached provider for chain reads`);return t.i(n,new a({provider:e.signer.provider}),e)}return t.i(new o({ethereum:e.ethereum}),`provider`in e&&e.provider?new a({provider:e.provider}):new a({ethereum:e.ethereum}),e)}function c(e){return{to:e.address,data:(0,r.encodeFunctionData)({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 l(e,t){let n=await e.call(c(t));if(!(0,r.isHex)(n))throw TypeError(`Expected hex string, got: ${n}`);return(0,r.decodeFunctionResult)({abi:t.abi,functionName:t.functionName,data:n})}async function u(e,t){let n=await e.sendTransaction(c(t));if(!(0,r.isHex)(n.hash))throw TypeError(`Expected hex string, got: ${n.hash}`);return n.hash}function d(t,n,r){return l(t,e.D(n,r))}function f(t,n){return l(t,e.T(n))}function p(t,n,r){return l(t,e.h(n,r))}function m(t,n,r,i,a){return u(t,e.k(n,r,i,a))}function h(t,n,r,i,a,o){return u(t,e.F(n,r,i,a,o))}function g(t,n,r,i,a){return u(t,e.I(n,r,i,a))}function _(t,n,r,i,a){return u(t,e.C(n,r,i,a))}function v(t,n,r,i){return u(t,e.N(n,r,i))}function y(t,n,r,i){return u(t,e.E(n,r,i))}function b(t,n){return l(t,e.i(n))}function x(t,n){return l(t,e.a(n))}function S(t,n,r,i){return l(t,e.o(n,r,i))}function C(t,n,r){return l(t,e.r(n,r))}function w(t,n,r){return l(t,e.t(n,r))}function T(t,n,r){return l(t,e.n(n,r))}function E(t,n,r){return l(t,e.s(n,r))}exports.EthersProvider=a,exports.EthersSigner=o,Object.defineProperty(exports,`ProviderRpcError`,{enumerable:!0,get:function(){return r.ProviderRpcError}}),exports.createConfig=s,exports.readConfidentialBalanceOfContract=d,exports.readConfidentialTokenAddressContract=w,exports.readIsConfidentialTokenValidContract=E,exports.readSupportsInterfaceContract=p,exports.readTokenAddressContract=T,exports.readTokenPairContract=C,exports.readTokenPairsContract=b,exports.readTokenPairsLengthContract=x,exports.readTokenPairsSliceContract=S,exports.readUnderlyingTokenContract=f,exports.writeConfidentialTransferContract=m,exports.writeFinalizeUnwrapContract=_,exports.writeSetOperatorContract=v,exports.writeUnwrapContract=h,exports.writeUnwrapFromBalanceContract=g,exports.writeWrapContract=y;
|
|
2
2
|
//# sourceMappingURL=index.cjs.map
|