Add pairing logic

This commit is contained in:
Ilja 2022-02-07 15:24:15 +02:00
parent 5640db7dff
commit d4f6d53a7d
11 changed files with 106 additions and 87 deletions

View File

@ -1,4 +1,5 @@
import { Text } from '@nextui-org/react' import { Divider, Text } from '@nextui-org/react'
import { Fragment } from 'react'
/** /**
* Types * Types
@ -12,15 +13,18 @@ interface Props {
*/ */
export default function PageHeader({ children }: Props) { export default function PageHeader({ children }: Props) {
return ( return (
<Fragment>
<Text <Text
h2 h3
weight="bold" weight="bold"
css={{ css={{
textGradient: '45deg, $primary, $secondary 100%', textGradient: '45deg, $primary, $secondary 100%',
marginBottom: '$10' marginBottom: '$5'
}} }}
> >
{children} {children}
</Text> </Text>
<Divider css={{ marginBottom: '$10' }} />
</Fragment>
) )
} }

View File

@ -1,26 +0,0 @@
import WalletConnectStore from '@/store/WalletConnectStore'
import { Modal } from '@nextui-org/react'
import { CLIENT_EVENTS } from '@walletconnect/client'
import { SessionTypes } from '@walletconnect/types'
import { useCallback, useEffect, useState } from 'react'
export default function WalletConnectManager() {
const [open, setOpen] = useState(false)
const { client } = WalletConnectStore.state
const onSessionProposal = useCallback((proposal: SessionTypes.Proposal) => {}, [])
useEffect(() => {
client.on(CLIENT_EVENTS.session.proposal, onSessionProposal)
return () => client.disconnect()
}, [client, onSessionProposal])
return (
<Modal closeButton open={open} onClose={() => setOpen(false)}>
<Modal.Header></Modal.Header>
<Modal.Body></Modal.Body>
<Modal.Footer></Modal.Footer>
</Modal>
)
}

View File

