diff --git a/.changeset/tidy-squids-end.md b/.changeset/tidy-squids-end.md deleted file mode 100644 index 4f00a5d5b94..00000000000 --- a/.changeset/tidy-squids-end.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@thirdweb-dev/service-utils": patch ---- - -Accept Request in authorizeNode diff --git a/.changeset/tricky-pears-check.md b/.changeset/tricky-pears-check.md new file mode 100644 index 00000000000..7cde4a548b6 --- /dev/null +++ b/.changeset/tricky-pears-check.md @@ -0,0 +1,5 @@ +--- +"thirdweb": patch +--- + +Adds Humanity Testnet as a legacy transaction chain diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 6c84a081eb8..07beb51f0a8 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1,26 +1,18 @@ # Order is important; the last matching pattern takes the most precedence. # default ownership group -- @jnsdls @joaquim-verges @MananTank @gregfromstl +@thirdweb-dev/developer-tools # packages -packages/thirdweb/ @joaquim-verges @gregfromstl @jnsdls +packages/thirdweb/ @thirdweb-dev/core-platform @thirdweb-dev/developer-tools ## specific thirdweb pieces -packages/thirdweb/src/react/ @joaquim-verges @gregfromstl @MananTank @jnsdls @edwardysun -packages/thirdweb/src/reactive/ @joaquim-verges @gregfromstl @MananTank @jnsdls -packages/thirdweb/src/gas/ @joaquim-verges @jnsdls -packages/thirdweb/src/pay/ @joaquim-verges @gregfromstl @MananTank @jnsdls @edwardysun -packages/service-utils/ @arcoraven @jnsdls @joaquim-verges -packages/eslint-config-thirdweb/ @jnsdls @joaquim-verges -packages/tw-tsconfig/ @jnsdls @joaquim-verges +packages/service-utils/ @thirdweb-dev/core-platform +packages/eslint-config-thirdweb/ @thirdweb-dev/core-platform @edwardysun +packages/tw-tsconfig/ @thirdweb-dev/core-platform @edwardysun # apps -apps/ @jnsdls @joaquim-verges -apps/dashboard/ @jnsdls @MananTank @joaquim-verges @jakubkrehel -apps/playground-web/ @joaquim-verges @gregfromstl @jnsdls @joaquim-verges @jakubkrehel -apps/wallet-ui/ @gregfromstl @jnsdls @joaquim-verges @MananTank @jakubkrehel -apps/portal/ @thirdweb-dev/product @thirdweb-dev/platform @thirdweb-dev/infra +apps/ @thirdweb-dev/developer-tools @thirdweb-dev/core-platform @jakubkrehel # .github folder + .changeset + turbo config is owned by jonas for now scripts/ @jnsdls @joaquim-verges diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 2513960703b..e88f64e74ee 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -5,12 +5,18 @@ version: 2 updates: - - package-ecosystem: "npm" # See documentation for possible values - directory: "/" # Location of package manifests + - package-ecosystem: "npm" + directory: "/" schedule: interval: "weekly" + ignore: + - dependency-name: "@aws-sdk/client-kms" + versions: ["3.592.0"] + - dependency-name: "@aws-sdk/client-lambda" + versions: ["3.592.0"] + - dependency-name: "@aws-sdk/credential-providers" + versions: ["3.592.0"] - package-ecosystem: "github-actions" directory: "/" schedule: - # Check for updates to GitHub Actions every week interval: "weekly" diff --git a/.github/workflows/auto-assign.yml b/.github/workflows/auto-assign.yml index 0c78598d065..8d08b73452e 100644 --- a/.github/workflows/auto-assign.yml +++ b/.github/workflows/auto-assign.yml @@ -2,7 +2,7 @@ name: Auto Author Assign on: pull_request: - types: [ opened, reopened ] + types: [opened, reopened] permissions: pull-requests: write @@ -10,5 +10,9 @@ permissions: jobs: assign-author: runs-on: ubuntu-latest + if: | + github.event.pull_request.author_association == 'MEMBER' || + github.event.pull_request.author_association == 'OWNER' || + github.event.pull_request.author_association == 'COLLABORATOR' steps: - uses: toshimaru/auto-author-assign@v2.1.1 diff --git a/.github/workflows/issue.yml b/.github/workflows/issue.yml index 9a141a6c280..ef8e9ad22cc 100644 --- a/.github/workflows/issue.yml +++ b/.github/workflows/issue.yml @@ -2,10 +2,10 @@ name: Linked Issue on: pull_request: - types: [opened, edited] + types: [opened, edited, ready_for_review] env: - VALID_ISSUE_PREFIXES: "CNCT|DASH|PROT|INSIGHT" + VALID_ISSUE_PREFIXES: "CORE|TOOL" jobs: linear: @@ -22,6 +22,17 @@ jobs: pull_number: context.issue.number }); + // Check if contributor is external + const isInternalContributor = ['MEMBER', 'OWNER', 'COLLABORATOR'].includes( + context.payload.pull_request.author_association + ); + + // Automatically pass for external contributors + if (!isInternalContributor) { + console.log('External contributor detected - automatically passing check'); + return; + } + const body = pr.data.body || ''; const branchName = pr.data.head.ref; const issueRegex = new RegExp(`(${process.env.VALID_ISSUE_PREFIXES})-\\d+`, 'i'); diff --git a/.github/workflows/typedoc.yml b/.github/workflows/typedoc.yml new file mode 100644 index 00000000000..9ef79f524fa --- /dev/null +++ b/.github/workflows/typedoc.yml @@ -0,0 +1,50 @@ +name: TypeDoc + +on: + push: + branches: + - main + +permissions: + contents: read + pages: write + id-token: write + +# Allow only one concurrent deployment +concurrency: + group: "typedoc" + cancel-in-progress: true + +jobs: + build: + name: "Generate TypeDoc" + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Install + uses: ./.github/composite-actions/install + + - name: Run TypeDoc + run: pnpm typedoc + + - name: Update Gist + uses: actions/github-script@v7 + with: + github-token: ${{ secrets.GIST_TOKEN }} + script: | + const fs = require('fs'); + const content = fs.readFileSync('./packages/thirdweb/typedoc/parsed.json', 'utf8'); + const gistId = '678fe1f331a01270bb002fee660f285d'; + + await github.rest.gists.update({ + gist_id: gistId, + files: { + 'data.json': { + content: content + } + } + }); + + console.log(`Permalink: https://gist.githubusercontent.com/raw/${gistId}/data.json`); diff --git a/apps/dashboard/next-env.d.ts b/apps/dashboard/next-env.d.ts index 725dd6f2451..3cd7048ed94 100644 --- a/apps/dashboard/next-env.d.ts +++ b/apps/dashboard/next-env.d.ts @@ -3,4 +3,4 @@ /// // NOTE: This file should not be edited -// see https://nextjs.org/docs/app/building-your-application/configuring/typescript for more information. +// see https://nextjs.org/docs/app/api-reference/config/typescript for more information. diff --git a/apps/dashboard/package.json b/apps/dashboard/package.json index 4862744e870..4393893a341 100644 --- a/apps/dashboard/package.json +++ b/apps/dashboard/package.json @@ -4,7 +4,7 @@ "private": true, "scripts": { "preinstall": "npx only-allow pnpm", - "dev": "next dev", + "dev": "next dev --turbo", "build": "NODE_OPTIONS=--max-old-space-size=6144 next build", "start": "next start", "format": "biome format ./src --write", @@ -30,28 +30,28 @@ "@hookform/resolvers": "^3.9.1", "@marsidev/react-turnstile": "^1.1.0", "@n8tb1t/use-scroll-position": "^2.0.3", - "@radix-ui/react-accordion": "^1.2.1", - "@radix-ui/react-alert-dialog": "^1.1.2", - "@radix-ui/react-avatar": "^1.1.1", - "@radix-ui/react-checkbox": "^1.1.2", - "@radix-ui/react-dialog": "1.1.2", - "@radix-ui/react-dropdown-menu": "^2.1.2", - "@radix-ui/react-hover-card": "^1.1.2", - "@radix-ui/react-label": "^2.1.0", - "@radix-ui/react-popover": "^1.1.2", - "@radix-ui/react-progress": "^1.1.0", - "@radix-ui/react-radio-group": "^1.2.1", - "@radix-ui/react-select": "^2.1.2", - "@radix-ui/react-separator": "^1.1.0", - "@radix-ui/react-slot": "^1.1.0", - "@radix-ui/react-switch": "^1.1.1", - "@radix-ui/react-tooltip": "1.1.4", - "@sentry/nextjs": "8.43.0", - "@shazow/whatsabi": "^0.17.0", + "@radix-ui/react-accordion": "^1.2.2", + "@radix-ui/react-alert-dialog": "^1.1.3", + "@radix-ui/react-avatar": "^1.1.2", + "@radix-ui/react-checkbox": "^1.1.3", + "@radix-ui/react-dialog": "1.1.3", + "@radix-ui/react-dropdown-menu": "^2.1.3", + "@radix-ui/react-hover-card": "^1.1.3", + "@radix-ui/react-label": "^2.1.1", + "@radix-ui/react-popover": "^1.1.3", + "@radix-ui/react-progress": "^1.1.1", + "@radix-ui/react-radio-group": "^1.2.2", + "@radix-ui/react-select": "^2.1.3", + "@radix-ui/react-separator": "^1.1.1", + "@radix-ui/react-slot": "^1.1.1", + "@radix-ui/react-switch": "^1.1.2", + "@radix-ui/react-tooltip": "1.1.5", + "@sentry/nextjs": "8.45.1", + "@shazow/whatsabi": "^0.18.0", "@tanstack/react-query": "5.62.7", - "@tanstack/react-table": "^8.17.3", + "@tanstack/react-table": "^8.20.6", "@thirdweb-dev/service-utils": "workspace:*", - "@vercel/functions": "^1.5.1", + "@vercel/functions": "^1.5.2", "@vercel/og": "^0.6.4", "abitype": "1.0.7", "chakra-react-select": "^4.7.6", @@ -62,7 +62,7 @@ "date-fns": "4.1.0", "fetch-event-stream": "0.1.5", "flat": "^6.0.1", - "framer-motion": "11.13.5", + "framer-motion": "11.15.0", "fuse.js": "7.0.0", "input-otp": "^1.4.1", "ioredis": "^5.4.1", @@ -133,7 +133,7 @@ "eslint-config-biome": "1.9.4", "eslint-plugin-react-compiler": "19.0.0-beta-df7b47d-20241124", "eslint-plugin-storybook": "^0.11.1", - "knip": "5.39.4", + "knip": "5.41.0", "next-sitemap": "^4.2.3", "postcss": "8.4.49", "storybook": "8.4.7", diff --git a/apps/dashboard/public/assets/ambassadors/access-icon.svg b/apps/dashboard/public/assets/ambassadors/access-icon.svg deleted file mode 100644 index d4b3f7938b6..00000000000 --- a/apps/dashboard/public/assets/ambassadors/access-icon.svg +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - diff --git a/apps/dashboard/public/assets/ambassadors/bank.jpg b/apps/dashboard/public/assets/ambassadors/bank.jpg deleted file mode 100644 index bbd26e987c9..00000000000 Binary files a/apps/dashboard/public/assets/ambassadors/bank.jpg and /dev/null differ diff --git a/apps/dashboard/public/assets/ambassadors/brolag.jpg b/apps/dashboard/public/assets/ambassadors/brolag.jpg deleted file mode 100644 index f72cc6f5cc3..00000000000 Binary files a/apps/dashboard/public/assets/ambassadors/brolag.jpg and /dev/null differ diff --git a/apps/dashboard/public/assets/ambassadors/card-1-icon.svg b/apps/dashboard/public/assets/ambassadors/card-1-icon.svg deleted file mode 100644 index 5b203c30667..00000000000 --- a/apps/dashboard/public/assets/ambassadors/card-1-icon.svg +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/apps/dashboard/public/assets/ambassadors/card-2-icon.svg b/apps/dashboard/public/assets/ambassadors/card-2-icon.svg deleted file mode 100644 index 718bd947aaa..00000000000 --- a/apps/dashboard/public/assets/ambassadors/card-2-icon.svg +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - diff --git a/apps/dashboard/public/assets/ambassadors/card-3-icon.svg b/apps/dashboard/public/assets/ambassadors/card-3-icon.svg deleted file mode 100644 index 1a8f675b3b1..00000000000 --- a/apps/dashboard/public/assets/ambassadors/card-3-icon.svg +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - - - - - - diff --git a/apps/dashboard/public/assets/ambassadors/connections.svg b/apps/dashboard/public/assets/ambassadors/connections.svg deleted file mode 100644 index 3c1d4f52a65..00000000000 --- a/apps/dashboard/public/assets/ambassadors/connections.svg +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/apps/dashboard/public/assets/ambassadors/danny.jpeg b/apps/dashboard/public/assets/ambassadors/danny.jpeg deleted file mode 100644 index c04c36fcc2e..00000000000 Binary files a/apps/dashboard/public/assets/ambassadors/danny.jpeg and /dev/null differ diff --git a/apps/dashboard/public/assets/ambassadors/frankramos.jpeg b/apps/dashboard/public/assets/ambassadors/frankramos.jpeg deleted file mode 100644 index ed1579b3ed6..00000000000 Binary files a/apps/dashboard/public/assets/ambassadors/frankramos.jpeg and /dev/null differ diff --git a/apps/dashboard/public/assets/ambassadors/gi.jpg b/apps/dashboard/public/assets/ambassadors/gi.jpg deleted file mode 100644 index b2d8f0aa099..00000000000 Binary files a/apps/dashboard/public/assets/ambassadors/gi.jpg and /dev/null differ diff --git a/apps/dashboard/public/assets/ambassadors/hackathon.svg b/apps/dashboard/public/assets/ambassadors/hackathon.svg deleted file mode 100644 index 732a588224d..00000000000 --- a/apps/dashboard/public/assets/ambassadors/hackathon.svg +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - diff --git a/apps/dashboard/public/assets/ambassadors/learn.svg b/apps/dashboard/public/assets/ambassadors/learn.svg deleted file mode 100644 index 31f8fa915aa..00000000000 --- a/apps/dashboard/public/assets/ambassadors/learn.svg +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/apps/dashboard/public/assets/ambassadors/matt.png b/apps/dashboard/public/assets/ambassadors/matt.png deleted file mode 100644 index 16cf38e24fd..00000000000 Binary files a/apps/dashboard/public/assets/ambassadors/matt.png and /dev/null differ diff --git a/apps/dashboard/public/assets/ambassadors/mentorship-icon.svg b/apps/dashboard/public/assets/ambassadors/mentorship-icon.svg deleted file mode 100644 index f4fc28ac472..00000000000 --- a/apps/dashboard/public/assets/ambassadors/mentorship-icon.svg +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - diff --git a/apps/dashboard/public/assets/ambassadors/merch-icon.svg b/apps/dashboard/public/assets/ambassadors/merch-icon.svg deleted file mode 100644 index fa3cced957c..00000000000 --- a/apps/dashboard/public/assets/ambassadors/merch-icon.svg +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - diff --git a/apps/dashboard/public/assets/ambassadors/myCreativeOwl.jpg b/apps/dashboard/public/assets/ambassadors/myCreativeOwl.jpg deleted file mode 100644 index 928b2b67ec3..00000000000 Binary files a/apps/dashboard/public/assets/ambassadors/myCreativeOwl.jpg and /dev/null differ diff --git a/apps/dashboard/public/assets/ambassadors/myk.png b/apps/dashboard/public/assets/ambassadors/myk.png deleted file mode 100644 index 67131ca664c..00000000000 Binary files a/apps/dashboard/public/assets/ambassadors/myk.png and /dev/null differ diff --git a/apps/dashboard/public/assets/ambassadors/naman.jpg b/apps/dashboard/public/assets/ambassadors/naman.jpg deleted file mode 100644 index 30010b3001d..00000000000 Binary files a/apps/dashboard/public/assets/ambassadors/naman.jpg and /dev/null differ diff --git a/apps/dashboard/public/assets/ambassadors/network-icon.svg b/apps/dashboard/public/assets/ambassadors/network-icon.svg deleted file mode 100644 index 6530e2b3e74..00000000000 --- a/apps/dashboard/public/assets/ambassadors/network-icon.svg +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - diff --git a/apps/dashboard/public/assets/ambassadors/office-hours.svg b/apps/dashboard/public/assets/ambassadors/office-hours.svg deleted file mode 100644 index 670e75ede25..00000000000 --- a/apps/dashboard/public/assets/ambassadors/office-hours.svg +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/apps/dashboard/public/assets/ambassadors/oss.svg b/apps/dashboard/public/assets/ambassadors/oss.svg deleted file mode 100644 index 2f0a663d4d7..00000000000 --- a/apps/dashboard/public/assets/ambassadors/oss.svg +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/apps/dashboard/public/assets/ambassadors/paula.png b/apps/dashboard/public/assets/ambassadors/paula.png deleted file mode 100644 index 97212c75094..00000000000 Binary files a/apps/dashboard/public/assets/ambassadors/paula.png and /dev/null differ diff --git a/apps/dashboard/public/assets/ambassadors/recognition-icon.svg b/apps/dashboard/public/assets/ambassadors/recognition-icon.svg deleted file mode 100644 index ad0d7bfc343..00000000000 --- a/apps/dashboard/public/assets/ambassadors/recognition-icon.svg +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - - - - - - diff --git a/apps/dashboard/public/assets/ambassadors/rexan.jpg b/apps/dashboard/public/assets/ambassadors/rexan.jpg deleted file mode 100644 index f79970c5ed9..00000000000 Binary files a/apps/dashboard/public/assets/ambassadors/rexan.jpg and /dev/null differ diff --git a/apps/dashboard/public/assets/ambassadors/samu.jpeg b/apps/dashboard/public/assets/ambassadors/samu.jpeg deleted file mode 100644 index beaa8c9eef1..00000000000 Binary files a/apps/dashboard/public/assets/ambassadors/samu.jpeg and /dev/null differ diff --git a/apps/dashboard/public/assets/ambassadors/takaji.jpg b/apps/dashboard/public/assets/ambassadors/takaji.jpg deleted file mode 100644 index 61588b4c13c..00000000000 Binary files a/apps/dashboard/public/assets/ambassadors/takaji.jpg and /dev/null differ diff --git a/apps/dashboard/public/assets/ambassadors/tanay.png b/apps/dashboard/public/assets/ambassadors/tanay.png deleted file mode 100644 index e1ae9a56328..00000000000 Binary files a/apps/dashboard/public/assets/ambassadors/tanay.png and /dev/null differ diff --git a/apps/dashboard/public/assets/ambassadors/yuki.png b/apps/dashboard/public/assets/ambassadors/yuki.png deleted file mode 100644 index 038b0dc6162..00000000000 Binary files a/apps/dashboard/public/assets/ambassadors/yuki.png and /dev/null differ diff --git a/apps/dashboard/public/assets/chain-icons/polygon.png b/apps/dashboard/public/assets/chain-icons/polygon.png deleted file mode 100644 index fe700d12b04..00000000000 Binary files a/apps/dashboard/public/assets/chain-icons/polygon.png and /dev/null differ diff --git a/apps/dashboard/public/assets/community/gallery/3.png b/apps/dashboard/public/assets/community/gallery/3.png deleted file mode 100644 index ac2a03661ae..00000000000 Binary files a/apps/dashboard/public/assets/community/gallery/3.png and /dev/null differ diff --git a/apps/dashboard/public/assets/community/gallery/4.png b/apps/dashboard/public/assets/community/gallery/4.png deleted file mode 100644 index db67748e5f9..00000000000 Binary files a/apps/dashboard/public/assets/community/gallery/4.png and /dev/null differ diff --git a/apps/dashboard/public/assets/community/gallery/5.png b/apps/dashboard/public/assets/community/gallery/5.png deleted file mode 100644 index 405e664a924..00000000000 Binary files a/apps/dashboard/public/assets/community/gallery/5.png and /dev/null differ diff --git a/apps/dashboard/public/assets/community/gallery/6.png b/apps/dashboard/public/assets/community/gallery/6.png deleted file mode 100644 index 46b642bfbe0..00000000000 Binary files a/apps/dashboard/public/assets/community/gallery/6.png and /dev/null differ diff --git a/apps/dashboard/public/assets/community/gallery/7.png b/apps/dashboard/public/assets/community/gallery/7.png deleted file mode 100644 index 6d797a23a73..00000000000 Binary files a/apps/dashboard/public/assets/community/gallery/7.png and /dev/null differ diff --git a/apps/dashboard/public/assets/community/gallery/8.png b/apps/dashboard/public/assets/community/gallery/8.png deleted file mode 100644 index e4883ab0c6c..00000000000 Binary files a/apps/dashboard/public/assets/community/gallery/8.png and /dev/null differ diff --git a/apps/dashboard/public/assets/community/gallery/9.png b/apps/dashboard/public/assets/community/gallery/9.png deleted file mode 100644 index aea30abfb9a..00000000000 Binary files a/apps/dashboard/public/assets/community/gallery/9.png and /dev/null differ diff --git a/apps/dashboard/public/assets/community/home/ambassadors.svg b/apps/dashboard/public/assets/community/home/ambassadors.svg deleted file mode 100644 index 7d0f9985d7b..00000000000 --- a/apps/dashboard/public/assets/community/home/ambassadors.svg +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/apps/dashboard/public/assets/community/home/bug-bounty.svg b/apps/dashboard/public/assets/community/home/bug-bounty.svg deleted file mode 100644 index 440e80c81ea..00000000000 --- a/apps/dashboard/public/assets/community/home/bug-bounty.svg +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - diff --git a/apps/dashboard/public/assets/community/home/discord.png b/apps/dashboard/public/assets/community/home/discord.png deleted file mode 100644 index 92f3e9d5396..00000000000 Binary files a/apps/dashboard/public/assets/community/home/discord.png and /dev/null differ diff --git a/apps/dashboard/public/assets/community/home/events.svg b/apps/dashboard/public/assets/community/home/events.svg deleted file mode 100644 index 39462d9ffd0..00000000000 --- a/apps/dashboard/public/assets/community/home/events.svg +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/apps/dashboard/public/assets/community/home/hackathon.svg b/apps/dashboard/public/assets/community/home/hackathon.svg deleted file mode 100644 index c560cf8b340..00000000000 --- a/apps/dashboard/public/assets/community/home/hackathon.svg +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - diff --git a/apps/dashboard/public/assets/community/home/learn.svg b/apps/dashboard/public/assets/community/home/learn.svg deleted file mode 100644 index 20c8b0162e7..00000000000 --- a/apps/dashboard/public/assets/community/home/learn.svg +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/apps/dashboard/public/assets/community/home/office-hours.svg b/apps/dashboard/public/assets/community/home/office-hours.svg deleted file mode 100644 index 626dcf504c8..00000000000 --- a/apps/dashboard/public/assets/community/home/office-hours.svg +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/apps/dashboard/public/assets/community/home/oss.svg b/apps/dashboard/public/assets/community/home/oss.svg deleted file mode 100644 index 2f0a663d4d7..00000000000 --- a/apps/dashboard/public/assets/community/home/oss.svg +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/apps/dashboard/public/assets/grant/superchain/blog-background.png b/apps/dashboard/public/assets/grant/superchain/blog-background.png deleted file mode 100644 index 0970b1a75bf..00000000000 Binary files a/apps/dashboard/public/assets/grant/superchain/blog-background.png and /dev/null differ diff --git a/apps/dashboard/public/assets/grant/superchain/campNetwork-icon.jpg b/apps/dashboard/public/assets/grant/superchain/campNetwork-icon.jpg deleted file mode 100644 index a088c90ae99..00000000000 Binary files a/apps/dashboard/public/assets/grant/superchain/campNetwork-icon.jpg and /dev/null differ diff --git a/apps/dashboard/public/assets/grant/superchain/icon-ancient8.png b/apps/dashboard/public/assets/grant/superchain/icon-ancient8.png deleted file mode 100644 index a040acc31af..00000000000 Binary files a/apps/dashboard/public/assets/grant/superchain/icon-ancient8.png and /dev/null differ diff --git a/apps/dashboard/public/assets/grant/superchain/icon-arena-z.png b/apps/dashboard/public/assets/grant/superchain/icon-arena-z.png deleted file mode 100644 index 8ceef84d704..00000000000 Binary files a/apps/dashboard/public/assets/grant/superchain/icon-arena-z.png and /dev/null differ diff --git a/apps/dashboard/public/assets/grant/superchain/icon-base.png b/apps/dashboard/public/assets/grant/superchain/icon-base.png deleted file mode 100644 index 31269cac4df..00000000000 Binary files a/apps/dashboard/public/assets/grant/superchain/icon-base.png and /dev/null differ diff --git a/apps/dashboard/public/assets/grant/superchain/icon-cyber.png b/apps/dashboard/public/assets/grant/superchain/icon-cyber.png deleted file mode 100644 index 3672d667292..00000000000 Binary files a/apps/dashboard/public/assets/grant/superchain/icon-cyber.png and /dev/null differ diff --git a/apps/dashboard/public/assets/grant/superchain/icon-dashboard.svg b/apps/dashboard/public/assets/grant/superchain/icon-dashboard.svg deleted file mode 100644 index 97b4fc8ac53..00000000000 --- a/apps/dashboard/public/assets/grant/superchain/icon-dashboard.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/apps/dashboard/public/assets/grant/superchain/icon-donatuz.png b/apps/dashboard/public/assets/grant/superchain/icon-donatuz.png deleted file mode 100644 index 57c81b70312..00000000000 Binary files a/apps/dashboard/public/assets/grant/superchain/icon-donatuz.png and /dev/null differ diff --git a/apps/dashboard/public/assets/grant/superchain/icon-fraxtal.png b/apps/dashboard/public/assets/grant/superchain/icon-fraxtal.png deleted file mode 100644 index cfcef716ecd..00000000000 Binary files a/apps/dashboard/public/assets/grant/superchain/icon-fraxtal.png and /dev/null differ diff --git a/apps/dashboard/public/assets/grant/superchain/icon-lisk.png b/apps/dashboard/public/assets/grant/superchain/icon-lisk.png deleted file mode 100644 index 81f474debef..00000000000 Binary files a/apps/dashboard/public/assets/grant/superchain/icon-lisk.png and /dev/null differ diff --git a/apps/dashboard/public/assets/grant/superchain/icon-mode.png b/apps/dashboard/public/assets/grant/superchain/icon-mode.png deleted file mode 100644 index 33507cac81c..00000000000 Binary files a/apps/dashboard/public/assets/grant/superchain/icon-mode.png and /dev/null differ diff --git a/apps/dashboard/public/assets/grant/superchain/icon-op.png b/apps/dashboard/public/assets/grant/superchain/icon-op.png deleted file mode 100644 index abb5e215417..00000000000 Binary files a/apps/dashboard/public/assets/grant/superchain/icon-op.png and /dev/null differ diff --git a/apps/dashboard/public/assets/grant/superchain/icon-redstone.png b/apps/dashboard/public/assets/grant/superchain/icon-redstone.png deleted file mode 100644 index 3ab966e5d63..00000000000 Binary files a/apps/dashboard/public/assets/grant/superchain/icon-redstone.png and /dev/null differ diff --git a/apps/dashboard/public/assets/grant/superchain/icon-smart-wallet.svg b/apps/dashboard/public/assets/grant/superchain/icon-smart-wallet.svg deleted file mode 100644 index 6a6f1b8fa56..00000000000 --- a/apps/dashboard/public/assets/grant/superchain/icon-smart-wallet.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/apps/dashboard/public/assets/grant/superchain/icon-tool.svg b/apps/dashboard/public/assets/grant/superchain/icon-tool.svg deleted file mode 100644 index 751a14e9ab4..00000000000 --- a/apps/dashboard/public/assets/grant/superchain/icon-tool.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/apps/dashboard/public/assets/grant/superchain/icon-zora.png b/apps/dashboard/public/assets/grant/superchain/icon-zora.png deleted file mode 100644 index fdbc5d53cdc..00000000000 Binary files a/apps/dashboard/public/assets/grant/superchain/icon-zora.png and /dev/null differ diff --git a/apps/dashboard/public/assets/grant/superchain/link.svg b/apps/dashboard/public/assets/grant/superchain/link.svg deleted file mode 100644 index 2f7e695ed94..00000000000 --- a/apps/dashboard/public/assets/grant/superchain/link.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/apps/dashboard/public/assets/grant/superchain/logo-dashboard.png b/apps/dashboard/public/assets/grant/superchain/logo-dashboard.png deleted file mode 100644 index aa9aa254d54..00000000000 Binary files a/apps/dashboard/public/assets/grant/superchain/logo-dashboard.png and /dev/null differ diff --git a/apps/dashboard/public/assets/grant/superchain/mantle-icon.png b/apps/dashboard/public/assets/grant/superchain/mantle-icon.png deleted file mode 100644 index 8a7c7f96207..00000000000 Binary files a/apps/dashboard/public/assets/grant/superchain/mantle-icon.png and /dev/null differ diff --git a/apps/dashboard/public/assets/grant/superchain/op-thirdweb.png b/apps/dashboard/public/assets/grant/superchain/op-thirdweb.png deleted file mode 100644 index 8f6028ceaae..00000000000 Binary files a/apps/dashboard/public/assets/grant/superchain/op-thirdweb.png and /dev/null differ diff --git a/apps/dashboard/public/assets/grant/superchain/overlay.png b/apps/dashboard/public/assets/grant/superchain/overlay.png deleted file mode 100644 index 4e6ccc0d28d..00000000000 Binary files a/apps/dashboard/public/assets/grant/superchain/overlay.png and /dev/null differ diff --git a/apps/dashboard/public/assets/grant/superchain/soneium-icon.png b/apps/dashboard/public/assets/grant/superchain/soneium-icon.png deleted file mode 100644 index 66ed3a103a8..00000000000 Binary files a/apps/dashboard/public/assets/grant/superchain/soneium-icon.png and /dev/null differ diff --git a/apps/dashboard/public/assets/hackathon/sponsors/optimism.png b/apps/dashboard/public/assets/hackathon/sponsors/optimism.png deleted file mode 100644 index ac69a0f881f..00000000000 Binary files a/apps/dashboard/public/assets/hackathon/sponsors/optimism.png and /dev/null differ diff --git a/apps/dashboard/public/assets/hackathon/sponsors/polygon.png b/apps/dashboard/public/assets/hackathon/sponsors/polygon.png deleted file mode 100644 index d888869e789..00000000000 Binary files a/apps/dashboard/public/assets/hackathon/sponsors/polygon.png and /dev/null differ diff --git a/apps/dashboard/public/assets/landingpage/aavegotchi.png b/apps/dashboard/public/assets/landingpage/aavegotchi.png deleted file mode 100644 index 8f22f68e27d..00000000000 Binary files a/apps/dashboard/public/assets/landingpage/aavegotchi.png and /dev/null differ diff --git a/apps/dashboard/public/assets/landingpage/animoca.png b/apps/dashboard/public/assets/landingpage/animoca.png deleted file mode 100644 index 1630a01f44c..00000000000 Binary files a/apps/dashboard/public/assets/landingpage/animoca.png and /dev/null differ diff --git a/apps/dashboard/public/assets/landingpage/avacloud.png b/apps/dashboard/public/assets/landingpage/avacloud.png deleted file mode 100644 index 2cfcfe576b9..00000000000 Binary files a/apps/dashboard/public/assets/landingpage/avacloud.png and /dev/null differ diff --git a/apps/dashboard/public/assets/landingpage/coinbase.png b/apps/dashboard/public/assets/landingpage/coinbase.png deleted file mode 100644 index 86c5b654fe6..00000000000 Binary files a/apps/dashboard/public/assets/landingpage/coinbase.png and /dev/null differ diff --git a/apps/dashboard/public/assets/landingpage/coolcats.png b/apps/dashboard/public/assets/landingpage/coolcats.png deleted file mode 100644 index 2396c089055..00000000000 Binary files a/apps/dashboard/public/assets/landingpage/coolcats.png and /dev/null differ diff --git a/apps/dashboard/public/assets/landingpage/desktop/audience.png b/apps/dashboard/public/assets/landingpage/desktop/audience.png deleted file mode 100644 index ac667a219bd..00000000000 Binary files a/apps/dashboard/public/assets/landingpage/desktop/audience.png and /dev/null differ diff --git a/apps/dashboard/public/assets/landingpage/desktop/full-stack.png b/apps/dashboard/public/assets/landingpage/desktop/full-stack.png deleted file mode 100644 index 04b16219b17..00000000000 Binary files a/apps/dashboard/public/assets/landingpage/desktop/full-stack.png and /dev/null differ diff --git a/apps/dashboard/public/assets/landingpage/desktop/parallax-left.png b/apps/dashboard/public/assets/landingpage/desktop/parallax-left.png deleted file mode 100644 index a223774911a..00000000000 Binary files a/apps/dashboard/public/assets/landingpage/desktop/parallax-left.png and /dev/null differ diff --git a/apps/dashboard/public/assets/landingpage/desktop/parallax-right-v2.png b/apps/dashboard/public/assets/landingpage/desktop/parallax-right-v2.png deleted file mode 100644 index ba5db88bd85..00000000000 Binary files a/apps/dashboard/public/assets/landingpage/desktop/parallax-right-v2.png and /dev/null differ diff --git a/apps/dashboard/public/assets/landingpage/desktop/parallax-right.png b/apps/dashboard/public/assets/landingpage/desktop/parallax-right.png deleted file mode 100644 index 9c57731d990..00000000000 Binary files a/apps/dashboard/public/assets/landingpage/desktop/parallax-right.png and /dev/null differ diff --git a/apps/dashboard/public/assets/landingpage/desktop/xl-logo.png b/apps/dashboard/public/assets/landingpage/desktop/xl-logo.png deleted file mode 100644 index 3deba2d6564..00000000000 Binary files a/apps/dashboard/public/assets/landingpage/desktop/xl-logo.png and /dev/null differ diff --git a/apps/dashboard/public/assets/landingpage/games.png b/apps/dashboard/public/assets/landingpage/games.png deleted file mode 100644 index 0110913d8aa..00000000000 Binary files a/apps/dashboard/public/assets/landingpage/games.png and /dev/null differ diff --git a/apps/dashboard/public/assets/landingpage/infinigods.png b/apps/dashboard/public/assets/landingpage/infinigods.png deleted file mode 100644 index 19e098c053b..00000000000 Binary files a/apps/dashboard/public/assets/landingpage/infinigods.png and /dev/null differ diff --git a/apps/dashboard/public/assets/landingpage/layer3.png b/apps/dashboard/public/assets/landingpage/layer3.png deleted file mode 100644 index 0eca3568af4..00000000000 Binary files a/apps/dashboard/public/assets/landingpage/layer3.png and /dev/null differ diff --git a/apps/dashboard/public/assets/landingpage/mcfarlane.png b/apps/dashboard/public/assets/landingpage/mcfarlane.png deleted file mode 100644 index 83c2ff7bbd3..00000000000 Binary files a/apps/dashboard/public/assets/landingpage/mcfarlane.png and /dev/null differ diff --git a/apps/dashboard/public/assets/landingpage/mirror.png b/apps/dashboard/public/assets/landingpage/mirror.png deleted file mode 100644 index ce6a1dce356..00000000000 Binary files a/apps/dashboard/public/assets/landingpage/mirror.png and /dev/null differ diff --git a/apps/dashboard/public/assets/landingpage/mobile/audience.png b/apps/dashboard/public/assets/landingpage/mobile/audience.png deleted file mode 100644 index b171eaeffb0..00000000000 Binary files a/apps/dashboard/public/assets/landingpage/mobile/audience.png and /dev/null differ diff --git a/apps/dashboard/public/assets/landingpage/mobile/complexity.png b/apps/dashboard/public/assets/landingpage/mobile/complexity.png deleted file mode 100644 index c43e0cbe61b..00000000000 Binary files a/apps/dashboard/public/assets/landingpage/mobile/complexity.png and /dev/null differ diff --git a/apps/dashboard/public/assets/landingpage/mobile/full-stack.png b/apps/dashboard/public/assets/landingpage/mobile/full-stack.png deleted file mode 100644 index ea30393b7f1..00000000000 Binary files a/apps/dashboard/public/assets/landingpage/mobile/full-stack.png and /dev/null differ diff --git a/apps/dashboard/public/assets/landingpage/mobile/parallax-left-v2.png b/apps/dashboard/public/assets/landingpage/mobile/parallax-left-v2.png deleted file mode 100644 index b30570cc782..00000000000 Binary files a/apps/dashboard/public/assets/landingpage/mobile/parallax-left-v2.png and /dev/null differ diff --git a/apps/dashboard/public/assets/landingpage/mobile/parallax-left.png b/apps/dashboard/public/assets/landingpage/mobile/parallax-left.png deleted file mode 100644 index e75e2ec06d9..00000000000 Binary files a/apps/dashboard/public/assets/landingpage/mobile/parallax-left.png and /dev/null differ diff --git a/apps/dashboard/public/assets/landingpage/mobile/parallax-right.png b/apps/dashboard/public/assets/landingpage/mobile/parallax-right.png deleted file mode 100644 index 212f75d61ed..00000000000 Binary files a/apps/dashboard/public/assets/landingpage/mobile/parallax-right.png and /dev/null differ diff --git a/apps/dashboard/public/assets/landingpage/mobile/user-experience.png b/apps/dashboard/public/assets/landingpage/mobile/user-experience.png deleted file mode 100644 index 3ac5feb97ae..00000000000 Binary files a/apps/dashboard/public/assets/landingpage/mobile/user-experience.png and /dev/null differ diff --git a/apps/dashboard/public/assets/landingpage/mobile/web1.png b/apps/dashboard/public/assets/landingpage/mobile/web1.png deleted file mode 100644 index f1f3159c483..00000000000 Binary files a/apps/dashboard/public/assets/landingpage/mobile/web1.png and /dev/null differ diff --git a/apps/dashboard/public/assets/landingpage/mobile/web2.png b/apps/dashboard/public/assets/landingpage/mobile/web2.png deleted file mode 100644 index 602ff79e7cb..00000000000 Binary files a/apps/dashboard/public/assets/landingpage/mobile/web2.png and /dev/null differ diff --git a/apps/dashboard/public/assets/landingpage/mobile/web3.png b/apps/dashboard/public/assets/landingpage/mobile/web3.png deleted file mode 100644 index 7928ce568cf..00000000000 Binary files a/apps/dashboard/public/assets/landingpage/mobile/web3.png and /dev/null differ diff --git a/apps/dashboard/public/assets/landingpage/mobile/xl-logo.png b/apps/dashboard/public/assets/landingpage/mobile/xl-logo.png deleted file mode 100644 index 581a3ba025e..00000000000 Binary files a/apps/dashboard/public/assets/landingpage/mobile/xl-logo.png and /dev/null differ diff --git a/apps/dashboard/public/assets/landingpage/myna.png b/apps/dashboard/public/assets/landingpage/myna.png deleted file mode 100644 index 43613572c94..00000000000 Binary files a/apps/dashboard/public/assets/landingpage/myna.png and /dev/null differ diff --git a/apps/dashboard/public/assets/landingpage/pixels.png b/apps/dashboard/public/assets/landingpage/pixels.png deleted file mode 100644 index 4622bb15f92..00000000000 Binary files a/apps/dashboard/public/assets/landingpage/pixels.png and /dev/null differ diff --git a/apps/dashboard/public/assets/landingpage/rarible.png b/apps/dashboard/public/assets/landingpage/rarible.png deleted file mode 100644 index 0be0992c975..00000000000 Binary files a/apps/dashboard/public/assets/landingpage/rarible.png and /dev/null differ diff --git a/apps/dashboard/public/assets/landingpage/torque.png b/apps/dashboard/public/assets/landingpage/torque.png deleted file mode 100644 index 1300a29c481..00000000000 Binary files a/apps/dashboard/public/assets/landingpage/torque.png and /dev/null differ diff --git a/apps/dashboard/public/assets/landingpage/treasure.png b/apps/dashboard/public/assets/landingpage/treasure.png deleted file mode 100644 index a24d4d9fa1d..00000000000 Binary files a/apps/dashboard/public/assets/landingpage/treasure.png and /dev/null differ diff --git a/apps/dashboard/public/assets/landingpage/ztx.png b/apps/dashboard/public/assets/landingpage/ztx.png deleted file mode 100644 index 893fe6ddf7b..00000000000 Binary files a/apps/dashboard/public/assets/landingpage/ztx.png and /dev/null differ diff --git a/apps/dashboard/public/assets/og-image/mission.png b/apps/dashboard/public/assets/og-image/mission.png deleted file mode 100644 index e1668112b74..00000000000 Binary files a/apps/dashboard/public/assets/og-image/mission.png and /dev/null differ diff --git a/apps/dashboard/public/assets/partners/avalanche_white.png b/apps/dashboard/public/assets/partners/avalanche_white.png deleted file mode 100644 index 0edd1dfa01b..00000000000 Binary files a/apps/dashboard/public/assets/partners/avalanche_white.png and /dev/null differ diff --git a/apps/dashboard/public/assets/partners/aws.png b/apps/dashboard/public/assets/partners/aws.png deleted file mode 100644 index 7a97937920a..00000000000 Binary files a/apps/dashboard/public/assets/partners/aws.png and /dev/null differ diff --git a/apps/dashboard/public/assets/partners/coinbase.png b/apps/dashboard/public/assets/partners/coinbase.png deleted file mode 100644 index 34766ece60b..00000000000 Binary files a/apps/dashboard/public/assets/partners/coinbase.png and /dev/null differ diff --git a/apps/dashboard/public/assets/partners/coinbaseventures.png b/apps/dashboard/public/assets/partners/coinbaseventures.png deleted file mode 100644 index 28161f9b742..00000000000 Binary files a/apps/dashboard/public/assets/partners/coinbaseventures.png and /dev/null differ diff --git a/apps/dashboard/public/assets/partners/coolcats.png b/apps/dashboard/public/assets/partners/coolcats.png deleted file mode 100644 index 0e6975ce864..00000000000 Binary files a/apps/dashboard/public/assets/partners/coolcats.png and /dev/null differ diff --git a/apps/dashboard/public/assets/partners/cpg.png b/apps/dashboard/public/assets/partners/cpg.png deleted file mode 100644 index 164f7435485..00000000000 Binary files a/apps/dashboard/public/assets/partners/cpg.png and /dev/null differ diff --git a/apps/dashboard/public/assets/partners/finc.png b/apps/dashboard/public/assets/partners/finc.png deleted file mode 100644 index 622ace73e8b..00000000000 Binary files a/apps/dashboard/public/assets/partners/finc.png and /dev/null differ diff --git a/apps/dashboard/public/assets/partners/haun.png b/apps/dashboard/public/assets/partners/haun.png deleted file mode 100644 index cbaa363b54a..00000000000 Binary files a/apps/dashboard/public/assets/partners/haun.png and /dev/null differ diff --git a/apps/dashboard/public/assets/partners/infinigods.png b/apps/dashboard/public/assets/partners/infinigods.png deleted file mode 100644 index a7735837633..00000000000 Binary files a/apps/dashboard/public/assets/partners/infinigods.png and /dev/null differ diff --git a/apps/dashboard/public/assets/partners/layer3.png b/apps/dashboard/public/assets/partners/layer3.png deleted file mode 100644 index b41cc1d14de..00000000000 Binary files a/apps/dashboard/public/assets/partners/layer3.png and /dev/null differ diff --git a/apps/dashboard/public/assets/partners/monad.png b/apps/dashboard/public/assets/partners/monad.png deleted file mode 100644 index de25569bc74..00000000000 Binary files a/apps/dashboard/public/assets/partners/monad.png and /dev/null differ diff --git a/apps/dashboard/public/assets/partners/optimism.png b/apps/dashboard/public/assets/partners/optimism.png deleted file mode 100644 index 00e7907ea74..00000000000 Binary files a/apps/dashboard/public/assets/partners/optimism.png and /dev/null differ diff --git a/apps/dashboard/public/assets/partners/polygon.png b/apps/dashboard/public/assets/partners/polygon.png deleted file mode 100644 index 4c70bcd7503..00000000000 Binary files a/apps/dashboard/public/assets/partners/polygon.png and /dev/null differ diff --git a/apps/dashboard/public/assets/partners/rarible.png b/apps/dashboard/public/assets/partners/rarible.png deleted file mode 100644 index 1f3407e574a..00000000000 Binary files a/apps/dashboard/public/assets/partners/rarible.png and /dev/null differ diff --git a/apps/dashboard/public/assets/partners/shopify.png b/apps/dashboard/public/assets/partners/shopify.png deleted file mode 100644 index 99d3c54fa96..00000000000 Binary files a/apps/dashboard/public/assets/partners/shopify.png and /dev/null differ diff --git a/apps/dashboard/public/assets/partners/techstars.png b/apps/dashboard/public/assets/partners/techstars.png deleted file mode 100644 index 6afe453f989..00000000000 Binary files a/apps/dashboard/public/assets/partners/techstars.png and /dev/null differ diff --git a/apps/dashboard/public/assets/partners/treasure.png b/apps/dashboard/public/assets/partners/treasure.png deleted file mode 100644 index ae8db98bc65..00000000000 Binary files a/apps/dashboard/public/assets/partners/treasure.png and /dev/null differ diff --git a/apps/dashboard/public/assets/product-pages-icons/contracts/icon-dashboard.svg b/apps/dashboard/public/assets/product-pages-icons/contracts/icon-dashboard.svg deleted file mode 100644 index 5dfe7cd5170..00000000000 --- a/apps/dashboard/public/assets/product-pages-icons/contracts/icon-dashboard.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/apps/dashboard/public/assets/product-pages-icons/contracts/icon-smart-wallet.svg b/apps/dashboard/public/assets/product-pages-icons/contracts/icon-smart-wallet.svg deleted file mode 100644 index 6d92008611d..00000000000 --- a/apps/dashboard/public/assets/product-pages-icons/contracts/icon-smart-wallet.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/apps/dashboard/public/assets/product-pages-icons/contracts/icon-tool.svg b/apps/dashboard/public/assets/product-pages-icons/contracts/icon-tool.svg deleted file mode 100644 index 46b3d99eaeb..00000000000 --- a/apps/dashboard/public/assets/product-pages-icons/contracts/icon-tool.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/apps/dashboard/public/assets/product-pages-icons/infra/icon-dashboard.svg b/apps/dashboard/public/assets/product-pages-icons/infra/icon-dashboard.svg deleted file mode 100644 index 9326b1dcef8..00000000000 --- a/apps/dashboard/public/assets/product-pages-icons/infra/icon-dashboard.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/apps/dashboard/public/assets/product-pages-icons/payments/icon-smart-wallet.svg b/apps/dashboard/public/assets/product-pages-icons/payments/icon-smart-wallet.svg deleted file mode 100644 index 457312149d3..00000000000 --- a/apps/dashboard/public/assets/product-pages-icons/payments/icon-smart-wallet.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/apps/dashboard/public/assets/product-pages-icons/wallets/icon-smart-wallet.svg b/apps/dashboard/public/assets/product-pages-icons/wallets/icon-smart-wallet.svg deleted file mode 100644 index abfae1bfe64..00000000000 --- a/apps/dashboard/public/assets/product-pages-icons/wallets/icon-smart-wallet.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/apps/dashboard/public/assets/product-pages/engine/coinbase.png b/apps/dashboard/public/assets/product-pages/engine/coinbase.png deleted file mode 100644 index 1ebb322e818..00000000000 Binary files a/apps/dashboard/public/assets/product-pages/engine/coinbase.png and /dev/null differ diff --git a/apps/dashboard/public/assets/product-pages/engine/coolcats.png b/apps/dashboard/public/assets/product-pages/engine/coolcats.png deleted file mode 100644 index bc3b32c3c35..00000000000 Binary files a/apps/dashboard/public/assets/product-pages/engine/coolcats.png and /dev/null differ diff --git a/apps/dashboard/public/assets/product-pages/engine/infinigods.png b/apps/dashboard/public/assets/product-pages/engine/infinigods.png deleted file mode 100644 index b13856add40..00000000000 Binary files a/apps/dashboard/public/assets/product-pages/engine/infinigods.png and /dev/null differ diff --git a/apps/dashboard/public/assets/product-pages/engine/layer3.png b/apps/dashboard/public/assets/product-pages/engine/layer3.png deleted file mode 100644 index c6acf28e283..00000000000 Binary files a/apps/dashboard/public/assets/product-pages/engine/layer3.png and /dev/null differ diff --git a/apps/dashboard/public/assets/product-pages/engine/treasure.png b/apps/dashboard/public/assets/product-pages/engine/treasure.png deleted file mode 100644 index 3d8cf70cd4f..00000000000 Binary files a/apps/dashboard/public/assets/product-pages/engine/treasure.png and /dev/null differ diff --git a/apps/dashboard/public/assets/product-pages/mission/icon-control.svg b/apps/dashboard/public/assets/product-pages/mission/icon-control.svg deleted file mode 100644 index 25c2fce11ce..00000000000 --- a/apps/dashboard/public/assets/product-pages/mission/icon-control.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/apps/dashboard/public/assets/product-pages/mission/icon-open-source.svg b/apps/dashboard/public/assets/product-pages/mission/icon-open-source.svg deleted file mode 100644 index dc2f9594398..00000000000 --- a/apps/dashboard/public/assets/product-pages/mission/icon-open-source.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/apps/dashboard/public/assets/product-pages/mission/icon-unlock.svg b/apps/dashboard/public/assets/product-pages/mission/icon-unlock.svg deleted file mode 100644 index 6f3a33540ea..00000000000 --- a/apps/dashboard/public/assets/product-pages/mission/icon-unlock.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/apps/dashboard/public/assets/showcase/donatuz.png b/apps/dashboard/public/assets/showcase/donatuz.png deleted file mode 100644 index 607f36859da..00000000000 Binary files a/apps/dashboard/public/assets/showcase/donatuz.png and /dev/null differ diff --git a/apps/dashboard/public/assets/solutions-pages/commerce/shopify.png b/apps/dashboard/public/assets/solutions-pages/commerce/shopify.png deleted file mode 100644 index 75e21edefc4..00000000000 Binary files a/apps/dashboard/public/assets/solutions-pages/commerce/shopify.png and /dev/null differ diff --git a/apps/dashboard/public/assets/solutions-pages/icons/icon-dashboard.svg b/apps/dashboard/public/assets/solutions-pages/icons/icon-dashboard.svg deleted file mode 100644 index 5da97ea8f16..00000000000 --- a/apps/dashboard/public/assets/solutions-pages/icons/icon-dashboard.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/apps/dashboard/public/assets/solutions-pages/icons/icon-smart-wallet.svg b/apps/dashboard/public/assets/solutions-pages/icons/icon-smart-wallet.svg deleted file mode 100644 index 90da50bf573..00000000000 --- a/apps/dashboard/public/assets/solutions-pages/icons/icon-smart-wallet.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/apps/dashboard/public/assets/solutions-pages/icons/icon-tool.svg b/apps/dashboard/public/assets/solutions-pages/icons/icon-tool.svg deleted file mode 100644 index 31f2219fd63..00000000000 --- a/apps/dashboard/public/assets/solutions-pages/icons/icon-tool.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/apps/dashboard/public/assets/solutions-pages/loyalty/icon-smart-wallet.svg b/apps/dashboard/public/assets/solutions-pages/loyalty/icon-smart-wallet.svg deleted file mode 100644 index f3d6c036248..00000000000 --- a/apps/dashboard/public/assets/solutions-pages/loyalty/icon-smart-wallet.svg +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - - - diff --git a/apps/dashboard/public/assets/solutions-pages/loyalty/icon-tool.svg b/apps/dashboard/public/assets/solutions-pages/loyalty/icon-tool.svg deleted file mode 100644 index 237c260f141..00000000000 --- a/apps/dashboard/public/assets/solutions-pages/loyalty/icon-tool.svg +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - - - diff --git a/apps/dashboard/public/assets/startup-program/buildandscale-image.png b/apps/dashboard/public/assets/startup-program/buildandscale-image.png deleted file mode 100644 index 3732ac1c2b5..00000000000 Binary files a/apps/dashboard/public/assets/startup-program/buildandscale-image.png and /dev/null differ diff --git a/apps/dashboard/public/assets/startup-program/chain-icon1.png b/apps/dashboard/public/assets/startup-program/chain-icon1.png deleted file mode 100644 index 7b3a8fdeb34..00000000000 Binary files a/apps/dashboard/public/assets/startup-program/chain-icon1.png and /dev/null differ diff --git a/apps/dashboard/public/assets/startup-program/chain-icon2.png b/apps/dashboard/public/assets/startup-program/chain-icon2.png deleted file mode 100644 index 7f05b440b97..00000000000 Binary files a/apps/dashboard/public/assets/startup-program/chain-icon2.png and /dev/null differ diff --git a/apps/dashboard/public/assets/startup-program/chain-icon3.png b/apps/dashboard/public/assets/startup-program/chain-icon3.png deleted file mode 100644 index 51b2f64c086..00000000000 Binary files a/apps/dashboard/public/assets/startup-program/chain-icon3.png and /dev/null differ diff --git a/apps/dashboard/public/assets/startup-program/chain-icon4.png b/apps/dashboard/public/assets/startup-program/chain-icon4.png deleted file mode 100644 index d596dbc6d13..00000000000 Binary files a/apps/dashboard/public/assets/startup-program/chain-icon4.png and /dev/null differ diff --git a/apps/dashboard/public/assets/startup-program/coinbase-icon.png b/apps/dashboard/public/assets/startup-program/coinbase-icon.png deleted file mode 100644 index 432800b6142..00000000000 Binary files a/apps/dashboard/public/assets/startup-program/coinbase-icon.png and /dev/null differ diff --git a/apps/dashboard/public/assets/startup-program/community-image.png b/apps/dashboard/public/assets/startup-program/community-image.png deleted file mode 100644 index ecc79b5d418..00000000000 Binary files a/apps/dashboard/public/assets/startup-program/community-image.png and /dev/null differ diff --git a/apps/dashboard/public/assets/startup-program/courtyard-icon.png b/apps/dashboard/public/assets/startup-program/courtyard-icon.png deleted file mode 100644 index fbc61ac94f8..00000000000 Binary files a/apps/dashboard/public/assets/startup-program/courtyard-icon.png and /dev/null differ diff --git a/apps/dashboard/public/assets/startup-program/cube-bottom.png b/apps/dashboard/public/assets/startup-program/cube-bottom.png deleted file mode 100644 index fbbf59c6add..00000000000 Binary files a/apps/dashboard/public/assets/startup-program/cube-bottom.png and /dev/null differ diff --git a/apps/dashboard/public/assets/startup-program/cube-top.png b/apps/dashboard/public/assets/startup-program/cube-top.png deleted file mode 100644 index 7f9f3717566..00000000000 Binary files a/apps/dashboard/public/assets/startup-program/cube-top.png and /dev/null differ diff --git a/apps/dashboard/public/assets/startup-program/cube-topleft.png b/apps/dashboard/public/assets/startup-program/cube-topleft.png deleted file mode 100644 index 14f398d298f..00000000000 Binary files a/apps/dashboard/public/assets/startup-program/cube-topleft.png and /dev/null differ diff --git a/apps/dashboard/public/assets/startup-program/cube-topright.png b/apps/dashboard/public/assets/startup-program/cube-topright.png deleted file mode 100644 index e23da23da22..00000000000 Binary files a/apps/dashboard/public/assets/startup-program/cube-topright.png and /dev/null differ diff --git a/apps/dashboard/public/assets/startup-program/ellipse-track.png b/apps/dashboard/public/assets/startup-program/ellipse-track.png deleted file mode 100644 index 609aa56715a..00000000000 Binary files a/apps/dashboard/public/assets/startup-program/ellipse-track.png and /dev/null differ diff --git a/apps/dashboard/public/assets/startup-program/gradient-1.png b/apps/dashboard/public/assets/startup-program/gradient-1.png deleted file mode 100644 index 5181b77b7ec..00000000000 Binary files a/apps/dashboard/public/assets/startup-program/gradient-1.png and /dev/null differ diff --git a/apps/dashboard/public/assets/startup-program/gradient-2.png b/apps/dashboard/public/assets/startup-program/gradient-2.png deleted file mode 100644 index 2436c07513c..00000000000 Binary files a/apps/dashboard/public/assets/startup-program/gradient-2.png and /dev/null differ diff --git a/apps/dashboard/public/assets/startup-program/gradient-5.png b/apps/dashboard/public/assets/startup-program/gradient-5.png deleted file mode 100644 index 7e65ba541e7..00000000000 Binary files a/apps/dashboard/public/assets/startup-program/gradient-5.png and /dev/null differ diff --git a/apps/dashboard/public/assets/startup-program/layer3-icon.png b/apps/dashboard/public/assets/startup-program/layer3-icon.png deleted file mode 100644 index 6f137eb975c..00000000000 Binary files a/apps/dashboard/public/assets/startup-program/layer3-icon.png and /dev/null differ diff --git a/apps/dashboard/public/assets/startup-program/logo-rugradio.png b/apps/dashboard/public/assets/startup-program/logo-rugradio.png deleted file mode 100644 index 81f28d7c2be..00000000000 Binary files a/apps/dashboard/public/assets/startup-program/logo-rugradio.png and /dev/null differ diff --git a/apps/dashboard/public/assets/startup-program/mentorsandVCs-image.png b/apps/dashboard/public/assets/startup-program/mentorsandVCs-image.png deleted file mode 100644 index aebd84b0071..00000000000 Binary files a/apps/dashboard/public/assets/startup-program/mentorsandVCs-image.png and /dev/null differ diff --git a/apps/dashboard/public/assets/startup-program/rarible-icon.png b/apps/dashboard/public/assets/startup-program/rarible-icon.png deleted file mode 100644 index 243ca29b1c5..00000000000 Binary files a/apps/dashboard/public/assets/startup-program/rarible-icon.png and /dev/null differ diff --git a/apps/dashboard/public/assets/startup-program/treasure-icon.png b/apps/dashboard/public/assets/startup-program/treasure-icon.png deleted file mode 100644 index ce5e183004f..00000000000 Binary files a/apps/dashboard/public/assets/startup-program/treasure-icon.png and /dev/null differ diff --git a/apps/dashboard/src/@/components/blocks/Avatars/GradientAvatar.tsx b/apps/dashboard/src/@/components/blocks/Avatars/GradientAvatar.tsx index 1d70a27b13f..e0c411d6070 100644 --- a/apps/dashboard/src/@/components/blocks/Avatars/GradientAvatar.tsx +++ b/apps/dashboard/src/@/components/blocks/Avatars/GradientAvatar.tsx @@ -1,34 +1,8 @@ import { Img } from "@/components/blocks/Img"; -import { useMemo } from "react"; import type { ThirdwebClient } from "thirdweb"; import { resolveSchemeWithErrorHandler } from "../../../lib/resolveSchemeWithErrorHandler"; import { cn } from "../../../lib/utils"; - -const gradients = [ - ["#fca5a5", "#b91c1c"], - ["#fdba74", "#c2410c"], - ["#fcd34d", "#b45309"], - ["#fde047", "#a16207"], - ["#a3e635", "#4d7c0f"], - ["#86efac", "#15803d"], - ["#67e8f9", "#0e7490"], - ["#7dd3fc", "#0369a1"], - ["#93c5fd", "#1d4ed8"], - ["#a5b4fc", "#4338ca"], - ["#c4b5fd", "#6d28d9"], - ["#d8b4fe", "#7e22ce"], - ["#f0abfc", "#a21caf"], - ["#f9a8d4", "#be185d"], - ["#fda4af", "#be123c"], -]; - -function getGradientForString(str: string) { - const number = Math.abs( - str.split("").reduce((acc, b, i) => acc + b.charCodeAt(0) * (i + 1), 0), - ); - const index = number % gradients.length; - return gradients[index]; -} +import { GradientBlobbie } from "./GradientBlobbie"; export function GradientAvatar(props: { src: string | undefined; @@ -36,13 +10,6 @@ export function GradientAvatar(props: { className: string; client: ThirdwebClient; }) { - const gradient = useMemo(() => { - if (!props.id) { - return undefined; - } - return getGradientForString(props.id); - }, [props.id]); - const resolvedSrc = props.src ? resolveSchemeWithErrorHandler({ client: props.client, @@ -54,15 +21,7 @@ export function GradientAvatar(props: { - ) : undefined - } + fallback={props.id ? : undefined} /> ); } diff --git a/apps/dashboard/src/@/components/blocks/Avatars/GradientBlobbie.tsx b/apps/dashboard/src/@/components/blocks/Avatars/GradientBlobbie.tsx new file mode 100644 index 00000000000..d6446c6b147 --- /dev/null +++ b/apps/dashboard/src/@/components/blocks/Avatars/GradientBlobbie.tsx @@ -0,0 +1,45 @@ +// Note: This is also used in opengraph-image.tsx +// don't use any hooks or client side stuff here + +const gradients = [ + ["#fca5a5", "#b91c1c"], + ["#fdba74", "#c2410c"], + ["#fcd34d", "#b45309"], + ["#fde047", "#a16207"], + ["#a3e635", "#4d7c0f"], + ["#86efac", "#15803d"], + ["#67e8f9", "#0e7490"], + ["#7dd3fc", "#0369a1"], + ["#93c5fd", "#1d4ed8"], + ["#a5b4fc", "#4338ca"], + ["#c4b5fd", "#6d28d9"], + ["#d8b4fe", "#7e22ce"], + ["#f0abfc", "#a21caf"], + ["#f9a8d4", "#be185d"], + ["#fda4af", "#be123c"], +]; + +function getGradientForString(str: string) { + const number = Math.abs( + str.split("").reduce((acc, b, i) => acc + b.charCodeAt(0) * (i + 1), 0), + ); + const index = number % gradients.length; + return gradients[index]; +} + +export function GradientBlobbie(props: { + id: string; + style?: React.CSSProperties; +}) { + const gradient = getGradientForString(props.id); + return ( +
+ ); +} diff --git a/apps/dashboard/src/@/components/blocks/wallet-address.tsx b/apps/dashboard/src/@/components/blocks/wallet-address.tsx index bee1e2611b7..a4fc5fd4b6c 100644 --- a/apps/dashboard/src/@/components/blocks/wallet-address.tsx +++ b/apps/dashboard/src/@/components/blocks/wallet-address.tsx @@ -12,15 +12,11 @@ import { Check, Copy, ExternalLinkIcon } from "lucide-react"; import { useMemo } from "react"; import { type ThirdwebClient, isAddress } from "thirdweb"; import { ZERO_ADDRESS } from "thirdweb"; -import { - Blobbie, - MediaRenderer, - type SocialProfile, - useSocialProfiles, -} from "thirdweb/react"; +import { Blobbie, type SocialProfile, useSocialProfiles } from "thirdweb/react"; import { cn } from "../../lib/utils"; import { Badge } from "../ui/badge"; import { Button } from "../ui/button"; +import { Img } from "./Img"; export function WalletAddress(props: { address: string | undefined; @@ -182,14 +178,18 @@ function WalletAvatar(props: { profile.avatar.startsWith("ipfs")), )?.avatar; }, [props.profiles]); + + const resolvedAvatarSrc = avatar + ? resolveSchemeWithErrorHandler({ + client: props.thirdwebClient, + uri: avatar, + }) + : undefined; + return (
- {avatar ? ( - + {resolvedAvatarSrc ? ( + ) : ( )} diff --git a/apps/dashboard/src/@/components/ui/code/CodeBlockContainer.tsx b/apps/dashboard/src/@/components/ui/code/CodeBlockContainer.tsx index d927a06cf90..bfc697747f6 100644 --- a/apps/dashboard/src/@/components/ui/code/CodeBlockContainer.tsx +++ b/apps/dashboard/src/@/components/ui/code/CodeBlockContainer.tsx @@ -14,6 +14,7 @@ export function CodeBlockContainer(props: { scrollableContainerClassName?: string; copyButtonClassName?: string; shadowColor?: string; + onCopy?: (code: string) => void; }) { const { hasCopied, onCopy } = useClipboard(props.codeToCopy); @@ -38,7 +39,10 @@ export function CodeBlockContainer(props: {
) : null} - +
{allEvents?.slice(0, 3).map((e) => ( = ({ chainSlug={chainSlug} /> ))} - +
@@ -126,31 +125,7 @@ const EventsFeedItem: React.FC = ({ = ({
)} - +
{members.map((e) => ( ))} - +
)} @@ -124,31 +123,7 @@ const PermissionsItem: React.FC = ({ data }) => { - +
diff --git a/apps/dashboard/src/app/(dashboard)/profile/[addressOrEns]/components/profile-header.tsx b/apps/dashboard/src/app/(dashboard)/profile/[addressOrEns]/components/profile-header.tsx index 36e6d6d2b6b..eb381c98354 100644 --- a/apps/dashboard/src/app/(dashboard)/profile/[addressOrEns]/components/profile-header.tsx +++ b/apps/dashboard/src/app/(dashboard)/profile/[addressOrEns]/components/profile-header.tsx @@ -12,14 +12,17 @@ import { } from "thirdweb/react"; import { shortenIfAddress } from "utils/usedapp-external"; -export function ProfileHeader(props: { profileAddress: string }) { +export function ProfileHeader(props: { + profileAddress: string; + ensName: string | undefined; +}) { const client = useThirdwebClient(); return (
} fallbackComponent={ @@ -27,17 +30,22 @@ export function ProfileHeader(props: { profileAddress: string }) { />

- - shortenIfAddress(replaceDeployerAddress(addr)) - } - /> - } - loadingComponent={} - formatFn={(name) => replaceDeployerAddress(name)} - /> + {/* if we already have an ensName just use it */} + {props.ensName ? ( + props.ensName + ) : ( + + shortenIfAddress(replaceDeployerAddress(addr)) + } + /> + } + loadingComponent={} + formatFn={(name) => replaceDeployerAddress(name)} + /> + )}

diff --git a/apps/dashboard/src/app/(dashboard)/profile/[addressOrEns]/opengraph-image.tsx b/apps/dashboard/src/app/(dashboard)/profile/[addressOrEns]/opengraph-image.tsx new file mode 100644 index 00000000000..8cc4ea9c115 --- /dev/null +++ b/apps/dashboard/src/app/(dashboard)/profile/[addressOrEns]/opengraph-image.tsx @@ -0,0 +1,129 @@ +import { GradientBlobbie } from "@/components/blocks/Avatars/GradientBlobbie"; +/* eslint-disable @next/next/no-img-element */ +import { getThirdwebClient } from "@/constants/thirdweb.server"; +import { resolveSchemeWithErrorHandler } from "@/lib/resolveSchemeWithErrorHandler"; +import { notFound } from "next/navigation"; +import { ImageResponse } from "next/og"; +import { resolveAvatar } from "thirdweb/extensions/ens"; +import { shortenIfAddress } from "../../../../utils/usedapp-external"; +import { resolveAddressAndEns } from "./resolveAddressAndEns"; + +export const runtime = "edge"; + +export const size = { + width: 1200, + height: 630, +}; + +type PageProps = { + params: Promise<{ + addressOrEns: string; + }>; +}; + +export default async function Image(props: PageProps) { + const client = getThirdwebClient(); + const params = await props.params; + const resolvedInfo = await resolveAddressAndEns(params.addressOrEns); + + if (!resolvedInfo) { + notFound(); + } + + const [inter700, profileBackground] = await Promise.all([ + fetch(new URL("og-lib/fonts/inter/700.ttf", import.meta.url)).then((res) => + res.arrayBuffer(), + ), + fetch( + new URL("og-lib/assets/profile/background.png", import.meta.url), + ).then((res) => res.arrayBuffer()), + ]); + + const ensImage = resolvedInfo.ensName + ? await resolveAvatar({ + client: client, + name: resolvedInfo.ensName, + }) + : null; + + const resolvedENSImageSrc = ensImage + ? resolveSchemeWithErrorHandler({ + client: client, + uri: ensImage, + }) + : null; + + return new ImageResponse( +
+ + +
+
+ {resolvedENSImageSrc ? ( + + ) : ( + + )} + +

+ {resolvedInfo.ensName || shortenIfAddress(resolvedInfo.address)} +

+
+
+
+ +
+
+
+
, + { + ...size, + fonts: [ + { + data: inter700, + name: "Inter", + weight: 700, + }, + ], + }, + ); +} + +const OgBrandIcon: React.FC = () => ( + // biome-ignore lint/a11y/noSvgWithoutTitle: not needed + + + +); diff --git a/apps/dashboard/src/app/(dashboard)/profile/[addressOrEns]/page.tsx b/apps/dashboard/src/app/(dashboard)/profile/[addressOrEns]/page.tsx index f9c5ef1a707..3cdcd5ff828 100644 --- a/apps/dashboard/src/app/(dashboard)/profile/[addressOrEns]/page.tsx +++ b/apps/dashboard/src/app/(dashboard)/profile/[addressOrEns]/page.tsx @@ -21,7 +21,7 @@ export default async function Page(props: PageProps) { return ( ); @@ -39,8 +39,15 @@ export async function generateMetadata(props: PageProps): Promise { replaceDeployerAddress(resolvedInfo.ensName || resolvedInfo.address), ); + const title = displayName; + const description = `Visit ${displayName}'s profile. See their published contracts and deploy them in one click.`; + return { - title: displayName, - description: `Visit ${displayName}'s profile. See their published contracts and deploy them in one click.`, + title, + description, + openGraph: { + title, + description, + }, }; } diff --git a/apps/dashboard/src/app/login/LoginPage.tsx b/apps/dashboard/src/app/login/LoginPage.tsx index e63f01e1c4d..d13d044cafd 100644 --- a/apps/dashboard/src/app/login/LoginPage.tsx +++ b/apps/dashboard/src/app/login/LoginPage.tsx @@ -77,6 +77,20 @@ export function LoginAndOnboardingPage(props: {
+ +
+ ); +} + +export function LoginAndOnboardingPageContent(props: { + account: Account | undefined; + redirectPath: string; +}) { + return ( +
| null; <-- type of this is not available on https://nebula-api.thirdweb-dev.com/docs#/default/get_session_session__session_id__get }; @@ -50,10 +53,7 @@ export type UpdatedSessionInfo = { modal_name: string; account_id: string; execute_config: ExecuteConfig | null; - context_filter: { - chain_ids: string[]; - contract_addresses: string[]; - } | null; + context_filter: SessionContextFilter | null; }; export type DeletedSessionInfo = { diff --git a/apps/dashboard/src/app/nebula-app/(app)/chat/[session_id]/page.tsx b/apps/dashboard/src/app/nebula-app/(app)/chat/[session_id]/page.tsx index fc9b054e04d..8c12a9da38f 100644 --- a/apps/dashboard/src/app/nebula-app/(app)/chat/[session_id]/page.tsx +++ b/apps/dashboard/src/app/nebula-app/(app)/chat/[session_id]/page.tsx @@ -44,6 +44,7 @@ export default async function Page(props: { session={session} type="new-chat" account={account} + initialPrompt={undefined} /> ); } diff --git a/apps/dashboard/src/app/nebula-app/(app)/chat/history/ChatHistoryPage.tsx b/apps/dashboard/src/app/nebula-app/(app)/chat/history/ChatHistoryPage.tsx index efc24f3caeb..3b303e9c9fe 100644 --- a/apps/dashboard/src/app/nebula-app/(app)/chat/history/ChatHistoryPage.tsx +++ b/apps/dashboard/src/app/nebula-app/(app)/chat/history/ChatHistoryPage.tsx @@ -81,12 +81,12 @@ export function ChatHistoryPageUI(props: { {filteredSessions.length > 0 && ( {filteredSessions.length > 0 && ( -
+
{filteredSessions.map((session) => ( -

{props.session.title}

+
+

+ {props.session.title || "Untitled"} +

Updated{" "} diff --git a/apps/dashboard/src/app/nebula-app/(app)/chat/page.tsx b/apps/dashboard/src/app/nebula-app/(app)/chat/page.tsx index 31300c2f23f..c7c6c1db170 100644 --- a/apps/dashboard/src/app/nebula-app/(app)/chat/page.tsx +++ b/apps/dashboard/src/app/nebula-app/(app)/chat/page.tsx @@ -27,6 +27,7 @@ export default async function Page() { session={undefined} type="new-chat" account={account} + initialPrompt={undefined} /> ); } diff --git a/apps/dashboard/src/app/nebula-app/(app)/components/ChatBar.tsx b/apps/dashboard/src/app/nebula-app/(app)/components/ChatBar.tsx index 33245b51901..aecfd0ce08c 100644 --- a/apps/dashboard/src/app/nebula-app/(app)/components/ChatBar.tsx +++ b/apps/dashboard/src/app/nebula-app/(app)/components/ChatBar.tsx @@ -5,11 +5,8 @@ import { AutoResizeTextarea } from "@/components/ui/textarea"; import { cn } from "@/lib/utils"; import { ArrowUpIcon, CircleStopIcon } from "lucide-react"; import { useState } from "react"; -import type { ExecuteConfig } from "../api/types"; export function Chatbar(props: { - updateConfig: (config: ExecuteConfig) => void; - config: ExecuteConfig; sendMessage: (message: string) => void; isChatStreaming: boolean; abortChatStream: () => void; diff --git a/apps/dashboard/src/app/nebula-app/(app)/components/ChatPageContent.tsx b/apps/dashboard/src/app/nebula-app/(app)/components/ChatPageContent.tsx index 92dc3e64aef..2a4e8d7f0b4 100644 --- a/apps/dashboard/src/app/nebula-app/(app)/components/ChatPageContent.tsx +++ b/apps/dashboard/src/app/nebula-app/(app)/components/ChatPageContent.tsx @@ -1,11 +1,8 @@ "use client"; - -/* eslint-disable no-restricted-syntax */ -import { ScrollShadow } from "@/components/ui/ScrollShadow/ScrollShadow"; import { useThirdwebClient } from "@/constants/thirdweb.client"; import type { Account } from "@3rdweb-sdk/react/hooks/useApi"; -import { useMutation } from "@tanstack/react-query"; -import { useEffect, useRef, useState } from "react"; +import { useCallback, useEffect, useMemo, useRef, useState } from "react"; +import { useActiveAccount, useActiveWalletChain } from "thirdweb/react"; import { type ContextFilters, promptNebula } from "../api/chat"; import { createSession, updateSession } from "../api/session"; import type { ExecuteConfig, SessionInfo } from "../api/types"; @@ -21,7 +18,10 @@ export function ChatPageContent(props: { accountAddress: string; type: "landing" | "new-chat"; account: Account; + initialPrompt: string | undefined; }) { + const address = useActiveAccount()?.address; + const activeChain = useActiveWalletChain(); const client = useThirdwebClient(); const [userHasSubmittedMessage, setUserHasSubmittedMessage] = useState(false); const [messages, setMessages] = useState>(() => { @@ -35,23 +35,60 @@ export function ChatPageContent(props: { return []; }); - const [_config, setConfig] = useState(); - const [contextFilters, setContextFilters] = useState< + const [hasUserUpdatedContextFilters, setHasUserUpdatedContextFilters] = + useState(false); + + const [contextFilters, _setContextFilters] = useState< ContextFilters | undefined >(() => { const contextFilterRes = props.session?.context_filter; - if (contextFilterRes) { - return { - chainIds: contextFilterRes.chain_ids, - contractAddresses: contextFilterRes.contract_addresses, - }; - } + const value: ContextFilters = { + chainIds: contextFilterRes?.chain_ids || undefined, + contractAddresses: contextFilterRes?.contract_addresses || undefined, + walletAddresses: contextFilterRes?.wallet_addresses || undefined, + }; + + return value; }); - const config = _config || { - mode: "client", - signer_wallet_address: props.accountAddress, - }; + const setContextFilters = useCallback((v: ContextFilters | undefined) => { + _setContextFilters(v); + setHasUserUpdatedContextFilters(true); + }, []); + + const isNewSession = !props.session; + + // if this is a new session, user has not manually updated context filters + // update the context filters to the current user's wallet address and chain id + // eslint-disable-next-line no-restricted-syntax + useEffect(() => { + if ( + !isNewSession || + hasUserUpdatedContextFilters || + !address || + !activeChain + ) { + return; + } + + _setContextFilters((_contextFilters) => { + const updatedContextFilters: ContextFilters = _contextFilters + ? { ..._contextFilters } + : {}; + + updatedContextFilters.walletAddresses = [address]; + updatedContextFilters.chainIds = [activeChain.id.toString()]; + + return updatedContextFilters; + }); + }, [address, isNewSession, hasUserUpdatedContextFilters, activeChain]); + + const config: ExecuteConfig = useMemo(() => { + return { + mode: "client", + signer_wallet_address: props.accountAddress, + }; + }, [props.accountAddress]); const [sessionId, _setSessionId] = useState( props.session?.id, @@ -61,34 +98,27 @@ export function ChatPageContent(props: { AbortController | undefined >(); - function setSessionId(sessionId: string) { - _setSessionId(sessionId); - // update page URL without reloading - window.history.replaceState({}, "", `/chat/${sessionId}`); - - // if the current page is landing page, link to /chat - // if current page is new /chat page, link to landing page - if (props.type === "landing") { - newChatPageUrlStore.setValue("/chat"); - } else { - newChatPageUrlStore.setValue("/"); - } - } - - const messagesEndRef = useRef(null); - const [isChatStreaming, setIsChatStreaming] = useState(false); - const [isUserSubmittedMessage, setIsUserSubmittedMessage] = useState(false); + const setSessionId = useCallback( + (sessionId: string) => { + _setSessionId(sessionId); + // update page URL without reloading + window.history.replaceState({}, "", `/chat/${sessionId}`); - // biome-ignore lint/correctness/useExhaustiveDependencies: - useEffect(() => { - if (!isUserSubmittedMessage) { - return; - } + // if the current page is landing page, link to /chat + // if current page is new /chat page, link to landing page + if (props.type === "landing") { + newChatPageUrlStore.setValue("/chat"); + } else { + newChatPageUrlStore.setValue("/"); + } + }, + [props.type], + ); - messagesEndRef.current?.scrollIntoView({ behavior: "smooth" }); - }, [messages, isUserSubmittedMessage]); + const [isChatStreaming, setIsChatStreaming] = useState(false); + const [enableAutoScroll, setEnableAutoScroll] = useState(false); - async function initSession() { + const initSession = useCallback(async () => { const session = await createSession({ authToken: props.authToken, config, @@ -96,204 +126,198 @@ export function ChatPageContent(props: { }); setSessionId(session.id); return session; - } - - async function handleSendMessage(message: string) { - setUserHasSubmittedMessage(true); - setMessages((prev) => [ - ...prev, - { text: message, type: "user" }, - // instant loading indicator feedback to user - { - type: "presence", - text: "Thinking...", - }, - ]); - - setIsChatStreaming(true); - setIsUserSubmittedMessage(true); - const abortController = new AbortController(); - - try { - // Ensure we have a session ID - let currentSessionId = sessionId; - if (!currentSessionId) { - const session = await initSession(); - currentSessionId = session.id; - } - - let requestIdForMessage = ""; - - // add this session on sidebar - if (messages.length === 0) { - const prevValue = newSessionsStore.getValue(); - newSessionsStore.setValue([ - { - id: currentSessionId, - title: message, - created_at: new Date().toISOString(), - updated_at: new Date().toISOString(), - }, - ...prevValue, - ]); - } + }, [config, contextFilters, props.authToken, setSessionId]); - setChatAbortController(abortController); - - await promptNebula({ - abortController, - message: message, - sessionId: currentSessionId, - config: config, - authToken: props.authToken, - handleStream(res) { - if (abortController.signal.aborted) { - return; - } - - if (res.event === "init") { - requestIdForMessage = res.data.request_id; - } - - if (res.event === "delta") { - setMessages((prev) => { - const lastMessage = prev[prev.length - 1]; - // if last message is presence, overwrite it - if (lastMessage?.type === "presence") { - return [ - ...prev.slice(0, -1), - { - text: res.data.v, - type: "assistant", - request_id: requestIdForMessage, - }, - ]; - } + const handleSendMessage = useCallback( + async (message: string) => { + setUserHasSubmittedMessage(true); + setMessages((prev) => [ + ...prev, + { text: message, type: "user" }, + // instant loading indicator feedback to user + { + type: "presence", + text: "Thinking...", + }, + ]); - // if last message is from chat, append to it - if (lastMessage?.type === "assistant") { - return [ - ...prev.slice(0, -1), - { - text: lastMessage.text + res.data.v, - type: "assistant", - request_id: requestIdForMessage, - }, - ]; - } + setIsChatStreaming(true); + setEnableAutoScroll(true); + const abortController = new AbortController(); + + try { + // Ensure we have a session ID + let currentSessionId = sessionId; + if (!currentSessionId) { + const session = await initSession(); + currentSessionId = session.id; + } + + let requestIdForMessage = ""; + + // add this session on sidebar + if (messages.length === 0) { + const prevValue = newSessionsStore.getValue(); + newSessionsStore.setValue([ + { + id: currentSessionId, + title: message, + created_at: new Date().toISOString(), + updated_at: new Date().toISOString(), + }, + ...prevValue, + ]); + } + + setChatAbortController(abortController); + + await promptNebula({ + abortController, + message: message, + sessionId: currentSessionId, + config: config, + authToken: props.authToken, + handleStream(res) { + if (abortController.signal.aborted) { + return; + } - // otherwise, add a new message - return [ - ...prev, - { - text: res.data.v, - type: "assistant", - request_id: requestIdForMessage, - }, - ]; - }); - } - - if (res.event === "presence") { - setMessages((prev) => { - const lastMessage = prev[prev.length - 1]; - // if last message is presence, overwrite it - if (lastMessage?.type === "presence") { - return [ - ...prev.slice(0, -1), - { text: res.data.data, type: "presence" }, - ]; - } - // otherwise, add a new message - return [...prev, { text: res.data.data, type: "presence" }]; - }); - } + if (res.event === "init") { + requestIdForMessage = res.data.request_id; + } - if (res.event === "action") { - if (res.type === "sign_transaction") { + if (res.event === "delta") { setMessages((prev) => { - let prevMessages = prev; - // if last message is presence, remove it - if ( - prevMessages[prevMessages.length - 1]?.type === "presence" - ) { - prevMessages = prevMessages.slice(0, -1); + const lastMessage = prev[prev.length - 1]; + // if last message is presence, overwrite it + if (lastMessage?.type === "presence") { + return [ + ...prev.slice(0, -1), + { + text: res.data.v, + type: "assistant", + request_id: requestIdForMessage, + }, + ]; } + // if last message is from chat, append to it + if (lastMessage?.type === "assistant") { + return [ + ...prev.slice(0, -1), + { + text: lastMessage.text + res.data.v, + type: "assistant", + request_id: requestIdForMessage, + }, + ]; + } + + // otherwise, add a new message return [ - ...prevMessages, + ...prev, { - type: "send_transaction", - data: res.data, + text: res.data.v, + type: "assistant", + request_id: requestIdForMessage, }, ]; }); } - } - }, - contextFilters: contextFilters, - }); - } catch (error) { - if (abortController.signal.aborted) { - return; - } - console.error(error); - - setMessages((prev) => { - const newMessages = prev.slice( - 0, - prev[prev.length - 1]?.type === "presence" ? -1 : undefined, - ); - - // add error message - newMessages.push({ - text: `Error: ${error instanceof Error ? error.message : "Failed to execute command"}`, - type: "error", - }); - - return newMessages; - }); - } finally { - setIsChatStreaming(false); - } - } - async function handleUpdateConfig(newConfig: ExecuteConfig) { - setConfig(newConfig); + if (res.event === "presence") { + setMessages((prev) => { + const lastMessage = prev[prev.length - 1]; + // if last message is presence, overwrite it + if (lastMessage?.type === "presence") { + return [ + ...prev.slice(0, -1), + { text: res.data.data, type: "presence" }, + ]; + } + // otherwise, add a new message + return [...prev, { text: res.data.data, type: "presence" }]; + }); + } - try { - if (!sessionId) { - // If no session exists, create a new one - await initSession(); - } else { - await updateSession({ - authToken: props.authToken, - config: newConfig, - sessionId, - contextFilters, + if (res.event === "action") { + if (res.type === "sign_transaction") { + setMessages((prev) => { + let prevMessages = prev; + // if last message is presence, remove it + if ( + prevMessages[prevMessages.length - 1]?.type === "presence" + ) { + prevMessages = prevMessages.slice(0, -1); + } + + return [ + ...prevMessages, + { + type: "send_transaction", + data: res.data, + }, + ]; + }); + } + } + }, + contextFilters: contextFilters, + }); + } catch (error) { + if (abortController.signal.aborted) { + return; + } + console.error(error); + + setMessages((prev) => { + const newMessages = prev.slice( + 0, + prev[prev.length - 1]?.type === "presence" ? -1 : undefined, + ); + + // add error message + newMessages.push({ + text: `Error: ${error instanceof Error ? error.message : "Failed to execute command"}`, + type: "error", + }); + + return newMessages; }); + } finally { + setIsChatStreaming(false); + setEnableAutoScroll(false); } - } catch (error) { - console.error("Failed to update session", error); - setMessages((prev) => [ - ...prev, - { - text: `Error: Failed to ${sessionId ? "update" : "create"} session`, - type: "error", - }, - ]); - } - } + }, + [ + sessionId, + contextFilters, + config, + props.authToken, + messages.length, + initSession, + ], + ); - const updateConfig = useMutation({ - mutationFn: handleUpdateConfig, - }); + const hasDoneAutoPrompt = useRef(false); + + // eslint-disable-next-line no-restricted-syntax + useEffect(() => { + if ( + props.initialPrompt && + messages.length === 0 && + !hasDoneAutoPrompt.current + ) { + hasDoneAutoPrompt.current = true; + handleSendMessage(props.initialPrompt); + } + }, [props.initialPrompt, messages.length, handleSendMessage]); const showEmptyState = !userHasSubmittedMessage && messages.length === 0; return (

-
+
-
+
{showEmptyState ? ( -
- { - updateConfig.mutate(config); - }} - /> +
+
) : (
- - - {/* Scroll anchor */} -
- - - { - updateConfig.mutate(config); - }} - abortChatStream={() => { - chatAbortController?.abort(); - setChatAbortController(undefined); - setIsChatStreaming(false); - // if last message is presence, remove it - if (messages[messages.length - 1]?.type === "presence") { - setMessages((prev) => prev.slice(0, -1)); - } - }} + authToken={props.authToken} + sessionId={sessionId} + className="min-w-0 pt-10 pb-32" + twAccount={props.account} + client={client} + enableAutoScroll={enableAutoScroll} + setEnableAutoScroll={setEnableAutoScroll} /> + +
+ { + chatAbortController?.abort(); + setChatAbortController(undefined); + setIsChatStreaming(false); + // if last message is presence, remove it + if (messages[messages.length - 1]?.type === "presence") { + setMessages((prev) => prev.slice(0, -1)); + } + }} + /> +
)} diff --git a/apps/dashboard/src/app/nebula-app/(app)/components/ChatSidebar.tsx b/apps/dashboard/src/app/nebula-app/(app)/components/ChatSidebar.tsx index 76224a4b52f..3fc35bf5add 100644 --- a/apps/dashboard/src/app/nebula-app/(app)/components/ChatSidebar.tsx +++ b/apps/dashboard/src/app/nebula-app/(app)/components/ChatSidebar.tsx @@ -1,8 +1,13 @@ "use client"; import { ScrollShadow } from "@/components/ui/ScrollShadow/ScrollShadow"; +import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import type { Account } from "@3rdweb-sdk/react/hooks/useApi"; -import { ChevronRightIcon, MessageSquareDashedIcon } from "lucide-react"; +import { + ChevronRightIcon, + FlaskConicalIcon, + MessageSquareDashedIcon, +} from "lucide-react"; import Link from "next/link"; import type { TruncatedSessionInfo } from "../api/types"; import { useNewChatPageLink } from "../hooks/useNewChatPageLink"; @@ -23,10 +28,15 @@ export function ChatSidebar(props: { return (
-
+
+ + + + Alpha +
diff --git a/apps/dashboard/src/app/nebula-app/(app)/components/Chatbar.stories.tsx b/apps/dashboard/src/app/nebula-app/(app)/components/Chatbar.stories.tsx index cb73d8486f1..e54cc308b11 100644 --- a/apps/dashboard/src/app/nebula-app/(app)/components/Chatbar.stories.tsx +++ b/apps/dashboard/src/app/nebula-app/(app)/components/Chatbar.stories.tsx @@ -29,44 +29,19 @@ export const Mobile: Story = { function Story() { return (
- + {}} - config={{ - mode: "client", - signer_wallet_address: "xxxxx", - }} isChatStreaming={false} sendMessage={() => {}} - updateConfig={() => {}} /> - + {}} - config={{ - mode: "client", - signer_wallet_address: "xxxxx", - }} isChatStreaming={true} sendMessage={() => {}} - updateConfig={() => {}} - /> - - - - {}} - config={{ - mode: "engine", - engine_authorization_token: "xxxxx", - engine_backend_wallet_address: "0x1234", - engine_url: "https://some-engine-url.com", - }} - isChatStreaming={false} - sendMessage={() => {}} - updateConfig={() => {}} />
diff --git a/apps/dashboard/src/app/nebula-app/(app)/components/Chats.stories.tsx b/apps/dashboard/src/app/nebula-app/(app)/components/Chats.stories.tsx index a9065a397e4..72c7ae61d55 100644 --- a/apps/dashboard/src/app/nebula-app/(app)/components/Chats.stories.tsx +++ b/apps/dashboard/src/app/nebula-app/(app)/components/Chats.stories.tsx @@ -157,6 +157,8 @@ function Story() { }, ]} client={getThirdwebClient()} + enableAutoScroll={true} + setEnableAutoScroll={() => {}} /> @@ -167,6 +169,8 @@ function Story() { isChatStreaming={false} sessionId="xxxxx" twAccount={accountStub()} + enableAutoScroll={true} + setEnableAutoScroll={() => {}} messages={[ { text: randomLorem(10), @@ -182,6 +186,8 @@ function Story() { {}} client={getThirdwebClient()} authToken="xxxxx" isChatStreaming={false} diff --git a/apps/dashboard/src/app/nebula-app/(app)/components/Chats.tsx b/apps/dashboard/src/app/nebula-app/(app)/components/Chats.tsx index a5355bfe06d..2d42c17f3a5 100644 --- a/apps/dashboard/src/app/nebula-app/(app)/components/Chats.tsx +++ b/apps/dashboard/src/app/nebula-app/(app)/components/Chats.tsx @@ -1,7 +1,9 @@ import { GradientAvatar } from "@/components/blocks/Avatars/GradientAvatar"; +import { ScrollShadow } from "@/components/ui/ScrollShadow/ScrollShadow"; import { Spinner } from "@/components/ui/Spinner/Spinner"; import { Alert, AlertTitle } from "@/components/ui/alert"; import { Button } from "@/components/ui/button"; +import { getThirdwebClient } from "@/constants/thirdweb.server"; import { cn } from "@/lib/utils"; import type { Account as TWAccount } from "@3rdweb-sdk/react/hooks/useApi"; import { useMutation } from "@tanstack/react-query"; @@ -12,13 +14,15 @@ import { ThumbsDownIcon, ThumbsUpIcon, } from "lucide-react"; -import { useState } from "react"; +import { useEffect, useRef, useState } from "react"; import { toast } from "sonner"; import type { ThirdwebClient } from "thirdweb"; +import { sendTransaction } from "thirdweb"; import { useActiveAccount } from "thirdweb/react"; import type { Account } from "thirdweb/wallets"; import { TransactionButton } from "../../../../components/buttons/TransactionButton"; import { MarkdownRenderer } from "../../../../components/contract-components/published-contract/markdown-renderer"; +import { useV5DashboardChain } from "../../../../lib/v5-adapter"; import { submitFeedback } from "../api/feedback"; import { NebulaIcon } from "../icons/NebulaIcon"; @@ -48,97 +52,153 @@ export function Chats(props: { className?: string; twAccount: TWAccount; client: ThirdwebClient; + setEnableAutoScroll: (enable: boolean) => void; + enableAutoScroll: boolean; }) { + const { messages, setEnableAutoScroll, enableAutoScroll } = props; + const scrollAnchorRef = useRef(null); + const chatContainerRef = useRef(null); + + // auto scroll to bottom when messages change + // eslint-disable-next-line no-restricted-syntax + useEffect(() => { + if (!enableAutoScroll || messages.length === 0) { + return; + } + + scrollAnchorRef.current?.scrollIntoView({ behavior: "smooth" }); + }, [messages, enableAutoScroll]); + + // stop auto scrolling when user interacts with chat + // eslint-disable-next-line no-restricted-syntax + useEffect(() => { + if (!enableAutoScroll) { + return; + } + + const chatScrollContainer = + chatContainerRef.current?.querySelector("[data-scrollable]"); + + if (!chatScrollContainer) { + return; + } + + const disableScroll = () => { + setEnableAutoScroll(false); + chatScrollContainer.removeEventListener("mousedown", disableScroll); + chatScrollContainer.removeEventListener("wheel", disableScroll); + }; + + chatScrollContainer.addEventListener("mousedown", disableScroll); + chatScrollContainer.addEventListener("wheel", disableScroll); + }, [setEnableAutoScroll, enableAutoScroll]); + return ( -
- {props.messages.map((message, index) => { - const isMessagePending = - props.isChatStreaming && index === props.messages.length - 1; - return ( -
-
-
- {message.type === "user" ? ( - - ) : ( +
+ +
+
+ {props.messages.map((message, index) => { + const isMessagePending = + props.isChatStreaming && index === props.messages.length - 1; + return ( +
- {message.type === "presence" && ( - - )} +
+ {message.type === "user" ? ( + + ) : ( +
+ {message.type === "presence" && ( + + )} - {message.type === "assistant" && ( - - )} + {message.type === "assistant" && ( + + )} - {message.type === "error" && ( - - )} -
- )} -
-
- {message.type === "assistant" ? ( - - ) : message.type === "error" ? ( - - {message.text} - - ) : message.type === "send_transaction" ? ( - - ) : ( - {message.text} - )} + {message.type === "error" && ( + + )} +
+ )} +
+
+ {message.type === "assistant" ? ( + + ) : message.type === "error" ? ( + + {message.text} + + ) : message.type === "send_transaction" ? ( + + ) : ( + {message.text} + )} - {message.type === "assistant" && - !props.isChatStreaming && - props.sessionId && - message.request_id && ( - - )} -
-
+ {message.type === "assistant" && + !props.isChatStreaming && + props.sessionId && + message.request_id && ( + + )} +
+
+
+ ); + })} +
- ); - })} +
+
); } @@ -241,16 +301,28 @@ function SendTransactionButton(props: { twAccount: TWAccount; }) { const account = useActiveAccount(); + const chain = useV5DashboardChain(props.txData?.chainId); + const sendTxMutation = useMutation({ mutationFn: () => { if (!account) { throw new Error("No active account"); } - if (!props.txData) { + if (!props.txData || !chain) { throw new Error("Invalid transaction"); } - return account.sendTransaction(props.txData); + + return sendTransaction({ + account, + transaction: { + ...props.txData, + nonce: Number(props.txData.nonce), + to: props.txData.to || undefined, // Get rid of the potential null value + chain, + client: getThirdwebClient(), + }, + }); }, }); diff --git a/apps/dashboard/src/app/nebula-app/(app)/components/ContextFilters.stories.tsx b/apps/dashboard/src/app/nebula-app/(app)/components/ContextFilters.stories.tsx index 28b82f25688..f14a055342a 100644 --- a/apps/dashboard/src/app/nebula-app/(app)/components/ContextFilters.stories.tsx +++ b/apps/dashboard/src/app/nebula-app/(app)/components/ContextFilters.stories.tsx @@ -31,20 +31,70 @@ export const Mobile: Story = { function Story() { return ( -
+
+ + + + + + + + + + +
diff --git a/apps/dashboard/src/app/nebula-app/(app)/components/ContextFilters.tsx b/apps/dashboard/src/app/nebula-app/(app)/components/ContextFilters.tsx index 29af4ac1184..d2f9852fbfe 100644 --- a/apps/dashboard/src/app/nebula-app/(app)/components/ContextFilters.tsx +++ b/apps/dashboard/src/app/nebula-app/(app)/components/ContextFilters.tsx @@ -1,6 +1,7 @@ "use client"; import { Spinner } from "@/components/ui/Spinner/Spinner"; +import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { Dialog, @@ -42,14 +43,46 @@ export default function ContextFiltersButton(props: { mutationFn: props.updateContextFilters, }); + const chainIds = props.contextFilters?.chainIds; + const contractAddresses = props.contextFilters?.contractAddresses; + const walletAddresses = props.contextFilters?.walletAddresses; + return ( - @@ -74,6 +107,18 @@ export default function ContextFiltersButton(props: { ); } +const commaSeparateListOfAddresses = z.string().refine( + (s) => { + if (s.trim() === "") { + return true; + } + return s.split(",").every((s) => isAddress(s.trim())); + }, + { + message: "Must be a comma-separated list of valid addresses", + }, +); + const formSchema = z.object({ chainIds: z.string().refine( (s) => { @@ -89,18 +134,8 @@ const formSchema = z.object({ message: "Chain IDs must be a comma-separated list of integers", }, ), - contractAddresses: z.string().refine( - (s) => { - if (s.trim() === "") { - return true; - } - return s.trim().split(",").every(isAddress); - }, - { - message: - "Contract addresses must be a comma-separated list of valid addresses", - }, - ), + contractAddresses: commaSeparateListOfAddresses, + walletAddresses: commaSeparateListOfAddresses, }); function ContextFilterDialogContent(props: { @@ -117,25 +152,31 @@ function ContextFilterDialogContent(props: { contractAddresses: props.contextFilters?.contractAddresses ? props.contextFilters.contractAddresses.join(",") : "", + walletAddresses: props.contextFilters?.walletAddresses + ? props.contextFilters.walletAddresses.join(",") + : "", }, reValidateMode: "onChange", }); function onSubmit(values: z.infer) { - const { chainIds, contractAddresses } = values; - const chainIdsArray = chainIds.trim().split(",").filter(Boolean); + const { chainIds, contractAddresses, walletAddresses } = values; + + const chainIdsArray = chainIds.split(",").filter((id) => id.trim()); + const contractAddressesArray = contractAddresses - .trim() .split(",") - .filter(Boolean); - if (chainIdsArray.length === 0 && contractAddressesArray.length === 0) { - props.updateFilters(undefined); - } else { - props.updateFilters({ - chainIds: chainIdsArray, - contractAddresses: contractAddressesArray, - }); - } + .filter((v) => v.trim()); + + const walletAddressesArray = walletAddresses + .split(",") + .filter((v) => v.trim()); + + props.updateFilters({ + chainIds: chainIdsArray, + contractAddresses: contractAddressesArray, + walletAddresses: walletAddressesArray, + }); } return ( @@ -195,6 +236,27 @@ function ContextFilterDialogContent(props: { )} /> + + ( + + Wallet Addresses + + + + + Comma separated list of wallet addresses + + + + )} + />
diff --git a/apps/dashboard/src/app/nebula-app/(app)/components/EmptyStateChatPageContent.stories.tsx b/apps/dashboard/src/app/nebula-app/(app)/components/EmptyStateChatPageContent.stories.tsx index 4cb7d39c107..eee82fe6dc8 100644 --- a/apps/dashboard/src/app/nebula-app/(app)/components/EmptyStateChatPageContent.stories.tsx +++ b/apps/dashboard/src/app/nebula-app/(app)/components/EmptyStateChatPageContent.stories.tsx @@ -29,14 +29,7 @@ export const Mobile: Story = { function Story() { return (
- {}} - updateConfig={() => {}} - /> + {}} />
); } diff --git a/apps/dashboard/src/app/nebula-app/(app)/components/EmptyStateChatPageContent.tsx b/apps/dashboard/src/app/nebula-app/(app)/components/EmptyStateChatPageContent.tsx index 21903104452..72626890f78 100644 --- a/apps/dashboard/src/app/nebula-app/(app)/components/EmptyStateChatPageContent.tsx +++ b/apps/dashboard/src/app/nebula-app/(app)/components/EmptyStateChatPageContent.tsx @@ -2,14 +2,11 @@ import { ArrowUpRightIcon } from "lucide-react"; import { Button } from "../../../../@/components/ui/button"; -import type { ExecuteConfig } from "../api/types"; import { NebulaIcon } from "../icons/NebulaIcon"; import { Chatbar } from "./ChatBar"; export function EmptyStateChatPageContent(props: { - updateConfig: (config: ExecuteConfig) => void; sendMessage: (message: string) => void; - config: ExecuteConfig; }) { return (
@@ -31,9 +28,7 @@ export function EmptyStateChatPageContent(props: {
{ // the page will switch so, no need to handle abort here }} diff --git a/apps/dashboard/src/app/nebula-app/(app)/components/NebulaMobileNav.tsx b/apps/dashboard/src/app/nebula-app/(app)/components/NebulaMobileNav.tsx index fd0bd585522..1ecbdaa02cf 100644 --- a/apps/dashboard/src/app/nebula-app/(app)/components/NebulaMobileNav.tsx +++ b/apps/dashboard/src/app/nebula-app/(app)/components/NebulaMobileNav.tsx @@ -32,7 +32,7 @@ export function MobileNav(props: { onClick={() => setIsOpen(!isOpen)} className="h-auto w-auto p-0.5" > - + ; +}) { + const [searchParams, authToken] = await Promise.all([ + props.searchParams, + getAuthToken(), + ]); if (!authToken) { loginRedirect(); @@ -27,6 +34,7 @@ export default async function Page() { session={undefined} type="landing" account={account} + initialPrompt={searchParams.prompt} /> ); } diff --git a/apps/dashboard/src/app/nebula-app/[...not-found]/page.tsx b/apps/dashboard/src/app/nebula-app/[...not-found]/page.tsx new file mode 100644 index 00000000000..ff297366998 --- /dev/null +++ b/apps/dashboard/src/app/nebula-app/[...not-found]/page.tsx @@ -0,0 +1,67 @@ +import { TrackedLinkTW } from "@/components/ui/tracked-link"; + +export default function NebulaNotFound() { + return ( +
+
+
+
+ 404 +
+ +
+ +

+ Uh oh. + Looks like Nebula + can't be found here. +

+ +
+ +
+

+ Go to{" "} + + homepage + +

+
+ + +
+
+
+ ); +} + +type AuroraProps = { + size: { width: string; height: string }; + pos: { top: string; left: string }; + color: string; +}; + +const Aurora: React.FC = ({ color, pos, size }) => { + return ( +
+ ); +}; diff --git a/apps/dashboard/src/app/nebula-app/layout.tsx b/apps/dashboard/src/app/nebula-app/layout.tsx new file mode 100644 index 00000000000..77298a40e8a --- /dev/null +++ b/apps/dashboard/src/app/nebula-app/layout.tsx @@ -0,0 +1,21 @@ +import type { Metadata } from "next"; + +const title = + "thirdweb Nebula: The Most powerful AI for interacting with the blockchain"; +const description = + "The most powerful AI for interacting with the blockchain, with real-time access to EVM chains and their data"; + +export const metadata: Metadata = { + title, + description, + openGraph: { + title, + description, + }, +}; + +export default function Layout(props: { + children: React.ReactNode; +}) { + return props.children; +} diff --git a/apps/dashboard/src/app/nebula-app/login/NebulaLoginPage.tsx b/apps/dashboard/src/app/nebula-app/login/NebulaLoginPage.tsx new file mode 100644 index 00000000000..ede0bfc11b2 --- /dev/null +++ b/apps/dashboard/src/app/nebula-app/login/NebulaLoginPage.tsx @@ -0,0 +1,68 @@ +"use client"; + +import Link from "next/link"; +import { useState } from "react"; +import { EmptyStateChatPageContent } from "../(app)/components/EmptyStateChatPageContent"; +import { NebulaIcon } from "../(app)/icons/NebulaIcon"; +import { Button } from "../../../@/components/ui/button"; +import type { Account } from "../../../@3rdweb-sdk/react/hooks/useApi"; +import { LoginAndOnboardingPageContent } from "../../login/LoginPage"; + +export function NebulaLoginPage(props: { + account: Account | undefined; +}) { + const [message, setMessage] = useState(undefined); + const [showLoginPage, setShowLoginPage] = useState(false); + + return ( +
+
+
+ + +
+ + Support + + + + Docs + + + {!showLoginPage && ( + + )} +
+
+
+ + {showLoginPage ? ( + + ) : ( +
+ { + setMessage(msg); + setShowLoginPage(true); + }} + /> +
+ )} +
+ ); +} diff --git a/apps/dashboard/src/app/nebula-app/login/page.tsx b/apps/dashboard/src/app/nebula-app/login/page.tsx index 05e92f2870b..2e9d930936c 100644 --- a/apps/dashboard/src/app/nebula-app/login/page.tsx +++ b/apps/dashboard/src/app/nebula-app/login/page.tsx @@ -1,19 +1,8 @@ import { getRawAccount } from "../../account/settings/getAccount"; -import { LoginAndOnboardingPage } from "../../login/LoginPage"; -import { isValidEncodedRedirectPath } from "../../login/isValidEncodedRedirectPath"; +import { NebulaLoginPage } from "./NebulaLoginPage"; -export default async function NebulaLogin(props: { - searchParams: Promise<{ - next?: string; - }>; -}) { - const nextPath = (await props.searchParams).next; +export default async function NebulaLogin() { const account = await getRawAccount(); - const redirectPath = - nextPath && isValidEncodedRedirectPath(nextPath) ? nextPath : "/"; - - return ( - - ); + return ; } diff --git a/apps/dashboard/src/app/nebula-app/opengraph-image.png b/apps/dashboard/src/app/nebula-app/opengraph-image.png new file mode 100644 index 00000000000..6c632879f47 Binary files /dev/null and b/apps/dashboard/src/app/nebula-app/opengraph-image.png differ diff --git a/apps/dashboard/src/app/providers.tsx b/apps/dashboard/src/app/providers.tsx index 39680b3d838..8a5e1cf908a 100644 --- a/apps/dashboard/src/app/providers.tsx +++ b/apps/dashboard/src/app/providers.tsx @@ -2,11 +2,16 @@ import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; import { ThemeProvider } from "next-themes"; -import { useMemo } from "react"; -import { ThirdwebProvider, useActiveAccount } from "thirdweb/react"; +import { useEffect, useMemo } from "react"; +import { + ThirdwebProvider, + useActiveAccount, + useConnectionManager, +} from "thirdweb/react"; import { CustomConnectWallet } from "../@3rdweb-sdk/react/components/connect-wallet"; import { PosthogIdentifier } from "../components/wallets/PosthogIdentifier"; import { isSanctionedAddress } from "../data/eth-sanctioned-addresses"; +import { useAllChainsData } from "../hooks/chains/allChains"; import { SyncChainStores } from "../stores/chainStores"; import { TWAutoConnect } from "./components/autoconnect"; @@ -17,6 +22,7 @@ export function AppRouterProviders(props: { children: React.ReactNode }) { + { + if (allChainsV5.length > 0) { + connectionManager.defineChains(allChainsV5); + } + }, [allChainsV5, connectionManager]); + + return null; +} + const SanctionedAddressesChecker = ({ children, }: { diff --git a/apps/dashboard/src/app/team/[team_slug]/[project_slug]/connect/account-abstraction/AccountAbstractionPage.tsx b/apps/dashboard/src/app/team/[team_slug]/[project_slug]/connect/account-abstraction/AccountAbstractionPage.tsx index fcb3fd01e5d..00328f55525 100644 --- a/apps/dashboard/src/app/team/[team_slug]/[project_slug]/connect/account-abstraction/AccountAbstractionPage.tsx +++ b/apps/dashboard/src/app/team/[team_slug]/[project_slug]/connect/account-abstraction/AccountAbstractionPage.tsx @@ -2,7 +2,6 @@ import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert"; import { TrackedLinkTW } from "@/components/ui/tracked-link"; import { - type Account, type ApiKeyService, accountStatus, } from "@3rdweb-sdk/react/hooks/useApi"; @@ -25,7 +24,6 @@ export function AccountAbstractionPage(props: { apiKeyServices: ApiKeyService[]; billingStatus: "validPayment" | (string & {}) | null; tab?: string; - twAccount: Account; }) { const { apiKeyServices } = props; @@ -81,11 +79,9 @@ export function AccountAbstractionPage(props: {
diff --git a/apps/dashboard/src/app/team/[team_slug]/[project_slug]/connect/account-abstraction/page.tsx b/apps/dashboard/src/app/team/[team_slug]/[project_slug]/connect/account-abstraction/page.tsx index 0550876f974..86f3c8fe4ed 100644 --- a/apps/dashboard/src/app/team/[team_slug]/[project_slug]/connect/account-abstraction/page.tsx +++ b/apps/dashboard/src/app/team/[team_slug]/[project_slug]/connect/account-abstraction/page.tsx @@ -4,7 +4,6 @@ import { ChakraProviderSetup } from "@/components/ChakraProviderSetup"; import type { Metadata } from "next"; import { notFound, redirect } from "next/navigation"; import { getAbsoluteUrl } from "../../../../../../lib/vercel-utils"; -import { getValidAccount } from "../../../../../account/settings/getAccount"; import { getAPIKeyForProjectId } from "../../../../../api/lib/getAPIKeys"; import { AccountAbstractionPage } from "./AccountAbstractionPage"; @@ -14,10 +13,7 @@ export default async function Page(props: { }) { const { team_slug, project_slug } = await props.params; - const [account, team, project] = await Promise.all([ - getValidAccount( - `/${team_slug}/${project_slug}/connect/account-abstraction`, - ), + const [team, project] = await Promise.all([ getTeamBySlug(team_slug), getProject(team_slug, project_slug), ]); @@ -45,7 +41,6 @@ export default async function Page(props: { projectKey={project.publishableKey} apiKeyServices={apiKey.services || []} tab={(await props.searchParams).tab} - twAccount={account} /> ); diff --git a/apps/dashboard/src/app/team/[team_slug]/[project_slug]/connect/in-app-wallets/config/loading.tsx b/apps/dashboard/src/app/team/[team_slug]/[project_slug]/connect/in-app-wallets/config/loading.tsx deleted file mode 100644 index 6c54ef15def..00000000000 --- a/apps/dashboard/src/app/team/[team_slug]/[project_slug]/connect/in-app-wallets/config/loading.tsx +++ /dev/null @@ -1,3 +0,0 @@ -"use client"; - -export { GenericLoadingPage as default } from "@/components/blocks/skeletons/GenericLoadingPage"; diff --git a/apps/dashboard/src/app/team/[team_slug]/[project_slug]/connect/in-app-wallets/config/page.tsx b/apps/dashboard/src/app/team/[team_slug]/[project_slug]/connect/in-app-wallets/config/page.tsx deleted file mode 100644 index 1eaf77e9e90..00000000000 --- a/apps/dashboard/src/app/team/[team_slug]/[project_slug]/connect/in-app-wallets/config/page.tsx +++ /dev/null @@ -1,38 +0,0 @@ -import { getProject } from "@/api/projects"; -import { getAPIKeyForProjectId } from "app/api/lib/getAPIKeys"; -import { notFound, redirect } from "next/navigation"; -import { InAppWalletSettingsPage } from "../../../../../../../components/embedded-wallets/Configure"; -import { getValidAccount } from "../../../../../../account/settings/getAccount"; -import { TRACKING_CATEGORY } from "../_constants"; - -export default async function Page(props: { - params: Promise<{ team_slug: string; project_slug: string }>; -}) { - const params = await props.params; - const [account, project] = await Promise.all([ - getValidAccount( - `/${params.team_slug}/${params.project_slug}/connect/in-app-wallets/config`, - ), - getProject(params.team_slug, params.project_slug), - ]); - - if (!project) { - redirect("/team"); - } - - const apiKey = await getAPIKeyForProjectId(project.id); - - if (!apiKey) { - notFound(); - } - - return ( - <> - - - ); -} diff --git a/apps/dashboard/src/app/team/[team_slug]/[project_slug]/connect/in-app-wallets/layout.tsx b/apps/dashboard/src/app/team/[team_slug]/[project_slug]/connect/in-app-wallets/layout.tsx index 3dc051d0fcb..f3b8564326d 100644 --- a/apps/dashboard/src/app/team/[team_slug]/[project_slug]/connect/in-app-wallets/layout.tsx +++ b/apps/dashboard/src/app/team/[team_slug]/[project_slug]/connect/in-app-wallets/layout.tsx @@ -45,11 +45,6 @@ export default async function Layout(props: { path: `/team/${team_slug}/${project_slug}/connect/in-app-wallets/users`, exactMatch: true, }, - { - name: "Configuration", - path: `/team/${team_slug}/${project_slug}/connect/in-app-wallets/config`, - exactMatch: true, - }, ]} /> diff --git a/apps/dashboard/src/app/team/[team_slug]/[project_slug]/connect/page.tsx b/apps/dashboard/src/app/team/[team_slug]/[project_slug]/connect/page.tsx index e8c8a734c52..1b134327574 100644 --- a/apps/dashboard/src/app/team/[team_slug]/[project_slug]/connect/page.tsx +++ b/apps/dashboard/src/app/team/[team_slug]/[project_slug]/connect/page.tsx @@ -1,5 +1,4 @@ -import { getProject } from "@/api/projects"; -import { notFound, redirect } from "next/navigation"; +import { redirect } from "next/navigation"; export default async function Page(props: { params: Promise<{ @@ -8,11 +7,6 @@ export default async function Page(props: { }>; }) { const params = await props.params; - const project = await getProject(params.team_slug, params.project_slug); - - if (!project) { - notFound(); - } redirect( `/team/${params.team_slug}/${params.project_slug}/connect/in-app-wallets`, diff --git a/apps/dashboard/src/app/team/[team_slug]/[project_slug]/insight/[blueprint_slug]/blueprint-playground.client.tsx b/apps/dashboard/src/app/team/[team_slug]/[project_slug]/insight/[blueprint_slug]/blueprint-playground.client.tsx index aecd1cc031e..bc9fe21f76d 100644 --- a/apps/dashboard/src/app/team/[team_slug]/[project_slug]/insight/[blueprint_slug]/blueprint-playground.client.tsx +++ b/apps/dashboard/src/app/team/[team_slug]/[project_slug]/insight/[blueprint_slug]/blueprint-playground.client.tsx @@ -1,7 +1,7 @@ "use client"; import { SingleNetworkSelector } from "@/components/blocks/NetworkSelectors"; -import { useHeightObserver } from "@/components/ui/DynamicHeight"; +import { ScrollShadow } from "@/components/ui/ScrollShadow/ScrollShadow"; import { Spinner } from "@/components/ui/Spinner/Spinner"; import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert"; import { Badge } from "@/components/ui/badge"; @@ -28,9 +28,12 @@ import Link from "next/link"; import { useEffect, useMemo, useState } from "react"; import { type UseFormReturn, useForm } from "react-hook-form"; import { z } from "zod"; +import { useTrack } from "../../../../../../hooks/analytics/useTrack"; import { getVercelEnv } from "../../../../../../lib/vercel-utils"; import type { BlueprintParameter, BlueprintPathMetadata } from "../utils"; +const trackingCategory = "insightBlueprint"; + export function BlueprintPlayground(props: { metadata: BlueprintPathMetadata; backLink: string; @@ -151,6 +154,7 @@ export function BlueprintPlaygroundUI(props: { projectSettingsLink: string; supportedChainIds: number[]; }) { + const trackEvent = useTrack(); const parameters = useMemo(() => { return modifyParametersForPlayground(props.metadata.parameters); }, [props.metadata.parameters]); @@ -182,14 +186,15 @@ export function BlueprintPlaygroundUI(props: { intent: "run", }); + trackEvent({ + category: trackingCategory, + action: "click", + label: "run", + url: url, + }); props.onRun(url); } - // This allows us to always limit the grid height to whatever is the height of left section on desktop - // so that entire left section is always visible, but the right section has a scrollbar if it exceeds the height of left section - const { height, elementRef: leftSectionRef } = useHeightObserver(); - const isMobile = useIsMobileViewport(); - return (
@@ -230,10 +235,7 @@ export function BlueprintPlaygroundUI(props: { clientId={props.clientId} />
-
+
-
+
@@ -325,6 +324,14 @@ function PlaygroundHeader(props: { values: props.getFormValues(), intent: "copy", }); + + trackEvent({ + category: trackingCategory, + action: "click", + label: "copy-url", + url: url, + }); + setTimeout(() => { setHasCopied(false); }, 500); @@ -397,35 +404,37 @@ function RequestConfigSection(props: { const queryParams = props.parameters.filter((param) => param.in === "query"); return ( -
+
Request
- {pathVariables.length > 0 && ( - - )} + + {pathVariables.length > 0 && ( + + )} - {pathVariables.length > 0 && queryParams.length > 0 && } + {pathVariables.length > 0 && queryParams.length > 0 && } - {queryParams.length > 0 && ( - - )} + {queryParams.length > 0 && ( + + )} +
); } @@ -561,6 +570,7 @@ function ResponseSection(props: { | undefined; abortRequest: () => void; }) { + const trackEvent = useTrack(); const formattedData = useMemo(() => { if (!props.response?.data) return undefined; try { @@ -628,6 +638,13 @@ function ResponseSection(props: { scrollableContainerClassName="h-full" scrollableClassName="h-full" shadowColor="hsl(var(--muted)/50%)" + onCopy={() => { + trackEvent({ + category: trackingCategory, + action: "click", + label: "copy-response", + }); + }} /> )}
@@ -730,22 +747,3 @@ function ElapsedTimeCounter() { ); } - -const isMobileMedia = () => { - if (typeof window === "undefined") return false; - return window.matchMedia("(max-width: 640px)").matches; -}; - -function useIsMobileViewport() { - const [state, setState] = useState(isMobileMedia); - - // eslint-disable-next-line no-restricted-syntax - useEffect(() => { - if (typeof window === "undefined") return; - const handleResize = () => setState(isMobileMedia()); - window.addEventListener("resize", handleResize); - return () => window.removeEventListener("resize", handleResize); - }, []); - - return state; -} diff --git a/apps/dashboard/src/app/team/[team_slug]/[project_slug]/insight/page.tsx b/apps/dashboard/src/app/team/[team_slug]/[project_slug]/insight/page.tsx index 9f14d1d1c22..a04abfb81e7 100644 --- a/apps/dashboard/src/app/team/[team_slug]/[project_slug]/insight/page.tsx +++ b/apps/dashboard/src/app/team/[team_slug]/[project_slug]/insight/page.tsx @@ -98,26 +98,24 @@ function BlueprintCard(props: { description: string; }) { return ( -
-
-
-
- -
+
+
+
+
+
-
- -

{props.title}

- +
+ +

{props.title}

+ -

- {props.description} -

-
+

+ {props.description} +

); diff --git a/apps/dashboard/src/app/team/[team_slug]/[project_slug]/layout.tsx b/apps/dashboard/src/app/team/[team_slug]/[project_slug]/layout.tsx index 1f092a1a322..82e97357209 100644 --- a/apps/dashboard/src/app/team/[team_slug]/[project_slug]/layout.tsx +++ b/apps/dashboard/src/app/team/[team_slug]/[project_slug]/layout.tsx @@ -1,9 +1,9 @@ import { getProjects } from "@/api/projects"; import { getTeamNebulaWaitList, getTeams } from "@/api/team"; -import { TabPathLinks } from "@/components/ui/tabs"; import { notFound, redirect } from "next/navigation"; import { getValidAccount } from "../../../account/settings/getAccount"; import { TeamHeaderLoggedIn } from "../../components/TeamHeader/team-header-logged-in.client"; +import { ProjectTabs } from "./tabs"; export default async function TeamLayout(props: { children: React.ReactNode; @@ -55,39 +55,9 @@ export default async function TeamLayout(props: { teamsAndProjects={teamsAndProjects} account={account} /> -
{props.children}
diff --git a/apps/dashboard/src/app/team/[team_slug]/[project_slug]/page.tsx b/apps/dashboard/src/app/team/[team_slug]/[project_slug]/page.tsx index 857f7b5ca2f..fee25daf6cf 100644 --- a/apps/dashboard/src/app/team/[team_slug]/[project_slug]/page.tsx +++ b/apps/dashboard/src/app/team/[team_slug]/[project_slug]/page.tsx @@ -1,7 +1,7 @@ +import { type Project, getProject } from "@/api/projects"; +import { GenericLoadingPage } from "@/components/blocks/skeletons/GenericLoadingPage"; import { notFound } from "next/navigation"; -import { getProject } from "@/api/projects"; - import { type DurationId, type Range, @@ -22,6 +22,7 @@ import { isProjectActive, } from "@/api/analytics"; import { EmptyStateCard } from "app/team/components/Analytics/EmptyStateCard"; +import { Suspense } from "react"; import { type ChainMetadata, defineChain, @@ -69,6 +70,43 @@ export default async function ProjectOverviewPage(props: PageProps) { const isActive = await isProjectActive({ clientId: project.publishableKey }); + return ( +
+
+ +
+ {!isActive ? ( +
+ +
+ ) : ( +
+ }> + + +
+ )} +
+ ); +} + +async function ProjectAnalytics(props: { + project: Project; + range: Range; + interval: "day" | "week"; + searchParams: PageSearchParams; +}) { + const { project, range, interval, searchParams } = props; + // Fetch all analytics data in parallel const [ walletConnections, @@ -114,79 +152,64 @@ export default async function ProjectOverviewPage(props: PageProps) { ]); return ( -
-
- -
- {!isActive ? ( -
- +
+ {walletUserStatsTimeSeries.some((w) => w.totalUsers !== 0) ? ( +
+
) : ( -
- {walletUserStatsTimeSeries.some((w) => w.totalUsers !== 0) ? ( -
- -
- ) : ( - - )} - + )} + +
+ {walletConnections.length > 0 ? ( + + ) : ( + + )} + {inAppWalletUsage.length > 0 ? ( + + ) : ( + + )} +
+ {userOpUsage.length > 0 ? ( +
+ -
- {walletConnections.length > 0 ? ( - - ) : ( - - )} - {inAppWalletUsage.length > 0 ? ( - - ) : ( - - )} -
- {userOpUsage.length > 0 ? ( -
- -
- ) : ( - - )}
+ ) : ( + )}
); diff --git a/apps/dashboard/src/app/team/[team_slug]/[project_slug]/settings/ProjectGeneralSettingsPage.tsx b/apps/dashboard/src/app/team/[team_slug]/[project_slug]/settings/ProjectGeneralSettingsPage.tsx index 55211eb2fb0..86c8a961ee1 100644 --- a/apps/dashboard/src/app/team/[team_slug]/[project_slug]/settings/ProjectGeneralSettingsPage.tsx +++ b/apps/dashboard/src/app/team/[team_slug]/[project_slug]/settings/ProjectGeneralSettingsPage.tsx @@ -35,9 +35,9 @@ import { type FieldArrayWithId, useFieldArray } from "react-hook-form"; import { toast } from "sonner"; import { joinWithComma, toArrFromList } from "utils/string"; import { - type ApiKeyValidationSchema, HIDDEN_SERVICES, - apiKeyValidationSchema, + type ProjectSettingsPageFormSchema, + projectSettingsPageFormSchema, } from "../../../../../components/settings/ApiKeys/validations"; type EditProjectUIPaths = { @@ -86,7 +86,7 @@ interface EditApiKeyProps { showNebulaSettings: boolean; } -type UpdateAPIForm = UseFormReturn; +type UpdateAPIForm = UseFormReturn; export const ProjectGeneralSettingsPageUI: React.FC = ( props, @@ -94,8 +94,8 @@ export const ProjectGeneralSettingsPageUI: React.FC = ( const { apiKey, updateMutation, deleteMutation } = props; const trackEvent = useTrack(); const router = useDashboardRouter(); - const form = useForm({ - resolver: zodResolver(apiKeyValidationSchema), + const form = useForm({ + resolver: zodResolver(projectSettingsPageFormSchema), defaultValues: { name: apiKey.name, domains: joinWithComma(apiKey.domains), @@ -484,7 +484,7 @@ function EnabledServicesSetting(props: { }); const handleAction = ( srvIdx: number, - srv: FieldArrayWithId, + srv: FieldArrayWithId, actionName: string, checked: boolean, ) => { diff --git a/apps/dashboard/src/app/team/[team_slug]/[project_slug]/tabs.tsx b/apps/dashboard/src/app/team/[team_slug]/[project_slug]/tabs.tsx new file mode 100644 index 00000000000..dfa2212db26 --- /dev/null +++ b/apps/dashboard/src/app/team/[team_slug]/[project_slug]/tabs.tsx @@ -0,0 +1,49 @@ +"use client"; + +import { TabPathLinks } from "@/components/ui/tabs"; + +export function ProjectTabs(props: { + layoutPath: string; + isOnNebulaWaitList: boolean; +}) { + const { layoutPath, isOnNebulaWaitList } = props; + + return ( + path.startsWith(`${layoutPath}/connect`), + }, + { + path: `${layoutPath}/contracts`, + name: "Contracts", + }, + ...(isOnNebulaWaitList + ? [ + { + path: `${layoutPath}/nebula`, + name: "Nebula", + }, + ] + : []), + { + path: `${layoutPath}/insight`, + name: "Insight", + }, + { + path: `${layoutPath}/settings`, + name: "Settings", + }, + ]} + /> + ); +} diff --git a/apps/dashboard/src/components/buttons/MismatchButton.tsx b/apps/dashboard/src/components/buttons/MismatchButton.tsx index d632d32f7eb..feb18908776 100644 --- a/apps/dashboard/src/components/buttons/MismatchButton.tsx +++ b/apps/dashboard/src/components/buttons/MismatchButton.tsx @@ -59,6 +59,8 @@ const GAS_FREE_CHAINS = [ 4457845, // zero testnet 978658, // treasure topaz 300, // zksync sepolia + 7225878, // Saakuru Mainnet + 247253, // Saakuru Testnet ]; function useNetworkMismatchAdapter(desiredChainId: number) { @@ -127,6 +129,7 @@ export const MismatchButton = forwardRef< ); } + const notEnoughBalance = (evmBalance.data?.value || 0n) === 0n && !GAS_FREE_CHAINS.includes(chainId); diff --git a/apps/dashboard/src/components/contract-components/publisher/publisher-header.tsx b/apps/dashboard/src/components/contract-components/publisher/publisher-header.tsx index 115062b607d..36b15bb72db 100644 --- a/apps/dashboard/src/components/contract-components/publisher/publisher-header.tsx +++ b/apps/dashboard/src/components/contract-components/publisher/publisher-header.tsx @@ -65,7 +65,7 @@ export const PublisherHeader: React.FC = ({ } loadingComponent={} - className="size-14 rounded-full" + className="size-14 rounded-full object-cover" /> diff --git a/apps/dashboard/src/components/embedded-wallets/Configure/index.tsx b/apps/dashboard/src/components/embedded-wallets/Configure/index.tsx index 4fa6c060ccf..5f00301e239 100644 --- a/apps/dashboard/src/components/embedded-wallets/Configure/index.tsx +++ b/apps/dashboard/src/components/embedded-wallets/Configure/index.tsx @@ -422,6 +422,10 @@ function AuthEndpointFields(props: { name: "customAuthEndpoint.customHeaders", }); + const expandCustomAuthEndpointField = + form.watch("customAuthEndpoint")?.authEndpoint !== undefined && + canEditAdvancedFeatures; + return (
{ form.setValue( @@ -464,7 +466,7 @@ function AuthEndpointFields(props: { Allowed redirect URIs -