@zama-fhe/sdk 3.4.0-alpha.9 → 3.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/dist/cjs/base-signer.cjs +1 -1
  2. package/dist/cjs/base-signer.cjs.map +1 -1
  3. package/dist/cjs/ethers/index.cjs +1 -1
  4. package/dist/cjs/ethers/index.cjs.map +1 -1
  5. package/dist/cjs/fhevm-relayer.cjs +1 -1
  6. package/dist/cjs/fhevm-relayer.cjs.map +1 -1
  7. package/dist/cjs/index.cjs +1 -1
  8. package/dist/cjs/index.cjs.map +1 -1
  9. package/dist/cjs/node/index.cjs.map +1 -1
  10. package/dist/cjs/query/index.cjs +1 -1
  11. package/dist/cjs/query/index.cjs.map +1 -1
  12. package/dist/cjs/relayer.cjs +1 -1
  13. package/dist/cjs/relayer.cjs.map +1 -1
  14. package/dist/cjs/sdk-events.cjs +2 -0
  15. package/dist/cjs/sdk-events.cjs.map +1 -0
  16. package/dist/cjs/token.cjs +1 -1
  17. package/dist/cjs/token.cjs.map +1 -1
  18. package/dist/cjs/viem/index.cjs +1 -1
  19. package/dist/cjs/viem/index.cjs.map +1 -1
  20. package/dist/esm/{base-signer-Ds8CoYy0.d.ts → base-signer-BvL-jMNO.d.ts} +15 -2
  21. package/dist/esm/base-signer-YpkEmlp2.js +2 -0
  22. package/dist/esm/base-signer-YpkEmlp2.js.map +1 -0
  23. package/dist/esm/chains/index.d.ts +1 -1
  24. package/dist/esm/cleartext/index.d.ts +2 -2
  25. package/dist/esm/cleartext/index.js +1 -1
  26. package/dist/esm/{cleartext-_RCZVPOe.d.ts → cleartext-CxlICeUh.d.ts} +2 -2
  27. package/dist/esm/{cleartext-DfX0GUj1.js → cleartext-Qqh5JohW.js} +2 -2
  28. package/dist/esm/{cleartext-DfX0GUj1.js.map → cleartext-Qqh5JohW.js.map} +1 -1
  29. package/dist/esm/ethers/index.d.ts +53 -5
  30. package/dist/esm/ethers/index.js +1 -1
  31. package/dist/esm/ethers/index.js.map +1 -1
  32. package/dist/esm/fhevm-relayer-4Zd4QkKq.js +2 -0
  33. package/dist/esm/fhevm-relayer-4Zd4QkKq.js.map +1 -0
  34. package/dist/esm/{zama-sdk-BhD6nWLL.d.ts → index-DLaQtvYu.d.ts} +1253 -1780
  35. package/dist/esm/index-DNofJMCK.d.ts +61 -0
  36. package/dist/esm/{index-doNE2KoX.d.ts → index-S6_V7aAH.d.ts} +10 -1
  37. package/dist/esm/index.d.ts +8 -79
  38. package/dist/esm/index.js +1 -1
  39. package/dist/esm/index.js.map +1 -1
  40. package/dist/esm/node/index.d.ts +5 -5
  41. package/dist/esm/node/index.js +1 -1
  42. package/dist/esm/node/index.js.map +1 -1
  43. package/dist/esm/query/index.d.ts +522 -3
  44. package/dist/esm/query/index.js +1 -1
  45. package/dist/esm/query/index.js.map +1 -1
  46. package/dist/esm/relayer-BWHOLVcG.js +2 -0
  47. package/dist/esm/relayer-BWHOLVcG.js.map +1 -0
  48. package/dist/esm/sdk-events-D68bJ5jT.js +2 -0
  49. package/dist/esm/sdk-events-D68bJ5jT.js.map +1 -0
  50. package/dist/esm/token-Bn8I7xAu.js +2 -0
  51. package/dist/esm/token-Bn8I7xAu.js.map +1 -0
  52. package/dist/esm/{types-Tk8PiPCk.d.ts → types-BEz-VgR_.d.ts} +6 -3
  53. package/dist/esm/{types-CELdIAFG.d.ts → types-CWPSTRF6.d.ts} +98 -146
  54. package/dist/esm/{types-DlSUyFe2.d.ts → types-Dr7AmEs1.d.ts} +3 -3
  55. package/dist/esm/viem/index.d.ts +34 -5
  56. package/dist/esm/viem/index.js +1 -1
  57. package/dist/esm/viem/index.js.map +1 -1
  58. package/dist/esm/web/index.d.ts +2 -2
  59. package/dist/esm/web/index.js +1 -1
  60. package/package.json +3 -3
  61. package/dist/cjs/wrappers-registry.cjs +0 -2
  62. package/dist/cjs/wrappers-registry.cjs.map +0 -1
  63. package/dist/esm/base-signer-9CqICeQ8.js +0 -2
  64. package/dist/esm/base-signer-9CqICeQ8.js.map +0 -1
  65. package/dist/esm/fhevm-relayer-Bb_-KFJA.js +0 -2
  66. package/dist/esm/fhevm-relayer-Bb_-KFJA.js.map +0 -1
  67. package/dist/esm/index-9Cn2VKDw.d.ts +0 -329
  68. package/dist/esm/relayer-DLlyoabr.js +0 -2
  69. package/dist/esm/relayer-DLlyoabr.js.map +0 -1
  70. package/dist/esm/token-BBGMtloT.js +0 -2
  71. package/dist/esm/token-BBGMtloT.js.map +0 -1
  72. package/dist/esm/wrappers-registry-B1GuTt5t.js +0 -2
  73. package/dist/esm/wrappers-registry-B1GuTt5t.js.map +0 -1
