diff --git a/wallets/react-wallet-v2/src/components/AccountPicker.tsx b/wallets/react-wallet-v2/src/components/AccountPicker.tsx index ac5083e..1c0db84 100644 --- a/wallets/react-wallet-v2/src/components/AccountPicker.tsx +++ b/wallets/react-wallet-v2/src/components/AccountPicker.tsx @@ -1,17 +1,18 @@ import SettingsStore from '@/store/SettingsStore' +import { addresses } from '@/utils/WalletUtil' import { useSnapshot } from 'valtio' export default function AccountPicker() { - const { account } = useSnapshot(SettingsStore.state) + const { address } = useSnapshot(SettingsStore.state) return ( ) } diff --git a/wallets/react-wallet-v2/src/hooks/useInitialization.ts b/wallets/react-wallet-v2/src/hooks/useInitialization.ts index 56cf271..5b97ad6 100644 --- a/wallets/react-wallet-v2/src/hooks/useInitialization.ts +++ b/wallets/react-wallet-v2/src/hooks/useInitialization.ts @@ -1,3 +1,4 @@ +import SettingsStore from '@/store/SettingsStore' import { createWalletConnectClient } from '@/utils/WalletConnectUtil' import { createOrRestoreWallet } from '@/utils/WalletUtil' import { useCallback, useEffect, useState } from 'react' @@ -7,7 +8,8 @@ export default function useInitialization() { const onInitialize = useCallback(async () => { try { - createOrRestoreWallet() + const { addresses } = createOrRestoreWallet() + SettingsStore.setAddress(addresses[0]) await createWalletConnectClient() setInitialized(true) } catch (err: unknown) { diff --git a/wallets/react-wallet-v2/src/pages/index.tsx b/wallets/react-wallet-v2/src/pages/index.tsx index 7b677b1..feae016 100644 --- a/wallets/react-wallet-v2/src/pages/index.tsx +++ b/wallets/react-wallet-v2/src/pages/index.tsx @@ -3,14 +3,12 @@ import AccountPicker from '@/components/AccountPicker' import PageHeader from '@/components/PageHeader' import { EIP155_MAINNET_CHAINS, EIP155_TEST_CHAINS } from '@/data/EIP155Data' import SettingsStore from '@/store/SettingsStore' -import { wallets } from '@/utils/WalletUtil' import { Text } from '@nextui-org/react' import { Fragment } from 'react' import { useSnapshot } from 'valtio' export default function HomePage() { - const { testNets, account } = useSnapshot(SettingsStore.state) - const addresses = Object.keys(wallets) + const { testNets, address } = useSnapshot(SettingsStore.state) return ( @@ -21,7 +19,7 @@ export default function HomePage() { Mainnets {Object.values(EIP155_MAINNET_CHAINS).map(({ name, logo, rgb }) => ( - + ))} {testNets ? ( @@ -30,13 +28,7 @@ export default function HomePage() { Testnets {Object.values(EIP155_TEST_CHAINS).map(({ name, logo, rgb }) => ( - + ))} ) : null} diff --git a/wallets/react-wallet-v2/src/pages/settings.tsx b/wallets/react-wallet-v2/src/pages/settings.tsx index a30cb3a..3964abe 100644 --- a/wallets/react-wallet-v2/src/pages/settings.tsx +++ b/wallets/react-wallet-v2/src/pages/settings.tsx @@ -6,7 +6,7 @@ import { Fragment } from 'react' import { useSnapshot } from 'valtio' export default function SettingsPage() { - const { testNets } = useSnapshot(SettingsStore.state) + const { testNets, address } = useSnapshot(SettingsStore.state) return ( @@ -15,9 +15,7 @@ export default function SettingsPage() { Mnemonic - - {wallets['0xD0712a5018b6F3401b90Cd75C15d95B3353a4088'].mnemonic.phrase} - + {wallets[address].mnemonic.phrase} diff --git a/wallets/react-wallet-v2/src/store/SettingsStore.ts b/wallets/react-wallet-v2/src/store/SettingsStore.ts index 23075ef..e50eafe 100644 --- a/wallets/react-wallet-v2/src/store/SettingsStore.ts +++ b/wallets/react-wallet-v2/src/store/SettingsStore.ts @@ -5,7 +5,7 @@ import { proxy } from 'valtio' */ interface State { testNets: boolean - account: number + address: string } /** @@ -13,7 +13,7 @@ interface State { */ const state = proxy({ testNets: typeof localStorage !== 'undefined' ? Boolean(localStorage.getItem('TEST_NETS')) : true, - account: 0 + address: '' }) /** @@ -22,8 +22,8 @@ const state = proxy({ const SettingsStore = { state, - setAccount(value: number | string) { - state.account = Number(value) + setAddress(address: string) { + state.address = address }, toggleTestNets() { diff --git a/wallets/react-wallet-v2/src/utils/HelperUtil.ts b/wallets/react-wallet-v2/src/utils/HelperUtil.ts index 86ea4b9..9ddf3da 100644 --- a/wallets/react-wallet-v2/src/utils/HelperUtil.ts +++ b/wallets/react-wallet-v2/src/utils/HelperUtil.ts @@ -52,3 +52,20 @@ export function getSignTypedDataParamsData(params: string[]) { return data } + +/** + * Get our address from params checking if params string contains one + * of our wallet addresses + */ +export function getWalletAddressFromParams(addresses: string[], params: any) { + const paramsString = JSON.stringify(params) + let address = '' + + addresses.forEach(addr => { + if (paramsString.includes(addr)) { + address = addr + } + }) + + return address +} diff --git a/wallets/react-wallet-v2/src/utils/RequestHandlerUtil.ts b/wallets/react-wallet-v2/src/utils/RequestHandlerUtil.ts index e140a85..b9e9acb 100644 --- a/wallets/react-wallet-v2/src/utils/RequestHandlerUtil.ts +++ b/wallets/react-wallet-v2/src/utils/RequestHandlerUtil.ts @@ -1,12 +1,19 @@ -import { EIP155_SIGNING_METHODS } from '@/data/EIP155Data' -import { getSignParamsMessage, getSignTypedDataParamsData } from '@/utils/HelperUtil' +import { EIP155_CHAINS, EIP155_SIGNING_METHODS, TEIP155Chain } from '@/data/EIP155Data' +import { + getSignParamsMessage, + getSignTypedDataParamsData, + getWalletAddressFromParams +} from '@/utils/HelperUtil' +import { addresses, wallets } from '@/utils/WalletUtil' import { formatJsonRpcError, formatJsonRpcResult } from '@json-rpc-tools/utils' import { RequestEvent } from '@walletconnect/types' import { ERROR } from '@walletconnect/utils' -import { Wallet } from 'ethers' +import { providers } from 'ethers' -export async function approveEIP155Request(request: RequestEvent['request'], wallet: Wallet) { - const { method, params, id } = request +export async function approveEIP155Request(requestEvent: RequestEvent) { + const { method, params, id } = requestEvent.request + const { chainId } = requestEvent + const wallet = wallets[getWalletAddressFromParams(addresses, params)] switch (method) { case EIP155_SIGNING_METHODS.PERSONAL_SIGN: @@ -25,8 +32,10 @@ export async function approveEIP155Request(request: RequestEvent['request'], wal return formatJsonRpcResult(id, signedData) case EIP155_SIGNING_METHODS.ETH_SEND_TRANSACTION: + const provider = new providers.JsonRpcProvider(EIP155_CHAINS[chainId as TEIP155Chain].rpc) const sendTransaction = params[0] - const { hash } = await wallet.sendTransaction(sendTransaction) + const connectedWallet = wallet.connect(provider) + const { hash } = await connectedWallet.sendTransaction(sendTransaction) return formatJsonRpcResult(id, hash) case EIP155_SIGNING_METHODS.ETH_SIGN_TRANSACTION: diff --git a/wallets/react-wallet-v2/src/utils/WalletUtil.ts b/wallets/react-wallet-v2/src/utils/WalletUtil.ts index e5ec22f..67e771c 100644 --- a/wallets/react-wallet-v2/src/utils/WalletUtil.ts +++ b/wallets/react-wallet-v2/src/utils/WalletUtil.ts @@ -1,6 +1,7 @@ import { Wallet } from 'ethers' export let wallets: Record +export let addresses: string[] export let wallet1: Wallet export let wallet2: Wallet @@ -21,4 +22,10 @@ export function createOrRestoreWallet() { [wallet1.address]: wallet1, [wallet2.address]: wallet2 } + addresses = Object.keys(wallets) + + return { + wallets, + addresses + } } diff --git a/wallets/react-wallet-v2/src/views/SessionProposalModal.tsx b/wallets/react-wallet-v2/src/views/SessionProposalModal.tsx index d57809d..cd286e3 100644 --- a/wallets/react-wallet-v2/src/views/SessionProposalModal.tsx +++ b/wallets/react-wallet-v2/src/views/SessionProposalModal.tsx @@ -1,11 +1,25 @@ import { EIP155_CHAINS, TEIP155Chain } from '@/data/EIP155Data' import ModalStore from '@/store/ModalStore' +import { truncate } from '@/utils/HelperUtil' import { walletConnectClient } from '@/utils/WalletConnectUtil' -import { wallets } from '@/utils/WalletUtil' -import { Avatar, Button, Col, Container, Divider, Link, Modal, Row, Text } from '@nextui-org/react' -import { Fragment } from 'react' +import { addresses } from '@/utils/WalletUtil' +import { + Avatar, + Button, + Card, + Col, + Container, + Divider, + Link, + Modal, + Row, + Text +} from '@nextui-org/react' +import { Fragment, useState } from 'react' export default function SessionProposalModal() { + const [selectedAddresses, setSelectedAddresses] = useState([]) + // Get proposal data and wallet address from store const proposal = ModalStore.state.data?.proposal @@ -21,14 +35,29 @@ export default function SessionProposalModal() { const { methods } = permissions.jsonrpc const { protocol } = relay + // Add / remove address from selection + function onSelectAddress(address: string) { + if (selectedAddresses.includes(address)) { + const newAddresses = selectedAddresses.filter(a => a !== address) + setSelectedAddresses(newAddresses) + } else { + setSelectedAddresses([...selectedAddresses, address]) + } + } + // Hanlde approve action async function onApprove() { if (proposal) { + const accounts: string[] = [] + chains.forEach(chain => { + selectedAddresses.forEach(address => { + accounts.push(`${chain}:${address}`) + }) + }) + const response = { state: { - accounts: chains.map( - chain => `${chain}:${wallets['0xD0712a5018b6F3401b90Cd75C15d95B3353a4088'].address}` - ) + accounts } } await walletConnectClient.approve({ proposal, response }) @@ -92,6 +121,27 @@ export default function SessionProposalModal() { {protocol} + + + + + + Select Accounts to Connect + {addresses.map((address, index) => ( + onSelectAddress(address)} + clickable + key={address} + css={{ + marginTop: '$5', + backgroundColor: selectedAddresses.includes(address) ? '$green600' : '$accents2' + }} + > + {`Acc ${index + 1} - ${truncate(address, 19)}`} + + ))} + + @@ -99,7 +149,14 @@ export default function SessionProposalModal() { - diff --git a/wallets/react-wallet-v2/src/views/SessionSendTransactionModal.tsx b/wallets/react-wallet-v2/src/views/SessionSendTransactionModal.tsx index 507af48..e975b5c 100644 --- a/wallets/react-wallet-v2/src/views/SessionSendTransactionModal.tsx +++ b/wallets/react-wallet-v2/src/views/SessionSendTransactionModal.tsx @@ -3,7 +3,6 @@ import ModalStore from '@/store/ModalStore' import { truncate } from '@/utils/HelperUtil' import { approveEIP155Request, rejectEIP155Request } from '@/utils/RequestHandlerUtil' import { walletConnectClient } from '@/utils/WalletConnectUtil' -import { wallets } from '@/utils/WalletUtil' import { Avatar, Button, @@ -16,7 +15,6 @@ import { Row, Text } from '@nextui-org/react' -import { providers } from 'ethers' import { Fragment, useState } from 'react' export default function SessionSendTransactionModal() { @@ -42,10 +40,7 @@ export default function SessionSendTransactionModal() { async function onApprove() { if (requestEvent) { setLoading(true) - const provider = new providers.JsonRpcProvider(EIP155_CHAINS[chainId as TEIP155Chain].rpc) - const connectedWallet = - wallets['0xD0712a5018b6F3401b90Cd75C15d95B3353a4088'].connect(provider) - const response = await approveEIP155Request(requestEvent.request, connectedWallet) + const response = await approveEIP155Request(requestEvent) await walletConnectClient.respond({ topic: requestEvent.topic, response diff --git a/wallets/react-wallet-v2/src/views/SessionSignModal.tsx b/wallets/react-wallet-v2/src/views/SessionSignModal.tsx index 9aa1d91..c43eef8 100644 --- a/wallets/react-wallet-v2/src/views/SessionSignModal.tsx +++ b/wallets/react-wallet-v2/src/views/SessionSignModal.tsx @@ -3,7 +3,6 @@ import ModalStore from '@/store/ModalStore' import { getSignParamsMessage } from '@/utils/HelperUtil' import { approveEIP155Request, rejectEIP155Request } from '@/utils/RequestHandlerUtil' import { walletConnectClient } from '@/utils/WalletConnectUtil' -import { wallets } from '@/utils/WalletUtil' import { Avatar, Button, Col, Container, Divider, Link, Modal, Row, Text } from '@nextui-org/react' import { Fragment } from 'react' @@ -29,10 +28,7 @@ export default function SessionSignModal() { // Handle approve action (logic varies based on request method) async function onApprove() { if (requestEvent) { - const response = await approveEIP155Request( - requestEvent.request, - wallets['0xD0712a5018b6F3401b90Cd75C15d95B3353a4088'] - ) + const response = await approveEIP155Request(requestEvent) await walletConnectClient.respond({ topic: requestEvent.topic, response diff --git a/wallets/react-wallet-v2/src/views/SessionSignTypedDataModal.tsx b/wallets/react-wallet-v2/src/views/SessionSignTypedDataModal.tsx index 287f038..53d2c30 100644 --- a/wallets/react-wallet-v2/src/views/SessionSignTypedDataModal.tsx +++ b/wallets/react-wallet-v2/src/views/SessionSignTypedDataModal.tsx @@ -3,7 +3,6 @@ import ModalStore from '@/store/ModalStore' import { getSignTypedDataParamsData } from '@/utils/HelperUtil' import { approveEIP155Request, rejectEIP155Request } from '@/utils/RequestHandlerUtil' import { walletConnectClient } from '@/utils/WalletConnectUtil' -import { wallets } from '@/utils/WalletUtil' import { Avatar, Button, Col, Container, Divider, Link, Modal, Row, Text } from '@nextui-org/react' import { Fragment } from 'react' import { CodeBlock, codepen } from 'react-code-blocks' @@ -30,10 +29,7 @@ export default function SessionSignTypedDataModal() { // Handle approve action (logic varies based on request method) async function onApprove() { if (requestEvent) { - const response = await approveEIP155Request( - requestEvent.request, - wallets['0xD0712a5018b6F3401b90Cd75C15d95B3353a4088'] - ) + const response = await approveEIP155Request(requestEvent) await walletConnectClient.respond({ topic: requestEvent.topic, response