Refactor wallet into util, restore from mnemonic, prep for session page
This commit is contained in:
parent
4a95f9edbd
commit
de05b8c82c
@ -19,13 +19,13 @@
|
|||||||
"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.2.12"
|
"valtio": "1.3.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@walletconnect/types": "2.0.0-beta.22",
|
"@walletconnect/types": "2.0.0-beta.22",
|
||||||
"@types/node": "17.0.17",
|
"@types/node": "17.0.17",
|
||||||
"@types/react": "17.0.39",
|
"@types/react": "17.0.39",
|
||||||
"eslint": "8.8.0",
|
"eslint": "8.9.0",
|
||||||
"eslint-config-next": "12.0.10",
|
"eslint-config-next": "12.0.10",
|
||||||
"eslint-config-prettier": "8.3.0",
|
"eslint-config-prettier": "8.3.0",
|
||||||
"prettier": "2.5.1",
|
"prettier": "2.5.1",
|
||||||
|
@ -12,6 +12,7 @@ export default function AccountCard({ name, logo, rgb, address }: Props) {
|
|||||||
return (
|
return (
|
||||||
<Card
|
<Card
|
||||||
bordered
|
bordered
|
||||||
|
clickable
|
||||||
borderWeight="light"
|
borderWeight="light"
|
||||||
css={{
|
css={{
|
||||||
borderColor: `rgba(${rgb}, 0.4)`,
|
borderColor: `rgba(${rgb}, 0.4)`,
|
||||||
|
@ -3,10 +3,19 @@
|
|||||||
* @url https://chainlist.org
|
* @url https://chainlist.org
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export type CHAIN = keyof typeof MAINNET_CHAINS
|
/**
|
||||||
|
* Types
|
||||||
|
*/
|
||||||
|
export type TChain = keyof typeof MAINNET_CHAINS
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utilities
|
||||||
|
*/
|
||||||
export const LOGO_BASE_URL = 'https://blockchain-api.xyz/logos/'
|
export const LOGO_BASE_URL = 'https://blockchain-api.xyz/logos/'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Chains
|
||||||
|
*/
|
||||||
export const MAINNET_CHAINS = {
|
export const MAINNET_CHAINS = {
|
||||||
'eip155:1': {
|
'eip155:1': {
|
||||||
chainId: 1,
|
chainId: 1,
|
||||||
@ -33,3 +42,15 @@ export const MAINNET_CHAINS = {
|
|||||||
rgb: '44, 55, 75'
|
rgb: '44, 55, 75'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Methods
|
||||||
|
*/
|
||||||
|
export const SIGNING_METHODS = {
|
||||||
|
PERSONAL_SIGN: 'personal_sign',
|
||||||
|
SEND_TRANSACTION: 'eth_sendTransaction',
|
||||||
|
SIGN: 'eth_sign',
|
||||||
|
SIGN_TRANSACTION: 'eth_signTransaction',
|
||||||
|
SIGN_TYPED_DATA: 'eth_signTypedData',
|
||||||
|
SIGN_TYPED_DATA_V4: 'eth_signTypedData_v4'
|
||||||
|
}
|
@ -1,5 +1,5 @@
|
|||||||
import WalletStore from '@/store/WalletStore'
|
import { createWalletConnectClient } from '@/utils/WalletConnectUtil'
|
||||||
import { createClient } from '@/utils/WalletConnectUtil'
|
import { createOrRestoreWallet } from '@/utils/WalletUtil'
|
||||||
import { useCallback, useEffect, useState } from 'react'
|
import { useCallback, useEffect, useState } from 'react'
|
||||||
|
|
||||||
export default function useInitialization() {
|
export default function useInitialization() {
|
||||||
@ -7,8 +7,8 @@ export default function useInitialization() {
|
|||||||
|
|
||||||
const onInitialize = useCallback(async () => {
|
const onInitialize = useCallback(async () => {
|
||||||
try {
|
try {
|
||||||
WalletStore.createWallet()
|
createOrRestoreWallet()
|
||||||
await createClient()
|
await createWalletConnectClient()
|
||||||
setInitialized(true)
|
setInitialized(true)
|
||||||
} catch (err: unknown) {
|
} catch (err: unknown) {
|
||||||
alert(err)
|
alert(err)
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import ModalStore from '@/store/ModalStore'
|
import ModalStore from '@/store/ModalStore'
|
||||||
import { client } from '@/utils/WalletConnectUtil'
|
import { walletConnectClient } from '@/utils/WalletConnectUtil'
|
||||||
import { CLIENT_EVENTS } from '@walletconnect/client'
|
import { CLIENT_EVENTS } from '@walletconnect/client'
|
||||||
import { SessionTypes } from '@walletconnect/types'
|
import { SessionTypes } from '@walletconnect/types'
|
||||||
import { useCallback, useEffect } from 'react'
|
import { useCallback, useEffect } from 'react'
|
||||||
@ -10,24 +10,24 @@ export default function useWalletConnectEventsManager(initialized: boolean) {
|
|||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
const onSessionCreated = useCallback((created: SessionTypes.Created) => {
|
const onSessionCreated = useCallback((created: SessionTypes.Created) => {
|
||||||
// TODO show successful feedback here
|
// TODO show successful connection feedback here
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
const onSessionRequest = useCallback(async (request: SessionTypes.RequestEvent) => {
|
const onSessionRequest = useCallback(async (request: SessionTypes.RequestEvent) => {
|
||||||
const requestSession = await client?.session.get(request.topic)
|
const requestSession = await walletConnectClient.session.get(request.topic)
|
||||||
ModalStore.open('SessionRequestModal', { request, requestSession })
|
ModalStore.open('SessionRequestModal', { request, requestSession })
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (initialized && client) {
|
if (initialized) {
|
||||||
// 1. Open session proposal modal for confirmation / rejection
|
// 1. Open session proposal modal for confirmation / rejection
|
||||||
client.on(CLIENT_EVENTS.session.proposal, onSessionProposal)
|
walletConnectClient.on(CLIENT_EVENTS.session.proposal, onSessionProposal)
|
||||||
|
|
||||||
// 2. Open session created modal to show success feedback
|
// 2. Open session created modal to show success feedback
|
||||||
client.on(CLIENT_EVENTS.session.created, onSessionCreated)
|
walletConnectClient.on(CLIENT_EVENTS.session.created, onSessionCreated)
|
||||||
|
|
||||||
// 3. Open rpc request handling modal
|
// 3. Open rpc request handling modal
|
||||||
client.on(CLIENT_EVENTS.session.request, onSessionRequest)
|
walletConnectClient.on(CLIENT_EVENTS.session.request, onSessionRequest)
|
||||||
}
|
}
|
||||||
}, [initialized, onSessionProposal, onSessionCreated, onSessionRequest])
|
}, [initialized, onSessionProposal, onSessionCreated, onSessionRequest])
|
||||||
}
|
}
|
||||||
|
@ -1,17 +1,10 @@
|
|||||||
import AccountCard from '@/components/AccountCard'
|
import AccountCard from '@/components/AccountCard'
|
||||||
import PageHeader from '@/components/PageHeader'
|
import PageHeader from '@/components/PageHeader'
|
||||||
import WalletStore from '@/store/WalletStore'
|
import { MAINNET_CHAINS } from '@/data/EIP155Data'
|
||||||
import { MAINNET_CHAINS } from '@/utils/EIP155ChainsUtil'
|
import { wallet } from '@/utils/WalletUtil'
|
||||||
import { Fragment } from 'react'
|
import { Fragment } from 'react'
|
||||||
import { useSnapshot } from 'valtio'
|
|
||||||
|
|
||||||
export default function HomePage() {
|
export default function HomePage() {
|
||||||
const { wallet } = useSnapshot(WalletStore.state)
|
|
||||||
|
|
||||||
if (!wallet) {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
<PageHeader>Accounts</PageHeader>
|
<PageHeader>Accounts</PageHeader>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import PageHeader from '@/components/PageHeader'
|
import PageHeader from '@/components/PageHeader'
|
||||||
import WalletStore from '@/store/WalletStore'
|
import { wallet } from '@/utils/WalletUtil'
|
||||||
import { Card, Divider, Row, Switch, Text } from '@nextui-org/react'
|
import { Card, Divider, Row, Switch, Text } from '@nextui-org/react'
|
||||||
import { Fragment } from 'react'
|
import { Fragment } from 'react'
|
||||||
|
|
||||||
@ -11,7 +11,7 @@ export default function SettingsPage() {
|
|||||||
Mnemonic
|
Mnemonic
|
||||||
</Text>
|
</Text>
|
||||||
<Card bordered borderWeight="light">
|
<Card bordered borderWeight="light">
|
||||||
<Text css={{ fontFamily: '$mono' }}>{WalletStore.state.wallet?.mnemonic.phrase}</Text>
|
<Text css={{ fontFamily: '$mono' }}>{wallet.mnemonic.phrase}</Text>
|
||||||
</Card>
|
</Card>
|
||||||
|
|
||||||
<Text css={{ color: '$yellow500', marginTop: '$5', textAlign: 'center' }}>
|
<Text css={{ color: '$yellow500', marginTop: '$5', textAlign: 'center' }}>
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import PageHeader from '@/components/PageHeader'
|
import PageHeader from '@/components/PageHeader'
|
||||||
import QrReader from '@/components/QrReader'
|
import QrReader from '@/components/QrReader'
|
||||||
import { client } from '@/utils/WalletConnectUtil'
|
import { walletConnectClient } from '@/utils/WalletConnectUtil'
|
||||||
import { Button, Input, Loading, Text } from '@nextui-org/react'
|
import { Button, Input, Loading, Text } from '@nextui-org/react'
|
||||||
import { Fragment, useState } from 'react'
|
import { Fragment, useState } from 'react'
|
||||||
|
|
||||||
@ -11,7 +11,7 @@ export default function WalletConnectPage() {
|
|||||||
async function onConnect(uri: string) {
|
async function onConnect(uri: string) {
|
||||||
try {
|
try {
|
||||||
setLoading(true)
|
setLoading(true)
|
||||||
await client?.pair({ uri })
|
await walletConnectClient.pair({ uri })
|
||||||
} catch (err: unknown) {
|
} catch (err: unknown) {
|
||||||
alert(err)
|
alert(err)
|
||||||
} finally {
|
} finally {
|
||||||
|
@ -1,29 +0,0 @@
|
|||||||
import { Wallet } from 'ethers'
|
|
||||||
import { proxy } from 'valtio'
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Types
|
|
||||||
*/
|
|
||||||
interface State {
|
|
||||||
wallet?: Wallet
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* State
|
|
||||||
*/
|
|
||||||
const state = proxy<State>({
|
|
||||||
wallet: undefined
|
|
||||||
})
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Store / Actions
|
|
||||||
*/
|
|
||||||
const WalletStore = {
|
|
||||||
state,
|
|
||||||
|
|
||||||
createWallet() {
|
|
||||||
state.wallet = Wallet.createRandom()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default WalletStore
|
|
@ -1,3 +1,6 @@
|
|||||||
|
/**
|
||||||
|
* Truncates string (in the middle) via given lenght value
|
||||||
|
*/
|
||||||
export function truncate(value: string, length: number) {
|
export function truncate(value: string, length: number) {
|
||||||
if (value.length <= length) {
|
if (value.length <= length) {
|
||||||
return value
|
return value
|
||||||
@ -10,3 +13,14 @@ export function truncate(value: string, length: number) {
|
|||||||
|
|
||||||
return value.substring(0, frontLength) + separator + value.substring(value.length - backLength)
|
return value.substring(0, frontLength) + separator + value.substring(value.length - backLength)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helps to get message from various sign methods present in eth
|
||||||
|
* @details https://docs.metamask.io/guide/signing-data.html#a-brief-history
|
||||||
|
*/
|
||||||
|
export function getSignMessage(params: string[], walletAddress: string) {
|
||||||
|
// Remove our own address from params, so we are left with message
|
||||||
|
params.filter(p => p !== walletAddress)
|
||||||
|
|
||||||
|
return params[0]
|
||||||
|
}
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
import WalletConnectClient from '@walletconnect/client'
|
import WalletConnectClient from '@walletconnect/client'
|
||||||
|
|
||||||
export let client: WalletConnectClient | undefined = undefined
|
export let walletConnectClient: WalletConnectClient
|
||||||
|
|
||||||
export async function createClient() {
|
export async function createWalletConnectClient() {
|
||||||
client = await WalletConnectClient.init({
|
walletConnectClient = await WalletConnectClient.init({
|
||||||
controller: true,
|
controller: true,
|
||||||
projectId: '8f331b9812e0e5b8f2da2c7203624869',
|
projectId: '8f331b9812e0e5b8f2da2c7203624869',
|
||||||
relayUrl: 'wss://relay.walletconnect.com',
|
relayUrl: 'wss://relay.walletconnect.com',
|
||||||
|
17
wallets/react-wallet-v2/src/utils/WalletUtil.ts
Normal file
17
wallets/react-wallet-v2/src/utils/WalletUtil.ts
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
import { Wallet } from 'ethers'
|
||||||
|
|
||||||
|
const STORAGE_KEY = 'WALLET_MNEMONIC'
|
||||||
|
|
||||||
|
export let wallet: Wallet
|
||||||
|
|
||||||
|
export function createOrRestoreWallet() {
|
||||||
|
const mnemonic = localStorage.getItem(STORAGE_KEY)
|
||||||
|
|
||||||
|
if (mnemonic) {
|
||||||
|
wallet = Wallet.fromMnemonic(mnemonic)
|
||||||
|
} else {
|
||||||
|
wallet = Wallet.createRandom()
|
||||||
|
// Don't store mnemonic in local storage in a production project!
|
||||||
|
localStorage.setItem(STORAGE_KEY, wallet.mnemonic.phrase)
|
||||||
|
}
|
||||||
|
}
|
@ -1,14 +1,13 @@
|
|||||||
|
import { MAINNET_CHAINS, TChain } from '@/data/EIP155Data'
|
||||||
import ModalStore from '@/store/ModalStore'
|
import ModalStore from '@/store/ModalStore'
|
||||||
import WalletStore from '@/store/WalletStore'
|
import { walletConnectClient } from '@/utils/WalletConnectUtil'
|
||||||
import { CHAIN, MAINNET_CHAINS } from '@/utils/EIP155ChainsUtil'
|
import { wallet } from '@/utils/WalletUtil'
|
||||||
import { client } from '@/utils/WalletConnectUtil'
|
|
||||||
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 { Fragment } from 'react'
|
import { Fragment } from 'react'
|
||||||
|
|
||||||
export default function SessionProposalModal() {
|
export default function SessionProposalModal() {
|
||||||
// Get proposal data and wallet address from store
|
// Get proposal data and wallet address from store
|
||||||
const proposal = ModalStore.state.data?.proposal
|
const proposal = ModalStore.state.data?.proposal
|
||||||
const address = WalletStore.state.wallet?.address
|
|
||||||
|
|
||||||
// Ensure proposal is defined
|
// Ensure proposal is defined
|
||||||
if (!proposal) {
|
if (!proposal) {
|
||||||
@ -24,21 +23,21 @@ export default function SessionProposalModal() {
|
|||||||
|
|
||||||
// Hanlde approve action
|
// Hanlde approve action
|
||||||
async function onApprove() {
|
async function onApprove() {
|
||||||
if (client && proposal && address) {
|
if (proposal) {
|
||||||
const response = {
|
const response = {
|
||||||
state: {
|
state: {
|
||||||
accounts: chains.map(chain => `${chain}:${address}`)
|
accounts: chains.map(chain => `${chain}:${wallet.address}`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
await client.approve({ proposal, response })
|
await walletConnectClient.approve({ proposal, response })
|
||||||
}
|
}
|
||||||
ModalStore.close()
|
ModalStore.close()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hanlde reject action
|
// Hanlde reject action
|
||||||
async function onReject() {
|
async function onReject() {
|
||||||
if (client && proposal) {
|
if (proposal) {
|
||||||
await client.reject({ proposal })
|
await walletConnectClient.reject({ proposal })
|
||||||
}
|
}
|
||||||
ModalStore.close()
|
ModalStore.close()
|
||||||
}
|
}
|
||||||
@ -67,7 +66,7 @@ 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 CHAIN]?.name ?? chain).join(', ')}
|
{chains.map(chain => MAINNET_CHAINS[chain as TChain]?.name ?? chain).join(', ')}
|
||||||
</Text>
|
</Text>
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
|
import { MAINNET_CHAINS, TChain } from '@/data/EIP155Data'
|
||||||
import ModalStore from '@/store/ModalStore'
|
import ModalStore from '@/store/ModalStore'
|
||||||
import WalletStore from '@/store/WalletStore'
|
import { getSignMessage } from '@/utils/HelperUtil'
|
||||||
import { CHAIN, MAINNET_CHAINS } from '@/utils/EIP155ChainsUtil'
|
import { wallet } from '@/utils/WalletUtil'
|
||||||
import { client } from '@/utils/WalletConnectUtil'
|
|
||||||
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 { Fragment } from 'react'
|
import { Fragment } from 'react'
|
||||||
|
|
||||||
@ -9,23 +9,24 @@ export default function SessionRequestModal() {
|
|||||||
// Get request and wallet data from store
|
// Get request and wallet data from store
|
||||||
const request = ModalStore.state.data?.request
|
const request = ModalStore.state.data?.request
|
||||||
const requestSession = ModalStore.state.data?.requestSession
|
const requestSession = ModalStore.state.data?.requestSession
|
||||||
const { wallet } = WalletStore.state
|
|
||||||
|
|
||||||
// Ensure request and wallet are defined
|
// Ensure request and wallet are defined
|
||||||
if (!request || !requestSession || !wallet) {
|
if (!request || !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 } = request
|
||||||
const { method } = request.request
|
const { method, params } = request.request
|
||||||
const { protocol } = requestSession.relay
|
const { protocol } = requestSession.relay
|
||||||
const { name, icons, url } = requestSession.peer.metadata
|
const { name, icons, url } = requestSession.peer.metadata
|
||||||
|
|
||||||
// Handle approve action (logic varies based on request method)
|
// Handle approve action (logic varies based on request method)
|
||||||
async function onApprove() {
|
async function onApprove() {
|
||||||
if (client && wallet) {
|
// Handle sign requests
|
||||||
// TODO figure out how to sign different personal messages correctly with ethers
|
if (['eth_sign', 'personal_sign'].includes(method)) {
|
||||||
|
const message = getSignMessage(params, wallet.address)
|
||||||
|
const signedMessage = wallet.signMessage(message)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -55,7 +56,7 @@ export default function SessionRequestModal() {
|
|||||||
<Row>
|
<Row>
|
||||||
<Col>
|
<Col>
|
||||||
<Text h5>Blockchain</Text>
|
<Text h5>Blockchain</Text>
|
||||||
<Text color="$gray400">{MAINNET_CHAINS[chainId as CHAIN]?.name ?? chainId}</Text>
|
<Text color="$gray400">{MAINNET_CHAINS[chainId as TChain]?.name ?? chainId}</Text>
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
|
|
||||||
|
@ -43,14 +43,14 @@
|
|||||||
resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.7.4.tgz#19bf0f5af19149111c40d98bb0cf82119f5d9eeb"
|
resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.7.4.tgz#19bf0f5af19149111c40d98bb0cf82119f5d9eeb"
|
||||||
integrity sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==
|
integrity sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==
|
||||||
|
|
||||||
"@eslint/eslintrc@^1.0.5":
|
"@eslint/eslintrc@^1.1.0":
|
||||||
version "1.0.5"
|
version "1.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.0.5.tgz#33f1b838dbf1f923bfa517e008362b78ddbbf318"
|
resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.1.0.tgz#583d12dbec5d4f22f333f9669f7d0b7c7815b4d3"
|
||||||
integrity sha512-BLxsnmK3KyPunz5wmCCpqy0YelEoxxGmH73Is+Z74oOTMtExcjkr3dDR6quwrjh1YspA8DH9gnX1o069KiS9AQ==
|
integrity sha512-C1DfL7XX4nPqGd6jcP01W9pVM1HYCuUkFk1432D7F0v3JSlUIeOYn9oCoi3eoLZ+iwBSb29BMFxxny0YrrEZqg==
|
||||||
dependencies:
|
dependencies:
|
||||||
ajv "^6.12.4"
|
ajv "^6.12.4"
|
||||||
debug "^4.3.2"
|
debug "^4.3.2"
|
||||||
espree "^9.2.0"
|
espree "^9.3.1"
|
||||||
globals "^13.9.0"
|
globals "^13.9.0"
|
||||||
ignore "^4.0.6"
|
ignore "^4.0.6"
|
||||||
import-fresh "^3.2.1"
|
import-fresh "^3.2.1"
|
||||||
@ -1465,10 +1465,10 @@ eslint-plugin-react@^7.27.0:
|
|||||||
semver "^6.3.0"
|
semver "^6.3.0"
|
||||||
string.prototype.matchall "^4.0.6"
|
string.prototype.matchall "^4.0.6"
|
||||||
|
|
||||||
eslint-scope@^7.1.0:
|
eslint-scope@^7.1.1:
|
||||||
version "7.1.0"
|
version "7.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.1.0.tgz#c1f6ea30ac583031f203d65c73e723b01298f153"
|
resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.1.1.tgz#fff34894c2f65e5226d3041ac480b4513a163642"
|
||||||
integrity sha512-aWwkhnS0qAXqNOgKOK0dJ2nvzEbhEvpy8OlJ9kZ0FeZnA6zpjv1/Vei+puGFFX7zkPCkHHXb7IDX3A+7yPrRWg==
|
integrity sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==
|
||||||
dependencies:
|
dependencies:
|
||||||
esrecurse "^4.3.0"
|
esrecurse "^4.3.0"
|
||||||
estraverse "^5.2.0"
|
estraverse "^5.2.0"
|
||||||
@ -1485,17 +1485,22 @@ eslint-visitor-keys@^2.0.0:
|
|||||||
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz#f65328259305927392c938ed44eb0a5c9b2bd303"
|
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz#f65328259305927392c938ed44eb0a5c9b2bd303"
|
||||||
integrity sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==
|
integrity sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==
|
||||||
|
|
||||||
eslint-visitor-keys@^3.0.0, eslint-visitor-keys@^3.1.0, eslint-visitor-keys@^3.2.0:
|
eslint-visitor-keys@^3.0.0:
|
||||||
version "3.2.0"
|
version "3.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.2.0.tgz#6fbb166a6798ee5991358bc2daa1ba76cc1254a1"
|
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.2.0.tgz#6fbb166a6798ee5991358bc2daa1ba76cc1254a1"
|
||||||
integrity sha512-IOzT0X126zn7ALX0dwFiUQEdsfzrm4+ISsQS8nukaJXwEyYKRSnEIIDULYg1mCtGp7UUXgfGl7BIolXREQK+XQ==
|
integrity sha512-IOzT0X126zn7ALX0dwFiUQEdsfzrm4+ISsQS8nukaJXwEyYKRSnEIIDULYg1mCtGp7UUXgfGl7BIolXREQK+XQ==
|
||||||
|
|
||||||
eslint@8.8.0:
|
eslint-visitor-keys@^3.3.0:
|
||||||
version "8.8.0"
|
version "3.3.0"
|
||||||
resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.8.0.tgz#9762b49abad0cb4952539ffdb0a046392e571a2d"
|
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz#f6480fa6b1f30efe2d1968aa8ac745b862469826"
|
||||||
integrity sha512-H3KXAzQGBH1plhYS3okDix2ZthuYJlQQEGE5k0IKuEqUSiyu4AmxxlJ2MtTYeJ3xB4jDhcYCwGOg2TXYdnDXlQ==
|
integrity sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==
|
||||||
|
|
||||||
|
eslint@8.9.0:
|
||||||
|
version "8.9.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.9.0.tgz#a2a8227a99599adc4342fd9b854cb8d8d6412fdb"
|
||||||
|
integrity sha512-PB09IGwv4F4b0/atrbcMFboF/giawbBLVC7fyDamk5Wtey4Jh2K+rYaBhCAbUyEI4QzB1ly09Uglc9iCtFaG2Q==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@eslint/eslintrc" "^1.0.5"
|
"@eslint/eslintrc" "^1.1.0"
|
||||||
"@humanwhocodes/config-array" "^0.9.2"
|
"@humanwhocodes/config-array" "^0.9.2"
|
||||||
ajv "^6.10.0"
|
ajv "^6.10.0"
|
||||||
chalk "^4.0.0"
|
chalk "^4.0.0"
|
||||||
@ -1503,10 +1508,10 @@ eslint@8.8.0:
|
|||||||
debug "^4.3.2"
|
debug "^4.3.2"
|
||||||
doctrine "^3.0.0"
|
doctrine "^3.0.0"
|
||||||
escape-string-regexp "^4.0.0"
|
escape-string-regexp "^4.0.0"
|
||||||
eslint-scope "^7.1.0"
|
eslint-scope "^7.1.1"
|
||||||
eslint-utils "^3.0.0"
|
eslint-utils "^3.0.0"
|
||||||
eslint-visitor-keys "^3.2.0"
|
eslint-visitor-keys "^3.3.0"
|
||||||
espree "^9.3.0"
|
espree "^9.3.1"
|
||||||
esquery "^1.4.0"
|
esquery "^1.4.0"
|
||||||
esutils "^2.0.2"
|
esutils "^2.0.2"
|
||||||
fast-deep-equal "^3.1.3"
|
fast-deep-equal "^3.1.3"
|
||||||
@ -1531,14 +1536,14 @@ eslint@8.8.0:
|
|||||||
text-table "^0.2.0"
|
text-table "^0.2.0"
|
||||||
v8-compile-cache "^2.0.3"
|
v8-compile-cache "^2.0.3"
|
||||||
|
|
||||||
espree@^9.2.0, espree@^9.3.0:
|
espree@^9.3.1:
|
||||||
version "9.3.0"
|
version "9.3.1"
|
||||||
resolved "https://registry.yarnpkg.com/espree/-/espree-9.3.0.tgz#c1240d79183b72aaee6ccfa5a90bc9111df085a8"
|
resolved "https://registry.yarnpkg.com/espree/-/espree-9.3.1.tgz#8793b4bc27ea4c778c19908e0719e7b8f4115bcd"
|
||||||
integrity sha512-d/5nCsb0JcqsSEeQzFZ8DH1RmxPcglRWh24EFTlUEmCKoehXGdpsx0RkHDubqUI8LSAIKMQp4r9SzQ3n+sm4HQ==
|
integrity sha512-bvdyLmJMfwkV3NCRl5ZhJf22zBFo1y8bYh3VYb+bfzqNB4Je68P2sSuXyuFquzWLebHpNd2/d5uv7yoP9ISnGQ==
|
||||||
dependencies:
|
dependencies:
|
||||||
acorn "^8.7.0"
|
acorn "^8.7.0"
|
||||||
acorn-jsx "^5.3.1"
|
acorn-jsx "^5.3.1"
|
||||||
eslint-visitor-keys "^3.1.0"
|
eslint-visitor-keys "^3.3.0"
|
||||||
|
|
||||||
esquery@^1.4.0:
|
esquery@^1.4.0:
|
||||||
version "1.4.0"
|
version "1.4.0"
|
||||||
@ -3116,10 +3121,10 @@ v8-compile-cache@^2.0.3:
|
|||||||
resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee"
|
resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee"
|
||||||
integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==
|
integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==
|
||||||
|
|
||||||
valtio@1.2.12:
|
valtio@1.3.0:
|
||||||
version "1.2.12"
|
version "1.3.0"
|
||||||
resolved "https://registry.yarnpkg.com/valtio/-/valtio-1.2.12.tgz#14f46f6c90b63c6e4176831c68ab9b729fea38ee"
|
resolved "https://registry.yarnpkg.com/valtio/-/valtio-1.3.0.tgz#b83cfcca8455940119738659946565d5c0389af8"
|
||||||
integrity sha512-TlQkbSma4aAAgs6tQXrvGilMZBVH0q8gbbWxRbo2R43FhkW4lWi45f9jC6gAdJdC40bsNnYyBsYDB9OOKNlqSw==
|
integrity sha512-wsE6EDIkt+CNZPNHOxNVzoi026Fyt6ZRT750etZCAvrndcdT3N7Z+SSV4kJQdCwl5gNxsnU4BhP1wFS7cu21oA==
|
||||||
dependencies:
|
dependencies:
|
||||||
proxy-compare "2.0.2"
|
proxy-compare "2.0.2"
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user