Save progress

This commit is contained in:
Ilja 2022-02-10 16:13:01 +02:00
parent f970b91d7d
commit 008fb6cbe2
7 changed files with 150 additions and 21 deletions

View File

@ -1,15 +1,16 @@
import ModalStore from '@/store/ModalStore'
import SessionProposalModal from '@/views/SessionProposalModal'
import { Modal as NextModal } from '@nextui-org/react'
import { useSnapshot } from 'valtio'
export default function Modal() {
const { open } = useSnapshot(ModalStore.state)
const { open, view } = useSnapshot(ModalStore.state)
console.log(open)
return (
<NextModal open={open} onClose={ModalStore.close}>
<NextModal.Header></NextModal.Header>
<NextModal.Body></NextModal.Body>
<NextModal.Footer></NextModal.Footer>
<NextModal blur open={open} style={{ border: '1px solid rgba(139, 139, 139, 0.4)' }}>
{view === 'SessionProposalModal' && <SessionProposalModal />}
</NextModal>
)
}

View File

@ -1,16 +1,26 @@
import ModalStore from '@/store/ModalStore'
import { client } from '@/utils/WalletConnectUtil'
import { CLIENT_EVENTS } from '@walletconnect/client'
import { SessionTypes } from '@walletconnect/types'
import { useCallback, useEffect } from 'react'
export default function useWalletConnectEventsManager(initialized: boolean) {
const onPairingProposal = useCallback((proposal: SessionTypes.Proposal) => {
const onSessionProposal = useCallback((proposal: SessionTypes.Proposal) => {
console.log(proposal)
ModalStore.open('SessionProposalModal', { proposal })
}, [])
const onSessionCreated = useCallback((created: SessionTypes.Created) => {
// ModalStore.open('SessionCreatedModal', { created })
}, [])
useEffect(() => {
if (initialized) {
client?.on(CLIENT_EVENTS.pairing.proposal, onPairingProposal)
if (initialized && client) {
// 1. Open session proposal modal for confirmation / rejection
client.on(CLIENT_EVENTS.session.proposal, onSessionProposal)
// 2. Open session created modal to show success feedback
client.on(CLIENT_EVENTS.session.created, onSessionCreated)
}
}, [initialized, onPairingProposal])
}, [initialized, onSessionProposal, onSessionCreated])
}

View File

@ -15,6 +15,7 @@ export default function WalletConnectPage() {
} catch (err: unknown) {
alert(err)
} finally {
setUri('')
setLoading(false)
}
}

View File

@ -1,17 +1,27 @@
import { SessionTypes } from '@walletconnect/types'
import { proxy } from 'valtio'
/**
* Types
*/
interface ModalData {
proposal?: SessionTypes.Proposal
created?: SessionTypes.Created
}
interface State {
open: boolean
view?: 'SessionProposalModal' | 'SessionCreatedModal'
data?: ModalData
}
/**
* State
*/
const state = proxy<State>({
open: false
view: undefined,
open: false,
data: undefined
})
/**
@ -20,7 +30,9 @@ const state = proxy<State>({
const ModalStore = {
state,
open() {
open(view: State['view'], data: State['data']) {
state.view = view
state.data = data
state.open = true
},

View File

@ -3,30 +3,31 @@
* @url https://chainlist.org
*/
export type CHAIN = keyof typeof MAINNET_CHAINS
export const LOGO_BASE_URL = 'https://blockchain-api.xyz/logos/'
export const MAINNET_CHAINS = {
'1': {
'eip155:1': {
chainId: 1,
name: 'Ethereum',
logo: LOGO_BASE_URL + 'eip155:1.png',
rgb: '99, 125, 234'
},
'10': {
'eip155:10': {
chainId: 10,
name: 'Optimism',
logo: LOGO_BASE_URL + 'eip155:10.png',
rgb: '233, 1, 1'
},
'100': {
name: 'Gnosis',
logo: LOGO_BASE_URL + 'eip155:100.png',
rgb: '73, 169, 166'
},
'137': {
'eip155:137': {
chainId: 137,
name: 'Polygon',
logo: LOGO_BASE_URL + 'eip155:137.png',
rgb: '130, 71, 229'
},
'42161': {
'eip155:42161': {
chainId: 42161,
name: 'Arbitrum',
logo: LOGO_BASE_URL + 'eip155:42161.png',
rgb: '44, 55, 75'

View File

@ -5,7 +5,6 @@ export let client: WalletConnectClient | undefined = undefined
export async function createClient() {
client = await WalletConnectClient.init({
controller: true,
logger: 'debug',
projectId: '8f331b9812e0e5b8f2da2c7203624869',
relayUrl: 'wss://relay.walletconnect.com',
metadata: {

View File

@ -0,0 +1,105 @@
import ModalStore from '@/store/ModalStore'
import WalletStore from '@/store/WalletStore'
import { CHAIN, MAINNET_CHAINS } from '@/utils/EIP155ChainsUtil'
import { client } from '@/utils/WalletConnectUtil'
import { Avatar, Button, Col, Container, Divider, Link, Modal, Row, Text } from '@nextui-org/react'
import { Fragment } from 'react'
export default function SessionProposalModal() {
// Get proposal data and wallet address from store
const proposal = ModalStore.state.data?.proposal
const address = WalletStore.state.wallet?.address
// Ensure proposal and client are defined
if (!proposal || !client) {
return <Text>Missing proposal data</Text>
}
// Get data to display
const { proposer, permissions, relay } = proposal
const { icons, name, url } = proposer.metadata
const { chains } = permissions.blockchain
const { methods } = permissions.jsonrpc
const { protocol } = relay
// Hanlde approve action
async function onApprove() {
if (client && proposal && address) {
const response = {
state: {
accounts: chains.map(chain => `${chain}:${address}`)
}
}
await client.approve({ proposal, response })
}
ModalStore.close()
}
// Hanlde reject action
async function onReject() {
if (client && proposal) {
await client.reject({ proposal })
}
ModalStore.close()
}
return (
<Fragment>
<Modal.Header>
<Text h3>Session Proposal</Text>
</Modal.Header>
<Modal.Body>
<Container css={{ padding: 0 }}>
<Row align="center">
<Col span={3}>
<Avatar src={icons[0]} />
</Col>
<Col span={14}>
<Text h5>{name}</Text>
<Link href={url}>{url}</Link>
</Col>
</Row>
<Divider y={2} />
<Row>
<Col>
<Text h5>Blockchains</Text>
<Text color="$gray400">
{chains.map(chain => MAINNET_CHAINS[chain as CHAIN]?.name ?? chain).join(', ')}
</Text>
</Col>
</Row>
<Divider y={2} />
<Row>
<Col>
<Text h5>Methods</Text>
<Text color="$gray400">{methods.map(method => method).join(', ')}</Text>
</Col>
</Row>
<Divider y={2} />
<Row>
<Col>
<Text h5>Relay Protocol</Text>
<Text color="$gray400">{protocol}</Text>
</Col>
</Row>
</Container>
</Modal.Body>
<Modal.Footer>
<Button auto flat color="error" onClick={onReject}>
Reject
</Button>
<Button auto flat color="success" onClick={onApprove}>
Approve
</Button>
</Modal.Footer>
</Fragment>
)
}