diff --git a/examples/web2login-demo/.gitignore b/examples/web2login-demo/.gitignore new file mode 100644 index 0000000..a547bf3 --- /dev/null +++ b/examples/web2login-demo/.gitignore @@ -0,0 +1,24 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/examples/web2login-demo/README.md b/examples/web2login-demo/README.md new file mode 100644 index 0000000..99613fc --- /dev/null +++ b/examples/web2login-demo/README.md @@ -0,0 +1,28 @@ +## Usage + +```bash +$ npm install # or pnpm install or yarn install +``` + +### Learn more on the [Solid Website](https://solidjs.com) and come chat with us on our [Discord](https://discord.com/invite/solidjs) + +## Available Scripts + +In the project directory, you can run: + +### `npm run dev` + +Runs the app in the development mode.
+Open [http://localhost:5173](http://localhost:5173) to view it in the browser. + +### `npm run build` + +Builds the app for production to the `dist` folder.
+It correctly bundles Solid in production mode and optimizes the build for the best performance. + +The build is minified and the filenames include the hashes.
+Your app is ready to be deployed! + +## Deployment + +Learn more about deploying your application with the [documentations](https://vitejs.dev/guide/static-deploy.html) diff --git a/examples/web2login-demo/index.html b/examples/web2login-demo/index.html new file mode 100644 index 0000000..601bfa5 --- /dev/null +++ b/examples/web2login-demo/index.html @@ -0,0 +1,13 @@ + + + + + + + JoyID Web2Login Demo + + +
+ + + diff --git a/examples/web2login-demo/package.json b/examples/web2login-demo/package.json new file mode 100644 index 0000000..f3e4f0c --- /dev/null +++ b/examples/web2login-demo/package.json @@ -0,0 +1,23 @@ +{ + "name": "web2login-demo", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "vite --host --open", + "build": "tsc && vite build", + "preview": "vite preview" + }, + "dependencies": { + "@joyid/evm": "workspace:*", + "@solid-primitives/clipboard": "^1.5.4", + "@vitejs/plugin-basic-ssl": "^1.1.0", + "solid-js": "^1.8.15", + "solid-toast": "^0.5.0" + }, + "devDependencies": { + "typescript": "^5.2.2", + "vite": "^5.2.0", + "vite-plugin-solid": "^2.10.2" + } +} diff --git a/examples/web2login-demo/public/joyid.svg b/examples/web2login-demo/public/joyid.svg new file mode 100644 index 0000000..4722452 --- /dev/null +++ b/examples/web2login-demo/public/joyid.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/examples/web2login-demo/src/App.css b/examples/web2login-demo/src/App.css new file mode 100644 index 0000000..613607d --- /dev/null +++ b/examples/web2login-demo/src/App.css @@ -0,0 +1,27 @@ +#root { + max-width: 1280px; + margin: 0 auto; + padding: 2rem; + text-align: center; +} + +.logo { + height: 6em; + padding: 1.5em; + will-change: filter; + transition: filter 300ms; +} +.logo:hover { + filter: drop-shadow(0 0 2em #646cffaa); +} +.logo.solid:hover { + filter: drop-shadow(0 0 2em #61dafbaa); +} + +.card { + padding: 2em; +} + +.read-the-docs { + color: #888; +} diff --git a/examples/web2login-demo/src/App.tsx b/examples/web2login-demo/src/App.tsx new file mode 100644 index 0000000..8ba65dd --- /dev/null +++ b/examples/web2login-demo/src/App.tsx @@ -0,0 +1,89 @@ +import { Show, createSignal } from 'solid-js' +import { writeClipboard } from '@solid-primitives/clipboard' +import { Toaster } from 'solid-toast' +import toast from 'solid-toast' + +import { buildRedirectUrl } from './utils' +import { + initConfig, + connect, + connectWithRedirect, + connectCallback, +} from '@joyid/evm/web2login' + +import joyidLogo from './assets/joyid.svg' +import './App.css' + +declare let isProd: boolean +let _IsProd: boolean = false + +function App() { + try { + _IsProd = isProd + } catch (e) { + /* empty */ + } + + initConfig({ + backgroundImage: `center center / cover no-repeat url("https://images.unsplash.com/photo-1601314167099-232775b3d6fd?q=80&w=2072&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D")`, + joyidAppURL: _IsProd ? 'https://app.joy.id' : 'https://testnet.joyid.dev', + }) + + const [address, setAddress] = createSignal('') + + try { + setAddress(connectCallback().uid) + } catch (error) { + // TODO: handle error + } + + function onConnectRedirect() { + const url = buildRedirectUrl('connect') + connectWithRedirect(url) + } + + const onConnectPopup = async () => { + console.log('onConnectPopup') + const { uid } = await connect() + console.log('address', uid) + setAddress(uid) + } + + const onCopyAddress = async () => { + await writeClipboard(address()) + toast.success('Copied Successfully!', { + position: 'bottom-center', + }) + } + + return ( + <> + +
+ + + +
+

