diff --git a/.changeset/README.md b/.changeset/README.md new file mode 100644 index 00000000..a2780cea --- /dev/null +++ b/.changeset/README.md @@ -0,0 +1,24 @@ +# Changesets + +This project uses [Changesets](https://github.com/changesets/changesets) to manage versioning and changelogs for `@mysten/memwal`. + +## How to add a changeset + +When you make a change that should be released: + +```bash +pnpm changeset +``` + +This will prompt you to: +1. Select which packages have changed (`@mysten/memwal`) +2. Choose the semver bump type (major / minor / patch) +3. Write a summary of the change + +A markdown file will be created in this directory describing the change. + +## Release flow + +1. Changesets bot creates a **"Version Packages"** PR on `main` +2. That PR bumps versions and updates `CHANGELOG.md` +3. When you **merge** the PR, GitHub Actions automatically **publishes to npm** diff --git a/.changeset/config.json b/.changeset/config.json new file mode 100644 index 00000000..42efca95 --- /dev/null +++ b/.changeset/config.json @@ -0,0 +1,19 @@ +{ + "$schema": "https://unpkg.com/@changesets/config@3.1.1/schema.json", + "changelog": [ + "@changesets/changelog-github", + { "repo": "CommandOSSLabs/MemWal" } + ], + "commit": true, + "fixed": [], + "linked": [], + "access": "public", + "baseBranch": "main", + "updateInternalDependencies": "patch", + "ignore": [ + "@memwal/app", + "@memwal/noter", + "@memwal/chatbot", + "researcher" + ] +} diff --git a/.github/workflows/deploy-app-walrus.yml b/.github/workflows/deploy-app-walrus.yml new file mode 100644 index 00000000..ff5c5d3f --- /dev/null +++ b/.github/workflows/deploy-app-walrus.yml @@ -0,0 +1,89 @@ +name: Deploy App to Walrus Site + +on: + push: + branches: + - main + paths: + - 'apps/app/**' + - '.github/workflows/deploy-app-walrus.yml' + workflow_dispatch: + +permissions: + contents: write + +jobs: + deploy-app: + runs-on: ubuntu-latest + environment: mainnet + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '20' + + - name: Install pnpm + uses: pnpm/action-setup@v4 + + - name: Install dependencies + run: pnpm install --frozen-lockfile + + - name: Validate ws-resources.json exists + run: | + if [ ! -f "./apps/app/ws-resources.json" ]; then + echo "## Deployment Failed" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "Missing required file: \`apps/app/ws-resources.json\`" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "This file is generated after your first manual deployment with \`site-builder\`." >> $GITHUB_STEP_SUMMARY + + echo "ERROR: apps/app/ws-resources.json not found!" + echo "This file is generated after your first manual deployment with site-builder." + exit 1 + fi + echo "ws-resources.json found!" + + - name: Build SDK + run: pnpm build:sdk + + - name: Build app for Mainnet + working-directory: ./apps/app + run: | + pnpm build + if [ -f "ws-resources.json" ]; then + cp ws-resources.json dist/ + fi + env: + VITE_SUI_NETWORK: mainnet + VITE_MEMWAL_SERVER_URL: ${{ vars.VITE_MEMWAL_SERVER_URL }} + VITE_MEMWAL_PACKAGE_ID: ${{ vars.VITE_MEMWAL_PACKAGE_ID }} + VITE_MEMWAL_REGISTRY_ID: ${{ vars.VITE_MEMWAL_REGISTRY_ID }} + VITE_SEAL_KEY_SERVERS: ${{ vars.VITE_SEAL_KEY_SERVERS }} + VITE_DOCS_URL: ${{ vars.VITE_DOCS_URL }} + + - name: Deploy to Walrus Site (Mainnet) + id: deploy-mainnet + uses: MystenLabs/walrus-sites-github-actions/deploy@v1 + with: + SUI_ADDRESS: ${{ vars.SUI_ADDRESS }} + SUI_KEYSTORE: ${{ secrets.SUI_KEYSTORE }} + DIST: ./apps/app/dist + SUI_NETWORK: mainnet + EPOCHS: ${{ vars.WALRUS_EPOCHS || '3' }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + SITES_CONFIG: | + contexts: + mainnet: + portal: wal.app + package: 0x26eb7ee8688da02c5f671679524e379f0b837a12f1d1d799f255b7eea260ad27 + staking_object: 0x10b9d30c28448939ce6c4d6c6e0ffce4a7f8a4ada8248bdad09ef8b70e4a3904 + general: + wallet_env: mainnet + walrus_context: mainnet + walrus_package: 0xfdc88f7d7cf30afab2f82e8380d11ee8f70efb90e863d1de8616fae1bb09ea77 + gas_budget: 500000000 + default_context: mainnet diff --git a/.github/workflows/release-sdk.yml b/.github/workflows/release-sdk.yml new file mode 100644 index 00000000..65659e03 --- /dev/null +++ b/.github/workflows/release-sdk.yml @@ -0,0 +1,80 @@ +name: Release SDK + +on: + push: + branches: + - main + - staging + - dev + paths: + - 'packages/sdk/**' + - '.changeset/**' + - '.github/workflows/release-sdk.yml' + workflow_dispatch: + +concurrency: ${{ github.workflow }}-${{ github.ref }} + +jobs: + release: + name: Version & Publish + runs-on: ubuntu-latest + permissions: + contents: write + pull-requests: write + id-token: write + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup PNPM + uses: pnpm/action-setup@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '20' + cache: pnpm + registry-url: 'https://registry.npmjs.org' + + - name: Install dependencies + run: pnpm install --frozen-lockfile + + - name: Typecheck + run: pnpm --filter @mysten/memwal typecheck + + - name: Build SDK + run: pnpm build:sdk + + # ── main branch → stable release (latest) ── + - name: Create Release PR or Publish to npm + if: github.ref == 'refs/heads/main' + uses: changesets/action@v1 + with: + title: 'chore: version packages' + commit: 'chore: version packages' + publish: pnpm changeset publish + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + NPM_TOKEN: ${{ secrets.NPM_TOKEN }} + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} + + # ── staging branch → release candidate (rc tag) ── + - name: Publish staging release candidate + if: github.ref == 'refs/heads/staging' + run: | + PKG_VERSION=$(node -p "require('./packages/sdk/package.json').version") + npm view @mysten/memwal@$PKG_VERSION version 2>/dev/null && echo "Version $PKG_VERSION already published, skipping" && exit 0 + cd packages/sdk && npm publish --tag rc --access public + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} + + # ── dev branch → prerelease (dev tag) ── + - name: Publish dev prerelease + if: github.ref == 'refs/heads/dev' + run: | + PKG_VERSION=$(node -p "require('./packages/sdk/package.json').version") + npm view @mysten/memwal@$PKG_VERSION version 2>/dev/null && echo "Version $PKG_VERSION already published, skipping" && exit 0 + cd packages/sdk && npm publish --tag dev --access public + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/.gitignore b/.gitignore index f9bcbe74..2a06430a 100644 --- a/.gitignore +++ b/.gitignore @@ -113,3 +113,6 @@ CLAUDE.md x-wallet tmp-rememe/ tmp-smashblob/ + +# Railway sensitive docs +railway-*.md diff --git a/README.md b/README.md index 1e8c9d13..bcce43d4 100644 --- a/README.md +++ b/README.md @@ -1,17 +1,14 @@ # MemWal -Privacy-first AI memory SDK and protocol stack for storing encrypted memories on Walrus and +Privacy-first AI memory layer for storing encrypted memories on Walrus and retrieving them with semantic search. -> MemWal is currently in beta. It is usable today, but the protocol, SDK, and operational -> surfaces may still evolve as we harden the system. The docs site is the primary source of -> truth for the supported integration path and current architecture, and contributions are very -> welcome as we improve the stack. +> MemWal is currently in beta and actively evolving. While fully usable today, we continue to refine the developer experience and operational guidance. We welcome feedback from early builders as we continue to improve the product. ## Install ```bash -pnpm add @cmdoss/memwal +pnpm add @mysten/memwal ``` Peer dependencies (install as needed): @@ -23,11 +20,12 @@ pnpm add @mysten/sui @mysten/seal @mysten/walrus ai zod ## Quick Start ```ts -import { MemWal } from "@cmdoss/memwal"; +import { MemWal } from "@mysten/memwal"; const memwal = MemWal.create({ key: "your-delegate-key-hex", - serverUrl: "https://your-memwal-server.com", + accountId: "your-memwal-account-id", + serverUrl: "https://your-relayer-url.com", namespace: "demo", }); @@ -40,11 +38,11 @@ await memwal.restore("demo"); - Docs source of truth: `docs/` - Docs site entry points: - - [Overview](docs/about/what-is-memwal.md) - - [Build Your First Integration](docs/getting-started/for-developers.md) - - [SDK Overview](docs/sdk/overview.md) + - [What is MemWal?](docs/getting-started/what-is-memwal.md) + - [Quick Start](docs/getting-started/quick-start.md) + - [SDK Quick Start](docs/sdk/quick-start.md) - [Relayer Overview](docs/relayer/overview.md) - - [SDK API Reference](docs/reference/sdk-api.md) + - [SDK API Reference](docs/sdk/api-reference.md) ## Contributing @@ -78,9 +76,9 @@ For broader local setup guidance, see: | Entry | Description | |---|---| -| `@cmdoss/memwal` | Default client (`MemWal`). The relayer handles embedding, encryption, Walrus upload/download, retrieval, and restore. | -| `@cmdoss/memwal/manual` | Manual client flow (`MemWalManual`). You handle embedding calls and local SEAL operations. The relayer still handles upload relay, registration, search, and restore. | -| `@cmdoss/memwal/ai` | Vercel AI SDK integration - wraps `MemWal` as middleware for use with `streamText`, `generateText`, etc. | +| `@mysten/memwal` | Default client (`MemWal`). The relayer handles embedding, encryption, Walrus upload/download, retrieval, and restore. | +| `@mysten/memwal/manual` | Manual client flow (`MemWalManual`). You handle embedding calls and local SEAL operations. The relayer still handles upload relay, registration, search, and restore. | +| `@mysten/memwal/ai` | Vercel AI SDK integration - wraps `MemWal` as middleware for use with `streamText`, `generateText`, etc. | ## How It Works diff --git a/apps/app/Dockerfile b/apps/app/Dockerfile index 115c77c5..4bc5d12c 100644 --- a/apps/app/Dockerfile +++ b/apps/app/Dockerfile @@ -20,9 +20,9 @@ COPY apps/app/package.json ./apps/app/ # Install all workspace deps RUN pnpm install -# Build SDK first (apps/app depends on @cmdoss/memwal via workspace:*) +# Build SDK first (apps/app depends on @mysten/memwal via workspace:*) COPY packages/sdk/ ./packages/sdk/ -RUN pnpm --filter @cmdoss/memwal build +RUN pnpm --filter @mysten/memwal build # Copy app source COPY apps/app/ ./apps/app/ diff --git a/apps/app/index.html b/apps/app/index.html index 903503c9..b3716ce9 100644 --- a/apps/app/index.html +++ b/apps/app/index.html @@ -4,14 +4,29 @@ + + - - memwal — AI memory dashboard + content="MemWal — privacy-preserving AI memory. Store your AI conversations encrypted on Walrus, searchable with embeddings. You own your data." /> + + + + + + + + + + + + + + + MemWal — AI Memory Dashboard diff --git a/apps/app/package.json b/apps/app/package.json index ea4fc1ca..40b94b89 100644 --- a/apps/app/package.json +++ b/apps/app/package.json @@ -10,9 +10,9 @@ "preview": "vite preview" }, "dependencies": { - "@cmdoss/memwal": "workspace:*", "@mysten/dapp-kit": "^1.0.3", "@mysten/enoki": "^1.0.4", + "@mysten/memwal": "workspace:*", "@mysten/seal": "^1.1.0", "@mysten/sui": "^2.6.0", "@mysten/walrus": "^1.0.3", @@ -29,6 +29,7 @@ "react": "^19.2.0", "react-dom": "^19.2.0", "react-router-dom": "^7.13.1", + "react-syntax-highlighter": "^15.6.6", "tailwind-merge": "^3.5.0", "tailwindcss": "^4.2.1", "three": "^0.183.2", @@ -39,6 +40,7 @@ "@types/node": "^24.10.1", "@types/react": "^19.2.7", "@types/react-dom": "^19.2.3", + "@types/react-syntax-highlighter": "^15.5.13", "@vitejs/plugin-react": "^5.1.1", "eslint": "^9.39.1", "eslint-plugin-react-hooks": "^7.0.1", diff --git a/apps/app/public/android-chrome-192x192.png b/apps/app/public/android-chrome-192x192.png index c3bdb98c..1a17f2c7 100644 Binary files a/apps/app/public/android-chrome-192x192.png and b/apps/app/public/android-chrome-192x192.png differ diff --git a/apps/app/public/android-chrome-512x512.png b/apps/app/public/android-chrome-512x512.png index 21189ab1..5c3c8cd0 100644 Binary files a/apps/app/public/android-chrome-512x512.png and b/apps/app/public/android-chrome-512x512.png differ diff --git a/apps/app/public/apple-touch-icon.png b/apps/app/public/apple-touch-icon.png index 5f6a1b56..3dd3749b 100644 Binary files a/apps/app/public/apple-touch-icon.png and b/apps/app/public/apple-touch-icon.png differ diff --git a/apps/app/public/favicon-16x16.png b/apps/app/public/favicon-16x16.png index 8f08f111..bd9d160e 100644 Binary files a/apps/app/public/favicon-16x16.png and b/apps/app/public/favicon-16x16.png differ diff --git a/apps/app/public/favicon-32x32.png b/apps/app/public/favicon-32x32.png index 62147a4c..44566bcd 100644 Binary files a/apps/app/public/favicon-32x32.png and b/apps/app/public/favicon-32x32.png differ diff --git a/apps/app/public/favicon.ico b/apps/app/public/favicon.ico index 01249845..60d04bd8 100644 Binary files a/apps/app/public/favicon.ico and b/apps/app/public/favicon.ico differ diff --git a/apps/app/public/fonts/Ratch-Variable.ttf b/apps/app/public/fonts/Ratch-Variable.ttf new file mode 100644 index 00000000..fbb19050 Binary files /dev/null and b/apps/app/public/fonts/Ratch-Variable.ttf differ diff --git a/apps/app/public/memwal-grid-bg.png b/apps/app/public/memwal-grid-bg.png new file mode 100644 index 00000000..28506e58 Binary files /dev/null and b/apps/app/public/memwal-grid-bg.png differ diff --git a/apps/app/public/memwal-hero-full.png b/apps/app/public/memwal-hero-full.png new file mode 100644 index 00000000..74bd7ddd Binary files /dev/null and b/apps/app/public/memwal-hero-full.png differ diff --git a/apps/app/public/memwal-icon.svg b/apps/app/public/memwal-icon.svg new file mode 100644 index 00000000..dd239118 --- /dev/null +++ b/apps/app/public/memwal-icon.svg @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/apps/app/public/memwal-mascot.png b/apps/app/public/memwal-mascot.png new file mode 100644 index 00000000..b643f086 Binary files /dev/null and b/apps/app/public/memwal-mascot.png differ diff --git a/apps/app/public/og-image.jpg b/apps/app/public/og-image.jpg new file mode 100644 index 00000000..df7b2b31 Binary files /dev/null and b/apps/app/public/og-image.jpg differ diff --git a/apps/app/public/site.webmanifest b/apps/app/public/site.webmanifest index 45dc8a20..693cf762 100644 --- a/apps/app/public/site.webmanifest +++ b/apps/app/public/site.webmanifest @@ -1 +1,11 @@ -{"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"} \ No newline at end of file +{ + "name": "MemWal", + "short_name": "MemWal", + "icons": [ + { "src": "/android-chrome-192x192.png", "sizes": "192x192", "type": "image/png" }, + { "src": "/android-chrome-512x512.png", "sizes": "512x512", "type": "image/png" } + ], + "theme_color": "#000000", + "background_color": "#FAF8F5", + "display": "standalone" +} \ No newline at end of file diff --git a/apps/app/src/App.tsx b/apps/app/src/App.tsx index 498c156d..c4e8d3e8 100644 --- a/apps/app/src/App.tsx +++ b/apps/app/src/App.tsx @@ -16,6 +16,7 @@ import { import { isEnokiNetwork, registerEnokiWallets } from '@mysten/enoki' import { getJsonRpcFullnodeUrl } from '@mysten/sui/jsonRpc' import { QueryClient, QueryClientProvider } from '@tanstack/react-query' +import { BrowserRouter, Routes, Route, Navigate } from 'react-router-dom' import { config } from './config' import LandingPage from './pages/LandingPage' @@ -127,22 +128,20 @@ function RegisterEnokiWallets() { function AppContent() { const currentAccount = useCurrentAccount() const { delegateKey } = useDelegateKey() - const [page, setPage] = useState(() => window.location.hash.replace('#', '') || '') - - useEffect(() => { - const onHash = () => setPage(window.location.hash.replace('#', '') || '') - window.addEventListener('hashchange', onHash) - return () => window.removeEventListener('hashchange', onHash) - }, []) return ( - <> - - {!currentAccount && } - {currentAccount && !delegateKey && page !== 'playground' && } - {currentAccount && page === 'playground' && } - {currentAccount && delegateKey && page !== 'playground' && } - + + } /> + : + delegateKey ? : + } /> + : + delegateKey ? : + } /> + } /> + ) } @@ -152,17 +151,19 @@ function AppContent() { export default function App() { return ( - - - - - -
- -
-
-
-
-
+ + + + + + +
+ +
+
+
+
+
+
) } diff --git a/apps/app/src/assets/memwal-logo.svg b/apps/app/src/assets/memwal-logo.svg new file mode 100644 index 00000000..02124e7b --- /dev/null +++ b/apps/app/src/assets/memwal-logo.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/apps/app/src/index.css b/apps/app/src/index.css index 4979794a..80ae5753 100644 --- a/apps/app/src/index.css +++ b/apps/app/src/index.css @@ -1,20 +1,34 @@ -@import url('https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap'); +@import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500&display=swap'); + +@font-face { + font-family: 'Ratch'; + src: url('/fonts/Ratch-Variable.ttf') format('truetype'); + font-weight: 100 900; + font-display: swap; +} :root { - --bg-primary: #ffffff; - --bg-secondary: #fafafa; + --bg-primary: #FAF8F5; + --bg-secondary: #F5F3F0; --bg-card: #ffffff; --bg-card-hover: #e4e5e4; - --bg-input: #f0f0ee; + --bg-input: #F0EDE8; - --text-primary: #191a23; + --text-primary: #000000; --text-secondary: #3d4252; --text-muted: #505566; - --accent: #191a23; - --accent-hover: #101117; - --accent-glow: rgba(25, 26, 35, 0.18); - --accent-subtle: rgba(25, 26, 35, 0.05); + --accent: #000000; + --accent-hover: #1a1a1a; + --accent-glow: rgba(0, 0, 0, 0.18); + --accent-subtle: rgba(0, 0, 0, 0.05); + + --color-violet: #CAB1FF; + --color-yellow: #F0FFA0; + --color-tusk: #FAF8F5; + --color-violet-soft: rgba(202, 177, 255, 0.30); + --color-yellow-soft: rgba(232, 255, 117, 0.45); + --gradient-brand: linear-gradient(135deg, #CAB1FF, #E8FF75); --success: #166534; --success-border: #22c55e; @@ -23,21 +37,21 @@ --danger: #b91c1c; --danger-border: #ef4444; - --border: 2px solid #191a23; - --border-accent: 2px solid #191a23; - --border-light: 1px solid rgba(25, 26, 35, 0.18); + --border: 2px solid #000000; + --border-accent: 2px solid #000000; + --border-light: 1px solid rgba(0, 0, 0, 0.18); /* neo-brutalism flat shadow */ - --neo-shadow: 4px 4px 0 #191a23; - --neo-shadow-sm: 3px 3px 0 #191a23; - --neo-shadow-xs: 2px 2px 0 #191a23; + --neo-shadow: 4px 4px 0 #000000; + --neo-shadow-sm: 3px 3px 0 #000000; + --neo-shadow-xs: 2px 2px 0 #000000; --radius-sm: 10px; --radius-md: 12px; --radius-lg: 16px; --radius-xl: 20px; - --font-sans: 'Space Grotesk', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; + --font-sans: 'Ratch', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; --font-mono: 'JetBrains Mono', 'Fira Code', monospace; /* legacy shadows kept for modal */ @@ -46,52 +60,7 @@ --shadow-lg: 0 24px 44px rgba(0, 0, 0, 0.32); --shadow-glow: 0 0 24px rgba(0, 0, 0, 0.26); - --nav-bg: #e8eae9; -} - -@media (prefers-color-scheme: dark) { - :root { - /* Clean dark charcoal — no purple tints */ - --bg-primary: #1a1a1e; - --bg-secondary: #222228; - --bg-card: #28282f; - --bg-card-hover: #323239; - --bg-input: #222228; - - /* High-contrast readable text */ - --text-primary: #f0f0f2; - --text-secondary: #b0b0bc; - --text-muted: #70707e; - - --accent: #e8e8f0; - --accent-hover: #ffffff; - --accent-glow: rgba(255, 255, 255, 0.06); - --accent-subtle: rgba(255, 255, 255, 0.04); - - --success: #4ade80; - --success-border: #22c55e; - --warning: #fbbf24; - --warning-border: #f59e0b; - --danger: #f87171; - --danger-border: #ef4444; - - /* Soft subtle borders — not harsh white */ - --border: 1px solid rgba(255, 255, 255, 0.10); - --border-accent: 1px solid rgba(255, 255, 255, 0.18); - --border-light: 1px solid rgba(255, 255, 255, 0.06); - - /* Restored neo-brutalist offset shadows — black instead of white */ - --neo-shadow: 6px 6px 0 #000000; - --neo-shadow-sm: 5px 5px 0 #000000; - --neo-shadow-xs: 3px 3px 0 #000000; - - --shadow-sm: 0 1px 4px rgba(0, 0, 0, 0.5); - --shadow-md: 0 8px 24px rgba(0, 0, 0, 0.6); - --shadow-lg: 0 20px 48px rgba(0, 0, 0, 0.7); - --shadow-glow: 0 0 20px rgba(255, 255, 255, 0.05); - - --nav-bg: #1c1c22; - } + --nav-bg: #F0EDE8; } * { @@ -102,6 +71,7 @@ html { font-size: 17px; + font-weight: 500; } html, @@ -118,6 +88,10 @@ body { background-image: none; } +h1, h2, h3 { + font-weight: 800; +} + /* ========== Layout ========== */ .app { @@ -125,6 +99,8 @@ body { display: flex; flex-direction: column; position: relative; + background: linear-gradient(180deg, #CAB1FF 0%, #E8FF75 100%); + min-height: 100vh; } /* Floating Docs Button */ @@ -135,13 +111,13 @@ body { width: 72px; height: 72px; border-radius: 50%; - background: #22d3ee; - color: #ffffff; + background: #000000; + color: #FAF8F5; display: flex; align-items: center; justify-content: center; text-decoration: none; - box-shadow: 4px 4px 0 #191a23; + box-shadow: 4px 4px 0 #000000; z-index: 9999; transition: transform 0.2s, box-shadow 0.2s; overflow: hidden; @@ -158,23 +134,12 @@ body { .floating-docs-btn:hover { transform: translate(-3px, -3px); - box-shadow: 8px 8px 0 #191a23; + box-shadow: 8px 8px 0 #000000; } .floating-docs-btn:active { transform: translate(3px, 3px); - box-shadow: 3px 3px 0 #191a23; -} - -/* Dark mode */ -@media (prefers-color-scheme: dark) { - .floating-docs-btn { - background: #22d3ee; - box-shadow: 4px 4px 0 rgba(255, 255, 255, 0.15); - } - .floating-docs-btn:hover { - box-shadow: 6px 6px 0 rgba(255, 255, 255, 0.2); - } + box-shadow: 3px 3px 0 #000000; } .container { @@ -190,18 +155,22 @@ body { position: sticky; top: 0; z-index: 50; - background: var(--nav-bg); - border-bottom: 1px solid var(--border); - padding: 0 24px; + background: #CAB1FF; + border-bottom: none; + padding: 0 48px; + height: 72px; + display: flex; + align-items: center; } .nav-inner { - max-width: 960px; + max-width: 1280px; margin: 0 auto; display: flex; align-items: center; justify-content: space-between; - height: 64px; + height: 72px; + width: 100%; } .nav-brand { @@ -225,12 +194,24 @@ body { .nav-address { font-size: 0.8rem; - color: var(--text-secondary); + color: #000000; font-family: var(--font-mono); - background: var(--bg-card); + background: rgba(0, 0, 0, 0.06); padding: 6px 12px; border-radius: 999px; - border: 1px solid var(--border); + border: none; +} + +.nav-docs-link { + font-size: 0.85rem; + font-weight: 500; + color: #000000; + text-decoration: none; + transition: opacity 0.2s; +} + +.nav-docs-link:hover { + opacity: 0.7; } /* ========== Buttons ========== */ @@ -256,16 +237,15 @@ body { } .btn-primary { - background: #191a23; - color: #f5f7f6; - border: 2px solid #191a23; - box-shadow: 3px 3px 0 #6b6d7a; + background: #000000; + color: #E8FF75; + border: 2px solid #000000; + box-shadow: 3px 3px 0 #CAB1FF; } .btn-primary:hover:not(:disabled) { - background: #101117; - box-shadow: none; transform: translate(3px, 3px); + box-shadow: none; } .btn-primary:disabled { @@ -276,16 +256,15 @@ body { } .btn-secondary { - background: var(--bg-card); - color: var(--text-primary); - border: var(--border); - box-shadow: var(--neo-shadow-xs); + background: #CAB1FF; + color: #000000; + border: 2px solid #000000; + box-shadow: 2px 2px 0 #000000; } .btn-secondary:hover:not(:disabled) { - background: var(--bg-card-hover); - box-shadow: none; transform: translate(2px, 2px); + box-shadow: none; } .btn-danger { @@ -338,11 +317,11 @@ body { /* ========== Cards ========== */ .card { - background: var(--bg-card); - border: var(--border); - border-radius: var(--radius-md); + background: #FAF8F5; + border: 2px solid #000000; + border-radius: 12px; padding: 24px; - box-shadow: var(--neo-shadow); + box-shadow: 4px 4px 0 #000000; } .card:hover { @@ -443,465 +422,338 @@ body { color: var(--text-muted); } -/* ========== Landing Rebrand (Positivus-inspired) ========== */ +/* ========== Landing Page ========== */ -.lp-bg { +.lp-page { min-height: 100vh; - padding: 24px 22px; + background: var(--color-violet); display: flex; - align-items: center; - justify-content: center; - background: var(--bg-primary); + flex-direction: column; + color-scheme: light; } -.lp-sheet { - max-width: 1080px; - margin: 0 auto; - padding: 30px; - border-radius: 24px; - border: 2px solid #191a23; - background: #f6f6f6; - box-shadow: 0 24px 60px rgba(0, 0, 0, 0.35); -} +/* ── Nav ── */ -.lp-hero { - display: grid; - grid-template-columns: 1.05fr 1fr; - gap: 28px; +.lp-nav { + padding: 0 48px; + height: 72px; + display: flex; align-items: center; - margin-bottom: 42px; -} - -.lp-copy h1 { - color: #191a23; - font-size: clamp(2.2rem, 5.6vw, 3.6rem); - line-height: 1.06; - letter-spacing: -0.03em; - margin: 10px 0 14px; } -.lp-copy p { - color: #3d4252; - font-size: 1rem; - line-height: 1.6; - max-width: 560px; - margin-bottom: 20px; -} - -.lp-kicker { - display: inline-block; - color: #ffffff; - background: #111111; - border: 2px solid #111111; - border-radius: 10px; - padding: 5px 11px; - font-size: 0.75rem; - letter-spacing: 0.06em; - font-weight: 700; +.lp-nav-inner { + width: 100%; + display: flex; + align-items: center; + justify-content: space-between; } -.lp-btn-main { - background: #191a23; - color: #f5f7fb; - border: 2px solid #191a23; - border-radius: 12px; - font-size: 0.94rem; - font-weight: 600; - padding: 12px 20px; +.lp-nav-brand { + display: flex; + align-items: center; + text-decoration: none; } -.lp-btn-main:hover { - transform: translateY(-1px); - background: #101117; +.lp-nav-brand img { + height: 28px; } -.lp-btn-docs { - background: transparent; - color: #191a23; - border: 2px solid #191a23; +.lp-nav-links { + display: flex; + align-items: center; + gap: 32px; } -.lp-btn-docs:hover { - background: #191a23; - color: #f5f7fb; - transform: translateY(-1px); +.lp-nav-links a:not(.lp-nav-cta) { + color: #000000; + text-decoration: none; + font-size: 0.92rem; + font-weight: 500; + transition: opacity 0.2s; } -.lp-connect-fallback { - display: inline-flex; +.lp-nav-links a:not(.lp-nav-cta):hover { + opacity: 0.7; } -.lp-connect-fallback button { - text-transform: lowercase; +.lp-nav-github { + display: flex; + align-items: center; + gap: 6px; + color: #000000; + text-decoration: none; + font-size: 0.92rem; + font-weight: 500; + transition: opacity 0.2s; } -.lp-cta-row { - display: flex; - align-items: stretch; - gap: 20px; +.lp-nav-github:hover { + opacity: 0.7; } -.lp-cta-row > button.btn { - background: #191a23; - color: #f5f7fb; - border: 2px solid #191a23; +.lp-nav-cta { + background: #E8FF75; + color: #000000; + border: 2px solid #000000; border-radius: 12px; - font-size: 0.94rem; - font-weight: 600; - padding: 8px 24px; - cursor: pointer; - text-transform: lowercase; + padding: 10px 22px; + font-size: 0.92rem; + font-weight: 700; font-family: var(--font-sans); - line-height: 1.4; - box-sizing: border-box; - box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); + cursor: pointer; + transition: transform 0.15s, box-shadow 0.15s; + box-shadow: 3px 3px 0 #000000; } -.lp-illustration { - position: relative; - height: 320px; - border-radius: 22px; - border: 2px solid #191a23; - background: linear-gradient(135deg, #e8e8e8, #d0d0d0); - overflow: hidden; +.lp-nav-cta:hover { + transform: translate(-2px, -2px); + box-shadow: 5px 5px 0 #000000; } -.lp-mega { - position: absolute; - width: 180px; - height: 110px; - border: 3px solid #191a23; - border-radius: 28px 68px 28px 68px; - background: #ffffff; - transform: rotate(-24deg); - top: 106px; - left: 78px; +.lp-nav-cta:active { + transform: translate(2px, 2px); + box-shadow: 1px 1px 0 #000000; } -.lp-orbit { - position: absolute; - border: 2px solid #3e4252; - border-radius: 999px; -} +/* ── Hero ── */ -.lp-orbit-a { - width: 260px; - height: 100px; - top: 84px; - left: 40px; - transform: rotate(14deg); +.lp-hero { + flex: 1; + display: flex; + align-items: center; + padding: 0 0 0 48px; } -.lp-orbit-b { - width: 230px; - height: 88px; - top: 118px; - left: 58px; - transform: rotate(-7deg); +.lp-hero-inner { + width: 100%; + display: grid; + grid-template-columns: 3fr 2fr; + gap: 40px; + align-items: center; } -.lp-dot { - position: absolute; - width: 18px; - height: 18px; - border-radius: 999px; - background: #191a23; - top: 72px; - right: 88px; +.lp-hero-copy h1 { + color: #000000; + font-size: clamp(2.8rem, 6vw, 5rem); + font-weight: 600; + line-height: 1.04; + letter-spacing: -0.03em; + margin-bottom: 20px; } -.lp-star { - position: absolute; - font-size: 30px; - color: #191a23; - right: 42px; - bottom: 44px; +.lp-hero-copy p { + color: #2d2d3a; + font-size: 1rem; + line-height: 1.7; + max-width: 480px; + margin-bottom: 30px; } -.lp-trust { +/* ── CTA buttons ── */ + +.lp-hero-actions { display: flex; + align-items: center; + gap: 16px; flex-wrap: wrap; - gap: 20px; - justify-content: space-between; - margin-top: 22px; - padding: 16px 0 8px; - border-top: 2px dashed #d0d4dc; } -.lp-trust span { - color: #505566; - font-size: 0.92rem; - font-weight: 600; - letter-spacing: 0.03em; - text-transform: lowercase; -} - -.lp-services { - margin-top: 20px; -} - -.lp-footer { - display: flex; - justify-content: space-between; +.lp-btn-yellow { + background: #E8FF75; + color: #000000; + border: 2px solid #000000; + border-radius: 12px; + padding: 12px 26px; + font-size: 0.94rem; + font-weight: 700; + font-family: var(--font-sans); + cursor: pointer; + transition: transform 0.15s, box-shadow 0.15s; + box-shadow: 3px 3px 0 #000000; + display: inline-flex; align-items: center; - padding: 24px 0; - margin-top: 40px; - border-top: 1px solid var(--border); - font-size: 0.8rem; - color: var(--text-muted); + gap: 6px; } -.lp-footer-docs { - color: var(--text-secondary); - text-decoration: none; - font-weight: 500; +.lp-btn-yellow:hover { + transform: translate(-2px, -2px); + box-shadow: 5px 5px 0 #000000; } -.lp-footer-docs:hover { - color: var(--text-primary); +.lp-btn-yellow:active { + transform: translate(2px, 2px); + box-shadow: 1px 1px 0 #000000; } -.lp-title-row { - display: flex; +.lp-btn-outline { + background: transparent; + color: #000000; + border: 2px solid #000000; + border-radius: 12px; + padding: 12px 26px; + font-size: 0.94rem; + font-weight: 600; + font-family: var(--font-sans); + cursor: pointer; + text-decoration: none; + transition: background 0.2s, color 0.2s, transform 0.15s; + display: inline-flex; align-items: center; - gap: 14px; - flex-wrap: wrap; - margin-bottom: 14px; + gap: 6px; } -.lp-title-row h2 { - font-size: 1.1rem; +.lp-btn-outline:hover { + background: #000000; color: #ffffff; - background: #191a23; - border: 2px solid #191a23; - border-radius: 8px; - padding: 2px 8px; -} - -.lp-title-row p { - color: #4a5163; - font-size: 0.86rem; -} - -.lp-grid { - display: grid; - grid-template-columns: 1fr 1fr; - gap: 14px; -} - -.lp-service-card { - border: 2px solid #191a23; - border-radius: 18px; - background: #ffffff; - padding: 18px; - box-shadow: 0 5px 0 #191a23; + transform: translateY(-1px); } -.lp-service-card h3 { - color: #191a23; - font-size: 1.05rem; - margin-bottom: 8px; +.lp-arrow { + font-size: 0.85em; + display: inline-block; + transition: transform 0.2s; } -.lp-service-card p { - color: #4f566a; - font-size: 0.86rem; +.lp-btn-yellow:hover .lp-arrow, +.lp-btn-outline:hover .lp-arrow, +.lp-nav-cta:hover .lp-arrow { + transform: translate(2px, -2px); } -.lp-service-card--lime { - background: #f0f0f0; -} +/* ── Hero Art (mascot + grid bg) ── */ -.lp-service-card--dark { - background: #191a23; +.lp-hero-art { + position: relative; + height: 520px; + display: flex; + align-items: flex-end; + justify-content: center; + overflow: visible; } -.lp-service-card--dark h3, -.lp-service-card--dark p { - color: #e9edf8; +.lp-hero-grid { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: -20%; + width: 120%; + height: 100%; + object-fit: cover; + object-position: left center; + border-radius: 0; + opacity: 0.85; } -.lp-dark-band { - margin-top: 18px; - border: 2px solid #191a23; - border-radius: 20px; - background: #191a23; - color: #e9edf8; - padding: 20px; - display: flex; - align-items: center; - justify-content: space-between; - gap: 20px; +.lp-hero-mascot { + position: relative; + z-index: 1; + height: 100%; + max-height: 520px; + object-fit: contain; + filter: drop-shadow(0 12px 32px rgba(0, 0, 0, 0.15)); + transform: translateX(-10%); } -.lp-dark-band h3 { - font-size: 1.16rem; - margin-bottom: 6px; -} +/* ── Landing page Connect button override ── */ -.lp-dark-band p { - color: #c4cade; - font-size: 0.9rem; +.lp-hero-actions [class*="ConnectButton"] button, +.lp-hero-actions button[data-dapp-kit] { + background: #E8FF75 !important; + color: #000000 !important; + border: 2px solid #000000 !important; + border-radius: 12px !important; + padding: 12px 26px !important; + font-size: 0.94rem !important; + font-weight: 700 !important; + font-family: var(--font-sans) !important; + box-shadow: 3px 3px 0 #000000 !important; } -.lp-band-link { - flex-shrink: 0; - display: inline-flex; - align-items: center; - justify-content: center; - background: #ffffff; - border: 2px solid #ffffff; - color: #111111; - border-radius: 12px; - padding: 10px 14px; - text-decoration: none; - font-size: 0.88rem; - font-weight: 700; +.lp-nav-links [class*="ConnectButton"] button, +.lp-nav-links button[data-dapp-kit] { + background: #E8FF75 !important; + color: #000000 !important; + border: 2px solid #000000 !important; + border-radius: 12px !important; + padding: 10px 22px !important; + font-size: 0.92rem !important; + font-weight: 700 !important; + font-family: var(--font-sans) !important; + box-shadow: 3px 3px 0 #000000 !important; + transition: transform 0.15s, box-shadow 0.15s !important; } -.lp-band-link:hover { - background: #e8e8e8; +.lp-nav-links [class*="ConnectButton"] button:hover, +.lp-nav-links button[data-dapp-kit]:hover { + transform: translate(-2px, -2px) !important; + box-shadow: 5px 5px 0 #000000 !important; } -@media (prefers-color-scheme: dark) { - .nav-brand span { - color: var(--text-primary); - } - - .lp-bg { - background: var(--bg-primary); - } - - .lp-sheet { - background: #1a1a1a; - border-color: #444444; - box-shadow: 0 24px 56px rgba(0, 0, 0, 0.5); - } - - .lp-copy h1 { - color: #f5f5f5; - } - - .lp-copy p { - color: #d4d4d4; - } - - .lp-kicker { - color: #f5f5f5; - background: #111111; - border-color: #f5f5f5; - } - - .lp-illustration { - border-color: #444444; - background: linear-gradient(140deg, #2a2a2a, #1e1e1e); - box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.04); - } - - .lp-mega { - background: #eeeeee; - border-color: #cccccc; - box-shadow: 0 10px 26px rgba(0, 0, 0, 0.4); - } - - .lp-orbit { - border-color: rgba(200, 200, 200, 0.3); - } - - .lp-dot { - background: #eeeeee; - box-shadow: 0 0 0 6px rgba(255, 255, 255, 0.04); - } - - .lp-star { - color: #aaaaaa; - } - - .lp-trust { - border-top-color: #444444; - } - - .lp-trust span { - color: #c0c0c0; - } - - .lp-title-row h2 { - color: #f5f5f5; - background: #111111; - border-color: #eeeeee; - } +/* ── Responsive ── */ - .lp-title-row p { - color: #c0c0c0; +@media (max-width: 860px) { + .lp-nav { + padding: 0 24px; } - .lp-service-card { - background: #242424; - border-color: #444444; - box-shadow: 0 5px 0 #444444; + .lp-hero { + padding: 0 24px; } - .lp-service-card h3 { - color: #f0f0f0; + .lp-hero-inner { + grid-template-columns: 1fr; + gap: 32px; + text-align: center; } - .lp-service-card p { - color: #c0c0c0; + .lp-hero-copy p { + margin-left: auto; + margin-right: auto; } - .lp-service-card--lime { - background: #2c2c2c; - border-color: #666666; - box-shadow: 0 5px 0 #555555; + .lp-hero-actions { + justify-content: center; } - .lp-service-card--lime h3, - .lp-service-card--lime p { - color: #f0f0f0; + .lp-hero-art { + height: 360px; } - .lp-service-card--dark { - background: #111111; - border-color: #444444; - box-shadow: 0 5px 0 #333333; + .lp-nav-links a:not(.lp-nav-cta) { + display: none; } +} - .lp-service-card--dark h3, - .lp-service-card--dark p { - color: #f0f0f0; +@media (max-width: 480px) { + .lp-hero-copy h1 { + font-size: 2rem; } - .lp-btn-docs { - color: #f0f0f0; - border-color: #f0f0f0; + .lp-hero-art { + height: 280px; } - .lp-btn-docs:hover { - background: #f0f0f0; - color: #191a23; + .lp-hero-actions { + flex-direction: column; + gap: 12px; } - .lp-cta-row > button.btn { - background: #444444; - color: #f0f0f0; - border-color: #555555; + .lp-btn-yellow, + .lp-btn-outline { + width: 100%; + justify-content: center; } } + /* ========== Dashboard ========== */ .dashboard { padding: 40px 0; -} - -.dashboard > .card { - background: #f0f0ee; -} - -@media (prefers-color-scheme: dark) { - .dashboard > .card { - background: #1e1e24; - } + max-width: 960px; + margin: 0 auto; + padding: 40px 24px; } .dashboard-header { @@ -910,13 +762,14 @@ body { .dashboard-header h2 { font-size: 1.5rem; - font-weight: 700; - letter-spacing: -0.02em; + font-weight: 800; + letter-spacing: -0.03em; margin-bottom: 6px; + color: #000000; } .dashboard-header p { - color: var(--text-secondary); + color: #2d2d3a; font-size: 0.9rem; } @@ -928,8 +781,8 @@ body { text-decoration: none; margin-bottom: 24px; border-radius: var(--radius-md); - border: 2px solid #191a23; - background: #b8b9c4; + border: 2px solid #000000; + background: var(--color-violet); padding: 18px 24px; box-shadow: var(--neo-shadow); cursor: pointer; @@ -1146,26 +999,27 @@ body { .input-group label { display: block; font-size: 0.8rem; - color: var(--text-secondary); + font-weight: 700; + color: #000000; margin-bottom: 6px; } .input { width: 100%; padding: 10px 14px; - background: var(--bg-primary); - border: var(--border); - border-radius: var(--radius-sm); - color: var(--text-primary); + background: #FAF8F5; + border: 2px solid #000000; + border-radius: 10px; + color: #000000; font-family: var(--font-sans); font-size: 0.875rem; - box-shadow: var(--neo-shadow-xs); + box-shadow: 2px 2px 0 #000000; transition: box-shadow 0.15s ease; } .input:focus { outline: none; - box-shadow: var(--neo-shadow-xs); + box-shadow: 2px 2px 0 #000000; } /* ========== Spinner ========== */ @@ -1252,36 +1106,26 @@ body { } .demo-step-badge--highlight { - background: #191a23; - color: #f5f7f6; + background: var(--color-yellow); + color: #000000; box-shadow: var(--neo-shadow-xs); } -@media (prefers-color-scheme: dark) { - .demo-step-badge { - background: var(--bg-card); - border: var(--border-accent); - color: var(--text-primary); - } - - .demo-step-badge--highlight { - background: #e8e8f0; - color: #0f0f11; - border: none; - } +.demo-step-title { + color: var(--text-primary); } .demo-code-block { - background: #ffffff; - border: var(--border); - border-radius: var(--radius-md); + background: #FAF8F5; + border: 2px solid #000000; + border-radius: 12px; padding: 16px; overflow: auto; font-size: 0.78rem; line-height: 1.7; font-family: var(--font-mono); - color: var(--text-secondary); - box-shadow: var(--neo-shadow-xs); + color: #2d2d3a; + box-shadow: 2px 2px 0 #000000; } .install-command { @@ -1289,6 +1133,45 @@ body { font-weight: 700; } +.install-tabs { + display: flex; + gap: 0; + overflow: hidden; +} + +.install-tab { + padding: 10px 20px; + font-size: 0.82rem; + font-weight: 600; + font-family: var(--font-mono); + background: transparent; + color: var(--text-muted); + border: 2px solid #000000; + border-bottom: none; + border-right: none; + border-radius: 10px 10px 0 0; + cursor: pointer; + transition: background 0.15s, color 0.15s; +} + +.install-tab:last-child { + border-right: 2px solid #000000; +} + +.install-tab:hover { + background: rgba(0, 0, 0, 0.04); +} + +.install-tab--active { + background: #E8FF75; + color: #000000; + font-weight: 700; +} + +.install-tabs + .demo-code-block { + border-top-left-radius: 0; +} + .demo-code-block--spaced { margin-bottom: 12px; } @@ -1396,14 +1279,14 @@ body { } .demo-server-tag { - background: var(--bg-card); - border: var(--border); - border-radius: var(--radius-sm); + background: #E8FF75; + border: 2px solid #000000; + border-radius: 10px; padding: 8px 16px; font-size: 0.8rem; font-family: var(--font-mono); - color: var(--text-secondary); - box-shadow: var(--neo-shadow-xs); + color: #000000; + box-shadow: 2px 2px 0 #000000; } .demo-tag-value { @@ -1437,112 +1320,6 @@ body { text-decoration: none; } -@media (prefers-color-scheme: dark) { - .install-command { - color: var(--text-primary); - font-weight: 700; - } - - .key-display .key-label { - color: var(--text-muted); - } - - .key-display { - background: var(--bg-card); - border: var(--border-accent); - } - - .key-display--white { - background: var(--bg-card); - border: var(--border-accent); - } - - .demo-code-block { - background: #141418; - border: var(--border); - color: var(--text-secondary); - } - - .warning-box { - background: rgba(251, 191, 36, 0.08); - border-color: rgba(245, 158, 11, 0.5); - } - - .nav { - border-bottom: 1px solid rgba(255, 255, 255, 0.07); - } - - .demo-info-label { - color: var(--text-muted); - } - - .demo-tag-value--server { - color: var(--text-primary); - } - - .demo-tag-value--sdk { - color: var(--text-secondary); - } - - /* Cards in dark: neo-brutalist with black offset shadow */ - .card { - border: var(--border); - box-shadow: var(--neo-shadow); - } - - .stat-card { - border: var(--border); - box-shadow: var(--neo-shadow); - } - - .dashboard-cta { - background: #484854; - border-color: rgba(255,255,255,0.25); - } - - .dashboard-cta-title { - color: #f5f5f8; - } - - .dashboard-cta-subtitle { - color: #c0c0cc; - } - - .demo-server-tag { - border: var(--border); - box-shadow: none; - } - - .btn-secondary { - border: var(--border-accent); - background: var(--bg-card); - } - - .btn-primary { - background: #e8e8f0; - color: #0f0f11; - border: 2px solid #000000; - box-shadow: var(--neo-shadow-sm); - } - - .btn-primary:hover:not(:disabled) { - background: #ffffff; - transform: translate(5px, 5px); - box-shadow: none; - } - - .nav-address { - background: var(--bg-card); - border: var(--border); - } - - .modal { - background: var(--bg-card); - border: var(--border-accent); - box-shadow: 0 24px 60px rgba(0,0,0,0.7); - } -} - /* ========== Responsive ========== */ @media (max-width: 640px) { diff --git a/apps/app/src/pages/Dashboard.tsx b/apps/app/src/pages/Dashboard.tsx index dd2b7ca4..29e66a2a 100644 --- a/apps/app/src/pages/Dashboard.tsx +++ b/apps/app/src/pages/Dashboard.tsx @@ -10,10 +10,20 @@ import { useSuiClient, } from '@mysten/dapp-kit' import { useSponsoredTransaction } from '../hooks/useSponsoredTransaction' -import { generateDelegateKey, addDelegateKey, removeDelegateKey } from '@cmdoss/memwal/account' -import type { WalletSigner } from '@cmdoss/memwal/manual' +import { generateDelegateKey, addDelegateKey, removeDelegateKey } from '@mysten/memwal/account' +import type { WalletSigner } from '@mysten/memwal/manual' +import { Link } from 'react-router-dom' +import { Copy, Eye, EyeOff, Trash2, RefreshCw, Plus, LogOut } from 'lucide-react' +import { Light as SyntaxHighlighter } from 'react-syntax-highlighter' +import js from 'react-syntax-highlighter/dist/esm/languages/hljs/javascript' +import bash from 'react-syntax-highlighter/dist/esm/languages/hljs/bash' +import { githubGist } from 'react-syntax-highlighter/dist/esm/styles/hljs' + +SyntaxHighlighter.registerLanguage('javascript', js) +SyntaxHighlighter.registerLanguage('bash', bash) import { useDelegateKey } from '../App' import { config } from '../config' +import memwalLogo from '../assets/memwal-logo.svg' // ============================================================ // Types @@ -41,6 +51,7 @@ export default function Dashboard() { const address = currentAccount?.address || '' const [showKey, setShowKey] = useState(false) const [copied, setCopied] = useState(null) + const [pkgManager, setPkgManager] = useState<'npm' | 'pnpm' | 'yarn' | 'bun'>('npm') // Delegate key management state const [onChainKeys, setOnChainKeys] = useState([]) @@ -197,7 +208,7 @@ export default function Dashboard() { // SDK code snippets // ============================================================ - const sdkSnippet = `import { MemWal } from "@cmdoss/memwal" + const sdkSnippet = `import { MemWal } from "@mysten/memwal" const memwal = MemWal.create({ key: "${delegateKey?.slice(0, 8)}...${delegateKey?.slice(-8)}", @@ -213,7 +224,7 @@ const result = await memwal.recall("food allergies") console.log(result.results[0].text)` const aiSnippet = `import { generateText } from "ai" -import { withMemWal } from "@cmdoss/memwal/ai" +import { withMemWal } from "@mysten/memwal/ai" import { openai } from "@ai-sdk/openai" const model = withMemWal(openai("gpt-4o"), { @@ -234,15 +245,15 @@ const result = await generateText({ <>