@ -1,14 +1,18 @@
import WalletConnectStore from '@/store/WalletConnectStore'
import WalletStore from '@/store/WalletStore' import WalletStore from '@/store/WalletStore'
import { createClient } from '@/utils/WalletConnectUtil'
import { useCallback, useEffect, useState } from 'react' import { useCallback, useEffect, useState } from 'react'
export default function useInitialization() { export default function useInitialization() {
const [initialized, setInitialized] = useState(false) const [initialized, setInitialized] = useState(false)
const onInitialize = useCallback(async () => { const onInitialize = useCallback(async () => {
try {
WalletStore.createWallet() WalletStore.createWallet()
await WalletConnectStore.createWalletConnectClient() await createClient()
setInitialized(true) setInitialized(true)
} catch (err: unknown) {
alert(err)
}
}, []) }, [])
useEffect(() => { useEffect(() => {

View File

@ -0,0 +1,16 @@
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 onSessionProposal = useCallback((proposal: SessionTypes.Proposal) => {
console.log(proposal)
}, [])
useEffect(() => {
if (initialized) {
client?.on(CLIENT_EVENTS.session.proposal, onSessionProposal)
}
}, [initialized, onSessionProposal])
}

View File

@ -1,14 +1,18 @@
import Layout from '@/components/Layout' import Layout from '@/components/Layout'
import WalletConnectManager from '@/components/WalletConnectManager'
import useInitialization from '@/hooks/useInitialization' import useInitialization from '@/hooks/useInitialization'
import useWalletConnectEventsManager from '@/hooks/useWalletConnectEventsManager'
import { darkTheme, lightTheme } from '@/utils/ThemeUtil' import { darkTheme, lightTheme } from '@/utils/ThemeUtil'
import { NextUIProvider } from '@nextui-org/react' import { NextUIProvider } from '@nextui-org/react'
import { ThemeProvider } from 'next-themes' import { ThemeProvider } from 'next-themes'
import { AppProps } from 'next/app' import { AppProps } from 'next/app'
export default function App({ Component, pageProps }: AppProps) { export default function App({ Component, pageProps }: AppProps) {
// Step 1 - Initialize wallets and wallet connect client
const initialized = useInitialization() const initialized = useInitialization()
// Step 2 - Once initialized, set up wallet connect event manager
useWalletConnectEventsManager(initialized)
return ( return (
<ThemeProvider <ThemeProvider
defaultTheme="system" defaultTheme="system"
@ -22,8 +26,6 @@ export default function App({ Component, pageProps }: AppProps) {
<Layout initialized={initialized}> <Layout initialized={initialized}>
<Component {...pageProps} /> <Component {...pageProps} />
</Layout> </Layout>
{initialized && <WalletConnectManager />}
</NextUIProvider> </NextUIProvider>
</ThemeProvider> </ThemeProvider>
) )

View File

@ -8,6 +8,10 @@ import { useSnapshot } from 'valtio'
export default function HomePage() { export default function HomePage() {
const { wallet } = useSnapshot(WalletStore.state) const { wallet } = useSnapshot(WalletStore.state)
if (!wallet) {
return null
}
return ( return (
<Fragment> <Fragment>
<PageHeader>Accounts</PageHeader> <PageHeader>Accounts</PageHeader>

View File

@ -0,0 +1,38 @@
import PageHeader from '@/components/PageHeader'
import { client } from '@/utils/WalletConnectUtil'
import { Button, Input, Loading } from '@nextui-org/react'
import { Fragment, useState } from 'react'
export default function WalletConnectPage() {
const [uri, setUri] = useState('')
const [loading, setLoading] = useState(false)
async function onConnect() {
try {
setLoading(true)
await client?.pair({ uri })
} catch (err: unknown) {
alert(err)
} finally {
setLoading(false)
}
}
return (
<Fragment>
<PageHeader>WalletConnect</PageHeader>
<Input
bordered
label="WalletConnect URI"
placeholder="e.g. wc:a281567bb3e4..."
onChange={e => setUri(e.target.value)}
value={uri}
contentRight={
<Button size="xs" disabled={!uri} css={{ marginLeft: -60 }} onClick={onConnect}>
{loading ? <Loading size="sm" /> : 'Connect'}
</Button>
}
/>
</Fragment>
)
}

View File

@ -1,41 +0,0 @@
import WalletConnectClient from '@walletconnect/client'
import { proxy } from 'valtio'
/**
* Types
*/
interface State {
client: WalletConnectClient
}
/**
* State
*/
const state = proxy<State>({
client: undefined
})
/**
* Store / Actions
*/
const WalletConnectStore = {
state,
async createWalletConnectClient() {
const client = await WalletConnectClient.init({
controller: true,
logger: 'debug',
projectId: '8f331b9812e0e5b8f2da2c7203624869',
relayUrl: 'wss://relay.walletconnect.com',
metadata: {
name: 'React Wallet',
description: 'React Wallet for WalletConnect',
url: 'https://walletconnect.com/',
icons: ['https://avatars.githubusercontent.com/u/37784886']
}
})
state.client = client
}
}
export default WalletConnectStore

View File

@ -5,7 +5,7 @@ import { proxy } from 'valtio'
* Types * Types
*/ */
interface State { interface State {
wallet: Wallet wallet?: Wallet
} }
/** /**

View File

@ -0,0 +1,18 @@
import WalletConnectClient from '@walletconnect/client'
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: {
name: 'React Wallet',
description: 'React Wallet for WalletConnect',
url: 'https://walletconnect.com/',
icons: ['https://avatars.githubusercontent.com/u/37784886']
}
})
}

View File

@ -8,7 +8,7 @@
], ],
"allowJs": true, "allowJs": true,
"skipLibCheck": true, "skipLibCheck": true,
"strict": false, "strict": true,
"forceConsistentCasingInFileNames": true, "forceConsistentCasingInFileNames": true,
"noEmit": true, "noEmit": true,
"incremental": true, "incremental": true,