Wrap up eth_sign and personal_sign examples
This commit is contained in:
parent
de05b8c82c
commit
e2ac17957e
@ -19,7 +19,8 @@
|
|||||||
"react-qr-reader-es6": "2.2.1-2",
|
"react-qr-reader-es6": "2.2.1-2",
|
||||||
"framer-motion": "6.2.6",
|
"framer-motion": "6.2.6",
|
||||||
"ethers": "5.5.4",
|
"ethers": "5.5.4",
|
||||||
"valtio": "1.3.0"
|
"valtio": "1.3.0",
|
||||||
|
"@json-rpc-tools/utils": "1.7.6"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@walletconnect/types": "2.0.0-beta.22",
|
"@walletconnect/types": "2.0.0-beta.22",
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import { truncate } from '@/utils/HelperUtil'
|
import { truncate } from '@/utils/HelperUtil'
|
||||||
import { Avatar, Card, Text } from '@nextui-org/react'
|
import { Avatar, Card, Text } from '@nextui-org/react'
|
||||||
|
import Link from 'next/link'
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
name: string
|
name: string
|
||||||
@ -10,36 +11,38 @@ interface Props {
|
|||||||
|
|
||||||
export default function AccountCard({ name, logo, rgb, address }: Props) {
|
export default function AccountCard({ name, logo, rgb, address }: Props) {
|
||||||
return (
|
return (
|
||||||
<Card
|
<Link href={`/sessions?address=${address}`} passHref>
|
||||||
bordered
|
<Card
|
||||||
clickable
|
bordered
|
||||||
borderWeight="light"
|
clickable
|
||||||
css={{
|
borderWeight="light"
|
||||||
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={{
|
css={{
|
||||||
flexDirection: 'row',
|
borderColor: `rgba(${rgb}, 0.4)`,
|
||||||
alignItems: 'center',
|
boxShadow: `0 0 10px 0 rgba(${rgb}, 0.15)`,
|
||||||
justifyContent: 'space-between',
|
backgroundColor: `rgba(${rgb}, 0.25)`,
|
||||||
overflow: 'hidden'
|
marginBottom: '$6',
|
||||||
|
minHeight: '70px'
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Avatar src={logo} />
|
<Card.Body
|
||||||
<div style={{ flex: 1 }}>
|
css={{
|
||||||
<Text h5 css={{ marginLeft: '$9' }}>
|
flexDirection: 'row',
|
||||||
{name}
|
alignItems: 'center',
|
||||||
</Text>
|
justifyContent: 'space-between',
|
||||||
<Text weight="light" size={13} css={{ marginLeft: '$9' }}>
|
overflow: 'hidden'
|
||||||
{truncate(address, 19)}
|
}}
|
||||||
</Text>
|
>
|
||||||
</div>
|
<Avatar src={logo} />
|
||||||
</Card.Body>
|
<div style={{ flex: 1 }}>
|
||||||
</Card>
|
<Text h5 css={{ marginLeft: '$9' }}>
|
||||||
|
{name}
|
||||||
|
</Text>
|
||||||
|
<Text weight="light" size={13} css={{ marginLeft: '$9' }}>
|
||||||
|
{truncate(address, 19)}
|
||||||
|
</Text>
|
||||||
|
</div>
|
||||||
|
</Card.Body>
|
||||||
|
</Card>
|
||||||
|
</Link>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import ModalStore from '@/store/ModalStore'
|
import ModalStore from '@/store/ModalStore'
|
||||||
import SessionProposalModal from '@/views/SessionProposalModal'
|
import SessionProposalModal from '@/views/SessionProposalModal'
|
||||||
import SessionRequestModal from '@/views/SessionRequestModal'
|
import SessionRequestModal from '@/views/SessionSignModal'
|
||||||
import { Modal as NextModal } from '@nextui-org/react'
|
import { Modal as NextModal } from '@nextui-org/react'
|
||||||
import { useSnapshot } from 'valtio'
|
import { useSnapshot } from 'valtio'
|
||||||
|
|
||||||
@ -10,7 +10,7 @@ export default function Modal() {
|
|||||||
return (
|
return (
|
||||||
<NextModal blur open={open} style={{ border: '1px solid rgba(139, 139, 139, 0.4)' }}>
|
<NextModal blur open={open} style={{ border: '1px solid rgba(139, 139, 139, 0.4)' }}>
|
||||||
{view === 'SessionProposalModal' && <SessionProposalModal />}
|
{view === 'SessionProposalModal' && <SessionProposalModal />}
|
||||||
{view === 'SessionRequestModal' && <SessionRequestModal />}
|
{view === 'SessionSignModal' && <SessionRequestModal />}
|
||||||
</NextModal>
|
</NextModal>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -3,20 +3,20 @@
|
|||||||
* @url https://chainlist.org
|
* @url https://chainlist.org
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
|
||||||
* Types
|
|
||||||
*/
|
|
||||||
export type TChain = keyof typeof MAINNET_CHAINS
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utilities
|
* Utilities
|
||||||
*/
|
*/
|
||||||
export const LOGO_BASE_URL = 'https://blockchain-api.xyz/logos/'
|
const LOGO_BASE_URL = 'https://blockchain-api.xyz/logos/'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Types
|
||||||
|
*/
|
||||||
|
export type TEIP155Chain = keyof typeof EIP155_CHAINS
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Chains
|
* Chains
|
||||||
*/
|
*/
|
||||||
export const MAINNET_CHAINS = {
|
export const EIP155_CHAINS = {
|
||||||
'eip155:1': {
|
'eip155:1': {
|
||||||
chainId: 1,
|
chainId: 1,
|
||||||
name: 'Ethereum',
|
name: 'Ethereum',
|
||||||
@ -46,11 +46,12 @@ export const MAINNET_CHAINS = {
|
|||||||
/**
|
/**
|
||||||
* Methods
|
* Methods
|
||||||
*/
|
*/
|
||||||
export const SIGNING_METHODS = {
|
export const EIP155_SIGNING_METHODS = {
|
||||||
PERSONAL_SIGN: 'personal_sign',
|
PERSONAL_SIGN: 'personal_sign',
|
||||||
SEND_TRANSACTION: 'eth_sendTransaction',
|
ETH_SIGN: 'eth_sign',
|
||||||
SIGN: 'eth_sign',
|
ETH_SIGN_TRANSACTION: 'eth_signTransaction',
|
||||||
SIGN_TRANSACTION: 'eth_signTransaction',
|
ETH_SIGN_TYPED_DATA: 'eth_signTypedData',
|
||||||
SIGN_TYPED_DATA: 'eth_signTypedData',
|
ETH_SIGN_TYPED_DATA_V4: 'eth_signTypedData_v4',
|
||||||
SIGN_TYPED_DATA_V4: 'eth_signTypedData_v4'
|
ETH_SIGN_RAW_TRANSACTION: 'eth_sendRawTransaction',
|
||||||
|
ETH_SEND_TRANSACTION: 'eth_sendTransaction'
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import { EIP155_SIGNING_METHODS } from '@/data/EIP155Data'
|
||||||
import ModalStore from '@/store/ModalStore'
|
import ModalStore from '@/store/ModalStore'
|
||||||
import { walletConnectClient } from '@/utils/WalletConnectUtil'
|
import { walletConnectClient } from '@/utils/WalletConnectUtil'
|
||||||
import { CLIENT_EVENTS } from '@walletconnect/client'
|
import { CLIENT_EVENTS } from '@walletconnect/client'
|
||||||
@ -5,28 +6,31 @@ import { SessionTypes } from '@walletconnect/types'
|
|||||||
import { useCallback, useEffect } from 'react'
|
import { useCallback, useEffect } from 'react'
|
||||||
|
|
||||||
export default function useWalletConnectEventsManager(initialized: boolean) {
|
export default function useWalletConnectEventsManager(initialized: boolean) {
|
||||||
|
// 1. Open session proposal modal for confirmation / rejection
|
||||||
const onSessionProposal = useCallback((proposal: SessionTypes.Proposal) => {
|
const onSessionProposal = useCallback((proposal: SessionTypes.Proposal) => {
|
||||||
ModalStore.open('SessionProposalModal', { proposal })
|
ModalStore.open('SessionProposalModal', { proposal })
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
const onSessionCreated = useCallback((created: SessionTypes.Created) => {
|
// 2. Open session created modal to show success feedback
|
||||||
// TODO show successful connection feedback here
|
const onSessionCreated = useCallback((created: SessionTypes.Created) => {}, [])
|
||||||
}, [])
|
|
||||||
|
|
||||||
const onSessionRequest = useCallback(async (request: SessionTypes.RequestEvent) => {
|
// 3. Open rpc request handling modal based on method that was used
|
||||||
const requestSession = await walletConnectClient.session.get(request.topic)
|
const onSessionRequest = useCallback(async (requestEvent: SessionTypes.RequestEvent) => {
|
||||||
ModalStore.open('SessionRequestModal', { request, requestSession })
|
const { topic, request } = requestEvent
|
||||||
|
const { method } = request
|
||||||
|
const requestSession = await walletConnectClient.session.get(topic)
|
||||||
|
|
||||||
|
if ([EIP155_SIGNING_METHODS.ETH_SIGN, EIP155_SIGNING_METHODS.PERSONAL_SIGN].includes(method)) {
|
||||||
|
ModalStore.open('SessionSignModal', { requestEvent, requestSession })
|
||||||
|
}
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (initialized) {
|
if (initialized) {
|
||||||
// 1. Open session proposal modal for confirmation / rejection
|
|
||||||
walletConnectClient.on(CLIENT_EVENTS.session.proposal, onSessionProposal)
|
walletConnectClient.on(CLIENT_EVENTS.session.proposal, onSessionProposal)
|
||||||
|
|
||||||
// 2. Open session created modal to show success feedback
|
|
||||||
walletConnectClient.on(CLIENT_EVENTS.session.created, onSessionCreated)
|
walletConnectClient.on(CLIENT_EVENTS.session.created, onSessionCreated)
|
||||||
|
|
||||||
// 3. Open rpc request handling modal
|
|
||||||
walletConnectClient.on(CLIENT_EVENTS.session.request, onSessionRequest)
|
walletConnectClient.on(CLIENT_EVENTS.session.request, onSessionRequest)
|
||||||
}
|
}
|
||||||
}, [initialized, onSessionProposal, onSessionCreated, onSessionRequest])
|
}, [initialized, onSessionProposal, onSessionCreated, onSessionRequest])
|
||||||
|
@ -2,11 +2,11 @@ import Layout from '@/components/Layout'
|
|||||||
import Modal from '@/components/Modal'
|
import Modal from '@/components/Modal'
|
||||||
import useInitialization from '@/hooks/useInitialization'
|
import useInitialization from '@/hooks/useInitialization'
|
||||||
import useWalletConnectEventsManager from '@/hooks/useWalletConnectEventsManager'
|
import useWalletConnectEventsManager from '@/hooks/useWalletConnectEventsManager'
|
||||||
import '@/styles/main.css'
|
|
||||||
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'
|
||||||
|
import '../../public/main.css'
|
||||||
|
|
||||||
export default function App({ Component, pageProps }: AppProps) {
|
export default function App({ Component, pageProps }: AppProps) {
|
||||||
// Step 1 - Initialize wallets and wallet connect client
|
// Step 1 - Initialize wallets and wallet connect client
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import AccountCard from '@/components/AccountCard'
|
import AccountCard from '@/components/AccountCard'
|
||||||
import PageHeader from '@/components/PageHeader'
|
import PageHeader from '@/components/PageHeader'
|
||||||
import { MAINNET_CHAINS } from '@/data/EIP155Data'
|
import { EIP155_CHAINS } from '@/data/EIP155Data'
|
||||||
import { wallet } from '@/utils/WalletUtil'
|
import { wallet } from '@/utils/WalletUtil'
|
||||||
import { Fragment } from 'react'
|
import { Fragment } from 'react'
|
||||||
|
|
||||||
@ -8,7 +8,7 @@ export default function HomePage() {
|
|||||||
return (
|
return (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
<PageHeader>Accounts</PageHeader>
|
<PageHeader>Accounts</PageHeader>
|
||||||
{Object.values(MAINNET_CHAINS).map(({ name, logo, rgb }) => (
|
{Object.values(EIP155_CHAINS).map(({ name, logo, rgb }) => (
|
||||||
<AccountCard key={name} name={name} logo={logo} rgb={rgb} address={wallet.address} />
|
<AccountCard key={name} name={name} logo={logo} rgb={rgb} address={wallet.address} />
|
||||||
))}
|
))}
|
||||||
</Fragment>
|
</Fragment>
|
||||||
|
20
wallets/react-wallet-v2/src/pages/sessions.tsx
Normal file
20
wallets/react-wallet-v2/src/pages/sessions.tsx
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
import PageHeader from '@/components/PageHeader'
|
||||||
|
import { truncate } from '@/utils/HelperUtil'
|
||||||
|
import { walletConnectClient } from '@/utils/WalletConnectUtil'
|
||||||
|
import { useRouter } from 'next/router'
|
||||||
|
import { Fragment, useEffect } from 'react'
|
||||||
|
|
||||||
|
export default function SessionsPage() {
|
||||||
|
const { query } = useRouter()
|
||||||
|
const address = (query?.address as string) ?? 'Unknown'
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
console.log(walletConnectClient.session.values)
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Fragment>
|
||||||
|
<PageHeader>{truncate(address, 15)}</PageHeader>
|
||||||
|
</Fragment>
|
||||||
|
)
|
||||||
|
}
|
@ -7,13 +7,13 @@ import { proxy } from 'valtio'
|
|||||||
interface ModalData {
|
interface ModalData {
|
||||||
proposal?: SessionTypes.Proposal
|
proposal?: SessionTypes.Proposal
|
||||||
created?: SessionTypes.Created
|
created?: SessionTypes.Created
|
||||||
request?: SessionTypes.RequestEvent
|
requestEvent?: SessionTypes.RequestEvent
|
||||||
requestSession?: SessionTypes.Settled
|
requestSession?: SessionTypes.Settled
|
||||||
}
|
}
|
||||||
|
|
||||||
interface State {
|
interface State {
|
||||||
open: boolean
|
open: boolean
|
||||||
view?: 'SessionProposalModal' | 'SessionRequestModal'
|
view?: 'SessionProposalModal' | 'SessionSignModal'
|
||||||
data?: ModalData
|
data?: ModalData
|
||||||
}
|
}
|
||||||
|
|
||||||
|
28
wallets/react-wallet-v2/src/utils/RequestHandlerUtil.ts
Normal file
28
wallets/react-wallet-v2/src/utils/RequestHandlerUtil.ts
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
import { EIP155_SIGNING_METHODS } from '@/data/EIP155Data'
|
||||||
|
import { formatJsonRpcError, formatJsonRpcResult } from '@json-rpc-tools/utils'
|
||||||
|
import { RequestEvent } from '@walletconnect/types'
|
||||||
|
import { ERROR } from '@walletconnect/utils'
|
||||||
|
import { Wallet } from 'ethers'
|
||||||
|
|
||||||
|
export async function approveEIP155Request(request: RequestEvent['request'], wallet: Wallet) {
|
||||||
|
const { method, params, id } = request
|
||||||
|
|
||||||
|
switch (method) {
|
||||||
|
case EIP155_SIGNING_METHODS.PERSONAL_SIGN:
|
||||||
|
const personalSignResult = await wallet.signMessage(params[0])
|
||||||
|
return formatJsonRpcResult(id, personalSignResult)
|
||||||
|
|
||||||
|
case EIP155_SIGNING_METHODS.ETH_SIGN:
|
||||||
|
const ethSignResult = await wallet.signMessage(params[1])
|
||||||
|
return formatJsonRpcResult(id, ethSignResult)
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new Error(ERROR.UNKNOWN_JSONRPC_METHOD.format().message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function rejectEIP155Request(request: RequestEvent['request']) {
|
||||||
|
const { id } = request
|
||||||
|
|
||||||
|
return formatJsonRpcError(id, ERROR.JSONRPC_REQUEST_METHOD_REJECTED.format().message)
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
import { MAINNET_CHAINS, TChain } from '@/data/EIP155Data'
|
import { EIP155_CHAINS, TEIP155Chain } from '@/data/EIP155Data'
|
||||||
import ModalStore from '@/store/ModalStore'
|
import ModalStore from '@/store/ModalStore'
|
||||||
import { walletConnectClient } from '@/utils/WalletConnectUtil'
|
import { walletConnectClient } from '@/utils/WalletConnectUtil'
|
||||||
import { wallet } from '@/utils/WalletUtil'
|
import { wallet } from '@/utils/WalletUtil'
|
||||||
@ -66,7 +66,9 @@ export default function SessionProposalModal() {
|
|||||||
<Col>
|
<Col>
|
||||||
<Text h5>Blockchains</Text>
|
<Text h5>Blockchains</Text>
|
||||||
<Text color="$gray400">
|
<Text color="$gray400">
|
||||||
{chains.map(chain => MAINNET_CHAINS[chain as TChain]?.name ?? chain).join(', ')}
|
{chains
|
||||||
|
.map(chain => EIP155_CHAINS[chain as TEIP155Chain]?.name ?? chain)
|
||||||
|
.join(', ')}
|
||||||
</Text>
|
</Text>
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
|
@ -1,37 +1,57 @@
|
|||||||
import { MAINNET_CHAINS, TChain } from '@/data/EIP155Data'
|
import { EIP155_CHAINS, EIP155_SIGNING_METHODS, TEIP155Chain } from '@/data/EIP155Data'
|
||||||
import ModalStore from '@/store/ModalStore'
|
import ModalStore from '@/store/ModalStore'
|
||||||
import { getSignMessage } from '@/utils/HelperUtil'
|
import { approveEIP155Request, rejectEIP155Request } from '@/utils/RequestHandlerUtil'
|
||||||
|
import { walletConnectClient } from '@/utils/WalletConnectUtil'
|
||||||
import { wallet } from '@/utils/WalletUtil'
|
import { wallet } from '@/utils/WalletUtil'
|
||||||
import { Avatar, Button, Col, Container, Divider, Link, Modal, Row, Text } from '@nextui-org/react'
|
import { Avatar, Button, Col, Container, Divider, Link, Modal, Row, Text } from '@nextui-org/react'
|
||||||
|
import { utils } from 'ethers'
|
||||||
import { Fragment } from 'react'
|
import { Fragment } from 'react'
|
||||||
|
|
||||||
export default function SessionRequestModal() {
|
export default function SessionSignModal() {
|
||||||
// Get request and wallet data from store
|
// Get request and wallet data from store
|
||||||
const request = ModalStore.state.data?.request
|
const requestEvent = ModalStore.state.data?.requestEvent
|
||||||
const requestSession = ModalStore.state.data?.requestSession
|
const requestSession = ModalStore.state.data?.requestSession
|
||||||
|
|
||||||
// Ensure request and wallet are defined
|
// Ensure request and wallet are defined
|
||||||
if (!request || !requestSession) {
|
if (!requestEvent || !requestSession) {
|
||||||
return <Text>Missing request data</Text>
|
return <Text>Missing request data</Text>
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get required request data
|
// Get required request data
|
||||||
const { chainId } = request
|
const { chainId } = requestEvent
|
||||||
const { method, params } = request.request
|
const { method, params } = requestEvent.request
|
||||||
const { protocol } = requestSession.relay
|
const { protocol } = requestSession.relay
|
||||||
const { name, icons, url } = requestSession.peer.metadata
|
const { name, icons, url } = requestSession.peer.metadata
|
||||||
|
|
||||||
|
// Get message as utf string
|
||||||
|
let message = method === EIP155_SIGNING_METHODS.PERSONAL_SIGN ? params[0] : params[1]
|
||||||
|
if (utils.isHexString(message)) {
|
||||||
|
message = utils.toUtf8String(message)
|
||||||
|
}
|
||||||
|
|
||||||
// Handle approve action (logic varies based on request method)
|
// Handle approve action (logic varies based on request method)
|
||||||
async function onApprove() {
|
async function onApprove() {
|
||||||
// Handle sign requests
|
if (requestEvent) {
|
||||||
if (['eth_sign', 'personal_sign'].includes(method)) {
|
const response = await approveEIP155Request(requestEvent.request, wallet)
|
||||||
const message = getSignMessage(params, wallet.address)
|
await walletConnectClient.respond({
|
||||||
const signedMessage = wallet.signMessage(message)
|
topic: requestEvent.topic,
|
||||||
|
response
|
||||||
|
})
|
||||||
|
ModalStore.close()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle reject action
|
// Handle reject action
|
||||||
async function onReject() {}
|
async function onReject() {
|
||||||
|
if (requestEvent) {
|
||||||
|
const response = rejectEIP155Request(requestEvent.request)
|
||||||
|
await walletConnectClient.respond({
|
||||||
|
topic: requestEvent.topic,
|
||||||
|
response
|
||||||
|
})
|
||||||
|
ModalStore.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
@ -56,7 +76,18 @@ export default function SessionRequestModal() {
|
|||||||
<Row>
|
<Row>
|
||||||
<Col>
|
<Col>
|
||||||
<Text h5>Blockchain</Text>
|
<Text h5>Blockchain</Text>
|
||||||
<Text color="$gray400">{MAINNET_CHAINS[chainId as TChain]?.name ?? chainId}</Text>
|
<Text color="$gray400">
|
||||||
|
{EIP155_CHAINS[chainId as TEIP155Chain]?.name ?? chainId}
|
||||||
|
</Text>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
|
||||||
|
<Divider y={2} />
|
||||||
|
|
||||||
|
<Row>
|
||||||
|
<Col>
|
||||||
|
<Text h5>Message</Text>
|
||||||
|
<Text color="$gray400">{message}</Text>
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
|
|
@ -417,6 +417,21 @@
|
|||||||
resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45"
|
resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45"
|
||||||
integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==
|
integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==
|
||||||
|
|
||||||
|
"@json-rpc-tools/types@^1.7.6":
|
||||||
|
version "1.7.6"
|
||||||
|
resolved "https://registry.yarnpkg.com/@json-rpc-tools/types/-/types-1.7.6.tgz#5abd5fde01364a130c46093b501715bcce5bdc0e"
|
||||||
|
integrity sha512-nDSqmyRNEqEK9TZHtM15uNnDljczhCUdBmRhpNZ95bIPKEDQ+nTDmGMFd2lLin3upc5h2VVVd9tkTDdbXUhDIQ==
|
||||||
|
dependencies:
|
||||||
|
keyvaluestorage-interface "^1.0.0"
|
||||||
|
|
||||||
|
"@json-rpc-tools/utils@1.7.6":
|
||||||
|
version "1.7.6"
|
||||||
|
resolved "https://registry.yarnpkg.com/@json-rpc-tools/utils/-/utils-1.7.6.tgz#67f04987dbaa2e7adb6adff1575367b75a9a9ba1"
|
||||||
|
integrity sha512-HjA8x/U/Q78HRRe19yh8HVKoZ+Iaoo3YZjakJYxR+rw52NHo6jM+VE9b8+7ygkCFXl/EHID5wh/MkXaE/jGyYw==
|
||||||
|
dependencies:
|
||||||
|
"@json-rpc-tools/types" "^1.7.6"
|
||||||
|
"@pedrouid/environment" "^1.0.1"
|
||||||
|
|
||||||
"@next/env@12.0.10":
|
"@next/env@12.0.10":
|
||||||
version "12.0.10"
|
version "12.0.10"
|
||||||
resolved "https://registry.yarnpkg.com/@next/env/-/env-12.0.10.tgz#561640fd62279218ccd2798ae907bae8d94a7730"
|
resolved "https://registry.yarnpkg.com/@next/env/-/env-12.0.10.tgz#561640fd62279218ccd2798ae907bae8d94a7730"
|
||||||
@ -517,6 +532,11 @@
|
|||||||
"@nodelib/fs.scandir" "2.1.5"
|
"@nodelib/fs.scandir" "2.1.5"
|
||||||
fastq "^1.6.0"
|
fastq "^1.6.0"
|
||||||
|
|
||||||
|
"@pedrouid/environment@^1.0.1":
|
||||||
|
version "1.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/@pedrouid/environment/-/environment-1.0.1.tgz#858f0f8a057340e0b250398b75ead77d6f4342ec"
|
||||||
|
integrity sha512-HaW78NszGzRZd9SeoI3JD11JqY+lubnaOx7Pewj5pfjqWXOEATpeKIFb9Z4t2WBUK2iryiXX3lzWwmYWgUL0Ug==
|
||||||
|
|
||||||
"@react-aria/focus@3.5.0":
|
"@react-aria/focus@3.5.0":
|
||||||
version "3.5.0"
|
version "3.5.0"
|
||||||
resolved "https://registry.yarnpkg.com/@react-aria/focus/-/focus-3.5.0.tgz#02b85f97d6114af1eccc0902ce40723b626cb7f9"
|
resolved "https://registry.yarnpkg.com/@react-aria/focus/-/focus-3.5.0.tgz#02b85f97d6114af1eccc0902ce40723b626cb7f9"
|
||||||
|
Loading…
Reference in New Issue
Block a user