From 103b9b4c92c790419222c9d8d79c0a63f9c28a10 Mon Sep 17 00:00:00 2001 From: Thomas Date: Sat, 1 Nov 2025 17:07:18 +0100 Subject: [PATCH 01/16] Add SolidStart web3 onboarding template --- examples/with-solidstart/.env.example | 2 + examples/with-solidstart/.gitignore | 5 + examples/with-solidstart/README.md | 63 +++++++++++ examples/with-solidstart/app.config.ts | 7 ++ examples/with-solidstart/package.json | 28 +++++ examples/with-solidstart/public/favicon.svg | 92 ++++++++++++++++ examples/with-solidstart/public/logo.svg | 1 + examples/with-solidstart/public/onboard.svg | 1 + examples/with-solidstart/src/app.css | 25 +++++ examples/with-solidstart/src/app.tsx | 33 ++++++ .../with-solidstart/src/auth/Provider.tsx | 100 +++++++++++++++++ examples/with-solidstart/src/auth/context.ts | 13 +++ examples/with-solidstart/src/auth/index.ts | 34 ++++++ examples/with-solidstart/src/auth/server.ts | 31 ++++++ examples/with-solidstart/src/auth/web3.ts | 48 ++++++++ .../src/components/Balance.tsx | 19 ++++ .../with-solidstart/src/components/Error.tsx | 36 ++++++ .../with-solidstart/src/components/Icons.tsx | 28 +++++ .../with-solidstart/src/components/Nav.tsx | 104 ++++++++++++++++++ examples/with-solidstart/src/db/index.ts | 50 +++++++++ examples/with-solidstart/src/db/schema.ts | 6 + examples/with-solidstart/src/entry-client.tsx | 3 + examples/with-solidstart/src/entry-server.tsx | 24 ++++ examples/with-solidstart/src/global.d.ts | 1 + .../with-solidstart/src/routes/[...404].tsx | 17 +++ examples/with-solidstart/src/routes/about.tsx | 19 ++++ examples/with-solidstart/src/routes/index.tsx | 35 ++++++ examples/with-solidstart/src/web3/index.ts | 57 ++++++++++ examples/with-solidstart/src/web3/utils.ts | 21 ++++ examples/with-solidstart/tsconfig.json | 19 ++++ 30 files changed, 922 insertions(+) create mode 100644 examples/with-solidstart/.env.example create mode 100644 examples/with-solidstart/.gitignore create mode 100644 examples/with-solidstart/README.md create mode 100644 examples/with-solidstart/app.config.ts create mode 100644 examples/with-solidstart/package.json create mode 100644 examples/with-solidstart/public/favicon.svg create mode 100644 examples/with-solidstart/public/logo.svg create mode 100644 examples/with-solidstart/public/onboard.svg create mode 100644 examples/with-solidstart/src/app.css create mode 100644 examples/with-solidstart/src/app.tsx create mode 100644 examples/with-solidstart/src/auth/Provider.tsx create mode 100644 examples/with-solidstart/src/auth/context.ts create mode 100644 examples/with-solidstart/src/auth/index.ts create mode 100644 examples/with-solidstart/src/auth/server.ts create mode 100644 examples/with-solidstart/src/auth/web3.ts create mode 100644 examples/with-solidstart/src/components/Balance.tsx create mode 100644 examples/with-solidstart/src/components/Error.tsx create mode 100644 examples/with-solidstart/src/components/Icons.tsx create mode 100644 examples/with-solidstart/src/components/Nav.tsx create mode 100644 examples/with-solidstart/src/db/index.ts create mode 100644 examples/with-solidstart/src/db/schema.ts create mode 100644 examples/with-solidstart/src/entry-client.tsx create mode 100644 examples/with-solidstart/src/entry-server.tsx create mode 100644 examples/with-solidstart/src/global.d.ts create mode 100644 examples/with-solidstart/src/routes/[...404].tsx create mode 100644 examples/with-solidstart/src/routes/about.tsx create mode 100644 examples/with-solidstart/src/routes/index.tsx create mode 100644 examples/with-solidstart/src/web3/index.ts create mode 100644 examples/with-solidstart/src/web3/utils.ts create mode 100644 examples/with-solidstart/tsconfig.json diff --git a/examples/with-solidstart/.env.example b/examples/with-solidstart/.env.example new file mode 100644 index 000000000..d2d5e82b2 --- /dev/null +++ b/examples/with-solidstart/.env.example @@ -0,0 +1,2 @@ +# Generate using `openssl rand -hex 32` +SESSION_SECRET = myverylongsessionsecretkeythatishouldchange diff --git a/examples/with-solidstart/.gitignore b/examples/with-solidstart/.gitignore new file mode 100644 index 000000000..d9ec65bf5 --- /dev/null +++ b/examples/with-solidstart/.gitignore @@ -0,0 +1,5 @@ +node_modules +.data +pnpm-lock.yaml +package-lock.json +.env diff --git a/examples/with-solidstart/README.md b/examples/with-solidstart/README.md new file mode 100644 index 000000000..a43b560cb --- /dev/null +++ b/examples/with-solidstart/README.md @@ -0,0 +1,63 @@ +[![Banner](https://assets.solidjs.com/banner?background=tiles&type=Start&project=template)](https://github.com/solidjs/solid-start) + +Kickstart your DeFi app development with this starter template, built with [SolidStart](https://start.solidjs.com) and [Web3Onboard](https://web3onboard.thirdweb.com). +It seamlessly integrates SolidStart’s server-side rendering (_SSR_) with client-side Web3 features, leveraging libraries like [ethers.js](https://github.com/ethers-io/ethers.js). + +## Features + +- **SSR Compliant**: Web3 code loads only on the client, ensuring compatibility with SSR architecture +- **Auth Context**: A reactive context to monitor wallet changes, handle signatures, and more +- **Local Storage**: Utilizes a lightweight, file-based database with `unstorage` for persistence +- **Starter Kit for DeFi**: Preconfigured setup to kickstart your DeFi app development with SolidStart and Web3Onboard +- **Client-Only**: Easily isolate client-side logic for Web3 interactions + +## Getting Started + +1. Install dependencies + + ```bash + # use preferred package manager + npm install + ``` + +2. Run the development server + + ```bash + # use preferred package manager + npm run dev + ``` + +3. Rename `.env.example` to `.env`. For production, generate a secure `SESSION_SECRET` with + + ```bash + openssl rand -hex 32 + ``` + +## Usage + +To ensure Web3-related logic runs only on the client, use the `clientOnly` utility from SolidStart. Here are two ways to implement client-only code: + +1. **Client-Only Component** (e.g. for a component showing user balance) + + ```jsx + import { clientOnly } from "@solidjs/start/client"; + + const ClientComponent = clientOnly(() => import("./ClientOnlyComponent")); + ``` + +2. **Client-Only Page** (e.g. for a `/swap` page) + Add the following at the top of your route file to render the entire page on the client: + + ```jsx + import { clientOnly } from "@solidjs/start/client"; + + export default clientOnly(async () => ({ default: MyPage })); + ``` + +For more details, refer to the `clientOnly` [documentation](https://docs.solidjs.com/solid-start/reference/client/client-only#clientonly). + +
+
+
+ +
diff --git a/examples/with-solidstart/app.config.ts b/examples/with-solidstart/app.config.ts new file mode 100644 index 000000000..8c75b850f --- /dev/null +++ b/examples/with-solidstart/app.config.ts @@ -0,0 +1,7 @@ +import { defineConfig } from "@solidjs/start/config"; +import tailwindcss from "@tailwindcss/vite"; + +export default defineConfig({ + server: { preset: "" }, // your deployment + vite: { plugins: [tailwindcss()] } +}); diff --git a/examples/with-solidstart/package.json b/examples/with-solidstart/package.json new file mode 100644 index 000000000..ff2b68a8b --- /dev/null +++ b/examples/with-solidstart/package.json @@ -0,0 +1,28 @@ +{ + "type": "module", + "scripts": { + "dev": "vinxi dev --port 3001", + "build": "vinxi build", + "start": "vinxi start", + "format": "prettier --write . --trailing-comma none" + }, + "dependencies": { + "@solidjs/meta": "^0.29.4", + "@solidjs/router": "^0.15.3", + "@solidjs/start": "^1.2.0", + "@web3-onboard/core": "^2.24.1", + "@web3-onboard/injected-wallets": "^2.11.3", + "ethers": "^6.15.0", + "solid-js": "^1.9.10", + "unstorage": "1.17.1", + "vinxi": "^0.5.8" + }, + "devDependencies": { + "@tailwindcss/vite": "^4.1.16", + "prettier": "^3.6.2", + "tailwindcss": "^4.1.16" + }, + "engines": { + "node": ">=22" + } +} diff --git a/examples/with-solidstart/public/favicon.svg b/examples/with-solidstart/public/favicon.svg new file mode 100644 index 000000000..e9a615cff --- /dev/null +++ b/examples/with-solidstart/public/favicon.svg @@ -0,0 +1,92 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/with-solidstart/public/logo.svg b/examples/with-solidstart/public/logo.svg new file mode 100644 index 000000000..e8e7915ef --- /dev/null +++ b/examples/with-solidstart/public/logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/examples/with-solidstart/public/onboard.svg b/examples/with-solidstart/public/onboard.svg new file mode 100644 index 000000000..56647b05b --- /dev/null +++ b/examples/with-solidstart/public/onboard.svg @@ -0,0 +1 @@ + diff --git a/examples/with-solidstart/src/app.css b/examples/with-solidstart/src/app.css new file mode 100644 index 000000000..b1d616d57 --- /dev/null +++ b/examples/with-solidstart/src/app.css @@ -0,0 +1,25 @@ +@import "tailwindcss"; + +#app { + background-color: white; + user-select: none; + @media (scripting: none) { + display: none; + } +} + +main { + @apply flex flex-col items-center justify-center min-h-screen bg-gray-50 gap-18 px-4; +} + +h1 { + @apply uppercase text-6xl text-sky-700 font-thin; +} + +button { + cursor: pointer; +} + +.loader { + @apply animate-spin border-current border-t-transparent text-current rounded-full; +} diff --git a/examples/with-solidstart/src/app.tsx b/examples/with-solidstart/src/app.tsx new file mode 100644 index 000000000..3197390e8 --- /dev/null +++ b/examples/with-solidstart/src/app.tsx @@ -0,0 +1,33 @@ +import { Suspense } from "solid-js"; +import { Router, type RouteDefinition } from "@solidjs/router"; +import { FileRoutes } from "@solidjs/start/router"; +import { MetaProvider } from "@solidjs/meta"; +import { querySession } from "./auth"; +import AuthProvider from "./auth/Provider"; +import Nav from "./components/Nav"; +import ErrorNotification from "./components/Error"; +import "./app.css"; + +export const route: RouteDefinition = { + preload: ({ location }) => querySession(location.pathname) +}; + +export default function App() { + return ( + ( + + + +