@cofhe/react 0.0.0-beta-20260417095940 → 0.0.0-beta-20260420143138

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -767,6 +767,65 @@ import * as viemChains from "viem/chains";
767
767
  // src/types/token.ts
768
768
  import { baseSepolia, sepolia } from "@cofhe/sdk/chains";
769
769
  var ETH_ADDRESS_LOWERCASE = "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee";
770
+ var TOKEN_CONFIDENTIALITY_SUPPORT = {
771
+ wrapped: {
772
+ enabled: true,
773
+ publicBalanceSource: "erc20Pair",
774
+ operations: {
775
+ confidentialBalance: true,
776
+ transfer: true,
777
+ publicBalance: true,
778
+ shield: true,
779
+ unshield: true,
780
+ claim: true,
781
+ claimable: true
782
+ }
783
+ },
784
+ pure: {
785
+ enabled: false,
786
+ publicBalanceSource: null,
787
+ operations: {
788
+ confidentialBalance: false,
789
+ transfer: false,
790
+ publicBalance: false,
791
+ shield: false,
792
+ unshield: false,
793
+ claim: false,
794
+ claimable: false
795
+ }
796
+ },
797
+ dual: {
798
+ enabled: false,
799
+ publicBalanceSource: "token",
800
+ operations: {
801
+ confidentialBalance: false,
802
+ transfer: false,
803
+ publicBalance: false,
804
+ shield: false,
805
+ unshield: false,
806
+ claim: false,
807
+ claimable: false
808
+ }
809
+ }
810
+ };
811
+ var TOKEN_CONFIDENTIALITY_TYPES = Object.keys(TOKEN_CONFIDENTIALITY_SUPPORT);
812
+ function isTokenConfidentialityType(value) {
813
+ return typeof value === "string" && value in TOKEN_CONFIDENTIALITY_SUPPORT;
814
+ }
815
+ function isSupportedTokenConfidentialityType(value) {
816
+ return isTokenConfidentialityType(value) && TOKEN_CONFIDENTIALITY_SUPPORT[value].enabled;
817
+ }
818
+ function isTokenOperationSupported(type, operation) {
819
+ return isTokenConfidentialityType(type) && TOKEN_CONFIDENTIALITY_SUPPORT[type].operations[operation];
820
+ }
821
+ function getPublicBalanceSourceType(type) {
822
+ if (!isTokenConfidentialityType(type)) return null;
823
+ return TOKEN_CONFIDENTIALITY_SUPPORT[type].publicBalanceSource;
824
+ }
825
+ function assertTokenOperationSupported(type, operation) {
826
+ if (isTokenOperationSupported(type, operation)) return;
827
+ throw new Error(`${operation} not supported for confidentialityType: ${type ?? "undefined"}`);
828
+ }
770
829
  var WETH_SEPOLIA_TOKEN = {
771
830
  chainId: 11155111,
772
831
  address: "0x87A3effB84CBE1E4caB6Ab430139eC41d156D55A",
@@ -845,7 +904,7 @@ var isEthPair = (erc20Pair) => {
845
904
  return erc20Pair.address.toLowerCase() === ETH_ADDRESS_LOWERCASE;
846
905
  };
847
906
  var isWrappedEthToken = (token) => {
848
- if (token.extensions.fhenix.confidentialityType !== "wrapped") return false;
907
+ if (!isSupportedTokenConfidentialityType(token.extensions.fhenix.confidentialityType)) return false;
849
908
  return isEthPair(token.extensions.fhenix.erc20Pair);
850
909
  };
851
910
  var FheTypesList = [
@@ -1606,249 +1665,222 @@ function useCofheReadContract(params, queryOptions) {
1606
1665
  // src/hooks/useTrackPendingTransactions.ts
1607
1666
  import "@tanstack/react-query";
1608
1667
 
1609
- // src/constants/confidentialTokenABIs.ts
1668
+ // src/constants/confidentialTokenWrapped.ts
1610
1669
  import { parseAbi } from "viem";
1611
- var ERC20_ALLOWANCE_ABI = parseAbi([
1612
- "function allowance(address owner, address spender) view returns (uint256)"
1613
- ]);
1614
- var ERC20_APPROVE_ABI = parseAbi(["function approve(address spender, uint256 amount) returns (bool)"]);
1615
- var CONFIDENTIAL_TYPE_WRAPPED_ABI = [
1616
- {
1617
- inputs: [
1618
- {
1619
- internalType: "address",
1620
- name: "account",
1621
- type: "address"
1622
- }
1623
- ],
1624
- name: "encBalanceOf",
1625
- outputs: [
1626
- {
1627
- internalType: "euint128",
1628
- name: "",
1629
- type: "uint256"
1630
- }
1631
- ],
1632
- stateMutability: "view",
1633
- type: "function"
1634
- }
1635
- ];
1636
- var CONFIDENTIAL_TYPE_PURE_ABI = parseAbi([
1637
- "function confidentialBalanceOf(address account) view returns (uint256)"
1638
- ]);
1639
- var CONFIDENTIAL_TYPE_DUAL_ABI = parseAbi([
1640
- "function confidentialBalanceOf(address account) view returns (uint256)"
1641
- ]);
1642
- var CONFIDENTIAL_ABIS = {
1643
- wrapped: {
1644
- abi: CONFIDENTIAL_TYPE_WRAPPED_ABI,
1645
- functionName: "encBalanceOf"
1646
- },
1647
- pure: {
1648
- abi: CONFIDENTIAL_TYPE_PURE_ABI,
1649
- functionName: "confidentialBalanceOf"
1670
+ var wrappedErc20ApprovalContracts = {
1671
+ allowance: {
1672
+ abi: parseAbi(["function allowance(address owner, address spender) view returns (uint256)"]),
1673
+ functionName: "allowance"
1650
1674
  },
1651
- dual: {
1652
- abi: CONFIDENTIAL_TYPE_DUAL_ABI,
1653
- functionName: "confidentialBalanceOf"
1675
+ approve: {
1676
+ abi: parseAbi(["function approve(address spender, uint256 amount) returns (bool)"]),
1677
+ functionName: "approve"
1654
1678
  }
1655
1679
  };
1656
- var WRAPPED_TRANSFER_ABI = [
1657
- {
1658
- inputs: [
1659
- {
1660
- internalType: "address",
1661
- name: "to",
1662
- type: "address"
1663
- },
1680
+ var WRAPPED_TOKEN_CONTRACTS = {
1681
+ confidentialBalance: {
1682
+ abi: [
1664
1683
  {
1665
- components: [
1684
+ inputs: [
1685
+ {
1686
+ internalType: "address",
1687
+ name: "account",
1688
+ type: "address"
1689
+ }
1690
+ ],
1691
+ name: "encBalanceOf",
1692
+ outputs: [
1666
1693
  {
1667
- internalType: "uint256",
1668
- name: "ctHash",
1694
+ internalType: "euint128",
1695
+ name: "",
1669
1696
  type: "uint256"
1670
- },
1697
+ }
1698
+ ],
1699
+ stateMutability: "view",
1700
+ type: "function"
1701
+ }
1702
+ ],
1703
+ functionName: "encBalanceOf"
1704
+ },
1705
+ confidentialTransfer: {
1706
+ abi: [
1707
+ {
1708
+ inputs: [
1671
1709
  {
1672
- internalType: "uint8",
1673
- name: "securityZone",
1674
- type: "uint8"
1710
+ internalType: "address",
1711
+ name: "to",
1712
+ type: "address"
1675
1713
  },
1676
1714
  {
1677
- internalType: "uint8",
1678
- name: "utype",
1679
- type: "uint8"
1680
- },
1715
+ components: [
1716
+ {
1717
+ internalType: "uint256",
1718
+ name: "ctHash",
1719
+ type: "uint256"
1720
+ },
1721
+ {
1722
+ internalType: "uint8",
1723
+ name: "securityZone",
1724
+ type: "uint8"
1725
+ },
1726
+ {
1727
+ internalType: "uint8",
1728
+ name: "utype",
1729
+ type: "uint8"
1730
+ },
1731
+ {
1732
+ internalType: "bytes",
1733
+ name: "signature",
1734
+ type: "bytes"
1735
+ }
1736
+ ],
1737
+ internalType: "struct InEuint128",
1738
+ name: "inValue",
1739
+ type: "tuple"
1740
+ }
1741
+ ],
1742
+ name: "encTransfer",
1743
+ outputs: [
1681
1744
  {
1682
- internalType: "bytes",
1683
- name: "signature",
1684
- type: "bytes"
1745
+ internalType: "euint128",
1746
+ name: "transferred",
1747
+ type: "uint256"
1685
1748
  }
1686
1749
  ],
1687
- internalType: "struct InEuint128",
1688
- name: "inValue",
1689
- type: "tuple"
1690
- }
1691
- ],
1692
- name: "encTransfer",
1693
- outputs: [
1694
- {
1695
- internalType: "euint128",
1696
- name: "transferred",
1697
- type: "uint256"
1698
- }
1699
- ],
1700
- stateMutability: "nonpayable",
1701
- type: "function"
1702
- }
1703
- ];
1704
- var PURE_TRANSFER_ABI = [
1705
- {
1706
- name: "confidentialTransfer",
1707
- type: "function",
1708
- stateMutability: "nonpayable",
1709
- inputs: [
1710
- { name: "to", type: "address" },
1711
- {
1712
- name: "inValue",
1713
- type: "tuple",
1714
- components: [
1715
- { name: "ctHash", type: "uint256" },
1716
- { name: "securityZone", type: "uint8" },
1717
- { name: "utype", type: "uint8" },
1718
- { name: "signature", type: "bytes" }
1719
- ]
1750
+ stateMutability: "nonpayable",
1751
+ type: "function"
1720
1752
  }
1721
1753
  ],
1722
- outputs: [{ name: "transferred", type: "uint256" }]
1723
- }
1724
- ];
1725
- var DUAL_TRANSFER_ABI = [
1726
- {
1727
- name: "TBD_DUAL_FUNCTION_NAME",
1728
- type: "function",
1729
- stateMutability: "nonpayable",
1730
- inputs: [
1731
- { name: "to", type: "address" },
1732
- {
1733
- name: "inValue",
1734
- type: "tuple",
1735
- components: [
1736
- { name: "ctHash", type: "uint256" },
1737
- { name: "securityZone", type: "uint8" },
1738
- { name: "utype", type: "uint8" },
1739
- { name: "signature", type: "bytes" }
1740
- ]
1741
- }
1742
- ],
1743
- outputs: [{ name: "transferred", type: "uint256" }]
1744
- }
1745
- ];
1746
- var TRANSFER_ABIS = {
1747
- wrapped: {
1748
- abi: WRAPPED_TRANSFER_ABI,
1749
1754
  functionName: "encTransfer"
1750
1755
  },
1751
- pure: {
1752
- abi: PURE_TRANSFER_ABI,
1753
- functionName: "confidentialTransfer"
1756
+ shield: {
1757
+ approval: wrappedErc20ApprovalContracts,
1758
+ erc20: {
1759
+ abi: parseAbi(["function encrypt(address to, uint128 value) public"]),
1760
+ functionName: "encrypt"
1761
+ },
1762
+ native: {
1763
+ abi: parseAbi(["function encryptETH(address to) public payable"]),
1764
+ functionName: "encryptETH"
1765
+ },
1766
+ wrappedPair: {
1767
+ abi: parseAbi(["function encryptWETH(address to, uint128 value) public"]),
1768
+ functionName: "encryptWETH"
1769
+ }
1754
1770
  },
1755
- dual: {
1756
- // Placeholder for dual type
1757
- abi: DUAL_TRANSFER_ABI,
1758
- functionName: "TBD_DUAL_FUNCTION_NAME"
1771
+ unshield: {
1772
+ abi: parseAbi(["function decrypt(address to, uint128 value) public"]),
1773
+ functionName: "decrypt"
1774
+ },
1775
+ claims: {
1776
+ single: {
1777
+ abi: parseAbi(["function claimDecrypted(uint256 ctHash) public"]),
1778
+ functionName: "claimDecrypted"
1779
+ },
1780
+ all: {
1781
+ abi: parseAbi(["function claimAllDecrypted() public"]),
1782
+ functionName: "claimAllDecrypted"
1783
+ },
1784
+ query: {
1785
+ abi: [
1786
+ {
1787
+ inputs: [{ name: "user", type: "address" }],
1788
+ name: "getUserClaims",
1789
+ outputs: [
1790
+ {
1791
+ components: [
1792
+ { name: "ctHash", type: "uint256" },
1793
+ { name: "requestedAmount", type: "uint128" },
1794
+ { name: "decryptedAmount", type: "uint128" },
1795
+ { name: "decrypted", type: "bool" },
1796
+ { name: "to", type: "address" },
1797
+ { name: "claimed", type: "bool" }
1798
+ ],
1799
+ name: "",
1800
+ type: "tuple[]"
1801
+ }
1802
+ ],
1803
+ stateMutability: "view",
1804
+ type: "function"
1805
+ }
1806
+ ],
1807
+ functionName: "getUserClaims"
1808
+ }
1759
1809
  }
1760
1810
  };
1761
- var DUAL_SHIELD_ABI = parseAbi(["function shield(uint256 amount) public"]);
1762
- var DUAL_UNSHIELD_ABI = parseAbi(["function unshield(uint64 amount) public"]);
1763
- var DUAL_CLAIM_UNSHIELD_ABI = parseAbi(["function claimUnshielded() public"]);
1764
- var DUAL_GET_UNSHIELD_CLAIM_ABI = [
1765
- {
1766
- name: "getUserUnshieldClaim",
1767
- type: "function",
1768
- stateMutability: "view",
1769
- inputs: [{ name: "user", type: "address" }],
1770
- outputs: [
1771
- {
1772
- name: "",
1773
- type: "tuple",
1774
- components: [
1775
- { name: "ctHash", type: "uint256" },
1776
- { name: "requestedAmount", type: "uint64" },
1777
- { name: "decryptedAmount", type: "uint64" },
1778
- { name: "decrypted", type: "bool" },
1779
- { name: "claimed", type: "bool" }
1780
- ]
1781
- }
1782
- ]
1811
+
1812
+ // src/constants/confidentialTokenABIs.ts
1813
+ function getRequiredContractConfig(configs, confidentialityType, operation) {
1814
+ const config = configs[confidentialityType];
1815
+ if (!config) {
1816
+ throw new Error(`${operation} config is not defined for confidentialityType: ${confidentialityType}`);
1783
1817
  }
1784
- ];
1785
- var WRAPPED_ENCRYPT_ABI = parseAbi(["function encrypt(address to, uint128 value) public"]);
1786
- var WRAPPED_DECRYPT_ABI = parseAbi(["function decrypt(address to, uint128 value) public"]);
1787
- var WRAPPED_CLAIM_DECRYPTED_ABI = parseAbi(["function claimDecrypted(uint256 ctHash) public"]);
1788
- var WRAPPED_CLAIM_ALL_DECRYPTED_ABI = parseAbi(["function claimAllDecrypted() public"]);
1789
- var WRAPPED_GET_USER_CLAIMS_ABI = [
1790
- {
1791
- inputs: [{ name: "user", type: "address" }],
1792
- name: "getUserClaims",
1793
- outputs: [
1794
- {
1795
- components: [
1796
- { name: "ctHash", type: "uint256" },
1797
- { name: "requestedAmount", type: "uint128" },
1798
- { name: "decryptedAmount", type: "uint128" },
1799
- { name: "decrypted", type: "bool" },
1800
- { name: "to", type: "address" },
1801
- { name: "claimed", type: "bool" }
1802
- ],
1803
- name: "",
1804
- type: "tuple[]"
1805
- }
1806
- ],
1807
- stateMutability: "view",
1808
- type: "function"
1818
+ return config;
1819
+ }
1820
+ var TOKEN_CONFIDENTIALITY_CONTRACTS = {
1821
+ wrapped: WRAPPED_TOKEN_CONTRACTS
1822
+ };
1823
+ function getDefaultShieldApprovalContracts() {
1824
+ return WRAPPED_TOKEN_CONTRACTS.shield.approval;
1825
+ }
1826
+ function getContractsForType(confidentialityType) {
1827
+ return getRequiredContractConfig(TOKEN_CONFIDENTIALITY_CONTRACTS, confidentialityType, "token contracts");
1828
+ }
1829
+ function getTokenContractConfig(confidentialityType) {
1830
+ return getContractsForType(confidentialityType).confidentialBalance;
1831
+ }
1832
+ function getTransferContractConfig(confidentialityType) {
1833
+ return getContractsForType(confidentialityType).confidentialTransfer;
1834
+ }
1835
+ function getShieldContractConfig(confidentialityType) {
1836
+ const contracts = getContractsForType(confidentialityType).shield;
1837
+ if (!contracts) {
1838
+ throw new Error(`shield config is not defined for confidentialityType: ${confidentialityType}`);
1809
1839
  }
1810
- ];
1811
- var WRAPPED_ETH_ENCRYPT_ETH_ABI = parseAbi(["function encryptETH(address to) public payable"]);
1812
- var WRAPPED_ETH_ENCRYPT_WETH_ABI = parseAbi(["function encryptWETH(address to, uint128 value) public"]);
1813
- var SHIELD_ABIS = {
1814
- dual: {
1815
- abi: DUAL_SHIELD_ABI,
1816
- functionName: "shield"
1817
- },
1818
- wrapped: {
1819
- // TBD - needs approval flow and underlying token reference
1820
- abi: WRAPPED_ENCRYPT_ABI,
1821
- functionName: "encrypt"
1840
+ return contracts.erc20;
1841
+ }
1842
+ function getShieldAllowanceContractConfig() {
1843
+ return getDefaultShieldApprovalContracts().allowance;
1844
+ }
1845
+ function getShieldApproveContractConfig() {
1846
+ return getDefaultShieldApprovalContracts().approve;
1847
+ }
1848
+ function getShieldEthContractConfig(confidentialityType) {
1849
+ const contracts = getContractsForType(confidentialityType).shield;
1850
+ if (!contracts) {
1851
+ throw new Error(`shield ETH config is not defined for confidentialityType: ${confidentialityType}`);
1822
1852
  }
1823
- };
1824
- var UNSHIELD_ABIS = {
1825
- dual: {
1826
- abi: DUAL_UNSHIELD_ABI,
1827
- functionName: "unshield"
1828
- },
1829
- wrapped: {
1830
- // TBD - needs claim flow
1831
- abi: WRAPPED_DECRYPT_ABI,
1832
- functionName: "decrypt"
1853
+ return contracts.native;
1854
+ }
1855
+ function getUnshieldContractConfig(confidentialityType) {
1856
+ const contracts = getContractsForType(confidentialityType).unshield;
1857
+ if (!contracts) {
1858
+ throw new Error(`unshield config is not defined for confidentialityType: ${confidentialityType}`);
1833
1859
  }
1834
- };
1835
- var CLAIM_ABIS = {
1836
- dual: {
1837
- abi: DUAL_CLAIM_UNSHIELD_ABI,
1838
- functionName: "claimUnshielded"
1839
- },
1840
- wrapped: {
1841
- abi: WRAPPED_CLAIM_ALL_DECRYPTED_ABI,
1842
- functionName: "claimAllDecrypted"
1860
+ return contracts;
1861
+ }
1862
+ function getClaimContractConfig(confidentialityType) {
1863
+ const contracts = getContractsForType(confidentialityType).claims;
1864
+ if (!contracts) {
1865
+ throw new Error(`claim config is not defined for confidentialityType: ${confidentialityType}`);
1843
1866
  }
1844
- };
1845
- function getTokenContractConfig(confidentialityType) {
1846
- return CONFIDENTIAL_ABIS[confidentialityType];
1867
+ return contracts.all;
1868
+ }
1869
+ function getClaimableContractConfig(confidentialityType) {
1870
+ const contracts = getContractsForType(confidentialityType).claims;
1871
+ if (!contracts) {
1872
+ throw new Error(`claimable config is not defined for confidentialityType: ${confidentialityType}`);
1873
+ }
1874
+ return contracts.query;
1847
1875
  }
1848
1876
 
1849
1877
  // src/hooks/useCofheTokenLists.ts
1850
1878
  import "@tanstack/react-query";
1851
1879
  import { useMemo as useMemo4 } from "react";
1880
+ function isSupportedToken(token) {
1881
+ const confidentialityType = token.extensions?.fhenix?.confidentialityType;
1882
+ return isSupportedTokenConfidentialityType(confidentialityType);
1883
+ }
1852
1884
  function useCofheTokenLists({ chainId }, queryOptions) {
1853
1885
  const widgetConfig = useCofheContext().client.config.react;
1854
1886
  const tokensListsUrls = chainId ? widgetConfig.tokenLists?.[chainId] : [];
@@ -1870,7 +1902,7 @@ function useCofheTokenLists({ chainId }, queryOptions) {
1870
1902
  select: (data) => {
1871
1903
  return {
1872
1904
  ...data,
1873
- tokens: data.tokens.filter((token) => token.chainId === chainId)
1905
+ tokens: data.tokens.filter((token) => token.chainId === chainId && isSupportedToken(token))
1874
1906
  };
1875
1907
  },
1876
1908
  ...queryOptions
@@ -1962,7 +1994,8 @@ function constructPublicTokenBalanceQueryKeyForInvalidation({
1962
1994
  function getPublicTokenBalanceSource(token) {
1963
1995
  const confidentialityType = token?.extensions.fhenix.confidentialityType;
1964
1996
  const underlyingErc20 = token?.extensions.fhenix.erc20Pair;
1965
- const tokenToFetchBalanceFrom = confidentialityType === "wrapped" ? underlyingErc20 : confidentialityType === "dual" ? token : void 0;
1997
+ const publicBalanceSourceType = getPublicBalanceSourceType(confidentialityType);
1998
+ const tokenToFetchBalanceFrom = publicBalanceSourceType === "erc20Pair" ? underlyingErc20 : publicBalanceSourceType === "token" ? token : void 0;
1966
1999
  if (!tokenToFetchBalanceFrom) return void 0;
1967
2000
  return {
1968
2001
  address: tokenToFetchBalanceFrom.address,
@@ -2220,7 +2253,7 @@ var DEFAULT_UNSHIELD_CLAIM_SUMMARY = {
2220
2253
  hasPending: false
2221
2254
  };
2222
2255
  function isTokenConfidentialityTypeClaimable(type) {
2223
- return type === "dual" || type === "wrapped";
2256
+ return isTokenOperationSupported(type, "claimable");
2224
2257
  }
2225
2258
  async function fetchUnshieldClaimsSummary({
2226
2259
  publicClient,
@@ -2230,58 +2263,36 @@ async function fetchUnshieldClaimsSummary({
2230
2263
  queryKey,
2231
2264
  signal
2232
2265
  }) {
2233
- if (confidentialityType === "dual") {
2234
- const claim = await decryptionAwareReadContract({
2235
- publicClient,
2236
- queryKey,
2237
- signal,
2238
- readContractParams: {
2239
- address: token.address,
2240
- abi: DUAL_GET_UNSHIELD_CLAIM_ABI,
2241
- functionName: "getUserUnshieldClaim",
2242
- args: [accountAddress]
2243
- }
2244
- });
2245
- if (claim.ctHash === 0n || claim.claimed) return DEFAULT_UNSHIELD_CLAIM_SUMMARY;
2246
- return {
2247
- claimableAmount: claim.decrypted ? claim.decryptedAmount : 0n,
2248
- pendingAmount: claim.decrypted ? 0n : claim.requestedAmount,
2249
- hasClaimable: claim.decrypted && claim.decryptedAmount > 0n,
2250
- hasPending: !claim.decrypted
2251
- };
2252
- }
2253
- if (confidentialityType === "wrapped") {
2254
- const result = await decryptionAwareReadContract({
2255
- publicClient,
2256
- queryKey,
2257
- signal,
2258
- readContractParams: {
2259
- address: token.address,
2260
- abi: WRAPPED_GET_USER_CLAIMS_ABI,
2261
- functionName: "getUserClaims",
2262
- args: [accountAddress]
2266
+ const contractConfig = getClaimableContractConfig(confidentialityType);
2267
+ const result = await decryptionAwareReadContract({
2268
+ publicClient,
2269
+ queryKey,
2270
+ signal,
2271
+ readContractParams: {
2272
+ address: token.address,
2273
+ abi: contractConfig.abi,
2274
+ functionName: contractConfig.functionName,
2275
+ args: [accountAddress]
2276
+ }
2277
+ });
2278
+ const claims = result.filter((c) => !c.claimed);
2279
+ const { claimableAmount, pendingAmount } = claims.reduce(
2280
+ (acc, claim) => {
2281
+ if (claim.decrypted) {
2282
+ acc.claimableAmount += claim.decryptedAmount;
2283
+ } else {
2284
+ acc.pendingAmount += claim.requestedAmount;
2263
2285
  }
2264
- });
2265
- const claims = result.filter((c) => !c.claimed);
2266
- const { claimableAmount, pendingAmount } = claims.reduce(
2267
- (acc, claim) => {
2268
- if (claim.decrypted) {
2269
- acc.claimableAmount += claim.decryptedAmount;
2270
- } else {
2271
- acc.pendingAmount += claim.requestedAmount;
2272
- }
2273
- return acc;
2274
- },
2275
- { claimableAmount: 0n, pendingAmount: 0n }
2276
- );
2277
- return {
2278
- claimableAmount,
2279
- pendingAmount,
2280
- hasClaimable: claimableAmount > 0n,
2281
- hasPending: pendingAmount > 0n
2282
- };
2283
- }
2284
- return DEFAULT_UNSHIELD_CLAIM_SUMMARY;
2286
+ return acc;
2287
+ },
2288
+ { claimableAmount: 0n, pendingAmount: 0n }
2289
+ );
2290
+ return {
2291
+ claimableAmount,
2292
+ pendingAmount,
2293
+ hasClaimable: claimableAmount > 0n,
2294
+ hasPending: pendingAmount > 0n
2295
+ };
2285
2296
  }
2286
2297
  function useCofheTokenClaimable({ accountAddress: account, token }, queryOptions) {
2287
2298
  const publicClient = useCofhePublicClient();
@@ -2372,12 +2383,15 @@ function createTokenAllowanceQueryOptions(params) {
2372
2383
  (0, import_ts_essentials4.assert)(tokenAddress, "Token address is required to fetch token allowance");
2373
2384
  (0, import_ts_essentials4.assert)(ownerAddress, "Owner address is required to fetch token allowance");
2374
2385
  (0, import_ts_essentials4.assert)(spenderAddress, "Spender address is required to fetch token allowance");
2375
- return publicClient.readContract({
2386
+ const allowanceContract = getShieldAllowanceContractConfig();
2387
+ const allowance = await publicClient.readContract({
2376
2388
  address: tokenAddress,
2377
- abi: ERC20_ALLOWANCE_ABI,
2378
- functionName: "allowance",
2389
+ abi: allowanceContract.abi,
2390
+ functionName: allowanceContract.functionName,
2379
2391
  args: [ownerAddress, spenderAddress]
2380
2392
  });
2393
+ (0, import_ts_essentials4.assert)(typeof allowance === "bigint", "Token allowance must resolve to bigint");
2394
+ return allowance;
2381
2395
  },
2382
2396
  enabled,
2383
2397
  refetchOnMount: false,
@@ -2701,7 +2715,7 @@ var CopyButton = ({ text, size = 14, className }) => {
2701
2715
  setCopied(true);
2702
2716
  setTimeout(() => setCopied(false), 800);
2703
2717
  } catch (err) {
2704
- console.error("Failed to copy address:", err);
2718
+ cofheLogger.error("Failed to copy address:", err);
2705
2719
  }
2706
2720
  };
2707
2721
  return /* @__PURE__ */ jsx3(
@@ -2884,7 +2898,7 @@ function useTransactionGlobalToastsLifecycle() {
2884
2898
  }
2885
2899
  }
2886
2900
  }
2887
- console.error("____ Transaction submission failed for type:", transactionType, "with error:", error);
2901
+ cofheLogger.error("____ Transaction submission failed for type:", transactionType, "with error:", error);
2888
2902
  addToast(
2889
2903
  {
2890
2904
  variant: "error",
@@ -2929,7 +2943,7 @@ function useTransactionGlobalToastsLifecycle() {
2929
2943
  },
2930
2944
  // 2.b. tx receipt fetch failed
2931
2945
  onWatchReceiptFailure: (error, transaction) => {
2932
- console.error("____ Transaction receipt fetch failed for tx:", transaction, "with error:", error);
2946
+ cofheLogger.error("____ Transaction receipt fetch failed for tx:", transaction, "with error:", error);
2933
2947
  addToast(
2934
2948
  {
2935
2949
  variant: "error",
@@ -3134,7 +3148,7 @@ function useHandleInvalidations() {
3134
3148
  );
3135
3149
  }
3136
3150
  } else {
3137
- console.warn("No invalidation logic for transaction action type:", tx.actionType);
3151
+ cofheLogger.warn("No invalidation logic for transaction action type:", tx.actionType);
3138
3152
  }
3139
3153
  };
3140
3154
  return handleInvalidations;
@@ -3883,7 +3897,8 @@ function useCofheTokenTransfer(writeMutationOptions) {
3883
3897
  encryptAmountAndSendToken: ({ input, encryptionOptions }) => {
3884
3898
  const { token, to, amount, userAddress } = input;
3885
3899
  const { input: _ignoredInput, ...encryptionOpts } = encryptionOptions ?? {};
3886
- const contractConfig = TRANSFER_ABIS[token.extensions.fhenix.confidentialityType];
3900
+ assertTokenOperationSupported(token.extensions.fhenix.confidentialityType, "transfer");
3901
+ const contractConfig = getTransferContractConfig(token.extensions.fhenix.confidentialityType);
3887
3902
  return encryptAndWrite({
3888
3903
  params: {
3889
3904
  address: token.address,
@@ -3942,30 +3957,16 @@ function getCofheTokenShieldCallArgs(params) {
3942
3957
  if (!confidentialityType) {
3943
3958
  throw new Error("confidentialityType is required in token extensions");
3944
3959
  }
3945
- if (confidentialityType !== "dual" && confidentialityType !== "wrapped") {
3946
- throw new Error(`Shield not supported for confidentialityType: ${confidentialityType}`);
3947
- }
3948
- if (confidentialityType === "dual") {
3949
- const contractConfig = SHIELD_ABIS.dual;
3950
- return {
3951
- main: {
3952
- address: tokenAddress,
3953
- abi: contractConfig.abi,
3954
- functionName: contractConfig.functionName,
3955
- args: [amount],
3956
- account,
3957
- chain: void 0
3958
- }
3959
- };
3960
- }
3960
+ assertTokenOperationSupported(confidentialityType, "shield");
3961
3961
  const erc20PairAddress = token.extensions.fhenix.erc20Pair?.address;
3962
3962
  const isEth = erc20PairAddress?.toLowerCase() === ETH_ADDRESS_LOWERCASE;
3963
3963
  if (isEth) {
3964
+ const contractConfig = getShieldEthContractConfig(confidentialityType);
3964
3965
  return {
3965
3966
  main: {
3966
3967
  address: tokenAddress,
3967
- abi: WRAPPED_ETH_ENCRYPT_ETH_ABI,
3968
- functionName: "encryptETH",
3968
+ abi: contractConfig.abi,
3969
+ functionName: contractConfig.functionName,
3969
3970
  args: [account],
3970
3971
  value: amount,
3971
3972
  account,
@@ -3979,16 +3980,14 @@ function getCofheTokenShieldCallArgs(params) {
3979
3980
  return {
3980
3981
  approval: {
3981
3982
  address: erc20PairAddress,
3982
- abi: ERC20_APPROVE_ABI,
3983
- functionName: "approve",
3983
+ ...getShieldApproveContractConfig(),
3984
3984
  args: [tokenAddress, amount],
3985
3985
  account,
3986
3986
  chain: void 0
3987
3987
  },
3988
3988
  main: {
3989
+ ...getShieldContractConfig(confidentialityType),
3989
3990
  address: tokenAddress,
3990
- abi: WRAPPED_ENCRYPT_ABI,
3991
- functionName: "encrypt",
3992
3991
  args: [account, amount],
3993
3992
  account,
3994
3993
  chain: void 0
@@ -4018,47 +4017,35 @@ function useCofheTokenShield(options) {
4018
4017
  if (!walletClient.account) {
4019
4018
  throw new Error("Wallet account is required for token shield");
4020
4019
  }
4021
- if (confidentialityType !== "dual" && confidentialityType !== "wrapped") {
4022
- throw new Error(`Shield not supported for confidentialityType: ${confidentialityType}`);
4023
- }
4020
+ assertTokenOperationSupported(confidentialityType, "shield");
4024
4021
  let hash;
4025
- if (confidentialityType === "wrapped") {
4026
- const erc20PairAddress = input.token.extensions.fhenix.erc20Pair?.address;
4027
- const isEth = erc20PairAddress?.toLowerCase() === ETH_ADDRESS_LOWERCASE;
4028
- if (isEth) {
4029
- const { request } = await publicClient.simulateContract({
4030
- address: tokenAddress,
4031
- abi: WRAPPED_ETH_ENCRYPT_ETH_ABI,
4032
- functionName: "encryptETH",
4033
- args: [walletClient.account.address],
4034
- value: input.amount,
4035
- account: walletClient.account
4036
- });
4037
- hash = await walletClient.writeContract({ ...request, chain: void 0 });
4038
- } else {
4039
- if (!erc20PairAddress) {
4040
- throw new Error("erc20Pair address is required for wrapped ERC20 tokens");
4041
- }
4042
- input.onStatusChange?.("Please confirm shield in wallet...");
4043
- const { request: encryptRequest } = await publicClient.simulateContract({
4044
- address: tokenAddress,
4045
- abi: WRAPPED_ENCRYPT_ABI,
4046
- functionName: "encrypt",
4047
- args: [walletClient.account.address, input.amount],
4048
- account: walletClient.account
4049
- });
4050
- hash = await walletClient.writeContract({ ...encryptRequest, chain: void 0 });
4051
- }
4052
- } else {
4053
- const contractConfig = SHIELD_ABIS.dual;
4022
+ const erc20PairAddress = input.token.extensions.fhenix.erc20Pair?.address;
4023
+ const isEth = erc20PairAddress?.toLowerCase() === ETH_ADDRESS_LOWERCASE;
4024
+ if (isEth) {
4025
+ const contractConfig = getShieldEthContractConfig(confidentialityType);
4054
4026
  const { request } = await publicClient.simulateContract({
4055
4027
  address: tokenAddress,
4056
4028
  abi: contractConfig.abi,
4057
4029
  functionName: contractConfig.functionName,
4058
- args: [input.amount],
4030
+ args: [walletClient.account.address],
4031
+ value: input.amount,
4059
4032
  account: walletClient.account
4060
4033
  });
4061
4034
  hash = await walletClient.writeContract({ ...request, chain: void 0 });
4035
+ } else {
4036
+ if (!erc20PairAddress) {
4037
+ throw new Error("erc20Pair address is required for wrapped ERC20 tokens");
4038
+ }
4039
+ input.onStatusChange?.("Please confirm shield in wallet...");
4040
+ const contractConfig = getShieldContractConfig(confidentialityType);
4041
+ const { request: encryptRequest } = await publicClient.simulateContract({
4042
+ address: tokenAddress,
4043
+ abi: contractConfig.abi,
4044
+ functionName: contractConfig.functionName,
4045
+ args: [walletClient.account.address, input.amount],
4046
+ account: walletClient.account
4047
+ });
4048
+ hash = await walletClient.writeContract({ ...encryptRequest, chain: void 0 });
4062
4049
  }
4063
4050
  return hash;
4064
4051
  },
@@ -4188,29 +4175,13 @@ function getCofheTokenUnshieldCallArgs(params) {
4188
4175
  if (!confidentialityType) {
4189
4176
  throw new Error("confidentialityType is required in token extensions");
4190
4177
  }
4191
- if (confidentialityType !== "dual" && confidentialityType !== "wrapped") {
4192
- throw new Error(`Unshield not supported for confidentialityType: ${confidentialityType}`);
4193
- }
4194
- const contractConfig = UNSHIELD_ABIS[confidentialityType];
4195
- if (!contractConfig) {
4196
- throw new Error(`Unsupported confidentialityType for unshield: ${confidentialityType}`);
4197
- }
4198
- if (confidentialityType === "wrapped") {
4199
- return {
4200
- address: tokenAddress,
4201
- abi: contractConfig.abi,
4202
- functionName: contractConfig.functionName,
4203
- args: [account, rawAmount],
4204
- account,
4205
- chain: void 0
4206
- };
4207
- }
4208
- const amount = BigInt.asUintN(64, rawAmount);
4178
+ assertTokenOperationSupported(confidentialityType, "unshield");
4179
+ const contractConfig = getUnshieldContractConfig(confidentialityType);
4209
4180
  return {
4210
4181
  address: tokenAddress,
4211
4182
  abi: contractConfig.abi,
4212
4183
  functionName: contractConfig.functionName,
4213
- args: [amount],
4184
+ args: [account, rawAmount],
4214
4185
  account,
4215
4186
  chain: void 0
4216
4187
  };
@@ -4238,35 +4209,18 @@ function useCofheTokenUnshieldMutation(options) {
4238
4209
  if (!walletClient.account) {
4239
4210
  throw new Error("Wallet account is required for token unshield");
4240
4211
  }
4241
- if (confidentialityType !== "dual" && confidentialityType !== "wrapped") {
4242
- throw new Error(`Unshield not supported for confidentialityType: ${confidentialityType}`);
4243
- }
4244
- const contractConfig = UNSHIELD_ABIS[confidentialityType];
4245
- if (!contractConfig) {
4246
- throw new Error(`Unsupported confidentialityType for unshield: ${confidentialityType}`);
4247
- }
4212
+ assertTokenOperationSupported(confidentialityType, "unshield");
4213
+ const contractConfig = getUnshieldContractConfig(confidentialityType);
4248
4214
  let hash;
4249
4215
  input.onStatusChange?.("Please confirm in wallet...");
4250
- if (confidentialityType === "wrapped") {
4251
- const { request } = await publicClient.simulateContract({
4252
- address: tokenAddress,
4253
- abi: contractConfig.abi,
4254
- functionName: contractConfig.functionName,
4255
- args: [walletClient.account.address, input.amount],
4256
- account: walletClient.account
4257
- });
4258
- hash = await walletClient.writeContract({ ...request, chain: void 0 });
4259
- } else {
4260
- const amount = BigInt.asUintN(64, input.amount);
4261
- const { request } = await publicClient.simulateContract({
4262
- address: tokenAddress,
4263
- abi: contractConfig.abi,
4264
- functionName: contractConfig.functionName,
4265
- args: [amount],
4266
- account: walletClient.account
4267
- });
4268
- hash = await walletClient.writeContract({ ...request, chain: void 0 });
4269
- }
4216
+ const { request } = await publicClient.simulateContract({
4217
+ address: tokenAddress,
4218
+ abi: contractConfig.abi,
4219
+ functionName: contractConfig.functionName,
4220
+ args: [walletClient.account.address, input.amount],
4221
+ account: walletClient.account
4222
+ });
4223
+ hash = await walletClient.writeContract({ ...request, chain: void 0 });
4270
4224
  return hash;
4271
4225
  },
4272
4226
  onError: (error, variables, onMutateResult, context) => {
@@ -4323,13 +4277,8 @@ function getCofheTokenClaimUnshieldedCallArgs(params) {
4323
4277
  if (!confidentialityType) {
4324
4278
  throw new Error("confidentialityType is required in token extensions");
4325
4279
  }
4326
- if (confidentialityType !== "dual" && confidentialityType !== "wrapped") {
4327
- throw new Error(`Claim not supported for confidentialityType: ${confidentialityType}`);
4328
- }
4329
- const contractConfig = CLAIM_ABIS[confidentialityType];
4330
- if (!contractConfig) {
4331
- throw new Error(`Unsupported confidentialityType for claim: ${confidentialityType}`);
4332
- }
4280
+ assertTokenOperationSupported(confidentialityType, "claim");
4281
+ const contractConfig = getClaimContractConfig(confidentialityType);
4333
4282
  return {
4334
4283
  address: tokenAddress,
4335
4284
  abi: contractConfig.abi,
@@ -4362,13 +4311,8 @@ function useCofheTokenClaimUnshielded(options) {
4362
4311
  if (!walletClient.account) {
4363
4312
  throw new Error("Wallet account is required for claim");
4364
4313
  }
4365
- if (confidentialityType !== "dual" && confidentialityType !== "wrapped") {
4366
- throw new Error(`Claim not supported for confidentialityType: ${confidentialityType}`);
4367
- }
4368
- const contractConfig = CLAIM_ABIS[confidentialityType];
4369
- if (!contractConfig) {
4370
- throw new Error(`Unsupported confidentialityType for claim: ${confidentialityType}`);
4371
- }
4314
+ assertTokenOperationSupported(confidentialityType, "claim");
4315
+ const contractConfig = getClaimContractConfig(confidentialityType);
4372
4316
  const { request } = await publicClient.simulateContract({
4373
4317
  address: tokenAddress,
4374
4318
  abi: contractConfig.abi,
@@ -5198,7 +5142,7 @@ function useReceivePermit({ onSuccess, onError } = {}) {
5198
5142
  setImportedPermit(permit);
5199
5143
  setErrorMsg(null);
5200
5144
  } catch (e) {
5201
- console.error("Error parsing pasted permit data", e);
5145
+ cofheLogger.error("Error parsing pasted permit data", e);
5202
5146
  setImportedPermit(null);
5203
5147
  setErrorMsg(`Invalid permit data. Expected JSON.`);
5204
5148
  }
@@ -6173,7 +6117,7 @@ var AddressButton = ({ address, className, icon, showCopyIcon = true }) => {
6173
6117
  setCopied(true);
6174
6118
  setTimeout(() => setCopied(false), 2e3);
6175
6119
  } catch (err) {
6176
- console.error("Failed to copy address:", err);
6120
+ cofheLogger.error("Failed to copy address:", err);
6177
6121
  }
6178
6122
  };
6179
6123
  const truncatedAddress = truncateAddress(address) || "Not connected";
@@ -7747,7 +7691,7 @@ var ImportPermitPage = () => {
7747
7691
  title: "Failed to import permit",
7748
7692
  description: error.message
7749
7693
  });
7750
- console.error("Error importing permit", error);
7694
+ cofheLogger.error("Error importing permit", error);
7751
7695
  }
7752
7696
  });
7753
7697
  return /* @__PURE__ */ jsx45(
@@ -8079,7 +8023,7 @@ var SendPage = ({ token: _token }) => {
8079
8023
  onError: (error2) => {
8080
8024
  const errorMessage = cofheHumanizeViemError(error2) ?? (error2 instanceof Error ? error2.message : "Failed to send tokens");
8081
8025
  setError(errorMessage);
8082
- console.error("Send tx submit error:", error2);
8026
+ cofheLogger.error("Send tx submit error:", error2);
8083
8027
  },
8084
8028
  onMutate: () => {
8085
8029
  setError(null);
@@ -8350,7 +8294,7 @@ function useClaimUnshieldedWithLifecycle() {
8350
8294
  const errorMessage = cofheHumanizeViemError(error2) ?? (error2 instanceof Error ? error2.message : "Failed to claim unshielded tokens");
8351
8295
  setError(errorMessage);
8352
8296
  setStatus(null);
8353
- console.error("Claim tx submit error:", error2);
8297
+ cofheLogger.error("Claim tx submit error:", error2);
8354
8298
  }
8355
8299
  });
8356
8300
  const { isMining: isClaimingMining } = useOnceTransactionMined({
@@ -8409,7 +8353,7 @@ function useShieldWithLifecycle(token) {
8409
8353
  const errorMessage = cofheHumanizeViemError(error2) ?? (error2 instanceof Error ? error2.message : "Failed to shield tokens");
8410
8354
  setError(errorMessage);
8411
8355
  setStatus(null);
8412
- console.error("Shield tx submit error:", error2);
8356
+ cofheLogger.error("Shield tx submit error:", error2);
8413
8357
  }
8414
8358
  });
8415
8359
  const { tokenApprove, isApprovingMining } = useApproveWithLifecycle({
@@ -8558,7 +8502,7 @@ function useUnshieldWithLifecycle(token) {
8558
8502
  const errorMessage = cofheHumanizeViemError(error2) ?? (error2 instanceof Error ? error2.message : "Failed to unshield tokens");
8559
8503
  setError(errorMessage);
8560
8504
  setStatus(null);
8561
- console.error("Unshield tx submit error:", error2);
8505
+ cofheLogger.error("Unshield tx submit error:", error2);
8562
8506
  },
8563
8507
  onceMined: (transaction) => {
8564
8508
  if (transaction.status === "confirmed") {
@@ -8628,7 +8572,6 @@ function useUnshieldWithLifecycle(token) {
8628
8572
  primaryIcon: /* @__PURE__ */ jsx50(TbShieldMinus2, { className: "w-3 h-3" })
8629
8573
  };
8630
8574
  }
8631
- var shieldableTypes = /* @__PURE__ */ new Set(["dual", "wrapped"]);
8632
8575
  var ShieldPageV2 = ({ token: _token, defaultMode }) => {
8633
8576
  const [mode, setMode] = useState11(defaultMode ?? "shield");
8634
8577
  const [overriddenToken, setOverriddenToken] = useState11(null);
@@ -8754,9 +8697,15 @@ var ShieldAndUnshieldPageView = ({
8754
8697
  }) => {
8755
8698
  const { navigateBack } = usePortalNavigation();
8756
8699
  const { openModal } = usePortalModals();
8757
- const isShieldableToken = shieldableTypes.has(token.extensions.fhenix.confidentialityType);
8700
+ const isShieldableToken = isTokenOperationSupported(token.extensions.fhenix.confidentialityType, "shield");
8758
8701
  const { tokensWithExistingEncryptedBalance } = useCofheTokensWithExistingEncryptedBalances();
8759
8702
  const { tokensWithPublicBalances } = useTokensWithPublicBalances();
8703
+ const selectableTokens = useMemo31(
8704
+ () => (mode === "unshield" ? tokensWithExistingEncryptedBalance : tokensWithPublicBalances).filter(
8705
+ (candidate) => isTokenOperationSupported(candidate.extensions.fhenix.confidentialityType, mode)
8706
+ ),
8707
+ [mode, tokensWithExistingEncryptedBalance, tokensWithPublicBalances]
8708
+ );
8760
8709
  return /* @__PURE__ */ jsx50(
8761
8710
  PageContainer,
8762
8711
  {
@@ -8777,7 +8726,7 @@ var ShieldAndUnshieldPageView = ({
8777
8726
  {
8778
8727
  onClick: () => openModal("tokenList" /* TokenList */, {
8779
8728
  balanceType: mode === "shield" ? "public" /* Public */ : "confidential" /* Confidential */,
8780
- tokens: mode === "unshield" ? tokensWithExistingEncryptedBalance : tokensWithPublicBalances,
8729
+ tokens: selectableTokens,
8781
8730
  title: mode === "shield" ? "Select token to shield" : "Select token to unshield",
8782
8731
  onSelectToken: (token2) => setToken(token2)
8783
8732
  }),
@@ -8898,7 +8847,7 @@ function useApproveWithLifecycle({
8898
8847
  const errorMessage = cofheHumanizeViemError(error) ?? (error instanceof Error ? error.message : "Failed to approve tokens");
8899
8848
  setError(errorMessage);
8900
8849
  setStatus(null);
8901
- console.error("Approve tx submit error:", error);
8850
+ cofheLogger.error("Approve tx submit error:", error);
8902
8851
  }
8903
8852
  });
8904
8853
  const { isMining: isApprovingMining } = useOnceTransactionMined({
@@ -10431,7 +10380,7 @@ var CofheEncryptInput = ({
10431
10380
  setCopySuccess(false);
10432
10381
  }, 2e3);
10433
10382
  } catch (error) {
10434
- console.error("Failed to copy to clipboard:", error);
10383
+ cofheLogger.error("Failed to copy to clipboard:", error);
10435
10384
  }
10436
10385
  };
10437
10386
  const handleTypeSelect = async (type) => {
@@ -10450,13 +10399,13 @@ var CofheEncryptInput = ({
10450
10399
  onEncryptComplete?.(data);
10451
10400
  } catch (error) {
10452
10401
  const errorMessage2 = error instanceof Error ? error.message : "Encryption failed";
10453
- console.error("Encryption failed:", error);
10402
+ cofheLogger.error("Encryption failed:", error);
10454
10403
  onEncryptError?.(errorMessage2);
10455
10404
  }
10456
10405
  })();
10457
10406
  } catch (error) {
10458
10407
  const errorMessage2 = error instanceof Error ? error.message : "Encryption setup failed";
10459
- console.error("Encryption setup failed:", error);
10408
+ cofheLogger.error("Encryption setup failed:", error);
10460
10409
  onEncryptError?.(errorMessage2);
10461
10410
  }
10462
10411
  }