diff --git a/LICENSE b/LICENSE index 437803bdb..e548abd56 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright 2019-2024 Rosco Kalis +Copyright 2019-2025 Rosco Kalis Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: diff --git a/README.md b/README.md index 359bb8433..b8e7ec8dd 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ If you want to learn more about (unlimited) token approvals, I wrote an article ## Running locally ``` -git clone git@github.com:rkalis/revoke.cash.git +git clone git@github.com:RevokeCash/revoke.cash.git cd revoke.cash yarn yarn dev @@ -51,11 +51,11 @@ Adding a new network is relatively straightforward as you only need to change th #### Prerequisites -To add a new network, one of the following needs to be available: +To add a new network, **one** of the following needs to be available: - A (public or private) RPC endpoint that supports `eth_getLogs` requests for the entire history of the network. -- Support in [CovalentHQ](https://www.covalenthq.com/) for the network. -- A block explorer with an exposed API that is compatible with Etherscan's API (such as Blockscout). +- Or: Support in [CovalentHQ](https://www.covalenthq.com/) for the network. +- Or: A block explorer with an exposed API that is compatible with Etherscan's API (such as Blockscout). Also make sure that your network is listed in [ethereum-lists/chains](https://github.com/ethereum-lists/chains) (and that it has subsequently been included in [@revoke.cash/chains](https://github.com/RevokeCash/chains)). Besides the earlier requirements, we also require a publicly available RPC endpoint with rate limits that are not too restrictive. It is also helpful if your network is listed (with TVL and volume stats) on DeFiLlama, but this is not required. diff --git a/app/[locale]/private/approve/page.tsx b/app/[locale]/private/approve/page.tsx new file mode 100644 index 000000000..0c5fbb282 --- /dev/null +++ b/app/[locale]/private/approve/page.tsx @@ -0,0 +1,206 @@ +'use client'; + +import ContentPageLayout from 'app/layouts/ContentPageLayout'; +import Button from 'components/common/Button'; +import Input from 'components/common/Input'; +import { displayTransactionSubmittedToast } from 'components/common/TransactionSubmittedToast'; +import Select from 'components/common/select/Select'; +import { ERC20_ABI, ERC721_ABI } from 'lib/abis'; +import { writeContractUnlessExcessiveGas } from 'lib/utils'; +import { AllowanceType } from 'lib/utils/allowances'; +import { parseErrorMessage } from 'lib/utils/errors'; +import { permit2Approve } from 'lib/utils/permit2'; +import { useState } from 'react'; +import { toast } from 'react-toastify'; +import { isAddress } from 'viem'; +import { useAccount, usePublicClient } from 'wagmi'; +import { useWalletClient } from 'wagmi'; + +const ApprovePage = () => { + const { data: walletClient } = useWalletClient(); + const { address: account } = useAccount(); + const publicClient = usePublicClient()!; + const [allowanceType, setAllowanceType] = useState(AllowanceType.ERC20); + const [tokenAddress, setTokenAddress] = useState(''); + const [spenderAddress, setSpenderAddress] = useState(''); + const [permit2Address, setPermit2Address] = useState(''); + const [amount, setAmount] = useState(''); + const [tokenId, setTokenId] = useState(''); + const [expiration, setExpiration] = useState(''); + const options = Object.values(AllowanceType).map((type) => ({ value: type, label: type })); + + const handleApprove = async () => { + try { + if (!tokenAddress || !spenderAddress) { + throw new Error('Token address and spender address are required'); + } + + if (allowanceType === AllowanceType.ERC721_SINGLE && !tokenId) { + throw new Error('Token ID is required'); + } + + if (allowanceType === AllowanceType.PERMIT2 && (!permit2Address || !expiration || !isAddress(permit2Address))) { + throw new Error('Permit2 address and expiration are required'); + } + + if (!isAddress(tokenAddress) || !isAddress(spenderAddress)) { + throw new Error('Invalid address'); + } + + switch (allowanceType) { + case AllowanceType.ERC20: { + if (!amount) { + throw new Error('Amount is required'); + } + + const tx = await writeContractUnlessExcessiveGas(publicClient, walletClient!, { + address: tokenAddress, + account: account!, + chain: walletClient!.chain!, + abi: ERC20_ABI, + functionName: 'approve', + args: [spenderAddress, BigInt(amount)], + }); + + displayTransactionSubmittedToast(walletClient!.chain!.id, tx); + break; + } + case AllowanceType.PERMIT2: { + if (!amount || !expiration || !permit2Address || !isAddress(permit2Address)) { + throw new Error('Amount, expiration, and permit2 address are required'); + } + + const tokenContract = { + address: tokenAddress, + publicClient, + abi: ERC20_ABI, + }; + + const tx = await permit2Approve( + permit2Address, + walletClient!, + tokenContract, + spenderAddress, + BigInt(amount), + Number(expiration), + ); + + displayTransactionSubmittedToast(walletClient!.chain!.id, tx); + break; + } + case AllowanceType.ERC721_SINGLE: { + if (!tokenId) { + throw new Error('Token ID is required'); + } + + const tx = await writeContractUnlessExcessiveGas(publicClient, walletClient!, { + address: tokenAddress, + account: account!, + chain: walletClient!.chain!, + abi: ERC721_ABI, + functionName: 'approve', + args: [spenderAddress, BigInt(tokenId)], + }); + + displayTransactionSubmittedToast(walletClient!.chain!.id, tx); + break; + } + case AllowanceType.ERC721_ALL: { + const tx = await writeContractUnlessExcessiveGas(publicClient, walletClient!, { + address: tokenAddress, + account: account!, + chain: walletClient!.chain!, + abi: ERC721_ABI, + functionName: 'setApprovalForAll', + args: [spenderAddress, true], + }); + + displayTransactionSubmittedToast(walletClient!.chain!.id, tx); + break; + } + } + } catch (e) { + toast.error(e instanceof Error ? parseErrorMessage(e) : 'An error occurred'); + } + }; + + return ( + +
+

Approve Arbitrary Contracts

+

For testing purposes only.

