diff --git a/advanced/wallets/react-wallet-v2/next.config.js b/advanced/wallets/react-wallet-v2/next.config.js index ebacdf340..88d9d99a8 100644 --- a/advanced/wallets/react-wallet-v2/next.config.js +++ b/advanced/wallets/react-wallet-v2/next.config.js @@ -1,5 +1,8 @@ module.exports = { reactStrictMode: true, + typescript: { + ignoreBuildErrors: true, + }, webpack(config) { config.resolve.fallback = { ...config.resolve.fallback, diff --git a/advanced/wallets/react-wallet-v2/package.json b/advanced/wallets/react-wallet-v2/package.json index 2ef1a9fe8..3d8770dc7 100644 --- a/advanced/wallets/react-wallet-v2/package.json +++ b/advanced/wallets/react-wallet-v2/package.json @@ -30,7 +30,7 @@ "@polkadot/keyring": "^10.1.2", "@polkadot/types": "^9.3.3", "@reown/appkit-experimental": "1.6.8", - "@reown/walletkit": "1.0.0", + "@reown/walletkit": "1.1.2-canary-ca-1", "@rhinestone/module-sdk": "0.1.25", "@solana/web3.js": "1.89.2", "@taquito/signer": "^15.1.0", @@ -63,7 +63,7 @@ "tiny-secp256k1": "^2.2.3", "tronweb": "^4.4.0", "valtio": "1.13.2", - "viem": "2.17.8", + "viem": "2.23.2", "webauthn-p256": "0.0.2" }, "devDependencies": { diff --git a/advanced/wallets/react-wallet-v2/public/bridge.png b/advanced/wallets/react-wallet-v2/public/bridge.png new file mode 100644 index 000000000..218ea79bb Binary files /dev/null and b/advanced/wallets/react-wallet-v2/public/bridge.png differ diff --git a/advanced/wallets/react-wallet-v2/src/components/BridgeBadge.tsx b/advanced/wallets/react-wallet-v2/src/components/BridgeBadge.tsx new file mode 100644 index 000000000..48e8fd97b --- /dev/null +++ b/advanced/wallets/react-wallet-v2/src/components/BridgeBadge.tsx @@ -0,0 +1,26 @@ +import { Icon } from '@mui/material' +import bridgeIcon from './../../public/bridge.png' + +export default function BridgeBadge() { + return ( +
+ +
+ ) +} diff --git a/advanced/wallets/react-wallet-v2/src/components/ChainAbstractionBalanceCard.tsx b/advanced/wallets/react-wallet-v2/src/components/ChainAbstractionBalanceCard.tsx index 96f274e7c..e282dd50b 100644 --- a/advanced/wallets/react-wallet-v2/src/components/ChainAbstractionBalanceCard.tsx +++ b/advanced/wallets/react-wallet-v2/src/components/ChainAbstractionBalanceCard.tsx @@ -11,7 +11,7 @@ import { Hex } from 'viem' export default function ChainAbstractionBalanceCard() { const { eip155Address } = useSnapshot(SettingsStore.state) - const [balances, setBalances] = useState>>({}) + const [balances, setBalances] = useState>>({}) const [totalBalance, setTotalBalance] = useState>({}) const [loading, setLoading] = useState(true) useEffect(() => { @@ -20,7 +20,7 @@ export default function ChainAbstractionBalanceCard() { const fetchedBalances: Record = {} for (const asset of Object.keys(multibridgeSupportedAssets)) { - const assetBalances: Record = {} + const assetBalances: Record = {} for (const chainId of Object.keys(multibridgeSupportedAssets[asset])) { const tokenAddress = multibridgeSupportedAssets[asset][Number(chainId)] const balance = await getErc20TokenBalance( @@ -43,7 +43,7 @@ export default function ChainAbstractionBalanceCard() { for (const asset of Object.keys(balances)) { let total = 0 for (const chainBalance of Object.values(balances[asset])) { - total += chainBalance + total += parseFloat(chainBalance) } totalBalances[asset] = total } diff --git a/advanced/wallets/react-wallet-v2/src/components/MultibridgeRequestModal.tsx b/advanced/wallets/react-wallet-v2/src/components/MultibridgeRequestModal.tsx index f7d8e3409..e5c90d907 100644 --- a/advanced/wallets/react-wallet-v2/src/components/MultibridgeRequestModal.tsx +++ b/advanced/wallets/react-wallet-v2/src/components/MultibridgeRequestModal.tsx @@ -1,136 +1,122 @@ -import { useCallback, useState } from 'react' -import { Avatar, Col, Divider, Row, Text } from '@nextui-org/react' +import { useCallback, useEffect, useMemo, useState } from 'react' +import { Avatar, Col, Row, Text } from '@nextui-org/react' import { LoaderProps } from '@/components/ModalFooter' -import RequestMethodCard from '@/components/RequestMethodCard' import RequestModal from './RequestModal' import ModalStore from '@/store/ModalStore' import { styledToast } from '@/utils/HelperUtil' -import { approveEIP155Request } from '@/utils/EIP155RequestHandlerUtil' import { convertTokenBalance, decodeErc20Transaction, - getAssetByContractAddress + getAssetByContractAddress, + getErc20TokenBalance } from '@/utils/MultibridgeUtil' -import { getWallet } from '@/utils/EIP155WalletUtil' +import { getWalletByAddress } from '@/utils/EIP155WalletUtil' import { walletkit } from '@/utils/WalletConnectUtil' import { EIP155_CHAINS, TEIP155Chain } from '@/data/EIP155Data' -import { ChainAbstractionService, Transaction } from '@/utils/ChainAbstractionService' -import { providers } from 'ethers' -import { formatJsonRpcError } from '@json-rpc-tools/utils' +import { formatJsonRpcError, formatJsonRpcResult } from '@json-rpc-tools/utils' +import { ChainAbstractionTypes } from '@reown/walletkit' +import { Hex } from 'viem' +import BridgeBadge from './BridgeBadge' +import { privateKeyToAccount } from 'viem/accounts' interface IProps { onReject: () => void - transactions?: Transaction[] - orchestrationId: string rejectLoader?: LoaderProps + bridgeDetails: ChainAbstractionTypes.UiFields } -export default function MultibridgeRequestModal({ - transactions, - orchestrationId, - onReject, - rejectLoader -}: IProps) { +export default function MultibridgeRequestModal({ onReject, rejectLoader, bridgeDetails }: IProps) { const [isLoadingApprove, setIsLoadingApprove] = useState(false) + const [tokenBalances, setTokenBalances] = useState>({}) + const transaction = bridgeDetails.initial.transaction + console.log('bridgeDetails', bridgeDetails) + const bridgingTransactions = bridgeDetails.route.map(route => route) + const orchestrationId = bridgeDetails.routeResponse.orchestrationId + const totalFee = bridgeDetails.localTotal.formattedAlt + const initialTransactionMetadata = bridgeDetails.routeResponse.metadata.initialTransaction + const fundingFrom = bridgeDetails.routeResponse.metadata.fundingFrom + console.log('transactions', bridgingTransactions) - const bridgingTransactions = transactions?.slice(0, transactions.length - 1) || [] - const initialTransaction = transactions?.[transactions.length - 1] - - const eip155ChainsFundsSourcedFrom = transactions - ? new Set(bridgingTransactions.map(transaction => transaction.chainId)) - : new Set() - - const eip155ChainFundsDestination = initialTransaction?.chainId + const eip155ChainFundsDestination = transaction?.chainId // Get request and wallet data from store const requestEvent = ModalStore.state.data?.requestEvent const requestSession = ModalStore.state.data?.requestSession - const topic = requestEvent?.topic const params = requestEvent?.params - const chainId = params?.chainId const request = params?.request - const caService = new ChainAbstractionService() - const bridgeFunds = useCallback(async (): Promise => { - if (!bridgingTransactions) { - throw new Error('bridgingTransactions are unavailable') - } + const bridgeFunds = async ( + bridgeSignedTransactions: string[], + initialSignedTransaction: string + ) => { + return await walletkit.chainAbstraction.execute({ + orchestrationId, + bridgeSignedTransactions, + initialSignedTransaction + }) + } - const wallet = await getWallet(params) - console.log( - 'Bridge funds from', - eip155ChainsFundsSourcedFrom, - 'to', - eip155ChainFundsDestination - ) - - for (const transaction of bridgingTransactions) { - console.log('Bridging transaction', transaction) - const chainId = transaction.chainId - const chainProvider = new providers.JsonRpcProvider( - EIP155_CHAINS[chainId as TEIP155Chain].rpc - ) - const chainConnectedWallet = await wallet.connect(chainProvider) - const walletAddress = wallet.getAddress() - - const txResponse = await chainConnectedWallet.sendTransaction({ - from: walletAddress, - to: transaction.to, - value: transaction.value, - data: transaction.data, - nonce: transaction.nonce, - gasPrice: transaction.gasPrice, - gasLimit: transaction.gas - }) - const txHash = typeof txResponse === 'string' ? txResponse : txResponse?.hash - const txReceipt = await txResponse.wait() - const txStatus = txReceipt.status - console.log( - `Transaction broadcasted on chain ${chainId} , ${{ txHash }}, status: ${txStatus}` + useEffect(() => { + console.log('Initial transaction', initialTransactionMetadata) + const fetchTokenBalance = async (tokenAddress: string) => { + const tokenBalance = await getErc20TokenBalance( + tokenAddress as Hex, + Number(transaction.chainId.split(':')[1]), + transaction?.from as Hex ) + console.log('Token balance', tokenBalance) + setTokenBalances(prevState => ({ + ...prevState, + [tokenAddress]: tokenBalance + })) } - await pollOrchestrationStatus(orchestrationId) - }, [bridgingTransactions, orchestrationId, onReject, params]) - - async function pollOrchestrationStatus( - orchestrationId: string, - maxAttempts = 100, - interval = 1500 - ): Promise { - for (let attempt = 0; attempt < maxAttempts; attempt++) { - const { status } = await caService.getOrchestrationStatus(orchestrationId) - console.log(attempt, '- Orchestration status:', status) - if (status === 'completed') { - console.log('Bridging completed') - return - } - await new Promise(resolve => setTimeout(resolve, interval)) - } - console.log('Max attempts reached. Orchestration not completed.') - throw new Error('Max attempts reached. Orchestration not completed.') - } + fetchTokenBalance(initialTransactionMetadata.tokenContract) + }, []) const onApprove = useCallback(async (): Promise => { - if (requestEvent && topic) { + if (requestEvent) { + const topic = requestEvent.topic + const id = requestEvent.id setIsLoadingApprove(true) try { - performance.mark('startInititalTransactionSend') - await bridgeFunds() - const response = await approveEIP155Request(requestEvent) - performance.mark('endInititalTransactionSend') - console.log( - `Initial transaction send: ${ - performance.measure( - 'initial-tx-send', - 'startInititalTransactionSend', - 'endInititalTransactionSend' - ).duration - } ms` - ) - - await walletkit.respondSessionRequest({ topic, response }) + console.log('Approving request', transaction) + const loadedWallet = getWalletByAddress(transaction.from) + const account = privateKeyToAccount(loadedWallet.getPrivateKey() as Hex) + // const account = mnemonicToAccount(loadedWallet.getMnemonic()) + console.log('Account', account) + + console.log('Connected wallet', account) + const bridgeSignedTransactions = [] + for (const route of bridgeDetails.route) { + const message = route.transactionHashToSign + const signature = await account.sign({ hash: message }) + bridgeSignedTransactions.push(signature) + console.log('Signed bridge transaction', { + message, + signature, + address: account.address + }) + } + + const message = bridgeDetails.initial.transactionHashToSign + const initialSignedTransaction = await account.sign({ + hash: message + }) + + console.log('Signed initial transaction', { + message, + signature: initialSignedTransaction, + address: account.address + }) + const result = await bridgeFunds(bridgeSignedTransactions, initialSignedTransaction) + + await walletkit.respondSessionRequest({ + topic, + response: formatJsonRpcResult(id, result.initialTxnHash) + }) + ModalStore.close() } catch (e) { const { id } = requestEvent const errorMessage = (e as Error).message || 'Error bridging funds' @@ -144,9 +130,8 @@ export default function MultibridgeRequestModal({ } finally { setIsLoadingApprove(false) } - ModalStore.close() } - }, [bridgeFunds, requestEvent, topic]) + }, [bridgeDetails, bridgeFunds]) if (!request || !requestSession || !bridgingTransactions || bridgingTransactions.length === 0) { return Request not found @@ -160,9 +145,20 @@ export default function MultibridgeRequestModal({ const asset = getAssetByContractAddress(transfer.contract) const amount = convertTokenBalance(asset, transfer.amount) const destination = transfer.to - const sourceChain = EIP155_CHAINS[Array.from(eip155ChainsFundsSourcedFrom)[0] as TEIP155Chain] const targetChain = EIP155_CHAINS[eip155ChainFundsDestination as TEIP155Chain] + const formatAddress = (address: string) => { + return `${address.slice(0, 6)}...${address.slice(-4)}` + } + + function hexToDecimal(hex: string, decimals: number, toFixed?: number): string { + // Convert hex to decimal + const decimalValue = parseInt(hex, 16) + + // Apply decimal places + return (decimalValue / Math.pow(10, decimals)).toFixed(toFixed || decimals) + } + return ( - - - Transaction details - - Sending {amount} {asset} to: - - - {destination} - - - - - - - Chain details - Target chain: - - - +
+
+ + Sending + + {/* */} + {amount} {asset} + {/* */} + {/* + {destination} + */} - {targetChain.name} - - Sourcing funds from: - + + To + {formatAddress(destination)} + + - + + Source of funds + + + + + + + Balance + + + + ~{tokenBalances[initialTransactionMetadata.tokenContract]}{' '} + {initialTransactionMetadata.symbol} + + + {fundingFrom?.map((funding, i) => { + return ( + + + + Bridging + + + + ~{hexToDecimal(funding.amount, funding.decimals, 2)} {funding.symbol} + + from {EIP155_CHAINS[funding.chainId as TEIP155Chain]?.name} + + + + + ) + })} - {sourceChain.name} - - - - +
+
+
+
+ + + App + + + {requestSession.peer.metadata.url} + + + + + + + Network + + + {' '} + {targetChain.name} + + + + + + + Estimated Fees + ~{totalFee} + + +
+
) } diff --git a/advanced/wallets/react-wallet-v2/src/hooks/useWalletConnectEventsManager.ts b/advanced/wallets/react-wallet-v2/src/hooks/useWalletConnectEventsManager.ts index c7b5821f6..1dfe5d8a0 100644 --- a/advanced/wallets/react-wallet-v2/src/hooks/useWalletConnectEventsManager.ts +++ b/advanced/wallets/react-wallet-v2/src/hooks/useWalletConnectEventsManager.ts @@ -41,6 +41,7 @@ export default function useWalletConnectEventsManager(initialized: boolean) { *****************************************************************************/ const onSessionRequest = useCallback( async (requestEvent: SignClientTypes.EventArguments['session_request']) => { + console.log('session_request', JSON.parse(JSON.stringify(requestEvent))) const { topic, params, verifyContext, id } = requestEvent const { request } = params const requestSession = walletkit.engine.signClient.session.get(topic) @@ -181,6 +182,33 @@ export default function useWalletConnectEventsManager(initialized: boolean) { refreshSessionsList() }) walletkit.on('session_authenticate', onSessionAuthenticate) + + onSessionRequest({ + id: 1738225968028357, + topic: '67132090c8b0fd3c2362b7dea4be21ebc6b0b14b6b27e82eb358bfc6f96c4533', + params: { + request: { + method: 'eth_sendTransaction', + params: [ + { + data: '0xa9059cbb00000000000000000000000013a2ff792037aa2cd77fe1f4b522921ac59a9c5200000000000000000000000000000000000000000000000000000000003d0900', + from: '0x13A2Ff792037AA2cd77fE1f4B522921ac59a9C52', + to: '0xaf88d065e77c8cC2239327C5EDb3A432268e5831' + } + ], + expiryTimestamp: 1738226268 + }, + chainId: 'eip155:42161' + }, + verifyContext: { + verified: { + verifyUrl: 'https://verify.walletconnect.org', + validation: 'VALID', + origin: 'https://appkit-lab.reown.com', + isScam: false + } + } + }) // load sessions on init refreshSessionsList() } diff --git a/advanced/wallets/react-wallet-v2/src/lib/EIP155Lib.ts b/advanced/wallets/react-wallet-v2/src/lib/EIP155Lib.ts index b4e7488df..09210a05b 100644 --- a/advanced/wallets/react-wallet-v2/src/lib/EIP155Lib.ts +++ b/advanced/wallets/react-wallet-v2/src/lib/EIP155Lib.ts @@ -5,6 +5,7 @@ import { providers, Wallet } from 'ethers' */ interface IInitArgs { mnemonic?: string + privateKey?: string } export interface EIP155Wallet { getMnemonic(): string @@ -26,14 +27,21 @@ export default class EIP155Lib implements EIP155Wallet { this.wallet = wallet } - static init({ mnemonic }: IInitArgs) { - const wallet = mnemonic ? Wallet.fromMnemonic(mnemonic) : Wallet.createRandom() + static init({ mnemonic, privateKey }: IInitArgs) { + let wallet + if (privateKey) { + wallet = new Wallet(privateKey) + } else if (mnemonic) { + wallet = Wallet.fromMnemonic(mnemonic) + } else { + wallet = Wallet.createRandom() + } return new EIP155Lib(wallet) } getMnemonic() { - return this.wallet.mnemonic.phrase + return this.wallet.mnemonic?.phrase || this.getPrivateKey() } getPrivateKey() { diff --git a/advanced/wallets/react-wallet-v2/src/lib/smart-accounts/SmartAccountLib.ts b/advanced/wallets/react-wallet-v2/src/lib/smart-accounts/SmartAccountLib.ts index df9d7964b..8830439f0 100644 --- a/advanced/wallets/react-wallet-v2/src/lib/smart-accounts/SmartAccountLib.ts +++ b/advanced/wallets/react-wallet-v2/src/lib/smart-accounts/SmartAccountLib.ts @@ -211,6 +211,7 @@ export abstract class SmartAccountLib implements EIP155Wallet { if (!this.client?.account) { throw new Error('Client not initialized') } + console.log('Sending transaction from smart account', { type: this.type, to, value, data }) const txResult = await this.client.sendTransaction({ to, value: BigInt(value), diff --git a/advanced/wallets/react-wallet-v2/src/pages/settings.tsx b/advanced/wallets/react-wallet-v2/src/pages/settings.tsx index cbe3efd8d..41416acd5 100644 --- a/advanced/wallets/react-wallet-v2/src/pages/settings.tsx +++ b/advanced/wallets/react-wallet-v2/src/pages/settings.tsx @@ -2,12 +2,12 @@ import PageHeader from '@/components/PageHeader' import RelayRegionPicker from '@/components/RelayRegionPicker' import SettingsStore from '@/store/SettingsStore' import { cosmosWallets } from '@/utils/CosmosWalletUtil' -import { eip155Wallets } from '@/utils/EIP155WalletUtil' +import { eip155Wallets, replaceEip155Mnemonic } from '@/utils/EIP155WalletUtil' import { solanaWallets } from '@/utils/SolanaWalletUtil' import { multiversxWallets } from '@/utils/MultiversxWalletUtil' import { tronWallets } from '@/utils/TronWalletUtil' import { kadenaWallets } from '@/utils/KadenaWalletUtil' -import { Card, Col, Divider, Row, Switch, Text } from '@nextui-org/react' +import { Button, Card, Col, Divider, Row, Switch, Text } from '@nextui-org/react' import { Fragment } from 'react' import { useSnapshot } from 'valtio' import packageJSON from '../../package.json' @@ -32,6 +32,12 @@ export default function SettingsPage() { chainAbstractionEnabled } = useSnapshot(SettingsStore.state) + const onImportEip155Mnemonic = (value: string | null) => { + console.log('Importing EIP155 Mnemonic: ', value) + if (!value) throw new Error('No value provided') + replaceEip155Mnemonic(value.trim()) + } + return ( @@ -191,8 +197,14 @@ export default function SettingsPage() { be used elsewhere! - + EIP155 Mnemonic + {eip155Wallets[eip155Address].getMnemonic()} diff --git a/advanced/wallets/react-wallet-v2/src/utils/ChainAbstractionService.ts b/advanced/wallets/react-wallet-v2/src/utils/ChainAbstractionService.ts index 54e7a0403..6e037c0f9 100644 --- a/advanced/wallets/react-wallet-v2/src/utils/ChainAbstractionService.ts +++ b/advanced/wallets/react-wallet-v2/src/utils/ChainAbstractionService.ts @@ -5,12 +5,11 @@ export interface Transaction { from: string to: string value: string - gas: string - gasPrice: string data: string nonce: string maxFeePerGas: string maxPriorityFeePerGas: string + gasLimit: string chainId: string } diff --git a/advanced/wallets/react-wallet-v2/src/utils/EIP155WalletUtil.ts b/advanced/wallets/react-wallet-v2/src/utils/EIP155WalletUtil.ts index 247c0ec84..9fbc871aa 100644 --- a/advanced/wallets/react-wallet-v2/src/utils/EIP155WalletUtil.ts +++ b/advanced/wallets/react-wallet-v2/src/utils/EIP155WalletUtil.ts @@ -1,6 +1,7 @@ import EIP155Lib from '@/lib/EIP155Lib' import { smartAccountWallets } from './SmartAccountUtil' import { getWalletAddressFromParams } from './HelperUtil' +import { ethers } from 'ethers' export let wallet1: EIP155Lib export let wallet2: EIP155Lib @@ -18,7 +19,11 @@ export function createOrRestoreEIP155Wallet() { const mnemonic2 = localStorage.getItem('EIP155_MNEMONIC_2') if (mnemonic1 && mnemonic2) { - wallet1 = EIP155Lib.init({ mnemonic: mnemonic1 }) + if (mnemonic1.includes(' ')) { + wallet1 = EIP155Lib.init({ mnemonic: mnemonic1 }) + } else { + wallet1 = EIP155Lib.init({ privateKey: mnemonic1 }) + } wallet2 = EIP155Lib.init({ mnemonic: mnemonic2 }) } else { wallet1 = EIP155Lib.init({}) @@ -44,6 +49,29 @@ export function createOrRestoreEIP155Wallet() { } } +export async function replaceEip155Mnemonic(mnemonicOrPrivateKey: string) { + try { + let wallet + if (mnemonicOrPrivateKey.includes(' ')) { + wallet = EIP155Lib.init({ mnemonic: mnemonicOrPrivateKey }) + } else { + wallet = EIP155Lib.init({ privateKey: mnemonicOrPrivateKey }) + } + localStorage.setItem('EIP155_MNEMONIC_1', wallet.getMnemonic()) + location.reload() + } catch (error) { + console.error('Failed to replace mnemonic: ', error) + throw new Error('Invalid mnemonic or private key') + } +} + +export const getWalletByAddress = (address: string) => { + const checksumAddress = ethers.utils.getAddress(address) + const wallet = eip155Wallets[checksumAddress] + console.log('getWalletByAddress', { checksumAddress, wallet, eip155Wallets }) + return wallet +} + /** * Get wallet for the address in params */ diff --git a/advanced/wallets/react-wallet-v2/src/utils/MultibridgeUtil.ts b/advanced/wallets/react-wallet-v2/src/utils/MultibridgeUtil.ts index 1fc7e03be..422384457 100644 --- a/advanced/wallets/react-wallet-v2/src/utils/MultibridgeUtil.ts +++ b/advanced/wallets/react-wallet-v2/src/utils/MultibridgeUtil.ts @@ -1,7 +1,7 @@ import { createPublicClient, decodeFunctionData, erc20Abi, getContract, Hex, http } from 'viem' import { arbitrum, base, optimism } from 'viem/chains' import { getChainById } from './ChainUtil' -import { providers } from 'ethers' +import { ethers, providers } from 'ethers' import { EIP155_CHAINS, TEIP155Chain } from '@/data/EIP155Data' const BASE_URL = 'https://api.socket.tech/v2' @@ -13,11 +13,17 @@ export const supportedAssets: Record> = { [base.id]: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', [optimism.id]: '0x0b2c639c533813f4aa9d7837caf62653d097ff85', [arbitrum.id]: '0xaf88d065e77c8cC2239327C5EDb3A432268e5831' + }, + USDT: { + [base.id]: '0xfde4c96c8593536e31f229ea8f37b2ada2699bb2', + [optimism.id]: '0x94b008aa00579c1307b0ef2c499ad98a8ce58e58', + [arbitrum.id]: '0xfd086bc7cd5c481dcc9c85ebe478a1c0b69fcbb9' } } as const const assetDecimals: Record = { - USDC: 6 + USDC: 6, + USDT: 6 } export const supportedChains = [base, optimism, arbitrum] as const @@ -44,13 +50,15 @@ export function getAssetByContractAddress(address: Hex): string { } } } - throw new Error('Asset not found for the given contract address') + console.error('Asset not found for the given contract address') + return '' } -export function convertTokenBalance(asset: string, amount: number): number { +export function convertTokenBalance(asset: string, amount: number): number | undefined { const decimals = assetDecimals[asset] if (!decimals) { - throw new Error('Asset not supported') + console.error('Asset not supported') + return } const balance = amount / 10 ** decimals return balance @@ -61,7 +69,7 @@ export async function getErc20TokenBalance( chainId: number, account: Hex, convert: boolean = true -): Promise { +): Promise { const publicClient = createPublicClient({ chain: getChainById(chainId), transport: http() @@ -73,11 +81,12 @@ export async function getErc20TokenBalance( }) const result = await contract.read.balanceOf([account]) if (!convert) { - return Number(result) + return result.toString() } const decimals = await contract.read.decimals() - const balance = BigInt(result) / BigInt(10 ** decimals) - return Number(balance) + console.log('result', result, decimals) + const balance = Number(result) / Number(10 ** decimals) + return balance.toFixed(2) } type Erc20Transfer = { diff --git a/advanced/wallets/react-wallet-v2/src/utils/WalletConnectUtil.ts b/advanced/wallets/react-wallet-v2/src/utils/WalletConnectUtil.ts index b3a59dc86..fba139657 100644 --- a/advanced/wallets/react-wallet-v2/src/utils/WalletConnectUtil.ts +++ b/advanced/wallets/react-wallet-v2/src/utils/WalletConnectUtil.ts @@ -6,7 +6,7 @@ export async function createWalletKit(relayerRegionURL: string) { const core = new Core({ projectId: process.env.NEXT_PUBLIC_PROJECT_ID, relayUrl: relayerRegionURL ?? process.env.NEXT_PUBLIC_RELAY_URL, - logger: 'trace' + logger: 'debug' }) walletkit = await WalletKit.init({ core, diff --git a/advanced/wallets/react-wallet-v2/src/views/SessionSendTransactionModal.tsx b/advanced/wallets/react-wallet-v2/src/views/SessionSendTransactionModal.tsx index cac73e433..baf307a4e 100644 --- a/advanced/wallets/react-wallet-v2/src/views/SessionSendTransactionModal.tsx +++ b/advanced/wallets/react-wallet-v2/src/views/SessionSendTransactionModal.tsx @@ -1,9 +1,8 @@ import { useCallback, useEffect, useState } from 'react' -import { Card, Divider, Loading, Text } from '@nextui-org/react' +import { Card, Col, Divider, Loading, Row, Text } from '@nextui-org/react' import { approveEIP155Request, rejectEIP155Request } from '@/utils/EIP155RequestHandlerUtil' import { styledToast } from '@/utils/HelperUtil' import { walletkit } from '@/utils/WalletConnectUtil' -import { ChainAbstractionService, Transaction } from '@/utils/ChainAbstractionService' import ModalStore from '@/store/ModalStore' import SettingsStore from '@/store/SettingsStore' @@ -12,6 +11,7 @@ import RequestDetailsCard from '@/components/RequestDetalilsCard' import RequestMethodCard from '@/components/RequestMethodCard' import RequestModal from '@/components/RequestModal' import MultibridgeRequestModal from '@/components/MultibridgeRequestModal' +import { ChainAbstractionTypes } from '@reown/walletkit' // Types for props used in individual components type Session = { @@ -25,17 +25,15 @@ export default function SessionSendTransactionModal() { const [isLoadingApprove, setIsLoadingApprove] = useState(false) const [isLoadingReject, setIsLoadingReject] = useState(false) const [isReadyForRender, setIsReadyForRender] = useState(false) - const [requiresMultiChain, setRequiresMultiChain] = useState(false) - const [routeTransactions, setRouteTransactions] = useState([]) - const [orchestrationId, setOrchestrationId] = useState(null) - + useState() + const [bridgeDetails, setBridgeDetails] = useState() + const [chainAbstractionStatus, setChainAbstractionStatus] = useState('') // Extract request and wallet data from store const requestEvent = ModalStore.state.data?.requestEvent const requestSession = ModalStore.state.data?.requestSession const { topic, params } = requestEvent || {} const { chainId, request } = params || {} const transaction = request?.params[0] - // Check for multi-chain requirement and handle routing useEffect(() => { const initializeMultiChainCheck = async (): Promise => { @@ -53,11 +51,11 @@ export default function SessionSendTransactionModal() { } try { - const caService = new ChainAbstractionService() - const isMultiChain = await checkMultiChainRequirement(caService, request, chainId) - if (isMultiChain) { - await setupRouteTransactions(caService, request, chainId) - } + // const caService = new ChainAbstractionService() + // const isMultiChain = await checkMultiChainRequirement(caService, request, chainId) + // if (isMultiChain) { + await setupRouteTransactions(request, chainId) + // } } catch (error) { console.error('Error during multi-chain check:', error) styledToast('Unable to check multibridge availability', 'error') @@ -69,48 +67,47 @@ export default function SessionSendTransactionModal() { initializeMultiChainCheck() }, [request, chainId]) - const checkMultiChainRequirement = async ( - caService: ChainAbstractionService, - request: { params: [{ from: string; to: string; data: string }] }, - chainId: string - ): Promise => { - const { data, from, to } = request.params[0] - const isMultiChain = await caService.checkTransaction({ - from, - to, - value: '0', - gas: '0', - gasPrice: '0', - data, - nonce: '0', - maxFeePerGas: '0', - maxPriorityFeePerGas: '0', - chainId - }) - setRequiresMultiChain(isMultiChain) - return isMultiChain - } - const setupRouteTransactions = async ( - caService: ChainAbstractionService, - request: { params: [{ from: string; to: string; data: string }] }, + // caService: ChainAbstractionService, + request: { + params: [ + { + from: ChainAbstractionTypes.Hex + to: ChainAbstractionTypes.Hex + data: ChainAbstractionTypes.Hex + } + ] + }, chainId: string ): Promise => { const { data, from, to } = request.params[0] - const routeResult = await caService.routeTransaction({ - from, - to, - value: '0', - gas: '0', - gasPrice: '0', - data, - nonce: '0', - maxFeePerGas: '0', - maxPriorityFeePerGas: '0', - chainId + + const result = await walletkit.chainAbstraction.prepareDetailed({ + transaction: { + from, + to, + input: data, + chainId + } }) - setRouteTransactions(routeResult.transactions) - setOrchestrationId(routeResult.orchestrationId) + + console.log('prepare detaield result:', result) + if ('error' in result) { + setChainAbstractionStatus(result.error.error) + } + + if (!('success' in result)) { + return + } + + if ('notRequired' in result.success) { + setChainAbstractionStatus('not required') + } + + if ('available' in result.success) { + setChainAbstractionStatus('available') + setBridgeDetails(result.success.available) + } } const handleApproval = useCallback(async (): Promise => { @@ -141,12 +138,18 @@ export default function SessionSendTransactionModal() { } }, [requestEvent, topic]) - if (!request || !requestSession) return Request not found + if (!requestEvent) return Request not found if (!isReadyForRender) return - return !requiresMultiChain || orchestrationId == null ? ( + return bridgeDetails ? ( + + ) : ( - ) : ( - ) } @@ -184,6 +181,7 @@ type SingleChainModalProps = { onReject: () => Promise loadingApprove: boolean loadingReject: boolean + chainAbstractionStatus: string } const SingleChainModal = ({ @@ -194,7 +192,8 @@ const SingleChainModal = ({ onApprove, onReject, loadingApprove, - loadingReject + loadingReject, + chainAbstractionStatus }: SingleChainModalProps): JSX.Element => ( + + + + Chain Abstraction Status + + {chainAbstractionStatus} + + + @@ -213,22 +221,19 @@ const SingleChainModal = ({ ) type MultiChainModalProps = { - transactions: Transaction[] - orchestrationId: string onReject: () => Promise loadingReject: boolean + bridgeDetails: ChainAbstractionTypes.UiFields } const MultiChainModal = ({ - transactions, - orchestrationId, onReject, - loadingReject + loadingReject, + bridgeDetails }: MultiChainModalProps): JSX.Element => ( ) diff --git a/advanced/wallets/react-wallet-v2/yarn.lock b/advanced/wallets/react-wallet-v2/yarn.lock index b68a20610..515c548e1 100644 --- a/advanced/wallets/react-wallet-v2/yarn.lock +++ b/advanced/wallets/react-wallet-v2/yarn.lock @@ -7,11 +7,6 @@ resolved "https://registry.yarnpkg.com/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz#bd9154aec9983f77b3a034ecaa015c2e4201f6cf" integrity sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA== -"@adraffy/ens-normalize@1.10.0": - version "1.10.0" - resolved "https://registry.yarnpkg.com/@adraffy/ens-normalize/-/ens-normalize-1.10.0.tgz#d2a39395c587e092d77cbbc80acf956a54f38bf7" - integrity sha512-nA9XHtlAkYfJxY7bce8DcN7eKxWWCWkU+1GR9d+U6MbNpfwQp8TI7vqOsBsMcHoT4mBu2kypKoSKnghEzOOq5Q== - "@adraffy/ens-normalize@^1.10.1": version "1.11.0" resolved "https://registry.yarnpkg.com/@adraffy/ens-normalize/-/ens-normalize-1.11.0.tgz#42cc67c5baa407ac25059fcd7d405cc5ecdb0c33" @@ -1271,13 +1266,6 @@ dependencies: "@noble/hashes" "1.3.3" -"@noble/curves@1.4.0": - version "1.4.0" - resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.4.0.tgz#f05771ef64da724997f69ee1261b2417a49522d6" - integrity sha512-p+4cb332SFCrReJkCYe8Xzm0OWi4Jji5jVdIZRL/PmacmDkFNw6MrrV+gGpiPxLHbV+zKFRywUWbaseT+tZRXg== - dependencies: - "@noble/hashes" "1.4.0" - "@noble/curves@1.8.0": version "1.8.0" resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.8.0.tgz#fe035a23959e6aeadf695851b51a87465b5ba8f7" @@ -1292,7 +1280,7 @@ dependencies: "@noble/hashes" "1.7.1" -"@noble/curves@^1.4.0", "@noble/curves@~1.4.0": +"@noble/curves@^1.4.0": version "1.4.2" resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.4.2.tgz#40309198c76ed71bc6dbf7ba24e81ceb4d0d1fe9" integrity sha512-TavHr8qycMChk8UwMld0ZDRvatedkzWfH8IiaeGCfymOP5i0hSCozz9vHOL0nkwk7HRMlFnAiKpS2jrUmSybcw== @@ -1326,7 +1314,7 @@ resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.3.tgz#39908da56a4adc270147bb07968bf3b16cfe1699" integrity sha512-V7/fPHgl+jsVPXqqeOzT8egNj2iBIVt+ECeMMG8TdcnTikP3oaBtUVqpT/gYCR68aEBJSF+XbYUxStjbFMqIIA== -"@noble/hashes@1.4.0", "@noble/hashes@^1.4.0", "@noble/hashes@~1.4.0": +"@noble/hashes@1.4.0", "@noble/hashes@^1.4.0": version "1.4.0" resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.4.0.tgz#45814aa329f30e4fe0ba49426f49dfccdd066426" integrity sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg== @@ -2245,18 +2233,19 @@ valtio "1.13.2" viem ">=2.23.0" -"@reown/walletkit@1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@reown/walletkit/-/walletkit-1.0.0.tgz#ad930f2d95b612a7ec5ded47a19ea72660830dd0" - integrity sha512-n0RM2G1Qa7dSI+MiJX6m/HZpcAEyUrZXnogUUoSz2vV5cj0EkVturvJqh2/IpSkwLiCZlPdBO7F7yTgVDSYUbw== +"@reown/walletkit@1.1.2-canary-ca-1": + version "1.1.2-canary-ca-1" + resolved "https://registry.yarnpkg.com/@reown/walletkit/-/walletkit-1.1.2-canary-ca-1.tgz#12179dd1ad38085acbb705d208a6acd5c10ad596" + integrity sha512-hzUqikXlAt4kULYNDWNxPP0+0NWKDzGeSMUlnNFgXTniLmzb/eAnUJQ6WgWIJ2UDf86KQF40iZ0MBbu/SWs4ZA== dependencies: - "@walletconnect/core" "2.16.1" + "@walletconnect/core" "2.17.3" "@walletconnect/jsonrpc-provider" "1.0.14" "@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.3" + "@walletconnect/types" "2.17.3" + "@walletconnect/utils" "2.17.3" + brotli "^1.3.3" "@rhinestone/module-sdk@0.1.25": version "0.1.25" @@ -2286,11 +2275,6 @@ resolved "https://registry.yarnpkg.com/@scure/base/-/base-1.1.5.tgz#1d85d17269fe97694b9c592552dd9e5e33552157" integrity sha512-Brj9FiG2W1MRQSTB212YVPRrcbjkv48FoZi/u4l/zds/ieRrqsh7aUf6CLwkAq61oKXr/ZlTzlY66gLIj3TFTQ== -"@scure/base@~1.1.6": - version "1.1.7" - resolved "https://registry.yarnpkg.com/@scure/base/-/base-1.1.7.tgz#fe973311a5c6267846aa131bc72e96c5d40d2b30" - integrity sha512-PPNYBslrLNNUQ/Yad37MHYsNQtK67EhWb6WtSvNLLPo7SdVZgkUjD6Dg+5On7zNwmskf8OX7I7Nx5oN+MIWE0g== - "@scure/base@~1.2.2", "@scure/base@~1.2.4": version "1.2.4" resolved "https://registry.yarnpkg.com/@scure/base/-/base-1.2.4.tgz#002eb571a35d69bdb4c214d0995dff76a8dcd2a9" @@ -2305,15 +2289,6 @@ "@noble/hashes" "~1.3.2" "@scure/base" "~1.1.4" -"@scure/bip32@1.4.0": - version "1.4.0" - resolved "https://registry.yarnpkg.com/@scure/bip32/-/bip32-1.4.0.tgz#4e1f1e196abedcef395b33b9674a042524e20d67" - integrity sha512-sVUpc0Vq3tXCkDGYVWGIZTRfnvu8LoTDaev7vbwh0omSvVORONr960MQWdKqJDCReIEmTj3PAr73O3aoxz7OPg== - dependencies: - "@noble/curves" "~1.4.0" - "@noble/hashes" "~1.4.0" - "@scure/base" "~1.1.6" - "@scure/bip32@1.6.2", "@scure/bip32@^1.5.0": version "1.6.2" resolved "https://registry.yarnpkg.com/@scure/bip32/-/bip32-1.6.2.tgz#093caa94961619927659ed0e711a6e4bf35bffd0" @@ -2331,14 +2306,6 @@ "@noble/hashes" "~1.3.2" "@scure/base" "~1.1.4" -"@scure/bip39@1.3.0": - version "1.3.0" - resolved "https://registry.yarnpkg.com/@scure/bip39/-/bip39-1.3.0.tgz#0f258c16823ddd00739461ac31398b4e7d6a18c3" - integrity sha512-disdg7gHuTDZtY+ZdkmLpPCk7fxZSu3gBiEGuoC1XYxv9cGx3Z6cpTggCgW6odSOOIXCiDjuGejW+aJKCY/pIQ== - dependencies: - "@noble/hashes" "~1.4.0" - "@scure/base" "~1.1.6" - "@scure/bip39@1.5.4", "@scure/bip39@^1.4.0": version "1.5.4" resolved "https://registry.yarnpkg.com/@scure/bip39/-/bip39-1.5.4.tgz#07fd920423aa671be4540d59bdd344cc1461db51" @@ -2894,24 +2861,25 @@ version "0.3.1" resolved "https://codeload.github.com/ecadlabs/axios-fetch-adapter/tar.gz/167684f522e90343b9f3439d9a43ac571e2396f6" -"@walletconnect/core@2.16.1": - version "2.16.1" - resolved "https://registry.yarnpkg.com/@walletconnect/core/-/core-2.16.1.tgz#019b181387792e0d284e75074b961b48193d9b6a" - integrity sha512-UlsnEMT5wwFvmxEjX8s4oju7R3zadxNbZgsFeHEsjh7uknY2zgmUe1Lfc5XU6zyPb1Jx7Nqpdx1KN485ee8ogw== +"@walletconnect/core@2.17.3": + version "2.17.3" + resolved "https://registry.yarnpkg.com/@walletconnect/core/-/core-2.17.3.tgz#e59045a666951e9fc2e8420130c4f93221bd2492" + integrity sha512-57uv0FW4L6H/tmkb1kS2nG41MDguyDgZbGR58nkDUd1TO/HydyiTByVOhFzIxgN331cnY/1G1rMaKqncgdnOFA== dependencies: "@walletconnect/heartbeat" "1.2.2" "@walletconnect/jsonrpc-provider" "1.0.14" "@walletconnect/jsonrpc-types" "1.0.4" "@walletconnect/jsonrpc-utils" "1.0.8" - "@walletconnect/jsonrpc-ws-connection" "1.0.14" + "@walletconnect/jsonrpc-ws-connection" "1.0.16" "@walletconnect/keyvaluestorage" "1.1.1" "@walletconnect/logger" "2.1.2" "@walletconnect/relay-api" "1.0.11" "@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.3" + "@walletconnect/utils" "2.17.3" + "@walletconnect/window-getters" "1.0.1" events "3.3.0" lodash.isequal "4.5.0" uint8arrays "3.1.0" @@ -3007,16 +2975,6 @@ "@walletconnect/jsonrpc-types" "^1.0.3" tslib "1.14.1" -"@walletconnect/jsonrpc-ws-connection@1.0.14": - version "1.0.14" - resolved "https://registry.yarnpkg.com/@walletconnect/jsonrpc-ws-connection/-/jsonrpc-ws-connection-1.0.14.tgz#eec700e74766c7887de2bd76c91a0206628732aa" - integrity sha512-Jsl6fC55AYcbkNVkwNM6Jo+ufsuCQRqViOQ8ZBPH9pRREHH9welbBiszuTLqEJiQcO/6XfFDl6bzCJIkrEi8XA== - dependencies: - "@walletconnect/jsonrpc-utils" "^1.0.6" - "@walletconnect/safe-json" "^1.0.2" - events "^3.3.0" - ws "^7.5.1" - "@walletconnect/jsonrpc-ws-connection@1.0.16": version "1.0.16" resolved "https://registry.yarnpkg.com/@walletconnect/jsonrpc-ws-connection/-/jsonrpc-ws-connection-1.0.16.tgz#666bb13fbf32a2d4f7912d5b4d0bdef26a1d057b" @@ -3081,19 +3039,19 @@ dependencies: tslib "1.14.1" -"@walletconnect/sign-client@2.16.1": - version "2.16.1" - resolved "https://registry.yarnpkg.com/@walletconnect/sign-client/-/sign-client-2.16.1.tgz#94a2f630ba741bd180f540c53576c5ceaace4857" - integrity sha512-s2Tx2n2duxt+sHtuWXrN9yZVaHaYqcEcjwlTD+55/vs5NUPlISf+fFmZLwSeX1kUlrSBrAuxPUcqQuRTKcjLOA== +"@walletconnect/sign-client@2.17.3": + version "2.17.3" + resolved "https://registry.yarnpkg.com/@walletconnect/sign-client/-/sign-client-2.17.3.tgz#86c116bc927946bffa8415ca8d92d3ef412082e1" + integrity sha512-OzOWxRTfVGCHU3OOF6ibPkgPfDpivFJjuknfcOUt9PYWpTAv6YKOmT4cyfBPhc7llruyHpV44fYbykMcLIvEcg== dependencies: - "@walletconnect/core" "2.16.1" + "@walletconnect/core" "2.17.3" "@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.3" + "@walletconnect/utils" "2.17.3" events "3.3.0" "@walletconnect/sign-client@2.18.0": @@ -3118,10 +3076,10 @@ dependencies: tslib "1.14.1" -"@walletconnect/types@2.16.1": - version "2.16.1" - resolved "https://registry.yarnpkg.com/@walletconnect/types/-/types-2.16.1.tgz#6583d458d3f7b1919d482ba516ccb7878ec8c91f" - integrity sha512-9P4RG4VoDEF+yBF/n2TF12gsvT/aTaeZTVDb/AOayafqiPnmrQZMKmNCJJjq1sfdsDcHXFcZWMGsuCeSJCmrXA== +"@walletconnect/types@2.17.3": + version "2.17.3" + resolved "https://registry.yarnpkg.com/@walletconnect/types/-/types-2.17.3.tgz#906f25cf0c9691704b9161eaa305262b0e7626d0" + integrity sha512-5eFxnbZGJJx0IQyCS99qz+OvozpLJJYfVG96dEHGgbzZMd+C9V1eitYqVClx26uX6V+WQVqVwjpD2Dyzie++Wg== dependencies: "@walletconnect/events" "1.0.1" "@walletconnect/heartbeat" "1.2.2" @@ -3160,25 +3118,29 @@ events "3.3.0" lodash "4.17.21" -"@walletconnect/utils@2.16.1": - version "2.16.1" - resolved "https://registry.yarnpkg.com/@walletconnect/utils/-/utils-2.16.1.tgz#2099cc2bd16b0edc32022f64aa2c2c323b45d1d4" - integrity sha512-aoQirVoDoiiEtYeYDtNtQxFzwO/oCrz9zqeEEXYJaAwXlGVTS34KFe7W3/Rxd/pldTYKFOZsku2EzpISfH8Wsw== +"@walletconnect/utils@2.17.3": + version "2.17.3" + resolved "https://registry.yarnpkg.com/@walletconnect/utils/-/utils-2.17.3.tgz#a22938567febc3e3771efae8eb351adf3d499a8d" + integrity sha512-tG77UpZNeLYgeOwViwWnifpyBatkPlpKSSayhN0gcjY1lZAUNqtYslpm4AdTxlrA3pL61MnyybXgWYT5eZjarw== dependencies: + "@ethersproject/hash" "5.7.0" + "@ethersproject/transactions" "5.7.0" "@stablelib/chacha20poly1305" "1.0.1" "@stablelib/hkdf" "1.0.1" "@stablelib/random" "1.0.2" "@stablelib/sha256" "1.0.1" "@stablelib/x25519" "1.0.3" + "@walletconnect/jsonrpc-utils" "1.0.8" + "@walletconnect/keyvaluestorage" "1.1.1" "@walletconnect/relay-api" "1.0.11" "@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.3" "@walletconnect/window-getters" "1.0.1" "@walletconnect/window-metadata" "1.0.1" detect-browser "5.3.0" - elliptic "^6.5.7" + elliptic "6.6.1" query-string "7.1.3" uint8arrays "3.1.0" @@ -3257,11 +3219,6 @@ JSONStream@^1.3.5: jsonparse "^1.2.0" through ">=2.2.7 <3" -abitype@1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/abitype/-/abitype-1.0.5.tgz#29d0daa3eea867ca90f7e4123144c1d1270774b6" - integrity sha512-YzDhti7cjlfaBhHutMaboYB21Ha3rXR9QTkNJFzYC4kC8YclaiwPBBBJY8ejFdu2wnJeZCVZSMlQJ7fi8S6hsw== - abitype@1.0.8, abitype@^1.0.6: version "1.0.8" resolved "https://registry.yarnpkg.com/abitype/-/abitype-1.0.8.tgz#3554f28b2e9d6e9f35eb59878193eabd1b9f46ba" @@ -3504,7 +3461,7 @@ base-x@^5.0.0: resolved "https://registry.yarnpkg.com/base-x/-/base-x-5.0.0.tgz#6d835ceae379130e1a4cb846a70ac4746f28ea9b" integrity sha512-sMW3VGSX1QWVFA6l8U62MLKz29rRfpTlYdCqLdpLo1/Yd4zZwSbnUaDfciIAowAqvq7YFnWq9hrhdg1KYgc1lQ== -base64-js@^1.3.0, base64-js@^1.3.1: +base64-js@^1.1.2, base64-js@^1.3.0, base64-js@^1.3.1: version "1.5.1" resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== @@ -3690,6 +3647,13 @@ brorand@^1.1.0: resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" integrity sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w== +brotli@^1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/brotli/-/brotli-1.3.3.tgz#7365d8cc00f12cf765d2b2c898716bcf4b604d48" + integrity sha512-oTKjJdShmDuGW94SyyaoQvAjf30dZaHnjJ8uAF+u2/vGJkJbJPJAT1gDiOJP5v1Zb6f9KEyW/1HpuaWIXtGHPg== + dependencies: + base64-js "^1.1.2" + browserify-aes@^1.0.6: version "1.2.0" resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48" @@ -5582,11 +5546,6 @@ isomorphic-ws@^4.0.1: resolved "https://registry.yarnpkg.com/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz#55fd4cd6c5e6491e76dc125938dd863f5cd4f2dc" integrity sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w== -isows@1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/isows/-/isows-1.0.4.tgz#810cd0d90cc4995c26395d2aa4cfa4037ebdf061" - integrity sha512-hEzjY+x9u9hPmBom9IIAqdJCwNLax+xrPb51vEPpERoFlIxgmZcHzsT5jKG06nvInKOBGvReAVz80Umed5CczQ== - isows@1.0.6: version "1.0.6" resolved "https://registry.yarnpkg.com/isows/-/isows-1.0.6.tgz#0da29d706fa51551c663c627ace42769850f86e7" @@ -7713,21 +7672,7 @@ varuint-bitcoin@^1.0.1, varuint-bitcoin@^1.1.2: dependencies: safe-buffer "^5.1.1" -viem@2.17.8: - version "2.17.8" - resolved "https://registry.yarnpkg.com/viem/-/viem-2.17.8.tgz#79da50ef86fb429d3b36d4ef2f49be5b2999420f" - integrity sha512-AnLX26/8UAVguXvTc+o5jvehAUfoujomH+WLPNCo0Y0ukb9Z4qWpunkHvPyazeExP2V7EevVJB79mstZh0fLsQ== - dependencies: - "@adraffy/ens-normalize" "1.10.0" - "@noble/curves" "1.4.0" - "@noble/hashes" "1.4.0" - "@scure/bip32" "1.4.0" - "@scure/bip39" "1.3.0" - abitype "1.0.5" - isows "1.0.4" - ws "8.17.1" - -viem@>=2.23, viem@>=2.23.0: +viem@2.23.2, viem@>=2.23, viem@>=2.23.0: version "2.23.2" resolved "https://registry.yarnpkg.com/viem/-/viem-2.23.2.tgz#db395c8cf5f4fb5572914b962fb8ce5db09f681c" integrity sha512-NVmW/E0c5crMOtbEAqMF0e3NmvQykFXhLOc/CkLIXOlzHSA6KXVz3CYVmaKqBF8/xtjsjHAGjdJN3Ru1kFJLaA== @@ -7869,11 +7814,6 @@ ws@7.4.6: resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.6.tgz#5654ca8ecdeee47c33a9a4bf6d28e2be2980377c" integrity sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A== -ws@8.17.1: - version "8.17.1" - resolved "https://registry.yarnpkg.com/ws/-/ws-8.17.1.tgz#9293da530bb548febc95371d90f9c878727d919b" - integrity sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ== - ws@8.18.0: version "8.18.0" resolved "https://registry.yarnpkg.com/ws/-/ws-8.18.0.tgz#0d7505a6eafe2b0e712d232b42279f53bc289bbc"