Beta 100 (#27)
* update deps * revert react dep updates * chore: update deps to beta.50 * fix: get dapp running again up to Client.connect() * save progress * feat(debug): sets up a debug peerClient as responder * refactor: remove more hardcoded example connect params * fix: gets `checkPersistedState` working again * fix: gets client.disconnect + effects working again * feat: integrates `session_update` handling with namespaces * fix: remove hardcoded `chains` * stash progress * Establish session * save progress - established session with example dapp * refactor: rewrite namespace helpers to handle `requiredNamespaces` (#23) * fix: re-enables restoring persisted session * refactor: remove debug peerClient code * fix: re-enables restoring persisted pairings * Save progress * fix: re-enables pairing modal, connecting from existing pairing * Update modals to handle new payloads * fix(types): fix Metadata typing * chore(deps): upgrade to beta.53 * refactor: adjusts event handler args for beta.53 `session_update` * stash * fix: adds missing keys for `DEFAULT_EIP155_EVENTS` enum * stash * chore: update comment for client.request typing FIXME * feat: integrate beta.54 * feat: integrate beta.55, removes FIXME comments for client.request types * chore: clean up unused import * fix: log session_ping event * fix: log incoming `session_event` * chore: upgrade client@2.0.0-beta.55 -> sign-client@2.0.0-beta.56 * chore: integrate beta.57 * New beta changes (#24) * smal lchange * fix types * Add package info * format empty methods / events * Update deps * adjust styles * attempt ios layout fix * Revert "attempt ios layout fix" This reverts commit f0176f2ef52f338980ee54e75a767b3d452733f2. * beta.54 * fix build * Update to beta 55 * Add todos * update wallet to beta 56 * Update mumbai rpc add logger * update to beta 57 * chore: adds note on beta.100 compatibility * plock * beta.58 * beta.100; Co-authored-by: Ilja <idaderko@gmail.com> Co-authored-by: Ben Kremer <ben@walletconnect.com> Co-authored-by: Ilja <IljaDaderko@users.noreply.github.com>
This commit is contained in:
co-authored by
Ilja
Ben Kremer
Ilja
parent
dc76f21c2c
commit
954831538d
@@ -1,5 +1,7 @@
|
||||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
||||
|
||||
.DS_Store
|
||||
|
||||
# dependencies
|
||||
/node_modules
|
||||
/.pnp
|
||||
|
||||
@@ -13,13 +13,13 @@
|
||||
"@cosmjs/proto-signing": "0.28.4",
|
||||
"@json-rpc-tools/utils": "1.7.6",
|
||||
"@nextui-org/react": "1.0.8-beta.5",
|
||||
"@solana/web3.js": "1.39.1",
|
||||
"@walletconnect/client": "2.0.0-beta.26",
|
||||
"@walletconnect/utils": "2.0.0-beta.26",
|
||||
"@solana/web3.js": "1.43.0",
|
||||
"@walletconnect/sign-client": "2.0.0-beta.100",
|
||||
"@walletconnect/utils": "2.0.0-beta.100",
|
||||
"bs58": "5.0.0",
|
||||
"cosmos-wallet": "1.2.0",
|
||||
"ethers": "5.6.4",
|
||||
"framer-motion": "6.3.0",
|
||||
"ethers": "5.6.6",
|
||||
"framer-motion": "6.3.3",
|
||||
"mnemonic-keyring": "1.4.0",
|
||||
"next": "12.1.5",
|
||||
"react": "17.0.2",
|
||||
@@ -27,16 +27,16 @@
|
||||
"react-dom": "17.0.2",
|
||||
"react-qr-reader-es6": "2.2.1-2",
|
||||
"solana-wallet": "1.0.1",
|
||||
"valtio": "1.5.2"
|
||||
"valtio": "1.6.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "17.0.25",
|
||||
"@types/react": "17.0.40",
|
||||
"@walletconnect/types": "2.0.0-beta.26",
|
||||
"eslint": "8.13.0",
|
||||
"eslint-config-next": "12.1.5",
|
||||
"@types/node": "17.0.35",
|
||||
"@types/react": "18.0.9",
|
||||
"@walletconnect/types": "2.0.0-beta.100",
|
||||
"eslint": "8.15.0",
|
||||
"eslint-config-next": "12.1.6",
|
||||
"eslint-config-prettier": "8.5.0",
|
||||
"prettier": "2.6.2",
|
||||
"typescript": "4.6.3"
|
||||
"typescript": "4.6.4"
|
||||
}
|
||||
}
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
.container {
|
||||
width: 100%;
|
||||
height: calc(100% - 220px);
|
||||
display: flex;
|
||||
flex: 1;
|
||||
flex-direction: column;
|
||||
@@ -82,4 +83,4 @@ select:hover {
|
||||
|
||||
i {
|
||||
margin-top: -5px !important;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import ChainCard from '@/components/ChainCard'
|
||||
import { truncate } from '@/utils/HelperUtil'
|
||||
import { Avatar, Button, Card, Text, Tooltip } from '@nextui-org/react'
|
||||
import { Avatar, Button, Text, Tooltip } from '@nextui-org/react'
|
||||
import Image from 'next/image'
|
||||
import { useState } from 'react'
|
||||
|
||||
@@ -20,50 +21,31 @@ export default function AccountCard({ name, logo, rgb, address }: Props) {
|
||||
}
|
||||
|
||||
return (
|
||||
<Card
|
||||
bordered
|
||||
borderWeight="light"
|
||||
css={{
|
||||
borderColor: `rgba(${rgb}, 0.4)`,
|
||||
boxShadow: `0 0 10px 0 rgba(${rgb}, 0.15)`,
|
||||
backgroundColor: `rgba(${rgb}, 0.25)`,
|
||||
marginBottom: '$6',
|
||||
minHeight: '70px'
|
||||
}}
|
||||
>
|
||||
<Card.Body
|
||||
css={{
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'space-between',
|
||||
overflow: 'hidden'
|
||||
}}
|
||||
>
|
||||
<Avatar src={logo} />
|
||||
<div style={{ flex: 1 }}>
|
||||
<Text h5 css={{ marginLeft: '$9' }}>
|
||||
{name}
|
||||
</Text>
|
||||
<Text weight="light" size={13} css={{ marginLeft: '$9' }}>
|
||||
{truncate(address, 19)}
|
||||
</Text>
|
||||
</div>
|
||||
<ChainCard rgb={rgb} flexDirection="row" alignItems="center">
|
||||
<Avatar src={logo} />
|
||||
<div style={{ flex: 1 }}>
|
||||
<Text h5 css={{ marginLeft: '$9' }}>
|
||||
{name}
|
||||
</Text>
|
||||
<Text weight="light" size={13} css={{ marginLeft: '$9' }}>
|
||||
{truncate(address, 19)}
|
||||
</Text>
|
||||
</div>
|
||||
|
||||
<Tooltip content={copied ? 'Copied!' : 'Copy'} placement="left">
|
||||
<Button
|
||||
size="sm"
|
||||
css={{ minWidth: 'auto', backgroundColor: 'rgba(255, 255, 255, 0.15)' }}
|
||||
onClick={onCopy}
|
||||
>
|
||||
<Image
|
||||
src={copied ? '/icons/checkmark-icon.svg' : '/icons/copy-icon.svg'}
|
||||
width={15}
|
||||
height={15}
|
||||
alt="copy icon"
|
||||
/>
|
||||
</Button>
|
||||
</Tooltip>
|
||||
</Card.Body>
|
||||
</Card>
|
||||
<Tooltip content={copied ? 'Copied!' : 'Copy'} placement="left">
|
||||
<Button
|
||||
size="sm"
|
||||
css={{ minWidth: 'auto', backgroundColor: 'rgba(255, 255, 255, 0.15)' }}
|
||||
onClick={onCopy}
|
||||
>
|
||||
<Image
|
||||
src={copied ? '/icons/checkmark-icon.svg' : '/icons/copy-icon.svg'}
|
||||
width={15}
|
||||
height={15}
|
||||
alt="copy icon"
|
||||
/>
|
||||
</Button>
|
||||
</Tooltip>
|
||||
</ChainCard>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
import { Card } from '@nextui-org/react'
|
||||
import { ReactNode } from 'react'
|
||||
|
||||
interface Props {
|
||||
children: ReactNode | ReactNode[]
|
||||
rgb: string
|
||||
flexDirection: 'row' | 'col'
|
||||
alignItems: 'center' | 'flex-start'
|
||||
}
|
||||
|
||||
export default function ChainCard({ rgb, children, flexDirection, alignItems }: Props) {
|
||||
return (
|
||||
<Card
|
||||
bordered
|
||||
borderWeight="light"
|
||||
css={{
|
||||
borderColor: `rgba(${rgb}, 0.4)`,
|
||||
boxShadow: `0 0 10px 0 rgba(${rgb}, 0.15)`,
|
||||
backgroundColor: `rgba(${rgb}, 0.25)`,
|
||||
marginBottom: '$6',
|
||||
minHeight: '70px'
|
||||
}}
|
||||
>
|
||||
<Card.Body
|
||||
css={{
|
||||
flexDirection,
|
||||
alignItems,
|
||||
justifyContent: 'space-between',
|
||||
overflow: 'hidden'
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</Card.Body>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
@@ -31,7 +31,7 @@ export default function Layout({ children, initialized }: Props) {
|
||||
bordered={{ '@initial': false, '@xs': true }}
|
||||
borderWeight={{ '@initial': 'light', '@xs': 'light' }}
|
||||
css={{
|
||||
height: '100vh',
|
||||
height: '100%',
|
||||
width: '100%',
|
||||
justifyContent: initialized ? 'normal' : 'center',
|
||||
alignItems: initialized ? 'normal' : 'center',
|
||||
@@ -49,8 +49,10 @@ export default function Layout({ children, initialized }: Props) {
|
||||
<RouteTransition>
|
||||
<Card.Body
|
||||
css={{
|
||||
display: 'block',
|
||||
paddingLeft: 2,
|
||||
paddingRight: 2,
|
||||
paddingBottom: '40px',
|
||||
'@xs': {
|
||||
padding: '20px',
|
||||
paddingBottom: '40px'
|
||||
@@ -69,6 +71,7 @@ export default function Layout({ children, initialized }: Props) {
|
||||
justifyContent: 'flex-end',
|
||||
alignItems: 'flex-end',
|
||||
boxShadow: '0 -30px 20px #111111',
|
||||
backgroundColor: '#111111',
|
||||
zIndex: 200,
|
||||
bottom: 0,
|
||||
left: 0
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { Avatar, Col, Link, Row, Text } from '@nextui-org/react'
|
||||
import { SessionTypes } from '@walletconnect/types'
|
||||
import { SignClientTypes } from '@walletconnect/types'
|
||||
|
||||
/**
|
||||
* Types
|
||||
*/
|
||||
interface IProps {
|
||||
metadata: SessionTypes.Participant['metadata']
|
||||
metadata: SignClientTypes.Metadata
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,46 +1,39 @@
|
||||
import AccountSelectCard from '@/components/AccountSelectCard'
|
||||
import { Col, Divider, Row, Text } from '@nextui-org/react'
|
||||
import { Fragment } from 'react'
|
||||
import { Col, Row, Text } from '@nextui-org/react'
|
||||
|
||||
/**
|
||||
* Types
|
||||
*/
|
||||
interface IProps {
|
||||
name: string
|
||||
chain: string
|
||||
addresses: string[]
|
||||
selectedAddresses: string[]
|
||||
onSelect: (address: string) => void
|
||||
selectedAddresses: string[] | undefined
|
||||
onSelect: (chain: string, address: string) => void
|
||||
}
|
||||
|
||||
/**
|
||||
* Component
|
||||
*/
|
||||
export default function ProposalSelectSection({
|
||||
name,
|
||||
addresses,
|
||||
selectedAddresses,
|
||||
chain,
|
||||
onSelect
|
||||
}: IProps) {
|
||||
return (
|
||||
<Fragment>
|
||||
<Divider y={2} />
|
||||
|
||||
<Row>
|
||||
<Col>
|
||||
<Text h5>{`Select ${name} Accounts`}</Text>
|
||||
{addresses.map((address, index) => (
|
||||
<AccountSelectCard
|
||||
key={address}
|
||||
address={address}
|
||||
index={index}
|
||||
onSelect={() => onSelect(`${chain}:${address}`)}
|
||||
selected={selectedAddresses.includes(`${chain}:${address}`)}
|
||||
/>
|
||||
))}
|
||||
</Col>
|
||||
</Row>
|
||||
</Fragment>
|
||||
<Row>
|
||||
<Col>
|
||||
<Text h4 css={{ marginTop: '$5' }}>{`Choose ${chain} accounts`}</Text>
|
||||
{addresses.map((address, index) => (
|
||||
<AccountSelectCard
|
||||
key={address}
|
||||
address={address}
|
||||
index={index}
|
||||
onSelect={() => onSelect(chain, address)}
|
||||
selected={selectedAddresses?.includes(address) ?? false}
|
||||
/>
|
||||
))}
|
||||
</Col>
|
||||
</Row>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
import ChainCard from '@/components/ChainCard'
|
||||
import { COSMOS_MAINNET_CHAINS } from '@/data/COSMOSData'
|
||||
import { EIP155_MAINNET_CHAINS, EIP155_TEST_CHAINS } from '@/data/EIP155Data'
|
||||
import { SOLANA_MAINNET_CHAINS, SOLANA_TEST_CHAINS } from '@/data/SolanaData'
|
||||
import { formatChainName } from '@/utils/HelperUtil'
|
||||
import { Col, Row, Text } from '@nextui-org/react'
|
||||
import { SessionTypes } from '@walletconnect/types'
|
||||
import { Fragment } from 'react'
|
||||
|
||||
/**
|
||||
* Utilities
|
||||
*/
|
||||
const CHAIN_METADATA = {
|
||||
...COSMOS_MAINNET_CHAINS,
|
||||
...SOLANA_MAINNET_CHAINS,
|
||||
...EIP155_MAINNET_CHAINS,
|
||||
...EIP155_TEST_CHAINS,
|
||||
...SOLANA_TEST_CHAINS
|
||||
}
|
||||
|
||||
/**
|
||||
* Types
|
||||
*/
|
||||
interface IProps {
|
||||
namespace: SessionTypes.Namespace
|
||||
}
|
||||
|
||||
/**
|
||||
* Component
|
||||
*/
|
||||
export default function SessionChainCard({ namespace }: IProps) {
|
||||
const chains: string[] = []
|
||||
|
||||
// WIP
|
||||
|
||||
namespace.accounts.forEach(account => {
|
||||
const [type, chain] = account.split(':')
|
||||
const chainId = `${type}:${chain}`
|
||||
chains.push(chainId)
|
||||
})
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
{chains.map(chainId => {
|
||||
const extensionMethods: SessionTypes.Namespace['methods'] = []
|
||||
const extensionEvents: SessionTypes.Namespace['events'] = []
|
||||
|
||||
namespace.extension?.map(({ accounts, methods, events }) => {
|
||||
accounts.forEach(account => {
|
||||
const [type, chain] = account.split(':')
|
||||
const chainId = `${type}:${chain}`
|
||||
if (chains.includes(chainId)) {
|
||||
extensionMethods.push(...methods)
|
||||
extensionEvents.push(...events)
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
const allMethods = [...namespace.methods, ...extensionMethods]
|
||||
const allEvents = [...namespace.events, ...extensionEvents]
|
||||
// @ts-expect-error
|
||||
const rgb = CHAIN_METADATA[chainId]?.rgb
|
||||
|
||||
return (
|
||||
<ChainCard key={chainId} rgb={rgb ?? ''} flexDirection="col" alignItems="flex-start">
|
||||
<Text h5 css={{ marginBottom: '$5' }}>
|
||||
{formatChainName(chainId)}
|
||||
</Text>
|
||||
<Row>
|
||||
<Col>
|
||||
<Text h6>Methods</Text>
|
||||
<Text color="$gray300">{allMethods.length ? allMethods.join(', ') : '-'}</Text>
|
||||
</Col>
|
||||
</Row>
|
||||
<Row css={{ marginTop: '$5' }}>
|
||||
<Col>
|
||||
<Text h6>Events</Text>
|
||||
<Text color="$gray300">{allEvents.length ? allEvents.join(', ') : '-'}</Text>
|
||||
</Col>
|
||||
</Row>
|
||||
</ChainCard>
|
||||
)
|
||||
})}
|
||||
</Fragment>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
import ChainCard from '@/components/ChainCard'
|
||||
import { COSMOS_MAINNET_CHAINS } from '@/data/COSMOSData'
|
||||
import { EIP155_MAINNET_CHAINS, EIP155_TEST_CHAINS } from '@/data/EIP155Data'
|
||||
import { SOLANA_MAINNET_CHAINS, SOLANA_TEST_CHAINS } from '@/data/SolanaData'
|
||||
import { formatChainName } from '@/utils/HelperUtil'
|
||||
import { Col, Row, Text } from '@nextui-org/react'
|
||||
import { ProposalTypes } from '@walletconnect/types'
|
||||
import { Fragment } from 'react'
|
||||
|
||||
/**
|
||||
* Utilities
|
||||
*/
|
||||
const CHAIN_METADATA = {
|
||||
...COSMOS_MAINNET_CHAINS,
|
||||
...SOLANA_MAINNET_CHAINS,
|
||||
...EIP155_MAINNET_CHAINS,
|
||||
...EIP155_TEST_CHAINS,
|
||||
...SOLANA_TEST_CHAINS
|
||||
}
|
||||
|
||||
/**
|
||||
* Types
|
||||
*/
|
||||
interface IProps {
|
||||
requiredNamespace: ProposalTypes.RequiredNamespace
|
||||
}
|
||||
|
||||
/**
|
||||
* Component
|
||||
*/
|
||||
export default function SessionProposalChainCard({ requiredNamespace }: IProps) {
|
||||
return (
|
||||
<Fragment>
|
||||
{requiredNamespace.chains.map(chainId => {
|
||||
const extensionMethods: ProposalTypes.RequiredNamespace['methods'] = []
|
||||
const extensionEvents: ProposalTypes.RequiredNamespace['events'] = []
|
||||
|
||||
requiredNamespace.extension?.map(({ chains, methods, events }) => {
|
||||
if (chains.includes(chainId)) {
|
||||
extensionMethods.push(...methods)
|
||||
extensionEvents.push(...events)
|
||||
}
|
||||
})
|
||||
|
||||
const allMethods = [...requiredNamespace.methods, ...extensionMethods]
|
||||
const allEvents = [...requiredNamespace.events, ...extensionEvents]
|
||||
// @ts-expect-error
|
||||
const rgb = CHAIN_METADATA[chainId]?.rgb
|
||||
|
||||
return (
|
||||
<ChainCard key={chainId} rgb={rgb ?? ''} flexDirection="col" alignItems="flex-start">
|
||||
<Text h5 css={{ marginBottom: '$5' }}>
|
||||
{formatChainName(chainId)}
|
||||
</Text>
|
||||
<Row>
|
||||
<Col>
|
||||
<Text h6>Methods</Text>
|
||||
<Text color="$gray300">{allMethods.length ? allMethods.join(', ') : '-'}</Text>
|
||||
</Col>
|
||||
</Row>
|
||||
<Row css={{ marginTop: '$5' }}>
|
||||
<Col>
|
||||
<Text h6>Events</Text>
|
||||
<Text color="$gray300">{allEvents.length ? allEvents.join(', ') : '-'}</Text>
|
||||
</Col>
|
||||
</Row>
|
||||
</ChainCard>
|
||||
)
|
||||
})}
|
||||
</Fragment>
|
||||
)
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
import AccountSelectCard from '@/components/AccountSelectCard'
|
||||
import { Col, Divider, Row, Text } from '@nextui-org/react'
|
||||
import { Fragment } from 'react'
|
||||
|
||||
/**
|
||||
* Types
|
||||
*/
|
||||
interface IProps {
|
||||
name: string
|
||||
chain: string
|
||||
addresses: string[]
|
||||
selectedAddresses: string[]
|
||||
onDelete: (address: string) => void
|
||||
onAdd: (address: string) => void
|
||||
}
|
||||
|
||||
/**
|
||||
* Component
|
||||
*/
|
||||
export default function SessionSelectSection({
|
||||
name,
|
||||
addresses,
|
||||
chain,
|
||||
selectedAddresses,
|
||||
onDelete,
|
||||
onAdd
|
||||
}: IProps) {
|
||||
return (
|
||||
<Fragment>
|
||||
<Divider y={2} />
|
||||
|
||||
<Row>
|
||||
<Col>
|
||||
<Text h5>{`${name} Accounts`}</Text>
|
||||
{addresses.map((address, index) => {
|
||||
const fullAddress = `${chain}:${address}`
|
||||
const selected = selectedAddresses.includes(fullAddress)
|
||||
|
||||
return (
|
||||
<AccountSelectCard
|
||||
key={address}
|
||||
address={address}
|
||||
index={index}
|
||||
onSelect={() => (selected ? onDelete(fullAddress) : onAdd(fullAddress))}
|
||||
selected={selected}
|
||||
/>
|
||||
)
|
||||
})}
|
||||
</Col>
|
||||
</Row>
|
||||
</Fragment>
|
||||
)
|
||||
}
|
||||
@@ -55,7 +55,7 @@ export const EIP155_TEST_CHAINS = {
|
||||
name: 'Polygon Mumbai',
|
||||
logo: '/chain-logos/eip155-137.png',
|
||||
rgb: '130, 71, 229',
|
||||
rpc: 'https://rpc-mumbai.maticvigil.com/'
|
||||
rpc: 'https://matic-mumbai.chainstacklabs.com'
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ import SettingsStore from '@/store/SettingsStore'
|
||||
import { createOrRestoreCosmosWallet } from '@/utils/CosmosWalletUtil'
|
||||
import { createOrRestoreEIP155Wallet } from '@/utils/EIP155WalletUtil'
|
||||
import { createOrRestoreSolanaWallet } from '@/utils/SolanaWalletUtil'
|
||||
import { createWalletConnectClient } from '@/utils/WalletConnectUtil'
|
||||
import { createSignClient } from '@/utils/WalletConnectUtil'
|
||||
import { useCallback, useEffect, useState } from 'react'
|
||||
|
||||
export default function useInitialization() {
|
||||
@@ -18,7 +18,7 @@ export default function useInitialization() {
|
||||
SettingsStore.setCosmosAddress(cosmosAddresses[0])
|
||||
SettingsStore.setSolanaAddress(solanaAddresses[0])
|
||||
|
||||
await createWalletConnectClient()
|
||||
await createSignClient()
|
||||
|
||||
setInitialized(true)
|
||||
} catch (err: unknown) {
|
||||
|
||||
@@ -2,69 +2,72 @@ import { COSMOS_SIGNING_METHODS } from '@/data/COSMOSData'
|
||||
import { EIP155_SIGNING_METHODS } from '@/data/EIP155Data'
|
||||
import { SOLANA_SIGNING_METHODS } from '@/data/SolanaData'
|
||||
import ModalStore from '@/store/ModalStore'
|
||||
import { walletConnectClient } from '@/utils/WalletConnectUtil'
|
||||
import { CLIENT_EVENTS } from '@walletconnect/client'
|
||||
import { SessionTypes } from '@walletconnect/types'
|
||||
import { signClient } from '@/utils/WalletConnectUtil'
|
||||
import { SignClientTypes } from '@walletconnect/types'
|
||||
import { useCallback, useEffect } from 'react'
|
||||
|
||||
export default function useWalletConnectEventsManager(initialized: boolean) {
|
||||
/******************************************************************************
|
||||
* 1. Open session proposal modal for confirmation / rejection
|
||||
*****************************************************************************/
|
||||
const onSessionProposal = useCallback((proposal: SessionTypes.Proposal) => {
|
||||
ModalStore.open('SessionProposalModal', { proposal })
|
||||
}, [])
|
||||
|
||||
/******************************************************************************
|
||||
* 2. [Optional] hanle session created
|
||||
*****************************************************************************/
|
||||
const onSessionCreated = useCallback((created: SessionTypes.Created) => {}, [])
|
||||
const onSessionProposal = useCallback(
|
||||
(proposal: SignClientTypes.EventArguments['session_proposal']) => {
|
||||
ModalStore.open('SessionProposalModal', { proposal })
|
||||
},
|
||||
[]
|
||||
)
|
||||
|
||||
/******************************************************************************
|
||||
* 3. Open request handling modal based on method that was used
|
||||
*****************************************************************************/
|
||||
const onSessionRequest = useCallback(async (requestEvent: SessionTypes.RequestEvent) => {
|
||||
const { topic, request } = requestEvent
|
||||
const { method } = request
|
||||
const requestSession = await walletConnectClient.session.get(topic)
|
||||
const onSessionRequest = useCallback(
|
||||
async (requestEvent: SignClientTypes.EventArguments['session_request']) => {
|
||||
console.log('session_request', requestEvent)
|
||||
const { topic, params } = requestEvent
|
||||
const { request } = params
|
||||
const requestSession = signClient.session.get(topic)
|
||||
|
||||
switch (method) {
|
||||
case EIP155_SIGNING_METHODS.ETH_SIGN:
|
||||
case EIP155_SIGNING_METHODS.PERSONAL_SIGN:
|
||||
return ModalStore.open('SessionSignModal', { requestEvent, requestSession })
|
||||
switch (request.method) {
|
||||
case EIP155_SIGNING_METHODS.ETH_SIGN:
|
||||
case EIP155_SIGNING_METHODS.PERSONAL_SIGN:
|
||||
return ModalStore.open('SessionSignModal', { requestEvent, requestSession })
|
||||
|
||||
case EIP155_SIGNING_METHODS.ETH_SIGN_TYPED_DATA:
|
||||
case EIP155_SIGNING_METHODS.ETH_SIGN_TYPED_DATA_V3:
|
||||
case EIP155_SIGNING_METHODS.ETH_SIGN_TYPED_DATA_V4:
|
||||
return ModalStore.open('SessionSignTypedDataModal', { requestEvent, requestSession })
|
||||
case EIP155_SIGNING_METHODS.ETH_SIGN_TYPED_DATA:
|
||||
case EIP155_SIGNING_METHODS.ETH_SIGN_TYPED_DATA_V3:
|
||||
case EIP155_SIGNING_METHODS.ETH_SIGN_TYPED_DATA_V4:
|
||||
return ModalStore.open('SessionSignTypedDataModal', { requestEvent, requestSession })
|
||||
|
||||
case EIP155_SIGNING_METHODS.ETH_SEND_TRANSACTION:
|
||||
case EIP155_SIGNING_METHODS.ETH_SIGN_TRANSACTION:
|
||||
return ModalStore.open('SessionSendTransactionModal', { requestEvent, requestSession })
|
||||
case EIP155_SIGNING_METHODS.ETH_SEND_TRANSACTION:
|
||||
case EIP155_SIGNING_METHODS.ETH_SIGN_TRANSACTION:
|
||||
return ModalStore.open('SessionSendTransactionModal', { requestEvent, requestSession })
|
||||
|
||||
case COSMOS_SIGNING_METHODS.COSMOS_SIGN_DIRECT:
|
||||
case COSMOS_SIGNING_METHODS.COSMOS_SIGN_AMINO:
|
||||
return ModalStore.open('SessionSignCosmosModal', { requestEvent, requestSession })
|
||||
case COSMOS_SIGNING_METHODS.COSMOS_SIGN_DIRECT:
|
||||
case COSMOS_SIGNING_METHODS.COSMOS_SIGN_AMINO:
|
||||
return ModalStore.open('SessionSignCosmosModal', { requestEvent, requestSession })
|
||||
|
||||
case SOLANA_SIGNING_METHODS.SOLANA_SIGN_MESSAGE:
|
||||
case SOLANA_SIGNING_METHODS.SOLANA_SIGN_TRANSACTION:
|
||||
return ModalStore.open('SessionSignSolanaModal', { requestEvent, requestSession })
|
||||
case SOLANA_SIGNING_METHODS.SOLANA_SIGN_MESSAGE:
|
||||
case SOLANA_SIGNING_METHODS.SOLANA_SIGN_TRANSACTION:
|
||||
return ModalStore.open('SessionSignSolanaModal', { requestEvent, requestSession })
|
||||
|
||||
default:
|
||||
return ModalStore.open('SessionUnsuportedMethodModal', { requestEvent, requestSession })
|
||||
}
|
||||
}, [])
|
||||
default:
|
||||
return ModalStore.open('SessionUnsuportedMethodModal', { requestEvent, requestSession })
|
||||
}
|
||||
},
|
||||
[]
|
||||
)
|
||||
|
||||
/******************************************************************************
|
||||
* Set up WalletConnect event listeners
|
||||
*****************************************************************************/
|
||||
useEffect(() => {
|
||||
if (initialized) {
|
||||
walletConnectClient.on(CLIENT_EVENTS.session.proposal, onSessionProposal)
|
||||
|
||||
walletConnectClient.on(CLIENT_EVENTS.session.created, onSessionCreated)
|
||||
|
||||
walletConnectClient.on(CLIENT_EVENTS.session.request, onSessionRequest)
|
||||
signClient.on('session_proposal', onSessionProposal)
|
||||
signClient.on('session_request', onSessionRequest)
|
||||
// TODOs
|
||||
signClient.on('session_ping', data => console.log('ping', data))
|
||||
signClient.on('session_event', data => console.log('event', data))
|
||||
signClient.on('session_update', data => console.log('update', data))
|
||||
signClient.on('session_delete', data => console.log('delete', data))
|
||||
}
|
||||
}, [initialized, onSessionProposal, onSessionCreated, onSessionRequest])
|
||||
}, [initialized, onSessionProposal, onSessionRequest])
|
||||
}
|
||||
|
||||
@@ -1,18 +1,15 @@
|
||||
import PageHeader from '@/components/PageHeader'
|
||||
import PairingCard from '@/components/PairingCard'
|
||||
import { walletConnectClient } from '@/utils/WalletConnectUtil'
|
||||
import { signClient } from '@/utils/WalletConnectUtil'
|
||||
import { Text } from '@nextui-org/react'
|
||||
import { ERROR } from '@walletconnect/utils'
|
||||
import { Fragment, useState } from 'react'
|
||||
|
||||
export default function PairingsPage() {
|
||||
const [pairings, setPairings] = useState(walletConnectClient.pairing.values)
|
||||
const [pairings, setPairings] = useState(signClient.pairing.values)
|
||||
|
||||
async function onDelete(topic: string) {
|
||||
await walletConnectClient.pairing.delete({
|
||||
topic,
|
||||
reason: ERROR.DELETED.format()
|
||||
})
|
||||
await signClient.disconnect({ topic, reason: ERROR.DELETED.format() })
|
||||
const newPairings = pairings.filter(pairing => pairing.topic !== topic)
|
||||
setPairings(newPairings)
|
||||
}
|
||||
@@ -22,14 +19,14 @@ export default function PairingsPage() {
|
||||
<PageHeader title="Pairings" />
|
||||
{pairings.length ? (
|
||||
pairings.map(pairing => {
|
||||
const { metadata } = pairing.state
|
||||
const { peerMetadata } = pairing
|
||||
|
||||
return (
|
||||
<PairingCard
|
||||
key={pairing.topic}
|
||||
logo={metadata?.icons[0]}
|
||||
url={metadata?.url}
|
||||
name={metadata?.name}
|
||||
logo={peerMetadata?.icons[0]}
|
||||
url={peerMetadata?.url}
|
||||
name={peerMetadata?.name}
|
||||
onDelete={() => onDelete(pairing.topic)}
|
||||
/>
|
||||
)
|
||||
|
||||
@@ -1,15 +1,8 @@
|
||||
import PageHeader from '@/components/PageHeader'
|
||||
import ProjectInfoCard from '@/components/ProjectInfoCard'
|
||||
import SessionSelectSection from '@/components/SessionSelectSection'
|
||||
import { COSMOS_MAINNET_CHAINS, TCosmosChain } from '@/data/COSMOSData'
|
||||
import { EIP155_CHAINS, TEIP155Chain } from '@/data/EIP155Data'
|
||||
import { SOLANA_CHAINS, TSolanaChain } from '@/data/SolanaData'
|
||||
import { cosmosAddresses } from '@/utils/CosmosWalletUtil'
|
||||
import { eip155Addresses } from '@/utils/EIP155WalletUtil'
|
||||
import { isCosmosChain, isEIP155Chain, isSolanaChain } from '@/utils/HelperUtil'
|
||||
import { solanaAddresses } from '@/utils/SolanaWalletUtil'
|
||||
import { walletConnectClient } from '@/utils/WalletConnectUtil'
|
||||
import { Button, Col, Divider, Row, Text } from '@nextui-org/react'
|
||||
import SessionChainCard from '@/components/SessionChainCard'
|
||||
import { signClient } from '@/utils/WalletConnectUtil'
|
||||
import { Button, Divider, Loading, Row, Text } from '@nextui-org/react'
|
||||
import { ERROR } from '@walletconnect/utils'
|
||||
import { useRouter } from 'next/router'
|
||||
import { Fragment, useEffect, useState } from 'react'
|
||||
@@ -21,6 +14,7 @@ export default function SessionPage() {
|
||||
const [topic, setTopic] = useState('')
|
||||
const [updated, setUpdated] = useState(new Date())
|
||||
const { query, replace } = useRouter()
|
||||
const [loading, setLoading] = useState(false)
|
||||
|
||||
useEffect(() => {
|
||||
if (query?.topic) {
|
||||
@@ -28,7 +22,7 @@ export default function SessionPage() {
|
||||
}
|
||||
}, [query])
|
||||
|
||||
const session = walletConnectClient.session.values.find(s => s.topic === topic)
|
||||
const session = signClient.session.values.find(s => s.topic === topic)
|
||||
|
||||
if (!session) {
|
||||
return null
|
||||
@@ -36,116 +30,133 @@ export default function SessionPage() {
|
||||
|
||||
// Get necessary data from session
|
||||
const expiryDate = new Date(session.expiry * 1000)
|
||||
const { chains } = session.permissions.blockchain
|
||||
const { methods } = session.permissions.jsonrpc
|
||||
const { accounts } = session.state
|
||||
const { namespaces } = session
|
||||
|
||||
// Handle deletion of a session
|
||||
async function onDeleteSession() {
|
||||
await walletConnectClient.session.delete({
|
||||
topic,
|
||||
reason: ERROR.DELETED.format()
|
||||
})
|
||||
setLoading(true)
|
||||
await signClient.disconnect({ topic, reason: ERROR.DELETED.format() })
|
||||
replace('/sessions')
|
||||
setLoading(false)
|
||||
}
|
||||
|
||||
// Hanlde deletion of session account
|
||||
async function onDeleteAccount(account: string) {
|
||||
const newAccounts = accounts.filter(a => a !== account)
|
||||
await walletConnectClient.session.update({
|
||||
topic,
|
||||
state: {
|
||||
accounts: newAccounts
|
||||
}
|
||||
})
|
||||
setUpdated(new Date())
|
||||
async function onSessionPing() {
|
||||
setLoading(true)
|
||||
await signClient.ping({ topic })
|
||||
setLoading(false)
|
||||
}
|
||||
|
||||
// Handle addition of account to the session
|
||||
async function onAddAccount(account: string) {
|
||||
await walletConnectClient.session.update({
|
||||
async function onSessionEmit() {
|
||||
setLoading(true)
|
||||
console.log('baleg')
|
||||
await signClient.emit({
|
||||
topic,
|
||||
state: {
|
||||
accounts: [...accounts, account]
|
||||
}
|
||||
event: { name: 'chainChanged', data: 'Hello World' },
|
||||
chainId: 'eip155:1'
|
||||
})
|
||||
setUpdated(new Date())
|
||||
setLoading(false)
|
||||
}
|
||||
|
||||
const newNs = {
|
||||
eip155: {
|
||||
accounts: [
|
||||
'eip155:1:0x70012948c348CBF00806A3C79E3c5DAdFaAa347B',
|
||||
'eip155:137:0x70012948c348CBF00806A3C79E3c5DAdFaAa347B'
|
||||
],
|
||||
methods: ['personal_sign', 'eth_signTypedData', 'eth_sendTransaction'],
|
||||
events: []
|
||||
}
|
||||
}
|
||||
|
||||
async function onSessionUpdate() {
|
||||
setLoading(true)
|
||||
const { acknowledged } = await signClient.update({ topic, namespaces: newNs })
|
||||
await acknowledged()
|
||||
setUpdated(new Date())
|
||||
setLoading(false)
|
||||
}
|
||||
|
||||
// function renderAccountSelection(chain: string) {
|
||||
// if (isEIP155Chain(chain)) {
|
||||
// return (
|
||||
// <ProposalSelectSection
|
||||
// addresses={eip155Addresses}
|
||||
// selectedAddresses={selectedAccounts[chain]}
|
||||
// onSelect={onSelectAccount}
|
||||
// chain={chain}
|
||||
// />
|
||||
// )
|
||||
// } else if (isCosmosChain(chain)) {
|
||||
// return (
|
||||
// <ProposalSelectSection
|
||||
// addresses={cosmosAddresses}
|
||||
// selectedAddresses={selectedAccounts[chain]}
|
||||
// onSelect={onSelectAccount}
|
||||
// chain={chain}
|
||||
// />
|
||||
// )
|
||||
// } else if (isSolanaChain(chain)) {
|
||||
// return (
|
||||
// <ProposalSelectSection
|
||||
// addresses={solanaAddresses}
|
||||
// selectedAddresses={selectedAccounts[chain]}
|
||||
// onSelect={onSelectAccount}
|
||||
// chain={chain}
|
||||
// />
|
||||
// )
|
||||
// }
|
||||
// }
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<PageHeader title="Session Details" />
|
||||
|
||||
<ProjectInfoCard metadata={session.peer.metadata} />
|
||||
|
||||
{chains.map(chain => {
|
||||
if (isEIP155Chain(chain)) {
|
||||
return (
|
||||
<SessionSelectSection
|
||||
key={chain}
|
||||
chain={chain}
|
||||
name={EIP155_CHAINS[chain as TEIP155Chain]?.name}
|
||||
addresses={eip155Addresses}
|
||||
selectedAddresses={accounts}
|
||||
onDelete={onDeleteAccount}
|
||||
onAdd={onAddAccount}
|
||||
/>
|
||||
)
|
||||
} else if (isCosmosChain(chain)) {
|
||||
return (
|
||||
<SessionSelectSection
|
||||
key={chain}
|
||||
chain={chain}
|
||||
name={COSMOS_MAINNET_CHAINS[chain as TCosmosChain]?.name}
|
||||
addresses={cosmosAddresses}
|
||||
selectedAddresses={accounts}
|
||||
onDelete={onDeleteAccount}
|
||||
onAdd={onAddAccount}
|
||||
/>
|
||||
)
|
||||
} else if (isSolanaChain(chain)) {
|
||||
return (
|
||||
<SessionSelectSection
|
||||
key={chain}
|
||||
chain={chain}
|
||||
name={SOLANA_CHAINS[chain as TSolanaChain]?.name}
|
||||
addresses={solanaAddresses}
|
||||
selectedAddresses={accounts}
|
||||
onDelete={onDeleteAccount}
|
||||
onAdd={onAddAccount}
|
||||
/>
|
||||
)
|
||||
}
|
||||
<Divider y={2} />
|
||||
|
||||
{Object.keys(namespaces).map(chain => {
|
||||
return (
|
||||
<Fragment key={chain}>
|
||||
<Text h4 css={{ marginBottom: '$5' }}>{`Review ${chain} permissions`}</Text>
|
||||
<SessionChainCard namespace={namespaces[chain]} />
|
||||
{/* {renderAccountSelection(chain)} */}
|
||||
<Divider y={2} />
|
||||
</Fragment>
|
||||
)
|
||||
})}
|
||||
|
||||
<Divider y={1} />
|
||||
|
||||
<Row>
|
||||
<Col>
|
||||
<Text h5>Methods</Text>
|
||||
<Text color="$gray400">{methods.map(method => method).join(', ')}</Text>
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
<Divider y={1} />
|
||||
|
||||
<Row justify="space-between">
|
||||
<Text h5>Expiry</Text>
|
||||
<Text css={{ color: '$gray400' }}>{expiryDate.toDateString()}</Text>
|
||||
</Row>
|
||||
|
||||
<Divider y={1} />
|
||||
|
||||
<Row justify="space-between">
|
||||
<Text h5>Last Updated</Text>
|
||||
<Text css={{ color: '$gray400' }}>{updated.toDateString()}</Text>
|
||||
</Row>
|
||||
|
||||
<Divider y={1} />
|
||||
|
||||
<Row>
|
||||
<Row css={{ marginTop: '$10' }}>
|
||||
<Button flat css={{ width: '100%' }} color="error" onClick={onDeleteSession}>
|
||||
Delete Session
|
||||
{loading ? <Loading size="sm" color="error" /> : 'Delete'}
|
||||
</Button>
|
||||
</Row>
|
||||
|
||||
<Row css={{ marginTop: '$10' }}>
|
||||
<Button flat css={{ width: '100%' }} color="primary" onClick={onSessionPing}>
|
||||
{loading ? <Loading size="sm" color="primary" /> : 'Ping'}
|
||||
</Button>
|
||||
</Row>
|
||||
|
||||
<Row css={{ marginTop: '$10' }}>
|
||||
<Button flat css={{ width: '100%' }} color="secondary" onClick={onSessionEmit}>
|
||||
{loading ? <Loading size="sm" color="secondary" /> : 'Emit'}
|
||||
</Button>
|
||||
</Row>
|
||||
|
||||
<Row css={{ marginTop: '$10' }}>
|
||||
<Button flat css={{ width: '100%' }} color="warning" onClick={onSessionUpdate}>
|
||||
{loading ? <Loading size="sm" color="warning" /> : 'Update'}
|
||||
</Button>
|
||||
</Row>
|
||||
</Fragment>
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import PageHeader from '@/components/PageHeader'
|
||||
import SessionCard from '@/components/SessionCard'
|
||||
import { walletConnectClient } from '@/utils/WalletConnectUtil'
|
||||
import { signClient } from '@/utils/WalletConnectUtil'
|
||||
import { Text } from '@nextui-org/react'
|
||||
import { Fragment, useState } from 'react'
|
||||
|
||||
export default function SessionsPage() {
|
||||
const [sessions, setSessions] = useState(walletConnectClient.session.values)
|
||||
const [sessions, setSessions] = useState(signClient.session.values)
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
|
||||
@@ -6,6 +6,7 @@ import { solanaWallets } from '@/utils/SolanaWalletUtil'
|
||||
import { Card, Divider, Row, Switch, Text } from '@nextui-org/react'
|
||||
import { Fragment } from 'react'
|
||||
import { useSnapshot } from 'valtio'
|
||||
import packageJSON from '../../package.json'
|
||||
|
||||
export default function SettingsPage() {
|
||||
const { testNets, eip155Address, cosmosAddress, solanaAddress } = useSnapshot(SettingsStore.state)
|
||||
@@ -14,6 +15,24 @@ export default function SettingsPage() {
|
||||
<Fragment>
|
||||
<PageHeader title="Settings" />
|
||||
|
||||
<Text h4 css={{ marginBottom: '$5' }}>
|
||||
Packages
|
||||
</Text>
|
||||
<Row justify="space-between" align="center">
|
||||
<Text color="$gray400">@walletconnect/sign-client</Text>
|
||||
<Text color="$gray400">{packageJSON.dependencies['@walletconnect/sign-client']}</Text>
|
||||
</Row>
|
||||
<Row justify="space-between" align="center">
|
||||
<Text color="$gray400">@walletconnect/utils</Text>
|
||||
<Text color="$gray400">{packageJSON.dependencies['@walletconnect/utils']}</Text>
|
||||
</Row>
|
||||
<Row justify="space-between" align="center">
|
||||
<Text color="$gray400">@walletconnect/types</Text>
|
||||
<Text color="$gray400">{packageJSON.devDependencies['@walletconnect/types']}</Text>
|
||||
</Row>
|
||||
|
||||
<Divider y={2} />
|
||||
|
||||
<Text h4 css={{ marginBottom: '$5' }}>
|
||||
Testnets
|
||||
</Text>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import PageHeader from '@/components/PageHeader'
|
||||
import QrReader from '@/components/QrReader'
|
||||
import { walletConnectClient } from '@/utils/WalletConnectUtil'
|
||||
import { signClient } from '@/utils/WalletConnectUtil'
|
||||
import { Button, Input, Loading, Text } from '@nextui-org/react'
|
||||
import { Fragment, useState } from 'react'
|
||||
|
||||
@@ -11,7 +11,7 @@ export default function WalletConnectPage() {
|
||||
async function onConnect(uri: string) {
|
||||
try {
|
||||
setLoading(true)
|
||||
await walletConnectClient.pair({ uri })
|
||||
await signClient.pair({ uri })
|
||||
} catch (err: unknown) {
|
||||
alert(err)
|
||||
} finally {
|
||||
@@ -31,6 +31,7 @@ export default function WalletConnectPage() {
|
||||
</Text>
|
||||
|
||||
<Input
|
||||
css={{ width: '100%' }}
|
||||
bordered
|
||||
aria-label="wc url connect input"
|
||||
placeholder="e.g. wc:a281567bb3e4..."
|
||||
|
||||
@@ -1,14 +1,13 @@
|
||||
import { SessionTypes } from '@walletconnect/types'
|
||||
import { SessionTypes, SignClientTypes } from '@walletconnect/types'
|
||||
import { proxy } from 'valtio'
|
||||
|
||||
/**
|
||||
* Types
|
||||
*/
|
||||
interface ModalData {
|
||||
proposal?: SessionTypes.Proposal
|
||||
created?: SessionTypes.Created
|
||||
requestEvent?: SessionTypes.RequestEvent
|
||||
requestSession?: SessionTypes.Settled
|
||||
proposal?: SignClientTypes.EventArguments['session_proposal']
|
||||
requestEvent?: SignClientTypes.EventArguments['session_request']
|
||||
requestSession?: SessionTypes.Struct
|
||||
}
|
||||
|
||||
interface State {
|
||||
|
||||
@@ -2,24 +2,30 @@ import { COSMOS_SIGNING_METHODS } from '@/data/COSMOSData'
|
||||
import { cosmosAddresses, cosmosWallets } from '@/utils/CosmosWalletUtil'
|
||||
import { getWalletAddressFromParams } from '@/utils/HelperUtil'
|
||||
import { formatJsonRpcError, formatJsonRpcResult } from '@json-rpc-tools/utils'
|
||||
import { RequestEvent } from '@walletconnect/types'
|
||||
import { SignClientTypes } from '@walletconnect/types'
|
||||
import { ERROR } from '@walletconnect/utils'
|
||||
import { parseSignDocValues } from 'cosmos-wallet'
|
||||
|
||||
export async function approveCosmosRequest(requestEvent: RequestEvent) {
|
||||
const { method, params, id } = requestEvent.request
|
||||
export async function approveCosmosRequest(
|
||||
requestEvent: SignClientTypes.EventArguments['session_request']
|
||||
) {
|
||||
const { params, id } = requestEvent
|
||||
const { request } = params
|
||||
const wallet = cosmosWallets[getWalletAddressFromParams(cosmosAddresses, params)]
|
||||
|
||||
switch (method) {
|
||||
switch (request.method) {
|
||||
case COSMOS_SIGNING_METHODS.COSMOS_SIGN_DIRECT:
|
||||
const signedDirect = await wallet.signDirect(
|
||||
params.signerAddress,
|
||||
parseSignDocValues(params.signDoc)
|
||||
request.params.signerAddress,
|
||||
parseSignDocValues(request.params.signDoc)
|
||||
)
|
||||
return formatJsonRpcResult(id, signedDirect.signature)
|
||||
|
||||
case COSMOS_SIGNING_METHODS.COSMOS_SIGN_AMINO:
|
||||
const signedAmino = await wallet.signAmino(params.signerAddress, params.signDoc)
|
||||
const signedAmino = await wallet.signAmino(
|
||||
request.params.signerAddress,
|
||||
request.params.signDoc
|
||||
)
|
||||
return formatJsonRpcResult(id, signedAmino.signature)
|
||||
|
||||
default:
|
||||
@@ -27,7 +33,7 @@ export async function approveCosmosRequest(requestEvent: RequestEvent) {
|
||||
}
|
||||
}
|
||||
|
||||
export function rejectCosmosRequest(request: RequestEvent['request']) {
|
||||
export function rejectCosmosRequest(request: SignClientTypes.EventArguments['session_request']) {
|
||||
const { id } = request
|
||||
|
||||
return formatJsonRpcError(id, ERROR.JSONRPC_REQUEST_METHOD_REJECTED.format().message)
|
||||
|
||||
@@ -6,26 +6,28 @@ import {
|
||||
getWalletAddressFromParams
|
||||
} from '@/utils/HelperUtil'
|
||||
import { formatJsonRpcError, formatJsonRpcResult } from '@json-rpc-tools/utils'
|
||||
import { RequestEvent } from '@walletconnect/types'
|
||||
import { SignClientTypes } from '@walletconnect/types'
|
||||
import { ERROR } from '@walletconnect/utils'
|
||||
import { providers } from 'ethers'
|
||||
|
||||
export async function approveEIP155Request(requestEvent: RequestEvent) {
|
||||
const { method, params, id } = requestEvent.request
|
||||
const { chainId } = requestEvent
|
||||
export async function approveEIP155Request(
|
||||
requestEvent: SignClientTypes.EventArguments['session_request']
|
||||
) {
|
||||
const { params, id } = requestEvent
|
||||
const { chainId, request } = params
|
||||
const wallet = eip155Wallets[getWalletAddressFromParams(eip155Addresses, params)]
|
||||
|
||||
switch (method) {
|
||||
switch (request.method) {
|
||||
case EIP155_SIGNING_METHODS.PERSONAL_SIGN:
|
||||
case EIP155_SIGNING_METHODS.ETH_SIGN:
|
||||
const message = getSignParamsMessage(params)
|
||||
const message = getSignParamsMessage(request.params)
|
||||
const signedMessage = await wallet.signMessage(message)
|
||||
return formatJsonRpcResult(id, signedMessage)
|
||||
|
||||
case EIP155_SIGNING_METHODS.ETH_SIGN_TYPED_DATA:
|
||||
case EIP155_SIGNING_METHODS.ETH_SIGN_TYPED_DATA_V3:
|
||||
case EIP155_SIGNING_METHODS.ETH_SIGN_TYPED_DATA_V4:
|
||||
const { domain, types, message: data } = getSignTypedDataParamsData(params)
|
||||
const { domain, types, message: data } = getSignTypedDataParamsData(request.params)
|
||||
// https://github.com/ethers-io/ethers.js/issues/687#issuecomment-714069471
|
||||
delete types.EIP712Domain
|
||||
const signedData = await wallet._signTypedData(domain, types, data)
|
||||
@@ -33,13 +35,13 @@ export async function approveEIP155Request(requestEvent: RequestEvent) {
|
||||
|
||||
case EIP155_SIGNING_METHODS.ETH_SEND_TRANSACTION:
|
||||
const provider = new providers.JsonRpcProvider(EIP155_CHAINS[chainId as TEIP155Chain].rpc)
|
||||
const sendTransaction = params[0]
|
||||
const sendTransaction = request.params[0]
|
||||
const connectedWallet = wallet.connect(provider)
|
||||
const { hash } = await connectedWallet.sendTransaction(sendTransaction)
|
||||
return formatJsonRpcResult(id, hash)
|
||||
|
||||
case EIP155_SIGNING_METHODS.ETH_SIGN_TRANSACTION:
|
||||
const signTransaction = params[0]
|
||||
const signTransaction = request.params[0]
|
||||
const signature = await wallet.signTransaction(signTransaction)
|
||||
return formatJsonRpcResult(id, signature)
|
||||
|
||||
@@ -48,7 +50,7 @@ export async function approveEIP155Request(requestEvent: RequestEvent) {
|
||||
}
|
||||
}
|
||||
|
||||
export function rejectEIP155Request(request: RequestEvent['request']) {
|
||||
export function rejectEIP155Request(request: SignClientTypes.EventArguments['session_request']) {
|
||||
const { id } = request
|
||||
|
||||
return formatJsonRpcError(id, ERROR.JSONRPC_REQUEST_METHOD_REJECTED.format().message)
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
import { COSMOS_MAINNET_CHAINS, TCosmosChain } from '@/data/COSMOSData'
|
||||
import { EIP155_CHAINS, TEIP155Chain } from '@/data/EIP155Data'
|
||||
import { SOLANA_CHAINS, TSolanaChain } from '@/data/SolanaData'
|
||||
import { utils } from 'ethers'
|
||||
|
||||
/**
|
||||
@@ -90,3 +93,15 @@ export function isCosmosChain(chain: string) {
|
||||
export function isSolanaChain(chain: string) {
|
||||
return chain.includes('solana')
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats chainId to its name
|
||||
*/
|
||||
export function formatChainName(chainId: string) {
|
||||
return (
|
||||
EIP155_CHAINS[chainId as TEIP155Chain]?.name ??
|
||||
COSMOS_MAINNET_CHAINS[chainId as TCosmosChain]?.name ??
|
||||
SOLANA_CHAINS[chainId as TSolanaChain]?.name ??
|
||||
chainId
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2,23 +2,26 @@ import { SOLANA_SIGNING_METHODS } from '@/data/SolanaData'
|
||||
import { getWalletAddressFromParams } from '@/utils/HelperUtil'
|
||||
import { solanaAddresses, solanaWallets } from '@/utils/SolanaWalletUtil'
|
||||
import { formatJsonRpcError, formatJsonRpcResult } from '@json-rpc-tools/utils'
|
||||
import { RequestEvent } from '@walletconnect/types'
|
||||
import { SignClientTypes } from '@walletconnect/types'
|
||||
import { ERROR } from '@walletconnect/utils'
|
||||
|
||||
export async function approveSolanaRequest(requestEvent: RequestEvent) {
|
||||
const { method, params, id } = requestEvent.request
|
||||
export async function approveSolanaRequest(
|
||||
requestEvent: SignClientTypes.EventArguments['session_request']
|
||||
) {
|
||||
const { params, id } = requestEvent
|
||||
const { request } = params
|
||||
const wallet = solanaWallets[getWalletAddressFromParams(solanaAddresses, params)]
|
||||
|
||||
switch (method) {
|
||||
switch (request.method) {
|
||||
case SOLANA_SIGNING_METHODS.SOLANA_SIGN_MESSAGE:
|
||||
const signedMessage = await wallet.signMessage(params.message)
|
||||
const signedMessage = await wallet.signMessage(request.params.message)
|
||||
return formatJsonRpcResult(id, signedMessage)
|
||||
|
||||
case SOLANA_SIGNING_METHODS.SOLANA_SIGN_TRANSACTION:
|
||||
const signedTransaction = await wallet.signTransaction(
|
||||
params.feePayer,
|
||||
params.recentBlockhash,
|
||||
params.instructions
|
||||
request.params.feePayer,
|
||||
request.params.recentBlockhash,
|
||||
request.params.instructions
|
||||
)
|
||||
|
||||
return formatJsonRpcResult(id, signedTransaction)
|
||||
@@ -28,7 +31,7 @@ export async function approveSolanaRequest(requestEvent: RequestEvent) {
|
||||
}
|
||||
}
|
||||
|
||||
export function rejectSolanaRequest(request: RequestEvent['request']) {
|
||||
export function rejectSolanaRequest(request: SignClientTypes.EventArguments['session_request']) {
|
||||
const { id } = request
|
||||
|
||||
return formatJsonRpcError(id, ERROR.JSONRPC_REQUEST_METHOD_REJECTED.format().message)
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
import WalletConnectClient from '@walletconnect/client'
|
||||
import SignClient from '@walletconnect/sign-client'
|
||||
|
||||
export let walletConnectClient: WalletConnectClient
|
||||
export let signClient: SignClient
|
||||
|
||||
export async function createWalletConnectClient() {
|
||||
walletConnectClient = await WalletConnectClient.init({
|
||||
controller: true,
|
||||
export async function createSignClient() {
|
||||
signClient = await SignClient.init({
|
||||
projectId: process.env.NEXT_PUBLIC_PROJECT_ID,
|
||||
relayUrl: process.env.NEXT_PUBLIC_RELAY_URL ?? 'wss://relay.walletconnect.com',
|
||||
metadata: {
|
||||
|
||||
@@ -1,25 +1,21 @@
|
||||
import ProjectInfoCard from '@/components/ProjectInfoCard'
|
||||
import ProposalSelectSection from '@/components/ProposalSelectSection'
|
||||
import RequesDetailsCard from '@/components/RequestDetalilsCard'
|
||||
import RequestMethodCard from '@/components/RequestMethodCard'
|
||||
import RequestModalContainer from '@/components/RequestModalContainer'
|
||||
import { COSMOS_MAINNET_CHAINS, TCosmosChain } from '@/data/COSMOSData'
|
||||
import { EIP155_CHAINS, TEIP155Chain } from '@/data/EIP155Data'
|
||||
import { SOLANA_CHAINS, TSolanaChain } from '@/data/SolanaData'
|
||||
import SessionProposalChainCard from '@/components/SessionProposalChainCard'
|
||||
import ModalStore from '@/store/ModalStore'
|
||||
import { cosmosAddresses } from '@/utils/CosmosWalletUtil'
|
||||
import { eip155Addresses } from '@/utils/EIP155WalletUtil'
|
||||
import { isCosmosChain, isEIP155Chain, isSolanaChain } from '@/utils/HelperUtil'
|
||||
import { solanaAddresses } from '@/utils/SolanaWalletUtil'
|
||||
import { walletConnectClient } from '@/utils/WalletConnectUtil'
|
||||
import { signClient } from '@/utils/WalletConnectUtil'
|
||||
import { Button, Divider, Modal, Text } from '@nextui-org/react'
|
||||
import { SessionTypes } from '@walletconnect/types'
|
||||
import { ERROR } from '@walletconnect/utils'
|
||||
import { Fragment, useState } from 'react'
|
||||
|
||||
export default function SessionProposalModal() {
|
||||
const [selectedEIP155, setSelectedEip155] = useState<string[]>([])
|
||||
const [selectedCosmos, setSelectedCosmos] = useState<string[]>([])
|
||||
const [selectedSolana, setSelectedSolana] = useState<string[]>([])
|
||||
const allSelected = [...selectedEIP155, ...selectedCosmos, ...selectedSolana]
|
||||
const [selectedAccounts, setSelectedAccounts] = useState<Record<string, string[]>>({})
|
||||
const hasSelected = Object.keys(selectedAccounts).length
|
||||
|
||||
// Get proposal data and wallet address from store
|
||||
const proposal = ModalStore.state.data?.proposal
|
||||
@@ -30,50 +26,48 @@ export default function SessionProposalModal() {
|
||||
}
|
||||
|
||||
// Get required proposal data
|
||||
const { proposer, permissions, relay } = proposal
|
||||
const { chains } = permissions.blockchain
|
||||
const { methods } = permissions.jsonrpc
|
||||
const { id, params } = proposal
|
||||
const { proposer, requiredNamespaces, relays } = params
|
||||
|
||||
// Add / remove address from EIP155 selection
|
||||
function onSelectEIP155(address: string) {
|
||||
if (selectedEIP155.includes(address)) {
|
||||
const newAddresses = selectedEIP155.filter(a => a !== address)
|
||||
setSelectedEip155(newAddresses)
|
||||
function onSelectAccount(chain: string, account: string) {
|
||||
if (selectedAccounts[chain]?.includes(account)) {
|
||||
const newSelectedAccounts = selectedAccounts[chain]?.filter(a => a !== account)
|
||||
setSelectedAccounts(prev => ({
|
||||
...prev,
|
||||
[chain]: newSelectedAccounts
|
||||
}))
|
||||
} else {
|
||||
setSelectedEip155([...selectedEIP155, address])
|
||||
const prevChainAddresses = selectedAccounts[chain] ?? []
|
||||
setSelectedAccounts(prev => ({
|
||||
...prev,
|
||||
[chain]: [...prevChainAddresses, account]
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
// Add / remove address from Cosmos selection
|
||||
function onSelectCosmos(address: string) {
|
||||
if (selectedCosmos.includes(address)) {
|
||||
const newAddresses = selectedCosmos.filter(a => a !== address)
|
||||
setSelectedCosmos(newAddresses)
|
||||
} else {
|
||||
setSelectedCosmos([...selectedCosmos, address])
|
||||
}
|
||||
}
|
||||
|
||||
// Add / remove address from Solana selection
|
||||
function onSelectSolana(address: string) {
|
||||
if (selectedSolana.includes(address)) {
|
||||
const newAddresses = selectedSolana.filter(a => a !== address)
|
||||
setSelectedSolana(newAddresses)
|
||||
} else {
|
||||
setSelectedSolana([...selectedSolana, address])
|
||||
}
|
||||
}
|
||||
|
||||
// Hanlde approve action
|
||||
// Hanlde approve action, construct session namespace
|
||||
async function onApprove() {
|
||||
if (proposal) {
|
||||
const accounts = allSelected
|
||||
const response = {
|
||||
state: {
|
||||
accounts
|
||||
const namespaces: SessionTypes.Namespaces = {}
|
||||
Object.keys(requiredNamespaces).forEach(key => {
|
||||
const accounts: string[] = []
|
||||
requiredNamespaces[key].chains.map(chain => {
|
||||
selectedAccounts[key].map(acc => accounts.push(`${chain}:${acc}`))
|
||||
})
|
||||
namespaces[key] = {
|
||||
accounts,
|
||||
methods: requiredNamespaces[key].methods,
|
||||
events: requiredNamespaces[key].events
|
||||
}
|
||||
}
|
||||
await walletConnectClient.approve({ proposal, response })
|
||||
})
|
||||
|
||||
const { acknowledged } = await signClient.approve({
|
||||
id,
|
||||
relayProtocol: relays[0].protocol,
|
||||
namespaces
|
||||
})
|
||||
await acknowledged()
|
||||
}
|
||||
ModalStore.close()
|
||||
}
|
||||
@@ -81,56 +75,64 @@ export default function SessionProposalModal() {
|
||||
// Hanlde reject action
|
||||
async function onReject() {
|
||||
if (proposal) {
|
||||
await walletConnectClient.reject({ proposal })
|
||||
await signClient.reject({
|
||||
id,
|
||||
reason: ERROR.JSONRPC_REQUEST_METHOD_REJECTED.format()
|
||||
})
|
||||
}
|
||||
ModalStore.close()
|
||||
}
|
||||
|
||||
// Render account selection checkboxes based on chain
|
||||
function renderAccountSelection(chain: string) {
|
||||
if (isEIP155Chain(chain)) {
|
||||
return (
|
||||
<ProposalSelectSection
|
||||
addresses={eip155Addresses}
|
||||
selectedAddresses={selectedAccounts[chain]}
|
||||
onSelect={onSelectAccount}
|
||||
chain={chain}
|
||||
/>
|
||||
)
|
||||
} else if (isCosmosChain(chain)) {
|
||||
return (
|
||||
<ProposalSelectSection
|
||||
addresses={cosmosAddresses}
|
||||
selectedAddresses={selectedAccounts[chain]}
|
||||
onSelect={onSelectAccount}
|
||||
chain={chain}
|
||||
/>
|
||||
)
|
||||
} else if (isSolanaChain(chain)) {
|
||||
return (
|
||||
<ProposalSelectSection
|
||||
addresses={solanaAddresses}
|
||||
selectedAddresses={selectedAccounts[chain]}
|
||||
onSelect={onSelectAccount}
|
||||
chain={chain}
|
||||
/>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<RequestModalContainer title="Session Proposal">
|
||||
<ProjectInfoCard metadata={proposer.metadata} />
|
||||
|
||||
<Divider y={2} />
|
||||
|
||||
<RequesDetailsCard chains={chains} protocol={relay.protocol} />
|
||||
{/* TODO(ilja) Relays selection */}
|
||||
|
||||
<Divider y={2} />
|
||||
|
||||
<RequestMethodCard methods={methods} />
|
||||
|
||||
{chains.map(chain => {
|
||||
if (isEIP155Chain(chain)) {
|
||||
return (
|
||||
<ProposalSelectSection
|
||||
name={EIP155_CHAINS[chain as TEIP155Chain]?.name}
|
||||
addresses={eip155Addresses}
|
||||
selectedAddresses={selectedEIP155}
|
||||
onSelect={onSelectEIP155}
|
||||
chain={chain}
|
||||
/>
|
||||
)
|
||||
} else if (isCosmosChain(chain)) {
|
||||
return (
|
||||
<ProposalSelectSection
|
||||
name={COSMOS_MAINNET_CHAINS[chain as TCosmosChain]?.name}
|
||||
addresses={cosmosAddresses}
|
||||
selectedAddresses={selectedCosmos}
|
||||
onSelect={onSelectCosmos}
|
||||
chain={chain}
|
||||
/>
|
||||
)
|
||||
} else if (isSolanaChain(chain)) {
|
||||
return (
|
||||
<ProposalSelectSection
|
||||
name={SOLANA_CHAINS[chain as TSolanaChain]?.name}
|
||||
addresses={solanaAddresses}
|
||||
selectedAddresses={selectedSolana}
|
||||
onSelect={onSelectSolana}
|
||||
chain={chain}
|
||||
/>
|
||||
)
|
||||
}
|
||||
{Object.keys(requiredNamespaces).map(chain => {
|
||||
return (
|
||||
<Fragment key={chain}>
|
||||
<Text h4 css={{ marginBottom: '$5' }}>{`Review ${chain} permissions`}</Text>
|
||||
<SessionProposalChainCard requiredNamespace={requiredNamespaces[chain]} />
|
||||
{renderAccountSelection(chain)}
|
||||
<Divider y={2} />
|
||||
</Fragment>
|
||||
)
|
||||
})}
|
||||
</RequestModalContainer>
|
||||
|
||||
@@ -144,10 +146,8 @@ export default function SessionProposalModal() {
|
||||
flat
|
||||
color="success"
|
||||
onClick={onApprove}
|
||||
disabled={!allSelected.length}
|
||||
css={{
|
||||
opacity: allSelected.length ? 1 : 0.4
|
||||
}}
|
||||
disabled={!hasSelected}
|
||||
css={{ opacity: hasSelected ? 1 : 0.4 }}
|
||||
>
|
||||
Approve
|
||||
</Button>
|
||||
|
||||
@@ -5,7 +5,7 @@ import RequestMethodCard from '@/components/RequestMethodCard'
|
||||
import RequestModalContainer from '@/components/RequestModalContainer'
|
||||
import ModalStore from '@/store/ModalStore'
|
||||
import { approveEIP155Request, rejectEIP155Request } from '@/utils/EIP155RequestHandlerUtil'
|
||||
import { walletConnectClient } from '@/utils/WalletConnectUtil'
|
||||
import { signClient } from '@/utils/WalletConnectUtil'
|
||||
import { Button, Divider, Loading, Modal, Text } from '@nextui-org/react'
|
||||
import { Fragment, useState } from 'react'
|
||||
|
||||
@@ -23,16 +23,17 @@ export default function SessionSendTransactionModal() {
|
||||
|
||||
// Get required proposal data
|
||||
|
||||
const { method, params } = requestEvent.request
|
||||
const transaction = params[0]
|
||||
const { topic, params } = requestEvent
|
||||
const { request, chainId } = params
|
||||
const transaction = request.params[0]
|
||||
|
||||
// Handle approve action
|
||||
async function onApprove() {
|
||||
if (requestEvent) {
|
||||
setLoading(true)
|
||||
const response = await approveEIP155Request(requestEvent)
|
||||
await walletConnectClient.respond({
|
||||
topic: requestEvent.topic,
|
||||
await signClient.respond({
|
||||
topic,
|
||||
response
|
||||
})
|
||||
ModalStore.close()
|
||||
@@ -42,9 +43,9 @@ export default function SessionSendTransactionModal() {
|
||||
// Handle reject action
|
||||
async function onReject() {
|
||||
if (requestEvent) {
|
||||
const response = rejectEIP155Request(requestEvent.request)
|
||||
await walletConnectClient.respond({
|
||||
topic: requestEvent.topic,
|
||||
const response = rejectEIP155Request(requestEvent)
|
||||
await signClient.respond({
|
||||
topic,
|
||||
response
|
||||
})
|
||||
ModalStore.close()
|
||||
@@ -62,14 +63,11 @@ export default function SessionSendTransactionModal() {
|
||||
|
||||
<Divider y={2} />
|
||||
|
||||
<RequesDetailsCard
|
||||
chains={[requestEvent.chainId ?? '']}
|
||||
protocol={requestSession.relay.protocol}
|
||||
/>
|
||||
<RequesDetailsCard chains={[chainId ?? '']} protocol={requestSession.relay.protocol} />
|
||||
|
||||
<Divider y={2} />
|
||||
|
||||
<RequestMethodCard methods={[method]} />
|
||||
<RequestMethodCard methods={[request.method]} />
|
||||
</RequestModalContainer>
|
||||
|
||||
<Modal.Footer>
|
||||
|
||||
@@ -5,7 +5,7 @@ import RequestMethodCard from '@/components/RequestMethodCard'
|
||||
import RequestModalContainer from '@/components/RequestModalContainer'
|
||||
import ModalStore from '@/store/ModalStore'
|
||||
import { approveCosmosRequest, rejectCosmosRequest } from '@/utils/CosmosRequestHandler'
|
||||
import { walletConnectClient } from '@/utils/WalletConnectUtil'
|
||||
import { signClient } from '@/utils/WalletConnectUtil'
|
||||
import { Button, Divider, Modal, Text } from '@nextui-org/react'
|
||||
import { Fragment } from 'react'
|
||||
|
||||
@@ -20,14 +20,15 @@ export default function SessionSignCosmosModal() {
|
||||
}
|
||||
|
||||
// Get required request data
|
||||
const { method, params } = requestEvent.request
|
||||
const { topic, params } = requestEvent
|
||||
const { chainId, request } = params
|
||||
|
||||
// Handle approve action (logic varies based on request method)
|
||||
async function onApprove() {
|
||||
if (requestEvent) {
|
||||
const response = await approveCosmosRequest(requestEvent)
|
||||
await walletConnectClient.respond({
|
||||
topic: requestEvent.topic,
|
||||
await signClient.respond({
|
||||
topic,
|
||||
response
|
||||
})
|
||||
ModalStore.close()
|
||||
@@ -37,9 +38,9 @@ export default function SessionSignCosmosModal() {
|
||||
// Handle reject action
|
||||
async function onReject() {
|
||||
if (requestEvent) {
|
||||
const response = rejectCosmosRequest(requestEvent.request)
|
||||
await walletConnectClient.respond({
|
||||
topic: requestEvent.topic,
|
||||
const response = rejectCosmosRequest(requestEvent)
|
||||
await signClient.respond({
|
||||
topic,
|
||||
response
|
||||
})
|
||||
ModalStore.close()
|
||||
@@ -53,10 +54,7 @@ export default function SessionSignCosmosModal() {
|
||||
|
||||
<Divider y={2} />
|
||||
|
||||
<RequesDetailsCard
|
||||
chains={[requestEvent.chainId ?? '']}
|
||||
protocol={requestSession.relay.protocol}
|
||||
/>
|
||||
<RequesDetailsCard chains={[chainId ?? '']} protocol={requestSession.relay.protocol} />
|
||||
|
||||
<Divider y={2} />
|
||||
|
||||
@@ -64,7 +62,7 @@ export default function SessionSignCosmosModal() {
|
||||
|
||||
<Divider y={2} />
|
||||
|
||||
<RequestMethodCard methods={[method]} />
|
||||
<RequestMethodCard methods={[request.method]} />
|
||||
</RequestModalContainer>
|
||||
|
||||
<Modal.Footer>
|
||||
|
||||
@@ -5,7 +5,7 @@ import RequestModalContainer from '@/components/RequestModalContainer'
|
||||
import ModalStore from '@/store/ModalStore'
|
||||
import { approveEIP155Request, rejectEIP155Request } from '@/utils/EIP155RequestHandlerUtil'
|
||||
import { getSignParamsMessage } from '@/utils/HelperUtil'
|
||||
import { walletConnectClient } from '@/utils/WalletConnectUtil'
|
||||
import { signClient } from '@/utils/WalletConnectUtil'
|
||||
import { Button, Col, Divider, Modal, Row, Text } from '@nextui-org/react'
|
||||
import { Fragment } from 'react'
|
||||
|
||||
@@ -20,17 +20,18 @@ export default function SessionSignModal() {
|
||||
}
|
||||
|
||||
// Get required request data
|
||||
const { method, params } = requestEvent.request
|
||||
const { topic, params } = requestEvent
|
||||
const { request, chainId } = params
|
||||
|
||||
// Get message, convert it to UTF8 string if it is valid hex
|
||||
const message = getSignParamsMessage(params)
|
||||
const message = getSignParamsMessage(request.params)
|
||||
|
||||
// Handle approve action (logic varies based on request method)
|
||||
async function onApprove() {
|
||||
if (requestEvent) {
|
||||
const response = await approveEIP155Request(requestEvent)
|
||||
await walletConnectClient.respond({
|
||||
topic: requestEvent.topic,
|
||||
await signClient.respond({
|
||||
topic,
|
||||
response
|
||||
})
|
||||
ModalStore.close()
|
||||
@@ -40,9 +41,9 @@ export default function SessionSignModal() {
|
||||
// Handle reject action
|
||||
async function onReject() {
|
||||
if (requestEvent) {
|
||||
const response = rejectEIP155Request(requestEvent.request)
|
||||
await walletConnectClient.respond({
|
||||
topic: requestEvent.topic,
|
||||
const response = rejectEIP155Request(requestEvent)
|
||||
await signClient.respond({
|
||||
topic,
|
||||
response
|
||||
})
|
||||
ModalStore.close()
|
||||
@@ -56,10 +57,7 @@ export default function SessionSignModal() {
|
||||
|
||||
<Divider y={2} />
|
||||
|
||||
<RequesDetailsCard
|
||||
chains={[requestEvent.chainId ?? '']}
|
||||
protocol={requestSession.relay.protocol}
|
||||
/>
|
||||
<RequesDetailsCard chains={[chainId ?? '']} protocol={requestSession.relay.protocol} />
|
||||
|
||||
<Divider y={2} />
|
||||
|
||||
@@ -72,7 +70,7 @@ export default function SessionSignModal() {
|
||||
|
||||
<Divider y={2} />
|
||||
|
||||
<RequestMethodCard methods={[method]} />
|
||||
<RequestMethodCard methods={[request.method]} />
|
||||
</RequestModalContainer>
|
||||
|
||||
<Modal.Footer>
|
||||
|
||||
@@ -5,7 +5,7 @@ import RequestMethodCard from '@/components/RequestMethodCard'
|
||||
import RequestModalContainer from '@/components/RequestModalContainer'
|
||||
import ModalStore from '@/store/ModalStore'
|
||||
import { approveSolanaRequest, rejectSolanaRequest } from '@/utils/SolanaRequestHandlerUtil'
|
||||
import { walletConnectClient } from '@/utils/WalletConnectUtil'
|
||||
import { signClient } from '@/utils/WalletConnectUtil'
|
||||
import { Button, Divider, Modal, Text } from '@nextui-org/react'
|
||||
import { Fragment } from 'react'
|
||||
|
||||
@@ -20,14 +20,15 @@ export default function SessionSignSolanaModal() {
|
||||
}
|
||||
|
||||
// Get required request data
|
||||
const { method, params } = requestEvent.request
|
||||
const { topic, params } = requestEvent
|
||||
const { request, chainId } = params
|
||||
|
||||
// Handle approve action (logic varies based on request method)
|
||||
async function onApprove() {
|
||||
if (requestEvent) {
|
||||
const response = await approveSolanaRequest(requestEvent)
|
||||
await walletConnectClient.respond({
|
||||
topic: requestEvent.topic,
|
||||
await signClient.respond({
|
||||
topic,
|
||||
response
|
||||
})
|
||||
ModalStore.close()
|
||||
@@ -37,9 +38,9 @@ export default function SessionSignSolanaModal() {
|
||||
// Handle reject action
|
||||
async function onReject() {
|
||||
if (requestEvent) {
|
||||
const response = rejectSolanaRequest(requestEvent.request)
|
||||
await walletConnectClient.respond({
|
||||
topic: requestEvent.topic,
|
||||
const response = rejectSolanaRequest(requestEvent)
|
||||
await signClient.respond({
|
||||
topic,
|
||||
response
|
||||
})
|
||||
ModalStore.close()
|
||||
@@ -53,10 +54,7 @@ export default function SessionSignSolanaModal() {
|
||||
|
||||
<Divider y={2} />
|
||||
|
||||
<RequesDetailsCard
|
||||
chains={[requestEvent.chainId ?? '']}
|
||||
protocol={requestSession.relay.protocol}
|
||||
/>
|
||||
<RequesDetailsCard chains={[chainId ?? '']} protocol={requestSession.relay.protocol} />
|
||||
|
||||
<Divider y={2} />
|
||||
|
||||
@@ -64,7 +62,7 @@ export default function SessionSignSolanaModal() {
|
||||
|
||||
<Divider y={2} />
|
||||
|
||||
<RequestMethodCard methods={[method]} />
|
||||
<RequestMethodCard methods={[request.method]} />
|
||||
</RequestModalContainer>
|
||||
|
||||
<Modal.Footer>
|
||||
|
||||
@@ -6,7 +6,7 @@ import RequestModalContainer from '@/components/RequestModalContainer'
|
||||
import ModalStore from '@/store/ModalStore'
|
||||
import { approveEIP155Request, rejectEIP155Request } from '@/utils/EIP155RequestHandlerUtil'
|
||||
import { getSignTypedDataParamsData } from '@/utils/HelperUtil'
|
||||
import { walletConnectClient } from '@/utils/WalletConnectUtil'
|
||||
import { signClient } from '@/utils/WalletConnectUtil'
|
||||
import { Button, Divider, Modal, Text } from '@nextui-org/react'
|
||||
import { Fragment } from 'react'
|
||||
|
||||
@@ -21,17 +21,18 @@ export default function SessionSignTypedDataModal() {
|
||||
}
|
||||
|
||||
// Get required request data
|
||||
const { method, params } = requestEvent.request
|
||||
const { topic, params } = requestEvent
|
||||
const { request, chainId } = params
|
||||
|
||||
// Get data
|
||||
const data = getSignTypedDataParamsData(params)
|
||||
const data = getSignTypedDataParamsData(request.params)
|
||||
|
||||
// Handle approve action (logic varies based on request method)
|
||||
async function onApprove() {
|
||||
if (requestEvent) {
|
||||
const response = await approveEIP155Request(requestEvent)
|
||||
await walletConnectClient.respond({
|
||||
topic: requestEvent.topic,
|
||||
await signClient.respond({
|
||||
topic,
|
||||
response
|
||||
})
|
||||
ModalStore.close()
|
||||
@@ -41,9 +42,9 @@ export default function SessionSignTypedDataModal() {
|
||||
// Handle reject action
|
||||
async function onReject() {
|
||||
if (requestEvent) {
|
||||
const response = rejectEIP155Request(requestEvent.request)
|
||||
await walletConnectClient.respond({
|
||||
topic: requestEvent.topic,
|
||||
const response = rejectEIP155Request(requestEvent)
|
||||
await signClient.respond({
|
||||
topic,
|
||||
response
|
||||
})
|
||||
ModalStore.close()
|
||||
@@ -57,10 +58,7 @@ export default function SessionSignTypedDataModal() {
|
||||
|
||||
<Divider y={2} />
|
||||
|
||||
<RequesDetailsCard
|
||||
chains={[requestEvent.chainId ?? '']}
|
||||
protocol={requestSession.relay.protocol}
|
||||
/>
|
||||
<RequesDetailsCard chains={[chainId ?? '']} protocol={requestSession.relay.protocol} />
|
||||
|
||||
<Divider y={2} />
|
||||
|
||||
@@ -68,7 +66,7 @@ export default function SessionSignTypedDataModal() {
|
||||
|
||||
<Divider y={2} />
|
||||
|
||||
<RequestMethodCard methods={[method]} />
|
||||
<RequestMethodCard methods={[request.method]} />
|
||||
</RequestModalContainer>
|
||||
|
||||
<Modal.Footer>
|
||||
|
||||
@@ -17,7 +17,8 @@ export default function SessionUnsuportedMethodModal() {
|
||||
}
|
||||
|
||||
// Get required request data
|
||||
const { method } = requestEvent.request
|
||||
const { topic, params } = requestEvent
|
||||
const { chainId, request } = params
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
@@ -26,14 +27,11 @@ export default function SessionUnsuportedMethodModal() {
|
||||
|
||||
<Divider y={2} />
|
||||
|
||||
<RequesDetailsCard
|
||||
chains={[requestEvent.chainId ?? '']}
|
||||
protocol={requestSession.relay.protocol}
|
||||
/>
|
||||
<RequesDetailsCard chains={[chainId ?? '']} protocol={requestSession.relay.protocol} />
|
||||
|
||||
<Divider y={2} />
|
||||
|
||||
<RequestMethodCard methods={[method]} />
|
||||
<RequestMethodCard methods={[request.method]} />
|
||||
</RequestModalContainer>
|
||||
|
||||
<Modal.Footer>
|
||||
|
||||
+1031
-617
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user