+
+
+ Approval Type + setTokenAddress(e.target.value)} + /> +
+
+ Spender Address + setSpenderAddress(e.target.value)} + /> +
+ {allowanceType === AllowanceType.PERMIT2 && ( +
+ Permit2 Address + setPermit2Address(e.target.value)} + /> +
+ )} + {(allowanceType === AllowanceType.ERC20 || allowanceType === AllowanceType.PERMIT2) && ( +
+ Amount + setAmount(e.target.value)} /> +
+ )} + {allowanceType === AllowanceType.ERC721_SINGLE && ( +
+ Token ID + setTokenId(e.target.value)} /> +
+ )} + {allowanceType === AllowanceType.PERMIT2 && ( +
+ Expiration + setExpiration(e.target.value)} + /> +
+ )} +
+ +
+
+ ); +}; + +export default ApprovePage; diff --git a/app/robots.txt b/app/robots.txt index f340b70e2..8584d7834 100644 --- a/app/robots.txt +++ b/app/robots.txt @@ -1,4 +1,5 @@ User-agent: * Allow: / +Disallow: /private/ Sitemap: https://revoke.cash/sitemap.xml diff --git a/components/allowances/controls/batch-revoke/BatchRevokeControls.tsx b/components/allowances/controls/batch-revoke/BatchRevokeControls.tsx index afe8a3161..2c61107bb 100644 --- a/components/allowances/controls/batch-revoke/BatchRevokeControls.tsx +++ b/components/allowances/controls/batch-revoke/BatchRevokeControls.tsx @@ -2,8 +2,7 @@ import Button from 'components/common/Button'; import TipSection from 'components/common/donate/TipSection'; import { useDonate } from 'lib/hooks/ethereum/useDonate'; import { useAddressPageContext } from 'lib/hooks/page-context/AddressPageContext'; -import { TokenAllowanceData } from 'lib/utils/allowances'; -import { analytics } from 'lib/utils/analytics'; +import type { TokenAllowanceData } from 'lib/utils/allowances'; import { useTranslations } from 'next-intl'; import { useState } from 'react'; import ControlsWrapper from '../ControlsWrapper'; @@ -13,38 +12,16 @@ interface Props { isRevoking: boolean; isAllConfirmed: boolean; setOpen: (open: boolean) => void; - revoke: () => Promise; + revoke: (tipAmount: string) => Promise; } const BatchRevokeControls = ({ selectedAllowances, isRevoking, isAllConfirmed, setOpen, revoke }: Props) => { const t = useTranslations(); const { address, selectedChainId } = useAddressPageContext(); + const { defaultAmount, nativeToken } = useDonate(selectedChainId, 'batch-revoke-tip'); - const { donate, nativeToken, defaultAmount } = useDonate(selectedChainId, 'batch-revoke-tip'); const [tipAmount, setTipAmount] = useState(null); - const revokeAndTip = async (tipAmount: string | null) => { - if (!tipAmount) throw new Error('Tip amount is required'); - - const getTipSelection = () => { - if (tipAmount === '0') return 'none'; - if (Number(tipAmount) < Number(defaultAmount)) return 'low'; - if (Number(tipAmount) > Number(defaultAmount)) return 'high'; - return 'mid'; - }; - - analytics.track('Batch Revoked', { - chainId: selectedChainId, - address, - allowances: selectedAllowances.length, - amount: tipAmount, - tipSelection: getTipSelection(), - }); - - await revoke(); - await donate(tipAmount); - }; - const getButtonText = () => { if (isRevoking) return t('common.buttons.revoking'); if (isAllConfirmed) return t('common.buttons.close'); @@ -53,7 +30,10 @@ const BatchRevokeControls = ({ selectedAllowances, isRevoking, isAllConfirmed, s const getButtonAction = () => { if (isAllConfirmed) return () => setOpen(false); - return () => revokeAndTip(tipAmount); + return async () => { + if (!tipAmount) throw new Error('Tip amount is required'); + await revoke(tipAmount); + }; }; return ( diff --git a/components/header/WalletIndicatorDropdown.tsx b/components/header/WalletIndicatorDropdown.tsx index b20ec535c..d19c79828 100644 --- a/components/header/WalletIndicatorDropdown.tsx +++ b/components/header/WalletIndicatorDropdown.tsx @@ -14,7 +14,7 @@ interface Props { const WalletIndicatorDropdown = ({ size, style, className }: Props) => { const t = useTranslations(); - const { address: account } = useAccount(); + const { address: account, chainId } = useAccount(); const { domainName } = useNameLookup(account); const { disconnect } = useDisconnect(); @@ -22,7 +22,7 @@ const WalletIndicatorDropdown = ({ size, style, className }: Props) => {
{account ? ( - + {t('common.buttons.my_allowances')} disconnect()}>{t('common.buttons.disconnect')} diff --git a/components/signatures/cells/CancelPermitCell.tsx b/components/signatures/cells/CancelPermitCell.tsx index 643e02e2f..8fbd075c7 100644 --- a/components/signatures/cells/CancelPermitCell.tsx +++ b/components/signatures/cells/CancelPermitCell.tsx @@ -21,8 +21,8 @@ const CancelPermitCell = ({ token, onCancel }: Props) => { const { address, selectedChainId } = useAddressPageContext(); const handleTransaction = useHandleTransaction(selectedChainId); - const sendCancelTransaction = async (): Promise => { - if (isErc721Contract(token.contract)) return; + const sendCancelTransaction = async (): Promise => { + if (isErc721Contract(token.contract)) throw new Error('Cannot cancel ERC721 tokens'); const hash = await permit(walletClient!, token.contract, DUMMY_ADDRESS, 0n); analytics.track('Cancelled Permit Signatures', { diff --git a/content/en/exploits/short/moby.md b/content/en/exploits/short/moby.md new file mode 100644 index 000000000..e9e76e004 --- /dev/null +++ b/content/en/exploits/short/moby.md @@ -0,0 +1 @@ +Close to $2.5m was stolen from DeFi platform Moby Trade and its users. The attacker was able to gain access to the protocol's admin keys, which they used to execute malicious upgrades on the protocol's contracts - allowing them to drain the wallets of any users that had active token approvals for the protocol. Close to $1.5m was recovered by the protocol's team and SEAL911, resulting in a loss of $1m for the users. diff --git a/cypress/e2e/chains.cy.ts b/cypress/e2e/chains.cy.ts index eeacb5b2a..e735af2ec 100644 --- a/cypress/e2e/chains.cy.ts +++ b/cypress/e2e/chains.cy.ts @@ -102,6 +102,8 @@ const TEST_ADDRESSES = { [ChainId.Shibarium]: '0x8fA1F2969082a8d141DA3f0DD06D308C783fe7bB', [ChainId.Shiden]: '0xD377cFFCc52C16bF6e9840E77F78F42Ddb946568', [ChainId.ShimmerEVM]: '0xAc4682eF9fE8c62980cd8bd8d8a3Bb100FD652e7', + [ChainId.Soneium]: '0x351F34efCE7BBF960da2ca61130a89bF41471047', + [ChainId.SonicMainnet]: '0xA93093fc1D0343298966E1F971fAE10a7a629296', [ChainId['SongbirdCanary-Network']]: '0x4E8De52271D3bE18cC972af892198103C1e6AfE8', [ChainId.StoryOdysseyTestnet]: '0x2343bcb7f864D6e2880b3510492dc3da33E75f14', [ChainId.SyscoinMainnet]: '0xc594AE94f7C98d759Ed4c792F5DbFB7285184044', @@ -122,7 +124,7 @@ const TEST_ADDRESSES = { [ChainId.ZkSyncMainnet]: '0x82FdF36736f3f8eE6f04Ab96eA32213c8d826FaA', [ChainId.Zora]: '0x061EFb2DF7767D6e63529BA99394037d4dCa39D6', // Testnets - [ChainId.AbstractTestnet]: '0xe126b3E5d052f1F575828f61fEBA4f4f2603652a', + [ChainId.AbstractSepoliaTestnet]: '0xe126b3E5d052f1F575828f61fEBA4f4f2603652a', [ChainId.Amoy]: '0x57BD9b2E821d2bF1f8136026ba3A29848eff9e47', [ChainId.ArbitrumSepolia]: '0xDd3287043493E0a08d2B348397554096728B459c', [ChainId.AvalancheFujiTestnet]: '0x4D915A2f0a2c94b159b69D36bc26338E0ef8E3F6', diff --git a/lib/api/logs/EtherscanEventGetter.ts b/lib/api/logs/EtherscanEventGetter.ts index bd723535e..1f071b89f 100644 --- a/lib/api/logs/EtherscanEventGetter.ts +++ b/lib/api/logs/EtherscanEventGetter.ts @@ -121,9 +121,9 @@ const formatEtherscanEvent = (etherscanLog: any) => ({ topics: etherscanLog.topics.filter((topic: string) => !isNullish(topic)), data: etherscanLog.data, transactionHash: etherscanLog.transactionHash, - blockNumber: Number.parseInt(etherscanLog.blockNumber, 16), - transactionIndex: Number.parseInt(etherscanLog.transactionIndex, 16), - logIndex: Number.parseInt(etherscanLog.logIndex, 16), + blockNumber: Number.parseInt(etherscanLog.blockNumber, 16) || 0, + transactionIndex: Number.parseInt(etherscanLog.transactionIndex, 16) || 0, + logIndex: Number.parseInt(etherscanLog.logIndex, 16) || 0, timestamp: Number.parseInt(etherscanLog.timeStamp, 16), }); diff --git a/lib/chains/Chain.ts b/lib/chains/Chain.ts index 6ce665482..8dc90d1ce 100644 --- a/lib/chains/Chain.ts +++ b/lib/chains/Chain.ts @@ -125,8 +125,9 @@ export class Chain { return this.options.infoUrl ?? getChain(mainnetChainId)?.infoURL ?? getChain(this.chainId)?.infoURL; } - getNativeToken(): string | undefined { - return this.options.nativeToken ?? getChain(this.chainId)?.nativeCurrency?.symbol; + // Note: we run tests to make sure that this is configured correctly for all chains (which is why we override the type) + getNativeToken(): string { + return (this.options.nativeToken ?? getChain(this.chainId)?.nativeCurrency?.symbol) as string; } getEtherscanCompatibleApiUrl(): string | undefined { diff --git a/lib/hooks/ethereum/EthereumProvider.tsx b/lib/hooks/ethereum/EthereumProvider.tsx index cd1d60a3b..26205997b 100644 --- a/lib/hooks/ethereum/EthereumProvider.tsx +++ b/lib/hooks/ethereum/EthereumProvider.tsx @@ -1,5 +1,6 @@ 'use client'; +import { abstractWalletConnector } from '@abstract-foundation/agw-react/connectors'; import { useCsrRouter } from 'lib/i18n/csr-navigation'; import { usePathname } from 'lib/i18n/navigation'; import { ORDERED_CHAINS, createViemPublicClientForChain, getViemChainConfig } from 'lib/utils/chains'; @@ -26,6 +27,7 @@ export const connectors = [ }, }), coinbaseWallet({ appName: 'Revoke.cash' }), + abstractWalletConnector(), ]; export const wagmiConfig = createConfig({ diff --git a/lib/hooks/ethereum/useDonate.tsx b/lib/hooks/ethereum/useDonate.tsx index 5389fad75..fe93eec20 100644 --- a/lib/hooks/ethereum/useDonate.tsx +++ b/lib/hooks/ethereum/useDonate.tsx @@ -3,10 +3,10 @@ import type { DonateButtonType } from 'components/common/donate/DonateModal'; import { DONATION_ADDRESS } from 'lib/constants'; import { type TransactionSubmitted, TransactionType } from 'lib/interfaces'; -import { getWalletAddress, waitForTransactionConfirmation } from 'lib/utils'; +import { waitForTransactionConfirmation } from 'lib/utils'; import { analytics } from 'lib/utils/analytics'; -import { getChainName, getChainNativeToken, getDefaultDonationAmount } from 'lib/utils/chains'; -import { parseEther } from 'viem'; +import { type DocumentedChainId, getChainName, getChainNativeToken, getDefaultDonationAmount } from 'lib/utils/chains'; +import { type SendTransactionParameters, parseEther } from 'viem'; import { usePublicClient, useWalletClient } from 'wagmi'; import { useHandleTransaction } from './useHandleTransaction'; @@ -17,39 +17,59 @@ export const useDonate = (chainId: number, type: DonateButtonType) => { const publicClient = usePublicClient({ chainId })!; const handleTransaction = useHandleTransaction(chainId); - const sendDonation = async (amount: string): Promise => { + const sendDonation = async (amount: string): Promise => { if (!walletClient) { throw new Error('Please connect your web3 wallet to a supported network'); } - if (!amount || Number(amount) === 0) return; + if (!amount || Number(amount) === 0) { + throw new Error('User rejected donation'); + } + + const hash = await walletClient.sendTransaction(await prepareDonate(amount)); + + return { hash, confirmation: waitForTransactionConfirmation(hash, publicClient) }; + }; - const hash = await walletClient.sendTransaction({ - account: await getWalletAddress(walletClient), + const prepareDonate = async (amount: string): Promise => { + if (!walletClient) { + throw new Error('Please connect your web3 wallet to a supported network'); + } + + return { + account: walletClient.account!, to: DONATION_ADDRESS, value: parseEther(amount), chain: walletClient.chain, kzg: undefined, // TODO: Idk why I need to add this, but since Viem v2 it's required 😅 - }); - - return { hash, confirmation: waitForTransactionConfirmation(hash, publicClient) }; + }; }; const donate = async (amount: string): Promise => { const transactionSubmitted = await handleTransaction(sendDonation(amount), TransactionType.DONATE); - - if (transactionSubmitted) { - analytics.track('Donated', { - chainId, - chainName: getChainName(chainId), - nativeToken, - amount: Number(amount), - type, - }); - } - + if (transactionSubmitted) trackDonate(chainId, amount, type); return transactionSubmitted; }; - return { donate, nativeToken, defaultAmount }; + return { prepareDonate, donate, nativeToken, defaultAmount }; +}; + +export const getTipSelection = (chainId: DocumentedChainId, amount: string) => { + const defaultAmount = getDefaultDonationAmount(getChainNativeToken(chainId)); + if (Number(amount) === 0) return 'none'; + if (Number(amount) < Number(defaultAmount)) return 'low'; + if (Number(amount) > Number(defaultAmount)) return 'high'; + return 'mid'; +}; + +export const trackDonate = (chainId: DocumentedChainId, amount: string, type: DonateButtonType) => { + if (!Number(amount)) return; + + analytics.track('Donated', { + chainId, + chainName: getChainName(chainId), + nativeToken: getChainNativeToken(chainId), + amount: Number(amount), + type, + }); }; diff --git a/lib/hooks/ethereum/useHandleTransaction.tsx b/lib/hooks/ethereum/useHandleTransaction.tsx index d71b2ce23..d4f54c005 100644 --- a/lib/hooks/ethereum/useHandleTransaction.tsx +++ b/lib/hooks/ethereum/useHandleTransaction.tsx @@ -36,14 +36,11 @@ export const useHandleTransaction = (chainId: number) => { return void toast.info(t('common.toasts.transaction_failed', { message })); }; - const handleTransaction = async ( - transactionPromise: Promise, - type: TransactionType, - ) => { + const handleTransaction = async (transactionPromise: Promise, type: TransactionType) => { try { const transaction = await transactionPromise; - if (transaction?.hash) { + if (transaction.hash) { if (type === TransactionType.DONATE) { toast.info(t('common.toasts.donation_sent')); } else { diff --git a/lib/hooks/ethereum/useRevokeBatch.tsx b/lib/hooks/ethereum/useRevokeBatch.tsx index bdcc8ff93..d31a49e94 100644 --- a/lib/hooks/ethereum/useRevokeBatch.tsx +++ b/lib/hooks/ethereum/useRevokeBatch.tsx @@ -1,23 +1,22 @@ 'use client'; -import { - type OnUpdate, - type TokenAllowanceData, - getAllowanceKey, - revokeAllowance, - wrapRevoke, -} from 'lib/utils/allowances'; +import { type OnUpdate, type TokenAllowanceData, getAllowanceKey } from 'lib/utils/allowances'; +import { walletSupportsEip5792 } from 'lib/utils/eip5792'; import PQueue from 'p-queue'; import { useCallback, useEffect, useMemo } from 'react'; import { useAsyncCallback } from 'react-async-hook'; import { useWalletClient } from 'wagmi'; import { useTransactionStore } from '../../stores/transaction-store'; +import { useRevokeBatchEip5792 } from './useRevokeBatchEip5792'; +import { useRevokeBatchQueuedTransactions } from './useRevokeBatchQueuedTransactions'; // Limit to 50 concurrent revokes to avoid wallets crashing const REVOKE_QUEUE = new PQueue({ interval: 100, intervalCap: 1, concurrency: 50 }); export const useRevokeBatch = (allowances: TokenAllowanceData[], onUpdate: OnUpdate) => { const { results, getTransaction, updateTransaction } = useTransactionStore(); + const revokeEip5792 = useRevokeBatchEip5792(allowances, onUpdate); + const revokeQueuedTransactions = useRevokeBatchQueuedTransactions(allowances, onUpdate); const { data: walletClient } = useWalletClient(); @@ -27,24 +26,12 @@ export const useRevokeBatch = (allowances: TokenAllowanceData[], onUpdate: OnUpd }); }, [allowances]); - const { execute: revoke, loading: isSubmitting } = useAsyncCallback(async () => { - await Promise.race([ - Promise.all( - allowances.map(async (allowance) => { - // Skip if already confirmed or pending - if (['confirmed', 'pending'].includes(getTransaction(allowance).status)) return; - - const revoke = wrapRevoke( - allowance, - () => revokeAllowance(walletClient!, allowance, onUpdate), - updateTransaction, - ); - - await REVOKE_QUEUE.add(revoke); - }), - ), - REVOKE_QUEUE.onIdle(), - ]); + const { execute: revoke, loading: isSubmitting } = useAsyncCallback(async (tipAmount: string): Promise => { + if (await walletSupportsEip5792(walletClient!)) { + await revokeEip5792(REVOKE_QUEUE, tipAmount); + } else { + await revokeQueuedTransactions(REVOKE_QUEUE, tipAmount); + } }); const pause = useCallback(() => { diff --git a/lib/hooks/ethereum/useRevokeBatchEip5792.tsx b/lib/hooks/ethereum/useRevokeBatchEip5792.tsx new file mode 100644 index 000000000..5f56e6d61 --- /dev/null +++ b/lib/hooks/ethereum/useRevokeBatchEip5792.tsx @@ -0,0 +1,115 @@ +'use client'; + +import { throwIfExcessiveGas } from 'lib/utils'; +import { type OnUpdate, type TokenAllowanceData, prepareRevokeAllowance, wrapRevoke } from 'lib/utils/allowances'; +import { trackBatchRevoke } from 'lib/utils/batch-revoke'; +import { + type Eip5792Call, + mapContractTransactionRequestToEip5792Call, + mapTransactionRequestToEip5792Call, + mapWalletCallReceiptToTransactionSubmitted, + pollForCallsReceipts, +} from 'lib/utils/eip5792'; +import type PQueue from 'p-queue'; +import type { EstimateContractGasParameters } from 'viem'; +import { eip5792Actions } from 'viem/experimental'; +import { useWalletClient } from 'wagmi'; +import { useTransactionStore } from '../../stores/transaction-store'; +import { useAddressPageContext } from '../page-context/AddressPageContext'; +import { trackDonate, useDonate } from './useDonate'; + +export const useRevokeBatchEip5792 = (allowances: TokenAllowanceData[], onUpdate: OnUpdate) => { + const { getTransaction, updateTransaction } = useTransactionStore(); + const { address, selectedChainId } = useAddressPageContext(); + const { prepareDonate } = useDonate(selectedChainId, 'batch-revoke-tip'); + + const { data: walletClient } = useWalletClient(); + + const revoke = async (REVOKE_QUEUE: PQueue, tipAmount: string) => { + if (!walletClient) { + throw new Error('Please connect your web3 wallet to a supported network'); + } + + const extendedWalletClient = walletClient.extend(eip5792Actions()); + + const callsSettled = await Promise.allSettled( + allowances.map(async (allowance): Promise => { + const transactionRequest = await prepareRevokeAllowance(walletClient, allowance); + + const publicClient = allowance.contract.publicClient; + const estimatedGas = + transactionRequest.gas ?? + (await publicClient.estimateContractGas(transactionRequest as EstimateContractGasParameters)); + + throwIfExcessiveGas(selectedChainId, allowance.owner, estimatedGas); + + return mapContractTransactionRequestToEip5792Call(transactionRequest); + }), + ); + + const calls = callsSettled.filter((call) => call.status === 'fulfilled').map((call) => call.value); + + if (tipAmount && Number(tipAmount) > 0 && calls.length > 0) { + const donateTransaction = await prepareDonate(tipAmount); + calls.push(mapTransactionRequestToEip5792Call(donateTransaction)); + } + + const batchPromise = extendedWalletClient.sendCalls({ + account: walletClient.account!, + chain: walletClient.chain!, + calls, + }); + + await Promise.race([ + Promise.all( + allowances.map(async (allowance, index) => { + // Skip if already confirmed or pending + if (['confirmed', 'pending'].includes(getTransaction(allowance).status)) return; + + const revoke = wrapRevoke( + allowance, + async () => { + // Check whether the revoke failed *before* even making it into wallet_sendCalls + const settlement = callsSettled[index]; + if (settlement.status === 'rejected') throw settlement.reason; + + const id = await batchPromise; + const { receipts } = await pollForCallsReceipts(id, extendedWalletClient); + + if (receipts?.length === 1) { + return mapWalletCallReceiptToTransactionSubmitted(allowance, receipts[0], onUpdate); + } + + const callIndex = getCallIndex(index, callsSettled); + + if (!receipts?.[callIndex]) { + console.log('receipts', receipts); + throw new Error('An error occurred related to EIP5792 batch calls'); + } + + return mapWalletCallReceiptToTransactionSubmitted(allowance, receipts[callIndex], onUpdate); + }, + updateTransaction, + ); + + await REVOKE_QUEUE.add(revoke); + }), + ), + REVOKE_QUEUE.onIdle(), + ]); + + trackBatchRevoke(selectedChainId, address, allowances, tipAmount, 'eip5792'); + trackDonate(selectedChainId, tipAmount, 'batch-revoke-tip'); + }; + + return revoke; +}; + +const getCallIndex = (index: number, callsSettled: PromiseSettledResult[]): number => { + const numberOfFailedCallsBeforeIndex = callsSettled + .slice(0, index) + .filter((call) => call.status === 'rejected').length; + + const adjustedIndex = index - numberOfFailedCallsBeforeIndex; + return adjustedIndex; +}; diff --git a/lib/hooks/ethereum/useRevokeBatchQueuedTransactions.tsx b/lib/hooks/ethereum/useRevokeBatchQueuedTransactions.tsx new file mode 100644 index 000000000..160e7c995 --- /dev/null +++ b/lib/hooks/ethereum/useRevokeBatchQueuedTransactions.tsx @@ -0,0 +1,41 @@ +'use client'; + +import { type OnUpdate, type TokenAllowanceData, revokeAllowance, wrapRevoke } from 'lib/utils/allowances'; +import { trackBatchRevoke } from 'lib/utils/batch-revoke'; +import type PQueue from 'p-queue'; +import { useWalletClient } from 'wagmi'; +import { useTransactionStore } from '../../stores/transaction-store'; +import { useAddressPageContext } from '../page-context/AddressPageContext'; +import { useDonate } from './useDonate'; + +export const useRevokeBatchQueuedTransactions = (allowances: TokenAllowanceData[], onUpdate: OnUpdate) => { + const { getTransaction, updateTransaction } = useTransactionStore(); + const { address, selectedChainId } = useAddressPageContext(); + const { donate } = useDonate(selectedChainId, 'batch-revoke-tip'); + const { data: walletClient } = useWalletClient(); + + const revoke = async (REVOKE_QUEUE: PQueue, tipAmount: string) => { + await Promise.race([ + Promise.all( + allowances.map(async (allowance) => { + // Skip if already confirmed or pending + if (['confirmed', 'pending'].includes(getTransaction(allowance).status)) return; + + const revoke = wrapRevoke( + allowance, + () => revokeAllowance(walletClient!, allowance, onUpdate), + updateTransaction, + ); + + await REVOKE_QUEUE.add(revoke); + }), + ), + REVOKE_QUEUE.onIdle(), + ]); + + trackBatchRevoke(selectedChainId, address, allowances, tipAmount, 'queued'); + await donate(tipAmount); + }; + + return revoke; +}; diff --git a/lib/i18n/csr-navigation.tsx b/lib/i18n/csr-navigation.tsx index 1fe7a3a41..4767eea18 100644 --- a/lib/i18n/csr-navigation.tsx +++ b/lib/i18n/csr-navigation.tsx @@ -21,8 +21,8 @@ const getHrefRetainingCurrentSearchParams = ( const [path, search] = hrefString.split('?'); const mergedSearchParams = new URLSearchParams({ - ...Object.fromEntries(searchParamsToRetain), ...Object.fromEntries(new URLSearchParams(search)), + ...Object.fromEntries(searchParamsToRetain), }); return `${path}?${mergedSearchParams.toString()}`; }; diff --git a/lib/utils/allowances.ts b/lib/utils/allowances.ts index 10a144e33..96002de09 100644 --- a/lib/utils/allowances.ts +++ b/lib/utils/allowances.ts @@ -317,8 +317,8 @@ export const revokeAllowance = async ( walletClient: WalletClient, allowance: TokenAllowanceData, onUpdate: OnUpdate, -): Promise => { - if (!allowance.payload) return undefined; +): Promise => { + if (!allowance.payload) throw new Error('Cannot revoke undefined allowance'); if (isErc721Contract(allowance.contract)) { return revokeErc721Allowance(walletClient, allowance, onUpdate); @@ -334,7 +334,6 @@ export const revokeErc721Allowance = async ( ): Promise => { const transactionRequest = await prepareRevokeErc721Allowance(walletClient, allowance); const hash = await writeContractUnlessExcessiveGas(allowance.contract.publicClient, walletClient, transactionRequest); - trackTransaction(allowance, hash); const waitForConfirmation = async () => { const transactionReceipt = await waitForTransactionConfirmation(hash, allowance.contract.publicClient); @@ -349,7 +348,7 @@ export const revokeErc20Allowance = async ( walletClient: WalletClient, allowance: TokenAllowanceData, onUpdate: OnUpdate, -): Promise => { +): Promise => { return updateErc20Allowance(walletClient, allowance, '0', onUpdate); }; @@ -358,13 +357,17 @@ export const updateErc20Allowance = async ( allowance: TokenAllowanceData, newAmount: string, onUpdate: OnUpdate, -): Promise => { +): Promise => { const newAmountParsed = parseFixedPointBigInt(newAmount, allowance.metadata.decimals); const transactionRequest = await prepareUpdateErc20Allowance(walletClient, allowance, newAmountParsed); - if (!transactionRequest) return; const hash = await writeContractUnlessExcessiveGas(allowance.contract.publicClient, walletClient, transactionRequest); - trackTransaction(allowance, hash, newAmount); + + // Note that tracking happens in the wrapRevoke function already so we only need to track if the allowance is not being revoked + // TODO: Merge tracking with wrapRevoke + if (newAmount !== '0') { + trackRevokeTransaction(allowance, newAmount); + } const waitForConfirmation = async () => { const transactionReceipt = await waitForTransactionConfirmation(hash, allowance.contract.publicClient); @@ -383,8 +386,11 @@ export const updateErc20Allowance = async ( return { hash, confirmation: waitForConfirmation() }; }; -export const prepareRevokeAllowance = async (walletClient: WalletClient, allowance: TokenAllowanceData) => { - if (!allowance.payload) return undefined; +export const prepareRevokeAllowance = async ( + walletClient: WalletClient, + allowance: TokenAllowanceData, +): Promise => { + if (!allowance.payload) throw new Error('Cannot revoke undefined allowance'); if (isErc721Contract(allowance.contract)) { return prepareRevokeErc721Allowance(walletClient, allowance); @@ -429,7 +435,7 @@ export const prepareRevokeErc721Allowance = async ( export const prepareRevokeErc20Allowance = async ( walletClient: WalletClient, allowance: TokenAllowanceData, -): Promise => { +): Promise => { return prepareUpdateErc20Allowance(walletClient, allowance, 0n); }; @@ -437,7 +443,7 @@ export const prepareUpdateErc20Allowance = async ( walletClient: WalletClient, allowance: TokenAllowanceData, newAmount: bigint, -): Promise => { +): Promise => { if (!allowance.payload) throw new Error('Cannot update undefined allowance'); if (isErc721Contract(allowance.contract) || isErc721Allowance(allowance.payload)) { @@ -445,7 +451,7 @@ export const prepareUpdateErc20Allowance = async ( } const differenceAmount = newAmount - allowance.payload.amount; - if (differenceAmount === 0n) return; + if (differenceAmount === 0n) throw new Error('User rejected update transaction'); if (allowance.payload.type === AllowanceType.PERMIT2) { return preparePermit2Approve( @@ -506,25 +512,25 @@ export const prepareUpdateErc20Allowance = async ( } }; -const trackTransaction = (allowance: TokenAllowanceData, hash: string, newAmount?: string) => { - if (!hash) return; - +export const trackRevokeTransaction = (allowance: TokenAllowanceData, newAmount?: string) => { if (isErc721Contract(allowance.contract)) { analytics.track('Revoked ERC721 allowance', { chainId: allowance.chainId, account: allowance.owner, spender: allowance.payload?.spender, token: allowance.contract.address, - tokenId: (allowance.payload as any).tokenId, + tokenId: allowance.payload?.type === AllowanceType.ERC721_SINGLE ? allowance.payload.tokenId : undefined, }); } - analytics.track(newAmount === '0' ? 'Revoked ERC20 allowance' : 'Updated ERC20 allowance', { + const isRevoke = !newAmount || newAmount === '0'; + + analytics.track(isRevoke ? 'Revoked ERC20 allowance' : 'Updated ERC20 allowance', { chainId: allowance.chainId, account: allowance.owner, spender: allowance.payload?.spender, token: allowance.contract.address, - amount: newAmount === '0' ? undefined : newAmount, + amount: isRevoke ? undefined : newAmount, permit2: allowance.payload?.type === AllowanceType.PERMIT2, }); }; @@ -533,7 +539,7 @@ const trackTransaction = (allowance: TokenAllowanceData, hash: string, newAmount // TODO: Add other kinds of transactions besides "revoke" transactions to the store export const wrapRevoke = ( allowance: TokenAllowanceData, - revoke: () => Promise, + revoke: () => Promise, updateTransaction: TransactionStore['updateTransaction'], handleTransaction?: ReturnType, ) => { @@ -545,10 +551,12 @@ export const wrapRevoke = ( if (handleTransaction) await handleTransaction(transactionPromise, TransactionType.REVOKE); const transactionSubmitted = await transactionPromise; - updateTransaction(allowance, { status: 'pending', transactionHash: transactionSubmitted?.hash }); + updateTransaction(allowance, { status: 'pending', transactionHash: transactionSubmitted.hash }); + + trackRevokeTransaction(allowance); // We don't await this, since we want to return after submitting all transactions, even if they're still pending - transactionSubmitted?.confirmation.then(() => { + transactionSubmitted.confirmation.then(() => { updateTransaction(allowance, { status: 'confirmed', transactionHash: transactionSubmitted.hash }); }); diff --git a/lib/utils/batch-revoke.ts b/lib/utils/batch-revoke.ts new file mode 100644 index 000000000..c19b3e08b --- /dev/null +++ b/lib/utils/batch-revoke.ts @@ -0,0 +1,22 @@ +import { getTipSelection } from 'lib/hooks/ethereum/useDonate'; +import type { TokenAllowanceData } from './allowances'; +import { analytics } from './analytics'; + +export type BatchType = 'eip5792' | 'queued'; + +export const trackBatchRevoke = ( + chainId: number, + address: string, + allowances: TokenAllowanceData[], + tipAmount: string, + batchType: BatchType, +) => { + analytics.track('Batch Revoked', { + chainId, + address, + allowances: allowances.length, + tipSelection: getTipSelection(chainId, tipAmount), + amount: tipAmount, + batchType, + }); +}; diff --git a/lib/utils/chains.ts b/lib/utils/chains.ts index 83f1fd89d..b2a0d00e4 100644 --- a/lib/utils/chains.ts +++ b/lib/utils/chains.ts @@ -42,6 +42,7 @@ export const CHAIN_SELECT_MAINNETS = [ ChainId.SeiNetwork, ChainId.BOB, ChainId.RootstockMainnet, + ChainId.SonicMainnet, ChainId.FantomOpera, ChainId.MerlinMainnet, ChainId.CeloMainnet, @@ -58,6 +59,7 @@ export const CHAIN_SELECT_MAINNETS = [ ChainId['SongbirdCanary-Network'], ChainId['WEMIX3.0Mainnet'], ChainId.AuroraMainnet, + ChainId.Soneium, ChainId.ImmutablezkEVM, ChainId.RolluxMainnet, ChainId.SyscoinMainnet, @@ -133,7 +135,7 @@ export const CHAIN_SELECT_TESTNETS = [ ChainId.ArbitrumSepolia, ChainId.BaseSepoliaTestnet, ChainId.ZkSyncSepoliaTestnet, - ChainId.AbstractTestnet, + ChainId.AbstractSepoliaTestnet, ChainId.LineaSepolia, ChainId.ScrollSepoliaTestnet, ChainId.TaikoHeklaL2, @@ -178,12 +180,13 @@ export const CHAINS = { nativeToken: 'ETH', logoUrl: '/assets/images/vendor/chains/abstract.jpg', }), - [ChainId.AbstractTestnet]: new Chain({ + [ChainId.AbstractSepoliaTestnet]: new Chain({ type: SupportType.PROVIDER, - chainId: ChainId.AbstractTestnet, + chainId: ChainId.AbstractSepoliaTestnet, name: 'Abstract Testnet', nativeToken: 'ETH', logoUrl: '/assets/images/vendor/chains/abstract.jpg', + explorerUrl: 'https://sepolia.abscan.org', rpc: { main: `https://abstract-testnet.g.alchemy.com/v2/${ALCHEMY_API_KEY}`, }, @@ -2025,6 +2028,7 @@ export const CHAINS = { logoUrl: '/assets/images/vendor/chains/ethereum.svg', rpc: { main: `https://sepolia.infura.io/v3/${INFURA_API_KEY}`, + free: 'https://sepolia.drpc.org', }, deployedContracts: { ...MULTICALL }, isTestnet: true, @@ -2082,6 +2086,30 @@ export const CHAINS = { isTestnet: true, correspondingMainnetChainId: ChainId.ShimmerEVM, }), + [ChainId.Soneium]: new Chain({ + type: SupportType.PROVIDER, + chainId: ChainId.Soneium, + name: 'Soneium', + explorerUrl: 'https://soneium.blockscout.com', + rpc: { + main: `https://soneium-mainnet.g.alchemy.com/v2/${ALCHEMY_API_KEY}`, + free: 'https://rpc.soneium.org', + }, + deployedContracts: { ...MULTICALL }, + priceStrategy: undefined, // TODO + }), + [ChainId.SonicMainnet]: new Chain({ + type: SupportType.PROVIDER, + chainId: ChainId.SonicMainnet, + name: 'Sonic', + explorerUrl: 'https://sonicscan.org', + logoUrl: '/assets/images/vendor/chains/sonic.svg', + rpc: { + main: `https://sonic-mainnet.g.alchemy.com/v2/${ALCHEMY_API_KEY}`, + }, + deployedContracts: { ...MULTICALL }, + priceStrategy: undefined, // TODO + }), [ChainId['SongbirdCanary-Network']]: new Chain({ type: SupportType.ETHERSCAN_COMPATIBLE, chainId: ChainId['SongbirdCanary-Network'], @@ -2522,7 +2550,7 @@ export const getChainInfoUrl = (chainId: DocumentedChainId): string | undefined return getChainConfig(chainId).getInfoUrl(); }; -export const getChainNativeToken = (chainId: DocumentedChainId): string | undefined => { +export const getChainNativeToken = (chainId: DocumentedChainId): string => { return getChainConfig(chainId).getNativeToken(); }; @@ -2636,6 +2664,7 @@ export const DEFAULT_DONATION_AMOUNTS: Record = { ROSE: '80', RSS3: '50', SAMA: '600', + S: '5', SDN: '50', SEI: '15', SGB: '600', @@ -2657,6 +2686,7 @@ export const DEFAULT_DONATION_AMOUNTS: Record = { ZETA: '10', }; -export const getDefaultDonationAmount = (nativeToken: string): string | undefined => { +// Note: we run tests to make sure that this is configured correctly for all chains +export const getDefaultDonationAmount = (nativeToken: string): string => { return DEFAULT_DONATION_AMOUNTS[nativeToken]; }; diff --git a/lib/utils/eip5792.ts b/lib/utils/eip5792.ts new file mode 100644 index 000000000..1f11cde63 --- /dev/null +++ b/lib/utils/eip5792.ts @@ -0,0 +1,73 @@ +import type { TransactionSubmitted } from 'lib/interfaces'; +import type { SendTransactionParameters, WalletCallReceipt, WalletClient, WriteContractParameters } from 'viem'; +import type { Call } from 'viem/_types/types/calls'; +import { type Eip5792Actions, type GetCallsStatusReturnType, eip5792Actions } from 'viem/experimental'; +import type { OnUpdate } from './allowances'; +import type { TokenAllowanceData } from './allowances'; + +export type Eip5792Call = Call; + +export const walletSupportsEip5792 = async (walletClient: WalletClient) => { + try { + const extendedWalletClient = walletClient.extend(eip5792Actions()); + const capabilities = await extendedWalletClient.getCapabilities(); + console.log('Wallet supports EIP5792:', capabilities); + return true; + } catch (e) { + console.log('Wallet does not support EIP5792'); + return false; + } +}; + +export const pollForCallsReceipts = async (id: string, walletClient: WalletClient & Eip5792Actions) => { + return new Promise((resolve) => { + const interval = setInterval(async () => { + const res = await walletClient.getCallsStatus({ id }); + if (res.status === 'CONFIRMED') { + clearInterval(interval); + resolve(res); + } + }, 2000); + + return () => clearInterval(interval); + }); +}; + +export const mapContractTransactionRequestToEip5792Call = ( + transactionRequest: WriteContractParameters, +): Eip5792Call => { + return { + to: transactionRequest.address, + abi: transactionRequest.abi, + functionName: transactionRequest.functionName, + args: transactionRequest.args, + value: transactionRequest.value, + }; +}; + +export const mapTransactionRequestToEip5792Call = (transactionRequest: SendTransactionParameters): Eip5792Call => { + return { + to: transactionRequest.to!, + data: transactionRequest.data, + value: transactionRequest.value, + }; +}; + +export const mapWalletCallReceiptToTransactionSubmitted = ( + allowance: TokenAllowanceData, + walletCallReceipt: WalletCallReceipt, + onUpdate: OnUpdate, +): TransactionSubmitted => { + const awaitConfirmationAndUpdate = async () => { + const receipt = await allowance.contract.publicClient.getTransactionReceipt({ + hash: walletCallReceipt.transactionHash, + }); + onUpdate(allowance, undefined); + return receipt; + }; + + return { + hash: walletCallReceipt.transactionHash, + confirmation: awaitConfirmationAndUpdate(), + }; +}; diff --git a/lib/utils/errors.ts b/lib/utils/errors.ts index 19cf99467..ad0abcfa0 100644 --- a/lib/utils/errors.ts +++ b/lib/utils/errors.ts @@ -76,6 +76,7 @@ export const isNetworkError = (error?: string | any): boolean => { export const parseErrorMessage = (error: any): string => { const errorMessage = + error?.cause?.details || // Abstract Global Wallet error?.error?.message || error?.data?.message || error?.response?.data?.message || diff --git a/lib/utils/index.ts b/lib/utils/index.ts index c5aacd4ae..dd907c26e 100644 --- a/lib/utils/index.ts +++ b/lib/utils/index.ts @@ -5,6 +5,7 @@ import type { getTranslations } from 'next-intl/server'; import { toast } from 'react-toastify'; import { type Address, + type EstimateContractGasParameters, type Hash, type Hex, type PublicClient, @@ -99,7 +100,7 @@ export const normaliseLabel = (label: string) => { }; export const getWalletAddress = async (walletClient: WalletClient) => { - const [address] = await walletClient.requestAddresses(); + const [address] = await walletClient.getAddresses(); return address; }; @@ -138,7 +139,9 @@ export const writeContractUnlessExcessiveGas = async ( walletClient: WalletClient, transactionRequest: WriteContractParameters, ) => { - const estimatedGas = transactionRequest.gas ?? (await publicClient.estimateContractGas(transactionRequest)); + const estimatedGas = + transactionRequest.gas ?? + (await publicClient.estimateContractGas(transactionRequest as EstimateContractGasParameters)); throwIfExcessiveGas(transactionRequest.chain!.id, transactionRequest.address, estimatedGas); return walletClient.writeContract({ ...transactionRequest, gas: estimatedGas }); }; diff --git a/lib/utils/wallet.ts b/lib/utils/wallet.ts index 6945dbd79..5c9781b90 100644 --- a/lib/utils/wallet.ts +++ b/lib/utils/wallet.ts @@ -12,6 +12,7 @@ export const getWalletIcon = (connector: Connector): string | undefined => { const mapping: Record = { // Injected wallets '1inchwallet': '/assets/images/vendor/wallets/1inch.svg', + abstract: '/assets/images/vendor/wallets/abstract.jpg', backpack: '/assets/images/vendor/wallets/backpack.svg', 'bifrost wallet': '/assets/images/vendor/wallets/bifrost.svg', bitkeep: '/assets/images/vendor/wallets/bitkeep.svg', diff --git a/locales/en/networks.json b/locales/en/networks.json index ccf1373d9..1fe99bb1e 100644 --- a/locales/en/networks.json +++ b/locales/en/networks.json @@ -101,6 +101,8 @@ "shape": "Shape is a Layer 2 scaling solution for Ethereum that is focused on creators. It features a gasback system in which creators cann claim back a large part of the gas fees that are generated through their smart contracts. Shape is built using Optimism's Open Source OP Stack, so just like Optimism it uses optimistic rollup technology.", "shibarium": "Shibarium is an Ethereum sidechain that was created to bring a native smart contract ecosystem to the Shiba Inu community. As a sidechain it compromises on decentralization to provide faster and cheaper transactions. Shibarium also features a bridge to Ethereum, allowing users to transfer their SHIB tokens and other popular Ethereum tokens to and from Shibarium.", "shimmer": "Shimmer EVM is an EVM compatible Layer 2 blockchain built on top of the interoperable Shimmer network. Because it is a Layer 2 to Shimmer, it is easily interoperable with other chains in the Shimmer / IOTA ecosystem. Shimmer EVM offers a few interesting innovations, such as parallel processing of transactions and native randomness in the protocol.", + "soneium": "Soneium is a Layer 2 blockchain built on top of Ethereum and Optimism's Superchain. It is built using Optimism's Open Source OP Stack, so just like Optimism it uses optimistic rollup technology. It was founded by Sony with the vision of creating a network with mass mainstream adoption.", + "sonic": "Sonic is a Layer 1 blockchain that is created by the team behind Fantom as its spiritual successor. It offers a high throughput and low fees and offers incentives for developers to build on the network.", "story": "Story is a Layer 1 blockchain focused on providing a framework for onchain intellectual property. This aims to make it easier for creators to protect, license and monetize their work. Story is built using the Cosmos SDK and offers full support for EVM compatible smart contracts.", "syscoin": "Syscoin is a Layer 1 blockchain that began in 2014 as a fork of Bitcoin. Over the years it evolved into a Dual-Chain system, with one part of the network being a Bitcoin fork, and the other part being an EVM compatible blockchain. Both chains are secured using a process called Merged Mining, which allows Bitcoin miners to simultaneously use their hashrate for Bitcoin and Syscoin transactions.", "tabi": "Tabi is a Layer 1 blockchain that uses a consensus mechanism based on Proof of Stake. It is built using the Cosmos SDK and aims to offer interoperability between EVM chains and the Cosmos ecosystem.", diff --git a/locales/es/networks.json b/locales/es/networks.json index 26b8e144a..1a487b346 100644 --- a/locales/es/networks.json +++ b/locales/es/networks.json @@ -30,7 +30,7 @@ "chiliz": "Chiliz es una blockchain de Capa 1 que se centra en los deportes y el entretenimiento. Se centra en mejorar la participación de los aficionados al deporte a través de la tokenización, lo que permite a los aficionados interactuar y relacionarse con sus equipos y clubes deportivos favoritos.", "coinex-smart-chain": "CoinEx Smart Chain (CSC) es una blockchain de Capa 1 creada por la bolsa CoinEx. Se creó para ofrecer tarifas de transacción más bajas y tiempos de transacción más rápidos que Ethereum. Lo consigue utilizando un mecanismo de consenso más centralizado que integra funciones de Prueba de Participación y Prueba de Autoridad.", "core": "CORE es una blockchain de Capa 1 que utiliza un nuevo mecanismo de consenso llamado Satoshi Plus, que aprovecha el hashrate de Bitcoin y combina características de Prueba de Trabajo y Prueba Delegada de Participación. Aunque proporciona su propia red de blockchain, la DAO de CORE también se centra en extender el uso de la tecnología Satoshi Plus a otras blockchains.", - "creator-chain": "Creator Chain is a Layer 2 blockchain that is built using Optimism's OP Stack, so just like Optimism it uses optimistic rollup technology. Creator Chain is focused on providing cheap and fast transactions, while enabling developers to earn a share of the network's revenue.", + "creator-chain": "Creator Chain es una blockchain de Capa 2 que se construye utilizando OP Stack de Optimism, por lo que, al igual que Optimism, utiliza tecnología de rollup optimista. Creator Chain se centra en proporcionar transacciones baratas y rápidas, al tiempo que permite a los desarrolladores obtener una parte de los ingresos de la red.", "cronos": "Cronos es la sidechain compatible con EVM de la blockchain Crypto.org. Cronos utiliza un mecanismo de consenso de Prueba de Autoridad, que hace que la cadena sea rápida y barata de utilizar, pero compromete la descentralización. También utiliza el protocolo Inter Blockchain Communications (IBC) para permitir la interoperabilidad entre Cronos y otras blockchains.", "darwinia": "Darwinia es una paracadena compatible con Ethereum que se ejecuta en Polkadot. Como paracadena de Polkadot, se integra bien con otras redes construidas en Polkadot, ya que tiene como objetivo proporcionar interoperabilidad entre cadenas entre diferentes cadenas de bloques utilizando su tecnología Darwinia MsgPort.", "degen-chain": "Degen Chain es una blockchain de Capa 3 creada en torno al token comunitario DEGEN para la red social Farcaster. Está construida utilizando el marco Orbit de Arbitrum con liquidación en Base, una solución de escalado de Nivel 2 para Ethereum.", @@ -54,7 +54,7 @@ "horizen-eon": "Horizen es una red de blockchains centrada principalmente en la privacidad. Cuenta con una cadena principal de Prueba de Trabajo y Zendoo, un marco para crear sidechains de Prueba de Participación que se conectan a la cadena principal de Horizen. Horizen EON es la cadena lateral compatible con EVM del ecosistema Horizen.", "immutable-zkevm": "Immutable zkEVM es una blockchain de Capa 2 creada para la industria del juego por el desarrollador y editor de juegos Web3 Immutable. Immutable zkEVM se construye utilizando el Kit de Desarrollo de Cadenas (CDK) de Polygon para proporcionar bajo coste y alta escala para aplicaciones de juegos.", "inevm": "inEVM es una red compatible con EVM creada por el equipo detrás de Injective blockchain basada en Cosmos. Su objetivo es ofrecer compatibilidad e interoperabilidad entre Ethereum, Cosmos y Solana.", - "ink": "Ink is a Layer 2 scaling solution for Ethereum that was created by the team behind crypto exchange Kraken. It is built on Optimism's Open Source OP Stack, so just like Optimism it uses optimistic rollup technology. Ink is focused on providing a low cost and high throughput solution for DeFi use cases.", + "ink": "Ink es una solución de escalado de Capa 2 para Ethereum que fue creada por el equipo detrás del exchange de criptomonedas Kraken. Se basa en la Pila OP de Código Abierto de Optimism, por lo que, al igual que Optimism, utiliza la tecnología de rollup optimista. Ink se centra en proporcionar una solución de bajo coste y alto rendimiento para los casos de uso de DeFi.", "iota-evm": "Al integrar la red de IOTA con una cadena de contratos inteligentes compatible con EVM, IOTA EVM proporciona escalabilidad horizontal y protección MEV avanzada para una tokenización eficiente de activos del mundo real. Admite contratos inteligentes escalables y seguros dentro de una arquitectura flexible de varias máquinas virtuales. La plataforma permite la transferencia y el comercio de activos y está orientada a DeFi, juegos, NFT y DAO con sólidas capacidades de interacción entre cadenas.", "kardiachain": "KardiaChain es una blockchain de Capa 1 que utiliza un mecanismo de consenso basado en la Prueba Delegada de Participación. Se centra en ofrecer soluciones para aplicaciones phygital (físicas + digitales) e interoperabilidad entre diferentes blockchains. KardiaChain se centra principalmente en Vietnam y en el mercado del Sudeste Asiático.", "kava": "Kava es la primera blockchain que combina la tecnología del SDK de Cosmos con el apoyo a los desarrolladores y la compatibilidad de la EVM. Utiliza una arquitectura denominada \"co-cadena\" que permite a los desarrolladores utilizar tanto la tecnología compatible de Cosmos como la de Ethereum, que se combinan mediante una capa de gobierno y seguridad global.", @@ -101,6 +101,8 @@ "shape": "Shape es una solución de escalado de Capa 2 para Ethereum que se centra en los creadores. Cuenta con un sistema de devolución de gas en el que los creadores pueden reclamar una gran parte de las tarifas de gas que se generan a través de sus contratos inteligentes. Shape se construye utilizando la pila OP de código abierto de Optimism, por lo que, al igual que Optimism, utiliza la tecnología de rollup optimista.", "shibarium": "Shibarium es una sidechain de Ethereum que se creó para aportar un ecosistema nativo de contratos inteligentes a la comunidad Shiba Inu. Como sidechain, se compromete con la descentralización para proporcionar transacciones más rápidas y baratas. Shibarium también cuenta con un puente a Ethereum, que permite a los usuarios transferir sus tokens SHIB y otros tokens populares de Ethereum a y desde Shibarium.", "shimmer": "Shimmer EVM es una blockchain de Capa 2 compatible con EVM construida sobre la red interoperable Shimmer. Al ser de Capa 2 de Shimmer, es fácilmente interoperable con otras cadenas del ecosistema Shimmer / IOTA. Shimmer EVM ofrece algunas innovaciones interesantes, como el procesamiento paralelo de las transacciones y la aleatoriedad nativa en el protocolo.", + "soneium": "Soneium is a Layer 2 blockchain built on top of Ethereum and Optimism's Superchain. It is built using Optimism's Open Source OP Stack, so just like Optimism it uses optimistic rollup technology. It was founded by Sony with the vision of creating a network with mass mainstream adoption.", + "sonic": "Sonic es una blockchain de Capa 1 creada por el equipo detrás de Fantom como su sucesor espiritual. Ofrece un alto rendimiento y tarifas bajas y ofrece incentivos para que los desarrolladores construyan en la red.", "story": "Story es una blockchain de Capa 1 centrada en proporcionar un marco para la propiedad intelectual en cadena. Su objetivo es facilitar a los creadores la protección, la concesión de licencias y la monetización de su trabajo. Story se crea con el SDK de Cosmos y ofrece soporte completo para contratos inteligentes compatibles con EVM.", "syscoin": "Syscoin es una blockchain de Capa 1 que comenzó en 2014 como una bifurcación de Bitcoin. Con el paso de los años evolucionó hasta convertirse en un sistema de doble cadena, en el que una parte de la red es una bifurcación de Bitcoin y la otra parte es una blockchain compatible con EVM. Ambas cadenas están aseguradas mediante un proceso llamado Minería Fusionada, que permite a los mineros de Bitcoin utilizar simultáneamente su hashrate para transacciones de Bitcoin y Syscoin.", "tabi": "Tabi es una blockchain de Capa 1 que utiliza un mecanismo de consenso basado en Proof of Stake. Se construye utilizando el SDK de Cosmos y pretende ofrecer interoperabilidad entre las cadenas EVM y el ecosistema Cosmos.", diff --git a/locales/ja/networks.json b/locales/ja/networks.json index 7c69c56cc..795f1c4e8 100644 --- a/locales/ja/networks.json +++ b/locales/ja/networks.json @@ -101,6 +101,8 @@ "shape": "Shapeは、クリエイターに焦点を当てたEthereumのレイヤー2のスケーリングソリューションです。その特徴はガスバックシステムで、クリエイターはスマートコントラクトを通じて発生するガス料金の大部分を請求することができます。ShapeはOptimismのオープンソースOPスタックを使用して構築されているため、Optimismと同様にオプティミスティックロールアップテクノロジーを使用しています。", "shibarium": "Shibariumは、シバ犬コミュニティーにネイティブのスマートコントラクトエコシステムをもたらすために作成されたEthereumのサイドチェーンです。サイドチェーンとしては分散化に妥協し、より高速で安価な取引を実現しています。また、ShibariumはEthereumへのブリッジ機能も備えているため、ユーザーはSHIBトークンやその他の一般的なEthereumトークンをShibariumとの間で転送できます。", "shimmer": "Shimmer EVMは、相互運用可能なShimmerネットワーク上に構築されたEVM互換のレイヤー2のブロックチェーンです。これはShimmerのレイヤー2であるため、Shimmer/IOTAエコシステム内の他のチェーンと簡単に相互運用できます。Shimmer EVMには、取引の並列処理やプロトコルのネイティブランダム性など、興味深いイノベーションがいくつかあります。", + "soneium": "Soneium is a Layer 2 blockchain built on top of Ethereum and Optimism's Superchain. It is built using Optimism's Open Source OP Stack, so just like Optimism it uses optimistic rollup technology. It was founded by Sony with the vision of creating a network with mass mainstream adoption.", + "sonic": "Sonic is a Layer 1 blockchain that is created by the team behind Fantom as its spiritual successor. It offers a high throughput and low fees and offers incentives for developers to build on the network.", "story": "Storyは、オンチェーン知的財産のフレームワークを提供することに重点を置いたレイヤー1のブロックチェーンです。これは、クリエイターが自分の作品をより簡単に保護し、ライセンス供与し、収益化できるようにすることを目的としています。StoryはCosmos SDKを使用して構築されており、EVM互換のスマートコントラクトを完全にサポートしています。", "syscoin": "Syscoinは、2014年にビットコインのフォークとして始まったレイヤー1のブロックチェーンです。何年にもわたってデュアルチェーンシステムに発展し、ネットワークの一部はビットコインフォーク、もう片方はEVM互換のブロックチェーンになりました。どちらのチェーンも、マージ・マイニングと呼ばれるプロセスを使用して保護されています。これにより、ビットコイン・マイナーはそれぞれのハッシュレートをビットコインとシスコインの取引に同時に使用できます。", "tabi": "Tabiは、プルーフ・オブ・ステークに基づくコンセンサスメカニズムを使用するレイヤー1のブロックチェーンです。Cosmos SDKを使用して構築されており、EVMチェーンとCosmosエコシステム間の相互運用性を提供することを目的としています。", diff --git a/locales/ru/networks.json b/locales/ru/networks.json index 210b529ac..f9b26c9e6 100644 --- a/locales/ru/networks.json +++ b/locales/ru/networks.json @@ -101,6 +101,8 @@ "shape": "Shape — это Layer 2 решение для масштабирования для Ethereum, ориентированное на создателей. В нем есть система gasback, в которой создатели могут требовать возврата значительной части платы за газ, генерируемой с помощью их смарт-контрактов. Shape создан с использованием стека OP Suite с открытым исходным кодом от Optimism, поэтому, как и Optimism, он использует технологию оптимистичного ролапа.", "shibarium": "Shibarium - это сайдчейн Ethereum, который был создан для того, чтобы привнести нативную экосистему смарт-контрактов в сообщество Shiba Inu. Будучи сайдчейном, он идёт на компромисс с децентрализацией, чтобы обеспечить более быстрые и дешёвые транзакции. Shibarium также имеет мост к Ethereum, что позволяет пользователям переводить свои токены SHIB и другие популярные токены Ethereum на Shibarium и обратно.", "shimmer": "Shimmer EVM — это Layer 2 совместимый с EVM, построенный на основе совместимой сети Shimmer. Поскольку это Layer 2 для Shimmer, он легко совместим с другими чейнами экосистемы Shimmer/IOTA. Shimmer EVM предлагает несколько интересных нововведений, таких как параллельная обработка транзакций и встроенная случайность в протоколе.", + "soneium": "Soneium is a Layer 2 blockchain built on top of Ethereum and Optimism's Superchain. It is built using Optimism's Open Source OP Stack, so just like Optimism it uses optimistic rollup technology. It was founded by Sony with the vision of creating a network with mass mainstream adoption.", + "sonic": "Sonic is a Layer 1 blockchain that is created by the team behind Fantom as its spiritual successor. It offers a high throughput and low fees and offers incentives for developers to build on the network.", "story": "Story — это Layer 1 блокчейн, ориентированный на обеспечение основы для интеллектуальной собственности в сети. Это направлено на то, чтобы авторам было проще защищать, лицензировать и монетизировать свою работу. Story создан с использованием Cosmos SDK и предлагает полную поддержку смарт-контрактов, совместимых с EVM.", "syscoin": "Syscoin - это Layer 1 блокчейн, который начал свою работу в 2014 году как форк Bitcoin. Со временем, он превратился в двухчейновую систему, одна часть сети которой представляет собой форк Bitcoin, а другая - блокчейн, совместимый с EVM. Оба чейна обеспечены с помощью процесса под названием Merged Mining, который позволяет майнерам Bitcoin одновременно использовать свой хешрейт для транзакций Bitcoin и Syscoin.", "tabi": "Tabi — это Layer 1 блокчейн, в котором используется механизм консенсуса, основанный на Proof of Stake. Он создан с использованием Cosmos SDK и призван обеспечить совместимость между цепочками EVM и экосистемой Cosmos.", diff --git a/locales/zh/networks.json b/locales/zh/networks.json index 734f6c6f4..20a918e05 100644 --- a/locales/zh/networks.json +++ b/locales/zh/networks.json @@ -101,6 +101,8 @@ "shape": "Shape 是以太坊的第 2 层(Layer 2)扩展解决方案,为创作者量身打造而成。创作者可以通过 Shape 独特的汽油费返还激励系统回收通过其智能合约产生的大部分汽油费。Shape 基于 Optimism 的 OP Stack 构建,因此与 Optimism 一样,它也使用 Optimistic Rollup 技术。", "shibarium": "Shibarium 是一个以太坊侧链,旨在为 Shiba Inu 社区引入原生智能合约生态系统。作为侧链,它在去中心化方面做出了妥协,以保证交易速度更快、成本更低。Shibarium 可桥接至以太坊,用户可以将 SHIB 代币和其他流行的以太坊代币转入或转出 Shibarium。", "shimmer": "Shimmer EVM 是一个兼容 EVM 的第 2 层(Layer 2)区块链,建立在可互操作的 Shimmer 网络之上。由于是 Shimmer 的第 2 层链,Shimmer EVM 可以轻松地与 Shimmer/IOTA 生态系统中的其他链进行互操作。Shimmer EVM 带来了一些有趣的创新,例如交易的并行处理和协议中的原生随机性。", + "soneium": "Soneium is a Layer 2 blockchain built on top of Ethereum and Optimism's Superchain. It is built using Optimism's Open Source OP Stack, so just like Optimism it uses optimistic rollup technology. It was founded by Sony with the vision of creating a network with mass mainstream adoption.", + "sonic": "Sonic is a Layer 1 blockchain that is created by the team behind Fantom as its spiritual successor. It offers a high throughput and low fees and offers incentives for developers to build on the network.", "story": "Story 是第 1 层(Layer 1)区块链,专为链上知识产权提供框架。其目的是让创作者能够更轻松地对作品进行保护、授权和货币化。Story 使用 Cosmos SDK 构建,并完全支持与 EVM 兼容的智能合约。", "syscoin": "Syscoin 创建于 2014 年,是作为比特币的一个分支而创建的第 1 层(Layer 1)区块链。多年来,它演变为双链系统,一部分是比特币分支,另一部分则是兼容 EVM 的区块链。两条链都采用合并挖矿技术保证安全,该技术过程允许比特币矿工同时使用哈希率进行比特币和 Syscoin 交易。", "tabi": "Tabi 是第 1 层(Layer 1)区块链,采用了权益证明(PoS)共识机制。Tabi 使用 Cosmos SDK 构建,旨在提高EVM 链与 Cosmos 生态之间的互操作性。", diff --git a/package.json b/package.json index e00670d35..1ba87ed51 100644 --- a/package.json +++ b/package.json @@ -23,11 +23,14 @@ }, "private": true, "dependencies": { + "@abstract-foundation/agw-client": "^1.0.0", + "@abstract-foundation/agw-react": "^1.0.0", "@dotenvx/dotenvx": "^1.14.2", "@headlessui/react": "^2.1.2", "@heroicons/react": "^2.1.5", "@neondatabase/serverless": "^0.10.1", - "@revoke.cash/chains": "^59.0.0", + "@privy-io/cross-app-connect": "^0.1.2", + "@revoke.cash/chains": "^60.0.0", "@tanstack/query-sync-storage-persister": "^5.52.0", "@tanstack/react-query": "^5.52.0", "@tanstack/react-query-persist-client": "^5.52.0", @@ -66,8 +69,8 @@ "timeago-react": "^3.0.6", "timeago.js": "^4.0.2", "use-local-storage": "^3.0.0", - "viem": "^2.19.9", - "wagmi": "^2.12.7", + "viem": "^2.22.2", + "wagmi": "^2.14.6", "zustand": "^5.0.0-rc.2" }, "devDependencies": { @@ -77,6 +80,7 @@ "@cypress/grep": "^4.1.0", "@lavamoat/allow-scripts": "^3.2.0", "@localazy/cli": "^1.7.14", + "@rainbow-me/rainbowkit": "^2.2.1", "@tailwindcss/typography": "^0.5.14", "@types/md5": "^2.3.5", "@types/mixpanel-browser": "^2.49.1", @@ -111,6 +115,8 @@ "lavamoat": { "allowScripts": { "$root$": true, + "@abstract-foundation/agw-react>secp256k1": false, + "@biomejs/biome": true, "@vercel/speed-insights": false, "cypress": true, "sharp": true, @@ -118,8 +124,7 @@ "viem>ws>bufferutil": true, "viem>ws>utf-8-validate": true, "wagmi>@wagmi/connectors>cbw-sdk>keccak": false, - "wagmi>@wagmi/connectors>@metamask/sdk>eciesjs>secp256k1": false, - "@biomejs/biome": true + "wagmi>@wagmi/connectors>@metamask/sdk>eciesjs>secp256k1": false } }, "mocha": { diff --git a/public/assets/images/vendor/chains/soneium.png b/public/assets/images/vendor/chains/soneium.png new file mode 100644 index 000000000..a7ceb520e Binary files /dev/null and b/public/assets/images/vendor/chains/soneium.png differ diff --git a/public/assets/images/vendor/chains/sonic.svg b/public/assets/images/vendor/chains/sonic.svg new file mode 100644 index 000000000..8454dd97a --- /dev/null +++ b/public/assets/images/vendor/chains/sonic.svg @@ -0,0 +1,13 @@ + + Logomark_Sonic_Black + + + + + + + + + \ No newline at end of file diff --git a/public/assets/images/vendor/wallets/abstract.jpg b/public/assets/images/vendor/wallets/abstract.jpg new file mode 100644 index 000000000..fba6c2f01 Binary files /dev/null and b/public/assets/images/vendor/wallets/abstract.jpg differ diff --git a/test/chains.test.ts b/test/chains.test.ts index 2b7d9fb76..934e5d6d1 100644 --- a/test/chains.test.ts +++ b/test/chains.test.ts @@ -37,17 +37,17 @@ describe('Chain Support', () => { describe(`${chainName} (${nativeToken})`, () => { it('should have base chain data', () => { - expect(getChainName(chainId)).to.exist; - expect(getChainLogo(chainId)).to.exist; - expect(getChainInfoUrl(chainId)).to.exist; - expect(getChainExplorerUrl(chainId)).to.exist; - expect(getChainRpcUrl(chainId)).to.exist; - expect(getChainLogsRpcUrl(chainId)).to.exist; - expect(getChainFreeRpcUrl(chainId)).to.exist; - expect(getChainSlug(chainId)).to.exist; - expect(getChainIdFromSlug(getChainSlug(chainId))).to.equal(chainId); - expect(nativeToken).to.exist; - expect(getDefaultDonationAmount(nativeToken)).to.exist; + expect(getChainName(chainId), `${chainName} name`).to.exist; + expect(getChainLogo(chainId), `${chainName} logo`).to.exist; + expect(getChainInfoUrl(chainId), `${chainName} info url`).to.exist; + expect(getChainExplorerUrl(chainId), `${chainName} explorer url`).to.exist; + expect(getChainRpcUrl(chainId), `${chainName} rpc url`).to.exist; + expect(getChainLogsRpcUrl(chainId), `${chainName} logs rpc url`).to.exist; + expect(getChainFreeRpcUrl(chainId), `${chainName} free rpc url`).to.exist; + expect(getChainSlug(chainId), `${chainName} slug`).to.exist; + expect(getChainIdFromSlug(getChainSlug(chainId)), `${chainName} chain id from slug`).to.equal(chainId); + expect(nativeToken, `${chainName} native token`).to.exist; + expect(getDefaultDonationAmount(nativeToken), `${chainName} default donation amount`).to.exist; }); if (getChainConfig(chainId)?.type === SupportType.ETHERSCAN_COMPATIBLE) { diff --git a/yarn.lock b/yarn.lock index 918360f8f..48ef0ad75 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5,6 +5,46 @@ __metadata: version: 6 cacheKey: 8 +"@abstract-foundation/agw-client@npm:1.0.0, @abstract-foundation/agw-client@npm:^1.0.0": + version: 1.0.0 + resolution: "@abstract-foundation/agw-client@npm:1.0.0" + peerDependencies: + abitype: ^1.0.0 + typescript: ">=5.0.4" + viem: ^2.21.26 + peerDependenciesMeta: + typescript: + optional: true + checksum: 4e68a931cfde14aabb6c4b3c4b5fa4ba949262c0a91d1bb729ff52a3779169642f65bcb171c34f6bc88638dcd11625c6f025dffb57be8765b784727855bad07e + languageName: node + linkType: hard + +"@abstract-foundation/agw-react@npm:^1.0.0": + version: 1.0.0 + resolution: "@abstract-foundation/agw-react@npm:1.0.0" + dependencies: + "@abstract-foundation/agw-client": 1.0.0 + peerDependencies: + "@privy-io/cross-app-connect": ^0.1.2 + "@privy-io/react-auth": ^1.97.0 + "@tanstack/react-query": ^5 + react: ">=18" + secp256k1: ">=5.0.1" + thirdweb: ^5.68.0 + typescript: ">=5.0.4" + viem: ^2.21.26 + wagmi: ^2 + peerDependenciesMeta: + "@rainbow-me/rainbowkit": + optional: true + thirdweb: + optional: true + typescript: + optional: true + checksum: c531d9158c5bbbff2ced23514f93e5200409d296f924fdef2f9c3f86f0d64aa2d8ea2db37aff93a89d21602bf61aba326ee1506ddc326f5414044d44c2faf02b + languageName: node + linkType: hard + "@adraffy/ens-normalize@npm:1.10.0": version: 1.10.0 resolution: "@adraffy/ens-normalize@npm:1.10.0" @@ -12,6 +52,13 @@ __metadata: languageName: node linkType: hard +"@adraffy/ens-normalize@npm:^1.10.1": + version: 1.11.0 + resolution: "@adraffy/ens-normalize@npm:1.11.0" + checksum: b2911269e3e0ec6396a2e5433a99e0e1f9726befc6c167994448cd0e53dbdd0be22b4835b4f619558b568ed9aa7312426b8fa6557a13999463489daa88169ee5 + languageName: node + linkType: hard + "@alloc/quick-lru@npm:^5.2.0": version: 5.2.0 resolution: "@alloc/quick-lru@npm:5.2.0" @@ -106,7 +153,7 @@ __metadata: languageName: node linkType: hard -"@babel/runtime@npm:^7.12.0, @babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.18.3, @babel/runtime@npm:^7.19.4, @babel/runtime@npm:^7.21.0, @babel/runtime@npm:^7.23.2, @babel/runtime@npm:^7.3.1, @babel/runtime@npm:^7.5.5, @babel/runtime@npm:^7.8.7": +"@babel/runtime@npm:^7.12.0, @babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.18.3, @babel/runtime@npm:^7.21.0, @babel/runtime@npm:^7.3.1, @babel/runtime@npm:^7.5.5, @babel/runtime@npm:^7.8.7": version: 7.25.6 resolution: "@babel/runtime@npm:7.25.6" dependencies: @@ -115,6 +162,15 @@ __metadata: languageName: node linkType: hard +"@babel/runtime@npm:^7.26.0": + version: 7.26.0 + resolution: "@babel/runtime@npm:7.26.0" + dependencies: + regenerator-runtime: ^0.14.0 + checksum: c8e2c0504ab271b3467a261a8f119bf2603eb857a0d71e37791f4e3fae00f681365073cc79f141ddaa90c6077c60ba56448004ad5429d07ac73532be9f7cf28a + languageName: node + linkType: hard + "@babel/template@npm:^7.25.0": version: 7.25.0 resolution: "@babel/template@npm:7.25.0" @@ -243,17 +299,15 @@ __metadata: languageName: node linkType: hard -"@coinbase/wallet-sdk@npm:4.0.4": - version: 4.0.4 - resolution: "@coinbase/wallet-sdk@npm:4.0.4" +"@coinbase/wallet-sdk@npm:4.2.3": + version: 4.2.3 + resolution: "@coinbase/wallet-sdk@npm:4.2.3" dependencies: - buffer: ^6.0.3 + "@noble/hashes": ^1.4.0 clsx: ^1.2.1 eventemitter3: ^5.0.1 - keccak: ^3.0.3 - preact: ^10.16.0 - sha.js: ^2.4.11 - checksum: 002d03d791683a15b465a285d7293a7994684f6f91d67c01b52ee9a07ba62f555a12d5c9471c964ccae0df048190f9c2e82929aeba9247e6d97ad1a9e9dd4132 + preact: ^10.24.2 + checksum: f1cb3c5975bf7eed46aa56077943becea16e92ac7dda46e78fb2939b3f3864815a7f218842410abb40b2b3182d09c9636ea699714c3d564009438c3611f45abc languageName: node linkType: hard @@ -547,6 +601,15 @@ __metadata: languageName: node linkType: hard +"@ecies/ciphers@npm:^0.2.2": + version: 0.2.2 + resolution: "@ecies/ciphers@npm:0.2.2" + peerDependencies: + "@noble/ciphers": ^1.0.0 + checksum: 10a623261aa212184850fcd41788ae1f616365b5084df03ac0d7108223519e24a5f7d92caac1ee9e0f2e3b6cfae3037a42e466b25de20cf85e91098f60ba1187 + languageName: node + linkType: hard + "@emnapi/runtime@npm:^1.2.0": version: 1.3.1 resolution: "@emnapi/runtime@npm:1.3.1" @@ -588,6 +651,13 @@ __metadata: languageName: node linkType: hard +"@emotion/hash@npm:^0.9.0": + version: 0.9.2 + resolution: "@emotion/hash@npm:0.9.2" + checksum: 379bde2830ccb0328c2617ec009642321c0e009a46aa383dfbe75b679c6aea977ca698c832d225a893901f29d7b3eef0e38cf341f560f6b2b56f1ff23c172387 + languageName: node + linkType: hard + "@emotion/hash@npm:^0.9.1": version: 0.9.1 resolution: "@emotion/hash@npm:0.9.1" @@ -1405,9 +1475,9 @@ __metadata: languageName: node linkType: hard -"@metamask/sdk-communication-layer@npm:0.28.2": - version: 0.28.2 - resolution: "@metamask/sdk-communication-layer@npm:0.28.2" +"@metamask/sdk-communication-layer@npm:0.31.0": + version: 0.31.0 + resolution: "@metamask/sdk-communication-layer@npm:0.31.0" dependencies: bufferutil: ^4.0.8 date-fns: ^2.29.3 @@ -1416,71 +1486,47 @@ __metadata: uuid: ^8.3.2 peerDependencies: cross-fetch: ^4.0.0 - eciesjs: ^0.3.16 - eventemitter2: ^6.4.7 + eciesjs: "*" + eventemitter2: ^6.4.9 readable-stream: ^3.6.2 socket.io-client: ^4.5.1 - checksum: 349103ca72018fc4077ddf3d84d3976572525cf27b17b65308c6a00710c66f06d2d3880bb611a4a6462d1fb54bc59edd6855826f78796f49d8c7cd9904742577 + checksum: 3f9283d828d736f331154bfa0e1368b7c7c18e00eff66ccd20e97fb86618433cef3c60ed4168e2565bda825303562eb00bb9ca101d1abdcdc3f3848f807e614e languageName: node linkType: hard -"@metamask/sdk-install-modal-web@npm:0.28.1": - version: 0.28.1 - resolution: "@metamask/sdk-install-modal-web@npm:0.28.1" +"@metamask/sdk-install-modal-web@npm:0.31.2": + version: 0.31.2 + resolution: "@metamask/sdk-install-modal-web@npm:0.31.2" dependencies: - qr-code-styling: ^1.6.0-rc.1 - peerDependencies: - i18next: 23.11.5 - react: ^18.2.0 - react-dom: ^18.2.0 - react-native: "*" - peerDependenciesMeta: - react: - optional: true - react-dom: - optional: true - react-native: - optional: true - checksum: 8ee147c63927323105bdf7d76667c06618119b30b355543a74f3a08e7559448d217bdf9a4fee0900efa0fc3f5a13f6376a76b2679e0b8322f6811789868dce42 + "@paulmillr/qr": ^0.2.1 + checksum: 02b5dac25b572d5ede5cf436dae3905193d38010da51bcfc89551902a4aa2867c51e03d95c11d8e13839b7478d368fb3e38fd19d3bde9882d1adbec51ad8a240 languageName: node linkType: hard -"@metamask/sdk@npm:0.28.2": - version: 0.28.2 - resolution: "@metamask/sdk@npm:0.28.2" +"@metamask/sdk@npm:0.31.4": + version: 0.31.4 + resolution: "@metamask/sdk@npm:0.31.4" dependencies: + "@babel/runtime": ^7.26.0 "@metamask/onboarding": ^1.0.1 "@metamask/providers": 16.1.0 - "@metamask/sdk-communication-layer": 0.28.2 - "@metamask/sdk-install-modal-web": 0.28.1 - "@types/dom-screen-wake-lock": ^1.0.0 - "@types/uuid": ^10.0.0 + "@metamask/sdk-communication-layer": 0.31.0 + "@metamask/sdk-install-modal-web": 0.31.2 + "@paulmillr/qr": ^0.2.1 bowser: ^2.9.0 cross-fetch: ^4.0.0 debug: ^4.3.4 - eciesjs: ^0.3.15 + eciesjs: ^0.4.11 eth-rpc-errors: ^4.0.3 - eventemitter2: ^6.4.7 - i18next: 23.11.5 - i18next-browser-languagedetector: 7.1.0 + eventemitter2: ^6.4.9 obj-multiplex: ^1.0.0 pump: ^3.0.0 - qrcode-terminal-nooctal: ^0.12.1 - react-native-webview: ^11.26.0 readable-stream: ^3.6.2 - rollup-plugin-visualizer: ^5.9.2 socket.io-client: ^4.5.1 + tslib: ^2.6.0 util: ^0.12.4 uuid: ^8.3.2 - peerDependencies: - react: ^18.2.0 - react-dom: ^18.2.0 - peerDependenciesMeta: - react: - optional: true - react-dom: - optional: true - checksum: f51eb506b8614b8eae2015668eccb9c5924c31bbdfc050bfa788bd03349107d9281a52107021f6daf3888bd0bd15796605ce883b270b2c4a304f830bac15aaf7 + checksum: c77a15fd664ce0ffbc7962721985f0e5bc062a1b32e487c3df5eddb0ed0be3e6b0448418a5703bbeb86c50b249f4a59ff47758dd3d1d1cd1154a48aa23f485c7 languageName: node linkType: hard @@ -1734,7 +1780,7 @@ __metadata: languageName: node linkType: hard -"@noble/curves@npm:^1.6.0": +"@noble/curves@npm:1.7.0, @noble/curves@npm:^1.6.0, @noble/curves@npm:~1.7.0": version: 1.7.0 resolution: "@noble/curves@npm:1.7.0" dependencies: @@ -1743,6 +1789,22 @@ __metadata: languageName: node linkType: hard +"@noble/curves@npm:^1.5.0, @noble/curves@npm:~1.8.0": + version: 1.8.0 + resolution: "@noble/curves@npm:1.8.0" + dependencies: + "@noble/hashes": 1.7.0 + checksum: 88198bc5b8049358dfcc6c5e121125744fb81c703299127800f38f868a41697bc26bef8f88dc38f1939f4e0133b8db5f24337164eca7421a6a9480ee711f5e1b + languageName: node + linkType: hard + +"@noble/hashes@npm:1.3.2": + version: 1.3.2 + resolution: "@noble/hashes@npm:1.3.2" + checksum: fe23536b436539d13f90e4b9be843cc63b1b17666a07634a2b1259dded6f490be3d050249e6af98076ea8f2ea0d56f578773c2197f2aa0eeaa5fba5bc18ba474 + languageName: node + linkType: hard + "@noble/hashes@npm:1.4.0, @noble/hashes@npm:^1.3.1, @noble/hashes@npm:^1.4.0, @noble/hashes@npm:~1.4.0": version: 1.4.0 resolution: "@noble/hashes@npm:1.4.0" @@ -1757,13 +1819,20 @@ __metadata: languageName: node linkType: hard -"@noble/hashes@npm:^1.5.0": +"@noble/hashes@npm:1.6.1, @noble/hashes@npm:^1.5.0, @noble/hashes@npm:~1.6.0": version: 1.6.1 resolution: "@noble/hashes@npm:1.6.1" checksum: 57c62f65ee217c0293b4321b547792aa6d79812bfe70a7d62dc83e0f936cc677b14ed981b4e88cf8fdad37cd6d3a0cbd3bd0908b0728adc9daf066e678be8901 languageName: node linkType: hard +"@noble/hashes@npm:1.7.0, @noble/hashes@npm:~1.7.0": + version: 1.7.0 + resolution: "@noble/hashes@npm:1.7.0" + checksum: c06949ead7f5771a74f6fc9a346c7519212b3484c5b7916c8cad6b1b0e5f5f6c997ac3a43c0884ef8b99cfc55fac89058eefb29b6aad1cb41f436c748b316a1c + languageName: node + linkType: hard + "@noble/hashes@npm:~1.5.0": version: 1.5.0 resolution: "@noble/hashes@npm:1.5.0" @@ -2027,6 +2096,13 @@ __metadata: languageName: node linkType: hard +"@paulmillr/qr@npm:^0.2.1": + version: 0.2.1 + resolution: "@paulmillr/qr@npm:0.2.1" + checksum: 8a7b882f74f472759b0e5911c9c902a29c5232609373af4c5775625d9aad4ebda635d84c25be27e694144ba73d8e4204e72c3b9b59e9a375ec1d19f034a2d2ad + languageName: node + linkType: hard + "@pkgjs/parseargs@npm:^0.11.0": version: 0.11.0 resolution: "@pkgjs/parseargs@npm:0.11.0" @@ -2048,6 +2124,47 @@ __metadata: languageName: node linkType: hard +"@privy-io/cross-app-connect@npm:^0.1.2": + version: 0.1.2 + resolution: "@privy-io/cross-app-connect@npm:0.1.2" + dependencies: + "@noble/curves": ^1.5.0 + "@noble/hashes": 1.3.2 + "@scure/base": ~1.1.2 + peerDependencies: + "@rainbow-me/rainbowkit": ^2.1.5 + "@wagmi/core": ^2.13.4 + viem: ^2.21.3 + peerDependenciesMeta: + "@rainbow-me/rainbowkit": + optional: true + "@wagmi/core": + optional: true + checksum: 0b2f9d6f3b09f3f0fd7b087bb09fa073a07fdba48454c4d9ccee510fb2a3544b0d1cb1284ef952a94c6b35a1a18b49767069b774c21d14a1956a4ddaca840b6f + languageName: node + linkType: hard + +"@rainbow-me/rainbowkit@npm:^2.2.1": + version: 2.2.1 + resolution: "@rainbow-me/rainbowkit@npm:2.2.1" + dependencies: + "@vanilla-extract/css": 1.15.5 + "@vanilla-extract/dynamic": 2.1.2 + "@vanilla-extract/sprinkles": 1.6.3 + clsx: 2.1.1 + qrcode: 1.5.4 + react-remove-scroll: 2.6.0 + ua-parser-js: ^1.0.37 + peerDependencies: + "@tanstack/react-query": ">=5.0.0" + react: ">=18" + react-dom: ">=18" + viem: 2.x + wagmi: ^2.9.0 + checksum: 0647344590fe2970b2d0446b08a4b4d29af015992df0e8da47c17388fd7e8d1334d3a7aae4e574306950bb0ce51faef11d8713ed557e04d8bd92627938d91915 + languageName: node + linkType: hard + "@react-aria/focus@npm:^3.17.1": version: 3.18.2 resolution: "@react-aria/focus@npm:3.18.2" @@ -2123,10 +2240,10 @@ __metadata: languageName: node linkType: hard -"@revoke.cash/chains@npm:^59.0.0": - version: 59.0.0 - resolution: "@revoke.cash/chains@npm:59.0.0" - checksum: 3b4ac2525118b24918918c05d920d738ccb8526302ab09c94d4dc79f0cf0f2f08bea089d5e199e76840fd8404b332bd665055ff83e60d71e3d09fc6e117db965 +"@revoke.cash/chains@npm:^60.0.0": + version: 60.0.0 + resolution: "@revoke.cash/chains@npm:60.0.0" + checksum: ac9f65a2a916584f84031aa19b99f93b2e8f5e12bf9af16eeab9c608a24c3f897c48285a336bdca10a37bb746f6c515fdfddd61f02bee6366585f96d530eb5e4 languageName: node linkType: hard @@ -2139,13 +2256,13 @@ __metadata: languageName: node linkType: hard -"@safe-global/safe-apps-provider@npm:0.18.3": - version: 0.18.3 - resolution: "@safe-global/safe-apps-provider@npm:0.18.3" +"@safe-global/safe-apps-provider@npm:0.18.5": + version: 0.18.5 + resolution: "@safe-global/safe-apps-provider@npm:0.18.5" dependencies: "@safe-global/safe-apps-sdk": ^9.1.0 events: ^3.3.0 - checksum: e208df42fe49474d54847d8edd44efb601b5aafaf9e25537500db7fefb1172201a62f577c749f424b34932439dd7ebe461d33b23075cf6b80fb35ef841017a30 + checksum: 0d00a4f24c66a0f96d2808f918e1ee33aed5fc6454c3a3b7ca5419cbd420b30e6517991fc79cefb4dc54aec1dde5ec40154aeac1813dc32d39674cf53d86b303 languageName: node linkType: hard @@ -2173,6 +2290,20 @@ __metadata: languageName: node linkType: hard +"@scure/base@npm:~1.1.2": + version: 1.1.9 + resolution: "@scure/base@npm:1.1.9" + checksum: 120820a37dfe9dfe4cab2b7b7460552d08e67dee8057ed5354eb68d8e3440890ae983ce3bee957d2b45684950b454a2b6d71d5ee77c1fd3fddc022e2a510337f + languageName: node + linkType: hard + +"@scure/base@npm:~1.2.1": + version: 1.2.1 + resolution: "@scure/base@npm:1.2.1" + checksum: 061e04e4f6ed7bada6cdad4c799e6a82f30dda3f4008895bdb2e556f333f9b41f44dc067d25c064357ed6c012ea9c8be1e7927caf8a083af865b8de27b52370c + languageName: node + linkType: hard + "@scure/bip32@npm:1.4.0": version: 1.4.0 resolution: "@scure/bip32@npm:1.4.0" @@ -2184,6 +2315,28 @@ __metadata: languageName: node linkType: hard +"@scure/bip32@npm:1.6.0": + version: 1.6.0 + resolution: "@scure/bip32@npm:1.6.0" + dependencies: + "@noble/curves": ~1.7.0 + "@noble/hashes": ~1.6.0 + "@scure/base": ~1.2.1 + checksum: 1347477e28678a9bc4e2ec5e8e0f679263f2e3cb19c0e65849f76810c4c608461d4b283521c897249fa7dacc8c76e1b50e2a866b22467c8e93662a9c545cd42b + languageName: node + linkType: hard + +"@scure/bip32@npm:^1.5.0": + version: 1.6.1 + resolution: "@scure/bip32@npm:1.6.1" + dependencies: + "@noble/curves": ~1.8.0 + "@noble/hashes": ~1.7.0 + "@scure/base": ~1.2.1 + checksum: a3a604aab771c425ce2422965b7041fcbaefceb5a77f6c3a9b6a2a1530932dfdc8d8b4e9447164fe14e31969d09f8883e0f29176b07c86b880d23e0f88df3727 + languageName: node + linkType: hard + "@scure/bip39@npm:1.3.0": version: 1.3.0 resolution: "@scure/bip39@npm:1.3.0" @@ -2204,6 +2357,26 @@ __metadata: languageName: node linkType: hard +"@scure/bip39@npm:1.5.0": + version: 1.5.0 + resolution: "@scure/bip39@npm:1.5.0" + dependencies: + "@noble/hashes": ~1.6.0 + "@scure/base": ~1.2.1 + checksum: 03d1888f5d0d514eebc5c3adc1e071d225963d434fcf789abea5ef2c8b4b99f3ad9ebee8a597c0c13d5415e6b2b380f55f61560c1643cd871961ab91cbcf5122 + languageName: node + linkType: hard + +"@scure/bip39@npm:^1.4.0": + version: 1.5.1 + resolution: "@scure/bip39@npm:1.5.1" + dependencies: + "@noble/hashes": ~1.7.0 + "@scure/base": ~1.2.1 + checksum: 3069832465fc5b84602ee73271be22c47a7adb8459538b8121ad384e631f466703d7005b927db8b5554d70981e8c96bb99d5761cc45622786bfc555d46625e3e + languageName: node + linkType: hard + "@sinonjs/text-encoding@npm:0.7.2": version: 0.7.2 resolution: "@sinonjs/text-encoding@npm:0.7.2" @@ -2543,13 +2716,6 @@ __metadata: languageName: node linkType: hard -"@types/dom-screen-wake-lock@npm:^1.0.0": - version: 1.0.3 - resolution: "@types/dom-screen-wake-lock@npm:1.0.3" - checksum: 66bece3508b4f4147db97a530c758f8f5d3132ef00c06cab1db4bf2b4af6a3a614ae0a0ba6b53ddc4177a6545adf9d312547087256efc8eff7314b13221380b8 - languageName: node - linkType: hard - "@types/estree-jsx@npm:^1.0.0": version: 1.0.5 resolution: "@types/estree-jsx@npm:1.0.5" @@ -2701,15 +2867,6 @@ __metadata: languageName: node linkType: hard -"@types/secp256k1@npm:^4.0.6": - version: 4.0.6 - resolution: "@types/secp256k1@npm:4.0.6" - dependencies: - "@types/node": "*" - checksum: 984494caf49a4ce99fda2b9ea1840eb47af946b8c2737314108949bcc0c06b4880e871296bd49ed6ea4c8423e3a302ad79fec43abfc987330e7eb98f0c4e8ba4 - languageName: node - linkType: hard - "@types/sinonjs__fake-timers@npm:8.1.1": version: 8.1.1 resolution: "@types/sinonjs__fake-timers@npm:8.1.1" @@ -2745,13 +2902,6 @@ __metadata: languageName: node linkType: hard -"@types/uuid@npm:^10.0.0": - version: 10.0.0 - resolution: "@types/uuid@npm:10.0.0" - checksum: e3958f8b0fe551c86c14431f5940c3470127293280830684154b91dc7eb3514aeb79fe3216968833cf79d4d1c67f580f054b5be2cd562bebf4f728913e73e944 - languageName: node - linkType: hard - "@types/yauzl@npm:^2.9.1": version: 2.10.3 resolution: "@types/yauzl@npm:2.10.3" @@ -2795,6 +2945,51 @@ __metadata: languageName: node linkType: hard +"@vanilla-extract/css@npm:1.15.5": + version: 1.15.5 + resolution: "@vanilla-extract/css@npm:1.15.5" + dependencies: + "@emotion/hash": ^0.9.0 + "@vanilla-extract/private": ^1.0.6 + css-what: ^6.1.0 + cssesc: ^3.0.0 + csstype: ^3.0.7 + dedent: ^1.5.3 + deep-object-diff: ^1.1.9 + deepmerge: ^4.2.2 + lru-cache: ^10.4.3 + media-query-parser: ^2.0.2 + modern-ahocorasick: ^1.0.0 + picocolors: ^1.0.0 + checksum: 0c260e55a1648a827df74cae4475a1a61767e4ef3a7a3a299853ae3f77ed220d7a4b604737886140ea9e72a379eda4ee45b7349a4651cf3d5a4f2c8697448d6d + languageName: node + linkType: hard + +"@vanilla-extract/dynamic@npm:2.1.2": + version: 2.1.2 + resolution: "@vanilla-extract/dynamic@npm:2.1.2" + dependencies: + "@vanilla-extract/private": ^1.0.6 + checksum: ec6ec9b02c7ec8a9d60aebf63225fd3f930c06ad824321f03f683f1948eb6d4e554d934303da140b3230b4af2fa15bab494c6da2a3b9a172e4118c245b4f942a + languageName: node + linkType: hard + +"@vanilla-extract/private@npm:^1.0.6": + version: 1.0.6 + resolution: "@vanilla-extract/private@npm:1.0.6" + checksum: 2265b02af29d8cd40f6ddeeed197fb2df1a7695f5a9821d5e3597677179be8b83bcd8fe4df4a6178544f89123d745a3c6a13599d4fe4e5873b065a8ad329f690 + languageName: node + linkType: hard + +"@vanilla-extract/sprinkles@npm:1.6.3": + version: 1.6.3 + resolution: "@vanilla-extract/sprinkles@npm:1.6.3" + peerDependencies: + "@vanilla-extract/css": ^1.0.0 + checksum: 7eb4fe0f1a6048bf5ffb5ffab964c2d127ff95244da79dca2e448af380b591c7af3b4f63ab243584baa8a42c7694d8fe9eeb366587a2da381a481fe1a9e02af8 + languageName: node + linkType: hard + "@vercel/speed-insights@npm:^1.0.12": version: 1.0.12 resolution: "@vercel/speed-insights@npm:1.0.12" @@ -2822,35 +3017,34 @@ __metadata: languageName: node linkType: hard -"@wagmi/connectors@npm:5.1.10": - version: 5.1.10 - resolution: "@wagmi/connectors@npm:5.1.10" +"@wagmi/connectors@npm:5.7.3": + version: 5.7.3 + resolution: "@wagmi/connectors@npm:5.7.3" dependencies: - "@coinbase/wallet-sdk": 4.0.4 - "@metamask/sdk": 0.28.2 - "@safe-global/safe-apps-provider": 0.18.3 + "@coinbase/wallet-sdk": 4.2.3 + "@metamask/sdk": 0.31.4 + "@safe-global/safe-apps-provider": 0.18.5 "@safe-global/safe-apps-sdk": 9.1.0 - "@walletconnect/ethereum-provider": 2.16.1 - "@walletconnect/modal": 2.6.2 + "@walletconnect/ethereum-provider": 2.17.0 cbw-sdk: "npm:@coinbase/wallet-sdk@3.9.3" peerDependencies: - "@wagmi/core": 2.13.5 + "@wagmi/core": 2.16.3 typescript: ">=5.0.4" viem: 2.x peerDependenciesMeta: typescript: optional: true - checksum: ab6cfdd394bdda32582ed35f3785cc6f76a290837df6579ce6ef45884b6f1aabf74407ace5bc22d49a29110a0fecacff5db2a23648e89dc5f5842ea9373bfb46 + checksum: 52886c9dbc86b853c159337bb401346f57bd661a5858783fe9b2a84b248cc40cedeae77eec73c9d8b73a2e3fbfdccd28103362100006a2e6acf4ec0cd8edbde9 languageName: node linkType: hard -"@wagmi/core@npm:2.13.5": - version: 2.13.5 - resolution: "@wagmi/core@npm:2.13.5" +"@wagmi/core@npm:2.16.3": + version: 2.16.3 + resolution: "@wagmi/core@npm:2.16.3" dependencies: eventemitter3: 5.0.1 mipd: 0.0.7 - zustand: 4.4.1 + zustand: 5.0.0 peerDependencies: "@tanstack/query-core": ">=5.0.0" typescript: ">=5.0.4" @@ -2860,13 +3054,13 @@ __metadata: optional: true typescript: optional: true - checksum: e0fce057b613a36e35f43ceaaea3f300d92e37a53590d767cc4934035e0fff36dfe5c8ec64486fc78b3a11abcb10b0ac0b65f369ea0034afb5932572cb6f1187 + checksum: d5df7e351dfcf1656a422ac8c2f8847ca25b05a59003b4d68169abfb1b7d8c2feb308b9ddbe2b6040ec6bef959ab2080c63cb1c07c045d74fdfe5793750b7e0f languageName: node linkType: hard -"@walletconnect/core@npm:2.16.1": - version: 2.16.1 - resolution: "@walletconnect/core@npm:2.16.1" +"@walletconnect/core@npm:2.17.0": + version: 2.17.0 + resolution: "@walletconnect/core@npm:2.17.0" dependencies: "@walletconnect/heartbeat": 1.2.2 "@walletconnect/jsonrpc-provider": 1.0.14 @@ -2879,12 +3073,12 @@ __metadata: "@walletconnect/relay-auth": 1.0.4 "@walletconnect/safe-json": 1.0.2 "@walletconnect/time": 1.0.2 - "@walletconnect/types": 2.16.1 - "@walletconnect/utils": 2.16.1 + "@walletconnect/types": 2.17.0 + "@walletconnect/utils": 2.17.0 events: 3.3.0 lodash.isequal: 4.5.0 uint8arrays: 3.1.0 - checksum: ab658833fb845624ccb2d109c5218f5b4624b948b4a8b01bf22eb964c5e5d3cd890ee43645e196ad73d1be9a25d6a1bcd16a83893266ee1b30c9ec5377086820 + checksum: 97cd155fe79fe6dfc7128da6c38b6644209cf1840bc4c43fc76d691c3c0ba2fe544e5c61e5a8198886c3b037cc5551ed211523938793220db7f1effce705f4e2 languageName: node linkType: hard @@ -2897,21 +3091,21 @@ __metadata: languageName: node linkType: hard -"@walletconnect/ethereum-provider@npm:2.16.1": - version: 2.16.1 - resolution: "@walletconnect/ethereum-provider@npm:2.16.1" +"@walletconnect/ethereum-provider@npm:2.17.0": + version: 2.17.0 + resolution: "@walletconnect/ethereum-provider@npm:2.17.0" dependencies: "@walletconnect/jsonrpc-http-connection": 1.0.8 "@walletconnect/jsonrpc-provider": 1.0.14 "@walletconnect/jsonrpc-types": 1.0.4 "@walletconnect/jsonrpc-utils": 1.0.8 - "@walletconnect/modal": 2.6.2 - "@walletconnect/sign-client": 2.16.1 - "@walletconnect/types": 2.16.1 - "@walletconnect/universal-provider": 2.16.1 - "@walletconnect/utils": 2.16.1 + "@walletconnect/modal": 2.7.0 + "@walletconnect/sign-client": 2.17.0 + "@walletconnect/types": 2.17.0 + "@walletconnect/universal-provider": 2.17.0 + "@walletconnect/utils": 2.17.0 events: 3.3.0 - checksum: f88c6e41b7718a75452795efa7a1b51f5286aa728358a6b5f477e26f9c37e6cf5df1ec69fa227fe67674be53c2871296d767becbc23fc287ca6298a12d2c4984 + checksum: e851ed258f9a1ef45db00cf46b225a9dc2efb09e4503f4a711a48e14abf4fa3746fad60960791e14c87cebde855e8487fe29146f1b025644472bacb5bb1d3a0f languageName: node linkType: hard @@ -3018,34 +3212,34 @@ __metadata: languageName: node linkType: hard -"@walletconnect/modal-core@npm:2.6.2": - version: 2.6.2 - resolution: "@walletconnect/modal-core@npm:2.6.2" +"@walletconnect/modal-core@npm:2.7.0": + version: 2.7.0 + resolution: "@walletconnect/modal-core@npm:2.7.0" dependencies: valtio: 1.11.2 - checksum: 94daceba50c323b06ecbeac2968d9f0972f327359c6118887c6526cd64006249b12f64322d71bc6c4a2b928436ecc89cf3d3af706511fcdc264c1f4b34a2dd5d + checksum: 2abc4958eed0f65b3f03599f25f7393f06c94602df8ffceb59795e9da6ab3a36242520ee7f1e0733b14278422e9bbba5f850915b0b069f7f0a8f2d48c51365de languageName: node linkType: hard -"@walletconnect/modal-ui@npm:2.6.2": - version: 2.6.2 - resolution: "@walletconnect/modal-ui@npm:2.6.2" +"@walletconnect/modal-ui@npm:2.7.0": + version: 2.7.0 + resolution: "@walletconnect/modal-ui@npm:2.7.0" dependencies: - "@walletconnect/modal-core": 2.6.2 + "@walletconnect/modal-core": 2.7.0 lit: 2.8.0 motion: 10.16.2 qrcode: 1.5.3 - checksum: cd1ec0205eb491e529670599d3dd26f6782d7c5a99d5594bf6949a8c760c1c5f4eb6ed72b8662450774fe4e2dd47678f2c05145c8f2494bd7153446ddf4bd7ed + checksum: fbea115142df9aeeaa95eeb08581d03d829a5bef1aa145227f3e8c367e4ad990c0b833da37fe82464bf1349744197092a741ca85d3fe9ee255e42ba911f862cc languageName: node linkType: hard -"@walletconnect/modal@npm:2.6.2": - version: 2.6.2 - resolution: "@walletconnect/modal@npm:2.6.2" +"@walletconnect/modal@npm:2.7.0": + version: 2.7.0 + resolution: "@walletconnect/modal@npm:2.7.0" dependencies: - "@walletconnect/modal-core": 2.6.2 - "@walletconnect/modal-ui": 2.6.2 - checksum: 68b354d49960b96d22de0e47a3801df27c01a3e96ec5fbde3ca6df1344ca2b20668b0c4d58fe1803f5670ac7b7b4c6f5b7b405e354f5f9eaff5cca147c13de9c + "@walletconnect/modal-core": 2.7.0 + "@walletconnect/modal-ui": 2.7.0 + checksum: 028e914db306faac24e350510ea286f08c2aec1b6c39857b2ba8740f7d1bfab6a6c4d2acba5ab63fc127fd7da617ec80ab13599083363f13e72e2aff611615bf languageName: node linkType: hard @@ -3081,20 +3275,20 @@ __metadata: languageName: node linkType: hard -"@walletconnect/sign-client@npm:2.16.1": - version: 2.16.1 - resolution: "@walletconnect/sign-client@npm:2.16.1" +"@walletconnect/sign-client@npm:2.17.0": + version: 2.17.0 + resolution: "@walletconnect/sign-client@npm:2.17.0" dependencies: - "@walletconnect/core": 2.16.1 + "@walletconnect/core": 2.17.0 "@walletconnect/events": 1.0.1 "@walletconnect/heartbeat": 1.2.2 "@walletconnect/jsonrpc-utils": 1.0.8 "@walletconnect/logger": 2.1.2 "@walletconnect/time": 1.0.2 - "@walletconnect/types": 2.16.1 - "@walletconnect/utils": 2.16.1 + "@walletconnect/types": 2.17.0 + "@walletconnect/utils": 2.17.0 events: 3.3.0 - checksum: e25808e2fbfc01cff47391281e7cb050927cde2e83f5eec640e5be52c8adc9ee50bd70447a2e72defc9cad3d3e3009ef48ac7d1b694dafa5d6a62e046863b58a + checksum: 980c747a815c7016191086597f295268a4f285a5a830d6d80b2896bc6f6ca4a2528bae3c16bde83d2524b94553feb6fe74fd041de8d95d54dc6fd7f0613e87e2 languageName: node linkType: hard @@ -3107,9 +3301,9 @@ __metadata: languageName: node linkType: hard -"@walletconnect/types@npm:2.16.1": - version: 2.16.1 - resolution: "@walletconnect/types@npm:2.16.1" +"@walletconnect/types@npm:2.17.0": + version: 2.17.0 + resolution: "@walletconnect/types@npm:2.17.0" dependencies: "@walletconnect/events": 1.0.1 "@walletconnect/heartbeat": 1.2.2 @@ -3117,30 +3311,30 @@ __metadata: "@walletconnect/keyvaluestorage": 1.1.1 "@walletconnect/logger": 2.1.2 events: 3.3.0 - checksum: 9ea47bfb0d5db8f0e440e040d55b05b4932aa3f56e976d42290e831c39d4bc5f2d4cd400f64ca86d8a6a195e34d6370f8db878f7b339ff7cac60a12bbfd9e445 + checksum: 0dd1eecd69a90a920f7cd33baeb1613f11ca24466783482752435b80a9362fd8f55b0d21c03073d97c20224f932d3fafc72fe8f6defeb0d1a139e8f10cc58aa3 languageName: node linkType: hard -"@walletconnect/universal-provider@npm:2.16.1": - version: 2.16.1 - resolution: "@walletconnect/universal-provider@npm:2.16.1" +"@walletconnect/universal-provider@npm:2.17.0": + version: 2.17.0 + resolution: "@walletconnect/universal-provider@npm:2.17.0" dependencies: "@walletconnect/jsonrpc-http-connection": 1.0.8 "@walletconnect/jsonrpc-provider": 1.0.14 "@walletconnect/jsonrpc-types": 1.0.4 "@walletconnect/jsonrpc-utils": 1.0.8 "@walletconnect/logger": 2.1.2 - "@walletconnect/sign-client": 2.16.1 - "@walletconnect/types": 2.16.1 - "@walletconnect/utils": 2.16.1 + "@walletconnect/sign-client": 2.17.0 + "@walletconnect/types": 2.17.0 + "@walletconnect/utils": 2.17.0 events: 3.3.0 - checksum: 2852ff1b1b06628bf08015ade517f73b743f11873f56e4358063668fd13c290adc648274cc965b34789f2c91879ec338135b42c01e466a2ef76e82ccec74400e + checksum: c7bb25a571ad5e354bd5e2aceabab3468def3b47a7ea83e0e93278b3c33c5a68a751e95bc526cd3b27c071cfabf37cda72736315c1416fcf226100b75c74c363 languageName: node linkType: hard -"@walletconnect/utils@npm:2.16.1": - version: 2.16.1 - resolution: "@walletconnect/utils@npm:2.16.1" +"@walletconnect/utils@npm:2.17.0": + version: 2.17.0 + resolution: "@walletconnect/utils@npm:2.17.0" dependencies: "@stablelib/chacha20poly1305": 1.0.1 "@stablelib/hkdf": 1.0.1 @@ -3151,14 +3345,14 @@ __metadata: "@walletconnect/relay-auth": 1.0.4 "@walletconnect/safe-json": 1.0.2 "@walletconnect/time": 1.0.2 - "@walletconnect/types": 2.16.1 + "@walletconnect/types": 2.17.0 "@walletconnect/window-getters": 1.0.1 "@walletconnect/window-metadata": 1.0.1 detect-browser: 5.3.0 elliptic: ^6.5.7 query-string: 7.1.3 uint8arrays: 3.1.0 - checksum: 404c5f262e020c208ab30283c1dbe23f7a4876d3d89ebb23dde95ea32deb8ada72886d64151f6a826d21774797fa44feed70d33729661aa0de4b6850b3ace0d5 + checksum: 093e508718f1c770b1ff05442376add40ecbaffa8cb5c8cfdf76786d6422e33afdb39d4b7b374a3b65330a4da2cbb71a2c552b041831295a12006dc29cb32340 languageName: node linkType: hard @@ -3222,6 +3416,36 @@ __metadata: languageName: node linkType: hard +"abitype@npm:1.0.7": + version: 1.0.7 + resolution: "abitype@npm:1.0.7" + peerDependencies: + typescript: ">=5.0.4" + zod: ^3 >=3.22.0 + peerDependenciesMeta: + typescript: + optional: true + zod: + optional: true + checksum: c3b3ee19becbbce1d5c55a40a13dee6c09c0d710eee9c601433eb496c5ee2cd39e97dd0d043fa1ff7e68b1239ef83fe56951b2009d467e989fe941785cd7f8b8 + languageName: node + linkType: hard + +"abitype@npm:^1.0.6": + version: 1.0.8 + resolution: "abitype@npm:1.0.8" + peerDependencies: + typescript: ">=5.0.4" + zod: ^3 >=3.22.0 + peerDependenciesMeta: + typescript: + optional: true + zod: + optional: true + checksum: 104bc2f6820ced8d2cb61521916f7f22c0981a846216f5b6144f69461265f7da137a4ae108bf4b84cd8743f2dd1e9fdadffc0f95371528e15a59e0a369e08438 + languageName: node + linkType: hard + "abort-controller@npm:3.0.0": version: 3.0.0 resolution: "abort-controller@npm:3.0.0" @@ -4091,6 +4315,13 @@ __metadata: languageName: node linkType: hard +"clsx@npm:2.1.1, clsx@npm:^2.0.0, clsx@npm:^2.1.0": + version: 2.1.1 + resolution: "clsx@npm:2.1.1" + checksum: acd3e1ab9d8a433ecb3cc2f6a05ab95fe50b4a3cfc5ba47abb6cbf3754585fcb87b84e90c822a1f256c4198e3b41c7f6c391577ffc8678ad587fc0976b24fd57 + languageName: node + linkType: hard + "clsx@npm:^1.2.1": version: 1.2.1 resolution: "clsx@npm:1.2.1" @@ -4098,13 +4329,6 @@ __metadata: languageName: node linkType: hard -"clsx@npm:^2.0.0, clsx@npm:^2.1.0": - version: 2.1.1 - resolution: "clsx@npm:2.1.1" - checksum: acd3e1ab9d8a433ecb3cc2f6a05ab95fe50b4a3cfc5ba47abb6cbf3754585fcb87b84e90c822a1f256c4198e3b41c7f6c391577ffc8678ad587fc0976b24fd57 - languageName: node - linkType: hard - "cmd-shim@npm:^6.0.0": version: 6.0.3 resolution: "cmd-shim@npm:6.0.3" @@ -4427,6 +4651,13 @@ __metadata: languageName: node linkType: hard +"css-what@npm:^6.1.0": + version: 6.1.0 + resolution: "css-what@npm:6.1.0" + checksum: b975e547e1e90b79625918f84e67db5d33d896e6de846c9b584094e529f0c63e2ab85ee33b9daffd05bff3a146a1916bec664e18bb76dd5f66cbff9fc13b2bbe + languageName: node + linkType: hard + "cssesc@npm:^3.0.0": version: 3.0.0 resolution: "cssesc@npm:3.0.0" @@ -4436,7 +4667,7 @@ __metadata: languageName: node linkType: hard -"csstype@npm:^3.0.2": +"csstype@npm:^3.0.2, csstype@npm:^3.0.7": version: 3.1.3 resolution: "csstype@npm:3.1.3" checksum: 8db785cc92d259102725b3c694ec0c823f5619a84741b5c7991b8ad135dfaa66093038a1cc63e03361a6cd28d122be48f2106ae72334e067dd619a51f49eddf7 @@ -4585,6 +4816,18 @@ __metadata: languageName: node linkType: hard +"dedent@npm:^1.5.3": + version: 1.5.3 + resolution: "dedent@npm:1.5.3" + peerDependencies: + babel-plugin-macros: ^3.1.0 + peerDependenciesMeta: + babel-plugin-macros: + optional: true + checksum: 045b595557b2a8ea2eb9b0b4623d764e9a87326486fe2b61191b4342ed93dc01245644d8a09f3108a50c0ee7965f1eedd92e4a3a503ed89ea8e810566ea27f9a + languageName: node + linkType: hard + "deep-eql@npm:^5.0.1": version: 5.0.2 resolution: "deep-eql@npm:5.0.2" @@ -4592,6 +4835,20 @@ __metadata: languageName: node linkType: hard +"deep-object-diff@npm:^1.1.9": + version: 1.1.9 + resolution: "deep-object-diff@npm:1.1.9" + checksum: ecd42455e4773f653595d28070295e7aaa8402db5f8ab21d0bec115a7cb4de5e207a5665514767da5f025c96597f1d3a0a4888aeb4dd49e03c996871a3aa05ef + languageName: node + linkType: hard + +"deepmerge@npm:^4.2.2": + version: 4.3.1 + resolution: "deepmerge@npm:4.3.1" + checksum: 2024c6a980a1b7128084170c4cf56b0fd58a63f2da1660dcfe977415f27b17dbe5888668b59d0b063753f3220719d5e400b7f113609489c90160bb9a5518d052 + languageName: node + linkType: hard + "define-data-property@npm:^1.1.4": version: 1.1.4 resolution: "define-data-property@npm:1.1.4" @@ -4661,6 +4918,13 @@ __metadata: languageName: node linkType: hard +"detect-node-es@npm:^1.1.0": + version: 1.1.0 + resolution: "detect-node-es@npm:1.1.0" + checksum: e46307d7264644975b71c104b9f028ed1d3d34b83a15b8a22373640ce5ea630e5640b1078b8ea15f202b54641da71e4aa7597093bd4b91f113db520a26a37449 + languageName: node + linkType: hard + "devlop@npm:^1.0.0, devlop@npm:^1.1.0": version: 1.1.0 resolution: "devlop@npm:1.1.0" @@ -4776,17 +5040,6 @@ __metadata: languageName: node linkType: hard -"eciesjs@npm:^0.3.15": - version: 0.3.20 - resolution: "eciesjs@npm:0.3.20" - dependencies: - "@types/secp256k1": ^4.0.6 - futoin-hkdf: ^1.5.3 - secp256k1: ^5.0.0 - checksum: 449e56a4e5ce812313c38d876d5874f8b5740750288de4f1059ea1016716ceb006cba6b3126c08aafd3bcdc5c1ad8d6ca67e44bc2f434bb01ed14040aa067e47 - languageName: node - linkType: hard - "eciesjs@npm:^0.4.10": version: 0.4.12 resolution: "eciesjs@npm:0.4.12" @@ -4799,6 +5052,18 @@ __metadata: languageName: node linkType: hard +"eciesjs@npm:^0.4.11": + version: 0.4.13 + resolution: "eciesjs@npm:0.4.13" + dependencies: + "@ecies/ciphers": ^0.2.2 + "@noble/ciphers": ^1.0.0 + "@noble/curves": ^1.6.0 + "@noble/hashes": ^1.5.0 + checksum: d5c66e2b4c6590e09a5b0fbb3b3ce63f31155b7ebd9e89a693035f623177166b850364ba74b9f44dfb17f3c7206d7b8d49f0d27760ea7f99a44b81cf959d36cb + languageName: node + linkType: hard + "electron-to-chromium@npm:^1.5.4": version: 1.5.22 resolution: "electron-to-chromium@npm:1.5.22" @@ -4806,7 +5071,7 @@ __metadata: languageName: node linkType: hard -"elliptic@npm:^6.5.4, elliptic@npm:^6.5.7": +"elliptic@npm:^6.5.7": version: 6.5.7 resolution: "elliptic@npm:6.5.7" dependencies: @@ -5033,13 +5298,6 @@ __metadata: languageName: node linkType: hard -"escape-string-regexp@npm:2.0.0": - version: 2.0.0 - resolution: "escape-string-regexp@npm:2.0.0" - checksum: 9f8a2d5743677c16e85c810e3024d54f0c8dea6424fad3c79ef6666e81dd0846f7437f5e729dfcdac8981bc9e5294c39b4580814d114076b8d36318f46ae4395 - languageName: node - linkType: hard - "escape-string-regexp@npm:^1.0.5": version: 1.0.5 resolution: "escape-string-regexp@npm:1.0.5" @@ -5142,13 +5400,20 @@ __metadata: languageName: node linkType: hard -"eventemitter2@npm:6.4.7, eventemitter2@npm:^6.4.7": +"eventemitter2@npm:6.4.7": version: 6.4.7 resolution: "eventemitter2@npm:6.4.7" checksum: 1b36a77e139d6965ebf3a36c01fa00c089ae6b80faa1911e52888f40b3a7057b36a2cc45dcd1ad87cda3798fe7b97a0aabcbb8175a8b96092a23bb7d0f039e66 languageName: node linkType: hard +"eventemitter2@npm:^6.4.9": + version: 6.4.9 + resolution: "eventemitter2@npm:6.4.9" + checksum: be59577c1e1c35509c7ba0e2624335c35bbcfd9485b8a977384c6cc6759341ea1a98d3cb9dbaa5cea4fff9b687e504504e3f9c2cc1674cf3bd8a43a7c74ea3eb + languageName: node + linkType: hard + "eventemitter3@npm:5.0.1, eventemitter3@npm:^5.0.1": version: 5.0.1 resolution: "eventemitter3@npm:5.0.1" @@ -5571,13 +5836,6 @@ __metadata: languageName: node linkType: hard -"futoin-hkdf@npm:^1.5.3": - version: 1.5.3 - resolution: "futoin-hkdf@npm:1.5.3" - checksum: 790da5675b31df4b9a34c19a5181f673171b5ad81fa92b91981bcfd2250692f895d6aada5ae4203212babba3c7d7a1916432e0b42c7aa88d3f70408439ec315e - languageName: node - linkType: hard - "get-caller-file@npm:^2.0.1, get-caller-file@npm:^2.0.5": version: 2.0.5 resolution: "get-caller-file@npm:2.0.5" @@ -5612,6 +5870,13 @@ __metadata: languageName: node linkType: hard +"get-nonce@npm:^1.0.0": + version: 1.0.1 + resolution: "get-nonce@npm:1.0.1" + checksum: e2614e43b4694c78277bb61b0f04583d45786881289285c73770b07ded246a98be7e1f78b940c80cbe6f2b07f55f0b724e6db6fd6f1bcbd1e8bdac16521074ed + languageName: node + linkType: hard + "get-port-please@npm:^3.1.2": version: 3.1.2 resolution: "get-port-please@npm:3.1.2" @@ -6119,24 +6384,6 @@ __metadata: languageName: node linkType: hard -"i18next-browser-languagedetector@npm:7.1.0": - version: 7.1.0 - resolution: "i18next-browser-languagedetector@npm:7.1.0" - dependencies: - "@babel/runtime": ^7.19.4 - checksum: 36981b9a9995ed66387f3735cceffe107ed3cdb6ca278d45fa243fabc65669c0eca095ed4a55a93dac046ca1eb23fd986ec0079723be7ebb8505e6ba25f379bb - languageName: node - linkType: hard - -"i18next@npm:23.11.5": - version: 23.11.5 - resolution: "i18next@npm:23.11.5" - dependencies: - "@babel/runtime": ^7.23.2 - checksum: e9ec83703af59205af81f10929fd420314c0c976d1f4c42a191dc4d13f1284d13517105325286772571292953839c7183baa92e9bb43f41efe87dbc50c9aed1c - languageName: node - linkType: hard - "iconv-lite@npm:^0.6.2": version: 0.6.3 resolution: "iconv-lite@npm:0.6.3" @@ -6255,15 +6502,6 @@ __metadata: languageName: node linkType: hard -"invariant@npm:2.2.4": - version: 2.2.4 - resolution: "invariant@npm:2.2.4" - dependencies: - loose-envify: ^1.0.0 - checksum: cc3182d793aad82a8d1f0af697b462939cb46066ec48bbf1707c150ad5fad6406137e91a262022c269702e01621f35ef60269f6c0d7fd178487959809acdfb14 - languageName: node - linkType: hard - "ip-address@npm:^9.0.5": version: 9.0.5 resolution: "ip-address@npm:9.0.5" @@ -6660,6 +6898,15 @@ __metadata: languageName: node linkType: hard +"isows@npm:1.0.6": + version: 1.0.6 + resolution: "isows@npm:1.0.6" + peerDependencies: + ws: "*" + checksum: ab9e85b50bcc3d70aa5ec875aa2746c5daf9321cb376ed4e5434d3c2643c5d62b1f466d93a05cd2ad0ead5297224922748c31707cb4fbd68f5d05d0479dce99c + languageName: node + linkType: hard + "isstream@npm:~0.1.2": version: 0.1.2 resolution: "isstream@npm:0.1.2" @@ -7175,7 +7422,7 @@ __metadata: languageName: node linkType: hard -"loose-envify@npm:^1.0.0, loose-envify@npm:^1.1.0, loose-envify@npm:^1.4.0": +"loose-envify@npm:^1.1.0, loose-envify@npm:^1.4.0": version: 1.4.0 resolution: "loose-envify@npm:1.4.0" dependencies: @@ -7483,6 +7730,15 @@ __metadata: languageName: node linkType: hard +"media-query-parser@npm:^2.0.2": + version: 2.0.2 + resolution: "media-query-parser@npm:2.0.2" + dependencies: + "@babel/runtime": ^7.12.5 + checksum: 8ef956d9e63fe6f4041988beda69843b3a6bb48228ea2923a066f6e7c8f7c5dba75fae357318c48a97ed5beae840b8425cb7e727fc1bb77acc65f2005f8945ab + languageName: node + linkType: hard + "memoize-one@npm:^6.0.0": version: 6.0.0 resolution: "memoize-one@npm:6.0.0" @@ -8130,6 +8386,13 @@ __metadata: languageName: node linkType: hard +"modern-ahocorasick@npm:^1.0.0": + version: 1.1.0 + resolution: "modern-ahocorasick@npm:1.1.0" + checksum: 78b99840c9af086c1e36a594ee85bebd8c19d48e2ef31a67d1bad0e673ac12fc931e5961abb5b16daaf820af4923e700f76b1793b7413e18782230162866a0af + languageName: node + linkType: hard + "motion@npm:10.16.2": version: 10.16.2 resolution: "motion@npm:10.16.2" @@ -8339,15 +8602,6 @@ __metadata: languageName: node linkType: hard -"node-addon-api@npm:^5.0.0": - version: 5.1.0 - resolution: "node-addon-api@npm:5.1.0" - dependencies: - node-gyp: latest - checksum: 2508bd2d2981945406243a7bd31362fc7af8b70b8b4d65f869c61731800058fb818cc2fd36c8eac714ddd0e568cc85becf5e165cebbdf7b5024d5151bbc75ea1 - languageName: node - linkType: hard - "node-addon-api@npm:^7.0.0": version: 7.1.1 resolution: "node-addon-api@npm:7.1.1" @@ -8672,6 +8926,26 @@ __metadata: languageName: node linkType: hard +"ox@npm:0.6.0": + version: 0.6.0 + resolution: "ox@npm:0.6.0" + dependencies: + "@adraffy/ens-normalize": ^1.10.1 + "@noble/curves": ^1.6.0 + "@noble/hashes": ^1.5.0 + "@scure/bip32": ^1.5.0 + "@scure/bip39": ^1.4.0 + abitype: ^1.0.6 + eventemitter3: 5.0.1 + peerDependencies: + typescript: ">=5.4.0" + peerDependenciesMeta: + typescript: + optional: true + checksum: 7d4bbdcadc5e62290e34767a0f1b5fdd7d3bd3e6db7fc5a5d7f42cc4b55d39aa4e1228196711179b764392320dd2f211b963c710efd6bc45a1ae648596ec9df9 + languageName: node + linkType: hard + "p-limit@npm:^2.2.0": version: 2.3.0 resolution: "p-limit@npm:2.3.0" @@ -9217,6 +9491,13 @@ __metadata: languageName: node linkType: hard +"preact@npm:^10.24.2": + version: 10.25.4 + resolution: "preact@npm:10.25.4" + checksum: 309f3128267c5bcac828c70a7a97fba0fdfed7b9ef2ece32a50bf94d257b5c825975df0648d9d5c79f90201d3a295cb2c9f511640aca37cb6879e509688b885a + languageName: node + linkType: hard + "pretty-bytes@npm:^5.6.0": version: 5.6.0 resolution: "pretty-bytes@npm:5.6.0" @@ -9348,31 +9629,6 @@ __metadata: languageName: node linkType: hard -"qr-code-styling@npm:^1.6.0-rc.1": - version: 1.6.0-rc.1 - resolution: "qr-code-styling@npm:1.6.0-rc.1" - dependencies: - qrcode-generator: ^1.4.3 - checksum: 778754790fe0b586ecd38fb02de777c7dd9cf844cf6e3c88f9a23ad85b122200a8567c946e3c41dba84ddd2f0016aa31ddfd1507150e1dbfea8a58323b62d944 - languageName: node - linkType: hard - -"qrcode-generator@npm:^1.4.3": - version: 1.4.4 - resolution: "qrcode-generator@npm:1.4.4" - checksum: 860cfdd2a7a608d34e92cab99774cc08182e1911432f30ed36d16f8a5cdabd7fdf40239caed91fa2691cfe66c8d95c1340a2fc9cc439eed07a9f2eb328c6f527 - languageName: node - linkType: hard - -"qrcode-terminal-nooctal@npm:^0.12.1": - version: 0.12.1 - resolution: "qrcode-terminal-nooctal@npm:0.12.1" - bin: - qrcode-terminal: bin/qrcode-terminal.js - checksum: 1071c4be2bfa07b3956ad0a63c87452ced0b5180a9dc19f224fc3dd69bb24ad687a7af365acdde0f876ddf89dc1a4beadba88d89c7c5c5cbf2ef3efaef64736e - languageName: node - linkType: hard - "qrcode@npm:1.5.3": version: 1.5.3 resolution: "qrcode@npm:1.5.3" @@ -9387,6 +9643,19 @@ __metadata: languageName: node linkType: hard +"qrcode@npm:1.5.4": + version: 1.5.4 + resolution: "qrcode@npm:1.5.4" + dependencies: + dijkstrajs: ^1.0.1 + pngjs: ^5.0.0 + yargs: ^15.3.1 + bin: + qrcode: bin/qrcode + checksum: 0a162822e12c02b0333315462fd4ccad22255002130f86806773be7592aec5ef295efaffa3eb148cbf00e290839c7b610f63b0d62a0c5efc5bc52a68f4189684 + languageName: node + linkType: hard + "qs@npm:6.10.4": version: 6.10.4 resolution: "qs@npm:6.10.4" @@ -9520,16 +9789,38 @@ __metadata: languageName: node linkType: hard -"react-native-webview@npm:^11.26.0": - version: 11.26.1 - resolution: "react-native-webview@npm:11.26.1" +"react-remove-scroll-bar@npm:^2.3.6": + version: 2.3.8 + resolution: "react-remove-scroll-bar@npm:2.3.8" dependencies: - escape-string-regexp: 2.0.0 - invariant: 2.2.4 + react-style-singleton: ^2.2.2 + tslib: ^2.0.0 peerDependencies: - react: "*" - react-native: "*" - checksum: d2f95a89e944a2f1e8cf402e4e274f3568edae42e7ef190915e9fba8004a01d699c962459bdc9688c159060538e90aea3017cab24e6f4112021cbbc10ef57104 + "@types/react": "*" + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + "@types/react": + optional: true + checksum: c4663247f689dbe51c370836edf735487f6d8796acb7f15b09e8a1c14e84c7997360e8e3d54de2bc9c0e782fed2b2c4127d15b4053e4d2cf26839e809e57605f + languageName: node + linkType: hard + +"react-remove-scroll@npm:2.6.0": + version: 2.6.0 + resolution: "react-remove-scroll@npm:2.6.0" + dependencies: + react-remove-scroll-bar: ^2.3.6 + react-style-singleton: ^2.2.1 + tslib: ^2.1.0 + use-callback-ref: ^1.3.0 + use-sidecar: ^1.1.2 + peerDependencies: + "@types/react": ^16.8.0 || ^17.0.0 || ^18.0.0 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + "@types/react": + optional: true + checksum: e7ad2383ce20d63cf28f3ed14e63f684e139301fc4a5c1573da330d4465b733e6084c33b2bfcaee448c9b1df0e37993a15d6cba8a1dd80fe631f803e48e9f798 languageName: node linkType: hard @@ -9571,6 +9862,22 @@ __metadata: languageName: node linkType: hard +"react-style-singleton@npm:^2.2.1, react-style-singleton@npm:^2.2.2": + version: 2.2.3 + resolution: "react-style-singleton@npm:2.2.3" + dependencies: + get-nonce: ^1.0.0 + tslib: ^2.0.0 + peerDependencies: + "@types/react": "*" + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + checksum: a7b0bf493c9231065ebafa84c4237aed997c746c561196121b7de82fe155a5355b372db5070a3ac9fe980cf7f60dc0f1e8cf6402a2aa5b2957392932ccf76e76 + languageName: node + linkType: hard + "react-syntax-highlighter@npm:^15.5.0": version: 15.5.0 resolution: "react-syntax-highlighter@npm:15.5.0" @@ -9899,6 +10206,8 @@ __metadata: version: 0.0.0-use.local resolution: "revoke.cash@workspace:." dependencies: + "@abstract-foundation/agw-client": ^1.0.0 + "@abstract-foundation/agw-react": ^1.0.0 "@biomejs/biome": ^1.9.4 "@commitlint/cli": ^19.6.0 "@commitlint/config-conventional": ^19.6.0 @@ -9909,7 +10218,9 @@ __metadata: "@lavamoat/allow-scripts": ^3.2.0 "@localazy/cli": ^1.7.14 "@neondatabase/serverless": ^0.10.1 - "@revoke.cash/chains": ^59.0.0 + "@privy-io/cross-app-connect": ^0.1.2 + "@rainbow-me/rainbowkit": ^2.2.1 + "@revoke.cash/chains": ^60.0.0 "@tailwindcss/typography": ^0.5.14 "@tanstack/query-sync-storage-persister": ^5.52.0 "@tanstack/react-query": ^5.52.0 @@ -9973,8 +10284,8 @@ __metadata: tsx: ^4.17.0 typescript: ^5.5.4 use-local-storage: ^3.0.0 - viem: ^2.19.9 - wagmi: ^2.12.7 + viem: ^2.22.2 + wagmi: ^2.14.6 walkdir: ^0.4.1 zustand: ^5.0.0-rc.2 languageName: unknown @@ -9987,25 +10298,6 @@ __metadata: languageName: node linkType: hard -"rollup-plugin-visualizer@npm:^5.9.2": - version: 5.12.0 - resolution: "rollup-plugin-visualizer@npm:5.12.0" - dependencies: - open: ^8.4.0 - picomatch: ^2.3.1 - source-map: ^0.7.4 - yargs: ^17.5.1 - peerDependencies: - rollup: 2.x || 3.x || 4.x - peerDependenciesMeta: - rollup: - optional: true - bin: - rollup-plugin-visualizer: dist/bin/cli.js - checksum: 17dc10a93d4bd457c8bb7796a57c284487fb00f4b9703a33a1a954f5d40c66a89b24aca98564569922456f4fa8f72281c3ef96a95502195e6930b3fac62fce8e - languageName: node - linkType: hard - "rrdom@npm:^2.0.0-alpha.13": version: 2.0.0-alpha.16 resolution: "rrdom@npm:2.0.0-alpha.16" @@ -10093,18 +10385,6 @@ __metadata: languageName: node linkType: hard -"secp256k1@npm:^5.0.0": - version: 5.0.0 - resolution: "secp256k1@npm:5.0.0" - dependencies: - elliptic: ^6.5.4 - node-addon-api: ^5.0.0 - node-gyp: latest - node-gyp-build: ^4.2.0 - checksum: a0719dff4687c38d385b5e0b7e811c51a4ea24893128be9d097aee99f879eb0ea52582590deb15a49da627a3db23c6b028ad5c9c6ac1fca92ce760153b8cf21c - languageName: node - linkType: hard - "section-matter@npm:^1.0.0": version: 1.0.0 resolution: "section-matter@npm:1.0.0" @@ -10426,13 +10706,6 @@ __metadata: languageName: node linkType: hard -"source-map@npm:^0.7.4": - version: 0.7.4 - resolution: "source-map@npm:0.7.4" - checksum: 01cc5a74b1f0e1d626a58d36ad6898ea820567e87f18dfc9d24a9843a351aaa2ec09b87422589906d6ff1deed29693e176194dc88bcae7c9a852dc74b311dbf5 - languageName: node - linkType: hard - "space-separated-tokens@npm:^1.0.0": version: 1.1.5 resolution: "space-separated-tokens@npm:1.1.5" @@ -11006,6 +11279,13 @@ __metadata: languageName: node linkType: hard +"tslib@npm:^2.6.0": + version: 2.8.1 + resolution: "tslib@npm:2.8.1" + checksum: e4aba30e632b8c8902b47587fd13345e2827fa639e7c3121074d5ee0880723282411a8838f830b55100cbe4517672f84a2472667d355b81e8af165a55dc6203a + languageName: node + linkType: hard + "tsx@npm:^4.17.0": version: 4.19.1 resolution: "tsx@npm:4.19.1" @@ -11065,6 +11345,15 @@ __metadata: languageName: node linkType: hard +"ua-parser-js@npm:^1.0.37": + version: 1.0.40 + resolution: "ua-parser-js@npm:1.0.40" + bin: + ua-parser-js: script/cli.js + checksum: ae555a33dc9395dd877e295d6adbf5634e047aad7c3358328830218f3ca3a6233e35848cd355465a7612f269860e8029984389282940c7a27c9af4dfcdbba8c3 + languageName: node + linkType: hard + "ufo@npm:^1.4.0, ufo@npm:^1.5.3, ufo@npm:^1.5.4": version: 1.5.4 resolution: "ufo@npm:1.5.4" @@ -11339,6 +11628,21 @@ __metadata: languageName: node linkType: hard +"use-callback-ref@npm:^1.3.0": + version: 1.3.3 + resolution: "use-callback-ref@npm:1.3.3" + dependencies: + tslib: ^2.0.0 + peerDependencies: + "@types/react": "*" + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 4da1c82d7a2409cee6c882748a40f4a083decf238308bf12c3d0166f0e338f8d512f37b8d11987eb5a421f14b9b5b991edf3e11ed25c3bb7a6559081f8359b44 + languageName: node + linkType: hard + "use-intl@npm:^3.19.1": version: 3.19.1 resolution: "use-intl@npm:3.19.1" @@ -11372,6 +11676,22 @@ __metadata: languageName: node linkType: hard +"use-sidecar@npm:^1.1.2": + version: 1.1.3 + resolution: "use-sidecar@npm:1.1.3" + dependencies: + detect-node-es: ^1.1.0 + tslib: ^2.0.0 + peerDependencies: + "@types/react": "*" + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 88664c6b2c5b6e53e4d5d987694c9053cea806da43130248c74ca058945c8caa6ccb7b1787205a9eb5b9d124633e42153848904002828acabccdc48cda026622 + languageName: node + linkType: hard + "use-sync-external-store@npm:1.2.0": version: 1.2.0 resolution: "use-sync-external-store@npm:1.2.0" @@ -11496,7 +11816,7 @@ __metadata: languageName: node linkType: hard -"viem@npm:^2.1.1, viem@npm:^2.19.9": +"viem@npm:^2.1.1": version: 2.21.6 resolution: "viem@npm:2.21.6" dependencies: @@ -11518,12 +11838,34 @@ __metadata: languageName: node linkType: hard -"wagmi@npm:^2.12.7": - version: 2.12.11 - resolution: "wagmi@npm:2.12.11" +"viem@npm:^2.22.2": + version: 2.22.2 + resolution: "viem@npm:2.22.2" dependencies: - "@wagmi/connectors": 5.1.10 - "@wagmi/core": 2.13.5 + "@noble/curves": 1.7.0 + "@noble/hashes": 1.6.1 + "@scure/bip32": 1.6.0 + "@scure/bip39": 1.5.0 + abitype: 1.0.7 + isows: 1.0.6 + ox: 0.6.0 + webauthn-p256: 0.0.10 + ws: 8.18.0 + peerDependencies: + typescript: ">=5.0.4" + peerDependenciesMeta: + typescript: + optional: true + checksum: e13bf3f6e52cbd5ef99bfc3472f21460ea661ade9e4fb8b0e7b6ed06231df3aebd2c2446cd98507553d072d1ac8abb8e64dd6827439a4c9fea1f317419091a20 + languageName: node + linkType: hard + +"wagmi@npm:^2.14.6": + version: 2.14.6 + resolution: "wagmi@npm:2.14.6" + dependencies: + "@wagmi/connectors": 5.7.3 + "@wagmi/core": 2.16.3 use-sync-external-store: 1.2.0 peerDependencies: "@tanstack/react-query": ">=5.0.0" @@ -11533,7 +11875,7 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 46f50d30e57664631f48f8fcec1af8b1a77ca2d44aae513148d947ade30f57b763421ceeab9d8bc63f819b847a743d38a9f0ad2adbcaee1c40f8f95e9ecbf2f5 + checksum: a1f6c7c23dba2ce3b278831256ebd4ce77df9cbec05c446b36db2584a4769b8d0dd243b9410f16600a4500e0379c2edf22d856419f6335f5a04b127f8dc963ed languageName: node linkType: hard @@ -11544,6 +11886,16 @@ __metadata: languageName: node linkType: hard +"webauthn-p256@npm:0.0.10": + version: 0.0.10 + resolution: "webauthn-p256@npm:0.0.10" + dependencies: + "@noble/curves": ^1.4.0 + "@noble/hashes": ^1.4.0 + checksum: 0648a3d78451bfa7105b5151a34bd685ee60e193be9be1981fe73819ed5a92f410973bdeb72427ef03c8c2a848619f818cf3e66b94012d5127b462cb10c24f5d + languageName: node + linkType: hard + "webauthn-p256@npm:0.0.5": version: 0.0.5 resolution: "webauthn-p256@npm:0.0.5" @@ -11734,6 +12086,21 @@ __metadata: languageName: node linkType: hard +"ws@npm:8.18.0": + version: 8.18.0 + resolution: "ws@npm:8.18.0" + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ">=5.0.2" + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + checksum: 91d4d35bc99ff6df483bdf029b9ea4bfd7af1f16fc91231a96777a63d263e1eabf486e13a2353970efc534f9faa43bdbf9ee76525af22f4752cbc5ebda333975 + languageName: node + linkType: hard + "ws@npm:^7.3.1, ws@npm:^7.5.1": version: 7.5.10 resolution: "ws@npm:7.5.10" @@ -11836,7 +12203,7 @@ __metadata: languageName: node linkType: hard -"yargs@npm:17.7.2, yargs@npm:^17.0.0, yargs@npm:^17.5.1": +"yargs@npm:17.7.2, yargs@npm:^17.0.0": version: 17.7.2 resolution: "yargs@npm:17.7.2" dependencies: @@ -11909,15 +12276,14 @@ __metadata: languageName: node linkType: hard -"zustand@npm:4.4.1": - version: 4.4.1 - resolution: "zustand@npm:4.4.1" - dependencies: - use-sync-external-store: 1.2.0 +"zustand@npm:5.0.0": + version: 5.0.0 + resolution: "zustand@npm:5.0.0" peerDependencies: - "@types/react": ">=16.8" - immer: ">=9.0" - react: ">=16.8" + "@types/react": ">=18.0.0" + immer: ">=9.0.6" + react: ">=18.0.0" + use-sync-external-store: ">=1.2.0" peerDependenciesMeta: "@types/react": optional: true @@ -11925,7 +12291,9 @@ __metadata: optional: true react: optional: true - checksum: 80acd0fbf633782996642802c8692bbb80ae5c80a8dff4c501b88250acd5ccd468fbc6398bdce198475a25e3839c91385b81da921274f33ffb5c2d08c3eab400 + use-sync-external-store: + optional: true + checksum: dc7414de234f9d2c0afad472d6971e9ac32281292faa8ee0910521cad063f84eeeb6f792efab068d6750dab5854fb1a33ac6e9294b796925eb680a59fc1b42f9 languageName: node linkType: hard