JoyID Web2Login Demo

+ +

Address: {address()}

+ +
+
+ + + +

+ Edit src/App.tsx and save to test HMR +

+
+

Click on the JoyID logos to learn more

+ + ) +} + +export default App diff --git a/examples/web2login-demo/src/assets/joyid.svg b/examples/web2login-demo/src/assets/joyid.svg new file mode 100644 index 0000000..4722452 --- /dev/null +++ b/examples/web2login-demo/src/assets/joyid.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/examples/web2login-demo/src/chains/chains.json b/examples/web2login-demo/src/chains/chains.json new file mode 100644 index 0000000..de0daf5 --- /dev/null +++ b/examples/web2login-demo/src/chains/chains.json @@ -0,0 +1,34 @@ +[ + { + "name": "Ethereum Sepolia", + "chainId": 11155111, + "rpcURL": "https://ethereum-sepolia.blockpi.network/v1/rpc/public", + "unit": "ETH", + "explorer": "https://sepolia.etherscan.io", + "faucet": "https://sepoliafaucet.com" + }, + { + "name": "BNB Testnet", + "chainId": 97, + "rpcURL": "https://bsc-testnet.blockpi.network/v1/rpc/public", + "unit": "BNB", + "explorer": "https://testnet.bscscan.com", + "faucet": "https://testnet.bnbchain.org/faucet-smart" + }, + { + "name": "Avalanche Fuji", + "chainId": 43113, + "rpcURL": "https://avalanche-fuji.blockpi.network/v1/rpc/public", + "unit": "AVAX", + "explorer": "https://testnet.snowtrace.io", + "faucet": "https://core.app/tools/testnet-faucet/?subnet=c&token=c" + }, + { + "name": "Polygon Mumbai", + "chainId": 80001, + "rpcURL": "https://polygon-mumbai.blockpi.network/v1/rpc/public", + "unit": "MATIC", + "explorer": "https://mumbai.polygonscan.com", + "faucet": "https://mumbaifaucet.com" + } +] diff --git a/examples/web2login-demo/src/chains/index.ts b/examples/web2login-demo/src/chains/index.ts new file mode 100644 index 0000000..117da3c --- /dev/null +++ b/examples/web2login-demo/src/chains/index.ts @@ -0,0 +1,18 @@ +import chainList from './chains.json' + +export interface Chain { + name: string + chainId: number + rpcURL: string + unit: string + faucet: string + explorer: string +} + +export const EthSepolia: Chain = chainList[0] + +// eslint-disable-next-line unicorn/no-array-reduce +export const Chains = chainList.reduce>((prev, acc) => { + prev[acc.name] = acc + return prev +}, {}) diff --git a/examples/web2login-demo/src/hooks/localStorage.ts b/examples/web2login-demo/src/hooks/localStorage.ts new file mode 100644 index 0000000..3de035d --- /dev/null +++ b/examples/web2login-demo/src/hooks/localStorage.ts @@ -0,0 +1,51 @@ +import { createEffect } from 'solid-js' +import { + createStore, + produce, + type SetStoreFunction, + type Store, +} from 'solid-js/store' +import { type Chain } from '../chains' + +export function createLocalStore( + name: string, + init: T +): [Store, SetStoreFunction] { + const localState = localStorage.getItem(name) + const [state, setState] = createStore( + localState ? JSON.parse(localState) : init + ) + createEffect(() => { + localStorage.setItem(name, JSON.stringify(state)) + }) + return [state, setState] +} + +export const EMPTY_OBJECT = Object.create(null) + +export const storageKey = 'demo:auth-data:3' + +const [authData, setAuthData] = createLocalStore< + { ethAddress: string; mode: 'popup' | 'redirect' } & Chain +>(storageKey, EMPTY_OBJECT) + +export function useAuthData() { + const isAuthcated = Object.keys(authData).length > 0 + return { authData, setAuthData, isAuthcated } +} + +export function useLogout() { + return () => { + // localStorage.removeItem(storageKey) + setAuthData( + produce((s) => { + for (const k in s) { + if (Object.prototype.hasOwnProperty.call(s, k)) { + // @ts-expect-error + s[k] = undefined + } + } + }) + ) + } +} diff --git a/examples/web2login-demo/src/hooks/provider.tsx b/examples/web2login-demo/src/hooks/provider.tsx new file mode 100644 index 0000000..7d84bc8 --- /dev/null +++ b/examples/web2login-demo/src/hooks/provider.tsx @@ -0,0 +1,20 @@ +import { providers } from 'ethers' +import { useAuthData } from './localStorage' +import { createMemo } from 'solid-js' + +export const SepoliaNetwork = { + name: 'Ethereum Sepolia', + chainId: 11_155_111, +} + +export const useProvider = () => { + const { authData } = useAuthData() + return createMemo(() => + authData.name + ? new providers.JsonRpcBatchProvider(authData.rpcURL, { + name: authData.name, + chainId: authData.chainId, + }) + : null + ) +} diff --git a/examples/web2login-demo/src/hooks/useSendSuccessToast.tsx b/examples/web2login-demo/src/hooks/useSendSuccessToast.tsx new file mode 100644 index 0000000..a74fc00 --- /dev/null +++ b/examples/web2login-demo/src/hooks/useSendSuccessToast.tsx @@ -0,0 +1,65 @@ +import toast from 'solid-toast' +import { useAuthData } from './localStorage' + +export const useSendSuccessToast = () => { + const { authData } = useAuthData() + return (txHash: string) => { + toast.custom( + (t) => { + return ( +
+
+ + + +
+ Transaction Sent. View on: + + {txHash} + +
+
+ +
+
+
+ ) + }, + { + position: 'bottom-center', + duration: 10_000, + unmountDelay: 0, + } + ) + } +} diff --git a/examples/web2login-demo/src/index.css b/examples/web2login-demo/src/index.css new file mode 100644 index 0000000..6119ad9 --- /dev/null +++ b/examples/web2login-demo/src/index.css @@ -0,0 +1,68 @@ +:root { + font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif; + line-height: 1.5; + font-weight: 400; + + color-scheme: light dark; + color: rgba(255, 255, 255, 0.87); + background-color: #242424; + + font-synthesis: none; + text-rendering: optimizeLegibility; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +a { + font-weight: 500; + color: #646cff; + text-decoration: inherit; +} +a:hover { + color: #535bf2; +} + +body { + margin: 0; + display: flex; + place-items: center; + min-width: 320px; + min-height: 100vh; +} + +h1 { + font-size: 3.2em; + line-height: 1.1; +} + +button { + border-radius: 8px; + border: 1px solid transparent; + padding: 0.6em 1.2em; + font-size: 1em; + font-weight: 500; + font-family: inherit; + background-color: #1a1a1a; + cursor: pointer; + transition: border-color 0.25s; +} +button:hover { + border-color: #646cff; +} +button:focus, +button:focus-visible { + outline: 4px auto -webkit-focus-ring-color; +} + +@media (prefers-color-scheme: light) { + :root { + color: #213547; + background-color: #ffffff; + } + a:hover { + color: #747bff; + } + button { + background-color: #f9f9f9; + } +} diff --git a/examples/web2login-demo/src/index.tsx b/examples/web2login-demo/src/index.tsx new file mode 100644 index 0000000..6b0f244 --- /dev/null +++ b/examples/web2login-demo/src/index.tsx @@ -0,0 +1,9 @@ +/* @refresh reload */ +import { render } from 'solid-js/web' + +import './index.css' +import App from './App' + +const root = document.querySelector('#root') + +render(() => , root!) diff --git a/examples/web2login-demo/src/utils/index.ts b/examples/web2login-demo/src/utils/index.ts new file mode 100644 index 0000000..56e0b79 --- /dev/null +++ b/examples/web2login-demo/src/utils/index.ts @@ -0,0 +1,33 @@ +export function truncateMiddle( + str = '', + takeLength = 6, + tailLength = takeLength, + pad = '...' +): string { + if (takeLength + tailLength >= str.length) return str + return `${str.slice(0, takeLength)}${pad}${str.slice(-tailLength)}` +} + +export function remove0x(s: string) { + return s.startsWith('0x') ? s.slice(2) : s +} + +export function append0x(s: string) { + if (s.startsWith('0x')) { + return s + } + return `0x${s}` +} + +export type RedirectAction = + | 'send' + | 'send-erc20' + | 'sign-typed-data' + | 'sign-message' + | 'connect' + +export function buildRedirectUrl(action: RedirectAction) { + const url = new URL(`${window.location.origin}/redirect`) + url.searchParams.set('action', action) + return url.href +} diff --git a/examples/web2login-demo/src/vite-env.d.ts b/examples/web2login-demo/src/vite-env.d.ts new file mode 100644 index 0000000..11f02fe --- /dev/null +++ b/examples/web2login-demo/src/vite-env.d.ts @@ -0,0 +1 @@ +/// diff --git a/examples/web2login-demo/tsconfig.json b/examples/web2login-demo/tsconfig.json new file mode 100644 index 0000000..3999958 --- /dev/null +++ b/examples/web2login-demo/tsconfig.json @@ -0,0 +1,26 @@ +{ + "compilerOptions": { + "target": "ES2020", + "useDefineForClassFields": true, + "module": "ESNext", + "lib": ["ES2020", "DOM", "DOM.Iterable"], + "skipLibCheck": true, + + /* Bundler mode */ + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "resolveJsonModule": true, + "isolatedModules": true, + "noEmit": true, + "jsx": "preserve", + "jsxImportSource": "solid-js", + + /* Linting */ + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noFallthroughCasesInSwitch": true + }, + "include": ["src"], + "references": [{ "path": "./tsconfig.node.json" }] +} diff --git a/examples/web2login-demo/tsconfig.node.json b/examples/web2login-demo/tsconfig.node.json new file mode 100644 index 0000000..97ede7e --- /dev/null +++ b/examples/web2login-demo/tsconfig.node.json @@ -0,0 +1,11 @@ +{ + "compilerOptions": { + "composite": true, + "skipLibCheck": true, + "module": "ESNext", + "moduleResolution": "bundler", + "allowSyntheticDefaultImports": true, + "strict": true + }, + "include": ["vite.config.ts"] +} diff --git a/examples/web2login-demo/vite.config.ts b/examples/web2login-demo/vite.config.ts new file mode 100644 index 0000000..70bfb80 --- /dev/null +++ b/examples/web2login-demo/vite.config.ts @@ -0,0 +1,7 @@ +import { defineConfig } from 'vite' +import solid from 'vite-plugin-solid' +import basicSsl from '@vitejs/plugin-basic-ssl' + +export default defineConfig({ + plugins: [basicSsl(), solid()], +}) diff --git a/packages/evm/src/web2login.ts b/packages/evm/src/web2login.ts index 3965cfa..0167128 100644 --- a/packages/evm/src/web2login.ts +++ b/packages/evm/src/web2login.ts @@ -9,8 +9,13 @@ import { openPopup, runPopup, internalConfig, + getRedirectResponse, } from '@joyid/common' +interface WithState { + state?: string +} + export const initConfig = (config?: EvmWeb2LoginConfig): EvmWeb2LoginConfig => { Object.assign(internalConfig, config) return internalConfig as EvmWeb2LoginConfig @@ -53,3 +58,41 @@ export const connect = async ( type: DappRequestType.EvmWeb2Login, }) } + +export const connectWithRedirect = ( + redirectURL: string, + uid?: string, + config?: EvmWeb2LoginConfig +): void => { + const request = { + signerAddress: uid, + redirectURL: redirectURL, + requestNetwork: 'ethereum', + requestType: DappRequestType.EvmWeb2Login, + ...internalConfig, + ...config, + } + + window.location.assign( + buildJoyIDURL(request, DappCommunicationType.Redirect, '/evm-web2-login') + ) +} + +export const connectCallback = ( + uri?: string +): EvmWeb2LoginResponse & WithState => { + const { state, uid, entropy } = getRedirectResponse< + EvmWeb2LoginResponse & WithState + >(uri) + if (state != null) { + return { + state, + uid, + entropy, + } + } + return { + uid, + entropy, + } +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 29982bb..1df5733 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1,4 +1,4 @@ -lockfileVersion: '6.1' +lockfileVersion: '6.0' settings: autoInstallPeers: true @@ -395,6 +395,34 @@ importers: specifier: ^0.4.3 version: 0.4.3(eslint@8.57.0) + examples/web2login-demo: + dependencies: + '@joyid/evm': + specifier: workspace:* + version: link:../../packages/evm + '@solid-primitives/clipboard': + specifier: ^1.5.4 + version: 1.5.4(solid-js@1.8.17) + '@vitejs/plugin-basic-ssl': + specifier: ^1.1.0 + version: 1.1.0(vite@5.2.12) + solid-js: + specifier: ^1.8.15 + version: 1.8.17 + solid-toast: + specifier: ^0.5.0 + version: 0.5.0(solid-js@1.8.17) + devDependencies: + typescript: + specifier: ^5.2.2 + version: 5.2.2 + vite: + specifier: ^5.2.0 + version: 5.2.12 + vite-plugin-solid: + specifier: ^2.10.2 + version: 2.10.2(solid-js@1.8.17)(vite@5.2.12) + packages/bitcoin: dependencies: '@joyid/common': @@ -3816,6 +3844,7 @@ packages: /@emotion/memoize@0.7.4: resolution: {integrity: sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==} + requiresBuild: true dev: false optional: true @@ -3925,7 +3954,6 @@ packages: cpu: [ppc64] os: [aix] requiresBuild: true - dev: true optional: true /@esbuild/aix-ppc64@0.21.5: @@ -3952,7 +3980,6 @@ packages: cpu: [arm64] os: [android] requiresBuild: true - dev: true optional: true /@esbuild/android-arm64@0.21.5: @@ -3979,7 +4006,6 @@ packages: cpu: [arm] os: [android] requiresBuild: true - dev: true optional: true /@esbuild/android-arm@0.21.5: @@ -4006,7 +4032,6 @@ packages: cpu: [x64] os: [android] requiresBuild: true - dev: true optional: true /@esbuild/android-x64@0.21.5: @@ -4033,7 +4058,6 @@ packages: cpu: [arm64] os: [darwin] requiresBuild: true - dev: true optional: true /@esbuild/darwin-arm64@0.21.5: @@ -4060,7 +4084,6 @@ packages: cpu: [x64] os: [darwin] requiresBuild: true - dev: true optional: true /@esbuild/darwin-x64@0.21.5: @@ -4087,7 +4110,6 @@ packages: cpu: [arm64] os: [freebsd] requiresBuild: true - dev: true optional: true /@esbuild/freebsd-arm64@0.21.5: @@ -4114,7 +4136,6 @@ packages: cpu: [x64] os: [freebsd] requiresBuild: true - dev: true optional: true /@esbuild/freebsd-x64@0.21.5: @@ -4141,7 +4162,6 @@ packages: cpu: [arm64] os: [linux] requiresBuild: true - dev: true optional: true /@esbuild/linux-arm64@0.21.5: @@ -4168,7 +4188,6 @@ packages: cpu: [arm] os: [linux] requiresBuild: true - dev: true optional: true /@esbuild/linux-arm@0.21.5: @@ -4195,7 +4214,6 @@ packages: cpu: [ia32] os: [linux] requiresBuild: true - dev: true optional: true /@esbuild/linux-ia32@0.21.5: @@ -4222,7 +4240,6 @@ packages: cpu: [loong64] os: [linux] requiresBuild: true - dev: true optional: true /@esbuild/linux-loong64@0.21.5: @@ -4249,7 +4266,6 @@ packages: cpu: [mips64el] os: [linux] requiresBuild: true - dev: true optional: true /@esbuild/linux-mips64el@0.21.5: @@ -4276,7 +4292,6 @@ packages: cpu: [ppc64] os: [linux] requiresBuild: true - dev: true optional: true /@esbuild/linux-ppc64@0.21.5: @@ -4303,7 +4318,6 @@ packages: cpu: [riscv64] os: [linux] requiresBuild: true - dev: true optional: true /@esbuild/linux-riscv64@0.21.5: @@ -4330,7 +4344,6 @@ packages: cpu: [s390x] os: [linux] requiresBuild: true - dev: true optional: true /@esbuild/linux-s390x@0.21.5: @@ -4357,7 +4370,6 @@ packages: cpu: [x64] os: [linux] requiresBuild: true - dev: true optional: true /@esbuild/linux-x64@0.21.5: @@ -4384,7 +4396,6 @@ packages: cpu: [x64] os: [netbsd] requiresBuild: true - dev: true optional: true /@esbuild/netbsd-x64@0.21.5: @@ -4411,7 +4422,6 @@ packages: cpu: [x64] os: [openbsd] requiresBuild: true - dev: true optional: true /@esbuild/openbsd-x64@0.21.5: @@ -4438,7 +4448,6 @@ packages: cpu: [x64] os: [sunos] requiresBuild: true - dev: true optional: true /@esbuild/sunos-x64@0.21.5: @@ -4465,7 +4474,6 @@ packages: cpu: [arm64] os: [win32] requiresBuild: true - dev: true optional: true /@esbuild/win32-arm64@0.21.5: @@ -4492,7 +4500,6 @@ packages: cpu: [ia32] os: [win32] requiresBuild: true - dev: true optional: true /@esbuild/win32-ia32@0.21.5: @@ -4519,7 +4526,6 @@ packages: cpu: [x64] os: [win32] requiresBuild: true - dev: true optional: true /@esbuild/win32-x64@0.21.5: @@ -5271,7 +5277,7 @@ packages: qr-code-styling: 1.6.0-rc.1 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) - react-i18next: 13.5.0(i18next@23.11.5)(react-dom@18.2.0)(react-native@0.72.6)(react@18.2.0) + react-i18next: 13.5.0(i18next@22.5.1)(react-dom@18.2.0)(react-native@0.72.6)(react@18.2.0) react-native: 0.72.6(@babel/core@7.23.2)(@babel/preset-env@7.24.7)(react@18.2.0) /@metamask/sdk@0.20.5(react-dom@18.2.0)(react-i18next@13.5.0)(react-native@0.72.6)(react@18.2.0): @@ -6017,7 +6023,6 @@ packages: cpu: [arm] os: [android] requiresBuild: true - dev: true optional: true /@rollup/rollup-android-arm64@4.18.0: @@ -6025,7 +6030,6 @@ packages: cpu: [arm64] os: [android] requiresBuild: true - dev: true optional: true /@rollup/rollup-darwin-arm64@4.18.0: @@ -6033,7 +6037,6 @@ packages: cpu: [arm64] os: [darwin] requiresBuild: true - dev: true optional: true /@rollup/rollup-darwin-x64@4.18.0: @@ -6041,7 +6044,6 @@ packages: cpu: [x64] os: [darwin] requiresBuild: true - dev: true optional: true /@rollup/rollup-linux-arm-gnueabihf@4.18.0: @@ -6049,7 +6051,6 @@ packages: cpu: [arm] os: [linux] requiresBuild: true - dev: true optional: true /@rollup/rollup-linux-arm-musleabihf@4.18.0: @@ -6057,7 +6058,6 @@ packages: cpu: [arm] os: [linux] requiresBuild: true - dev: true optional: true /@rollup/rollup-linux-arm64-gnu@4.18.0: @@ -6065,7 +6065,6 @@ packages: cpu: [arm64] os: [linux] requiresBuild: true - dev: true optional: true /@rollup/rollup-linux-arm64-musl@4.18.0: @@ -6073,7 +6072,6 @@ packages: cpu: [arm64] os: [linux] requiresBuild: true - dev: true optional: true /@rollup/rollup-linux-powerpc64le-gnu@4.18.0: @@ -6081,7 +6079,6 @@ packages: cpu: [ppc64] os: [linux] requiresBuild: true - dev: true optional: true /@rollup/rollup-linux-riscv64-gnu@4.18.0: @@ -6089,7 +6086,6 @@ packages: cpu: [riscv64] os: [linux] requiresBuild: true - dev: true optional: true /@rollup/rollup-linux-s390x-gnu@4.18.0: @@ -6097,7 +6093,6 @@ packages: cpu: [s390x] os: [linux] requiresBuild: true - dev: true optional: true /@rollup/rollup-linux-x64-gnu@4.18.0: @@ -6105,7 +6100,6 @@ packages: cpu: [x64] os: [linux] requiresBuild: true - dev: true optional: true /@rollup/rollup-linux-x64-musl@4.18.0: @@ -6113,7 +6107,6 @@ packages: cpu: [x64] os: [linux] requiresBuild: true - dev: true optional: true /@rollup/rollup-win32-arm64-msvc@4.18.0: @@ -6121,7 +6114,6 @@ packages: cpu: [arm64] os: [win32] requiresBuild: true - dev: true optional: true /@rollup/rollup-win32-ia32-msvc@4.18.0: @@ -6129,7 +6121,6 @@ packages: cpu: [ia32] os: [win32] requiresBuild: true - dev: true optional: true /@rollup/rollup-win32-x64-msvc@4.18.0: @@ -6137,7 +6128,6 @@ packages: cpu: [x64] os: [win32] requiresBuild: true - dev: true optional: true /@safe-global/safe-apps-provider@0.18.1(typescript@5.2.2): @@ -6231,6 +6221,15 @@ packages: solid-js: 1.7.3 dev: false + /@solid-primitives/clipboard@1.5.4(solid-js@1.8.17): + resolution: {integrity: sha512-cycedcO71We6idHomneUC/EqcgWihjSpYKKJSzicBu/Pwly2eudnZ51q91U0LdKraPYRtT+12lZOPPQ92ehLCQ==} + peerDependencies: + solid-js: ^1.6.12 + dependencies: + '@solid-primitives/utils': 6.2.3(solid-js@1.8.17) + solid-js: 1.8.17 + dev: false + /@solid-primitives/storage@2.1.1(solid-js@1.7.3): resolution: {integrity: sha512-GDbELt4Xjp0ySsHZ+RHzup0YIl1epHz8A2SVQYNRZPgkIEJk0Fyrt2vW6Etym2yUruTt8yT3d8106LVb71KIWg==} peerDependencies: @@ -6252,6 +6251,14 @@ packages: solid-js: 1.7.3 dev: false + /@solid-primitives/utils@6.2.3(solid-js@1.8.17): + resolution: {integrity: sha512-CqAwKb2T5Vi72+rhebSsqNZ9o67buYRdEJrIFzRXz3U59QqezuuxPsyzTSVCacwS5Pf109VRsgCJQoxKRoECZQ==} + peerDependencies: + solid-js: ^1.6.12 + dependencies: + solid-js: 1.8.17 + dev: false + /@solidjs/router@0.8.2(solid-js@1.7.3): resolution: {integrity: sha512-gUKW+LZqxtX6y/Aw6JKyy4gQ9E7dLqp513oB9pSYJR1HM5c56Pf7eijzyXX+b3WuXig18Cxqah4tMtF0YGu80w==} peerDependencies: @@ -6702,7 +6709,6 @@ packages: /@types/estree@1.0.5: resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==} - dev: true /@types/istanbul-lib-coverage@2.0.6: resolution: {integrity: sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==} @@ -7021,6 +7027,15 @@ packages: '@vanilla-extract/css': 1.14.0 dev: false + /@vitejs/plugin-basic-ssl@1.1.0(vite@5.2.12): + resolution: {integrity: sha512-wO4Dk/rm8u7RNhOf95ZzcEmC9rYOncYgvq4z3duaJrCgjN8BxAnDVyndanfcJZ0O6XZzHz6Q0hTimxTg8Y9g/A==} + engines: {node: '>=14.6.0'} + peerDependencies: + vite: ^3.0.0 || ^4.0.0 || ^5.0.0 + dependencies: + vite: 5.2.12 + dev: false + /@vitejs/plugin-react@4.3.0(vite@5.2.12): resolution: {integrity: sha512-KcEbMsn4Dpk+LIbHMj7gDPRKaTMStxxWRkRmxsg/jVdFdJCZWt1SchZcf0M4t8lIKdwwMsEyzhrcOXRrDPtOBw==} engines: {node: ^14.18.0 || >=16.0.0} @@ -9465,7 +9480,6 @@ packages: '@esbuild/win32-arm64': 0.20.2 '@esbuild/win32-ia32': 0.20.2 '@esbuild/win32-x64': 0.20.2 - dev: true /esbuild@0.21.5: resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==} @@ -10680,11 +10694,6 @@ packages: dependencies: '@babel/runtime': 7.24.7 - /i18next@23.11.5: - resolution: {integrity: sha512-41pvpVbW9rhZPk5xjCX2TPJi2861LEig/YRhUkY+1FQ2IQPS0bKUDYnEqY8XPPbB48h1uIwLnP9iiEfuSl20CA==} - dependencies: - '@babel/runtime': 7.24.7 - /iconv-lite@0.4.24: resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} engines: {node: '>=0.10.0'} @@ -13126,7 +13135,7 @@ packages: react-dom: 18.2.0(react@18.2.0) dev: false - /react-i18next@13.5.0(i18next@23.11.5)(react-dom@18.2.0)(react-native@0.72.6)(react@18.2.0): + /react-i18next@13.5.0(i18next@22.5.1)(react-dom@18.2.0)(react-native@0.72.6)(react@18.2.0): resolution: {integrity: sha512-CFJ5NDGJ2MUyBohEHxljOq/39NQ972rh1ajnadG9BjTk+UXbHLq4z5DKEbEQBDoIhUmmbuS/fIMJKo6VOax1HA==} peerDependencies: i18next: '>= 23.2.3' @@ -13141,7 +13150,7 @@ packages: dependencies: '@babel/runtime': 7.24.7 html-parse-stringify: 3.0.1 - i18next: 23.11.5 + i18next: 22.5.1 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) react-native: 0.72.6(@babel/core@7.23.2)(@babel/preset-env@7.24.7)(react@18.2.0) @@ -13608,7 +13617,6 @@ packages: '@rollup/rollup-win32-ia32-msvc': 4.18.0 '@rollup/rollup-win32-x64-msvc': 4.18.0 fsevents: 2.3.3 - dev: true /run-parallel@1.2.0: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} @@ -13721,10 +13729,22 @@ packages: resolution: {integrity: sha512-ghgmKt5o4Tly5yEG/UJp8qTd0AN7Xalw4XBtDEKP655B699qMEtra1WlXeE6WIvdEG481JvRxULKsInq/iNysw==} engines: {node: '>=0.10.0'} + /seroval-plugins@1.0.7(seroval@1.0.7): + resolution: {integrity: sha512-GO7TkWvodGp6buMEX9p7tNyIkbwlyuAWbI6G9Ec5bhcm7mQdu3JOK1IXbEUwb3FVzSc363GraG/wLW23NSavIw==} + engines: {node: '>=10'} + peerDependencies: + seroval: ^1.0 + dependencies: + seroval: 1.0.7 + /seroval@0.5.1: resolution: {integrity: sha512-ZfhQVB59hmIauJG5Ydynupy8KHyr5imGNtdDhbZG68Ufh1Ynkv9KOYOAABf71oVbQxJ8VkWnMHAjEHE7fWkH5g==} engines: {node: '>=10'} + /seroval@1.0.7: + resolution: {integrity: sha512-n6ZMQX5q0Vn19Zq7CIKNIo7E75gPkGCFUEqDpa8jgwpYr/vScjqnQ6H09t1uIiZ0ZSK0ypEGvrYK2bhBGWsGdw==} + engines: {node: '>=10'} + /serve-static@1.15.0: resolution: {integrity: sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==} engines: {node: '>= 0.8.0'} @@ -13906,6 +13926,13 @@ packages: csstype: 3.1.3 seroval: 0.5.1 + /solid-js@1.8.17: + resolution: {integrity: sha512-E0FkUgv9sG/gEBWkHr/2XkBluHb1fkrHywUgA6o6XolPDCJ4g1HaLmQufcBBhiF36ee40q+HpG/vCZu7fLpI3Q==} + dependencies: + csstype: 3.1.3 + seroval: 1.0.7 + seroval-plugins: 1.0.7(seroval@1.0.7) + /solid-refresh@0.4.3(solid-js@1.7.3): resolution: {integrity: sha512-7+4/gYsVi0BlM4PzT1PU1TB5nW3Hv8FWuB+Kw/ofWui7KQkWBf+dVZOrReQYHEmLCzytHUa2JysUXgzVALJmSw==} peerDependencies: @@ -13919,6 +13946,19 @@ packages: - supports-color dev: true + /solid-refresh@0.6.3(solid-js@1.8.17): + resolution: {integrity: sha512-F3aPsX6hVw9ttm5LYlth8Q15x6MlI/J3Dn+o3EQyRTtTxidepSTwAYdozt01/YA+7ObcciagGEyXIopGZzQtbA==} + peerDependencies: + solid-js: ^1.3 + dependencies: + '@babel/generator': 7.24.7 + '@babel/helper-module-imports': 7.24.7 + '@babel/types': 7.24.7 + solid-js: 1.8.17 + transitivePeerDependencies: + - supports-color + dev: true + /solid-toast@0.5.0(solid-js@1.7.3): resolution: {integrity: sha512-t770JakjyS2P9b8Qa1zMLOD51KYKWXbTAyJePVUoYex5c5FH5S/HtUBUbZAWFcqRCKmAE8KhyIiCvDZA8bOnxQ==} peerDependencies: @@ -13927,6 +13967,14 @@ packages: solid-js: 1.7.3 dev: false + /solid-toast@0.5.0(solid-js@1.8.17): + resolution: {integrity: sha512-t770JakjyS2P9b8Qa1zMLOD51KYKWXbTAyJePVUoYex5c5FH5S/HtUBUbZAWFcqRCKmAE8KhyIiCvDZA8bOnxQ==} + peerDependencies: + solid-js: ^1.5.4 + dependencies: + solid-js: 1.8.17 + dev: false + /sonic-boom@2.8.0: resolution: {integrity: sha512-kuonw1YOYYNOve5iHdSahXPOK49GqwA+LZhI6Wz/l0rP57iKyXXIHaRagOBHAPmGwJC6od2Z9zgvZ5loSgMlVg==} dependencies: @@ -14995,6 +15043,28 @@ packages: - rollup dev: true + /vite-plugin-solid@2.10.2(solid-js@1.8.17)(vite@5.2.12): + resolution: {integrity: sha512-AOEtwMe2baBSXMXdo+BUwECC8IFHcKS6WQV/1NEd+Q7vHPap5fmIhLcAzr+DUJ04/KHx/1UBU0l1/GWP+rMAPQ==} + peerDependencies: + '@testing-library/jest-dom': ^5.16.6 || ^5.17.0 || ^6.* + solid-js: ^1.7.2 + vite: ^3.0.0 || ^4.0.0 || ^5.0.0 + peerDependenciesMeta: + '@testing-library/jest-dom': + optional: true + dependencies: + '@babel/core': 7.24.7 + '@types/babel__core': 7.20.5 + babel-preset-solid: 1.8.17(@babel/core@7.24.7) + merge-anything: 5.1.7 + solid-js: 1.8.17 + solid-refresh: 0.6.3(solid-js@1.8.17) + vite: 5.2.12 + vitefu: 0.2.5(vite@5.2.12) + transitivePeerDependencies: + - supports-color + dev: true + /vite-plugin-solid@2.5.0(solid-js@1.7.3)(vite@4.5.3): resolution: {integrity: sha512-VneGd3RyFJvwaiffsqgymeMaofn0IzQLPwDzafTV2f1agoWeeJlk5VrI5WqT9BTtLe69vNNbCJWqLhHr9fOdDw==} peerDependencies: @@ -15118,7 +15188,6 @@ packages: rollup: 4.18.0 optionalDependencies: fsevents: 2.3.3 - dev: true /vitefu@0.2.5(vite@4.5.3): resolution: {integrity: sha512-SgHtMLoqaeeGnd2evZ849ZbACbnwQCIwRH57t18FxcXoZop0uQu0uzlIhJBlF/eWVzuce0sHeqPcDo+evVcg8Q==} @@ -15131,6 +15200,17 @@ packages: vite: 4.5.3 dev: true + /vitefu@0.2.5(vite@5.2.12): + resolution: {integrity: sha512-SgHtMLoqaeeGnd2evZ849ZbACbnwQCIwRH57t18FxcXoZop0uQu0uzlIhJBlF/eWVzuce0sHeqPcDo+evVcg8Q==} + peerDependencies: + vite: ^3.0.0 || ^4.0.0 || ^5.0.0 + peerDependenciesMeta: + vite: + optional: true + dependencies: + vite: 5.2.12 + dev: true + /vitest@1.6.0: resolution: {integrity: sha512-H5r/dN06swuFnzNFhq/dnz37bPXnq8xB2xB5JOVk8K09rUtoeNN+LHWkoQ0A/i3hvbUKKcCei9KpbxqHMLhLLA==} engines: {node: ^18.0.0 || >=20.0.0}