@@ -0,0 +1,2 @@
1
+ import{d as e,r as t,t as n}from"./relayer-BWHOLVcG.js";import{C as r,S as i,U as a,a as o,b as s,c,i as l,l as u,o as d,q as f,r as p,s as m,x as h,z as g}from"./sdk-events-D68bJ5jT.js";import{a as _,c as v,n as y,o as b,s as x}from"./chains-CLv9HEJ_.js";import{hasFhevmRuntimeConfig as ee,setFhevmRuntimeConfig as te}from"@fhevm/sdk/viem";import{getAddress as S,isAddress as ne,isHex as re,zeroAddress as C}from"viem";import{z as w}from"zod/mini";var T=class{#e=null;#t=null;#n;#r;#i;constructor(e=`CredentialStore`,t=1,n=`credentials`){this.#n=e,this.#r=t,this.#i=n}#a(){return this.#e?Promise.resolve(this.#e):(this.#t||=new Promise((e,t)=>{let n=indexedDB.open(this.#n,this.#r);n.onupgradeneeded=()=>{let e=n.result;e.objectStoreNames.contains(this.#i)||e.createObjectStore(this.#i,{keyPath:`key`})},n.onsuccess=()=>{this.#e=n.result,this.#t=null,this.#e.onversionchange=()=>{this.#e?.close(),this.#e=null,this.#t=null},this.#e.onclose=()=>{this.#e=null,this.#t=null},e(this.#e)},n.onerror=()=>{this.#e=null,this.#t=null,t(n.error)}}),this.#t)}async#o(e,t){let n=await this.#a();return new Promise((r,i)=>{let a=n.transaction(this.#i,e);a.onabort=()=>i(a.error??Error(`Transaction aborted`));let o=t(a.objectStore(this.#i));e===`readonly`?o.onsuccess=()=>r(o.result):a.oncomplete=()=>r(o.result),o.onerror=()=>i(o.error)})}async get(e){return(await this.#o(`readonly`,t=>t.get(e)))?.value??null}async set(e,t){await this.#o(`readwrite`,n=>n.put({key:e,value:t}))}async delete(e){await this.#o(`readwrite`,t=>t.delete(e))}async clear(){await this.#o(`readwrite`,e=>e.clear())}};const ie=new T;var E=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 ae=new E;function oe(){return typeof window<`u`?new T(`CredentialStore`):new E}function se(e=oe(),t=e){return{storage:e,permitStorage:t}}function ce(e,t){let r=new Map(e.map(e=>[e.id,e]));if(r.size!==e.length){let t=e.map(e=>e.id);throw new n(`Duplicate chain id(s) [${[...new Set(t.filter((e,n)=>t.indexOf(e)!==n))].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(t)),a=new Map;for(let e of r.keys()){let t=r.get(e),o=i.get(String(e));if(!o)throw new n(`Chain ${e} has no relayer configured. Add a relayer entry: relayers: { [${e}]: web() }`);if(!t)throw new n(`Chain ${e} has a relayer configured but no entry in the chains array. Add the chain config to the chains array.`);a.set(e,{chain:t,relayerConfig:o})}let o=new Set(Object.keys(t).map(Number)),s=new Set([...o].filter(e=>!r.has(e)));if(s.size>0)throw new n(`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 le=class{#e;#t;#n;constructor(e,t){if(e.length===0)throw new n(`At least one chain is required.`);this.#e=new Map(e.map(e=>[e.id,e])),this.#n=e[0].id;let r=new Map;for(let[n,{relayerConfig:i,chain:a}]of ce(e,t))r.set(n,i.createRelayer(a));this.#t=r}get chains(){return[...this.#e.values()]}get chain(){let e=this.#e.get(this.#n);if(e===void 0)throw new n(`Chain ${this.#n} is not configured. Add it to the chains array.`);return e}switchChain(e){this.#n=e}get relayer(){let e=this.#t.get(this.chain.id);if(e===void 0)throw new n(`No relayer configured for chain ${this.#n}. Add it to the relayers object.`);return e}};function D(e){return S(e)}const O=w.custom(e=>typeof e==`string`&&re(e,{strict:!0}),`expected 0x-prefixed hex string`),ue=w.custom(e=>typeof e==`string`&&ne(e,{strict:!1}),`expected EVM address`),k=w.pipe(ue,w.transform(D)),A=w.int().check(w.nonnegative()),de=w.int().check(w.positive()),fe=w.int().check(w.nonnegative()),pe=w.int().check(w.positive());w.int().check(w.positive());const j=86400;function M(){return Math.floor(Date.now()/1e3)}function N(e){return[...new Set(e.map(D))].toSorted()}const P=`transportKeyPairTTL must be a positive integer number of seconds`,F=`permitTTL must be a positive integer number of days`,I=`transportKeyPairScope must be a non-empty string`,L=365*j,R=w.int({error:P}).check(w.positive({error:P}),w.maximum(L,`transportKeyPairTTL must not exceed the fhevm ACL maximum of ${L}s (365 days)`)),z=w.int({error:F}).check(w.positive({error:F})),B=w.string({error:I}).check(w.minLength(1,I)),me=w.object({publicKey:O,privateKey:O,createdAt:A,expiresAt:de,tkmsVersion:w.optional(w.string())}),he=w.object({domain:w.record(w.string(),w.unknown()),primaryType:w.optional(w.string()),types:w.record(w.string(),w.array(w.object({name:w.string(),type:w.string()}))),message:w.record(w.string(),w.unknown())}),V=w.object({version:w.int().check(w.positive()),eip712:he,signature:O,signerAddress:k}),H=w.object({keypairPublicKey:O,contractAddresses:w.array(k).check(w.maxLength(10)),serializedPermit:V,startTimestamp:A,durationDays:pe}),ge=w.array(H),_e=w.array(w.string());function U(e){return`keypair:${e}`}function W(e){return`keypair:scope:${e}`}function G(e){return`permits:${e.signerAddress}:${e.chainId}:${e.delegatorAddress}`}function K(e){return`permits-index:${e}`}var ve=class{#e;#t;#n;#r;#i;#a=new Map;#o=new Map;constructor(e){this.#e=e.generator,this.#t=e.storage,this.#n=e.ttl,this.#r=e.logger,this.#i=e.scope}#s(e){return this.#i===void 0?U(e):W(this.#i)}async readStored(e){return this.#c(this.#s(e))}async#c(e){let t=await this.#t.get(e);if(t==null)return null;let n=me.safeParse(t);if(!n.success)return await g(`delete transport key pair entry`,()=>this.#t.delete(e),this.#r),null;let r=n.data;return M()>=r.expiresAt?(await g(`delete transport key pair entry`,()=>this.#t.delete(e),this.#r),null):r}async getOrCreate(e){return this.#l(this.#s(e))}async#l(e,t){let n=`${e}::${t?.strict??!1}`,r=this.#a.get(n);if(r)return r;let i=this.#o.get(e)??0,a=(async()=>{let n=await this.#c(e);if(n!==null)return n;let r=await this.#e(),a=M(),o={publicKey:r.publicKey,privateKey:r.privateKey,createdAt:a,expiresAt:a+this.#n};return r.tkmsVersion&&(o.tkmsVersion=r.tkmsVersion),(this.#o.get(e)??0)===i&&(t?.strict?await this.#t.set(e,o):await g(`persist transport key pair`,()=>this.#t.set(e,o),this.#r)),o})().finally(()=>{this.#a.delete(n)});return this.#a.set(n,a),a}async clear(e){let t=U(e);await g(`delete transport key pair entry`,()=>this.#t.delete(t),this.#r)}async evict(e){let t=this.#s(e);await g(`evict transport key pair entry`,()=>this.#t.delete(t),this.#r)}async clearScope(){if(this.#i===void 0)return;let e=W(this.#i);this.#o.set(e,(this.#o.get(e)??0)+1),await this.#t.delete(e)}async warmScope(){this.#i!==void 0&&await this.#l(W(this.#i),{strict:!0})}};function q(e,t){let n=new Set(e.flatMap(e=>e.contractAddresses));return t.filter(e=>!n.has(e))}function ye(e){let t=[];for(let n=0;n<e.length;n+=10)t.push(e.slice(n,n+10));return t}function be(e,t,n){return e.filter(e=>e.keypairPublicKey===t&&n<e.startTimestamp+e.durationDays*86400)}function xe(e,t){let n=new Set(t);return e.filter(e=>!e.contractAddresses.some(e=>n.has(e)))}function Se(e,t){return[...new Set([...e,...t])].toSorted()}function Ce(e,t,n){let r=new Set(n),i=e.filter(e=>new Set([...e.contractAddresses,...t]).size<=10);if(i.length===0)return null;function a(e){return e.contractAddresses.reduce((e,t)=>e+ +!!r.has(t),0)}let o=Math.max(...i.map(a));return i.filter(e=>a(e)===o).reduce((e,t)=>t.startTimestamp>e.startTimestamp?t:e)}var J=class{#e;#t;constructor(e){this.#e=e.storage,this.#t=e.logger}async list(e){let t=G(e),n=await this.#e.get(t);if(n==null)return[];let r=ge.safeParse(n);return r.success?r.data:(await this.#a(t),await this.#i(e),[])}async listUsableAndPrune(e,t){let n=await this.list(e),r=be(n,t,Math.floor(Date.now()/1e3));if(r.length!==n.length){let t=G(e);r.length===0?(await this.#a(t),await this.#i(e)):await g(`update permit entry`,()=>this.#e.set(t,r),this.#t)}return r}async append(e,t){if(t.length===0)return;let n=t.map(e=>H.parse(e)),r=await this.list(e);await this.#e.set(G(e),[...r,...n]),await this.#r(e)}async replace(e,t,n){let r=H.parse(n),i=(await this.list(e)).filter(e=>e.serializedPermit.signature!==t);await this.#e.set(G(e),[...i,r]),await this.#r(e)}async deletePermitsTouching(e,t){let n=await this.list(e);if(n.length===0)return;let r=G(e),i=xe(n,t);i.length===0?(await this.#a(r),await this.#i(e)):await this.#e.set(r,i)}async clearAllForSigner(e){let t=K(e),n=await this.#n(t);await Promise.all(n.map(e=>this.#a(e))),await g(`delete permit index`,()=>this.#e.delete(t),this.#t)}async#n(e){let t=await this.#e.get(e);if(t==null)return[];let n=_e.safeParse(t);return n.success?n.data:(await g(`delete permit index`,()=>this.#e.delete(e),this.#t),[])}async#r(e){let t=K(e.signerAddress),n=G(e),r=await this.#n(t);r.includes(n)||await this.#e.set(t,[...r,n])}async#i(e){let t=K(e.signerAddress),n=G(e),r=await this.#n(t),i=r.filter(e=>e!==n);i.length!==r.length&&(i.length===0?await g(`delete permit index`,()=>this.#e.delete(t),this.#t):await g(`update permit index`,()=>this.#e.set(t,i),this.#t))}async#a(e){await g(`delete permit entry`,()=>this.#e.delete(e),this.#t)}},we=class{#e;#t;#n;#r;#i;#a;#o;constructor(e){this.#e=new ve({generator:async()=>{let t=e.router.relayer,n=await t.generateTransportKeyPair();return t.serializeTransportKeyPair({transportKeyPair:n})},storage:e.storage,ttl:e.transportKeyPairTTL,logger:e.logger,scope:e.scope}),this.#t=new J({storage:e.permitStorage??e.storage,logger:e.logger}),this.#n=e.router,this.#r=e.signer,this.#i=e.permitTTL,this.#a=e.logger,this.#o=e.scope}async grantPermit(e,t){let n=D(this.#r.requireWalletAccount(`grantPermit`).address),r=N(e),i=await this.#e.getOrCreate(n);if(r.length===0)return{keypair:i,permissions:[]};let a={signerAddress:n,chainId:this.#n.chain.id,delegatorAddress:t?D(t):n},o=await this.#t.listUsableAndPrune(a,i.publicKey),s=q(o,r);if(s.length>0){let e=Ce(o,s,r);if(e!==null){let t=Se(e.contractAddresses,s),n=await this.#s({chunk:t,keypair:i,scope:a});await g(`replace permit`,()=>this.#t.replace(a,e.serializedPermit.signature,n),this.#a),o[o.indexOf(e)]=n}else for(let e of ye(s)){let t=await this.#s({chunk:e,keypair:i,scope:a});o.push(t),await g(`persist permit`,()=>this.#t.append(a,[t]),this.#a)}}let c=new Set(r);return{keypair:i,permissions:o.filter(e=>e.contractAddresses.some(e=>c.has(e)))}}async hasPermit(e,t){if(e.length===0)return!0;let n=this.#r.walletAccount.getSnapshot();if(!n)return!1;let r=D(n.address),i=await this.#e.readStored(r);if(i===null)return!1;let a={signerAddress:r,chainId:this.#n.chain.id,delegatorAddress:t?D(t):r};return q(await this.#t.listUsableAndPrune(a,i.publicKey),N(e)).length===0}async revokePermits(e){let t=D(this.#r.requireWalletAccount(`revokePermits`).address);if(e===void 0){await this.#t.clearAllForSigner(t);return}let n=N(e);if(n.length===0)return;let r=this.#n.chain.id;await this.#t.deletePermitsTouching({signerAddress:t,chainId:r,delegatorAddress:t},n)}async clearCredentials(){let e=D(this.#r.requireWalletAccount(`clearCredentials`).address);await this.#e.clear(e),await this.#t.clearAllForSigner(e)}async revokeTransportKeyPair(e){if(this.#o===void 0)throw new n(`revokeTransportKeyPair() requires a transportKeyPairScope to be configured on this SDK instance — there is no shared key pair to revoke.`);if(e!==this.#o)throw new n(`revokeTransportKeyPair("${e}") does not match the configured scope ("${this.#o}").`);await this.#e.clearScope()}async warmTransportKeyPair(e){await this.#e.getOrCreate(D(e))}async warmTransportKeyPairScope(e){if(this.#o===void 0)throw new n(`warmTransportKeyPairScope() requires a transportKeyPairScope to be configured on this SDK instance — there is no shared key pair to warm.`);if(e!==this.#o)throw new n(`warmTransportKeyPairScope("${e}") does not match the configured scope ("${this.#o}").`);await this.#e.warmScope()}async handleWalletAccountChange(e,t){let n=e?D(e.address):void 0;n!==(t?D(t.address):void 0)&&n&&(await this.#e.clear(n),await this.#t.clearAllForSigner(n))}async#s(n){let{chunk:r,keypair:i,scope:a}=n,o=M(),s=a.delegatorAddress!==a.signerAddress,c=this.#n.relayer;try{let e={transportKeyPair:await c.parseTransportKeyPair(i),contractAddresses:r,startTimestamp:o,durationSeconds:this.#i*j,signerAddress:a.signerAddress,signer:this.#r},t=s?await c.signDecryptionPermit({...e,delegatorAddress:a.delegatorAddress}):await c.signDecryptionPermit(e),n=V.parse(await c.serializeSignedDecryptionPermit({signedPermit:t}));return{keypairPublicKey:i.publicKey,contractAddresses:r,serializedPermit:n,startTimestamp:o,durationDays:this.#i}}catch(n){throw n instanceof t?n:(n instanceof Error&&e(n.message)&&await this.#e.evict(a.signerAddress),f(n,`Credential signing failed`))}}async evictTransportKeyPair(){let e=this.#r.walletAccount.getSnapshot();e&&await this.#e.evict(D(e.address))}},Te=class{#e;#t=`[zama-sdk]`;constructor(e){this.#e=e}error(e,t){this.#e?.error(`${this.#t} ${e}`,t)}warn(e,t){this.#e?.warn(`${this.#t} ${e}`,t)}info(e,t){this.#e?.info(`${this.#t} ${e}`,t)}debug(e,t){this.#e?.debug(`${this.#t} ${e}`,t)}};function Y(e,t){let r=w.safeParse(e,t);if(r.success)return r.data;throw new n(w.prettifyError(r.error),{cause:r.error})}const X={[x.id]:x.registryAddress,[v.id]:v.registryAddress,[_.id]:_.registryAddress,[b.id]:b.registryAddress,[y.id]:y.registryAddress},Ee=w.record(w.string().check(w.regex(/^\d+$/,`expected numeric chain id key`)),k),Z=fe,Q=300*1e3;var De=class{provider;#e;#t;#n=new Map;constructor(e){this.provider=e.provider,this.#e=Object.assign({},X,Y(w.optional(Ee),e.registryAddresses)),this.#t=Y(Z,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 e=await this.provider.getChainId(),t=this.#e[e];if(!t)throw new n(`No wrappers registry address configured for chain ${e}.\nPass a registryAddresses entry for this chain.`);return S(t)}async listPairs(e={}){let t=e.page??1,r=e.pageSize??100,i=e.metadata??!1;if(t<1)throw new n(`page must be >= 1, got ${t}`);if(r<1)throw new n(`pageSize must be >= 1, got ${r}`);let a=await this.getRegistryAddress(),o=`total:${a}`,s=this.#r(o);if(s===void 0){let e=await this.provider.readContract(m(a));s=this.#i(o,Number(e))}let l=BigInt((t-1)*r),u=l+BigInt(r)>BigInt(s)?BigInt(s):l+BigInt(r);if(l>=BigInt(s))return{items:[],total:s,page:t,pageSize:r};let d=`slice:${a}:${l}:${u}`,f=this.#r(d);if(f===void 0){let e=await this.provider.readContract(c(a,l,u));f=this.#i(d,[...e])}if(!i)return{items:f,total:s,page:t,pageSize:r};let p=`metadata:${a}:${l}:${u}`,h=this.#r(p);if(h===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}}));h=this.#i(p,n,t?Q:void 0)}return{items:h,total:s,page:t,pageSize:r}}async#a(e){let[t,n,a,o,c,l,u]=await Promise.all([this.provider.readContract(i(e.tokenAddress)),this.provider.readContract(r(e.tokenAddress)),this.provider.readContract(s(e.tokenAddress)),this.provider.readContract(h(e.tokenAddress)),this.provider.readContract(i(e.confidentialTokenAddress)),this.provider.readContract(r(e.confidentialTokenAddress)),this.provider.readContract(s(e.confidentialTokenAddress))]);return{...e,underlying:{name:t,symbol:n,decimals:a,totalSupply:o},confidential:{name:c,symbol:l,decimals:u}}}async getConfidentialToken(e){let t=await this.getRegistryAddress(),n=S(e),r=`ct:${t}:${n}`,i=this.#r(r);if(i!==void 0)return i;let[a,o]=await this.provider.readContract(p(t,n));return o===C?this.#i(r,null,Q):this.#i(r,{confidentialTokenAddress:o,isValid:a})}async getUnderlyingToken(e){let t=await this.getRegistryAddress(),n=S(e),r=`ut:${t}:${n}`,i=this.#r(r);if(i!==void 0)return i;let[a,o]=await this.provider.readContract(l(t,n));return o===C?this.#i(r,null,Q):this.#i(r,{tokenAddress:o,isValid:a})}async getTokenPairs(){let e=await this.getRegistryAddress();return this.provider.readContract(d(e))}async getTokenPairsLength(){let e=await this.getRegistryAddress();return this.provider.readContract(m(e))}async getTokenPairsSlice(e,t){let n=await this.getRegistryAddress();return this.provider.readContract(c(n,e,t))}async getTokenPair(e){let t=await this.getRegistryAddress();return this.provider.readContract(o(t,e))}async getConfidentialTokenAddress(e){let t=await this.getRegistryAddress();return this.provider.readContract(p(t,S(e)))}async getTokenAddress(e){let t=await this.getRegistryAddress();return this.provider.readContract(l(t,S(e)))}async isConfidentialTokenValid(e){let t=await this.getRegistryAddress();return this.provider.readContract(u(t,S(e)))}};function Oe(e,t,n){let r=new Te(n.logger);ee()?r.warn(`runtime configuration is already set and cannot be changed.`):te({wasmAssetLoadMode:`auto`,moduleVersions:`auto`,logger:{error:(e,t)=>n.logger?.error(e,{cause:t}),warn:e=>n.logger?.warn(e),debug:e=>n.logger?.debug(e)},...n.runtime});let{storage:i,permitStorage:a}=se(n.storage,n.permitStorage),o=new le(n.chains,n.relayers);return{chains:n.chains,router:o,provider:t,signer:e,storage:i,permitStorage:a,transportKeyPairTTL:Y(R,n.transportKeyPairTTL??2592e3),permitTTL:Y(z,n.permitTTL??30),transportKeyPairScope:n.transportKeyPairScope===void 0?void 0:Y(B,n.transportKeyPairScope),registryTTL:Y(Z,n.registryTTL??86400),logger:r,onEvent:n.onEvent}}function ke(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;ke(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 Ae(e){return new $(e)}var je=class{walletAccount;#e=!1;constructor(e){this.walletAccount=new $(e)}requireWalletAccount(e){let t=this.walletAccount.getSnapshot();if(!t)throw new a(e);return t}dispose(){this.#e||(this.#e=!0,this.onDispose())}[Symbol.dispose](){this.dispose()}onDispose(){}};export{X as a,D as c,E as d,ae as f,Oe as i,k as l,ie as m,$ as n,De as o,T as p,Ae as r,we as s,je as t,O as u};
2
+ //# sourceMappingURL=base-signer-YpkEmlp2.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base-signer-YpkEmlp2.js","names":["#dbName","#dbVersion","#storeName","#db","#dbPromise","#withTransaction","#getDB","#map","#chains","#relayers","#chainId","#generator","#storage","#ttl","#logger","#scope","#pending","#epoch","#readByKey","#identityKey","#getOrCreateByKey","#storage","#logger","#deleteScope","#untrackScope","#trackScope","#readIndex","#vault","#store","#router","#signer","#permitTTL","#logger","#scope","#signPermit","#logger","#prefix","#addresses","#ttlMs","#cache","#getCached","#setCached","#pairWithMetadata","#listeners","#snapshot","#resolved","#emit","#disposed"],"sources":["../../src/storage/indexeddb-storage.ts","../../src/storage/memory-storage.ts","../../src/config/resolve.ts","../../src/chains/router.ts","../../src/schemas/primitives.ts","../../src/credentials/utils.ts","../../src/credentials/schemas.ts","../../src/credentials/storage-keys.ts","../../src/credentials/keypair-vault.ts","../../src/credentials/permissions.ts","../../src/credentials/permission-store.ts","../../src/credentials/credential-service.ts","../../src/services/logger-service.ts","../../src/validation.ts","../../src/wrappers-registry.ts","../../src/config/build.ts","../../src/signer/wallet-account-store.ts","../../src/signer/base-signer.ts"],"sourcesContent":["\"use client\";\n\nimport type { GenericStorage } from \"../types\";\n\n/**\n * IndexedDB-backed {@link GenericStorage}.\n *\n * Stores keypair and permit objects keyed by a hashed wallet address. The\n * SDK delegates security to the storage backend — values are persisted\n * verbatim with no SDK-layer encryption.\n */\nexport class IndexedDBStorage implements GenericStorage {\n #db: IDBDatabase | null = null;\n #dbPromise: Promise<IDBDatabase> | null = null;\n #dbName: string;\n #dbVersion: number;\n #storeName: string;\n\n constructor(dbName = \"CredentialStore\", dbVersion = 1, storeName = \"credentials\") {\n this.#dbName = dbName;\n this.#dbVersion = dbVersion;\n this.#storeName = storeName;\n }\n\n #getDB(): Promise<IDBDatabase> {\n if (this.#db) {\n return Promise.resolve(this.#db);\n }\n if (this.#dbPromise) {\n return this.#dbPromise;\n }\n\n this.#dbPromise = new Promise((resolve, reject) => {\n const request = indexedDB.open(this.#dbName, this.#dbVersion);\n\n request.onupgradeneeded = () => {\n const db = request.result;\n if (!db.objectStoreNames.contains(this.#storeName)) {\n db.createObjectStore(this.#storeName, { keyPath: \"key\" });\n }\n };\n\n request.onsuccess = () => {\n this.#db = request.result;\n this.#dbPromise = null;\n this.#db.onversionchange = () => {\n // Another tab upgraded the DB; close our handle so it can proceed.\n // Informational only and self-healing, so emit nothing to the console.\n this.#db?.close();\n this.#db = null;\n this.#dbPromise = null;\n };\n this.#db.onclose = () => {\n this.#db = null;\n this.#dbPromise = null;\n };\n resolve(this.#db);\n };\n\n request.onerror = () => {\n this.#db = null;\n this.#dbPromise = null;\n reject(request.error);\n };\n });\n\n return this.#dbPromise;\n }\n\n async #withTransaction<T>(\n mode: IDBTransactionMode,\n fn: (store: IDBObjectStore) => IDBRequest,\n ): Promise<T> {\n const db = await this.#getDB();\n return new Promise((resolve, reject) => {\n const tx = db.transaction(this.#storeName, mode);\n tx.onabort = () => reject(tx.error ?? new Error(\"Transaction aborted\"));\n const request = fn(tx.objectStore(this.#storeName));\n if (mode === \"readonly\") {\n request.onsuccess = () => resolve(request.result);\n } else {\n tx.oncomplete = () => resolve(request.result);\n }\n request.onerror = () => reject(request.error);\n });\n }\n\n /**\n * Retrieve a value by key.\n * @returns The stored value, or `null` if the key does not exist.\n */\n async get<T = unknown>(key: string): Promise<T | null> {\n const result = await this.#withTransaction<{ value: T } | undefined>(\"readonly\", (store) =>\n store.get(key),\n );\n return result?.value ?? null;\n }\n\n /** Store a value under the given key, overwriting any existing entry. */\n async set<T = unknown>(key: string, value: T): Promise<void> {\n await this.#withTransaction<void>(\"readwrite\", (store) => store.put({ key, value }));\n }\n\n /** Remove the entry for the given key (no-op if absent). */\n async delete(key: string): Promise<void> {\n await this.#withTransaction<void>(\"readwrite\", (store) => store.delete(key));\n }\n\n /** Remove all stored entries. */\n async clear(): Promise<void> {\n await this.#withTransaction<void>(\"readwrite\", (store) => store.clear());\n }\n}\n\n/** Default singleton for application-wide use. */\nexport const indexedDBStorage = new IndexedDBStorage();\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 /**\n * Retrieve a value by key.\n * @returns The stored value, or `null` if the key does not exist.\n */\n async get<T = unknown>(key: string): Promise<T | null> {\n return (this.#map.get(key) as T) ?? null;\n }\n\n /** Store a value under the given key, overwriting any existing entry. */\n async set<T = unknown>(key: string, value: T): Promise<void> {\n this.#map.set(key, value);\n }\n\n /** Remove the entry for the given key (no-op if absent). */\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\n/** @internal */\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\n/** @internal */\nexport interface ResolvedChainRelayer {\n chain: FheChain;\n relayerConfig: RelayerConfig;\n}\n\n/** @internal */\nexport function resolveChainRelayers(\n chains: readonly FheChain[],\n relayers: Readonly<Record<number, RelayerConfig>>,\n): Map<number, ResolvedChainRelayer> {\n const chainMap = new Map<number, FheChain>(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 chain = 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 (!chain) {\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, { chain, relayerConfig });\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 { FheChain } from \"./types\";\nimport { resolveChainRelayers } from \"../config/resolve\";\nimport type { RelayerConfig } from \"../config/types\";\nimport { ConfigurationError } from \"../errors\";\nimport type { RelayerSDK } from \"../relayer/types\";\n\n/**\n * Multichain router. Owns chain management (chains / chain / switchChain) and\n * hands out the single-chain {@link RelayerSDK} backend for the currently active\n * chain via {@link ChainRouter.relayer}. Builds one backend per chain from its\n * {@link RelayerConfig}.\n *\n * @internal\n */\nexport class ChainRouter {\n readonly #chains: Map<number, FheChain>;\n readonly #relayers: Map<number, RelayerSDK>;\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 // One backend per chain. A shared config object can yield the same backend\n // instance for several chains (createRelayer decides); terminate() dedupes.\n const relayers = new Map<number, RelayerSDK>();\n for (const [chainId, { relayerConfig, chain }] of resolveChainRelayers(chains, configs)) {\n relayers.set(chainId, relayerConfig.createRelayer(chain));\n }\n this.#relayers = relayers;\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 if (chain === undefined) {\n throw new ConfigurationError(\n `Chain ${this.#chainId} is not configured. Add it to the chains array.`,\n );\n }\n return chain;\n }\n\n /**\n * Point the router at `chainId`. The active chain follows the wallet even when\n * that chain has no configured backend: the {@link chain} / {@link relayer}\n * getters throw a {@link ConfigurationError} for an unconfigured chain, so an\n * unsupported chain fails loudly at the next operation rather than silently\n * routing to the previously active chain (which would encrypt against, and\n * sign an EIP-712 decryption permit for, the wrong chain's domain and ACL).\n * Switching back to a configured chain restores service.\n */\n switchChain(chainId: number): void {\n this.#chainId = chainId;\n }\n\n /** The single-chain backend for the currently active chain. */\n get relayer(): RelayerSDK {\n const relayer = this.#relayers.get(this.chain.id);\n if (relayer === undefined) {\n throw new ConfigurationError(\n `No relayer configured for chain ${this.#chainId}. Add it to the relayers object.`,\n );\n }\n return relayer;\n }\n}\n","import { type Address, getAddress, isAddress, isHex, type Hex } from \"viem\";\nimport { z } from \"zod/mini\";\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.custom<Hex>(\n (v) => typeof v === \"string\" && isHex(v, { strict: true }),\n \"expected 0x-prefixed hex string\",\n);\n\n/** Validates an EVM address string. Output type is `Address` (`` `0x${string}` ``). */\nexport const evmAddress = z.custom<Address>(\n (v) => typeof v === \"string\" && isAddress(v, { strict: false }),\n \"expected EVM address\",\n);\n\n/** Validates and EIP-55 checksums an EVM address. Output is {@link ChecksummedAddress}. */\nexport const checksummedAddress = z.pipe(evmAddress, z.transform(checksum));\n\n/** Non-negative integer Unix timestamp in seconds. */\nexport const unixSeconds = z.int().check(z.nonnegative());\n\n/** Positive integer count of seconds (e.g. a TTL). */\nexport const positiveSeconds = z.int().check(z.positive());\n\n/** Non-negative integer count of seconds (e.g. a cache TTL where 0 disables caching). */\nexport const nonNegativeSeconds = z.int().check(z.nonnegative());\n\n/** Positive integer count of days (e.g. a permit duration). */\nexport const positiveDays = z.int().check(z.positive());\n\n/** Positive integer EVM chain ID. */\nexport const chainId = z.int().check(z.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/mini\";\nimport {\n checksummedAddress,\n hex,\n positiveDays,\n positiveSeconds,\n unixSeconds,\n} from \"../schemas/primitives\";\nimport { MAX_CONTRACTS_PER_PERMIT, SECONDS_PER_DAY } from \"./utils\";\n\nconst transportKeyPairTTLError = \"transportKeyPairTTL must be a positive integer number of seconds\";\nconst permitTTLError = \"permitTTL must be a positive integer number of days\";\nconst transportKeyPairScopeError = \"transportKeyPairScope must be a non-empty string\";\n\n/** Maximum transportKeyPairTTL accepted by the fhevm ACL contract (365 days, in seconds). */\nexport const MAX_TRANSPORT_KEY_PAIR_TTL_SECONDS = 365 * SECONDS_PER_DAY;\n\n// z.int already rejects NaN, Infinity, and non-integers, so it covers\n// the previous .finite() + .int() combo with a single schema.\nexport const TransportKeyPairTTLSchema = z\n .int({ error: transportKeyPairTTLError })\n .check(\n z.positive({ error: transportKeyPairTTLError }),\n z.maximum(\n MAX_TRANSPORT_KEY_PAIR_TTL_SECONDS,\n `transportKeyPairTTL must not exceed the fhevm ACL maximum of ${MAX_TRANSPORT_KEY_PAIR_TTL_SECONDS}s (365 days)`,\n ),\n );\n\nexport const PermitTTLSchema = z\n .int({ error: permitTTLError })\n .check(z.positive({ error: permitTTLError }));\n\nexport const TransportKeyPairScopeSchema = z\n .string({ error: transportKeyPairScopeError })\n .check(z.minLength(1, transportKeyPairScopeError));\n\n/** @internal */\nexport const StoredTransportKeyPairSchema = z.object({\n publicKey: hex,\n privateKey: hex,\n createdAt: unixSeconds,\n expiresAt: positiveSeconds,\n tkmsVersion: z.optional(z.string()),\n});\n\nexport const Eip712Schema = z.object({\n domain: z.record(z.string(), z.unknown()),\n primaryType: z.optional(z.string()),\n types: z.record(z.string(), z.array(z.object({ name: z.string(), type: z.string() }))),\n message: z.record(z.string(), z.unknown()),\n});\n\nexport const SerializedPermitSchema = z.object({\n version: z.int().check(z.positive()),\n eip712: Eip712Schema,\n signature: hex,\n signerAddress: checksummedAddress,\n});\n\n/** @internal */\nexport const PermissionSchema = z.object({\n keypairPublicKey: hex,\n contractAddresses: z.array(checksummedAddress).check(z.maxLength(MAX_CONTRACTS_PER_PERMIT)),\n serializedPermit: SerializedPermitSchema,\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 { ChecksummedAddress } from \"../schemas/primitives\";\n\nexport interface PermissionScope {\n signerAddress: ChecksummedAddress;\n chainId: number;\n delegatorAddress: ChecksummedAddress;\n}\n\nexport function transportKeyPairStorageKey(signerAddress: ChecksummedAddress): string {\n // The \"keypair:\" prefix is intentionally preserved for back-compat with already-persisted entries.\n return `keypair:${signerAddress}`;\n}\n\n/**\n * Storage key for a scope-shared transport key pair (opt-in, B2B2C/WaaS operators).\n * Namespaced under \"keypair:scope:\" so it can never collide with a per-signer key,\n * whose suffix is always a checksummed `0x`-address.\n */\nexport function transportKeyPairScopeStorageKey(scope: string): string {\n return `keypair:scope:${scope}`;\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 { SerializeTransportKeyPairReturnType } from \"@fhevm/sdk/actions/chain\";\nimport type { ChecksummedAddress } from \"../schemas/primitives\";\nimport type { GenericLogger, GenericStorage } from \"../types\";\nimport { swallow } from \"../utils/swallow\";\nimport { StoredTransportKeyPairSchema } from \"./schemas\";\nimport { transportKeyPairScopeStorageKey, transportKeyPairStorageKey } from \"./storage-keys\";\nimport type { StoredTransportKeyPair } from \"./types\";\nimport { nowSeconds } from \"./utils\";\n\ninterface TransportKeyPairVaultConfig {\n generator: () => Promise<SerializeTransportKeyPairReturnType>;\n storage: GenericStorage;\n /** Transport key pair lifetime in seconds. Pre-validated by the caller. */\n ttl: number;\n /** SDK-wide logger for best-effort storage diagnostics. */\n logger: GenericLogger;\n /**\n * Opt-in shared-tenant scope (B2B2C/WaaS). When set, every signer configured with\n * this scope reads/creates the *same* key pair instead of one per signer address.\n * Undefined preserves the default per-signer behavior.\n */\n scope?: string;\n}\n\n/**\n * Identity-scoped, chain-independent vault for ML-KEM transport key pairs.\n *\n * One transport key pair per signer address by default; the key pair survives chain\n * switches and permit revocations. When `scope` is configured, reads/creates key\n * off the shared scope identity instead of the signer address. {@link clear} always\n * targets the per-signer key regardless of scope — an individual signer's teardown must\n * never delete a scope's shared key pair. Only {@link clearScope} can do that.\n */\nexport class TransportKeyPairVault {\n readonly #generator: () => Promise<SerializeTransportKeyPairReturnType>;\n readonly #storage: GenericStorage;\n readonly #ttl: number;\n readonly #logger: GenericLogger;\n readonly #scope: string | undefined;\n readonly #pending = new Map<string, Promise<StoredTransportKeyPair>>();\n /**\n * Per-key generation counter, bumped by {@link clearScope}. Lets a generation that\n * was already in flight when a rotation happened detect it's stale once its\n * `#generator()` round trip completes, so it skips persisting a key that would\n * silently resurrect the one the rotation just deleted.\n */\n readonly #epoch = new Map<string, number>();\n\n constructor(config: TransportKeyPairVaultConfig) {\n this.#generator = config.generator;\n this.#storage = config.storage;\n this.#ttl = config.ttl;\n this.#logger = config.logger;\n this.#scope = config.scope;\n }\n\n /** Storage identity for reads/creates: the shared scope key when configured, else the per-signer key. */\n #identityKey(signerAddress: ChecksummedAddress): string {\n return this.#scope !== undefined\n ? transportKeyPairScopeStorageKey(this.#scope)\n : transportKeyPairStorageKey(signerAddress);\n }\n\n async readStored(signerAddress: ChecksummedAddress): Promise<StoredTransportKeyPair | null> {\n return this.#readByKey(this.#identityKey(signerAddress));\n }\n\n async #readByKey(key: string): Promise<StoredTransportKeyPair | null> {\n const raw = await this.#storage.get(key);\n if (raw === null || raw === undefined) {\n return null;\n }\n const parsed = StoredTransportKeyPairSchema.safeParse(raw);\n if (!parsed.success) {\n await swallow(\n \"delete transport key pair entry\",\n () => this.#storage.delete(key),\n this.#logger,\n );\n return null;\n }\n const stored = parsed.data;\n if (nowSeconds() >= stored.expiresAt) {\n await swallow(\n \"delete transport key pair entry\",\n () => this.#storage.delete(key),\n this.#logger,\n );\n return null;\n }\n return stored;\n }\n\n /**\n * Return the cached transport key pair, generating and persisting a fresh one if absent or expired.\n *\n * @remarks Deduplicates concurrent calls within this process. Across separate\n * processes/instances sharing a scope, two first-time callers can still race the\n * underlying storage — unlike the per-signer version of this race, the loser here can\n * be a *different* end-user, whose existing permit then gets silently pruned as stale.\n * Pre-warm a scope once via {@link warmScope} before opening concurrent traffic to\n * avoid hitting this with a whole cohort at once.\n */\n async getOrCreate(signerAddress: ChecksummedAddress): Promise<StoredTransportKeyPair> {\n return this.#getOrCreateByKey(this.#identityKey(signerAddress));\n }\n\n /**\n * @param strict - When `true`, a `storage.set` failure during persistence rejects\n * instead of being logged and swallowed. Used by {@link warmScope}, which — like\n * {@link clearScope} — must not resolve successfully while its write silently failed.\n */\n async #getOrCreateByKey(\n identityKey: string,\n options?: { strict?: boolean },\n ): Promise<StoredTransportKeyPair> {\n const strict = options?.strict ?? false;\n // Keyed on (identityKey, strict), not identityKey alone: a strict caller\n // (warmScope) and a non-strict caller (getOrCreate) can target the same shared\n // scope identity, and must never adopt each other's persistence guarantee —\n // whichever registers first would otherwise silently impose its strictness on\n // the other. See the strict param doc above.\n const pendingKey = `${identityKey}::${strict}`;\n const existing = this.#pending.get(pendingKey);\n if (existing) {\n return existing;\n }\n\n const epochAtStart = this.#epoch.get(identityKey) ?? 0;\n\n const promise = (async () => {\n const cached = await this.#readByKey(identityKey);\n if (cached !== null) {\n return cached;\n }\n const fresh = await this.#generator();\n const createdAt = nowSeconds();\n const stored: StoredTransportKeyPair = {\n publicKey: fresh.publicKey,\n privateKey: fresh.privateKey,\n createdAt,\n expiresAt: createdAt + this.#ttl,\n };\n // Persist the TKMS version so a later parse deserializes the private key\n // under the version it was generated with, surviving a KMS/TKMS rotation.\n if (fresh.tkmsVersion) {\n stored.tkmsVersion = fresh.tkmsVersion;\n }\n // If a rotation bumped this key's epoch while `#generator()` was in flight, this\n // generation started before the rotation and must not persist — doing so would\n // silently resurrect the key the rotation just deleted (see `clearScope`). The\n // freshly generated key pair is still returned to whichever caller triggered this\n // round trip so their in-flight request succeeds; the next access regenerates and\n // persists properly against the new epoch.\n if ((this.#epoch.get(identityKey) ?? 0) === epochAtStart) {\n if (options?.strict) {\n await this.#storage.set(identityKey, stored);\n } else {\n await swallow(\n \"persist transport key pair\",\n () => this.#storage.set(identityKey, stored),\n this.#logger,\n );\n }\n }\n return stored;\n })().finally(() => {\n this.#pending.delete(pendingKey);\n });\n\n this.#pending.set(pendingKey, promise);\n return promise;\n }\n\n /**\n * Delete the stored transport key pair for the given signer address.\n *\n * Always targets the per-signer key, never the shared scope key — even when this\n * vault is configured with a scope. Signer-level teardown (disconnect, revoke) must\n * never take down a shared-tenant key pair; use {@link clearScope} for that.\n *\n * Best-effort: a storage failure is logged and swallowed. Worst case, one signer's\n * stale key lingers until its TTL — a low-stakes, self-correcting outcome.\n */\n async clear(signerAddress: ChecksummedAddress): Promise<void> {\n const key = transportKeyPairStorageKey(signerAddress);\n await swallow(\"delete transport key pair entry\", () => this.#storage.delete(key), this.#logger);\n }\n\n /**\n * Delete the stored key pair for this identity so the next {@link getOrCreate}\n * regenerates it. Unlike {@link clear}, this is **scope-aware** — it targets the\n * shared scope key when a scope is configured, else the per-signer key.\n *\n * The self-heal primitive for a key pair the relayer rejects as invalid (e.g. a\n * TKMS-version mismatch after a KMS rotation, which surfaces as\n * `invalid TransportKeyPairKeyPair`): the stored bytes can no longer be parsed,\n * so dropping and regenerating them is the only recovery. Best-effort — a\n * storage failure is logged and swallowed, so a wedged entry is retried on the\n * next call rather than hard-failing the current one.\n */\n async evict(signerAddress: ChecksummedAddress): Promise<void> {\n const key = this.#identityKey(signerAddress);\n await swallow(\"evict transport key pair entry\", () => this.#storage.delete(key), this.#logger);\n }\n\n /**\n * Delete the shared scope's transport key pair (operator-level rotation).\n *\n * Every permit in the scope embeds the old key pair's public key, so once it's gone,\n * `pruneUnusable` drops all of them as stale on next access — no separate permit\n * cleanup needed. No-op if no scope is configured on this vault.\n *\n * Unlike {@link clear}, this is **not** best-effort: a storage failure propagates\n * instead of being swallowed. This is the primitive operators reach for on suspected\n * key compromise — a caller that gets a resolved promise must be able to trust that\n * the key pair is actually gone, not silently still live because a transient storage\n * error (exactly the kind of failure likely during an incident) was logged and\n * dropped.\n *\n * Also bumps the key's generation epoch *before* deleting, so a `getOrCreate`/\n * `warmScope` generation already in flight for this same scope discards its result\n * instead of persisting it once the round trip completes — otherwise that write would\n * land after this delete and silently resurrect the key this call just removed. This\n * relies on the backing {@link GenericStorage} applying same-key writes in dispatch\n * order — true for `MemoryStorage` and conventional stores, but a custom async\n * adapter without that guarantee could still let an in-flight `set` land after this\n * `delete`.\n */\n async clearScope(): Promise<void> {\n if (this.#scope === undefined) {\n return;\n }\n const key = transportKeyPairScopeStorageKey(this.#scope);\n this.#epoch.set(key, (this.#epoch.get(key) ?? 0) + 1);\n await this.#storage.delete(key);\n }\n\n /**\n * Generate and persist the shared scope's transport key pair if absent — the\n * pre-warm counterpart to {@link clearScope}. No-op if no scope is configured.\n *\n * Unlike {@link getOrCreate}, this needs no signer address at all: a scoped identity\n * never depends on one. Operators use this to warm a scope once, deliberately,\n * before opening concurrent traffic to it — see the class docs on {@link getOrCreate}\n * for why that avoids a thundering-herd race across the whole cohort.\n *\n * Not best-effort: like {@link clearScope}, a `storage.set` failure during persistence\n * propagates instead of being swallowed. A resolved promise here is meant to mean the\n * key pair is actually warmed in shared storage — an operator pre-warming ahead of\n * traffic to avoid the thundering-herd race must be able to trust that, not silently\n * still be exposed to it because a transient write failure was logged and dropped.\n */\n async warmScope(): Promise<void> {\n if (this.#scope === undefined) {\n return;\n }\n await this.#getOrCreateByKey(transportKeyPairScopeStorageKey(this.#scope), { strict: true });\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.contractAddresses));\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.contractAddresses.some((a) => removeSet.has(a)));\n}\n\n/** Deduplicate and sort the union of two pre-checksummed address lists. */\nexport function sortedUnion<T extends string>(a: readonly T[], b: readonly T[]): T[] {\n return [...new Set([...a, ...b])].toSorted();\n}\n\n/**\n * Find the in-scope permit best suited to be widened with `uncovered`.\n *\n * Returns the permit whose `contractAddresses ∪ uncovered` still fits\n * the 10-contract cap and that has the largest overlap with `requested`. Ties\n * broken by most-recent `startTimestamp`. Returns `null` when none fits.\n */\nexport function findPermitToWiden(\n permissions: readonly Permission[],\n uncovered: readonly ChecksummedAddress[],\n requested: readonly ChecksummedAddress[],\n): Permission | null {\n const requestedSet = new Set(requested);\n const feasible = permissions.filter(\n (p) => new Set([...p.contractAddresses, ...uncovered]).size <= MAX_CONTRACTS_PER_PERMIT,\n );\n if (feasible.length === 0) {\n return null;\n }\n\n function overlap(p: Permission) {\n return p.contractAddresses.reduce((n, a) => n + (requestedSet.has(a) ? 1 : 0), 0);\n }\n\n const maxOverlap = Math.max(...feasible.map(overlap));\n const topTier = feasible.filter((p) => overlap(p) === maxOverlap);\n return topTier.reduce((a, b) => (b.startTimestamp > a.startTimestamp ? b : a));\n}\n","import type { Hex } from \"viem\";\nimport type { GenericLogger, 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 /** SDK-wide logger for best-effort storage diagnostics. */\n logger: GenericLogger;\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 readonly #logger: GenericLogger;\n\n constructor(config: PermissionStoreConfig) {\n this.#storage = config.storage;\n this.#logger = config.logger;\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), this.#logger);\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 * Replace the entry identified by `oldSignature` with `newPermission`.\n *\n * Atomic relative to the storage backend's `set`: the old entry survives in\n * storage until the new list is written. If `oldSignature` is not found\n * (raced eviction or concurrent prune), `newPermission` is still persisted —\n * equivalent to {@link append}.\n */\n async replace(\n scope: PermissionScope,\n oldSignature: Hex,\n newPermission: Permission,\n ): Promise<void> {\n const validated = PermissionSchema.parse(newPermission);\n const existing = await this.list(scope);\n const filtered = existing.filter((p) => p.serializedPermit.signature !== oldSignature);\n await this.#storage.set(permissionScopeKey(scope), [...filtered, 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 `contractAddresses`, 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), this.#logger);\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), this.#logger);\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), this.#logger);\n } else {\n await swallow(\"update permit index\", () => this.#storage.set(indexKey, next), this.#logger);\n }\n }\n\n async #deleteScope(scopeKey: string): Promise<void> {\n await swallow(\"delete permit entry\", () => this.#storage.delete(scopeKey), this.#logger);\n }\n}\n","import type { Address } from \"viem\";\nimport type { ChainRouter } from \"../chains/router\";\nimport { ZamaError } from \"../errors/base\";\nimport { ConfigurationError } from \"../errors/relayer\";\nimport { wrapSigningError } from \"../errors/signing\";\nimport type { ChecksummedAddress } from \"../schemas/primitives\";\nimport { checksum } from \"../schemas/primitives\";\nimport type { GenericLogger, GenericSigner, GenericStorage } from \"../types\";\nimport { isInvalidTransportKeyPairMessage } from \"../utils/error\";\nimport { swallow } from \"../utils/swallow\";\nimport { TransportKeyPairVault } from \"./keypair-vault\";\nimport { PermissionStore } from \"./permission-store\";\nimport { chunkContracts, findPermitToWiden, sortedUnion, uncoveredContracts } from \"./permissions\";\nimport { SerializedPermitSchema } from \"./schemas\";\nimport type { PermissionScope } from \"./storage-keys\";\nimport type {\n Permission,\n SerializedTransportKeyPairWithPermissions,\n StoredTransportKeyPair,\n} from \"./types\";\nimport { normalizeAddresses, nowSeconds, SECONDS_PER_DAY } from \"./utils\";\n\nexport const DEFAULT_TRANSPORT_KEY_PAIR_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 router: ChainRouter;\n signer: GenericSigner;\n /** Transport key pair lifetime in seconds. Pre-validated. */\n transportKeyPairTTL: number;\n /** Permit lifetime in days. Pre-validated. */\n permitTTL: number;\n /** Backing storage for transport key pairs (and permits if `permitStorage` is omitted). */\n storage: GenericStorage;\n /** Optional dedicated storage for permits; defaults to `storage`. */\n permitStorage?: GenericStorage;\n /** SDK-wide logger for credential-path diagnostics. */\n logger: GenericLogger;\n /**\n * Opt-in shared-tenant scope (B2B2C/WaaS operators). When set, every signer\n * configured with the same scope shares one transport key pair instead of one\n * per signer address. Permits stay per-signer regardless — see\n * {@link revokeTransportKeyPair} for the operator-level counterpart to\n * signer-level revocation.\n */\n scope?: string;\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 *\n * Two distinct revocation tiers exist and must not be conflated: {@link clearCredentials}\n * (signer-level, e.g. an end-user \"disconnect\") only ever removes that signer's own\n * key-pair slot and permits — when a scope is configured, the shared key pair was never\n * stored there, so it's untouched. {@link revokeTransportKeyPair} (operator-level) is\n * the only way to invalidate a scope's shared key pair, and it does so for every signer\n * in the scope at once.\n *\n * @internal\n */\nexport class CredentialService {\n readonly #vault: TransportKeyPairVault;\n readonly #store: PermissionStore;\n readonly #router: ChainRouter;\n readonly #signer: GenericSigner;\n readonly #permitTTL: number;\n readonly #logger: GenericLogger;\n readonly #scope: string | undefined;\n\n constructor(config: CredentialServiceConfig) {\n this.#vault = new TransportKeyPairVault({\n generator: async () => {\n const relayer = config.router.relayer;\n const transportKeyPair = await relayer.generateTransportKeyPair();\n return relayer.serializeTransportKeyPair({ transportKeyPair });\n },\n storage: config.storage,\n ttl: config.transportKeyPairTTL,\n logger: config.logger,\n scope: config.scope,\n });\n this.#store = new PermissionStore({\n storage: config.permitStorage ?? config.storage,\n logger: config.logger,\n });\n this.#router = config.router;\n this.#signer = config.signer;\n this.#permitTTL = config.permitTTL;\n this.#logger = config.logger;\n this.#scope = config.scope;\n }\n\n /**\n * Resolve a keypair and permissions covering `contracts`, minimizing wallet\n * prompts by reusing or widening existing permits where possible. Empty\n * `contracts` warms the keypair without prompting.\n *\n * @returns The resolved keypair and permits covering the requested contracts.\n * @throws if the user rejects a wallet signature prompt. {@link SigningRejectedError}\n * @throws if signing fails for any other reason. {@link SigningFailedError}\n */\n async grantPermit(\n contracts: readonly Address[],\n delegator?: Address,\n ): Promise<SerializedTransportKeyPairWithPermissions> {\n const account = this.#signer.requireWalletAccount(\"grantPermit\");\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, permissions: [] };\n }\n\n // Key permits by the router's active chain — the same source the permit's\n // EIP-712 domain is signed against (#signPermit uses this.#router.relayer) —\n // so the storage key and the signature can never disagree on the chain.\n const chainId = this.#router.chain.id;\n const scope: PermissionScope = {\n signerAddress,\n chainId,\n delegatorAddress: delegator ? checksum(delegator) : signerAddress,\n };\n const permissions = await this.#store.listUsableAndPrune(scope, keypair.publicKey);\n\n const uncovered = uncoveredContracts(permissions, requested);\n if (uncovered.length > 0) {\n const candidate = findPermitToWiden(permissions, uncovered, requested);\n if (candidate !== null) {\n const widenedSet = sortedUnion(candidate.contractAddresses, uncovered);\n const widened = await this.#signPermit({ chunk: widenedSet, keypair, scope });\n await swallow(\n \"replace permit\",\n () => this.#store.replace(scope, candidate.serializedPermit.signature, widened),\n this.#logger,\n );\n permissions[permissions.indexOf(candidate)] = widened;\n } else {\n for (const chunk of chunkContracts(uncovered)) {\n const permission = await this.#signPermit({ chunk, keypair, scope });\n permissions.push(permission);\n await swallow(\n \"persist permit\",\n () => this.#store.append(scope, [permission]),\n this.#logger,\n );\n }\n }\n }\n\n const requestedSet = new Set(requested);\n return {\n keypair,\n permissions: permissions.filter((p) => p.contractAddresses.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 hasPermit(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 = this.#router.chain.id;\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 if reading the signer address fails. {@link SigningFailedError}\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 = this.#router.chain.id;\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 * Signer-level only: when a scope is configured, the shared key pair was never\n * stored under this signer's own slot, so it survives untouched — only this\n * signer's permits are removed. Use {@link revokeTransportKeyPair} to invalidate\n * the shared key pair itself.\n *\n * @throws if reading the signer address fails. {@link SigningFailedError}\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 * Revoke this scope's shared transport key pair (operator-level action).\n *\n * Deletes the shared key pair. Every permit signed under it embeds the old\n * public key, so `listUsableAndPrune` treats them all as stale on next access —\n * no permit is touched directly, and no connected wallet is required. This is\n * the only operation that can invalidate a shared key pair; signer-level\n * {@link clearCredentials} never does.\n *\n * Not best-effort: unlike {@link clearCredentials}, a storage failure here rejects\n * instead of being logged and swallowed — see {@link TransportKeyPairVault.clearScope}.\n *\n * Only stops the SDK from reissuing or reusing the deleted key going forward — does\n * not revoke any permit already issued under it. A permit is a self-contained,\n * bearer-style EIP-712 signature the relayer accepts independently of this SDK's\n * storage; one already exfiltrated alongside the key remains usable until its own\n * `permitTTL` expiry regardless of this call.\n *\n * @param scopeId - Must match the scope this service was configured with. Requiring\n * the caller to name it guards against revoking the wrong scope by mistake.\n * @throws if no scope is configured, or `scopeId` doesn't match it. {@link ConfigurationError}\n * @throws if the underlying storage delete fails.\n */\n async revokeTransportKeyPair(scopeId: string): Promise<void> {\n if (this.#scope === undefined) {\n throw new ConfigurationError(\n \"revokeTransportKeyPair() requires a transportKeyPairScope to be configured on this SDK instance — there is no shared key pair to revoke.\",\n );\n }\n if (scopeId !== this.#scope) {\n throw new ConfigurationError(\n `revokeTransportKeyPair(\"${scopeId}\") does not match the configured scope (\"${this.#scope}\").`,\n );\n }\n await this.#vault.clearScope();\n }\n\n /**\n * Warm the signer transport key pair cache for a known address.\n *\n * Best-effort prefetch primitive: correctness still comes from `grantPermit`,\n * which lazily creates the transport key pair when needed. Errors (storage failure,\n * relayer 4xx, missing Worker in SSR) are **not** swallowed here — the caller\n * decides whether to log, ignore, or surface them.\n *\n * Not for pre-warming a shared scope: `address` is ignored for storage keying once\n * a scope is configured (see {@link TransportKeyPairVault}), so this call's actual\n * effect wouldn't match its apparent per-signer intent. Use\n * {@link warmTransportKeyPairScope} instead.\n */\n async warmTransportKeyPair(address: Address): Promise<void> {\n await this.#vault.getOrCreate(checksum(address));\n }\n\n /**\n * Warm this scope's shared transport key pair (operator-level, no wallet needed) —\n * the pre-warm counterpart to {@link revokeTransportKeyPair}.\n *\n * @param scopeId - Must match the scope this service was configured with. Requiring\n * the caller to name it guards against warming the wrong scope by mistake.\n * @throws if no scope is configured, or `scopeId` doesn't match it. {@link ConfigurationError}\n */\n async warmTransportKeyPairScope(scopeId: string): Promise<void> {\n if (this.#scope === undefined) {\n throw new ConfigurationError(\n \"warmTransportKeyPairScope() requires a transportKeyPairScope to be configured on this SDK instance — there is no shared key pair to warm.\",\n );\n }\n if (scopeId !== this.#scope) {\n throw new ConfigurationError(\n `warmTransportKeyPairScope(\"${scopeId}\") does not match the configured scope (\"${this.#scope}\").`,\n );\n }\n await this.#vault.warmScope();\n }\n\n /**\n * Apply a wallet account transition.\n *\n * Address change clears persisted credentials for the previous account.\n * Chain-only changes keep credentials intact because permits are chain-scoped\n * already and stale decrypt plaintext is cleared by `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 }\n\n async #signPermit(input: {\n chunk: ChecksummedAddress[];\n keypair: StoredTransportKeyPair;\n scope: PermissionScope;\n }): Promise<Permission> {\n const { chunk, keypair, scope } = input;\n const startTimestamp = nowSeconds();\n const isDelegated = scope.delegatorAddress !== scope.signerAddress;\n const relayer = this.#router.relayer;\n try {\n const transportKeyPair = await relayer.parseTransportKeyPair(keypair);\n const permitInput = {\n transportKeyPair,\n contractAddresses: chunk,\n startTimestamp,\n durationSeconds: this.#permitTTL * SECONDS_PER_DAY,\n signerAddress: scope.signerAddress,\n signer: this.#signer,\n };\n const signedPermit = isDelegated\n ? await relayer.signDecryptionPermit({\n ...permitInput,\n delegatorAddress: scope.delegatorAddress,\n })\n : await relayer.signDecryptionPermit(permitInput);\n\n const serializedPermit = SerializedPermitSchema.parse(\n await relayer.serializeSignedDecryptionPermit({ signedPermit }),\n );\n\n return {\n keypairPublicKey: keypair.publicKey,\n contractAddresses: chunk,\n serializedPermit,\n startTimestamp,\n durationDays: this.#permitTTL,\n };\n } catch (error) {\n if (error instanceof ZamaError) {\n throw error;\n }\n // A key pair the relayer can't re-derive (post KMS/TKMS rotation) is\n // unusable: evict it so the next grantPermit regenerates a valid one, then\n // surface the typed InvalidTransportKeyPairError via wrapSigningError.\n if (error instanceof Error && isInvalidTransportKeyPairMessage(error.message)) {\n await this.#vault.evict(scope.signerAddress);\n }\n throw wrapSigningError(error, \"Credential signing failed\");\n }\n }\n\n /**\n * Evict the current signer's transport key pair so the next credential\n * resolution regenerates it — the self-heal hook the decrypt path calls when\n * the relayer rejects the stored key pair as invalid (see\n * {@link InvalidTransportKeyPairError}). No-op when no wallet is connected;\n * best-effort, never throws.\n */\n async evictTransportKeyPair(): Promise<void> {\n const account = this.#signer.walletAccount.getSnapshot();\n if (!account) {\n return;\n }\n await this.#vault.evict(checksum(account.address));\n }\n}\n","import type { GenericLogger } from \"../types\";\n\n/**\n * Internal logger with a consistent, always-present shape.\n *\n * The consumer supplies an optional {@link GenericLogger} via configuration;\n * it is wrapped once into a `LoggerService` that is threaded through the SDK.\n * Internal code therefore calls `logger.warn(...)` directly — no optional\n * chaining, no per-call `undefined` checks — and a single place (this class)\n * owns the \"silent by default\" behavior: when no logger was supplied, every\n * level is a no-op.\n *\n * Every message is prefixed with `[zama-sdk]` here, so call sites pass only\n * their own message (and optional component tag) without repeating the prefix.\n *\n * `LoggerService` itself satisfies `GenericLogger`, so it can be passed\n * anywhere a logger is expected.\n */\nexport class LoggerService implements GenericLogger {\n readonly #logger: GenericLogger | undefined;\n readonly #prefix = \"[zama-sdk]\";\n\n constructor(logger?: GenericLogger) {\n this.#logger = logger;\n }\n\n error(message: string, data?: Record<string, unknown>): void {\n this.#logger?.error(`${this.#prefix} ${message}`, data);\n }\n\n warn(message: string, data?: Record<string, unknown>): void {\n this.#logger?.warn(`${this.#prefix} ${message}`, data);\n }\n\n info(message: string, data?: Record<string, unknown>): void {\n this.#logger?.info(`${this.#prefix} ${message}`, data);\n }\n\n debug(message: string, data?: Record<string, unknown>): void {\n this.#logger?.debug(`${this.#prefix} ${message}`, data);\n }\n}\n","import { z } from \"zod/mini\";\nimport { ConfigurationError } from \"./errors\";\n\nexport function parseConfiguration<T>(schema: z.core.$ZodType<T>, value: unknown): T {\n const parsed = z.safeParse(schema, value);\n if (parsed.success) {\n return parsed.data;\n }\n throw new ConfigurationError(z.prettifyError(parsed.error), { cause: parsed.error });\n}\n","import { type Address, getAddress, zeroAddress } from \"viem\";\nimport { z } from \"zod/mini\";\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, ingenTestnet, bscTestnet } 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 *\n * @deprecated Read `registryAddress` from the chain presets instead (e.g.\n * `sepolia.registryAddress`). Will be removed in the next major version.\n */\nexport const DefaultRegistryAddresses: Record<number, Address> = {\n [mainnet.id]: mainnet.registryAddress,\n [sepolia.id]: sepolia.registryAddress,\n [hoodi.id]: hoodi.registryAddress,\n [ingenTestnet.id]: ingenTestnet.registryAddress,\n [bscTestnet.id]: bscTestnet.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().check(z.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 /** Read-only chain access used for registry contract reads. */\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(z.optional(RegistryAddressesSchema), 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, { data, expiresAt: Date.now() + ttlMs });\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 if no address is configured for the chain. {@link ConfigurationError}\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 /** Lists registered underlying/confidential token pairs; pass `{ metadata: true }` to include on-chain token metadata. */\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: { name: \"Unknown\", symbol: \"???\", decimals: 0, totalSupply: 0n },\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: { name: uName, symbol: uSymbol, decimals: uDecimals, totalSupply: uTotalSupply },\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<{ confidentialTokenAddress: Address; isValid: boolean } | null>(\n cacheKey,\n );\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<{ tokenAddress: Address; isValid: boolean } | 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 { hasFhevmRuntimeConfig, setFhevmRuntimeConfig } from \"@fhevm/sdk/viem\";\nimport { ChainRouter } from \"../chains/router\";\nimport {\n DEFAULT_PERMIT_DURATION_DAYS,\n DEFAULT_TRANSPORT_KEY_PAIR_TTL_SECONDS,\n} from \"../credentials/credential-service\";\nimport {\n PermitTTLSchema,\n TransportKeyPairScopeSchema,\n TransportKeyPairTTLSchema,\n} from \"../credentials/schemas\";\nimport { LoggerService } from \"../services/logger-service\";\nimport type { GenericProvider, GenericSigner } from \"../types\";\nimport { parseConfiguration } from \"../validation\";\nimport { DEFAULT_REGISTRY_TTL_SECONDS, RegistryTTLSchema } from \"../wrappers-registry\";\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 logger = new LoggerService(params.logger);\n\n if (hasFhevmRuntimeConfig()) {\n logger.warn(\"runtime configuration is already set and cannot be changed.\");\n } else {\n setFhevmRuntimeConfig({\n wasmAssetLoadMode: \"auto\",\n moduleVersions: \"auto\",\n logger: {\n error: (message, cause) => params.logger?.error(message, { cause }),\n warn: (message) => params.logger?.warn(message),\n debug: (message) => params.logger?.debug(message),\n },\n ...params.runtime,\n });\n }\n\n const { storage, permitStorage } = resolveStorage(params.storage, params.permitStorage);\n\n const router = new ChainRouter(params.chains, params.relayers);\n\n return {\n chains: params.chains,\n router,\n provider,\n signer,\n storage,\n permitStorage,\n transportKeyPairTTL: parseConfiguration(\n TransportKeyPairTTLSchema,\n params.transportKeyPairTTL ?? DEFAULT_TRANSPORT_KEY_PAIR_TTL_SECONDS,\n ),\n permitTTL: parseConfiguration(\n PermitTTLSchema,\n params.permitTTL ?? DEFAULT_PERMIT_DURATION_DAYS,\n ),\n transportKeyPairScope:\n params.transportKeyPairScope === undefined\n ? undefined\n : parseConfiguration(TransportKeyPairScopeSchema, params.transportKeyPairScope),\n registryTTL: parseConfiguration(\n RegistryTTLSchema,\n params.registryTTL ?? DEFAULT_REGISTRY_TTL_SECONDS,\n ),\n logger,\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 /** Return the current wallet account snapshot, or `undefined` when none is set. */\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 /**\n * Register a listener for wallet account changes, emitting the current\n * snapshot immediately if one exists.\n * @returns An unsubscribe function.\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/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 /** Observable wallet account readiness state. */\n readonly walletAccount: MutableWalletAccountStore;\n #disposed = false;\n\n constructor(initial?: WalletAccount) {\n this.walletAccount = new MutableWalletAccountStore(initial);\n }\n\n /** Return the connected wallet account or throw {@link WalletNotConnectedError}. */\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 /** Sign EIP-712 typed data (used for decrypt authorization). */\n abstract signTypedData(typedData: EIP712TypedData): Promise<Hex>;\n\n /** Send a write transaction and return the tx hash. */\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 /** Release adapter-owned wallet watchers or provider event listeners; idempotent. */\n dispose(): void {\n if (this.#disposed) {\n return;\n }\n this.#disposed = true;\n this.onDispose();\n }\n\n /** `Disposable` support; delegates to {@link BaseSigner.dispose}. */\n [Symbol.dispose](): void {\n this.dispose();\n }\n\n /** Subclass cleanup hook, invoked once on the first {@link BaseSigner.dispose} call. */\n protected onDispose(): void {}\n}\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import { a as hoodi, c as sepolia, d as FheChainAuth, i as hardhat, l as AtLeastOneChain, n as bscTestnet, o as ingenTestnet, r as chains, s as mainnet, t as anvil, u as FheChain } from "../index-doNE2KoX.js";
1
+ import { a as hoodi, c as sepolia, d as FheChainAuth, i as hardhat, l as AtLeastOneChain, n as bscTestnet, o as ingenTestnet, r as chains, s as mainnet, t as anvil, u as FheChain } from "../index-S6_V7aAH.js";
2
2
  export { type AtLeastOneChain, type FheChain, type FheChainAuth, anvil, bscTestnet, chains, hardhat, hoodi, ingenTestnet, mainnet, sepolia };
@@ -1,3 +1,3 @@
1
- import { t as CleartextRelayerConfig } from "../types-CELdIAFG.js";
2
- import { t as cleartext } from "../cleartext-_RCZVPOe.js";
1
+ import { t as CleartextRelayerConfig } from "../types-CWPSTRF6.js";
2
+ import { t as cleartext } from "../cleartext-CxlICeUh.js";
3
3
  export { type CleartextRelayerConfig, cleartext };
@@ -1 +1 @@
1
- import{t as e}from"../cleartext-DfX0GUj1.js";export{e as cleartext};
1
+ import{t as e}from"../cleartext-Qqh5JohW.js";export{e as cleartext};
@@ -1,4 +1,4 @@
1
- import { qt as RelayerOptions, t as CleartextRelayerConfig } from "./types-CELdIAFG.js";
1
+ import { Kt as RelayerOptions, t as CleartextRelayerConfig } from "./types-CWPSTRF6.js";
2
2
  //#region src/config/cleartext.d.ts
3
3
  /**
4
4
  * Cleartext relayer — drives the FHE backend in cleartext mode (no FHE infrastructure).
@@ -15,4 +15,4 @@ import { qt as RelayerOptions, t as CleartextRelayerConfig } from "./types-CELdI
15
15
  declare function cleartext(options?: RelayerOptions): CleartextRelayerConfig;
16
16
  //#endregion
17
17
  export { cleartext as t };
18
- //# sourceMappingURL=cleartext-_RCZVPOe.d.ts.map
18
+ //# sourceMappingURL=cleartext-CxlICeUh.d.ts.map
@@ -1,2 +1,2 @@
1
- import{t as e}from"./relayer-DLlyoabr.js";import{t}from"./fhevm-relayer-Bb_-KFJA.js";function n(n){return{type:`cleartext`,createRelayer:r=>{if(!r.executorAddress)throw new e(`Cleartext relayer requires an executorAddress. Either use a chain preset that includes it (e.g. hardhat, hoodi) or set it on the chain definition.`);return new t({chain:r,options:n,cleartext:!0})}}}export{n as t};
2
- //# sourceMappingURL=cleartext-DfX0GUj1.js.map
1
+ import{t as e}from"./relayer-BWHOLVcG.js";import{t}from"./fhevm-relayer-4Zd4QkKq.js";function n(n){return{type:`cleartext`,createRelayer:r=>{if(!r.executorAddress)throw new e(`Cleartext relayer requires an executorAddress. Either use a chain preset that includes it (e.g. hardhat, hoodi) or set it on the chain definition.`);return new t({chain:r,options:n,cleartext:!0})}}}export{n as t};
2
+ //# sourceMappingURL=cleartext-Qqh5JohW.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"cleartext-DfX0GUj1.js","names":[],"sources":["../../src/config/cleartext.ts"],"sourcesContent":["import { ConfigurationError } from \"../errors\";\nimport { FhevmRelayer } from \"../relayer/fhevm-relayer\";\nimport type { RelayerOptions } from \"../relayer/types\";\nimport type { CleartextRelayerConfig } from \"./types\";\n\n/**\n * Cleartext relayer — drives the FHE backend in cleartext mode (no FHE infrastructure).\n *\n * When `executorAddress` is set on the chain definition (e.g. `hardhat`, `hoodi`),\n * it is picked up automatically.\n *\n * @example\n * ```ts\n * // executorAddress comes from the chain preset:\n * relayers: { [hardhat.id]: cleartext({ batchRpcCalls: true }) }\n * ```\n */\nexport function cleartext(options?: RelayerOptions): CleartextRelayerConfig {\n return {\n type: \"cleartext\",\n createRelayer: (chain) => {\n if (!chain.executorAddress) {\n throw new ConfigurationError(\n `Cleartext relayer requires an executorAddress. ` +\n `Either use a chain preset that includes it (e.g. hardhat, hoodi) ` +\n `or set it on the chain definition.`,\n );\n }\n return new FhevmRelayer({ chain, options, cleartext: true });\n },\n };\n}\n"],"mappings":"qFAiBA,SAAgB,EAAU,EAAkD,CAC1E,MAAO,CACL,KAAM,YACN,cAAgB,GAAU,CACxB,GAAI,CAAC,EAAM,gBACT,MAAM,IAAI,EACR,oJAGF,EAEF,OAAO,IAAI,EAAa,CAAE,QAAO,UAAS,UAAW,EAAK,CAAC,CAC7D,CACF,CACF"}
1
+ {"version":3,"file":"cleartext-Qqh5JohW.js","names":[],"sources":["../../src/config/cleartext.ts"],"sourcesContent":["import { ConfigurationError } from \"../errors\";\nimport { FhevmRelayer } from \"../relayer/fhevm-relayer\";\nimport type { RelayerOptions } from \"../relayer/types\";\nimport type { CleartextRelayerConfig } from \"./types\";\n\n/**\n * Cleartext relayer — drives the FHE backend in cleartext mode (no FHE infrastructure).\n *\n * When `executorAddress` is set on the chain definition (e.g. `hardhat`, `hoodi`),\n * it is picked up automatically.\n *\n * @example\n * ```ts\n * // executorAddress comes from the chain preset:\n * relayers: { [hardhat.id]: cleartext({ batchRpcCalls: true }) }\n * ```\n */\nexport function cleartext(options?: RelayerOptions): CleartextRelayerConfig {\n return {\n type: \"cleartext\",\n createRelayer: (chain) => {\n if (!chain.executorAddress) {\n throw new ConfigurationError(\n `Cleartext relayer requires an executorAddress. ` +\n `Either use a chain preset that includes it (e.g. hardhat, hoodi) ` +\n `or set it on the chain definition.`,\n );\n }\n return new FhevmRelayer({ chain, options, cleartext: true });\n },\n };\n}\n"],"mappings":"qFAiBA,SAAgB,EAAU,EAAkD,CAC1E,MAAO,CACL,KAAM,YACN,cAAgB,GAAU,CACxB,GAAI,CAAC,EAAM,gBACT,MAAM,IAAI,EACR,oJAGF,EAEF,OAAO,IAAI,EAAa,CAAE,QAAO,UAAS,UAAW,EAAK,CAAC,CAC7D,CACF,CACF"}
@@ -1,7 +1,7 @@
1
- import { u as FheChain } from "../index-doNE2KoX.js";
2
- import { Pt as TransactionReceipt, Ut as EncryptedValue, _ as ReadContractConfig, d as WalletAccount, i as ZamaConfig, l as GenericProvider, x as WriteContractConfig, zt as EIP712TypedData } from "../types-CELdIAFG.js";
3
- import { t as ZamaConfigEthers } from "../types-DlSUyFe2.js";
4
- import { t as BaseSigner } from "../base-signer-Ds8CoYy0.js";
1
+ import { d as FheChainAuth, l as AtLeastOneChain, u as FheChain } from "../index-S6_V7aAH.js";
2
+ import { A as EncryptErrorEvent, B as UnshieldPhase1SubmittedEvent, C as ApproveUnderlyingSubmittedEvent, D as DecryptStartEvent, E as DecryptErrorEvent, F as ShieldSubmittedEvent, G as ZamaSDKEvent, Gt as FhevmRuntimeConfig, H as UnshieldPhase2SubmittedEvent, I as TransactionErrorEvent, J as ZamaSDKEvents, K as ZamaSDKEventListener, L as TransactionOperation, Lt as EIP712TypedData, M as FinalizeUnwrapSubmittedEvent, Mt as TransactionReceipt, N as RevokeDelegationSubmittedEvent, O as DelegationSubmittedEvent, P as SetOperatorSubmittedEvent, Pt as ClearValue, R as TransferFromSubmittedEvent, S as WriteFunctionName, T as DecryptEndEvent, U as UnwrapSubmittedEvent, V as UnshieldPhase2StartedEvent, Vt as EncryptedValue, W as WrapSubmittedEvent, Z as ShieldPath, _ as ReadContractConfig, a as ZamaConfigBase, b as WriteContractArgs, c as GenericStorage, d as WalletAccount, f as WalletAccountChange, g as ReadContractArgs, h as ContractAbi, i as ZamaConfig, j as EncryptStartEvent, jt as RawLog, k as EncryptEndEvent, l as GenericProvider, m as WalletAccountStore, n as RelayerConfig, p as WalletAccountListener, q as ZamaSDKEventType, s as GenericLogger, u as GenericSigner, v as ReadContractReturnType, w as BaseEvent, x as WriteContractConfig, y as ReadFunctionName, z as TransferSubmittedEvent } from "../types-CWPSTRF6.js";
3
+ import { t as ZamaConfigEthers } from "../types-Dr7AmEs1.js";
4
+ import { n as MutableWalletAccountStore, t as BaseSigner } from "../base-signer-BvL-jMNO.js";
5
5
  import { Abi, Address, ContractFunctionArgs, ContractFunctionName, ContractFunctionReturnType, EIP1193EventMap, EIP1193Events, EIP1193Provider, EIP1193Provider as EIP1193Provider$1, Hex, Hex as Hex$1, ProviderConnectInfo, ProviderMessage, ProviderRpcError } from "viem";
6
6
  import { Signer, ethers } from "ethers";
7
7
  //#region src/ethers/config.d.ts
@@ -40,10 +40,19 @@ type EthersSignerConfig = {
40
40
  declare class EthersSigner extends BaseSigner {
41
41
  #private;
42
42
  constructor(config: EthersSignerConfig);
43
+ /**
44
+ * Return the connected wallet account, or throw {@link WalletAccountNotReadyError}
45
+ * while the initial async lookup is pending, or {@link WalletNotConnectedError}
46
+ * when no wallet is connected.
47
+ */
43
48
  requireWalletAccount(operation: string): WalletAccount;
49
+ /** Re-fetch the wallet account from the provider or signer and update `walletAccount`. */
44
50
  refreshWalletAccount(): Promise<WalletAccount | undefined>;
51
+ /** Unsubscribe from the EIP-1193 provider's wallet lifecycle events. */
45
52
  protected onDispose(): void;
53
+ /** Sign EIP-712 typed data (used for decrypt authorization). */
46
54
  signTypedData(typedData: EIP712TypedData): Promise<Hex$1>;
55
+ /** Send a write transaction and return the tx hash. */
47
56
  writeContract<const TAbi extends Abi | readonly unknown[], TFunctionName extends ContractFunctionName<TAbi, "nonpayable" | "payable">, const TArgs extends ContractFunctionArgs<TAbi, "nonpayable" | "payable", TFunctionName>>(config: WriteContractConfig<TAbi, TFunctionName, TArgs>): Promise<Hex$1>;
48
57
  }
49
58
  //#endregion
@@ -84,44 +93,83 @@ type EthersProviderConfig = {
84
93
  declare class EthersProvider implements GenericProvider {
85
94
  #private;
86
95
  constructor(config: EthersProviderConfig);
96
+ /** Return the chain ID of the connected network. */
87
97
  getChainId(): Promise<number>;
98
+ /**
99
+ * Execute a read-only call and return the decoded result.
100
+ *
101
+ * ethers is the transport only: the call goes out over `provider.call`, and viem does the
102
+ * encoding and decoding (via {@link ethersRead}). That keeps the result identical to
103
+ * `ViemProvider` — the return-type contract both providers implement — rather than re-deriving
104
+ * viem's decoding rules (small ints as `number`, named tuples as keyed objects, empty output as
105
+ * `undefined`) from ethers' own decoded values.
106
+ */
88
107
  readContract<const TAbi extends Abi | readonly unknown[], TFunctionName extends ContractFunctionName<TAbi, "pure" | "view">, const TArgs extends ContractFunctionArgs<TAbi, "pure" | "view", TFunctionName>>(config: ReadContractConfig<TAbi, TFunctionName, TArgs>): Promise<ContractFunctionReturnType<TAbi, "pure" | "view", TFunctionName, TArgs>>;
108
+ /** Return the latest block timestamp in seconds. */
89
109
  getBlockTimestamp(): Promise<bigint>;
110
+ /** Wait for a transaction to be mined and return its receipt. */
90
111
  waitForTransactionReceipt(hash: Hex$1): Promise<TransactionReceipt>;
91
112
  }
92
113
  //#endregion
93
114
  //#region src/ethers/contracts.d.ts
115
+ /** Minimal transaction request accepted by the ethers contract helpers. */
94
116
  interface EthersTransactionRequest {
117
+ /** Target contract address. */
95
118
  to: Address;
119
+ /** ABI-encoded call data. */
96
120
  data: Hex$1;
121
+ /** Optional gas limit for the transaction. */
97
122
  gasLimit?: bigint;
123
+ /** Optional native-token value to send with the call, in wei. */
98
124
  value?: bigint;
99
125
  }
126
+ /** Minimal transaction response returned by an {@link EthersTransactionSigner}. */
100
127
  interface EthersTransactionResponse {
128
+ /** Hash of the submitted transaction. */
101
129
  hash: string;
102
130
  }
131
+ /** Minimal read-only ethers provider shape used by the read contract helpers. */
103
132
  interface EthersCallProvider {
133
+ /** Performs an `eth_call` and resolves to the raw hex return data. */
104
134
  call(tx: EthersTransactionRequest): Promise<string>;
105
135
  }
136
+ /** Minimal ethers signer shape used by the write contract helpers. */
106
137
  interface EthersTransactionSigner extends EthersCallProvider {
138
+ /** Signs and broadcasts a transaction, resolving to the transaction response. */
107
139
  sendTransaction(tx: EthersTransactionRequest): Promise<EthersTransactionResponse>;
108
140
  }
141
+ /** Reads a token's confidential (encrypted) balance handle for `userAddress` via an ethers provider. */
109
142
  declare function readConfidentialBalanceOfContract(provider: EthersCallProvider, tokenAddress: Address, userAddress: Address): Promise<unknown>;
143
+ /** Reads the underlying ERC-20 address wrapped by a confidential wrapper via an ethers provider. */
110
144
  declare function readUnderlyingTokenContract(provider: EthersCallProvider, wrapperAddress: Address): Promise<unknown>;
145
+ /** Reads whether a token implements the given ERC-165 interface id via an ethers provider. */
111
146
  declare function readSupportsInterfaceContract(provider: EthersCallProvider, tokenAddress: Address, interfaceId: Address): Promise<unknown>;
147
+ /** Submits a confidential transfer of an encrypted amount to `to` via an ethers signer. */
112
148
  declare function writeConfidentialTransferContract(signer: EthersTransactionSigner, tokenAddress: Address, to: Address, encryptedAmount: EncryptedValue, inputProof: Hex$1): Promise<`0x${string}`>;
149
+ /** Submits an unwrap of an encrypted amount from `from` to `to` on a confidential ERC-20 via an ethers signer. */
113
150
  declare function writeUnwrapContract(signer: EthersTransactionSigner, encryptedErc20: Address, from: Address, to: Address, encryptedAmount: EncryptedValue, inputProof: Hex$1): Promise<`0x${string}`>;
151
+ /** Submits an unwrap of the full encrypted balance from `from` to `to` via an ethers signer. */
114
152
  declare function writeUnwrapFromBalanceContract(signer: EthersTransactionSigner, encryptedErc20: Address, from: Address, to: Address, encryptedBalance: EncryptedValue): Promise<`0x${string}`>;
153
+ /** Finalizes a pending unwrap request with the decrypted amount and decryption proof via an ethers signer. */
115
154
  declare function writeFinalizeUnwrapContract(signer: EthersTransactionSigner, wrapper: Address, unwrapRequestId: EncryptedValue, unwrapAmountCleartext: bigint, decryptionProof: Hex$1): Promise<`0x${string}`>;
155
+ /** Authorizes `operator` on a token, until an optional expiry timestamp, via an ethers signer. */
116
156
  declare function writeSetOperatorContract(signer: EthersTransactionSigner, tokenAddress: Address, operator: Address, until?: number): Promise<`0x${string}`>;
157
+ /** Wraps `amount` of the underlying ERC-20 into confidential tokens credited to `to` via an ethers signer. */
117
158
  declare function writeWrapContract(signer: EthersTransactionSigner, wrapperAddress: Address, to: Address, amount: bigint): Promise<`0x${string}`>;
159
+ /** Reads all underlying/confidential token pairs from a wrappers registry via an ethers provider. */
118
160
  declare function readTokenPairsContract(provider: EthersCallProvider, registry: Address): Promise<unknown>;
161
+ /** Reads the number of token pairs in a wrappers registry via an ethers provider. */
119
162
  declare function readTokenPairsLengthContract(provider: EthersCallProvider, registry: Address): Promise<unknown>;
163
+ /** Reads a slice of token pairs (`fromIndex` to `toIndex`) from a wrappers registry via an ethers provider. */
120
164
  declare function readTokenPairsSliceContract(provider: EthersCallProvider, registry: Address, fromIndex: bigint, toIndex: bigint): Promise<unknown>;
165
+ /** Reads the token pair at `index` from a wrappers registry via an ethers provider. */
121
166
  declare function readTokenPairContract(provider: EthersCallProvider, registry: Address, index: bigint): Promise<unknown>;
167
+ /** Reads the confidential token registered for a given underlying token in a wrappers registry via an ethers provider. */
122
168
  declare function readConfidentialTokenAddressContract(provider: EthersCallProvider, registry: Address, tokenAddress: Address): Promise<unknown>;
169
+ /** Reads the underlying token registered for a given confidential token in a wrappers registry via an ethers provider. */
123
170
  declare function readTokenAddressContract(provider: EthersCallProvider, registry: Address, confidentialTokenAddress: Address): Promise<unknown>;
171
+ /** Reads whether a confidential token is registered and valid in a wrappers registry via an ethers provider. */
124
172
  declare function readIsConfidentialTokenValidContract(provider: EthersCallProvider, registry: Address, confidentialTokenAddress: Address): Promise<unknown>;
125
173
  //#endregion
126
- export { type EIP1193EventMap, type EIP1193Events, type EIP1193Provider, type EncryptedValue, EthersProvider, type EthersProviderConfig, EthersSigner, type EthersSignerConfig, type Hex, type ProviderConnectInfo, type ProviderMessage, ProviderRpcError, type ZamaConfigEthers, createConfig, readConfidentialBalanceOfContract, readConfidentialTokenAddressContract, readIsConfidentialTokenValidContract, readSupportsInterfaceContract, readTokenAddressContract, readTokenPairContract, readTokenPairsContract, readTokenPairsLengthContract, readTokenPairsSliceContract, readUnderlyingTokenContract, writeConfidentialTransferContract, writeFinalizeUnwrapContract, writeSetOperatorContract, writeUnwrapContract, writeUnwrapFromBalanceContract, writeWrapContract };
174
+ export { type ApproveUnderlyingSubmittedEvent, type AtLeastOneChain, type BaseEvent, BaseSigner, type ClearValue, type ContractAbi, type DecryptEndEvent, type DecryptErrorEvent, type DecryptStartEvent, type DelegationSubmittedEvent, type EIP1193EventMap, type EIP1193Events, type EIP1193Provider, type EIP712TypedData, type EncryptEndEvent, type EncryptErrorEvent, type EncryptStartEvent, type EncryptedValue, type EthersCallProvider, EthersProvider, type EthersProviderConfig, EthersSigner, type EthersSignerConfig, type EthersTransactionRequest, type EthersTransactionResponse, type EthersTransactionSigner, type FheChain, type FheChainAuth, type FhevmRuntimeConfig, type FinalizeUnwrapSubmittedEvent, type GenericLogger, type GenericProvider, type GenericSigner, type GenericStorage, type Hex, type MutableWalletAccountStore, type ProviderConnectInfo, type ProviderMessage, ProviderRpcError, type RawLog, type ReadContractArgs, type ReadContractConfig, type ReadContractReturnType, type ReadFunctionName, type RelayerConfig, type RevokeDelegationSubmittedEvent, type SetOperatorSubmittedEvent, type ShieldPath, type ShieldSubmittedEvent, type TransactionErrorEvent, type TransactionOperation, type TransactionReceipt, type TransferFromSubmittedEvent, type TransferSubmittedEvent, type UnshieldPhase1SubmittedEvent, type UnshieldPhase2StartedEvent, type UnshieldPhase2SubmittedEvent, type UnwrapSubmittedEvent, type WalletAccount, type WalletAccountChange, type WalletAccountListener, type WalletAccountStore, type WrapSubmittedEvent, type WriteContractArgs, type WriteContractConfig, type WriteFunctionName, type ZamaConfig, type ZamaConfigBase, type ZamaConfigEthers, type ZamaSDKEvent, type ZamaSDKEventListener, type ZamaSDKEventType, ZamaSDKEvents, createConfig, readConfidentialBalanceOfContract, readConfidentialTokenAddressContract, readIsConfidentialTokenValidContract, readSupportsInterfaceContract, readTokenAddressContract, readTokenPairContract, readTokenPairsContract, readTokenPairsLengthContract, readTokenPairsSliceContract, readUnderlyingTokenContract, writeConfidentialTransferContract, writeFinalizeUnwrapContract, writeSetOperatorContract, writeUnwrapContract, writeUnwrapFromBalanceContract, writeWrapContract };
127
175
  //# sourceMappingURL=index.d.ts.map
@@ -1,2 +1,2 @@
1
- import{B as e,F as t,I as n,L as r,M as i,N as a,O as o,P as s,R as c,S as l,T as u,V as d,a as f,i as p,m,n as h,o as g,r as _,s as v,t as y}from"../wrappers-registry-B1GuTt5t.js";import{i as b,t as x}from"../base-signer-9CqICeQ8.js";import{t as S}from"../eip1193-subscribe-CNxVHW6y.js";import{ProviderRpcError as C,decodeFunctionResult as w,encodeFunctionData as T,getAddress as E,isHex as D}from"viem";import{BrowserProvider as O,Contract as k,ethers as A}from"ethers";var j=class{#e;constructor(e){`ethereum`in e?this.#e=new O(e.ethereum):this.#e=e.provider}async getChainId(){let e=await this.#e.getNetwork();return Number(e.chainId)}async readContract(e){return new A.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}))}}},M=class extends x{#e;#t;#n;#r;#i;constructor(e){super(),`ethereum`in e?(this.#e=new O(e.ethereum),this.#n=e.ethereum,this.#r=S({provider:e.ethereum,getInitialWalletAccount:()=>this.#l(),onWalletAccountChange:({next:e})=>{this.walletAccount.setSnapshot(e)}})):(this.#t=e.signer,this.#r=()=>{},r(`refresh wallet account`,async()=>{await this.refreshWalletAccount()}))}requireWalletAccount(t){let n=this.walletAccount.getSnapshot();if(!n&&!this.walletAccount.isReady())throw new e(t);if(!n)throw new d(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 c(`resolveSigner`);return this.#e.getSigner()}async#o(e){let t=e.provider;if(!t)return;let[n,r]=await Promise.all([e.getAddress(),t.getNetwork()]);return{address:E(n),chainId:Number(r.chainId)}}async signTypedData(e){let t=await this.#a(),{domain:n,types:r,message:i}=e,{EIP712Domain:a,...o}=r,s=Object.fromEntries(Object.entries(o).map(([e,t])=>[e,[...t]])),c=await t.signTypedData(n,s,i);if(!D(c))throw TypeError(`Expected hex string, got: ${c}`);return c}async writeContract(e){let t=await this.#a(),n=new k(e.address,e.abi,t),r={};e.value!==void 0&&(r.value=e.value),e.gas!==void 0&&(r.gasLimit=e.gas);let i=await n.getFunction(e.functionName)(...e.args,r);if(!D(i.hash))throw TypeError(`Expected hex string, got: ${i.hash}`);return i.hash}async#s(e){return this.#i??=this.#o(e).then(e=>(this.walletAccount.setSnapshot(e),e)).finally(()=>{this.#i=void 0}),this.#i}async#c(){let e=await this.#l();return this.walletAccount.setSnapshot(e),e}async#l(){let e=this.#n;if(!e)return;let[t,n]=await Promise.all([e.request({method:`eth_accounts`}),e.request({method:`eth_chainId`})]);if(!Array.isArray(t)||typeof t[0]!=`string`)return;let r=Number(n);if(!(!Number.isSafeInteger(r)||r<=0))return{address:E(t[0]),chainId:r}}};function N(e){if(`signer`in e&&e.signer){let t=new M({signer:e.signer});if(!e.signer.provider)throw Error(`createConfig requires a Signer with an attached provider for chain reads`);return b(t,new j({provider:e.signer.provider}),e)}return b(new M({ethereum:e.ethereum}),`provider`in e&&e.provider?new j({provider:e.provider}):new j({ethereum:e.ethereum}),e)}function P(e){return{to:e.address,data:T({abi:e.abi,functionName:e.functionName,args:e.args}),...e.gas===void 0?{}:{gasLimit:e.gas},...e.value===void 0?{}:{value:e.value}}}async function F(e,t){let n=await e.call(P(t));if(!D(n))throw TypeError(`Expected hex string, got: ${n}`);return w({abi:t.abi,functionName:t.functionName,data:n})}async function I(e,t){let n=await e.sendTransaction(P(t));if(!D(n.hash))throw TypeError(`Expected hex string, got: ${n.hash}`);return n.hash}function L(e,t,n){return F(e,l(t,n))}function R(e,t){return F(e,a(t))}function z(e,t,n){return F(e,m(t,n))}function B(e,t,n,r,i){return I(e,u(t,n,r,i))}function V(e,t,n,r,i,a){return I(e,s(t,n,r,i,a))}function H(e,n,r,i,a){return I(e,t(n,r,i,a))}function U(e,t,n,r,i){return I(e,o(t,n,r,i))}function W(e,t,n,r){return I(e,i(t,n,r))}function G(e,t,r,i){return I(e,n(t,r,i))}function K(e,t){return F(e,p(t))}function q(e,t){return F(e,f(t))}function J(e,t,n,r){return F(e,g(t,n,r))}function Y(e,t,n){return F(e,_(t,n))}function X(e,t,n){return F(e,y(t,n))}function Z(e,t,n){return F(e,h(t,n))}function Q(e,t,n){return F(e,v(t,n))}export{j as EthersProvider,M as EthersSigner,C as ProviderRpcError,N as createConfig,L as readConfidentialBalanceOfContract,X as readConfidentialTokenAddressContract,Q as readIsConfidentialTokenValidContract,z as readSupportsInterfaceContract,Z as readTokenAddressContract,Y as readTokenPairContract,K as readTokenPairsContract,q as readTokenPairsLengthContract,J as readTokenPairsSliceContract,R as readUnderlyingTokenContract,B as writeConfidentialTransferContract,U as writeFinalizeUnwrapContract,W as writeSetOperatorContract,V as writeUnwrapContract,H as writeUnwrapFromBalanceContract,G as writeWrapContract};
1
+ import{A as e,B as t,D as n,F as r,H as i,I as a,L as o,P as s,R as c,U as l,a as u,c as d,g as f,i as p,l as m,o as h,r as g,s as _,t as v,w as y,z as b}from"../sdk-events-D68bJ5jT.js";import{i as x,t as S}from"../base-signer-YpkEmlp2.js";import{t as C}from"../eip1193-subscribe-CNxVHW6y.js";import{ProviderRpcError as w,decodeFunctionResult as T,encodeFunctionData as E,getAddress as D,isHex as O}from"viem";import{BrowserProvider as k,Contract as A}from"ethers";function j(e){return{to:e.address,data:E({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 M(e,t){let n=await e.call(j(t));if(!O(n))throw TypeError(`Expected hex string, got: ${n}`);return T({abi:t.abi,functionName:t.functionName,data:n})}async function N(e,t){let n=await e.sendTransaction(j(t));if(!O(n.hash))throw TypeError(`Expected hex string, got: ${n.hash}`);return n.hash}function P(e,t,n){return M(e,y(t,n))}function F(e,t){return M(e,r(t))}function I(e,t,n){return M(e,f(t,n))}function L(e,t,r,i,a){return N(e,n(t,r,i,a))}function R(e,t,n,r,i,o){return N(e,a(t,n,r,i,o))}function z(e,t,n,r,i){return N(e,o(t,n,r,i))}function B(t,n,r,i,a){return N(t,e(n,r,i,a))}function V(e,t,n,r){return N(e,s(t,n,r))}function H(e,t,n,r){return N(e,c(t,n,r))}function U(e,t){return M(e,h(t))}function W(e,t){return M(e,_(t))}function G(e,t,n,r){return M(e,d(t,n,r))}function K(e,t,n){return M(e,u(t,n))}function q(e,t,n){return M(e,g(t,n))}function J(e,t,n){return M(e,p(t,n))}function Y(e,t,n){return M(e,m(t,n))}var X=class{#e;constructor(e){`ethereum`in e?this.#e=new k(e.ethereum):this.#e=e.provider}async getChainId(){let e=await this.#e.getNetwork();return Number(e.chainId)}async readContract(e){return M(this.#e,{address:e.address,abi:e.abi,functionName:e.functionName,args: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}))}}},Z=class extends S{#e;#t;#n;#r;#i;constructor(e){super(),`ethereum`in e?(this.#e=new k(e.ethereum),this.#n=e.ethereum,this.#r=C({provider:e.ethereum,getInitialWalletAccount:()=>this.#l(),onWalletAccountChange:({next:e})=>{this.walletAccount.setSnapshot(e)}})):(this.#t=e.signer,this.#r=()=>{},b(`refresh wallet account`,async()=>{await this.refreshWalletAccount()}))}requireWalletAccount(e){let t=this.walletAccount.getSnapshot();if(!t&&!this.walletAccount.isReady())throw new i(e);if(!t)throw new l(e);return t}refreshWalletAccount(){return this.#n?this.#c():this.#t?this.#s(this.#t):Promise.resolve(void 0)}onDispose(){this.#r()}async#a(){if(this.#t)return this.#t;if(!this.#e)throw new t(`resolveSigner`);return this.#e.getSigner()}async#o(e){let t=e.provider;if(!t)return;let[n,r]=await Promise.all([e.getAddress(),t.getNetwork()]);return{address:D(n),chainId:Number(r.chainId)}}async signTypedData(e){let t=await this.#a(),{domain:n,types:r,message:i}=e,{EIP712Domain:a,...o}=r,s=Object.fromEntries(Object.entries(o).map(([e,t])=>[e,[...t]])),c=await t.signTypedData(n,s,i);if(!O(c))throw TypeError(`Expected hex string, got: ${c}`);return c}async writeContract(e){let t=await this.#a(),n=new A(e.address,e.abi,t),r={};e.value!==void 0&&(r.value=e.value),e.gas!==void 0&&(r.gasLimit=e.gas);let i=await n.getFunction(e.functionName)(...e.args,r);if(!O(i.hash))throw TypeError(`Expected hex string, got: ${i.hash}`);return i.hash}async#s(e){return this.#i??=this.#o(e).then(e=>(this.walletAccount.setSnapshot(e),e)).finally(()=>{this.#i=void 0}),this.#i}async#c(){let e=await this.#l();return this.walletAccount.setSnapshot(e),e}async#l(){let e=this.#n;if(!e)return;let[t,n]=await Promise.all([e.request({method:`eth_accounts`}),e.request({method:`eth_chainId`})]);if(!Array.isArray(t)||typeof t[0]!=`string`)return;let r=Number(n);if(!(!Number.isSafeInteger(r)||r<=0))return{address:D(t[0]),chainId:r}}};function Q(e){if(`signer`in e&&e.signer){let t=new Z({signer:e.signer});if(!e.signer.provider)throw Error(`createConfig requires a Signer with an attached provider for chain reads`);return x(t,new X({provider:e.signer.provider}),e)}return x(new Z({ethereum:e.ethereum}),`provider`in e&&e.provider?new X({provider:e.provider}):new X({ethereum:e.ethereum}),e)}export{S as BaseSigner,X as EthersProvider,Z as EthersSigner,w as ProviderRpcError,v as ZamaSDKEvents,Q as createConfig,P as readConfidentialBalanceOfContract,q as readConfidentialTokenAddressContract,Y as readIsConfidentialTokenValidContract,I as readSupportsInterfaceContract,J as readTokenAddressContract,K as readTokenPairContract,U as readTokenPairsContract,W as readTokenPairsLengthContract,G as readTokenPairsSliceContract,F as readUnderlyingTokenContract,L as writeConfidentialTransferContract,B as writeFinalizeUnwrapContract,V as writeSetOperatorContract,R as writeUnwrapContract,z as writeUnwrapFromBalanceContract,H as writeWrapContract};
2
2
  //# sourceMappingURL=index.js.map