@zama-fhe/sdk 3.0.0-alpha.8 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +80 -13
- package/dist/cjs/activity.cjs +2 -0
- package/dist/cjs/activity.cjs.map +1 -0
- package/dist/cjs/cleartext.cjs +1 -1
- package/dist/cjs/cleartext.cjs.map +1 -1
- package/dist/cjs/ethers/index.cjs +1 -1
- package/dist/cjs/ethers/index.cjs.map +1 -1
- package/dist/cjs/index.cjs +22 -3
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/query/index.cjs +1 -1
- package/dist/cjs/query/index.cjs.map +1 -1
- package/dist/cjs/relayer-sdk.worker.js +20 -1
- package/dist/cjs/viem/index.cjs +1 -1
- package/dist/cjs/viem/index.cjs.map +1 -1
- package/dist/cjs/wrappers-registry.cjs +1 -1
- package/dist/cjs/wrappers-registry.cjs.map +1 -1
- package/dist/esm/{onchain-events-DcKcIxPp.d.ts → activity-DBMyE78S.d.ts} +4893 -4105
- package/dist/esm/activity-dMzF5FdR.js +2 -0
- package/dist/esm/activity-dMzF5FdR.js.map +1 -0
- package/dist/esm/cleartext/index.d.ts +10 -4
- package/dist/esm/cleartext/index.js +1 -1
- package/dist/esm/{cleartext-hS6TVszr.js → cleartext-Cs28cTsa.js} +2 -2
- package/dist/esm/cleartext-Cs28cTsa.js.map +1 -0
- package/dist/esm/ethers/index.d.ts +2 -2
- package/dist/esm/ethers/index.js +1 -1
- package/dist/esm/ethers/index.js.map +1 -1
- package/dist/esm/index.d.ts +12 -6
- package/dist/esm/index.js +22 -3
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/{memory-storage-GS1uT4ua.js → memory-storage-F8xjMzVy.js} +2 -2
- package/dist/esm/memory-storage-F8xjMzVy.js.map +1 -0
- package/dist/esm/node/index.d.ts +10 -4
- package/dist/esm/node/index.js +1 -1
- package/dist/esm/node/index.js.map +1 -1
- package/dist/esm/node/relayer-sdk.node-worker.js +1 -1
- package/dist/esm/node/relayer-sdk.node-worker.js.map +1 -1
- package/dist/esm/query/index.d.ts +57 -16
- package/dist/esm/query/index.js +1 -1
- package/dist/esm/query/index.js.map +1 -1
- package/dist/esm/{relayer-sdk-CjKGIodc.d.ts → relayer-sdk-DPqytEbO.d.ts} +10 -4
- package/dist/esm/{relayer-sdk.types-DawSwNjS.d.ts → relayer-sdk.types-CGfXwKcB.d.ts} +61 -24
- package/dist/esm/relayer-sdk.worker.js +20 -1
- package/dist/esm/{relayer-utils-DDa_R8Ft.js → relayer-utils-BeoTNDM4.js} +2 -2
- package/dist/esm/relayer-utils-BeoTNDM4.js.map +1 -0
- package/dist/esm/viem/index.d.ts +2 -2
- package/dist/esm/viem/index.js +1 -1
- package/dist/esm/viem/index.js.map +1 -1
- package/dist/esm/wrappers-registry-DO0729Zi.js +2 -0
- package/dist/esm/wrappers-registry-DO0729Zi.js.map +1 -0
- package/package.json +1 -1
- package/dist/cjs/readonly-token.cjs +0 -2
- package/dist/cjs/readonly-token.cjs.map +0 -1
- package/dist/esm/cleartext-hS6TVszr.js.map +0 -1
- package/dist/esm/memory-storage-GS1uT4ua.js.map +0 -1
- package/dist/esm/readonly-token-DpoyKcOQ.js +0 -2
- package/dist/esm/readonly-token-DpoyKcOQ.js.map +0 -1
- package/dist/esm/relayer-utils-DDa_R8Ft.js.map +0 -1
- package/dist/esm/wrappers-registry-CNHGAtEO.js +0 -2
- package/dist/esm/wrappers-registry-CNHGAtEO.js.map +0 -1
package/README.md
CHANGED
|
@@ -186,7 +186,7 @@ Full read/write interface for a single confidential ERC-20. Extends `ReadonlyTok
|
|
|
186
186
|
| `unwrap(amount)` | Request unwrap for a specific amount (low-level, requires manual finalization). |
|
|
187
187
|
| `unwrapAll()` | Request unwrap for the entire balance (low-level, requires manual finalization). |
|
|
188
188
|
| `resumeUnshield(unwrapTxHash, callbacks?)` | Resume an interrupted unshield from an existing unwrap tx hash. Goes straight to wait receipt → finalize. |
|
|
189
|
-
| `finalizeUnwrap(
|
|
189
|
+
| `finalizeUnwrap(burnAmountHandle)` | Complete unwrap with public decryption proof. |
|
|
190
190
|
| `confidentialTransfer(to, amount)` | Encrypted transfer. Encrypts amount, then calls the contract. |
|
|
191
191
|
| `confidentialTransferFrom(from, to, amt)` | Operator encrypted transfer. |
|
|
192
192
|
| `approve(spender, until?)` | Set operator approval. `until` defaults to now + 1 hour. |
|
|
@@ -534,15 +534,15 @@ interface ContractCallConfig {
|
|
|
534
534
|
|
|
535
535
|
### Wrapper
|
|
536
536
|
|
|
537
|
-
| Function
|
|
538
|
-
|
|
|
539
|
-
| `wrapContract(wrapper, to, amount)`
|
|
540
|
-
| `unwrapContract(token, from, to, encryptedAmount, inputProof)`
|
|
541
|
-
| `unwrapFromBalanceContract(token, from, to, encryptedBalance)`
|
|
542
|
-
| `finalizeUnwrapContract(wrapper,
|
|
543
|
-
| `underlyingContract(wrapper)`
|
|
544
|
-
| `inferredTotalSupplyContract(wrapper)`
|
|
545
|
-
| `totalSupplyContract(wrapper)`
|
|
537
|
+
| Function | Description |
|
|
538
|
+
| ---------------------------------------------------------------- | --------------------------------------------------- |
|
|
539
|
+
| `wrapContract(wrapper, to, amount)` | Wrap ERC-20 tokens. |
|
|
540
|
+
| `unwrapContract(token, from, to, encryptedAmount, inputProof)` | Request unwrap with encrypted amount. |
|
|
541
|
+
| `unwrapFromBalanceContract(token, from, to, encryptedBalance)` | Request unwrap using on-chain balance handle. |
|
|
542
|
+
| `finalizeUnwrapContract(wrapper, burntAmount, cleartext, proof)` | Finalize unwrap with decryption proof. |
|
|
543
|
+
| `underlyingContract(wrapper)` | Read underlying ERC-20 address. |
|
|
544
|
+
| `inferredTotalSupplyContract(wrapper)` | Read inferred plaintext total supply. |
|
|
545
|
+
| `totalSupplyContract(wrapper)` | Deprecated alias for `inferredTotalSupplyContract`. |
|
|
546
546
|
|
|
547
547
|
### ERC-165
|
|
548
548
|
|
|
@@ -626,8 +626,8 @@ Individual topic hashes are accessible via the `Topics` object: `Topics.Confiden
|
|
|
626
626
|
| --------------------------------- | ----------------------------------------------------------------------------------------------------------- |
|
|
627
627
|
| `decodeConfidentialTransfer(log)` | `ConfidentialTransferEvent \| null` — `{ from, to, encryptedAmountHandle }` |
|
|
628
628
|
| `decodeWrapped(log)` | `WrappedEvent \| null` — `{ to, amountIn }` |
|
|
629
|
-
| `decodeUnwrapRequested(log)` | `UnwrapRequestedEvent \| null` — `{ receiver,
|
|
630
|
-
| `decodeUnwrappedFinalized(log)` | `UnwrappedFinalizedEvent \| null` — `{ receiver,
|
|
629
|
+
| `decodeUnwrapRequested(log)` | `UnwrapRequestedEvent \| null` — `{ receiver, encryptedAmount }` |
|
|
630
|
+
| `decodeUnwrappedFinalized(log)` | `UnwrappedFinalizedEvent \| null` — `{ receiver, encryptedAmount, cleartextAmount }` |
|
|
631
631
|
| `decodeUnwrappedStarted(log)` | `UnwrappedStartedEvent \| null` — `{ returnVal, requestId, txId, to, refund, requestedAmount, burnAmount }` |
|
|
632
632
|
| `decodeOnChainEvent(log)` | `OnChainEvent \| null` — tries all decoders |
|
|
633
633
|
| `decodeOnChainEvents(logs)` | `OnChainEvent[]` — batch decode, skips unrecognized logs |
|
|
@@ -643,6 +643,73 @@ const wrappedEvent = findWrapped(receipt.logs);
|
|
|
643
643
|
const unwrapEvent = findUnwrapRequested(receipt.logs);
|
|
644
644
|
```
|
|
645
645
|
|
|
646
|
+
## Activity Feed Helpers
|
|
647
|
+
|
|
648
|
+
Transform raw event logs into a user-friendly activity feed with decrypted amounts.
|
|
649
|
+
|
|
650
|
+
### Pipeline
|
|
651
|
+
|
|
652
|
+
```ts
|
|
653
|
+
import {
|
|
654
|
+
parseActivityFeed,
|
|
655
|
+
extractEncryptedHandles,
|
|
656
|
+
applyDecryptedValues,
|
|
657
|
+
sortByBlockNumber,
|
|
658
|
+
} from "@zama-fhe/sdk";
|
|
659
|
+
|
|
660
|
+
// 1. Parse raw logs into classified activity items
|
|
661
|
+
const items = parseActivityFeed(logs, userAddress);
|
|
662
|
+
|
|
663
|
+
// 2. Extract encrypted handles that need decryption
|
|
664
|
+
const handles = extractEncryptedHandles(items);
|
|
665
|
+
|
|
666
|
+
// 3. Decrypt handles via SDK
|
|
667
|
+
const decryptedMap = await sdk.userDecrypt(
|
|
668
|
+
handles.map((h) => ({ handle: h, contractAddress: tokenAddress })),
|
|
669
|
+
);
|
|
670
|
+
|
|
671
|
+
// 4. Apply decrypted values back to activity items
|
|
672
|
+
const enrichedItems = applyDecryptedValues(items, decryptedMap);
|
|
673
|
+
|
|
674
|
+
// 5. Sort by block number (most recent first)
|
|
675
|
+
const sorted = sortByBlockNumber(enrichedItems);
|
|
676
|
+
```
|
|
677
|
+
|
|
678
|
+
### Types
|
|
679
|
+
|
|
680
|
+
```ts
|
|
681
|
+
type ActivityDirection = "incoming" | "outgoing" | "self";
|
|
682
|
+
|
|
683
|
+
type ActivityType =
|
|
684
|
+
| "transfer"
|
|
685
|
+
| "shield"
|
|
686
|
+
| "unshield_requested"
|
|
687
|
+
| "unshield_started"
|
|
688
|
+
| "unshield_finalized";
|
|
689
|
+
|
|
690
|
+
type ActivityAmount =
|
|
691
|
+
| { type: "clear"; value: bigint }
|
|
692
|
+
| { type: "encrypted"; handle: string; decryptedValue?: bigint };
|
|
693
|
+
|
|
694
|
+
interface ActivityItem {
|
|
695
|
+
type: ActivityType;
|
|
696
|
+
direction: ActivityDirection;
|
|
697
|
+
amount: ActivityAmount;
|
|
698
|
+
from?: string;
|
|
699
|
+
to?: string;
|
|
700
|
+
fee?: ActivityAmount;
|
|
701
|
+
success?: boolean;
|
|
702
|
+
metadata: ActivityLogMetadata;
|
|
703
|
+
rawEvent: OnChainEvent;
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
interface ActivityLogMetadata {
|
|
707
|
+
transactionHash?: string;
|
|
708
|
+
blockNumber?: bigint | number;
|
|
709
|
+
logIndex?: number;
|
|
710
|
+
}
|
|
711
|
+
```
|
|
712
|
+
|
|
646
713
|
## Error Handling
|
|
647
714
|
|
|
648
715
|
All SDK errors extend `ZamaError`. Use `instanceof` to catch specific error types:
|
|
@@ -752,7 +819,7 @@ Low-level FHE operations are available on the relayer backend via `sdk.relayer`:
|
|
|
752
819
|
| ------------------------------ | --------------------------------- | --------------------------------------------- |
|
|
753
820
|
| `ZERO_HANDLE` | `"0x0000...0000"` (32 zero bytes) | Sentinel for empty/zero encrypted values. |
|
|
754
821
|
| `ERC7984_INTERFACE_ID` | `"0x4958f2a4"` | ERC-165 interface ID for confidential tokens. |
|
|
755
|
-
| `ERC7984_WRAPPER_INTERFACE_ID` | `"
|
|
822
|
+
| `ERC7984_WRAPPER_INTERFACE_ID` | `"0xd04584ba"` | ERC-165 interface ID for wrapper contracts. |
|
|
756
823
|
|
|
757
824
|
## Exported ABIs
|
|
758
825
|
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
const e=require(`./relayer.cjs`),t=require(`./wrappers-registry.cjs`);let n=require(`viem`);var r=class extends e.a{constructor(t,n){super(e.o.SigningRejected,t,n),this.name=`SigningRejectedError`}},i=class extends e.a{constructor(t,n){super(e.o.SigningFailed,t,n),this.name=`SigningFailedError`}};function a(e,t){let n=typeof e==`object`&&!!e&&`code`in e&&e.code===4001,a=e instanceof Error?e.message:String(e),o=a.toLowerCase(),s=o.includes(`user rejected`)||o.includes(`user denied`),c=`${t}: ${a}`;throw n||s?new r(c,{cause:e}):new i(c,{cause:e})}var o=class extends e.a{constructor(t,n){super(e.o.KeypairExpired,t,n),this.name=`KeypairExpiredError`}},s=class extends e.a{constructor(t,n){super(e.o.InvalidKeypair,t,n),this.name=`InvalidKeypairError`}},c=class extends e.a{constructor(t,n){super(e.o.NoCiphertext,t,n),this.name=`NoCiphertextError`}},l=class extends e.a{constructor(t,n){super(e.o.DelegationSelfNotAllowed,t,n),this.name=`DelegationSelfNotAllowedError`}},u=class extends e.a{constructor(t,n){super(e.o.DelegationCooldown,t,n),this.name=`DelegationCooldownError`}},d=class extends e.a{constructor(t,n){super(e.o.DelegationNotFound,t,n),this.name=`DelegationNotFoundError`}},f=class extends e.a{constructor(t,n){super(e.o.DelegationExpired,t,n),this.name=`DelegationExpiredError`}},p=class extends e.a{constructor(t,n){super(e.o.DelegationExpiryUnchanged,t,n),this.name=`DelegationExpiryUnchangedError`}},m=class extends e.a{constructor(t,n){super(e.o.DelegationDelegateEqualsContract,t,n),this.name=`DelegationDelegateEqualsContractError`}},h=class extends e.a{constructor(t,n){super(e.o.DelegationContractIsSelf,t,n),this.name=`DelegationContractIsSelfError`}},g=class extends e.a{constructor(t,n){super(e.o.AclPaused,t,n),this.name=`AclPausedError`}},_=class extends e.a{constructor(t,n){super(e.o.DelegationExpirationTooSoon,t,n),this.name=`DelegationExpirationTooSoonError`}},v=class extends e.a{constructor(t,n){super(e.o.DelegationNotPropagated,t,n),this.name=`DelegationNotPropagatedError`}};function y(t,n,a=!1){if(t instanceof e.r||t instanceof c||t instanceof e.n||t instanceof v||t instanceof r||t instanceof i)return t;let o=typeof t==`object`&&t&&`statusCode`in t&&typeof t.statusCode==`number`?t.statusCode:void 0;return o===400?new c(t instanceof Error?t.message:`No ciphertext for this account`,{cause:t}):a&&o===500?new v(`Delegated decryption failed with a server error. This is most commonly caused by the delegation not having propagated to the gateway yet — after granting delegation, allow 1–2 minutes for cross-chain synchronization before retrying. If the error persists, the gateway or relayer may be experiencing an unrelated issue.`,{cause:t}):o===void 0?new e.r(n,{cause:t}):new e.n(t instanceof Error?t.message:n,o,{cause:t})}function b(t){return t instanceof r||t instanceof i||t instanceof e.t}function ee(e,t){if(e==null)throw TypeError(`${t} must not be null or undefined`)}function te(e,t){if(typeof e!=`object`||!e||Array.isArray(e))throw TypeError(`${t} must be an object, got ${typeof e}`)}function x(e,t){if(typeof e!=`string`)throw TypeError(`${t} must be a string, got ${typeof e}`)}function ne(e,t){if(!Array.isArray(e))throw TypeError(`${t} must be an array, got ${typeof e}`)}function re(e,t){if(typeof e!=`function`)throw TypeError(`${t} must be a function, got ${typeof e}`)}function S(e,t){if(typeof e!=`bigint`)throw TypeError(`${t} must be a bigint, got ${typeof e}`)}function ie(e,t,n){x(e[t],n)}function ae(e,t,n){re(e[t],n)}function oe(e,t){if(!e)throw TypeError(t)}function C(e){return e instanceof Error?e:typeof e==`object`&&e&&`message`in e?Error(String(e.message)):Error(String(e))}function se(e){if(!(e instanceof Error))return!1;if(e.name===`ContractFunctionExecutionError`||e.name===`ContractFunctionRevertedError`||`code`in e&&e.code===`CALL_EXCEPTION`)return!0;let t=e.message.toLowerCase();return t.includes(`execution reverted`)||t.includes(`call revert exception`)}function w(e){return e.startsWith(`0x`)?e:`0x${e}`}function T(e){return e===`0x0000000000000000000000000000000000000000000000000000000000000000`||e===`0x`}function E(e){return{address:e,abi:n.erc20Abi,functionName:`name`,args:[]}}function D(e){return{address:e,abi:n.erc20Abi,functionName:`symbol`,args:[]}}function O(e){return{address:e,abi:n.erc20Abi,functionName:`decimals`,args:[]}}function ce(e){return{address:e,abi:n.erc20Abi,functionName:`totalSupply`,args:[]}}function le(e,t){return{address:e,abi:n.erc20Abi,functionName:`balanceOf`,args:[t]}}function k(e,t,r){return{address:e,abi:n.erc20Abi,functionName:`allowance`,args:[t,r]}}function ue(e,t,r){return{address:e,abi:n.erc20Abi,functionName:`approve`,args:[t,r]}}const A=[{inputs:[{internalType:`address`,name:`delegate`,type:`address`},{internalType:`address`,name:`contractAddress`,type:`address`},{internalType:`uint64`,name:`expirationDate`,type:`uint64`}],name:`delegateForUserDecryption`,outputs:[],stateMutability:`nonpayable`,type:`function`},{inputs:[{internalType:`address`,name:`delegate`,type:`address`},{internalType:`address`,name:`contractAddress`,type:`address`}],name:`revokeDelegationForUserDecryption`,outputs:[],stateMutability:`nonpayable`,type:`function`},{inputs:[{internalType:`address`,name:`delegator`,type:`address`},{internalType:`address`,name:`delegate`,type:`address`},{internalType:`address`,name:`contractAddress`,type:`address`}],name:`getUserDecryptionDelegationExpirationDate`,outputs:[{internalType:`uint64`,name:``,type:`uint64`}],stateMutability:`view`,type:`function`},{inputs:[{internalType:`address`,name:`delegator`,type:`address`},{internalType:`address`,name:`delegate`,type:`address`},{internalType:`address`,name:`contractAddress`,type:`address`},{internalType:`bytes32`,name:`handle`,type:`bytes32`}],name:`isHandleDelegatedForUserDecryption`,outputs:[{internalType:`bool`,name:``,type:`bool`}],stateMutability:`view`,type:`function`}];function de(e,t,n,r){return{address:e,abi:A,functionName:`delegateForUserDecryption`,args:[t,n,r]}}function fe(e,t,n){return{address:e,abi:A,functionName:`revokeDelegationForUserDecryption`,args:[t,n]}}function j(e,t,n,r){return{address:e,abi:A,functionName:`getUserDecryptionDelegationExpirationDate`,args:[t,n,r]}}function pe(e,t,n,r,i){return{address:e,abi:A,functionName:`isHandleDelegatedForUserDecryption`,args:[t,n,r,i]}}const M=2n**64n-1n,N={CredentialsLoading:`credentials:loading`,CredentialsCached:`credentials:cached`,CredentialsExpired:`credentials:expired`,CredentialsCreating:`credentials:creating`,CredentialsCreated:`credentials:created`,CredentialsRevoked:`credentials:revoked`,CredentialsPersistFailed:`credentials:persist_failed`,CredentialsAllowed:`credentials:allowed`,CredentialsCorrupted:`credentials:corrupted`,SessionExpired:`session:expired`,EncryptStart:`encrypt:start`,EncryptEnd:`encrypt:end`,EncryptError:`encrypt:error`,DecryptStart:`decrypt:start`,DecryptEnd:`decrypt:end`,DecryptError:`decrypt:error`,TransactionError:`transaction:error`,ShieldSubmitted:`shield:submitted`,TransferSubmitted:`transfer:submitted`,TransferFromSubmitted:`transferFrom:submitted`,ApproveSubmitted:`approve:submitted`,ApproveUnderlyingSubmitted:`approveUnderlying:submitted`,UnwrapSubmitted:`unwrap:submitted`,FinalizeUnwrapSubmitted:`finalizeUnwrap:submitted`,DelegationSubmitted:`delegation:submitted`,RevokeDelegationSubmitted:`revokeDelegation:submitted`,UnshieldPhase1Submitted:`unshield:phase1_submitted`,UnshieldPhase2Started:`unshield:phase2_started`,UnshieldPhase2Submitted:`unshield:phase2_submitted`};async function P(e,t=1/0){if(Number.isFinite(t)&&t<=0)throw Error(`maxConcurrency must be a positive number`);if(!Number.isFinite(t)||t>=e.length)return Promise.all(e.map(e=>e()));let n=Array.from({length:e.length}),r=0;async function i(){for(;r<e.length;){let t=r++;e[t]&&(n[t]=await e[t]())}}return await Promise.all(Array.from({length:t},i)),n}var me=class r{sdk;address;constructor(e,t){this.sdk=e,this.address=(0,n.getAddress)(t)}async balanceOf(t){let r=t?(0,n.getAddress)(t):await this.sdk.signer.getAddress(),i=await this.readConfidentialBalanceOf(r),a=(await this.sdk.userDecrypt([{handle:i,contractAddress:this.address}]))[i];if(a===void 0)throw new e.r(`Decryption returned no value for handle ${i}`);return S(a,`balanceOf: result[handle]`),a}async confidentialBalanceOf(e){let t=e?(0,n.getAddress)(e):await this.sdk.signer.getAddress();return this.readConfidentialBalanceOf(t)}async isConfidential(){return this.sdk.signer.readContract(t.f(this.address,t.c))}async isWrapper(){return this.sdk.signer.readContract(t.f(this.address,t.l))}static async batchBalancesOf(t,n){let i=new Map,a=new Map;if(t.length===0)return{results:i,errors:a};await r.assertSameSdk(t).allow(t.map(e=>e.address));let o=await P(t.map(e=>async()=>{try{return{status:`fulfilled`,value:await e.balanceOf(n)}}catch(e){return{status:`rejected`,reason:e}}}),5);for(let n=0;n<t.length;n++){let r=t[n].address,s=o[n];if(s.status===`fulfilled`)i.set(r,s.value);else{let t=s.reason;if(b(t))throw t;let n=t instanceof e.a?t:new e.r(C(t).message,{cause:t});a.set(r,n)}}if(a.size===t.length)throw a.values().next().value??new e.r(`All token balance decryptions failed`);return{results:i,errors:a}}static async batchDecryptBalancesAs(t,n){if(t.length===0)return new Map;let{delegatorAddress:i,handles:a,owner:o,onError:s,maxConcurrency:c}=n,l=o??i,u=t[0];r.assertSameSdk(t);let d=a??await Promise.all(t.map(e=>e.readConfidentialBalanceOf(l)));if(t.length!==d.length)throw new e.r(`tokens.length (${t.length}) must equal handles.length (${d.length})`);let f=new Map,p=[],m=await Promise.all(t.map(async(e,t)=>{let n=d[t];return T(n)?0n:u.sdk.cache.get(l,e.address,n)}));for(let e=0;e<t.length;e++){let n=t[e],r=d[e],i=m[e];if(i!=null){S(i,`batchDecryptBalancesAs: cached`),f.set(n.address,i);continue}p.push({token:n,handle:r})}if(p.length===0)return f;await u.#e(i);let h=p.map(e=>e.token.address),g=await u.sdk.delegatedCredentials.allow(i,...h),_=[],v=[];for(let{token:t,handle:n}of p)v.push(()=>u.sdk.relayer.delegatedUserDecrypt({handles:[n],contractAddress:t.address,signedContractAddresses:g.contractAddresses,privateKey:g.privateKey,publicKey:g.publicKey,signature:g.signature,delegatorAddress:g.delegatorAddress,delegateAddress:g.delegateAddress,startTimestamp:g.startTimestamp,durationDays:g.durationDays}).then(async r=>{let i=r[n];if(i===void 0)throw new e.r(`Batch delegated decryption returned no value for handle ${n} on token ${t.address}`);S(i,`batchDecryptBalancesAs: result[handle]`),f.set(t.address,i),u.sdk.cache.set(l,t.address,n,i).catch(e=>{console.warn(`[zama-sdk] Failed to cache decrypted value:`,e)})}).catch(e=>{if(b(e))throw e;let n=C(e);if(s)try{f.set(t.address,s(n,t.address))}catch(e){_.push({address:t.address,error:C(e)})}else _.push({address:t.address,error:n})}));if(await P(v,c),_.length>0){let t=_.map(e=>`${e.address}: ${e.error.message}`).join(`; `);throw new e.r(`Batch delegated decryption failed for ${_.length} token(s): ${t}`,{cause:_[0].error})}return f}async underlyingToken(){return this.sdk.signer.readContract(t.T(this.address))}async allowance(e,r){let i=(0,n.getAddress)(e),a=await this.sdk.signer.readContract(t.T(i)),o=r?(0,n.getAddress)(r):await this.sdk.signer.getAddress();return this.sdk.signer.readContract(k(a,o,i))}async name(){return this.sdk.signer.readContract(E(this.address))}async symbol(){return this.sdk.signer.readContract(D(this.address))}async decimals(){return this.sdk.signer.readContract(O(this.address))}async allow(){await this.sdk.allow([this.address])}async isAllowed(){return this.sdk.credentials.isAllowed([this.address])}async revoke(...e){await this.sdk.credentials.revoke(...e)}static async allow(...e){e.length!==0&&await r.assertSameSdk(e).allow(e.map(e=>e.address))}async getAclAddress(){return this.sdk.relayer.getAclAddress()}async isDelegated(e){let t=await this.getDelegationExpiry(e);return t===0n?!1:t===M?!0:t>await this.sdk.signer.getBlockTimestamp()}async getDelegationExpiry({delegatorAddress:e,delegateAddress:t}){let r=await this.getAclAddress();return this.sdk.signer.readContract(j(r,(0,n.getAddress)(e),(0,n.getAddress)(t),this.address))}async#e(e){let t=await this.sdk.signer.getAddress(),n=await this.getDelegationExpiry({delegatorAddress:e,delegateAddress:t});if(n===0n)throw new d(`No active delegation from ${e} to ${t} for ${this.address}`);if(n!==M&&n<=await this.sdk.signer.getBlockTimestamp())throw new f(`Delegation from ${e} to ${t} for ${this.address} has expired`)}async readConfidentialBalanceOf(e){return await this.sdk.signer.readContract(t.p(this.address,e))}async decryptBalanceAs({delegatorAddress:t,owner:r}){let i=(0,n.getAddress)(t),a=r?(0,n.getAddress)(r):i,o=await this.readConfidentialBalanceOf(a);if(T(o))return 0n;let s=await this.sdk.cache.get(a,this.address,o);if(s!==null)return S(s,`decryptBalanceAs: cached`),s;await this.#e(i);let c=Date.now();try{this.emit({type:N.DecryptStart,handles:[o]});let t=await this.sdk.delegatedCredentials.allow(i,this.address),n=await this.sdk.relayer.delegatedUserDecrypt({handles:[o],contractAddress:this.address,signedContractAddresses:t.contractAddresses,privateKey:t.privateKey,publicKey:t.publicKey,signature:t.signature,delegatorAddress:t.delegatorAddress,delegateAddress:t.delegateAddress,startTimestamp:t.startTimestamp,durationDays:t.durationDays}),r=n[o];if(r===void 0)throw new e.r(`Delegated decryption returned no value for handle ${o}`);return S(r,`decryptBalanceAs: result[handle]`),this.emit({type:N.DecryptEnd,durationMs:Date.now()-c,handles:[o],result:n}),await this.sdk.cache.set(a,this.address,o,r),r}catch(e){throw this.emit({type:N.DecryptError,error:C(e),durationMs:Date.now()-c,handles:[o]}),y(e,`Failed to decrypt delegated balance`,!0)}}emit(e){this.sdk.emitEvent(e,this.address)}static assertSameSdk(t){let n=t[0].sdk;for(let r=1;r<t.length;r++)if(t[r].sdk!==n)throw new e.t(`All tokens in a batch operation must share the same ZamaSDK instance`);return n}};const F={ConfidentialTransfer:`0x67500e8d0ed826d2194f514dd0d8124f35648ab6e3fb5e6ed867134cffe661e9`,Wrapped:`0x4700c1726b4198077cd40320a32c45265a1910521eb0ef713dd1d8412413d7fc`,UnwrapRequested:`0x77d02d353c5629272875d11f1b34ec4c65d7430b075575b78cd2502034c469ee`,UnwrappedFinalized:`0x2d4edf3c2943002120f53dab3f8940043f34799f4a92ab90f2f81f7dd004a49e`,UnwrappedStarted:`0x3838891d4843c6d7f9f494570b6fd8843f4e3c3ddb817c1411760bd31b819806`};function I(e){return(0,n.getAddress)(w(e.slice(-40)))}function L(e){return BigInt(e)}function he(e){return e}function R(e,t){let n=2+t*64,r=e.slice(n,n+64);return r.length===64?r:r.padEnd(64,`0`)}function z(e,t){return(0,n.getAddress)(w(R(e,t).slice(-40)))}function B(e,t){return BigInt(`0x`+R(e,t))}function ge(e,t){return BigInt(`0x`+R(e,t))!==0n}function V(e,t){return w(R(e,t))}function H(e){return e.topics[0]!==F.ConfidentialTransfer||e.topics.length<4?null:{eventName:`ConfidentialTransfer`,from:I(e.topics[1]),to:I(e.topics[2]),encryptedAmountHandle:he(e.topics[3])}}function U(e){return e.topics[0]!==F.Wrapped||e.topics.length<2?null:{eventName:`Wrapped`,to:I(e.topics[1]),amountIn:B(e.data,0)}}function W(e){return e.topics[0]!==F.UnwrapRequested||e.topics.length<2?null:{eventName:`UnwrapRequested`,receiver:I(e.topics[1]),encryptedAmount:V(e.data,0)}}function G(e){return e.topics[0]!==F.UnwrappedFinalized||e.topics.length<2?null:{eventName:`UnwrappedFinalized`,receiver:I(e.topics[1]),encryptedAmount:V(e.data,0),cleartextAmount:B(e.data,1)}}function K(e){return e.topics[0]!==F.UnwrappedStarted||e.topics.length<4?null:{eventName:`UnwrappedStarted`,requestId:L(e.topics[1]),txId:L(e.topics[2]),to:I(e.topics[3]),returnVal:ge(e.data,0),refund:z(e.data,1),requestedAmount:V(e.data,2),burnAmount:V(e.data,3)}}function q(e){return H(e)??U(e)??W(e)??G(e)??K(e)}function _e(e){let t=[];for(let n of e){let e=q(n);e&&t.push(e)}return t}function ve(e){for(let t of e){let e=W(t);if(e)return e}return null}function ye(e){for(let t of e){let e=U(t);if(e)return e}return null}const be=[F.ConfidentialTransfer,F.Wrapped,F.UnwrapRequested,F.UnwrappedFinalized,F.UnwrappedStarted],J={DelegatedForUserDecryption:`0x527b025d7ff06689c1ab9d32dfd7881c964cce72ce8ac5b2fe1d3be8cfda5bfc`,RevokedDelegationForUserDecryption:`0x7aca80b6b7928b9038f186e3d9922a0fc5d52c398fbf144725c142c52a5277e4`};function Y(e){return e.topics[0]!==J.DelegatedForUserDecryption||e.topics.length<3?null:{eventName:`DelegatedForUserDecryption`,delegator:I(e.topics[1]),delegate:I(e.topics[2]),contractAddress:z(e.data,0),delegationCounter:B(e.data,1),oldExpirationDate:B(e.data,2),newExpirationDate:B(e.data,3)}}function X(e){return e.topics[0]!==J.RevokedDelegationForUserDecryption||e.topics.length<3?null:{eventName:`RevokedDelegationForUserDecryption`,delegator:I(e.topics[1]),delegate:I(e.topics[2]),contractAddress:z(e.data,0),delegationCounter:B(e.data,1),oldExpirationDate:B(e.data,2)}}function Z(e){return Y(e)??X(e)}function xe(e){let t=[];for(let n of e){let e=Z(n);e&&t.push(e)}return t}function Se(e){for(let t of e){let e=Y(t);if(e)return e}return null}function Ce(e){for(let t of e){let e=X(t);if(e)return e}return null}const we=[J.DelegatedForUserDecryption,J.RevokedDelegationForUserDecryption];function Q(e,t){return e.toLowerCase()===t.toLowerCase()}function $(e,t,n){let r=t!==void 0&&Q(e,t),i=n!==void 0&&Q(e,n);return r&&i?`self`:r?`outgoing`:`incoming`}function Te(e,t,n){switch(e.eventName){case`ConfidentialTransfer`:return Ee(e,t,n);case`Wrapped`:return De(e,t,n);case`UnwrapRequested`:return Oe(e,t,n);case`UnwrappedStarted`:return ke(e,t,n);case`UnwrappedFinalized`:return Ae(e,t,n);default:throw Error(`Unknown event: ${e.eventName}`)}}function Ee(e,t,n){return{type:`transfer`,direction:$(t,e.from,e.to),amount:{type:`encrypted`,handle:e.encryptedAmountHandle},from:e.from,to:e.to,metadata:n,rawEvent:e}}function De(e,t,n){return{type:`shield`,direction:$(t,void 0,e.to),amount:{type:`clear`,value:e.amountIn},to:e.to,metadata:n,rawEvent:e}}function Oe(e,t,n){return{type:`unshield_requested`,direction:$(t,void 0,e.receiver),amount:{type:`encrypted`,handle:e.encryptedAmount},to:e.receiver,metadata:n,rawEvent:e}}function ke(e,t,n){return{type:`unshield_started`,direction:$(t,void 0,e.to),amount:{type:`encrypted`,handle:e.requestedAmount},to:e.to,success:e.returnVal,metadata:n,rawEvent:e}}function Ae(e,t,n){return{type:`unshield_finalized`,direction:$(t,void 0,e.receiver),amount:{type:`clear`,value:e.cleartextAmount},to:e.receiver,metadata:n,rawEvent:e}}function je(e,t){let n=[];for(let r of e){let e=q(r);if(!e)continue;let i={transactionHash:r.transactionHash,blockNumber:r.blockNumber,logIndex:r.logIndex};n.push(Te(e,t,i))}return n}function Me(e){let t=new Set;for(let n of e)if(n.amount.type===`encrypted`&&n.amount.decryptedValue===void 0){let e=n.amount.handle;T(e)||t.add(e)}return[...t]}function Ne(e,t){return e.map(e=>{if(e.amount.type!==`encrypted`)return e;let n=t[e.amount.handle];return n===void 0?e:(S(n,`applyDecryptedValues: value`),{...e,amount:{type:`encrypted`,handle:e.amount.handle,decryptedValue:n}})})}function Pe(e){return[...e].toSorted((e,t)=>{let n=e.metadata.blockNumber,r=t.metadata.blockNumber;if(n===void 0&&r===void 0)return 0;if(n===void 0)return-1;if(r===void 0)return 1;let i=typeof n==`bigint`?n:BigInt(n),a=typeof r==`bigint`?r:BigInt(r);if(a>i)return 1;if(a<i)return-1;let o=e.metadata.logIndex??0;return(t.metadata.logIndex??0)-o})}Object.defineProperty(exports,`$`,{enumerable:!0,get:function(){return g}}),Object.defineProperty(exports,`A`,{enumerable:!0,get:function(){return pe}}),Object.defineProperty(exports,`B`,{enumerable:!0,get:function(){return T}}),Object.defineProperty(exports,`C`,{enumerable:!0,get:function(){return ye}}),Object.defineProperty(exports,`D`,{enumerable:!0,get:function(){return M}}),Object.defineProperty(exports,`E`,{enumerable:!0,get:function(){return N}}),Object.defineProperty(exports,`F`,{enumerable:!0,get:function(){return O}}),Object.defineProperty(exports,`G`,{enumerable:!0,get:function(){return S}}),Object.defineProperty(exports,`H`,{enumerable:!0,get:function(){return se}}),Object.defineProperty(exports,`I`,{enumerable:!0,get:function(){return ce}}),Object.defineProperty(exports,`J`,{enumerable:!0,get:function(){return ee}}),Object.defineProperty(exports,`K`,{enumerable:!0,get:function(){return oe}}),Object.defineProperty(exports,`L`,{enumerable:!0,get:function(){return E}}),Object.defineProperty(exports,`M`,{enumerable:!0,get:function(){return k}}),Object.defineProperty(exports,`N`,{enumerable:!0,get:function(){return ue}}),Object.defineProperty(exports,`O`,{enumerable:!0,get:function(){return de}}),Object.defineProperty(exports,`P`,{enumerable:!0,get:function(){return le}}),Object.defineProperty(exports,`Q`,{enumerable:!0,get:function(){return y}}),Object.defineProperty(exports,`R`,{enumerable:!0,get:function(){return D}}),Object.defineProperty(exports,`S`,{enumerable:!0,get:function(){return ve}}),Object.defineProperty(exports,`T`,{enumerable:!0,get:function(){return P}}),Object.defineProperty(exports,`U`,{enumerable:!0,get:function(){return C}}),Object.defineProperty(exports,`V`,{enumerable:!0,get:function(){return w}}),Object.defineProperty(exports,`W`,{enumerable:!0,get:function(){return ne}}),Object.defineProperty(exports,`X`,{enumerable:!0,get:function(){return x}}),Object.defineProperty(exports,`Y`,{enumerable:!0,get:function(){return te}}),Object.defineProperty(exports,`Z`,{enumerable:!0,get:function(){return ie}}),Object.defineProperty(exports,`_`,{enumerable:!0,get:function(){return G}}),Object.defineProperty(exports,`a`,{enumerable:!0,get:function(){return we}}),Object.defineProperty(exports,`at`,{enumerable:!0,get:function(){return p}}),Object.defineProperty(exports,`b`,{enumerable:!0,get:function(){return Se}}),Object.defineProperty(exports,`c`,{enumerable:!0,get:function(){return F}}),Object.defineProperty(exports,`ct`,{enumerable:!0,get:function(){return l}}),Object.defineProperty(exports,`d`,{enumerable:!0,get:function(){return H}}),Object.defineProperty(exports,`dt`,{enumerable:!0,get:function(){return c}}),Object.defineProperty(exports,`et`,{enumerable:!0,get:function(){return h}}),Object.defineProperty(exports,`f`,{enumerable:!0,get:function(){return Y}}),Object.defineProperty(exports,`ft`,{enumerable:!0,get:function(){return i}}),Object.defineProperty(exports,`g`,{enumerable:!0,get:function(){return W}}),Object.defineProperty(exports,`h`,{enumerable:!0,get:function(){return X}}),Object.defineProperty(exports,`i`,{enumerable:!0,get:function(){return Pe}}),Object.defineProperty(exports,`it`,{enumerable:!0,get:function(){return f}}),Object.defineProperty(exports,`j`,{enumerable:!0,get:function(){return fe}}),Object.defineProperty(exports,`k`,{enumerable:!0,get:function(){return j}}),Object.defineProperty(exports,`l`,{enumerable:!0,get:function(){return Z}}),Object.defineProperty(exports,`lt`,{enumerable:!0,get:function(){return s}}),Object.defineProperty(exports,`m`,{enumerable:!0,get:function(){return _e}}),Object.defineProperty(exports,`mt`,{enumerable:!0,get:function(){return a}}),Object.defineProperty(exports,`n`,{enumerable:!0,get:function(){return Me}}),Object.defineProperty(exports,`nt`,{enumerable:!0,get:function(){return m}}),Object.defineProperty(exports,`o`,{enumerable:!0,get:function(){return J}}),Object.defineProperty(exports,`ot`,{enumerable:!0,get:function(){return d}}),Object.defineProperty(exports,`p`,{enumerable:!0,get:function(){return q}}),Object.defineProperty(exports,`pt`,{enumerable:!0,get:function(){return r}}),Object.defineProperty(exports,`q`,{enumerable:!0,get:function(){return ae}}),Object.defineProperty(exports,`r`,{enumerable:!0,get:function(){return je}}),Object.defineProperty(exports,`rt`,{enumerable:!0,get:function(){return _}}),Object.defineProperty(exports,`s`,{enumerable:!0,get:function(){return be}}),Object.defineProperty(exports,`st`,{enumerable:!0,get:function(){return v}}),Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return Ne}}),Object.defineProperty(exports,`tt`,{enumerable:!0,get:function(){return u}}),Object.defineProperty(exports,`u`,{enumerable:!0,get:function(){return xe}}),Object.defineProperty(exports,`ut`,{enumerable:!0,get:function(){return o}}),Object.defineProperty(exports,`v`,{enumerable:!0,get:function(){return K}}),Object.defineProperty(exports,`w`,{enumerable:!0,get:function(){return me}}),Object.defineProperty(exports,`x`,{enumerable:!0,get:function(){return Ce}}),Object.defineProperty(exports,`y`,{enumerable:!0,get:function(){return U}}),Object.defineProperty(exports,`z`,{enumerable:!0,get:function(){return`0x0000000000000000000000000000000000000000000000000000000000000000`}});
|
|
2
|
+
//# sourceMappingURL=activity.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"activity.cjs","names":["ZamaError","ZamaErrorCode","ZamaError","ZamaErrorCode","ZamaError","ZamaErrorCode","DecryptionFailedError","RelayerRequestFailedError","ConfigurationError","erc20Abi","DecryptionFailedError","supportsInterfaceContract","ERC7984_INTERFACE_ID","ERC7984_WRAPPER_INTERFACE_ID","ZamaError","#assertDelegationActive","underlyingContract","confidentialBalanceOfContract","ConfigurationError"],"sources":["../../src/errors/signing.ts","../../src/errors/credential.ts","../../src/errors/delegation.ts","../../src/errors/decrypt.ts","../../src/errors/session.ts","../../src/utils/assertions.ts","../../src/utils/error.ts","../../src/utils/hex.ts","../../src/utils/handles.ts","../../src/contracts/erc20.ts","../../src/abi/acl.abi.ts","../../src/contracts/acl.ts","../../src/contracts/constants.ts","../../src/events/sdk-events.ts","../../src/utils/concurrency.ts","../../src/token/readonly-token.ts","../../src/events/onchain-events.ts","../../src/activity.ts"],"sourcesContent":["import { ZamaError, ZamaErrorCode } from \"./base\";\n\n/** User rejected the wallet signature prompt. */\nexport class SigningRejectedError extends ZamaError {\n constructor(message: string, options?: ErrorOptions) {\n super(ZamaErrorCode.SigningRejected, message, options);\n this.name = \"SigningRejectedError\";\n }\n}\n\n/** Wallet signature failed for a reason other than rejection. */\nexport class SigningFailedError extends ZamaError {\n constructor(message: string, options?: ErrorOptions) {\n super(ZamaErrorCode.SigningFailed, message, options);\n this.name = \"SigningFailedError\";\n }\n}\n\n/**\n * Wrap a signing error as {@link SigningRejectedError} or {@link SigningFailedError}.\n * Detects user rejection via EIP-1193 code 4001 or message heuristics.\n */\nexport function wrapSigningError(error: unknown, context: string): never {\n const hasCode4001 =\n typeof error === \"object\" && error !== null && \"code\" in error && error.code === 4001;\n const originalMsg = error instanceof Error ? error.message : String(error);\n const lowerMsg = originalMsg.toLowerCase();\n const hasRejectionMessage =\n lowerMsg.includes(\"user rejected\") || lowerMsg.includes(\"user denied\");\n const fullMessage = `${context}: ${originalMsg}`;\n if (hasCode4001 || hasRejectionMessage) {\n throw new SigningRejectedError(fullMessage, { cause: error });\n }\n throw new SigningFailedError(fullMessage, { cause: error });\n}\n","import { ZamaError, ZamaErrorCode } from \"./base\";\n\n/** FHE keypair has expired and needs regeneration. */\nexport class KeypairExpiredError extends ZamaError {\n constructor(message: string, options?: ErrorOptions) {\n super(ZamaErrorCode.KeypairExpired, message, options);\n this.name = \"KeypairExpiredError\";\n }\n}\n\n/** Relayer rejected FHE keypair (stale, expired, or malformed). */\nexport class InvalidKeypairError extends ZamaError {\n constructor(message: string, options?: ErrorOptions) {\n super(ZamaErrorCode.InvalidKeypair, message, options);\n this.name = \"InvalidKeypairError\";\n }\n}\n\n/** No FHE ciphertext exists for this account (never shielded). */\nexport class NoCiphertextError extends ZamaError {\n constructor(message: string, options?: ErrorOptions) {\n super(ZamaErrorCode.NoCiphertext, message, options);\n this.name = \"NoCiphertextError\";\n }\n}\n","import { ZamaError, ZamaErrorCode } from \"./base\";\n\n// Delegation errors — thrown by SDK pre-flight checks and by `matchAclRevert()`\n// when it maps ACL Solidity revert reasons to typed errors.\n\n/** Delegation cannot target self (delegate === msg.sender). */\nexport class DelegationSelfNotAllowedError extends ZamaError {\n constructor(message: string, options?: ErrorOptions) {\n super(ZamaErrorCode.DelegationSelfNotAllowed, message, options);\n this.name = \"DelegationSelfNotAllowedError\";\n }\n}\n\n/** Only one delegate/revoke per (delegator, delegate, contract) per block. */\nexport class DelegationCooldownError extends ZamaError {\n constructor(message: string, options?: ErrorOptions) {\n super(ZamaErrorCode.DelegationCooldown, message, options);\n this.name = \"DelegationCooldownError\";\n }\n}\n\n/** No active delegation found for this (delegator, delegate, contract) tuple. */\nexport class DelegationNotFoundError extends ZamaError {\n constructor(message: string, options?: ErrorOptions) {\n super(ZamaErrorCode.DelegationNotFound, message, options);\n this.name = \"DelegationNotFoundError\";\n }\n}\n\n/** The delegation has expired. */\nexport class DelegationExpiredError extends ZamaError {\n constructor(message: string, options?: ErrorOptions) {\n super(ZamaErrorCode.DelegationExpired, message, options);\n this.name = \"DelegationExpiredError\";\n }\n}\n\n/** The new expiration date equals the current one. */\nexport class DelegationExpiryUnchangedError extends ZamaError {\n constructor(message: string, options?: ErrorOptions) {\n super(ZamaErrorCode.DelegationExpiryUnchanged, message, options);\n this.name = \"DelegationExpiryUnchangedError\";\n }\n}\n\n/** Delegate address cannot be the contract address. */\nexport class DelegationDelegateEqualsContractError extends ZamaError {\n constructor(message: string, options?: ErrorOptions) {\n super(ZamaErrorCode.DelegationDelegateEqualsContract, message, options);\n this.name = \"DelegationDelegateEqualsContractError\";\n }\n}\n\n/** Contract address cannot be the sender address. */\nexport class DelegationContractIsSelfError extends ZamaError {\n constructor(message: string, options?: ErrorOptions) {\n super(ZamaErrorCode.DelegationContractIsSelf, message, options);\n this.name = \"DelegationContractIsSelfError\";\n }\n}\n\n/** The ACL contract is paused. */\nexport class AclPausedError extends ZamaError {\n constructor(message: string, options?: ErrorOptions) {\n super(ZamaErrorCode.AclPaused, message, options);\n this.name = \"AclPausedError\";\n }\n}\n\n/** Expiration date is too soon (must be at least 1 hour in the future). */\nexport class DelegationExpirationTooSoonError extends ZamaError {\n constructor(message: string, options?: ErrorOptions) {\n super(ZamaErrorCode.DelegationExpirationTooSoon, message, options);\n this.name = \"DelegationExpirationTooSoonError\";\n }\n}\n\n/**\n * Delegation exists on L1 but hasn't propagated to the gateway yet.\n *\n * After calling `delegateForUserDecryption()`, the delegation is recorded on-chain\n * immediately. However, the gateway (deployed on Arbitrum) must sync this state\n * via cross-chain event propagation, which typically takes 1–2 minutes.\n *\n * Calling `decryptBalanceAs` during this window will fail because the gateway's\n * `isHandleDelegatedForUserDecryption()` check reads from its own synced copy\n * of the ACL state, which hasn't been updated yet.\n *\n * **Note:** This error is raised as a best-effort heuristic — when a delegated\n * decryption receives an HTTP 500 from the relayer, the most likely cause is a\n * propagation delay. However, the same status code can occur if the gateway or\n * relayer experiences an unrelated internal error.\n */\nexport class DelegationNotPropagatedError extends ZamaError {\n constructor(message: string, options?: ErrorOptions) {\n super(ZamaErrorCode.DelegationNotPropagated, message, options);\n this.name = \"DelegationNotPropagatedError\";\n }\n}\n","import type { ZamaError } from \"./base\";\nimport { DecryptionFailedError } from \"./encryption\";\nimport { NoCiphertextError } from \"./credential\";\nimport { RelayerRequestFailedError } from \"./relayer\";\nimport { DelegationNotPropagatedError } from \"./delegation\";\nimport { SigningRejectedError, SigningFailedError } from \"./signing\";\n\n/**\n * Inspect a caught error for an HTTP status code and return the appropriate\n * typed SDK error (NoCiphertextError for 400, RelayerRequestFailedError for\n * other HTTP errors, or the generic DecryptionFailedError as fallback).\n *\n * Errors that are already typed SDK errors (e.g. {@link SigningRejectedError},\n * {@link DecryptionFailedError}) are returned as-is so callers can still match\n * the original cause.\n *\n * When `isDelegated` is true and the relayer returns a 500, the error is\n * wrapped as {@link DelegationNotPropagatedError} because the most likely\n * cause is that the gateway hasn't synced the delegation from L1 yet.\n */\nexport function wrapDecryptError(\n error: unknown,\n fallbackMessage: string,\n isDelegated = false,\n): ZamaError {\n if (\n error instanceof DecryptionFailedError ||\n error instanceof NoCiphertextError ||\n error instanceof RelayerRequestFailedError ||\n error instanceof DelegationNotPropagatedError ||\n error instanceof SigningRejectedError ||\n error instanceof SigningFailedError\n ) {\n return error;\n }\n\n const statusCode =\n error !== null &&\n error !== undefined &&\n typeof error === \"object\" &&\n \"statusCode\" in error &&\n typeof (error as Record<string, unknown>).statusCode === \"number\"\n ? ((error as Record<string, unknown>).statusCode as number)\n : undefined;\n\n if (statusCode === 400) {\n return new NoCiphertextError(\n error instanceof Error ? error.message : \"No ciphertext for this account\",\n { cause: error },\n );\n }\n\n if (isDelegated && statusCode === 500) {\n return new DelegationNotPropagatedError(\n \"Delegated decryption failed with a server error. \" +\n \"This is most commonly caused by the delegation not having propagated to the gateway yet — \" +\n \"after granting delegation, allow 1–2 minutes for cross-chain synchronization before retrying. \" +\n \"If the error persists, the gateway or relayer may be experiencing an unrelated issue.\",\n { cause: error },\n );\n }\n\n if (statusCode !== undefined) {\n return new RelayerRequestFailedError(\n error instanceof Error ? error.message : fallbackMessage,\n statusCode,\n { cause: error },\n );\n }\n\n return new DecryptionFailedError(fallbackMessage, {\n cause: error,\n });\n}\n","import { ConfigurationError } from \"./relayer\";\nimport { SigningRejectedError, SigningFailedError } from \"./signing\";\n\n/**\n * Returns `true` for errors that indicate a session-level failure — i.e.\n * problems that affect the whole SDK session (wallet signature rejected,\n * signing infra broken, SDK misconfigured) rather than a single item in a\n * batch operation.\n *\n * Callers iterating over a batch (e.g. per-token decrypt) should rethrow when\n * this predicate is true so the whole batch aborts, and record the error\n * per-item otherwise.\n */\nexport function isSessionError(error: unknown): boolean {\n return (\n error instanceof SigningRejectedError ||\n error instanceof SigningFailedError ||\n error instanceof ConfigurationError\n );\n}\n","export function assertNonNullable<T>(value: T, context: string): asserts value is NonNullable<T> {\n if (value === null || value === undefined) {\n throw new TypeError(`${context} must not be null or undefined`);\n }\n}\n\nexport function assertObject(\n value: unknown,\n context: string,\n): asserts value is Record<string, unknown> {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) {\n throw new TypeError(`${context} must be an object, got ${typeof value}`);\n }\n}\n\nexport function assertString(value: unknown, context: string): asserts value is string {\n if (typeof value !== \"string\") {\n throw new TypeError(`${context} must be a string, got ${typeof value}`);\n }\n}\n\nexport function assertArray(value: unknown, context: string): asserts value is unknown[] {\n if (!Array.isArray(value)) {\n throw new TypeError(`${context} must be an array, got ${typeof value}`);\n }\n}\n\n// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\nexport function assertFunction(value: unknown, context: string): asserts value is Function {\n if (typeof value !== \"function\") {\n throw new TypeError(`${context} must be a function, got ${typeof value}`);\n }\n}\n\nexport function assertBigint(value: unknown, context: string): asserts value is bigint {\n if (typeof value !== \"bigint\") {\n throw new TypeError(`${context} must be a bigint, got ${typeof value}`);\n }\n}\n\n/** Assert that `obj[key]` is a string. Narrows `obj` to include `{ [key]: string }`. */\nexport function assertStringProp<\n K extends string,\n O extends Record<string, unknown> = Record<string, unknown>,\n>(obj: O, key: K, context: string): asserts obj is O & Record<K, string> {\n assertString(obj[key], context);\n}\n\n/** Assert that `obj[key]` is a function. Narrows `obj` to include `{ [key]: F }`. */\nexport function assertFunctionProp<\n K extends string,\n // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\n F extends Function,\n O extends Record<string, unknown> = Record<string, unknown>,\n>(obj: O, key: K, context: string): asserts obj is O & Record<K, F> {\n assertFunction(obj[key], context);\n}\n\nexport function assertCondition(condition: boolean, message: string): asserts condition {\n if (!condition) {\n throw new TypeError(message);\n }\n}\n","/** Coerce an unknown caught value to an Error instance. */\nexport function toError(error: unknown): Error {\n if (error instanceof Error) {\n return error;\n }\n if (typeof error === \"object\" && error !== null && \"message\" in error) {\n return new Error(String(error.message));\n }\n return new Error(String(error));\n}\n\n/**\n * Returns true if the error is a contract call revert (as opposed to a network/transport error).\n * Detects viem's ContractFunctionExecutionError / ContractFunctionRevertedError\n * and ethers' CALL_EXCEPTION.\n */\nexport function isContractCallError(error: unknown): boolean {\n if (!(error instanceof Error)) {\n return false;\n }\n // viem: ContractFunctionExecutionError, ContractFunctionRevertedError\n if (\n error.name === \"ContractFunctionExecutionError\" ||\n error.name === \"ContractFunctionRevertedError\"\n ) {\n return true;\n }\n // ethers: error.code === \"CALL_EXCEPTION\"\n if (\"code\" in error && error.code === \"CALL_EXCEPTION\") {\n return true;\n }\n // Fallback: common revert message patterns from various providers\n const msg = error.message.toLowerCase();\n return msg.includes(\"execution reverted\") || msg.includes(\"call revert exception\");\n}\n","import type { Hex } from \"viem\";\nimport { assertCondition } from \"./assertions\";\n\n/** Normalize a un-prefixed hex payload to a 0x-prefixed `Hex` value. */\nexport function prefixHex(value: string): Hex {\n return (value.startsWith(\"0x\") ? value : `0x${value}`) as Hex;\n}\n\n/** Convert a public `Hex` value back an unprefixed format. */\nexport function unprefixHex(value: Hex): string {\n assertCondition(value.startsWith(\"0x\"), `Expected 0x-prefixed hex, got: ${value}`);\n return value.slice(2);\n}\n","export const ZERO_HANDLE =\n \"0x0000000000000000000000000000000000000000000000000000000000000000\" as const;\n\n/**\n * Check whether a handle represents the zero value.\n */\nexport function isZeroHandle(handle: string): boolean {\n return handle === ZERO_HANDLE || handle === \"0x\";\n}\n","import { erc20Abi, type Address } from \"viem\";\n\n/**\n * Returns the contract config to read a token's name.\n *\n * @example\n * ```ts\n * const name = await signer.readContract(nameContract(tokenAddress));\n * ```\n */\nexport function nameContract(tokenAddress: Address) {\n return {\n address: tokenAddress,\n abi: erc20Abi,\n functionName: \"name\",\n args: [],\n } as const;\n}\n\n/**\n * Returns the contract config to read a token's symbol.\n *\n * @example\n * ```ts\n * const symbol = await signer.readContract(symbolContract(tokenAddress));\n * ```\n */\nexport function symbolContract(tokenAddress: Address) {\n return {\n address: tokenAddress,\n abi: erc20Abi,\n functionName: \"symbol\",\n args: [],\n } as const;\n}\n\n/**\n * Returns the contract config to read a token's decimals.\n *\n * @example\n * ```ts\n * const decimals = await signer.readContract(decimalsContract(tokenAddress));\n * ```\n */\nexport function decimalsContract(tokenAddress: Address) {\n return {\n address: tokenAddress,\n abi: erc20Abi,\n functionName: \"decimals\",\n args: [],\n } as const;\n}\n\n/**\n * Returns the contract config to read an ERC-20 token's total supply.\n *\n * @example\n * ```ts\n * const supply = await signer.readContract(erc20TotalSupplyContract(tokenAddress));\n * ```\n */\nexport function erc20TotalSupplyContract(tokenAddress: Address) {\n return {\n address: tokenAddress,\n abi: erc20Abi,\n functionName: \"totalSupply\",\n args: [],\n } as const;\n}\n\n/**\n * Returns the contract config to read an ERC-20 balance.\n *\n * @example\n * ```ts\n * const balance = await signer.readContract(\n * balanceOfContract(tokenAddress, account),\n * );\n * ```\n */\nexport function balanceOfContract(tokenAddress: Address, account: Address) {\n return {\n address: tokenAddress,\n abi: erc20Abi,\n functionName: \"balanceOf\",\n args: [account],\n } as const;\n}\n\n/**\n * Returns the contract config to read an ERC-20 allowance.\n *\n * @example\n * ```ts\n * const allowance = await signer.readContract(\n * allowanceContract(tokenAddress, owner, spender),\n * );\n * ```\n */\nexport function allowanceContract(tokenAddress: Address, owner: Address, spender: Address) {\n return {\n address: tokenAddress,\n abi: erc20Abi,\n functionName: \"allowance\",\n args: [owner, spender],\n } as const;\n}\n\n/**\n * Returns the contract config for an ERC-20 approve.\n *\n * @example\n * ```ts\n * const txHash = await signer.writeContract(\n * approveContract(tokenAddress, spender, amount),\n * );\n * ```\n */\nexport function approveContract(tokenAddress: Address, spender: Address, value: bigint) {\n return {\n address: tokenAddress,\n abi: erc20Abi,\n functionName: \"approve\",\n args: [spender, value],\n } as const;\n}\n","export const aclAbi = [\n {\n inputs: [\n { internalType: \"address\", name: \"delegate\", type: \"address\" },\n { internalType: \"address\", name: \"contractAddress\", type: \"address\" },\n { internalType: \"uint64\", name: \"expirationDate\", type: \"uint64\" },\n ],\n name: \"delegateForUserDecryption\",\n outputs: [],\n stateMutability: \"nonpayable\",\n type: \"function\",\n },\n {\n inputs: [\n { internalType: \"address\", name: \"delegate\", type: \"address\" },\n { internalType: \"address\", name: \"contractAddress\", type: \"address\" },\n ],\n name: \"revokeDelegationForUserDecryption\",\n outputs: [],\n stateMutability: \"nonpayable\",\n type: \"function\",\n },\n {\n inputs: [\n { internalType: \"address\", name: \"delegator\", type: \"address\" },\n { internalType: \"address\", name: \"delegate\", type: \"address\" },\n { internalType: \"address\", name: \"contractAddress\", type: \"address\" },\n ],\n name: \"getUserDecryptionDelegationExpirationDate\",\n outputs: [{ internalType: \"uint64\", name: \"\", type: \"uint64\" }],\n stateMutability: \"view\",\n type: \"function\",\n },\n {\n inputs: [\n { internalType: \"address\", name: \"delegator\", type: \"address\" },\n { internalType: \"address\", name: \"delegate\", type: \"address\" },\n { internalType: \"address\", name: \"contractAddress\", type: \"address\" },\n { internalType: \"bytes32\", name: \"handle\", type: \"bytes32\" },\n ],\n name: \"isHandleDelegatedForUserDecryption\",\n outputs: [{ internalType: \"bool\", name: \"\", type: \"bool\" }],\n stateMutability: \"view\",\n type: \"function\",\n },\n] as const;\n","import type { Address } from \"viem\";\nimport { aclAbi } from \"../abi/acl.abi\";\n\n/**\n * Returns the contract config to delegate user decryption rights.\n *\n * @example\n * ```ts\n * const txHash = await signer.writeContract(\n * delegateForUserDecryptionContract(aclAddress, delegateAddress, contractAddress, expirationDate),\n * );\n * ```\n */\nexport function delegateForUserDecryptionContract(\n aclAddress: Address,\n delegateAddress: Address,\n contractAddress: Address,\n expirationDate: bigint,\n) {\n return {\n address: aclAddress,\n abi: aclAbi,\n functionName: \"delegateForUserDecryption\",\n args: [delegateAddress, contractAddress, expirationDate],\n } as const;\n}\n\n/**\n * Returns the contract config to revoke a user decryption delegation.\n *\n * @example\n * ```ts\n * const txHash = await signer.writeContract(\n * revokeDelegationContract(aclAddress, delegateAddress, contractAddress),\n * );\n * ```\n */\nexport function revokeDelegationContract(\n aclAddress: Address,\n delegateAddress: Address,\n contractAddress: Address,\n) {\n return {\n address: aclAddress,\n abi: aclAbi,\n functionName: \"revokeDelegationForUserDecryption\",\n args: [delegateAddress, contractAddress],\n } as const;\n}\n\n/**\n * Returns the contract config to read the delegation expiry date.\n *\n * @example\n * ```ts\n * const expiry = await signer.readContract(\n * getDelegationExpiryContract(aclAddress, delegatorAddress, delegateAddress, contractAddress),\n * );\n * ```\n */\nexport function getDelegationExpiryContract(\n aclAddress: Address,\n delegatorAddress: Address,\n delegateAddress: Address,\n contractAddress: Address,\n) {\n return {\n address: aclAddress,\n abi: aclAbi,\n functionName: \"getUserDecryptionDelegationExpirationDate\",\n args: [delegatorAddress, delegateAddress, contractAddress],\n } as const;\n}\n\n/**\n * Returns the contract config to check if a specific handle is delegated.\n *\n * @example\n * ```ts\n * const isDelegated = await signer.readContract(\n * isHandleDelegatedContract(aclAddress, delegatorAddress, delegateAddress, contractAddress, handle),\n * );\n * ```\n */\nexport function isHandleDelegatedContract(\n aclAddress: Address,\n delegatorAddress: Address,\n delegateAddress: Address,\n contractAddress: Address,\n handle: `0x${string}`,\n) {\n return {\n address: aclAddress,\n abi: aclAbi,\n functionName: \"isHandleDelegatedForUserDecryption\",\n args: [delegatorAddress, delegateAddress, contractAddress, handle],\n } as const;\n}\n","/** uint64 max — represents a permanent (no-expiry) delegation. */\nexport const MAX_UINT64 = 2n ** 64n - 1n;\n","import type { Address, Hex } from \"viem\";\nimport type { ClearValueType, Handle } from \"../relayer/relayer-sdk.types\";\n\n/**\n * All SDK event keys, accessible as `ZamaSDKEvents.EncryptStart` etc.\n */\nexport const ZamaSDKEvents = {\n // Credentials lifecycle\n CredentialsLoading: \"credentials:loading\",\n CredentialsCached: \"credentials:cached\",\n CredentialsExpired: \"credentials:expired\",\n CredentialsCreating: \"credentials:creating\",\n CredentialsCreated: \"credentials:created\",\n CredentialsRevoked: \"credentials:revoked\",\n CredentialsPersistFailed: \"credentials:persist_failed\",\n CredentialsAllowed: \"credentials:allowed\",\n CredentialsCorrupted: \"credentials:corrupted\",\n SessionExpired: \"session:expired\",\n // FHE operations\n EncryptStart: \"encrypt:start\",\n EncryptEnd: \"encrypt:end\",\n EncryptError: \"encrypt:error\",\n DecryptStart: \"decrypt:start\",\n DecryptEnd: \"decrypt:end\",\n DecryptError: \"decrypt:error\",\n // Write operations\n TransactionError: \"transaction:error\",\n ShieldSubmitted: \"shield:submitted\",\n TransferSubmitted: \"transfer:submitted\",\n TransferFromSubmitted: \"transferFrom:submitted\",\n ApproveSubmitted: \"approve:submitted\",\n ApproveUnderlyingSubmitted: \"approveUnderlying:submitted\",\n UnwrapSubmitted: \"unwrap:submitted\",\n FinalizeUnwrapSubmitted: \"finalizeUnwrap:submitted\",\n // Delegation operations\n DelegationSubmitted: \"delegation:submitted\",\n RevokeDelegationSubmitted: \"revokeDelegation:submitted\",\n // Unshield orchestration\n UnshieldPhase1Submitted: \"unshield:phase1_submitted\",\n UnshieldPhase2Started: \"unshield:phase2_started\",\n UnshieldPhase2Submitted: \"unshield:phase2_submitted\",\n} as const;\n\n/** Union of all SDK event type strings. */\nexport type ZamaSDKEventType = (typeof ZamaSDKEvents)[keyof typeof ZamaSDKEvents];\n\n// -- Base fields present on every event --\n\nexport interface BaseEvent {\n tokenAddress?: Address;\n timestamp: number;\n /** Shared identifier linking related events in multi-phase operations (e.g. unshield). */\n operationId?: string;\n}\n\n// -- Per-event typed payloads --\n\nexport interface CredentialsLoadingEvent extends BaseEvent {\n type: typeof ZamaSDKEvents.CredentialsLoading;\n /** Contract addresses being requested. */\n contractAddresses?: Address[];\n}\n\nexport interface CredentialsCachedEvent extends BaseEvent {\n type: typeof ZamaSDKEvents.CredentialsCached;\n /** Contract addresses covered by the cached credentials. */\n contractAddresses?: Address[];\n}\n\nexport interface CredentialsExpiredEvent extends BaseEvent {\n type: typeof ZamaSDKEvents.CredentialsExpired;\n /** Contract addresses that need re-authorization. */\n contractAddresses?: Address[];\n}\n\nexport interface CredentialsCreatingEvent extends BaseEvent {\n type: typeof ZamaSDKEvents.CredentialsCreating;\n /** Contract addresses being authorized. */\n contractAddresses?: Address[];\n}\n\nexport interface CredentialsCreatedEvent extends BaseEvent {\n type: typeof ZamaSDKEvents.CredentialsCreated;\n /** Contract addresses covered by the new credentials. */\n contractAddresses?: Address[];\n}\n\nexport interface CredentialsRevokedEvent extends BaseEvent {\n type: typeof ZamaSDKEvents.CredentialsRevoked;\n contractAddresses?: Address[];\n}\n\nexport interface CredentialsPersistFailedEvent extends BaseEvent {\n type: typeof ZamaSDKEvents.CredentialsPersistFailed;\n /** The error that caused the persist failure. */\n error: Error;\n}\n\nexport interface CredentialsAllowedEvent extends BaseEvent {\n type: typeof ZamaSDKEvents.CredentialsAllowed;\n /** Contract addresses covered by the authorized credentials. */\n contractAddresses?: Address[];\n}\n\nexport interface CredentialsCorruptedEvent extends BaseEvent {\n type: typeof ZamaSDKEvents.CredentialsCorrupted;\n /** The error that revealed storage corruption. */\n error: Error;\n}\n\nexport interface SessionExpiredEvent extends BaseEvent {\n type: typeof ZamaSDKEvents.SessionExpired;\n /** Why the session expired. Currently always `\"ttl\"`, extensible for future inactivity timeout. */\n reason: \"ttl\";\n}\n\nexport interface EncryptStartEvent extends BaseEvent {\n type: typeof ZamaSDKEvents.EncryptStart;\n}\n\nexport interface EncryptEndEvent extends BaseEvent {\n type: typeof ZamaSDKEvents.EncryptEnd;\n durationMs: number;\n}\n\nexport interface EncryptErrorEvent extends BaseEvent {\n type: typeof ZamaSDKEvents.EncryptError;\n /** The error that caused the encryption to fail. */\n error: Error;\n durationMs: number;\n}\n\nexport interface DecryptStartEvent extends BaseEvent {\n type: typeof ZamaSDKEvents.DecryptStart;\n /** Handles being decrypted — correlate with matching DecryptEnd/DecryptError. */\n handles: Handle[];\n}\n\nexport interface DecryptEndEvent extends BaseEvent {\n type: typeof ZamaSDKEvents.DecryptEnd;\n durationMs: number;\n /** Handles that were decrypted. */\n handles: Handle[];\n /** Decrypted values keyed by handle — use this to correlate events to specific handles. */\n result: Record<Handle, ClearValueType>;\n}\n\nexport interface DecryptErrorEvent extends BaseEvent {\n type: typeof ZamaSDKEvents.DecryptError;\n /** The error that caused the decryption to fail. */\n error: Error;\n durationMs: number;\n /** Handles that were being decrypted when the error occurred. */\n handles: Handle[];\n}\n\nexport interface TransactionErrorEvent extends BaseEvent {\n type: typeof ZamaSDKEvents.TransactionError;\n /** Which write operation failed. */\n operation: string;\n /** The error that caused the transaction to fail. */\n error: Error;\n}\n\nexport interface ShieldSubmittedEvent extends BaseEvent {\n type: typeof ZamaSDKEvents.ShieldSubmitted;\n txHash: Hex;\n}\n\nexport interface TransferSubmittedEvent extends BaseEvent {\n type: typeof ZamaSDKEvents.TransferSubmitted;\n txHash: Hex;\n}\n\nexport interface TransferFromSubmittedEvent extends BaseEvent {\n type: typeof ZamaSDKEvents.TransferFromSubmitted;\n txHash: Hex;\n}\n\nexport interface ApproveSubmittedEvent extends BaseEvent {\n type: typeof ZamaSDKEvents.ApproveSubmitted;\n txHash: Hex;\n}\n\nexport interface ApproveUnderlyingSubmittedEvent extends BaseEvent {\n type: typeof ZamaSDKEvents.ApproveUnderlyingSubmitted;\n txHash: Hex;\n}\n\nexport interface UnwrapSubmittedEvent extends BaseEvent {\n type: typeof ZamaSDKEvents.UnwrapSubmitted;\n txHash: Hex;\n}\n\nexport interface FinalizeUnwrapSubmittedEvent extends BaseEvent {\n type: typeof ZamaSDKEvents.FinalizeUnwrapSubmitted;\n txHash: Hex;\n}\n\nexport interface DelegationSubmittedEvent extends BaseEvent {\n type: typeof ZamaSDKEvents.DelegationSubmitted;\n txHash: Hex;\n}\n\nexport interface RevokeDelegationSubmittedEvent extends BaseEvent {\n type: typeof ZamaSDKEvents.RevokeDelegationSubmitted;\n txHash: Hex;\n}\n\nexport interface UnshieldPhase1SubmittedEvent extends BaseEvent {\n type: typeof ZamaSDKEvents.UnshieldPhase1Submitted;\n txHash: Hex;\n}\n\nexport interface UnshieldPhase2StartedEvent extends BaseEvent {\n type: typeof ZamaSDKEvents.UnshieldPhase2Started;\n}\n\nexport interface UnshieldPhase2SubmittedEvent extends BaseEvent {\n type: typeof ZamaSDKEvents.UnshieldPhase2Submitted;\n txHash: Hex;\n}\n\n/**\n * Discriminated union of all SDK events.\n *\n * Decrypt events carry handles and decrypted clear-text values so event\n * subscribers can correlate and bind them in UI layers. Events never carry\n * private keys, session signatures, or ZK proofs.\n */\nexport type ZamaSDKEvent =\n | CredentialsLoadingEvent\n | CredentialsCachedEvent\n | CredentialsExpiredEvent\n | CredentialsCreatingEvent\n | CredentialsCreatedEvent\n | CredentialsRevokedEvent\n | CredentialsPersistFailedEvent\n | CredentialsAllowedEvent\n | CredentialsCorruptedEvent\n | SessionExpiredEvent\n | EncryptStartEvent\n | EncryptEndEvent\n | EncryptErrorEvent\n | DecryptStartEvent\n | DecryptEndEvent\n | DecryptErrorEvent\n | TransactionErrorEvent\n | ShieldSubmittedEvent\n | TransferSubmittedEvent\n | TransferFromSubmittedEvent\n | ApproveSubmittedEvent\n | ApproveUnderlyingSubmittedEvent\n | UnwrapSubmittedEvent\n | FinalizeUnwrapSubmittedEvent\n | DelegationSubmittedEvent\n | RevokeDelegationSubmittedEvent\n | UnshieldPhase1SubmittedEvent\n | UnshieldPhase2StartedEvent\n | UnshieldPhase2SubmittedEvent;\n\nexport type ZamaSDKEventListener = (event: ZamaSDKEvent) => void;\n\n/** Distributive Omit that preserves the discriminated union. */\nexport type ZamaSDKEventInput = ZamaSDKEvent extends infer E\n ? E extends ZamaSDKEvent\n ? Omit<E, \"timestamp\" | \"tokenAddress\">\n : never\n : never;\n","/**\n * Execute an array of async thunks with bounded concurrency.\n * Defaults to `Infinity` (equivalent to `Promise.all`).\n */\nexport async function pLimit<T>(\n fns: (() => Promise<T>)[],\n maxConcurrency = Infinity,\n): Promise<T[]> {\n if (Number.isFinite(maxConcurrency) && maxConcurrency <= 0) {\n throw new Error(\"maxConcurrency must be a positive number\");\n }\n if (!Number.isFinite(maxConcurrency) || maxConcurrency >= fns.length) {\n return Promise.all(fns.map((f) => f()));\n }\n\n const results: T[] = Array.from({ length: fns.length });\n let index = 0;\n\n async function worker() {\n while (index < fns.length) {\n const i = index++;\n if (fns[i]) {\n results[i] = await fns[i]();\n }\n }\n }\n\n await Promise.all(Array.from({ length: maxConcurrency }, worker));\n return results;\n}\n","import { type Address, getAddress } from \"viem\";\nimport {\n allowanceContract,\n confidentialBalanceOfContract,\n decimalsContract,\n ERC7984_INTERFACE_ID,\n ERC7984_WRAPPER_INTERFACE_ID,\n getDelegationExpiryContract,\n MAX_UINT64,\n nameContract,\n supportsInterfaceContract,\n symbolContract,\n underlyingContract,\n} from \"../contracts\";\nimport {\n ConfigurationError,\n DecryptionFailedError,\n DelegationExpiredError,\n DelegationNotFoundError,\n isSessionError,\n wrapDecryptError,\n ZamaError,\n} from \"../errors\";\nimport { ZamaSDKEvents, type ZamaSDKEventInput } from \"../events/sdk-events\";\nimport { isZeroHandle, ZERO_HANDLE } from \"../utils/handles\";\nimport type { ClearValueType, Handle } from \"../relayer/relayer-sdk.types\";\nimport { toError } from \"../utils\";\nimport { assertBigint } from \"../utils/assertions\";\nimport { pLimit } from \"../utils/concurrency\";\nimport type { ZamaSDK } from \"../zama-sdk\";\n\n// Re-exported so consumers importing via `./token` keep a single canonical\n// reference. The constant itself lives in `utils/handles`.\nexport { ZERO_HANDLE, isZeroHandle };\n\n/** Options for {@link ReadonlyToken.batchDecryptBalancesAs}. */\nexport interface BatchDecryptAsOptions {\n /** The address of the account that delegated decryption rights. */\n delegatorAddress: Address;\n /** Pre-fetched encrypted handles. When omitted, handles are fetched from the chain. */\n handles?: Handle[];\n /** Balance owner address. Defaults to the delegator address. */\n owner?: Address;\n /** Maximum number of concurrent decrypt calls. Default: Infinity. */\n maxConcurrency?: number;\n /** Called when decryption fails for a single token. Return a fallback bigint. */\n onError?: (error: Error, address: Address) => bigint;\n}\n\n/** Result of {@link ReadonlyToken.batchBalancesOf}. */\nexport interface BatchBalancesResult {\n /** Successfully decrypted balances, keyed by token address. */\n results: Map<Address, bigint>;\n /** Per-token errors for tokens that failed to decrypt. */\n errors: Map<Address, ZamaError>;\n}\n\n/**\n * Read-only interface for a confidential token.\n * Supports balance queries, authorization, and ERC-165 checks.\n * Does not require a wrapper address.\n *\n * Decryption, credentials, caching, and event emission are handled by the\n * owning {@link ZamaSDK} — this class only exposes token-specific helpers\n * that delegate to {@link ZamaSDK.userDecrypt} and {@link ZamaSDK.allow}.\n */\nexport class ReadonlyToken {\n readonly sdk: ZamaSDK;\n readonly address: Address;\n\n constructor(sdk: ZamaSDK, address: Address) {\n this.sdk = sdk;\n this.address = getAddress(address);\n }\n\n /**\n * Decrypt and return the plaintext balance for the given owner.\n * Acquires FHE credentials via a wallet signature if none are cached.\n *\n * @param owner - Optional balance owner address. Defaults to the connected signer.\n * @returns The decrypted plaintext balance as a bigint.\n * @throws {@link DecryptionFailedError} if FHE decryption fails.\n *\n * @example\n * ```ts\n * const balance = await token.balanceOf();\n * // or for another address:\n * const balance = await token.balanceOf(\"0xOwner\");\n * ```\n */\n async balanceOf(owner?: Address): Promise<bigint> {\n const ownerAddress = owner ? getAddress(owner) : await this.sdk.signer.getAddress();\n const handle = await this.readConfidentialBalanceOf(ownerAddress);\n const result = await this.sdk.userDecrypt([{ handle, contractAddress: this.address }]);\n const value = result[handle];\n if (value === undefined) {\n throw new DecryptionFailedError(`Decryption returned no value for handle ${handle}`);\n }\n assertBigint(value, \"balanceOf: result[handle]\");\n return value;\n }\n\n /**\n * Return the raw encrypted balance handle without decrypting.\n *\n * @param owner - Optional balance owner address. Defaults to the connected signer.\n * @returns The encrypted balance handle as a hex string.\n *\n * @example\n * ```ts\n * const handle = await token.confidentialBalanceOf();\n * ```\n */\n async confidentialBalanceOf(owner?: Address): Promise<Handle> {\n const ownerAddress = owner ? getAddress(owner) : await this.sdk.signer.getAddress();\n return this.readConfidentialBalanceOf(ownerAddress);\n }\n\n /**\n * ERC-165 check for {@link ERC7984_INTERFACE_ID} support.\n *\n * @returns `true` if the contract implements the ERC-7984 confidential token interface.\n */\n async isConfidential(): Promise<boolean> {\n return this.sdk.signer.readContract(\n supportsInterfaceContract(this.address, ERC7984_INTERFACE_ID),\n );\n }\n\n /**\n * ERC-165 check for {@link ERC7984_WRAPPER_INTERFACE_ID} support.\n *\n * @returns `true` if the contract implements the ERC-7984 wrapper interface.\n */\n async isWrapper(): Promise<boolean> {\n return this.sdk.signer.readContract(\n supportsInterfaceContract(this.address, ERC7984_WRAPPER_INTERFACE_ID),\n );\n }\n\n /**\n * Decrypt confidential balances for multiple tokens in parallel, returning\n * successes and per-token errors separately. Pre-authorizes all token\n * addresses in a single wallet signature, then delegates each decrypt to\n * {@link ZamaSDK.userDecrypt}.\n *\n * Tokens that fail to decrypt land in `errors` rather than aborting the\n * whole batch — caller decides how to surface them.\n *\n * @param tokens - Array of {@link ReadonlyToken} instances bound to the same SDK.\n * @param owner - Optional balance owner address. Defaults to the connected signer.\n * @returns `{ results, errors }` partitioning the per-token outcomes.\n *\n * @example\n * ```ts\n * const { results, errors } = await ReadonlyToken.batchBalancesOf(tokens);\n * ```\n */\n static async batchBalancesOf(\n tokens: ReadonlyToken[],\n owner?: Address,\n ): Promise<BatchBalancesResult> {\n const results = new Map<Address, bigint>();\n const errors = new Map<Address, ZamaError>();\n if (tokens.length === 0) {\n return { results, errors };\n }\n\n const sdk = ReadonlyToken.assertSameSdk(tokens);\n // Pre-authorize the full token set in one wallet signature so subsequent\n // per-token userDecrypt calls reuse the cached credentials.\n await sdk.allow(tokens.map((t) => t.address));\n\n // Bound concurrency so a large token list can't overwhelm the relayer.\n // Default matches the inner userDecrypt limit.\n const outcomes = await pLimit(\n tokens.map((t) => async () => {\n try {\n return {\n status: \"fulfilled\" as const,\n value: await t.balanceOf(owner),\n };\n } catch (reason) {\n return { status: \"rejected\" as const, reason };\n }\n }),\n 5,\n );\n\n for (let i = 0; i < tokens.length; i++) {\n const tokenAddress = tokens[i]!.address;\n const outcome = outcomes[i]!;\n if (outcome.status === \"fulfilled\") {\n results.set(tokenAddress, outcome.value);\n } else {\n const reason = outcome.reason;\n // Session-level failures (user rejected signature, SDK misconfigured)\n // apply to every token — surface them instead of collecting per-token.\n if (isSessionError(reason)) {\n throw reason;\n }\n const error =\n reason instanceof ZamaError\n ? reason\n : new DecryptionFailedError(toError(reason).message, {\n cause: reason,\n });\n errors.set(tokenAddress, error);\n }\n }\n\n // Total failure: surface the first error so callers know nothing decrypted.\n if (errors.size === tokens.length) {\n const firstError = errors.values().next().value;\n throw firstError ?? new DecryptionFailedError(\"All token balance decryptions failed\");\n }\n\n return { results, errors };\n }\n\n /**\n * Batch decrypt confidential balances as a delegate across multiple tokens.\n * Mirrors {@link batchBalancesOf} but uses delegated credentials.\n *\n * **Error handling:** If a per-token decryption fails and no `onError` callback\n * is provided, errors are collected and thrown as an aggregated\n * `DecryptionFailedError`. When the relayer returns no value for a handle,\n * a `DecryptionFailedError` is thrown for that token (never silently returns `0n`).\n * Pass `onError: () => 0n` to opt into the silent zero behavior.\n *\n * @param tokens - Array of ReadonlyToken instances to decrypt balances for.\n * @param options - Delegated decryption configuration.\n * @returns A Map from token address to decrypted balance.\n * @throws {@link DelegationNotFoundError} if no active delegation exists from the delegator to the connected signer.\n * @throws {@link DelegationExpiredError} if the delegation has expired.\n * @throws {@link DecryptionFailedError} if any decryption fails and no `onError` callback is provided.\n * @throws {@link SigningRejectedError} if the user rejects the wallet signature prompt.\n *\n * @example\n * ```ts\n * const balances = await ReadonlyToken.batchDecryptBalancesAs(tokens, {\n * delegatorAddress: \"0xDelegator\",\n * onError: (err, addr) => { console.error(addr, err); return 0n; },\n * });\n * ```\n */\n static async batchDecryptBalancesAs(\n tokens: ReadonlyToken[],\n options: BatchDecryptAsOptions,\n ): Promise<Map<Address, bigint>> {\n if (tokens.length === 0) {\n return new Map();\n }\n\n const { delegatorAddress, handles, owner, onError, maxConcurrency } = options;\n const ownerAddress = owner ?? delegatorAddress;\n const firstToken = tokens[0]!;\n ReadonlyToken.assertSameSdk(tokens);\n\n const resolvedHandles =\n handles ?? (await Promise.all(tokens.map((t) => t.readConfidentialBalanceOf(ownerAddress))));\n\n if (tokens.length !== resolvedHandles.length) {\n throw new DecryptionFailedError(\n `tokens.length (${tokens.length}) must equal handles.length (${resolvedHandles.length})`,\n );\n }\n\n const results = new Map<Address, bigint>();\n\n // Parallel cache lookups — avoids sequential IDB round-trips.\n const uncached: { token: ReadonlyToken; handle: Handle }[] = [];\n const cachedValues = await Promise.all(\n tokens.map(async (token, i) => {\n const handle = resolvedHandles[i]!;\n if (isZeroHandle(handle)) {\n return 0n;\n }\n return firstToken.sdk.cache.get(ownerAddress, token.address, handle);\n }),\n );\n\n for (let i = 0; i < tokens.length; i++) {\n const token = tokens[i]!;\n const handle = resolvedHandles[i]!;\n const cached = cachedValues[i];\n\n if (cached !== null && cached !== undefined) {\n assertBigint(cached, \"batchDecryptBalancesAs: cached\");\n results.set(token.address, cached);\n continue;\n }\n\n uncached.push({ token, handle });\n }\n\n // All balances resolved from cache — no credentials needed.\n if (uncached.length === 0) {\n return results;\n }\n\n // Pre-flight delegation check runs after cache lookups — skips RPC overhead\n // when all balances are cached. Best-effort: checks the first token's\n // contract only (delegations are typically granted per-delegator, not per-token).\n await firstToken.#assertDelegationActive(delegatorAddress);\n\n const uncachedAddresses = uncached.map((entry) => entry.token.address);\n const creds = await firstToken.sdk.delegatedCredentials.allow(\n delegatorAddress,\n ...uncachedAddresses,\n );\n\n const errors: { address: Address; error: Error }[] = [];\n const decryptFns: (() => Promise<void>)[] = [];\n\n for (const { token, handle } of uncached) {\n decryptFns.push(() =>\n firstToken.sdk.relayer\n .delegatedUserDecrypt({\n handles: [handle],\n contractAddress: token.address,\n signedContractAddresses: creds.contractAddresses,\n privateKey: creds.privateKey,\n publicKey: creds.publicKey,\n signature: creds.signature,\n delegatorAddress: creds.delegatorAddress,\n delegateAddress: creds.delegateAddress,\n startTimestamp: creds.startTimestamp,\n durationDays: creds.durationDays,\n })\n .then(async (result) => {\n const value = result[handle];\n if (value === undefined) {\n throw new DecryptionFailedError(\n `Batch delegated decryption returned no value for handle ${handle} on token ${token.address}`,\n );\n }\n assertBigint(value, \"batchDecryptBalancesAs: result[handle]\");\n results.set(token.address, value);\n // Cache write is best-effort — log on failure so a broken cache\n // backend doesn't silently force re-decryption forever.\n firstToken.sdk.cache\n .set(ownerAddress, token.address, handle, value)\n .catch((cacheErr: unknown) => {\n // oxlint-disable-next-line no-console\n console.warn(\"[zama-sdk] Failed to cache decrypted value:\", cacheErr);\n });\n })\n .catch((error) => {\n // Session-level failures apply to every token — re-throw so the\n // whole batch aborts with the original typed error.\n if (isSessionError(error)) {\n throw error;\n }\n const err = toError(error);\n if (onError) {\n try {\n results.set(token.address, onError(err, token.address));\n } catch (callbackError) {\n errors.push({\n address: token.address,\n error: toError(callbackError),\n });\n }\n } else {\n errors.push({ address: token.address, error: err });\n }\n }),\n );\n }\n\n await pLimit(decryptFns, maxConcurrency);\n\n if (errors.length > 0) {\n const message = errors.map((e) => `${e.address}: ${e.error.message}`).join(\"; \");\n // Preserve the first original error as `cause` so callers can still\n // `instanceof`-check the underlying failure type.\n throw new DecryptionFailedError(\n `Batch delegated decryption failed for ${errors.length} token(s): ${message}`,\n { cause: errors[0]!.error },\n );\n }\n\n return results;\n }\n\n /**\n * Read the underlying ERC-20 address from this token's wrapper contract.\n *\n * @returns The underlying ERC-20 token address.\n */\n async underlyingToken(): Promise<Address> {\n return this.sdk.signer.readContract(underlyingContract(this.address));\n }\n\n /**\n * Read the ERC-20 allowance of the underlying token for a given wrapper.\n *\n * @param wrapper - The wrapper contract address to check allowance for.\n * @param owner - Optional owner address. Defaults to the connected signer.\n * @returns The current allowance as a bigint.\n */\n async allowance(wrapper: Address, owner?: Address): Promise<bigint> {\n const normalizedWrapper = getAddress(wrapper);\n const underlying = await this.sdk.signer.readContract(underlyingContract(normalizedWrapper));\n const userAddress = owner ? getAddress(owner) : await this.sdk.signer.getAddress();\n return this.sdk.signer.readContract(\n allowanceContract(underlying, userAddress, normalizedWrapper),\n );\n }\n\n /**\n * Read the token name from the contract.\n *\n * @returns The token name string.\n */\n async name(): Promise<string> {\n return this.sdk.signer.readContract(nameContract(this.address));\n }\n\n /**\n * Read the token symbol from the contract.\n *\n * @returns The token symbol string.\n */\n async symbol(): Promise<string> {\n return this.sdk.signer.readContract(symbolContract(this.address));\n }\n\n /**\n * Read the token decimals from the contract.\n *\n * @returns The number of decimals.\n */\n async decimals(): Promise<number> {\n return this.sdk.signer.readContract(decimalsContract(this.address));\n }\n\n /**\n * Ensure FHE decrypt credentials exist for this token.\n * Generates a keypair and requests an EIP-712 signature if needed.\n * Call this before any decrypt operation to avoid mid-flow wallet prompts.\n *\n * @returns Resolves when credentials are cached.\n *\n * @example\n * ```ts\n * await token.allow();\n * // Credentials are now cached — subsequent decrypts won't prompt\n * const balance = await token.balanceOf();\n * ```\n */\n async allow(): Promise<void> {\n await this.sdk.allow([this.address]);\n }\n\n /**\n * Whether a session signature is currently cached for the connected wallet.\n * Use this to check if decrypt operations can proceed without a wallet prompt.\n */\n async isAllowed(): Promise<boolean> {\n return this.sdk.credentials.isAllowed([this.address]);\n }\n\n /**\n * Revoke cached session signatures for the given contract addresses, forcing\n * a fresh wallet signature on the next decrypt operation for those contracts.\n * Stored credentials remain intact; only the in-memory session signature is\n * cleared.\n *\n * @param contractAddresses - Contract addresses to revoke credentials for.\n */\n async revoke(...contractAddresses: Address[]): Promise<void> {\n await this.sdk.credentials.revoke(...contractAddresses);\n }\n\n /**\n * Ensure FHE decrypt credentials exist for all given tokens in a single\n * wallet signature. Call this early (e.g. after loading the token list) so\n * that subsequent individual decrypt operations reuse cached credentials.\n *\n * @param tokens - Array of ReadonlyToken instances to allow.\n * @returns Resolves when all credentials are cached.\n *\n * @example\n * ```ts\n * const tokens = addresses.map(a => sdk.createReadonlyToken(a));\n * await ReadonlyToken.allow(...tokens);\n * // All tokens now share the same credentials\n * ```\n */\n static async allow(...tokens: ReadonlyToken[]): Promise<void> {\n if (tokens.length === 0) {\n return;\n }\n const sdk = ReadonlyToken.assertSameSdk(tokens);\n await sdk.allow(tokens.map((t) => t.address));\n }\n\n protected async getAclAddress(): Promise<Address> {\n return this.sdk.relayer.getAclAddress();\n }\n\n /**\n * Check whether a delegation is active for this token's contract address.\n *\n * @param delegatorAddress - The address that granted the delegation.\n * @param delegateAddress - The address that received delegation rights.\n * @returns `true` if the delegation exists and has not expired.\n */\n async isDelegated(params: {\n delegatorAddress: Address;\n delegateAddress: Address;\n }): Promise<boolean> {\n const expiry = await this.getDelegationExpiry(params);\n if (expiry === 0n) {\n return false;\n }\n // Permanent delegation (uint64 max) — skip the RPC round-trip for block timestamp.\n if (expiry === MAX_UINT64) {\n return true;\n }\n const now = await this.sdk.signer.getBlockTimestamp();\n return expiry > now;\n }\n\n /**\n * Get the expiration timestamp of a delegation for this token.\n *\n * @param delegatorAddress - The address that granted the delegation.\n * @param delegateAddress - The address that received delegation rights.\n * @returns Unix timestamp as bigint. `0n` = no delegation. `2^64 - 1` = permanent.\n */\n async getDelegationExpiry({\n delegatorAddress,\n delegateAddress,\n }: {\n delegatorAddress: Address;\n delegateAddress: Address;\n }): Promise<bigint> {\n const acl = await this.getAclAddress();\n return this.sdk.signer.readContract(\n getDelegationExpiryContract(\n acl,\n getAddress(delegatorAddress),\n getAddress(delegateAddress),\n this.address,\n ),\n );\n }\n\n /**\n * Throws if there is no active delegation from `delegatorAddress` to the\n * connected signer for this token contract.\n */\n async #assertDelegationActive(delegatorAddress: Address): Promise<void> {\n const delegateAddress = await this.sdk.signer.getAddress();\n const expiry = await this.getDelegationExpiry({\n delegatorAddress,\n delegateAddress,\n });\n if (expiry === 0n) {\n throw new DelegationNotFoundError(\n `No active delegation from ${delegatorAddress} to ${delegateAddress} for ${this.address}`,\n );\n }\n if (expiry !== MAX_UINT64) {\n const now = await this.sdk.signer.getBlockTimestamp();\n if (expiry <= now) {\n throw new DelegationExpiredError(\n `Delegation from ${delegatorAddress} to ${delegateAddress} for ${this.address} has expired`,\n );\n }\n }\n }\n\n protected async readConfidentialBalanceOf(owner: Address): Promise<Handle> {\n return await this.sdk.signer.readContract(confidentialBalanceOfContract(this.address, owner));\n }\n /**\n * Decrypt the balance of a delegator using delegated decryption credentials.\n * The connected signer acts as the delegate who has been granted permission\n * by the delegator to decrypt their balance.\n *\n * Decrypted values are cached in storage keyed by `(token, owner, handle)`.\n * Cache write failures are silently ignored — they do not affect the returned value.\n *\n * @param delegatorAddress - The address of the account that delegated decryption rights.\n * @param owner - Optional balance owner address. Defaults to the delegator address.\n * @returns The decrypted plaintext balance as a bigint.\n * @throws {@link DelegationNotFoundError} if no active delegation exists from the delegator to the connected signer.\n * @throws {@link DelegationExpiredError} if the delegation has expired.\n * @throws {@link DecryptionFailedError} if delegated decryption fails or the relayer returns no value.\n *\n * @example\n * ```ts\n * const balance = await token.decryptBalanceAs({\n * delegatorAddress: \"0xDelegator\",\n * });\n * ```\n */\n async decryptBalanceAs({\n delegatorAddress,\n owner,\n }: {\n delegatorAddress: Address;\n owner?: Address;\n }): Promise<bigint> {\n const normalizedDelegator = getAddress(delegatorAddress);\n const normalizedOwner = owner ? getAddress(owner) : normalizedDelegator;\n\n const handle = await this.readConfidentialBalanceOf(normalizedOwner);\n if (isZeroHandle(handle)) {\n return 0n;\n }\n\n const cached = await this.sdk.cache.get(normalizedOwner, this.address, handle);\n if (cached !== null) {\n assertBigint(cached, \"decryptBalanceAs: cached\");\n return cached;\n }\n\n // Pre-flight delegation check — avoids wasting a wallet signature on an\n // expired or non-existent delegation.\n await this.#assertDelegationActive(normalizedDelegator);\n\n const t0 = Date.now();\n try {\n this.emit({ type: ZamaSDKEvents.DecryptStart, handles: [handle] });\n\n const creds = await this.sdk.delegatedCredentials.allow(normalizedDelegator, this.address);\n\n const result = await this.sdk.relayer.delegatedUserDecrypt({\n handles: [handle],\n contractAddress: this.address,\n signedContractAddresses: creds.contractAddresses,\n privateKey: creds.privateKey,\n publicKey: creds.publicKey,\n signature: creds.signature,\n delegatorAddress: creds.delegatorAddress,\n delegateAddress: creds.delegateAddress,\n startTimestamp: creds.startTimestamp,\n durationDays: creds.durationDays,\n });\n\n // Validate the relayer response before emitting DecryptEnd so subscribers\n // never see a contradictory `Start → End → Error` sequence.\n const value = result[handle];\n if (value === undefined) {\n throw new DecryptionFailedError(\n `Delegated decryption returned no value for handle ${handle}`,\n );\n }\n assertBigint(value, \"decryptBalanceAs: result[handle]\");\n\n this.emit({\n type: ZamaSDKEvents.DecryptEnd,\n durationMs: Date.now() - t0,\n handles: [handle],\n result,\n });\n\n await this.sdk.cache.set(normalizedOwner, this.address, handle, value);\n return value;\n } catch (error) {\n this.emit({\n type: ZamaSDKEvents.DecryptError,\n error: toError(error),\n durationMs: Date.now() - t0,\n handles: [handle],\n });\n throw wrapDecryptError(error, \"Failed to decrypt delegated balance\", true);\n }\n }\n\n /**\n * Emit a decrypt-related event scoped to this token. Events are routed\n * through the owning {@link ZamaSDK} so subscribers see a unified stream.\n */\n protected emit(input: ZamaSDKEventInput): void {\n this.sdk.emitEvent(input, this.address);\n }\n\n /** Verify all tokens share the same SDK instance and return it. */\n private static assertSameSdk(tokens: ReadonlyToken[]): ZamaSDK {\n const sdk = tokens[0]!.sdk;\n for (let i = 1; i < tokens.length; i++) {\n if (tokens[i]!.sdk !== sdk) {\n throw new ConfigurationError(\n \"All tokens in a batch operation must share the same ZamaSDK instance\",\n );\n }\n }\n return sdk;\n }\n}\n\n/**\n * Re-exported alias used by tests and helpers for arbitrary-handle decryption.\n * Use {@link ZamaSDK.userDecrypt} directly in application code.\n *\n * @internal\n */\nexport type DecryptedHandlesMap = Map<Handle, ClearValueType>;\n","/**\n * Framework-agnostic event decoders for confidential token contracts.\n * Works with raw log data from any provider.\n */\n\nimport type { Handle } from \"../relayer/relayer-sdk.types\";\nimport { getAddress, type Address, type Hex } from \"viem\";\nimport { prefixHex } from \"../utils\";\nimport type { RawLog } from \"../types/transaction\";\nexport type { RawLog } from \"../types/transaction\";\n\n// ---------------------------------------------------------------------------\n// Event topic0 constants (keccak256 of canonical signature)\n// ---------------------------------------------------------------------------\n\n/**\n * Event topic0 constants (keccak256 of the canonical Solidity signature).\n * Pass to `getLogs({ topics: [Object.values(Topics)] })` to fetch all events.\n */\nexport const Topics = {\n /** `ConfidentialTransfer(address indexed from, address indexed to, bytes32 indexed amount)` */\n ConfidentialTransfer: \"0x67500e8d0ed826d2194f514dd0d8124f35648ab6e3fb5e6ed867134cffe661e9\",\n /** `Wrapped(address indexed to, uint256 amountIn)` */\n Wrapped: \"0x4700c1726b4198077cd40320a32c45265a1910521eb0ef713dd1d8412413d7fc\",\n /** `UnwrapRequested(address indexed receiver, bytes32 amount)` */\n UnwrapRequested: \"0x77d02d353c5629272875d11f1b34ec4c65d7430b075575b78cd2502034c469ee\",\n /** `UnwrapFinalized(address indexed receiver, bytes32 encryptedAmount, uint64 cleartextAmount)` */\n UnwrappedFinalized: \"0x2d4edf3c2943002120f53dab3f8940043f34799f4a92ab90f2f81f7dd004a49e\",\n /** `UnwrappedStarted(bool returnVal, uint256 indexed requestId, ...)` */\n UnwrappedStarted: \"0x3838891d4843c6d7f9f494570b6fd8843f4e3c3ddb817c1411760bd31b819806\",\n} as const;\n\n// ---------------------------------------------------------------------------\n// Typed event interfaces\n// ---------------------------------------------------------------------------\n\n/** Decoded `ConfidentialTransfer` event — an encrypted token transfer. */\nexport interface ConfidentialTransferEvent {\n readonly eventName: \"ConfidentialTransfer\";\n /** Sender address. */\n readonly from: Address;\n /** Receiver address. */\n readonly to: Address;\n /** FHE ciphertext handle for the transferred amount. */\n readonly encryptedAmountHandle: Handle;\n}\n\n/** Decoded `Wrapped` event — an ERC-20 shield (wrap) operation. */\nexport interface WrappedEvent {\n readonly eventName: \"Wrapped\";\n /** Receiver of the minted confidential tokens. */\n readonly to: Address;\n /** Underlying ERC-20 tokens deposited. */\n readonly amountIn: bigint;\n}\n\n/** Decoded `UnwrapRequested` event — an unshield request submitted. */\nexport interface UnwrapRequestedEvent {\n readonly eventName: \"UnwrapRequested\";\n /** Address that will receive the unwrapped ERC-20 tokens. */\n readonly receiver: Address;\n /** FHE ciphertext handle for the requested unshield amount. */\n readonly encryptedAmount: Handle;\n}\n\n/** Decoded `UnwrapFinalized` event — an unshield completed on-chain. */\nexport interface UnwrappedFinalizedEvent {\n readonly eventName: \"UnwrappedFinalized\";\n /** Address receiving the unwrapped ERC-20 tokens. */\n readonly receiver: Address;\n /** FHE ciphertext handle of the burnt confidential balance. */\n readonly encryptedAmount: Handle;\n /** Cleartext amount of underlying ERC-20 tokens returned. */\n readonly cleartextAmount: bigint;\n}\n\n/** Decoded `UnwrappedStarted` event — the relayer began processing an unshield. */\nexport interface UnwrappedStartedEvent {\n readonly eventName: \"UnwrappedStarted\";\n /** Whether the unwrap start succeeded. */\n readonly returnVal: boolean;\n /** On-chain request ID. */\n readonly requestId: bigint;\n /** On-chain transaction ID. */\n readonly txId: bigint;\n /** Receiver address. */\n readonly to: Address;\n /** Refund address (if applicable). */\n readonly refund: Address;\n /** FHE handle of the requested amount. */\n readonly requestedAmount: Handle;\n /** FHE handle of the burn amount. */\n readonly burnAmount: Handle;\n}\n\n/** Union of all decoded confidential token event types. */\nexport type OnChainEvent =\n | ConfidentialTransferEvent\n | WrappedEvent\n | UnwrapRequestedEvent\n | UnwrappedFinalizedEvent\n | UnwrappedStartedEvent;\n\n// ---------------------------------------------------------------------------\n// ABI decoding helpers (no external deps)\n// ---------------------------------------------------------------------------\n\nfunction topicToAddress(topic: Hex): Address {\n return getAddress(prefixHex(topic.slice(-40)));\n}\n\nfunction topicToBigInt(topic: Hex): bigint {\n return BigInt(topic);\n}\n\nfunction topicToBytes32(topic: Hex): Handle {\n // EVM topics are already 32-byte 0x-prefixed hex — cast directly\n return topic as Handle;\n}\n\nfunction wordAt(data: Hex, index: number): string {\n // data starts with \"0x\", each word is 64 hex chars (32 bytes)\n const start = 2 + index * 64;\n const word = data.slice(start, start + 64);\n return word.length === 64 ? word : word.padEnd(64, \"0\");\n}\n\nfunction wordToAddress(data: Hex, index: number): Address {\n return getAddress(prefixHex(wordAt(data, index).slice(-40)));\n}\n\nfunction wordToBigInt(data: Hex, index: number): bigint {\n return BigInt(\"0x\" + wordAt(data, index));\n}\n\nfunction wordToBool(data: Hex, index: number): boolean {\n return BigInt(\"0x\" + wordAt(data, index)) !== 0n;\n}\n\nfunction wordToBytes32(data: Hex, index: number): Handle {\n // wordAt returns exactly 64 hex chars — prefix and cast directly\n return prefixHex(wordAt(data, index)) as Handle;\n}\n\n// ---------------------------------------------------------------------------\n// Individual decoders\n// ---------------------------------------------------------------------------\n\n/**\n * ConfidentialTransfer(address indexed from, address indexed to, bytes32 indexed amount)\n * All 3 params indexed → topics[1..3], no data.\n */\nexport function decodeConfidentialTransfer(log: RawLog): ConfidentialTransferEvent | null {\n if (log.topics[0] !== Topics.ConfidentialTransfer) {\n return null;\n }\n if (log.topics.length < 4) {\n return null;\n }\n\n return {\n eventName: \"ConfidentialTransfer\",\n from: topicToAddress(log.topics[1]!),\n to: topicToAddress(log.topics[2]!),\n encryptedAmountHandle: topicToBytes32(log.topics[3]!),\n };\n}\n\n/**\n * Wrapped(address indexed to, uint256 amountIn)\n * Indexed: to (topics[1])\n * Data: amountIn (uint256)\n */\nexport function decodeWrapped(log: RawLog): WrappedEvent | null {\n if (log.topics[0] !== Topics.Wrapped) {\n return null;\n }\n if (log.topics.length < 2) {\n return null;\n }\n\n return {\n eventName: \"Wrapped\",\n to: topicToAddress(log.topics[1]!),\n amountIn: wordToBigInt(log.data, 0),\n };\n}\n\n/**\n * UnwrapRequested(address indexed receiver, bytes32 amount)\n * Indexed: receiver (topics[1])\n * Data: amount (bytes32)\n */\nexport function decodeUnwrapRequested(log: RawLog): UnwrapRequestedEvent | null {\n if (log.topics[0] !== Topics.UnwrapRequested) {\n return null;\n }\n if (log.topics.length < 2) {\n return null;\n }\n\n return {\n eventName: \"UnwrapRequested\",\n receiver: topicToAddress(log.topics[1]!),\n encryptedAmount: wordToBytes32(log.data, 0),\n };\n}\n\n/**\n * UnwrapFinalized(address indexed receiver, bytes32 encryptedAmount, uint64 cleartextAmount)\n * Indexed: receiver (topics[1])\n * Data: encryptedAmount (bytes32 FHE handle, word 0), cleartextAmount (uint64, word 1)\n */\nexport function decodeUnwrappedFinalized(log: RawLog): UnwrappedFinalizedEvent | null {\n if (log.topics[0] !== Topics.UnwrappedFinalized) {\n return null;\n }\n if (log.topics.length < 2) {\n return null;\n }\n\n return {\n eventName: \"UnwrappedFinalized\",\n receiver: topicToAddress(log.topics[1]!),\n encryptedAmount: wordToBytes32(log.data, 0),\n cleartextAmount: wordToBigInt(log.data, 1),\n };\n}\n\n/**\n * UnwrappedStarted(bool returnVal, uint256 indexed requestId, uint256 indexed txId, address indexed to,\n * address refund, bytes32 requestedAmount, bytes32 burnAmount)\n * Indexed: requestId (topics[1]), txId (topics[2]), to (topics[3])\n * Data: returnVal, refund, requestedAmount, burnAmount\n */\nexport function decodeUnwrappedStarted(log: RawLog): UnwrappedStartedEvent | null {\n if (log.topics[0] !== Topics.UnwrappedStarted) {\n return null;\n }\n if (log.topics.length < 4) {\n return null;\n }\n\n return {\n eventName: \"UnwrappedStarted\",\n requestId: topicToBigInt(log.topics[1]!),\n txId: topicToBigInt(log.topics[2]!),\n to: topicToAddress(log.topics[3]!),\n returnVal: wordToBool(log.data, 0),\n refund: wordToAddress(log.data, 1),\n requestedAmount: wordToBytes32(log.data, 2),\n burnAmount: wordToBytes32(log.data, 3),\n };\n}\n\n// ---------------------------------------------------------------------------\n// Convenience helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Try all decoders on a single log and return the first match, or `null`.\n *\n * @example\n * ```ts\n * const event = decodeOnChainEvent(log);\n * if (event?.eventName === \"ConfidentialTransfer\") {\n * console.log(event.from, event.to);\n * }\n * ```\n */\nexport function decodeOnChainEvent(log: RawLog): OnChainEvent | null {\n return (\n decodeConfidentialTransfer(log) ??\n decodeWrapped(log) ??\n decodeUnwrapRequested(log) ??\n decodeUnwrappedFinalized(log) ??\n decodeUnwrappedStarted(log)\n );\n}\n\n/**\n * Batch-decode an array of logs, skipping unrecognized entries.\n *\n * @example\n * ```ts\n * const events = decodeOnChainEvents(receipt.logs);\n * ```\n */\nexport function decodeOnChainEvents(logs: readonly RawLog[]): OnChainEvent[] {\n const events: OnChainEvent[] = [];\n for (const log of logs) {\n const event = decodeOnChainEvent(log);\n if (event) {\n events.push(event);\n }\n }\n return events;\n}\n\n/**\n * Find the first {@link UnwrapRequestedEvent} in a logs array.\n *\n * @example\n * ```ts\n * const event = findUnwrapRequested(receipt.logs);\n * if (event) console.log(event.receiver, event.encryptedAmount);\n * ```\n */\nexport function findUnwrapRequested(logs: readonly RawLog[]): UnwrapRequestedEvent | null {\n for (const log of logs) {\n const event = decodeUnwrapRequested(log);\n if (event) {\n return event;\n }\n }\n return null;\n}\n\n/**\n * Find the first {@link WrappedEvent} in a logs array.\n *\n * @example\n * ```ts\n * const event = findWrapped(receipt.logs);\n * if (event) console.log(event.to, event.amountIn);\n * ```\n */\nexport function findWrapped(logs: readonly RawLog[]): WrappedEvent | null {\n for (const log of logs) {\n const event = decodeWrapped(log);\n if (event) {\n return event;\n }\n }\n return null;\n}\n\n/**\n * All 5 confidential token event topic0 hashes.\n * Pass to `getLogs({ topics: [TOKEN_TOPICS] })` to fetch\n * all confidential token events in a single RPC call.\n */\nexport const TOKEN_TOPICS = [\n Topics.ConfidentialTransfer,\n Topics.Wrapped,\n Topics.UnwrapRequested,\n Topics.UnwrappedFinalized,\n Topics.UnwrappedStarted,\n] as const;\n\n// ---------------------------------------------------------------------------\n// ACL delegation event topic0 constants\n// ---------------------------------------------------------------------------\n\n/**\n * ACL delegation event topic0 constants (keccak256 of the canonical Solidity signature).\n * These are ACL events, NOT token events — they are emitted by the ACL contract.\n */\nexport const AclTopics = {\n /** `DelegatedForUserDecryption(address indexed delegator, address indexed delegate, address contractAddress, uint64 delegationCounter, uint64 oldExpirationDate, uint64 newExpirationDate)` */\n DelegatedForUserDecryption: \"0x527b025d7ff06689c1ab9d32dfd7881c964cce72ce8ac5b2fe1d3be8cfda5bfc\",\n /** `RevokedDelegationForUserDecryption(address indexed delegator, address indexed delegate, address contractAddress, uint64 delegationCounter, uint64 oldExpirationDate)` */\n RevokedDelegationForUserDecryption:\n \"0x7aca80b6b7928b9038f186e3d9922a0fc5d52c398fbf144725c142c52a5277e4\",\n} as const;\n\n// ---------------------------------------------------------------------------\n// ACL delegation event interfaces\n// ---------------------------------------------------------------------------\n\n/** Decoded `DelegatedForUserDecryption` event — a delegation was created or renewed. */\nexport interface DelegatedForUserDecryptionEvent {\n readonly eventName: \"DelegatedForUserDecryption\";\n /** Address of the delegator (the account granting access). */\n readonly delegator: Address;\n /** Address of the delegate (the account receiving access). */\n readonly delegate: Address;\n /** Contract address the delegation applies to. */\n readonly contractAddress: Address;\n /** Monotonic delegation counter. */\n readonly delegationCounter: bigint;\n /** Previous expiration timestamp (0 if first delegation). */\n readonly oldExpirationDate: bigint;\n /** New expiration timestamp. */\n readonly newExpirationDate: bigint;\n}\n\n/** Decoded `RevokedDelegationForUserDecryption` event — a delegation was revoked. */\nexport interface RevokedDelegationForUserDecryptionEvent {\n readonly eventName: \"RevokedDelegationForUserDecryption\";\n /** Address of the delegator. */\n readonly delegator: Address;\n /** Address of the delegate. */\n readonly delegate: Address;\n /** Contract address the revocation applies to. */\n readonly contractAddress: Address;\n /** Monotonic delegation counter. */\n readonly delegationCounter: bigint;\n /** Expiration date that was active before revocation. */\n readonly oldExpirationDate: bigint;\n}\n\n/** Union of all decoded ACL delegation event types. */\nexport type AclEvent = DelegatedForUserDecryptionEvent | RevokedDelegationForUserDecryptionEvent;\n\n// ---------------------------------------------------------------------------\n// ACL delegation event decoders\n// ---------------------------------------------------------------------------\n\n/**\n * DelegatedForUserDecryption(address indexed delegator, address indexed delegate,\n * address contractAddress, uint64 delegationCounter, uint64 oldExpirationDate, uint64 newExpirationDate)\n * Indexed: delegator (topics[1]), delegate (topics[2])\n * Data: contractAddress, delegationCounter, oldExpirationDate, newExpirationDate\n */\nexport function decodeDelegatedForUserDecryption(\n log: RawLog,\n): DelegatedForUserDecryptionEvent | null {\n if (log.topics[0] !== AclTopics.DelegatedForUserDecryption) {\n return null;\n }\n if (log.topics.length < 3) {\n return null;\n }\n\n return {\n eventName: \"DelegatedForUserDecryption\",\n delegator: topicToAddress(log.topics[1]!),\n delegate: topicToAddress(log.topics[2]!),\n contractAddress: wordToAddress(log.data, 0),\n delegationCounter: wordToBigInt(log.data, 1),\n oldExpirationDate: wordToBigInt(log.data, 2),\n newExpirationDate: wordToBigInt(log.data, 3),\n };\n}\n\n/**\n * RevokedDelegationForUserDecryption(address indexed delegator, address indexed delegate,\n * address contractAddress, uint64 delegationCounter, uint64 oldExpirationDate)\n * Indexed: delegator (topics[1]), delegate (topics[2])\n * Data: contractAddress, delegationCounter, oldExpirationDate\n */\nexport function decodeRevokedDelegationForUserDecryption(\n log: RawLog,\n): RevokedDelegationForUserDecryptionEvent | null {\n if (log.topics[0] !== AclTopics.RevokedDelegationForUserDecryption) {\n return null;\n }\n if (log.topics.length < 3) {\n return null;\n }\n\n return {\n eventName: \"RevokedDelegationForUserDecryption\",\n delegator: topicToAddress(log.topics[1]!),\n delegate: topicToAddress(log.topics[2]!),\n contractAddress: wordToAddress(log.data, 0),\n delegationCounter: wordToBigInt(log.data, 1),\n oldExpirationDate: wordToBigInt(log.data, 2),\n };\n}\n\n/**\n * Try all ACL delegation decoders on a single log and return the first match, or `null`.\n */\nexport function decodeAclEvent(log: RawLog): AclEvent | null {\n return decodeDelegatedForUserDecryption(log) ?? decodeRevokedDelegationForUserDecryption(log);\n}\n\n/**\n * Batch-decode an array of logs for ACL delegation events, skipping unrecognized entries.\n */\nexport function decodeAclEvents(logs: readonly RawLog[]): AclEvent[] {\n const events: AclEvent[] = [];\n for (const log of logs) {\n const event = decodeAclEvent(log);\n if (event) {\n events.push(event);\n }\n }\n return events;\n}\n\n/**\n * Find the first {@link DelegatedForUserDecryptionEvent} in a logs array.\n */\nexport function findDelegatedForUserDecryption(\n logs: readonly RawLog[],\n): DelegatedForUserDecryptionEvent | null {\n for (const log of logs) {\n const event = decodeDelegatedForUserDecryption(log);\n if (event) {\n return event;\n }\n }\n return null;\n}\n\n/**\n * Find the first {@link RevokedDelegationForUserDecryptionEvent} in a logs array.\n */\nexport function findRevokedDelegationForUserDecryption(\n logs: readonly RawLog[],\n): RevokedDelegationForUserDecryptionEvent | null {\n for (const log of logs) {\n const event = decodeRevokedDelegationForUserDecryption(log);\n if (event) {\n return event;\n }\n }\n return null;\n}\n\n/**\n * Both ACL delegation event topic0 hashes.\n * Pass to `getLogs({ topics: [ACL_TOPICS] })` to fetch\n * all delegation events in a single RPC call.\n */\nexport const ACL_TOPICS = [\n AclTopics.DelegatedForUserDecryption,\n AclTopics.RevokedDelegationForUserDecryption,\n] as const;\n","/**\n * Higher-level activity feed helpers for confidential token events.\n * Normalizes all 5 event types into a single renderable \"activity item\",\n * classifies direction (incoming/outgoing/self) relative to the user,\n * and supports batch-decryption of encrypted transfer amounts.\n *\n * Pure functions, no framework dependency — works with any provider.\n */\n\nimport {\n decodeOnChainEvent,\n type RawLog,\n type OnChainEvent,\n type ConfidentialTransferEvent,\n type WrappedEvent,\n type UnwrapRequestedEvent,\n type UnwrappedFinalizedEvent,\n type UnwrappedStartedEvent,\n} from \"./events/onchain-events\";\nimport type { Address, Hex } from \"viem\";\nimport type { ClearValueType, Handle } from \"./relayer/relayer-sdk.types\";\nimport { isZeroHandle } from \"./utils/handles\";\nimport { assertBigint } from \"./utils/assertions\";\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/** Direction of an activity item relative to the connected wallet. */\nexport type ActivityDirection = \"incoming\" | \"outgoing\" | \"self\";\n\n/** Classified type of a token activity event. */\nexport type ActivityType =\n | \"transfer\"\n | \"shield\"\n | \"unshield_requested\"\n | \"unshield_started\"\n | \"unshield_finalized\";\n\n/** Amount attached to an activity item — either cleartext or encrypted (with optional decrypted value). */\nexport type ActivityAmount =\n | { readonly type: \"clear\"; readonly value: bigint }\n | {\n readonly type: \"encrypted\";\n readonly handle: Handle;\n /** Populated after batch decryption via {@link applyDecryptedValues}. */\n readonly decryptedValue?: bigint;\n };\n\n/** On-chain metadata attached to each activity item. */\nexport interface ActivityLogMetadata {\n /** Transaction hash containing this event. */\n readonly transactionHash?: Hex;\n /** Block number where this event was emitted. */\n readonly blockNumber?: bigint | number;\n /** Log index within the transaction. */\n readonly logIndex?: number;\n}\n\n/**\n * A single renderable activity feed entry.\n * Produced by {@link parseActivityFeed} from raw event logs.\n */\nexport interface ActivityItem {\n /** Classified event type. */\n readonly type: ActivityType;\n /** Direction relative to the connected wallet. */\n readonly direction: ActivityDirection;\n /** Transfer amount (clear or encrypted). */\n readonly amount: ActivityAmount;\n /** Sender address (if applicable). */\n readonly from?: Address;\n /** Receiver address (if applicable). */\n readonly to?: Address;\n /** Whether the on-chain operation succeeded (for unshield_started events). */\n readonly success?: boolean;\n /** On-chain metadata (tx hash, block number, log index). */\n readonly metadata: ActivityLogMetadata;\n /** The original decoded event. */\n readonly rawEvent: OnChainEvent;\n}\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\nfunction addressesEqual(a: Address, b: Address): boolean {\n return a.toLowerCase() === b.toLowerCase();\n}\n\nfunction classifyDirection(\n userAddress: Address,\n from: Address | undefined,\n to: Address | undefined,\n): ActivityDirection {\n const isFrom = from !== undefined && addressesEqual(userAddress, from);\n const isTo = to !== undefined && addressesEqual(userAddress, to);\n\n if (isFrom && isTo) {\n return \"self\";\n }\n if (isFrom) {\n return \"outgoing\";\n }\n return \"incoming\";\n}\n\nfunction eventToActivityItem(\n event: OnChainEvent,\n userAddress: Address,\n metadata: ActivityLogMetadata,\n): ActivityItem {\n switch (event.eventName) {\n case \"ConfidentialTransfer\":\n return buildTransfer(event, userAddress, metadata);\n case \"Wrapped\":\n return buildShield(event, userAddress, metadata);\n case \"UnwrapRequested\":\n return buildUnshieldRequested(event, userAddress, metadata);\n case \"UnwrappedStarted\":\n return buildUnshieldStarted(event, userAddress, metadata);\n case \"UnwrappedFinalized\":\n return buildUnshieldFinalized(event, userAddress, metadata);\n default:\n throw new Error(`Unknown event: ${(event as OnChainEvent).eventName}`);\n }\n}\n\nfunction buildTransfer(\n event: ConfidentialTransferEvent,\n userAddress: Address,\n metadata: ActivityLogMetadata,\n): ActivityItem {\n return {\n type: \"transfer\",\n direction: classifyDirection(userAddress, event.from, event.to),\n amount: { type: \"encrypted\", handle: event.encryptedAmountHandle },\n from: event.from,\n to: event.to,\n metadata,\n rawEvent: event,\n };\n}\n\nfunction buildShield(\n event: WrappedEvent,\n userAddress: Address,\n metadata: ActivityLogMetadata,\n): ActivityItem {\n return {\n type: \"shield\",\n direction: classifyDirection(userAddress, undefined, event.to),\n amount: { type: \"clear\", value: event.amountIn },\n to: event.to,\n metadata,\n rawEvent: event,\n };\n}\n\nfunction buildUnshieldRequested(\n event: UnwrapRequestedEvent,\n userAddress: Address,\n metadata: ActivityLogMetadata,\n): ActivityItem {\n return {\n type: \"unshield_requested\",\n direction: classifyDirection(userAddress, undefined, event.receiver),\n amount: { type: \"encrypted\", handle: event.encryptedAmount },\n to: event.receiver,\n metadata,\n rawEvent: event,\n };\n}\n\nfunction buildUnshieldStarted(\n event: UnwrappedStartedEvent,\n userAddress: Address,\n metadata: ActivityLogMetadata,\n): ActivityItem {\n return {\n type: \"unshield_started\",\n direction: classifyDirection(userAddress, undefined, event.to),\n amount: { type: \"encrypted\", handle: event.requestedAmount },\n to: event.to,\n success: event.returnVal,\n metadata,\n rawEvent: event,\n };\n}\n\nfunction buildUnshieldFinalized(\n event: UnwrappedFinalizedEvent,\n userAddress: Address,\n metadata: ActivityLogMetadata,\n): ActivityItem {\n return {\n type: \"unshield_finalized\",\n direction: classifyDirection(userAddress, undefined, event.receiver),\n amount: { type: \"clear\", value: event.cleartextAmount },\n to: event.receiver,\n metadata,\n rawEvent: event,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Decode raw logs into classified activity items.\n * Skips logs that don't match any confidential token event.\n */\nexport function parseActivityFeed(\n logs: readonly (RawLog & Partial<ActivityLogMetadata>)[],\n userAddress: Address,\n): ActivityItem[] {\n const items: ActivityItem[] = [];\n for (const log of logs) {\n const event = decodeOnChainEvent(log);\n if (!event) {\n continue;\n }\n\n const metadata: ActivityLogMetadata = {\n transactionHash: log.transactionHash,\n blockNumber: log.blockNumber,\n logIndex: log.logIndex,\n };\n items.push(eventToActivityItem(event, userAddress, metadata));\n }\n return items;\n}\n\n/**\n * Extract unique non-zero encrypted handles that need decryption.\n */\nexport function extractEncryptedHandles(items: readonly ActivityItem[]): Handle[] {\n const handles = new Set<Handle>();\n for (const item of items) {\n if (item.amount.type === \"encrypted\" && item.amount.decryptedValue === undefined) {\n const h = item.amount.handle;\n // Skip zero handles\n if (!isZeroHandle(h)) {\n handles.add(h);\n }\n }\n }\n return [...handles];\n}\n\n/**\n * Return new activity items with decrypted values populated.\n * Items whose handles aren't in the map are returned unchanged.\n */\nexport function applyDecryptedValues(\n items: readonly ActivityItem[],\n decrypted: Readonly<Record<Handle, ClearValueType>>,\n): ActivityItem[] {\n return items.map((item) => {\n if (item.amount.type !== \"encrypted\") {\n return item;\n }\n\n const value = decrypted[item.amount.handle];\n if (value === undefined) {\n return item;\n }\n\n assertBigint(value, \"applyDecryptedValues: value\");\n\n return {\n ...item,\n amount: {\n type: \"encrypted\" as const,\n handle: item.amount.handle,\n decryptedValue: value,\n },\n };\n });\n}\n\n/**\n * Sort activity items by block number, most recent first.\n * Items without a block number are placed at the beginning (most recent).\n */\nexport function sortByBlockNumber(items: readonly ActivityItem[]): ActivityItem[] {\n return [...items].toSorted((a, b) => {\n const aBlock = a.metadata.blockNumber;\n const bBlock = b.metadata.blockNumber;\n\n if (aBlock === undefined && bBlock === undefined) {\n return 0;\n }\n if (aBlock === undefined) {\n return -1;\n }\n if (bBlock === undefined) {\n return 1;\n }\n\n // Convert to bigint for comparison\n const aBig = typeof aBlock === \"bigint\" ? aBlock : BigInt(aBlock);\n const bBig = typeof bBlock === \"bigint\" ? bBlock : BigInt(bBlock);\n\n if (bBig > aBig) {\n return 1;\n }\n if (bBig < aBig) {\n return -1;\n }\n\n // Same block: sort by logIndex descending\n const aIdx = a.metadata.logIndex ?? 0;\n const bIdx = b.metadata.logIndex ?? 0;\n return bIdx - aIdx;\n });\n}\n"],"mappings":"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"}
|
package/dist/cjs/cleartext.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const e=require(`./relayer.cjs`);let t=require(`viem`),n=require(`viem/accounts`),r=require(`viem/chains`);async function i(e,t=2){let n;for(let r=0;r<=t;r++)try{return await e()}catch(e){if(n=e,r<t&&a(e)){await o(500*2**r);continue}throw e}throw n}function a(e){if(!(e instanceof Error))return!1;let t=e.message.toLowerCase();return t.includes(`timed out`)||t.includes(`timeout`)||t.includes(`econnreset`)||t.includes(`econnrefused`)||t.includes(`network`)||t.includes(`fetch failed`)||t.includes(`socket hang up`)||t.includes(`502`)||t.includes(`503`)||t.includes(`504`)}function o(e){return new Promise(t=>setTimeout(t,e))}const s={chainId:1,gatewayChainId:261131,relayerUrl:`https://relayer.mainnet.zama.org/v2`,network:`https://ethereum-rpc.publicnode.com`,aclContractAddress:`0xcA2E8f1F656CD25C01F05d0b243Ab1ecd4a8ffb6`,kmsContractAddress:`0x77627828a55156b04Ac0DC0eb30467f1a552BB03`,inputVerifierContractAddress:`0xCe0FC2e05CFff1B719EFF7169f7D80Af770c8EA2`,verifyingContractAddressDecryption:`0x0f6024a97684f7d90ddb0fAAD79cB15F2C888D24`,verifyingContractAddressInputVerification:`0xcB1bB072f38bdAF0F328CdEf1Fc6eDa1DF029287`,registryAddress:`0xeb5015fF021DB115aCe010f23F55C2591059bBA0`},c={chainId:11155111,gatewayChainId:10901,relayerUrl:`https://relayer.testnet.zama.org/v2`,network:`https://ethereum-sepolia-rpc.publicnode.com`,aclContractAddress:`0xf0Ffdc93b7E186bC2f8CB3dAA75D86d1930A433D`,kmsContractAddress:`0xbE0E383937d564D7FF0BC3b46c51f0bF8d5C311A`,inputVerifierContractAddress:`0xBBC1fFCdc7C316aAAd72E807D9b0272BE8F84DA0`,verifyingContractAddressDecryption:`0x5D8BD78e2ea6bbE41f26dFe9fdaEAa349e077478`,verifyingContractAddressInputVerification:`0x483b9dE06E4E4C7D35CCf5837A1668487406D955`,registryAddress:`0x2f0750Bbb0A246059d80e94c454586a7F27a128e`},l={chainId:31337,gatewayChainId:10901,relayerUrl:``,network:`http://127.0.0.1:8545`,aclContractAddress:`0x50157CFfD6bBFA2DECe204a89ec419c23ef5755D`,inputVerifierContractAddress:`0x36772142b74871f255CbD7A3e89B401d3e45825f`,kmsContractAddress:`0x901F8942346f7AB3a01F6D7613119Bca447Bb030`,verifyingContractAddressDecryption:`0x5ffdaAB0373E62E2ea2944776209aEf29E631A64`,verifyingContractAddressInputVerification:`0x812b06e1CDCE800494b79fFE4f925A504a9A9810`,registryAddress:void 0},u={[s.chainId]:s,[c.chainId]:c,[l.chainId]:l},d=(e,t)=>({name:`InputVerification`,version:`1`,chainId:BigInt(e),verifyingContract:t}),f=(e,t)=>({name:`Decryption`,version:`1`,chainId:BigInt(e),verifyingContract:t}),p={domain:d,types:{CiphertextVerification:[{name:`ctHandles`,type:`bytes32[]`},{name:`userAddress`,type:`address`},{name:`contractAddress`,type:`address`},{name:`contractChainId`,type:`uint256`},{name:`extraData`,type:`bytes`}]}},m={domain:f,types:{PublicDecryptVerification:[{name:`ctHandles`,type:`bytes32[]`},{name:`decryptedResult`,type:`bytes`},{name:`extraData`,type:`bytes`}]}},h={domain:f,types:{UserDecryptRequestVerification:[{name:`publicKey`,type:`bytes`},{name:`contractAddresses`,type:`address[]`},{name:`startTimestamp`,type:`uint256`},{name:`durationDays`,type:`uint256`},{name:`extraData`,type:`bytes`}]}},g={domain:f,types:{DelegatedUserDecryptRequestVerification:[{name:`publicKey`,type:`bytes`},{name:`contractAddresses`,type:`address[]`},{name:`delegatorAddress`,type:`address`},{name:`startTimestamp`,type:`uint256`},{name:`durationDays`,type:`uint256`},{name:`extraData`,type:`bytes`}]}},_={ebool:0,euint8:2,euint16:3,euint32:4,euint64:5,euint128:6,eaddress:7,euint256:8},v={0:`ebool`,2:`euint8`,3:`euint16`,4:`euint32`,5:`euint64`,6:`euint128`,7:`eaddress`,8:`euint256`},y={0:2,2:8,3:16,4:32,5:64,6:128,7:160,8:256};Object.freeze(_),Object.freeze(v),Object.freeze(y),Object.freeze({2:0,8:2,16:3,32:4,64:5,128:6,160:7,256:8});function b(e){switch(e){case 0:case 2:case 3:case 4:case 5:case 6:case 7:case 8:return!0;default:return!1}}function x(e){return typeof e==`string`?e in _:!1}function S(e){if(!x(e))throw Error(`Invalid FheType name '${e}'`);return _[e]}function C(e){if(!b(e))throw Error(`Invalid FheType id '${e}'`);let t=y[e];if(t<2)throw Error(`Invalid FheType encryption bit width: ${t}. Minimum is 2 bits.`);return t}const w=(0,t.toBytes)(`ZK-w_rct`),T=(0,t.toBytes)(`ZK-w_hdl`);function E(e,n){let r=Math.ceil(C(n)/8);return(0,t.toBytes)((0,t.pad)((0,t.toHex)(e),{size:r}))}function D(n,r,i){if(i.length!==32)throw new e.i(`random32 must be exactly 32 bytes`);let a=E(r,n),o=(0,t.keccak256)((0,t.concat)([(0,t.toHex)(new Uint8Array([n])),(0,t.toHex)(a),(0,t.toHex)(i)]));return(0,t.keccak256)((0,t.concat)([(0,t.toHex)(w),o]))}function O(n,r,i,a,o){if(!Number.isInteger(r)||r<0||r>255)throw new e.i(`index must be an integer between 0 and 255`);let s=(0,t.keccak256)((0,t.concat)([(0,t.toHex)(w),n])),c=(0,t.keccak256)((0,t.encodePacked)([`bytes`,`bytes32`,`uint8`,`address`,`uint256`],[(0,t.toHex)(T),s,r,a,o])),l=o&18446744073709551615n;return(0,t.toHex)(BigInt(c)&115792089237316195423570985008687907853269984665640254554447762662844404858880n|BigInt(r)<<80n|l<<16n|BigInt(i)<<8n|BigInt(0),{size:32})}const k=(0,t.parseAbi)([`function persistAllowed(bytes32 handle, address account) view returns (bool)`,`function isAllowedForDecryption(bytes32 handle) view returns (bool)`,`function isHandleDelegatedForUserDecryption(address delegator, address delegate, address contractAddress, bytes32 handle) view returns (bool)`]),A=(0,t.parseAbi)([`function plaintexts(bytes32 handle) view returns (uint256)`]),j=[{name:`name`,type:`string`},{name:`version`,type:`string`},{name:`chainId`,type:`uint256`},{name:`verifyingContract`,type:`address`}],M={EIP712Domain:j,UserDecryptRequestVerification:h.types.UserDecryptRequestVerification},N={EIP712Domain:j,DelegatedUserDecryptRequestVerification:g.types.DelegatedUserDecryptRequestVerification},P={EIP712Domain:j,PublicDecryptVerification:m.types.PublicDecryptVerification},F=new Set([r.mainnet.id,r.sepolia.id]);function I(e,n){let r=Number(BigInt(e)>>8n&255n);return r===0?n!==0n:r===7?(0,t.toHex)(n,{size:20}):n}function L(n){if(!x(n.type))throw new e.i(`Unsupported FHE type`);let r=S(n.type),i;if(n.type===`ebool`){if(typeof n.value==`boolean`)i=n.value?1n:0n;else if(i=n.value,i!==0n&&i!==1n)throw new e.i(`Bool value must be 0, 1, true, or false`)}else i=n.type===`eaddress`?BigInt((0,t.getAddress)(n.value)):n.value;if(i<0n)throw new e.i(`Only non-negative cleartext values are supported`);let a=C(r),o=(1n<<BigInt(a))-1n;if(i>o)throw new e.i(`Value ${i} exceeds max ${o} for FheType ${r}`);return{fheType:r,value:i}}var R=class{#e;#t;kmsSigner;inputSigner;constructor(r){if(F.has(r.chainId))throw new e.t(`Cleartext mode is not allowed on chain ${r.chainId}. It is intended for local development and testing only.`);this.#e=(0,t.createPublicClient)({transport:typeof r.network==`string`?(0,t.http)(r.network):(0,t.custom)(r.network)}),this.#t=r,this.kmsSigner=(0,n.privateKeyToAccount)(r.kmsSignerPrivateKey??`0x388b7680e4e1afa06efbfd45cdd1fe39f3c6af381df6555a19661f283b97de91`),this.inputSigner=(0,n.privateKeyToAccount)(r.inputSignerPrivateKey??`0x7ec8ada6642fc4ccfb7729bc29c17cf8d21b61abd5642d1db992c0b8672ab901`)}async generateKeypair(){let e=(0,t.toHex)(crypto.getRandomValues(new Uint8Array(32))),n=(0,t.toHex)(crypto.getRandomValues(new Uint8Array(32)));for(;n===e;)n=(0,t.toHex)(crypto.getRandomValues(new Uint8Array(32)));return{publicKey:e,privateKey:n}}async createEIP712(e,t,n,r=7){return{domain:h.domain(this.#t.chainId,this.#t.verifyingContractAddressDecryption),types:M,primaryType:`UserDecryptRequestVerification`,message:{publicKey:e,contractAddresses:t,startTimestamp:String(n),durationDays:String(r),extraData:`0x00`}}}async encrypt(e){let n=e.values.map(L),r=(0,t.getAddress)(e.contractAddress),i=(0,t.getAddress)(e.userAddress),a=n.map(({fheType:e,value:t})=>D(e,t,crypto.getRandomValues(new Uint8Array(32)))),o=(0,t.keccak256)(a.length>0?(0,t.concat)(a):`0x`),s=n.map(({fheType:e},t)=>O(o,t,e,this.#t.aclContractAddress,BigInt(this.#t.chainId))),c=n.map(({value:e})=>(0,t.pad)((0,t.toHex)(e),{size:32})),l=c.length>0?(0,t.concat)(c):`0x`,u=await this.inputSigner.signTypedData({domain:p.domain(this.#t.gatewayChainId,this.#t.verifyingContractAddressInputVerification),types:{CiphertextVerification:p.types.CiphertextVerification},primaryType:`CiphertextVerification`,message:{ctHandles:s,userAddress:i,contractAddress:r,contractChainId:BigInt(this.#t.chainId),extraData:l}}),d=(0,t.toBytes)((0,t.concat)([(0,t.toHex)(new Uint8Array([s.length])),(0,t.toHex)(new Uint8Array([1])),...s,u,l]));return{handles:s.map(e=>(0,t.toBytes)(e)),inputProof:d}}async userDecrypt(e){return await this.#r(e.handles,(0,t.getAddress)(e.signerAddress),(0,t.getAddress)(e.contractAddress),`User`,`user decrypt`),this.#n(e.handles)}async publicDecrypt(n){let r=n,i=(await Promise.all(r.map(e=>this.#o(e)))).findIndex(e=>!e);if(i!==-1)throw new e.r(`Handle ${r[i]} is not allowed for public decryption`);let a=await Promise.all(r.map(e=>this.#s(e))),o=Object.fromEntries(r.map((e,t)=>[e,I(e,a[t])])),s=(0,t.concat)(a.map(e=>(0,t.pad)((0,t.toHex)(e),{size:32}))),c=await this.kmsSigner.signTypedData({domain:m.domain(this.#t.gatewayChainId,this.#t.verifyingContractAddressDecryption),types:P,primaryType:`PublicDecryptVerification`,message:{ctHandles:r,decryptedResult:s,extraData:`0x`}});return{clearValues:o,abiEncodedClearValues:s,decryptionProof:(0,t.concat)([(0,t.toHex)(new Uint8Array([1])),c])}}async createDelegatedUserDecryptEIP712(e,n,r,i,a=7){let o={publicKey:e,contractAddresses:n,delegatorAddress:(0,t.getAddress)(r),startTimestamp:String(i),durationDays:String(a),extraData:`0x00`};return{domain:g.domain(this.#t.chainId,this.#t.verifyingContractAddressDecryption),types:N,primaryType:`DelegatedUserDecryptRequestVerification`,message:o}}async delegatedUserDecrypt(e){return await this.#i(e.handles,(0,t.getAddress)(e.delegatorAddress),(0,t.getAddress)(e.delegateAddress),(0,t.getAddress)(e.contractAddress)),this.#n(e.handles)}async requestZKProofVerification(t){throw new e.t(`Not implemented in cleartext mode`)}async getPublicKey(){return{publicKeyId:`mock-public-key-id`,publicKey:new Uint8Array([32])}}async getPublicParams(e){return{publicParams:new Uint8Array([32]),publicParamsId:`mock-public-params-id`}}async getAclAddress(){return this.#t.aclContractAddress}terminate(){}[Symbol.dispose](){this.terminate()}async#n(e){let t=await Promise.all(e.map(e=>this.#s(e)));return Object.fromEntries(e.map((e,n)=>[e,I(e,t[n])]))}async#r(t,n,r,i,a){if(n===r)throw new e.r(`${i} address ${n} must not equal contract address for ${a}`);let o=await Promise.all(t.flatMap(e=>[this.#a(e,n),this.#a(e,r)]));for(let s=0;s<t.length;s++){let c=o[s*2],l=o[s*2+1];if(!c)throw new e.r(`${i} ${n} is not authorized for ${a} of handle ${t[s]}`);if(!l)throw new e.r(`Contract ${r} is not authorized for ${a} of handle ${t[s]}`)}}async#i(t,n,r,i){let a=await Promise.all(t.map(e=>this.#e.readContract({address:this.#t.aclContractAddress,abi:k,functionName:`isHandleDelegatedForUserDecryption`,args:[n,r,i,e]})));for(let n=0;n<t.length;n++)if(!a[n])throw new e.r(`Handle ${t[n]} is not delegated for user decryption`)}async#a(e,t){return this.#e.readContract({address:this.#t.aclContractAddress,abi:k,functionName:`persistAllowed`,args:[e,t]})}async#o(e){return this.#e.readContract({address:this.#t.aclContractAddress,abi:k,functionName:`isAllowedForDecryption`,args:[e]})}async#s(e){return this.#e.readContract({address:this.#t.executorAddress,abi:A,functionName:`plaintexts`,args:[e]})}};const z={...l,executorAddress:`0xe3a9105a3a932253A70F126eb1E3b589C643dD24`},B={chainId:560048,network:`https://rpc.hoodi.ethpandaops.io`,gatewayChainId:l.gatewayChainId,aclContractAddress:`0x6D3FAf6f86e1fF9F3B0831Dda920AbA1cBd5bd68`,executorAddress:`0xC316692627de536368d82e9121F1D44a550894E6`,verifyingContractAddressDecryption:l.verifyingContractAddressDecryption,verifyingContractAddressInputVerification:l.verifyingContractAddressInputVerification,registryAddress:`0x1807aE2f693F8530DFB126D0eF98F2F2518F292f`};Object.defineProperty(exports,`a`,{enumerable:!0,get:function(){return l}}),Object.defineProperty(exports,`c`,{enumerable:!0,get:function(){return i}}),Object.defineProperty(exports,`i`,{enumerable:!0,get:function(){return u}}),Object.defineProperty(exports,`n`,{enumerable:!0,get:function(){return B}}),Object.defineProperty(exports,`o`,{enumerable:!0,get:function(){return s}}),Object.defineProperty(exports,`r`,{enumerable:!0,get:function(){return R}}),Object.defineProperty(exports,`s`,{enumerable:!0,get:function(){return c}}),Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return z}});
|
|
1
|
+
const e=require(`./relayer.cjs`);let t=require(`viem`),n=require(`viem/accounts`),r=require(`viem/chains`);async function i(e,t=2){let n;for(let r=0;r<=t;r++)try{return await e()}catch(e){if(n=e,r<t&&a(e)){await o(500*2**r);continue}throw e}throw n}function a(e){if(!(e instanceof Error))return!1;let t=e.message.toLowerCase();return t.includes(`timed out`)||t.includes(`timeout`)||t.includes(`econnreset`)||t.includes(`econnrefused`)||t.includes(`network`)||t.includes(`fetch failed`)||t.includes(`socket hang up`)||t.includes(`502`)||t.includes(`503`)||t.includes(`504`)}function o(e){return new Promise(t=>setTimeout(t,e))}const s={chainId:1,gatewayChainId:261131,relayerUrl:`https://relayer.mainnet.zama.org/v2`,network:`https://ethereum-rpc.publicnode.com`,aclContractAddress:`0xcA2E8f1F656CD25C01F05d0b243Ab1ecd4a8ffb6`,kmsContractAddress:`0x77627828a55156b04Ac0DC0eb30467f1a552BB03`,inputVerifierContractAddress:`0xCe0FC2e05CFff1B719EFF7169f7D80Af770c8EA2`,verifyingContractAddressDecryption:`0x0f6024a97684f7d90ddb0fAAD79cB15F2C888D24`,verifyingContractAddressInputVerification:`0xcB1bB072f38bdAF0F328CdEf1Fc6eDa1DF029287`,registryAddress:`0xeb5015fF021DB115aCe010f23F55C2591059bBA0`},c={chainId:11155111,gatewayChainId:10901,relayerUrl:`https://relayer.testnet.zama.org/v2`,network:`https://ethereum-sepolia-rpc.publicnode.com`,aclContractAddress:`0xf0Ffdc93b7E186bC2f8CB3dAA75D86d1930A433D`,kmsContractAddress:`0xbE0E383937d564D7FF0BC3b46c51f0bF8d5C311A`,inputVerifierContractAddress:`0xBBC1fFCdc7C316aAAd72E807D9b0272BE8F84DA0`,verifyingContractAddressDecryption:`0x5D8BD78e2ea6bbE41f26dFe9fdaEAa349e077478`,verifyingContractAddressInputVerification:`0x483b9dE06E4E4C7D35CCf5837A1668487406D955`,registryAddress:`0x2f0750Bbb0A246059d80e94c454586a7F27a128e`},l={chainId:31337,gatewayChainId:10901,relayerUrl:``,network:`http://127.0.0.1:8545`,aclContractAddress:`0x50157CFfD6bBFA2DECe204a89ec419c23ef5755D`,inputVerifierContractAddress:`0x36772142b74871f255CbD7A3e89B401d3e45825f`,kmsContractAddress:`0x901F8942346f7AB3a01F6D7613119Bca447Bb030`,verifyingContractAddressDecryption:`0x5ffdaAB0373E62E2ea2944776209aEf29E631A64`,verifyingContractAddressInputVerification:`0x812b06e1CDCE800494b79fFE4f925A504a9A9810`,registryAddress:void 0},u={[s.chainId]:s,[c.chainId]:c,[l.chainId]:l},d={name:`string`,version:`string`,chainId:`uint256`,verifyingContract:`address`,salt:`bytes32`};function f(e){return Object.keys(d).filter(t=>t in e).map(e=>({name:e,type:d[e]}))}const p=(e,t)=>({name:`InputVerification`,version:`1`,chainId:Number(e),verifyingContract:t}),m=(e,t)=>({name:`Decryption`,version:`1`,chainId:Number(e),verifyingContract:t}),h={domain:p,types:{CiphertextVerification:[{name:`ctHandles`,type:`bytes32[]`},{name:`userAddress`,type:`address`},{name:`contractAddress`,type:`address`},{name:`contractChainId`,type:`uint256`},{name:`extraData`,type:`bytes`}]}},g={domain:m,types:{PublicDecryptVerification:[{name:`ctHandles`,type:`bytes32[]`},{name:`decryptedResult`,type:`bytes`},{name:`extraData`,type:`bytes`}]}},_={domain:m,types:{UserDecryptRequestVerification:[{name:`publicKey`,type:`bytes`},{name:`contractAddresses`,type:`address[]`},{name:`startTimestamp`,type:`uint256`},{name:`durationDays`,type:`uint256`},{name:`extraData`,type:`bytes`}]}},v={domain:m,types:{DelegatedUserDecryptRequestVerification:[{name:`publicKey`,type:`bytes`},{name:`contractAddresses`,type:`address[]`},{name:`delegatorAddress`,type:`address`},{name:`startTimestamp`,type:`uint256`},{name:`durationDays`,type:`uint256`},{name:`extraData`,type:`bytes`}]}},y={ebool:0,euint8:2,euint16:3,euint32:4,euint64:5,euint128:6,eaddress:7,euint256:8},b={0:`ebool`,2:`euint8`,3:`euint16`,4:`euint32`,5:`euint64`,6:`euint128`,7:`eaddress`,8:`euint256`},x={0:2,2:8,3:16,4:32,5:64,6:128,7:160,8:256};Object.freeze(y),Object.freeze(b),Object.freeze(x),Object.freeze({2:0,8:2,16:3,32:4,64:5,128:6,160:7,256:8});function S(e){switch(e){case 0:case 2:case 3:case 4:case 5:case 6:case 7:case 8:return!0;default:return!1}}function C(e){return typeof e==`string`?e in y:!1}function w(e){if(!C(e))throw Error(`Invalid FheType name '${e}'`);return y[e]}function T(e){if(!S(e))throw Error(`Invalid FheType id '${e}'`);let t=x[e];if(t<2)throw Error(`Invalid FheType encryption bit width: ${t}. Minimum is 2 bits.`);return t}const E=(0,t.toBytes)(`ZK-w_rct`),D=(0,t.toBytes)(`ZK-w_hdl`);function O(e,n){let r=Math.ceil(T(n)/8);return(0,t.toBytes)((0,t.pad)((0,t.toHex)(e),{size:r}))}function k(n,r,i){if(i.length!==32)throw new e.i(`random32 must be exactly 32 bytes`);let a=O(r,n),o=(0,t.keccak256)((0,t.concat)([(0,t.toHex)(new Uint8Array([n])),(0,t.toHex)(a),(0,t.toHex)(i)]));return(0,t.keccak256)((0,t.concat)([(0,t.toHex)(E),o]))}function A(n,r,i,a,o){if(!Number.isInteger(r)||r<0||r>255)throw new e.i(`index must be an integer between 0 and 255`);let s=(0,t.keccak256)((0,t.concat)([(0,t.toHex)(E),n])),c=(0,t.keccak256)((0,t.encodePacked)([`bytes`,`bytes32`,`uint8`,`address`,`uint256`],[(0,t.toHex)(D),s,r,a,o])),l=o&18446744073709551615n;return(0,t.toHex)(BigInt(c)&115792089237316195423570985008687907853269984665640254554447762662844404858880n|BigInt(r)<<80n|l<<16n|BigInt(i)<<8n|BigInt(0),{size:32})}const j=(0,t.parseAbi)([`function persistAllowed(bytes32 handle, address account) view returns (bool)`,`function isAllowedForDecryption(bytes32 handle) view returns (bool)`,`function isHandleDelegatedForUserDecryption(address delegator, address delegate, address contractAddress, bytes32 handle) view returns (bool)`]),M=(0,t.parseAbi)([`function plaintexts(bytes32 handle) view returns (uint256)`]),N=[{name:`name`,type:`string`},{name:`version`,type:`string`},{name:`chainId`,type:`uint256`},{name:`verifyingContract`,type:`address`}],P={EIP712Domain:N,UserDecryptRequestVerification:_.types.UserDecryptRequestVerification},F={EIP712Domain:N,DelegatedUserDecryptRequestVerification:v.types.DelegatedUserDecryptRequestVerification},I={EIP712Domain:N,PublicDecryptVerification:g.types.PublicDecryptVerification},L=new Set([r.mainnet.id,r.sepolia.id]);function R(e,n){let r=Number(BigInt(e)>>8n&255n);return r===0?n!==0n:r===7?(0,t.toHex)(n,{size:20}):n}function z(n){if(!C(n.type))throw new e.i(`Unsupported FHE type`);let r=w(n.type),i;if(n.type===`ebool`){if(typeof n.value==`boolean`)i=n.value?1n:0n;else if(i=n.value,i!==0n&&i!==1n)throw new e.i(`Bool value must be 0, 1, true, or false`)}else i=n.type===`eaddress`?BigInt((0,t.getAddress)(n.value)):n.value;if(i<0n)throw new e.i(`Only non-negative cleartext values are supported`);let a=T(r),o=(1n<<BigInt(a))-1n;if(i>o)throw new e.i(`Value ${i} exceeds max ${o} for FheType ${r}`);return{fheType:r,value:i}}var B=class{#e;#t;kmsSigner;inputSigner;constructor(r){if(L.has(r.chainId))throw new e.t(`Cleartext mode is not allowed on chain ${r.chainId}. It is intended for local development and testing only.`);this.#e=(0,t.createPublicClient)({transport:typeof r.network==`string`?(0,t.http)(r.network):(0,t.custom)(r.network)}),this.#t=r,this.kmsSigner=(0,n.privateKeyToAccount)(r.kmsSignerPrivateKey??`0x388b7680e4e1afa06efbfd45cdd1fe39f3c6af381df6555a19661f283b97de91`),this.inputSigner=(0,n.privateKeyToAccount)(r.inputSignerPrivateKey??`0x7ec8ada6642fc4ccfb7729bc29c17cf8d21b61abd5642d1db992c0b8672ab901`)}async generateKeypair(){let e=(0,t.toHex)(crypto.getRandomValues(new Uint8Array(32))),n=(0,t.toHex)(crypto.getRandomValues(new Uint8Array(32)));for(;n===e;)n=(0,t.toHex)(crypto.getRandomValues(new Uint8Array(32)));return{publicKey:e,privateKey:n}}async createEIP712(e,t,n,r=7){return{domain:_.domain(this.#t.chainId,this.#t.verifyingContractAddressDecryption),types:P,primaryType:`UserDecryptRequestVerification`,message:{publicKey:e,contractAddresses:t,startTimestamp:BigInt(n),durationDays:BigInt(r),extraData:`0x00`}}}async encrypt(e){let n=e.values.map(z),r=(0,t.getAddress)(e.contractAddress),i=(0,t.getAddress)(e.userAddress),a=n.map(({fheType:e,value:t})=>k(e,t,crypto.getRandomValues(new Uint8Array(32)))),o=(0,t.keccak256)(a.length>0?(0,t.concat)(a):`0x`),s=n.map(({fheType:e},t)=>A(o,t,e,this.#t.aclContractAddress,BigInt(this.#t.chainId))),c=n.map(({value:e})=>(0,t.pad)((0,t.toHex)(e),{size:32})),l=c.length>0?(0,t.concat)(c):`0x`,u=await this.inputSigner.signTypedData({domain:h.domain(this.#t.gatewayChainId,this.#t.verifyingContractAddressInputVerification),types:{CiphertextVerification:h.types.CiphertextVerification},primaryType:`CiphertextVerification`,message:{ctHandles:s,userAddress:i,contractAddress:r,contractChainId:BigInt(this.#t.chainId),extraData:l}}),d=(0,t.toBytes)((0,t.concat)([(0,t.toHex)(new Uint8Array([s.length])),(0,t.toHex)(new Uint8Array([1])),...s,u,l]));return{handles:s.map(e=>(0,t.toBytes)(e)),inputProof:d}}async userDecrypt(e){return await this.#r(e.handles,(0,t.getAddress)(e.signerAddress),(0,t.getAddress)(e.contractAddress),`User`,`user decrypt`),this.#n(e.handles)}async publicDecrypt(n){let r=n,i=(await Promise.all(r.map(e=>this.#o(e)))).findIndex(e=>!e);if(i!==-1)throw new e.r(`Handle ${r[i]} is not allowed for public decryption`);let a=await Promise.all(r.map(e=>this.#s(e))),o=Object.fromEntries(r.map((e,t)=>[e,R(e,a[t])])),s=(0,t.concat)(a.map(e=>(0,t.pad)((0,t.toHex)(e),{size:32}))),c=await this.kmsSigner.signTypedData({domain:g.domain(this.#t.gatewayChainId,this.#t.verifyingContractAddressDecryption),types:I,primaryType:`PublicDecryptVerification`,message:{ctHandles:r,decryptedResult:s,extraData:`0x`}});return{clearValues:o,abiEncodedClearValues:s,decryptionProof:(0,t.concat)([(0,t.toHex)(new Uint8Array([1])),c])}}async createDelegatedUserDecryptEIP712(e,n,r,i,a=7){let o={publicKey:e,contractAddresses:n,delegatorAddress:(0,t.getAddress)(r),startTimestamp:String(i),durationDays:String(a),extraData:`0x00`};return{domain:v.domain(BigInt(this.#t.chainId),this.#t.verifyingContractAddressDecryption),types:F,primaryType:`DelegatedUserDecryptRequestVerification`,message:o}}async delegatedUserDecrypt(e){return await this.#i(e.handles,(0,t.getAddress)(e.delegatorAddress),(0,t.getAddress)(e.delegateAddress),(0,t.getAddress)(e.contractAddress)),this.#n(e.handles)}async requestZKProofVerification(t){throw new e.t(`Not implemented in cleartext mode`)}async getPublicKey(){return{publicKeyId:`mock-public-key-id`,publicKey:new Uint8Array([32])}}async getPublicParams(e){return{publicParams:new Uint8Array([32]),publicParamsId:`mock-public-params-id`}}async getAclAddress(){return this.#t.aclContractAddress}terminate(){}[Symbol.dispose](){this.terminate()}async#n(e){let t=await Promise.all(e.map(e=>this.#s(e)));return Object.fromEntries(e.map((e,n)=>[e,R(e,t[n])]))}async#r(t,n,r,i,a){if(n===r)throw new e.r(`${i} address ${n} must not equal contract address for ${a}`);let o=await Promise.all(t.flatMap(e=>[this.#a(e,n),this.#a(e,r)]));for(let s=0;s<t.length;s++){let c=o[s*2],l=o[s*2+1];if(!c)throw new e.r(`${i} ${n} is not authorized for ${a} of handle ${t[s]}`);if(!l)throw new e.r(`Contract ${r} is not authorized for ${a} of handle ${t[s]}`)}}async#i(t,n,r,i){let a=await Promise.all(t.map(e=>this.#e.readContract({address:this.#t.aclContractAddress,abi:j,functionName:`isHandleDelegatedForUserDecryption`,args:[n,r,i,e]})));for(let n=0;n<t.length;n++)if(!a[n])throw new e.r(`Handle ${t[n]} is not delegated for user decryption`)}async#a(e,t){return this.#e.readContract({address:this.#t.aclContractAddress,abi:j,functionName:`persistAllowed`,args:[e,t]})}async#o(e){return this.#e.readContract({address:this.#t.aclContractAddress,abi:j,functionName:`isAllowedForDecryption`,args:[e]})}async#s(e){return this.#e.readContract({address:this.#t.executorAddress,abi:M,functionName:`plaintexts`,args:[e]})}};const V={...l,executorAddress:`0xe3a9105a3a932253A70F126eb1E3b589C643dD24`},H={chainId:560048,network:`https://rpc.hoodi.ethpandaops.io`,gatewayChainId:l.gatewayChainId,aclContractAddress:`0x6D3FAf6f86e1fF9F3B0831Dda920AbA1cBd5bd68`,executorAddress:`0xC316692627de536368d82e9121F1D44a550894E6`,verifyingContractAddressDecryption:l.verifyingContractAddressDecryption,verifyingContractAddressInputVerification:l.verifyingContractAddressInputVerification,registryAddress:`0x1807aE2f693F8530DFB126D0eF98F2F2518F292f`};Object.defineProperty(exports,`a`,{enumerable:!0,get:function(){return l}}),Object.defineProperty(exports,`c`,{enumerable:!0,get:function(){return f}}),Object.defineProperty(exports,`i`,{enumerable:!0,get:function(){return u}}),Object.defineProperty(exports,`l`,{enumerable:!0,get:function(){return i}}),Object.defineProperty(exports,`n`,{enumerable:!0,get:function(){return H}}),Object.defineProperty(exports,`o`,{enumerable:!0,get:function(){return s}}),Object.defineProperty(exports,`r`,{enumerable:!0,get:function(){return B}}),Object.defineProperty(exports,`s`,{enumerable:!0,get:function(){return c}}),Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return V}});
|
|
2
2
|
//# sourceMappingURL=cleartext.cjs.map
|